From 60e5542f3546b4a6d3e30cf1c2cc9fc9a1c795ec Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 26 Jun 2014 16:39:52 +0100 Subject: [PATCH] Get basic track changes list working --- services/web/app/views/project/editor.jade | 116 +------ .../web/app/views/project/editor/editor.jade | 19 ++ .../app/views/project/editor/file-tree.jade | 2 +- .../web/app/views/project/editor/header.jade | 27 ++ .../app/views/project/editor/left-menu.jade | 71 ++++ .../views/project/editor/track-changes.jade | 40 +++ .../coffee/app/filters/formatDate.coffee | 18 + services/web/public/coffee/app/ide.coffee | 5 + .../TrackChangesListController.coffee | 34 ++ .../track-changes/TrackChangesManager.coffee | 54 +++ services/web/public/coffee/app/main.coffee | 1 + .../coffee/app/main/project-list.coffee | 4 - .../web/public/stylesheets/app/editor.less | 195 +---------- .../stylesheets/app/editor/file-tree.less | 82 +++++ .../stylesheets/app/editor/left-menu.less | 35 ++ .../stylesheets/app/editor/toolbar.less | 63 ++++ .../stylesheets/app/editor/track-changes.less | 318 ++++++++++++++++++ 17 files changed, 786 insertions(+), 298 deletions(-) create mode 100644 services/web/app/views/project/editor/editor.jade create mode 100644 services/web/app/views/project/editor/header.jade create mode 100644 services/web/app/views/project/editor/left-menu.jade create mode 100644 services/web/app/views/project/editor/track-changes.jade create mode 100644 services/web/public/coffee/app/filters/formatDate.coffee create mode 100644 services/web/public/coffee/app/ide/track-changes/TrackChangesListController.coffee create mode 100644 services/web/public/coffee/app/ide/track-changes/TrackChangesManager.coffee create mode 100644 services/web/public/stylesheets/app/editor/file-tree.less create mode 100644 services/web/public/stylesheets/app/editor/left-menu.less create mode 100644 services/web/public/stylesheets/app/editor/toolbar.less create mode 100644 services/web/public/stylesheets/app/editor/track-changes.less diff --git a/services/web/app/views/project/editor.jade b/services/web/app/views/project/editor.jade index 20334d9fc4..5f261a0990 100644 --- a/services/web/app/views/project/editor.jade +++ b/services/web/app/views/project/editor.jade @@ -33,121 +33,17 @@ block content .alert.alert-warning.small(ng-if="connection.reconnecting") strong Reconnecting... - aside#left-menu( - ng-class="{ 'shown': ui.leftMenuShown }" - ng-cloak - ) - h4 Settings - form - .form-controls - label(for="compiler") Compiler - select.form-control( - name="compiler" - ng-model="project.compiler" - ) - option(value='pdflatex') pdfLaTeX - option(value='latex') LaTeX - option(value='xelatex') XeLaTeX - option(value='lualatex') LuaLaTeX + include ./editor/left-menu - .form-controls - label(for="spellCheckLanguage") Spell Check - select.form-control( - name="spellCheckLanguage" - ng-model="project.spellCheckLanguage" - ) - option(value="") Off - optgroup(label="Language") - for language in languages - option( - value=language.code - )= language.name - - .form-controls - label(for="autoComplete") Auto-Complete - input.form-control( - type="checkbox" - name="autoComplete" - ng-model="settings.autoComplete" - ) - - .form-controls - label(for="theme") Theme - select.form-control( - name="theme" - ng-model="settings.theme" - ) - each theme in themes - option(value=theme) #{theme} - - .form-controls - label(for="mode") Keybindings - select.form-control( - name="mode" - ng-model="settings.mode" - ) - option(value='default') None - option(value='vim') Vim - option(value='emacs') Emacs - - .form-controls - label(for="fontSize") Font Size - select.form-control( - name="fontSize" - ng-model="settings.fontSize" - ) - each size in ['10','11','12','13','14','16','20','24'] - option(value=size) #{size}px - - #left-menu-mask( - ng-show="ui.leftMenuShown", - ng-click="ui.leftMenuShown = false" - ng-cloak - ) - - header.toolbar.toolbar-header(ng-cloak, ng-hide="state.loading") - a.btn.btn-full-height( - href, - ng-click="ui.leftMenuShown = true" - tooltip="Menu", - tooltip-placement="bottom" - ) - i.fa.fa-bars - - span.name {{ project.name }} - - a(href='#', data-toggle="tooltip", title="Rename") - i.fa.fa-pencil - - .toolbar-right - a.btn.btn-full-height(href='#', tooltip="Share", tooltip-placement="bottom") - i.fa.fa-group - a.btn.btn-full-height(href='#', tooltip="Recent Changes", tooltip-placement="bottom") - i.fa.fa-history - a.btn.btn-full-height(href='#', tooltip="Chat", tooltip-placement="bottom") - i.fa.fa-comment + include ./editor/header #ide-body(ng-cloak, layout="main", ng-hide="state.loading") - include ./editor/file-tree + .ui-layout-west + include ./editor/file-tree .ui-layout-center - .loading(ng-show="!editor.sharejs_doc || editor.opening") - i.fa.fa-spin.fa-refresh - |   Loading... - #editor( - ace-editor, - ng-show="!!editor.sharejs_doc && !editor.opening" - theme="settings.theme", - keybindings="settings.mode", - font-size="settings.fontSize", - auto-complete="settings.autoComplete", - spell-check-language="project.spellCheckLanguage", - annotations="onlineUserCursorAnnotations[editor.open_doc_id]" - show-print-margin="false", - sharejs-doc="editor.sharejs_doc", - last-updated="editor.last_updated", - cursor-position="editor.cursorPosition" - ) + include ./editor/editor + include ./editor/track-changes //- #loadingScreen //- h3 Loading... diff --git a/services/web/app/views/project/editor/editor.jade b/services/web/app/views/project/editor/editor.jade new file mode 100644 index 0000000000..47bf67b4ee --- /dev/null +++ b/services/web/app/views/project/editor/editor.jade @@ -0,0 +1,19 @@ +div.full-size(ng-show="ui.view == 'editor'") + .loading(ng-show="!editor.sharejs_doc || editor.opening") + i.fa.fa-spin.fa-refresh + |   Loading... + + #editor( + ace-editor, + ng-show="!!editor.sharejs_doc && !editor.opening" + theme="settings.theme", + keybindings="settings.mode", + font-size="settings.fontSize", + auto-complete="settings.autoComplete", + spell-check-language="project.spellCheckLanguage", + annotations="onlineUserCursorAnnotations[editor.open_doc_id]" + show-print-margin="false", + sharejs-doc="editor.sharejs_doc", + last-updated="editor.last_updated", + cursor-position="editor.cursorPosition" + ) \ No newline at end of file diff --git a/services/web/app/views/project/editor/file-tree.jade b/services/web/app/views/project/editor/file-tree.jade index 3c7860a296..b26af79191 100644 --- a/services/web/app/views/project/editor/file-tree.jade +++ b/services/web/app/views/project/editor/file-tree.jade @@ -1,4 +1,4 @@ -aside#file-tree.ui-layout-west(ng-controller="FileTreeController") +aside#file-tree(ng-controller="FileTreeController") .toolbar.toolbar-small a( href, diff --git a/services/web/app/views/project/editor/header.jade b/services/web/app/views/project/editor/header.jade new file mode 100644 index 0000000000..6ebd08762a --- /dev/null +++ b/services/web/app/views/project/editor/header.jade @@ -0,0 +1,27 @@ +header.toolbar.toolbar-header(ng-cloak, ng-hide="state.loading") + a.btn.btn-full-height( + href, + ng-click="ui.leftMenuShown = true" + tooltip="Menu", + tooltip-placement="bottom" + ) + i.fa.fa-fw.fa-bars + + span.name {{ project.name }} + + a(href='#', data-toggle="tooltip", title="Rename") + i.fa.fa-pencil + + .toolbar-right + a.btn.btn-full-height(href='#', tooltip="Share", tooltip-placement="bottom") + i.fa.fa-fw.fa-group + a.btn.btn-full-height( + href, + ng-click="toggleTrackChanges()", + ng-class="{ active: (ui.view == 'track-changes') }" + tooltip="Recent Changes", + tooltip-placement="bottom" + ) + i.fa.fa-fw.fa-history + a.btn.btn-full-height(href='#', tooltip="Chat", tooltip-placement="bottom") + i.fa.fa-fw.fa-comment \ No newline at end of file diff --git a/services/web/app/views/project/editor/left-menu.jade b/services/web/app/views/project/editor/left-menu.jade new file mode 100644 index 0000000000..8ef522920d --- /dev/null +++ b/services/web/app/views/project/editor/left-menu.jade @@ -0,0 +1,71 @@ +aside#left-menu.full-size( + ng-class="{ 'shown': ui.leftMenuShown }" + ng-cloak +) + h4 Settings + form + .form-controls + label(for="compiler") Compiler + select.form-control( + name="compiler" + ng-model="project.compiler" + ) + option(value='pdflatex') pdfLaTeX + option(value='latex') LaTeX + option(value='xelatex') XeLaTeX + option(value='lualatex') LuaLaTeX + + .form-controls + label(for="spellCheckLanguage") Spell Check + select.form-control( + name="spellCheckLanguage" + ng-model="project.spellCheckLanguage" + ) + option(value="") Off + optgroup(label="Language") + for language in languages + option( + value=language.code + )= language.name + + .form-controls + label(for="autoComplete") Auto-Complete + input.form-control( + type="checkbox" + name="autoComplete" + ng-model="settings.autoComplete" + ) + + .form-controls + label(for="theme") Theme + select.form-control( + name="theme" + ng-model="settings.theme" + ) + each theme in themes + option(value=theme) #{theme} + + .form-controls + label(for="mode") Keybindings + select.form-control( + name="mode" + ng-model="settings.mode" + ) + option(value='default') None + option(value='vim') Vim + option(value='emacs') Emacs + + .form-controls + label(for="fontSize") Font Size + select.form-control( + name="fontSize" + ng-model="settings.fontSize" + ) + each size in ['10','11','12','13','14','16','20','24'] + option(value=size) #{size}px + +#left-menu-mask( + ng-show="ui.leftMenuShown", + ng-click="ui.leftMenuShown = false" + ng-cloak +) \ No newline at end of file diff --git a/services/web/app/views/project/editor/track-changes.jade b/services/web/app/views/project/editor/track-changes.jade new file mode 100644 index 0000000000..58059f6102 --- /dev/null +++ b/services/web/app/views/project/editor/track-changes.jade @@ -0,0 +1,40 @@ +div#trackChanges(ng-show="ui.view == 'track-changes'") + aside.change-list + ul.list-unstyled(ng-controller="TrackChangesListController") + li.change( + ng-repeat="update in trackChanges.updates" + ng-class="{\ + 'first-in-day': update.meta.first_in_day,\ + 'selected': update.inSelection,\ + 'selected-to': update.selectedTo,\ + 'selected-from': update.selectedFrom\ + }" + ng-controller="TrackChangesListItemController" + ) + + div.day(ng-show="update.meta.first_in_day") {{ update.meta.end_ts | relativeDate }} + + div.selectors + div.range + form + input.selector-from( + type="radio" + name="fromVersion" + ng-model="update.selectedFrom" + ng-value="true" + ) + form + input.selector-to( + type="radio" + name="toVersion" + ng-model="update.selectedTo" + ng-value="true" + ) + + div.description(ng-click="select()") + div.time {{ update.meta.end_ts | formatDate:'h:mm a' }} + div.docs(ng-repeat="(doc_id, doc) in update.docs") + span.doc {{ doc.entity.name }} + div.users + span.user(ng-repeat="user in update.meta.users") + | {{user.first_name}} {{user.last_name}} \ No newline at end of file diff --git a/services/web/public/coffee/app/filters/formatDate.coffee b/services/web/public/coffee/app/filters/formatDate.coffee new file mode 100644 index 0000000000..c8cef08dbd --- /dev/null +++ b/services/web/public/coffee/app/filters/formatDate.coffee @@ -0,0 +1,18 @@ +define [ + "base" +], (App) -> + moment.lang "en", calendar: + lastDay : '[Yesterday]' + sameDay : '[Today]' + nextDay : '[Tomorrow]' + lastWeek : "ddd, Do MMM YY" + nextWeek : "ddd, Do MMM YY" + sameElse : 'ddd, Do MMM YY' + + App.filter "formatDate", () -> + (date, format = "Do MMM YYYY, h:mm a") -> + moment(date).format(format) + + App.filter "relativeDate", () -> + (date) -> + moment(date).calendar() \ No newline at end of file diff --git a/services/web/public/coffee/app/ide.coffee b/services/web/public/coffee/app/ide.coffee index 355993df4e..f41919fae7 100644 --- a/services/web/public/coffee/app/ide.coffee +++ b/services/web/public/coffee/app/ide.coffee @@ -5,11 +5,13 @@ define [ "ide/editor/EditorManager" "ide/settings/SettingsManager" "ide/online-users/OnlineUsersManager" + "ide/track-changes/TrackChangesManager" "ide/directives/layout" "ide/services/ide" "directives/focus" "directives/fineUpload" "directives/onEnter" + "filters/formatDate" ], ( App FileTreeManager @@ -17,6 +19,7 @@ define [ EditorManager SettingsManager OnlineUsersManager + TrackChangesManager ) -> App.controller "IdeController", ["$scope", "$timeout", "ide", ($scope, $timeout, ide) -> # Don't freak out if we're already in an apply callback @@ -34,6 +37,7 @@ define [ } $scope.ui = { leftMenuShown: false + view: "editor" } window._ide = ide @@ -46,6 +50,7 @@ define [ ide.editorManager = new EditorManager(ide, $scope) ide.settingsManager = new SettingsManager(ide, $scope) ide.onlineUsersManager = new OnlineUsersManager(ide, $scope) + ide.trackChangesManager = new TrackChangesManager(ide, $scope) ] angular.bootstrap(document.body, ["SharelatexApp"]) \ No newline at end of file diff --git a/services/web/public/coffee/app/ide/track-changes/TrackChangesListController.coffee b/services/web/public/coffee/app/ide/track-changes/TrackChangesListController.coffee new file mode 100644 index 0000000000..e8d1b38920 --- /dev/null +++ b/services/web/public/coffee/app/ide/track-changes/TrackChangesListController.coffee @@ -0,0 +1,34 @@ +define [ + "base" +], (App) -> + App.controller "TrackChangesListController", ["$scope", ($scope) -> + $scope.recalculateSelectedUpdates = () -> + inSelection = false + for update in $scope.trackChanges.updates + if update.selectedTo + inSelection = true + update.inSelection = inSelection + if update.selectedFrom + inSelection = false + ] + + App.controller "TrackChangesListItemController", ["$scope", ($scope) -> + $scope.$watch "update.selectedFrom", (selectedFrom) -> + if selectedFrom? + if selectedFrom + for update in $scope.trackChanges.updates + update.selectedFrom = false unless update == $scope.update + $scope.recalculateSelectedUpdates() + + $scope.$watch "update.selectedTo", (selectedTo) -> + if selectedTo? + if selectedTo + for update in $scope.trackChanges.updates + update.selectedTo = false unless update == $scope.update + $scope.recalculateSelectedUpdates() + + $scope.select = () -> + $scope.update.selectedTo = true + $scope.update.selectedFrom = true + + ] \ No newline at end of file diff --git a/services/web/public/coffee/app/ide/track-changes/TrackChangesManager.coffee b/services/web/public/coffee/app/ide/track-changes/TrackChangesManager.coffee new file mode 100644 index 0000000000..218e243132 --- /dev/null +++ b/services/web/public/coffee/app/ide/track-changes/TrackChangesManager.coffee @@ -0,0 +1,54 @@ +define [ + "ide/track-changes/TrackChangesListController" +], () -> + class TrackChangesManager + constructor: (@ide, @$scope) -> + @$scope.trackChanges = { + updates: [] + nextBeforeTimestamp: null + atEnd: false + } + + @$scope.toggleTrackChanges = () => + if @$scope.ui.view == "track-changes" + @$scope.ui.view = "editor" + else + @$scope.ui.view = "track-changes" + + @$scope.$on "file-tree:initialized", () => + @fetchNextBatchOfChanges() + + BATCH_SIZE: 4 + fetchNextBatchOfChanges: () -> + url = "/project/#{@ide.project_id}/updates?min_count=#{@BATCH_SIZE}" + if @nextBeforeTimestamp? + url += "&before=#{@$scope.trackChanges.nextBeforeTimestamp}" + @ide.$http + .get(url) + .success (data) => + @_loadUpdates(data.updates) + @$scope.trackChanges.nextBeforeTimestamp = data.nextBeforeTimestamp + if !data.nextBeforeTimestamp? + @$scope.trackChanges.atEnd = true + + _loadUpdates: (updates = []) -> + previousUpdate = @$scope.trackChanges.updates[@$scope.trackChanges.updates.length - 1] + + for update in updates + for doc_id, doc of update.docs or {} + doc.entity = @ide.fileTreeManager.findEntityById(doc_id) + + for user in update.meta.users or [] + user.hue = @ide.onlineUsersManager.getHueForUserId(user.id) + + if !previousUpdate? or !moment(previousUpdate.meta.end_ts).isSame(update.meta.end_ts, "day") + update.meta.first_in_day = true + + update.selectedFrom = false + update.selectedTo = false + update.inSelection = false + + previousUpdate = update + + @$scope.trackChanges.updates = + @$scope.trackChanges.updates.concat(updates) diff --git a/services/web/public/coffee/app/main.coffee b/services/web/public/coffee/app/main.coffee index 8ffc093989..6d0579dc95 100644 --- a/services/web/public/coffee/app/main.coffee +++ b/services/web/public/coffee/app/main.coffee @@ -8,5 +8,6 @@ define [ "directives/equals" "directives/fineUpload" "directives/onEnter" + "filters/formatDate" ], () -> angular.bootstrap(document.body, ["SharelatexApp"]) \ No newline at end of file diff --git a/services/web/public/coffee/app/main/project-list.coffee b/services/web/public/coffee/app/main/project-list.coffee index d0cdd7d6ff..9879933ad6 100644 --- a/services/web/public/coffee/app/main/project-list.coffee +++ b/services/web/public/coffee/app/main/project-list.coffee @@ -1,10 +1,6 @@ define [ "base" ], (App) -> - App.filter "formatDate", () -> - (date, format = "Do MMM YYYY, h:mm a") -> - moment(date).format(format) - App.factory "queuedHttp", ["$http", "$q", ($http, $q) -> pendingRequests = [] inflight = false diff --git a/services/web/public/stylesheets/app/editor.less b/services/web/public/stylesheets/app/editor.less index d8ffcb2f2d..b1027d8271 100644 --- a/services/web/public/stylesheets/app/editor.less +++ b/services/web/public/stylesheets/app/editor.less @@ -1,3 +1,8 @@ +@import "./editor/file-tree.less"; +@import "./editor/track-changes.less"; +@import "./editor/toolbar.less"; +@import "./editor/left-menu.less"; + .full-size { position: absolute; top: 0; @@ -15,147 +20,6 @@ margin-left: -200px; } -.toolbar { - height: 40px; - border-bottom: 1px solid @toolbar-border-color; - - a { - display: inline-block; - color: @gray-light; - padding: 6px 12px 8px; - &:hover { - text-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); - color: @gray-dark; - } - } - - .btn-full-height { - border: none; - border-radius: 0; - border-right: 1px solid @toolbar-border-color; - color: @link-color; - padding: 6px 12px 8px; - &:hover { - text-shadow: 0 1px 0 rgba(0, 0, 0, 0.15); - background-color: darken(white, 10%); - color: @link-hover-color; - } - } - - .toolbar-right { - float: right; - .btn-full-height { - border-right: 0; - border-left: 1px solid @toolbar-border-color; - } - } - - &.toolbar-header { - box-shadow: 0 0 2px #ccc; - position: absolute; - top: 0; - left: 0; - right: 0; - z-index: 1; - } - - &.toolbar-small { - height: 32px; - a { - padding: 4px 2px 2px; - margin-left: 6px; - } - .toolbar-right { - a { - margin-left: 0; - margin-right: 6px; - } - } - } -} - -#file-tree { - background-color: #fafafa; - - ul.file-tree-list { - font-size: 0.8rem; - margin: 0; - padding: (@line-height-computed / 4) 0; - position: absolute; - top: 32px; - bottom: 0; - left: 0; - right: 0; - overflow-y: scroll; - - ul { - margin-left: (@line-height-computed / 2); - } - - li { - line-height: 2.6; - - .entity-name { - color: @gray-dark; - cursor: pointer; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - &:hover { - background-color: @gray-lightest; - } - input { - line-height: 1.6; - } - &.droppable-hover { - background-color: @file-tree-droppable-background-color; - } - } - - i.fa-folder-open, i.fa-folder { - color: lighten(desaturate(@link-color, 10%), 5%); - font-size: 14px; - } - - i.fa-file, i.fa-image { - color: @gray-light; - font-size: 14px; - } - - i.toggle { - width: 24px; - padding: 6px; - font-size: 0.7rem; - color: @gray - } - - &.selected { - > .entity > .entity-name { - color: @link-color; - border-right: 4px solid @link-color; - font-weight: bold; - i.fa-folder-open, i.fa-folder, i.fa-file, i.fa-image { - color: @link-color; - } - padding-right: 32px; - } - } - - .dropdown { - position: absolute; - right: 0; - > a { - padding: 0 12px; - } - } - } - } - - ul.droppable-hover { - background-color: @file-tree-droppable-background-color; - } -} - #ide-body { .full-size; top: 40px; @@ -163,14 +27,14 @@ #editor { .full-size; -} -.loading { - .full-size; - padding-top: 10rem; - font-family: @font-family-serif; - text-align: center; - background-color: #fafafa; + .loading { + .full-size; + padding-top: 10rem; + font-family: @font-family-serif; + text-align: center; + background-color: #fafafa; + } } // The internal components of the aceEditor directive @@ -258,38 +122,3 @@ z-index: 100; } -#left-menu { - position: absolute; - width: 210px; - padding: 10px; - top: 0; - bottom: 0; - background-color: #f4f4f4; - z-index: 100; - overflow: auto; - -webkit-transition: left ease-in-out 0.35s; - transition: left ease-in-out 0.35s; - - left: -280px; - &.shown { - left: 0; - } - - h4 { - font-family: @font-family-serif; - font-weight: 400; - font-size: 1rem; - margin: (@line-height-computed / 2) 0; - padding-bottom: (@line-height-computed / 4); - color: @gray-light; - border-bottom: 1px solid @gray-light; - text-transform: uppercase; - } -} - -#left-menu-mask { - .full-size; - opacity: 0.4; - background-color: #999; - z-index: 99; -} \ No newline at end of file diff --git a/services/web/public/stylesheets/app/editor/file-tree.less b/services/web/public/stylesheets/app/editor/file-tree.less new file mode 100644 index 0000000000..c4a5b89d76 --- /dev/null +++ b/services/web/public/stylesheets/app/editor/file-tree.less @@ -0,0 +1,82 @@ + +#file-tree { + background-color: #fafafa; + + ul.file-tree-list { + font-size: 0.8rem; + margin: 0; + padding: (@line-height-computed / 4) 0; + position: absolute; + top: 32px; + bottom: 0; + left: 0; + right: 0; + overflow-y: auto; + + ul { + margin-left: (@line-height-computed / 2); + } + + li { + line-height: 2.6; + + .entity-name { + color: @gray-dark; + cursor: pointer; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + &:hover { + background-color: @gray-lightest; + } + input { + line-height: 1.6; + } + &.droppable-hover { + background-color: @file-tree-droppable-background-color; + } + } + + i.fa-folder-open, i.fa-folder { + color: lighten(desaturate(@link-color, 10%), 5%); + font-size: 14px; + } + + i.fa-file, i.fa-image { + color: @gray-light; + font-size: 14px; + } + + i.toggle { + width: 24px; + padding: 6px; + font-size: 0.7rem; + color: @gray + } + + &.selected { + > .entity > .entity-name { + color: @link-color; + border-right: 4px solid @link-color; + font-weight: bold; + i.fa-folder-open, i.fa-folder, i.fa-file, i.fa-image { + color: @link-color; + } + padding-right: 32px; + } + } + + .dropdown { + position: absolute; + right: 0; + > a { + padding: 0 12px; + } + } + } + } + + ul.droppable-hover { + background-color: @file-tree-droppable-background-color; + } +} \ No newline at end of file diff --git a/services/web/public/stylesheets/app/editor/left-menu.less b/services/web/public/stylesheets/app/editor/left-menu.less new file mode 100644 index 0000000000..caaec20461 --- /dev/null +++ b/services/web/public/stylesheets/app/editor/left-menu.less @@ -0,0 +1,35 @@ +#left-menu { + position: absolute; + width: 210px; + padding: 10px; + top: 0; + bottom: 0; + background-color: #f4f4f4; + z-index: 100; + overflow: auto; + -webkit-transition: left ease-in-out 0.35s; + transition: left ease-in-out 0.35s; + + left: -280px; + &.shown { + left: 0; + } + + h4 { + font-family: @font-family-serif; + font-weight: 400; + font-size: 1rem; + margin: (@line-height-computed / 2) 0; + padding-bottom: (@line-height-computed / 4); + color: @gray-light; + border-bottom: 1px solid @gray-light; + text-transform: uppercase; + } +} + +#left-menu-mask { + .full-size; + opacity: 0.4; + background-color: #999; + z-index: 99; +} \ No newline at end of file diff --git a/services/web/public/stylesheets/app/editor/toolbar.less b/services/web/public/stylesheets/app/editor/toolbar.less new file mode 100644 index 0000000000..12472919c3 --- /dev/null +++ b/services/web/public/stylesheets/app/editor/toolbar.less @@ -0,0 +1,63 @@ +.toolbar { + height: 40px; + border-bottom: 1px solid @toolbar-border-color; + + a { + display: inline-block; + color: @gray-light; + padding: 6px 12px 8px; + &:hover { + text-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + color: @gray-dark; + } + } + + .btn-full-height { + border: none; + border-radius: 0; + border-right: 1px solid @toolbar-border-color; + color: @link-color; + padding: 6px 12px 8px; + &:hover { + text-shadow: 0 1px 0 rgba(0, 0, 0, 0.15); + background-color: darken(white, 10%); + color: @link-hover-color; + } + &.active, &:active { + color: white; + background-color: @link-color; + .box-shadow(inset 0 3px 5px rgba(0, 0, 0, 0.225)); + } + } + + .toolbar-right { + float: right; + .btn-full-height { + border-right: 0; + border-left: 1px solid @toolbar-border-color; + } + } + + &.toolbar-header { + box-shadow: 0 0 2px #ccc; + position: absolute; + top: 0; + left: 0; + right: 0; + z-index: 1; + } + + &.toolbar-small { + height: 32px; + a { + padding: 4px 2px 2px; + margin-left: 6px; + } + .toolbar-right { + a { + margin-left: 0; + margin-right: 6px; + } + } + } +} diff --git a/services/web/public/stylesheets/app/editor/track-changes.less b/services/web/public/stylesheets/app/editor/track-changes.less new file mode 100644 index 0000000000..8a497c22e3 --- /dev/null +++ b/services/web/public/stylesheets/app/editor/track-changes.less @@ -0,0 +1,318 @@ +@changesListWidth: 250px; +@changesListPadding: @line-height-computed / 2; + +@selector-padding-vertical: @line-height-computed / 3; +@selector-padding-horizontal: @line-height-computed / 2; +@day-header-height: 24px; + +@range-bar-color: @link-color; + +#trackChanges { + // .track-changes-diff { + // position: absolute; + // right: @changesListWidth + 1px; + // left: 0; + // top: 0; + // bottom: 0; + // height: 100%; + // .ace_editor { + // position: absolute; + // top: 42px; + // left: 0; + // right: 0; + // bottom: 0; + // .ace_active-line, .ace_cursor-layer, .ace_gutter-active-line { + // display: none; + // } + // } + // .track-changes-diff-toolbar { + // position: absolute; + // top: 0; + // left: 0; + // right: -1px; + // height: 32px; + // padding: 5px 5px 5px 5px; + // margin: 0; + // background-color: #282828; + // color: white; + // border-right: 1px solid white; + // .number-of-changes, .restore { + // position: absolute; + // } + // .number-of-changes { + // left: 10px; + // bottom: 7px; + // } + // .restore { + // right: 10px; + // bottom: 5px; + // padding: 3px 9px; + // } + // } + // } + + + // .track-changes-upgrade-control, .track-changes-upgrade-popup { + // position: absolute; + // top: 0; + // bottom: 0; + // left: 0; + // right: 0; + // z-index: 100; + // } + + // .track-changes-upgrade-popup { + // background-color: rgba(128,128,128,0.4); + // .message { + // margin: auto; + // margin-top: 200px; + // padding: 10px 10px 14px 10px; + // width: 400px; + // font-weight: bold; + // text-align: center; + // background-color: white; + // .border-radius(8px); + // } + // } + + // .track-changes-upgrade-control { + // background-color: #eeeeee; + // text-align: center; + // .message { + // font-size: 18px; + // margin: 12px; + // margin-top: 36px; + // } + // } + + // .deleted-background, + // .deleted-foreground, + // .inserted-background, + // .name-marker, + // .changes-before, + // .changes-after { + // position: absolute; + // z-index: 2; + // } + + // .name-marker { + // font-size: 0.8em; + // padding: 2px 6px; + // .border-radius(3px 3px 3px 3px); + // position: absolute; + // border: 1px solid #999; + // left: 0; + // white-space: pre; + // } + + // .changes-before { + // top: 6px; + // right: 6px; + // } + // .changes-after { + // bottom: 6px; + // right: 6px; + // } + // .changes-before, .changes-after { + // padding: 4px 8px; + // background-color: #eee; + // border: 1px solid #999; + // .border-radius(3px); + // } + + + aside.change-list { + border-left: 1px solid @toolbar-border-color; + height: 100%; + width: @changesListWidth; + position: absolute; + right: 0; + background-color: white; + + ul { + li.change { + position: relative; + cursor: pointer; + user-select: none; + -ms-user-select: none; + -moz-user-select: none; + -webkit-user-select: none; + + .day { + background-color: #fafafa; + border-bottom: 1px solid @toolbar-border-color; + padding: 4px; + font-weight: bold; + text-align: center; + height: @day-header-height; + font-size: 14px; + line-height: 1; + } + .selectors { + input { + margin: 0; + } + position: absolute; + left: @selector-padding-horizontal; + top: 0; + bottom: 0; + width: 24px; + .selector-from { + position: absolute; + bottom: @selector-padding-vertical; + left: 0; + opacity: 0.8; + } + .selector-to { + position: absolute; + top: @selector-padding-vertical; + left: 0; + opacity: 0.8; + } + .range { + position: absolute; + left: 5px; + width: 4px; + top: 0; + bottom: 0; + } + } + .description { + padding: (@line-height-computed / 4); + padding-left: 38px; + min-height: 38px; + border-bottom: 1px solid @toolbar-border-color; + } + .user { + font-size: 0.8rem; + color: @gray; + text-transform: capitalize; + } + .time { + float: right; + color: @gray; + display: inline-block; + padding-right: (@line-height-computed / 2); + font-size: 0.8rem; + line-height: @line-height-computed; + } + // .color-square { + // display: inline-block; + // height: 10px; + // width: 10px; + // margin-right: 4px; + // margin-bottom: -1px; + // } + .docs { + font-weight: bold; + font-size: 0.9rem; + } + &:hover { + background-color: @gray-lightest; + } + } + li.loading-changes, li.empty-message { + padding: 6px; + cursor: default; + &:hover { + background-color: inherit; + } + } + li.selected { + border-left: 4px solid @range-bar-color; + .description { + padding-left: 34px; + } + .selectors { + left: @selector-padding-horizontal - 4px; + .range { + background-color: @range-bar-color; + } + } + } + li.selected-to { + .selectors { + .range { + top: 10px; + } + .selector-to { + opacity: 1; + } + } + } + li.selected-from { + .selectors { + .range { + bottom: 10px; + } + .selector-from { + opacity: 1; + } + } + } + li.first-in-day { + .day { + display: block; + } + .selectors { + .selector-to { + top: @day-header-height + @selector-padding-vertical; + } + } + } + li.first-in-day.selected-to { + .selectors { + .range { + top: 33px; + } + } + } + } + ul.list.hover-state { + li { + .selectors { + .range { + background-color: transparent; + top: 0; + bottom: 0; + } + } + } + li.hover-selected { + .selectors { + .range { + top: 0; + background-color: #999; + } + } + } + li.hover-selected-to { + .selectors { + .range { + top: 10px; + } + .selector-to { + opacity: 1; + } + } + } + li.hover-selected-from { + .selectors { + .range { + bottom: 10px; + } + .selector-from { + opacity: 1; + } + } + } + li.first-in-day.hover-selected-to { + .selectors { + .range { + top: 33px; + } + } + } + } + } +} \ No newline at end of file