From 6e7bf3e54a593545cf3b6c76e1d09f599c63d9f1 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Fri, 27 Apr 2018 11:22:20 +0100 Subject: [PATCH 01/19] Wrap copies of existing history UI elements in components. --- app/views/project/editor/history.pug | 83 +------------ .../project/editor/history/entriesListV1.pug | 82 +++++++++++++ .../project/editor/history/entriesListV2.pug | 94 +++++++++++++++ .../coffee/ide/history/HistoryManager.coffee | 1 + .../ide/history/HistoryV2Manager.coffee | 2 + .../components/historyEntriesList.coffee | 17 +++ .../history/components/historyEntry.coffee | 15 +++ .../HistoryV2ListController.coffee | 110 ++++++++++++++++++ 8 files changed, 323 insertions(+), 81 deletions(-) create mode 100644 app/views/project/editor/history/entriesListV1.pug create mode 100644 app/views/project/editor/history/entriesListV2.pug create mode 100644 public/coffee/ide/history/components/historyEntriesList.coffee create mode 100644 public/coffee/ide/history/components/historyEntry.coffee create mode 100644 public/coffee/ide/history/controllers/HistoryV2ListController.coffee diff --git a/app/views/project/editor/history.pug b/app/views/project/editor/history.pug index d366d5f41a..f237aff89e 100644 --- a/app/views/project/editor/history.pug +++ b/app/views/project/editor/history.pug @@ -40,87 +40,8 @@ div#history(ng-show="ui.view == 'history'") p a.small(href, ng-click="toggleHistory()") #{translate("cancel")} - aside.change-list( - ng-controller="HistoryListController" - infinite-scroll="loadMore()" - infinite-scroll-disabled="history.loading || history.atEnd" - infinite-scroll-initialize="ui.view == 'history'" - ) - .infinite-scroll-inner - ul.list-unstyled( - ng-class="{\ - 'hover-state': history.hoveringOverListSelectors\ - }" - ) - li.change( - ng-repeat="update in history.updates" - ng-class="{\ - 'first-in-day': update.meta.first_in_day,\ - 'selected': update.inSelection,\ - 'selected-to': update.selectedTo,\ - 'selected-from': update.selectedFrom,\ - 'hover-selected': update.inHoverSelection,\ - 'hover-selected-to': update.hoverSelectedTo,\ - 'hover-selected-from': update.hoverSelectedFrom,\ - }" - ng-controller="HistoryListItemController" - ) - - 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" - ng-mouseover="mouseOverSelectedFrom()" - ng-mouseout="mouseOutSelectedFrom()" - ng-show="update.afterSelection || update.inSelection" - ) - form - input.selector-to( - type="radio" - name="toVersion" - ng-model="update.selectedTo" - ng-value="true" - ng-mouseover="mouseOverSelectedTo()" - ng-mouseout="mouseOutSelectedTo()" - ng-show="update.beforeSelection || update.inSelection" - ) - - div.description(ng-click="select()") - div.time {{ update.meta.end_ts | formatDate:'h:mm a' }} - div.action.action-edited(ng-if="history.isV2 && update.pathnames.length > 0") - | Edited - div.docs(ng-repeat="pathname in update.pathnames") - .doc {{ pathname }} - div.docs(ng-repeat="project_op in update.project_ops") - div(ng-if="project_op.rename") - .action Renamed - .doc {{ project_op.rename.pathname }} → {{ project_op.rename.newPathname }} - div(ng-if="project_op.add") - .action Created - .doc {{ project_op.add.pathname }} - div(ng-if="project_op.remove") - .action Deleted - .doc {{ project_op.remove.pathname }} - div.users - div.user(ng-repeat="update_user in update.meta.users") - .color-square(ng-if="update_user != null", ng-style="{'background-color': 'hsl({{ update_user.hue }}, 70%, 50%)'}") - .color-square(ng-if="update_user == null", ng-style="{'background-color': 'hsl(100, 70%, 50%)'}") - .name(ng-if="update_user && update_user.id != user.id" ng-bind="displayName(update_user)") - .name(ng-if="update_user && update_user.id == user.id") You - .name(ng-if="update_user == null") #{translate("anonymous")} - div.user(ng-if="update.meta.users.length == 0") - .color-square(style="background-color: hsl(100, 100%, 50%)") - span #{translate("anonymous")} - - .loading(ng-show="history.loading") - i.fa.fa-spin.fa-refresh - |    #{translate("loading")}... + include ./history/entriesListV1 + include ./history/entriesListV2 include ./history/diffPanelV1 include ./history/diffPanelV2 diff --git a/app/views/project/editor/history/entriesListV1.pug b/app/views/project/editor/history/entriesListV1.pug new file mode 100644 index 0000000000..2db6b9e533 --- /dev/null +++ b/app/views/project/editor/history/entriesListV1.pug @@ -0,0 +1,82 @@ +aside.change-list( + ng-if="!history.isV2" + ng-controller="HistoryListController" + infinite-scroll="loadMore()" + infinite-scroll-disabled="history.loading || history.atEnd" + infinite-scroll-initialize="ui.view == 'history'" + ) + .infinite-scroll-inner + ul.list-unstyled( + ng-class="{\ + 'hover-state': history.hoveringOverListSelectors\ + }" + ) + li.change( + ng-repeat="update in history.updates" + ng-class="{\ + 'first-in-day': update.meta.first_in_day,\ + 'selected': update.inSelection,\ + 'selected-to': update.selectedTo,\ + 'selected-from': update.selectedFrom,\ + 'hover-selected': update.inHoverSelection,\ + 'hover-selected-to': update.hoverSelectedTo,\ + 'hover-selected-from': update.hoverSelectedFrom,\ + }" + ng-controller="HistoryListItemController" + ) + + 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" + ng-mouseover="mouseOverSelectedFrom()" + ng-mouseout="mouseOutSelectedFrom()" + ng-show="update.afterSelection || update.inSelection" + ) + form + input.selector-to( + type="radio" + name="toVersion" + ng-model="update.selectedTo" + ng-value="true" + ng-mouseover="mouseOverSelectedTo()" + ng-mouseout="mouseOutSelectedTo()" + ng-show="update.beforeSelection || update.inSelection" + ) + + div.description(ng-click="select()") + div.time {{ update.meta.end_ts | formatDate:'h:mm a' }} + div.action.action-edited(ng-if="history.isV2 && update.pathnames.length > 0") + | Edited + div.docs(ng-repeat="pathname in update.pathnames") + .doc {{ pathname }} + div.docs(ng-repeat="project_op in update.project_ops") + div(ng-if="project_op.rename") + .action Renamed + .doc {{ project_op.rename.pathname }} → {{ project_op.rename.newPathname }} + div(ng-if="project_op.add") + .action Created + .doc {{ project_op.add.pathname }} + div(ng-if="project_op.remove") + .action Deleted + .doc {{ project_op.remove.pathname }} + div.users + div.user(ng-repeat="update_user in update.meta.users") + .color-square(ng-if="update_user != null", ng-style="{'background-color': 'hsl({{ update_user.hue }}, 70%, 50%)'}") + .color-square(ng-if="update_user == null", ng-style="{'background-color': 'hsl(100, 70%, 50%)'}") + .name(ng-if="update_user && update_user.id != user.id" ng-bind="displayName(update_user)") + .name(ng-if="update_user && update_user.id == user.id") You + .name(ng-if="update_user == null") #{translate("anonymous")} + div.user(ng-if="update.meta.users.length == 0") + .color-square(style="background-color: hsl(100, 100%, 50%)") + span #{translate("anonymous")} + + .loading(ng-show="history.loading") + i.fa.fa-spin.fa-refresh + |    #{translate("loading")}... diff --git a/app/views/project/editor/history/entriesListV2.pug b/app/views/project/editor/history/entriesListV2.pug new file mode 100644 index 0000000000..e5bc339c51 --- /dev/null +++ b/app/views/project/editor/history/entriesListV2.pug @@ -0,0 +1,94 @@ +aside.change-list( + ng-if="history.isV2" + ng-controller="HistoryV2ListController" +) + history-entries-list( + entries="history.updates" + load-entries="loadMore()" + load-disabled="history.loading || history.atEnd" + load-initialize="ui.view == 'history'" + is-loading="history.loading" + ) + + +script(type="text/ng-template", id="historyEntriesListTpl") + div( + infinite-scroll="$ctrl.loadEntries()" + infinite-scroll-disabled="$ctrl.loadDisabled" + infinite-scroll-initialize="$ctrl.loadInitialize" + ) + .infinite-scroll-inner + history-entry( + ng-repeat="entry in $ctrl.entries" + entry="entry" + ) + .loading(ng-show="history.loading") + i.fa.fa-spin.fa-refresh + |    #{translate("loading")}... + +script(type="text/ng-template", id="historyEntryTpl") + .change( + ng-class="{\ + 'first-in-day': $ctrl.entry.meta.first_in_day,\ + 'selected': $ctrl.entry.inSelection,\ + 'selected-to': $ctrl.entry.selectedTo,\ + 'selected-from': $ctrl.entry.selectedFrom,\ + 'hover-selected': $ctrl.entry.inHoverSelection,\ + 'hover-selected-to': $ctrl.entry.hoverSelectedTo,\ + 'hover-selected-from': $ctrl.entry.hoverSelectedFrom,\ + }" + ) + + div.day(ng-show="$ctrl.entry.meta.first_in_day") {{ $ctrl.entry.meta.end_ts | relativeDate }} + + //- div.selectors + //- div.range + //- form + //- input.selector-from( + //- type="radio" + //- name="fromVersion" + //- ng-model="$ctrl.entry.selectedFrom" + //- ng-value="true" + //- ng-mouseover="mouseOverSelectedFrom()" + //- ng-mouseout="mouseOutSelectedFrom()" + //- ng-show="$ctrl.entry.afterSelection || $ctrl.entry.inSelection" + //- ) + //- form + //- input.selector-to( + //- type="radio" + //- name="toVersion" + //- ng-model="$ctrl.entry.selectedTo" + //- ng-value="true" + //- ng-mouseover="mouseOverSelectedTo()" + //- ng-mouseout="mouseOutSelectedTo()" + //- ng-show="$ctrl.entry.beforeSelection || $ctrl.entry.inSelection" + ) + + div.description(ng-click="select()") + div.time {{ $ctrl.entry.meta.end_ts | formatDate:'h:mm a' }} + div.action.action-edited(ng-if="history.isV2 && $ctrl.entry.pathnames.length > 0") + | Edited + div.docs(ng-repeat="pathname in $ctrl.entry.pathnames") + div + .action Edited + .doc {{ pathname }} + div.docs(ng-repeat="project_op in $ctrl.entry.project_ops") + div(ng-if="project_op.rename") + .action Renamed + .doc {{ project_op.rename.pathname }} → {{ project_op.rename.newPathname }} + div(ng-if="project_op.add") + .action Created + .doc {{ project_op.add.pathname }} + div(ng-if="project_op.remove") + .action Deleted + .doc {{ project_op.remove.pathname }} + div.users + div.user(ng-repeat="update_user in $ctrl.entry.meta.users") + .color-square(ng-if="update_user != null", ng-style="{'background-color': 'hsl({{ update_user.hue }}, 70%, 50%)'}") + .color-square(ng-if="update_user == null", ng-style="{'background-color': 'hsl(100, 70%, 50%)'}") + .name(ng-if="update_user && update_user.id != user.id" ng-bind="$ctrl.displayName(update_user)") + .name(ng-if="update_user && update_user.id == user.id") You + .name(ng-if="update_user == null") #{translate("anonymous")} + div.user(ng-if="$ctrl.entry.meta.users.length == 0") + .color-square(style="background-color: hsl(100, 100%, 50%)") + span #{translate("anonymous")} \ No newline at end of file diff --git a/public/coffee/ide/history/HistoryManager.coffee b/public/coffee/ide/history/HistoryManager.coffee index cdc39ffd05..e79f0ad116 100644 --- a/public/coffee/ide/history/HistoryManager.coffee +++ b/public/coffee/ide/history/HistoryManager.coffee @@ -3,6 +3,7 @@ define [ "ide/colors/ColorManager" "ide/history/util/displayNameForUser" "ide/history/controllers/HistoryListController" + "ide/history/controllers/HistoryV2ListController" "ide/history/controllers/HistoryDiffController" "ide/history/controllers/HistoryV2DiffController" "ide/history/directives/infiniteScroll" diff --git a/public/coffee/ide/history/HistoryV2Manager.coffee b/public/coffee/ide/history/HistoryV2Manager.coffee index 72f4c79bdd..c2c75a0373 100644 --- a/public/coffee/ide/history/HistoryV2Manager.coffee +++ b/public/coffee/ide/history/HistoryV2Manager.coffee @@ -5,6 +5,8 @@ define [ "ide/history/controllers/HistoryListController" "ide/history/controllers/HistoryDiffController" "ide/history/directives/infiniteScroll" + "ide/history/components/historyEntriesList" + "ide/history/components/historyEntry" ], (moment, ColorManager, displayNameForUser) -> class HistoryManager constructor: (@ide, @$scope) -> diff --git a/public/coffee/ide/history/components/historyEntriesList.coffee b/public/coffee/ide/history/components/historyEntriesList.coffee new file mode 100644 index 0000000000..11ee4e73de --- /dev/null +++ b/public/coffee/ide/history/components/historyEntriesList.coffee @@ -0,0 +1,17 @@ +define [ + "base" +], (App) -> + historyEntriesListController = ($scope, $element, $attrs) -> + ctrl = @ + return + + App.component "historyEntriesList", { + bindings: + entries: "<" + loadEntries: "&" + loadDisabled: "<" + loadInitialize: "<" + isLoading: "<" + controller: historyEntriesListController + templateUrl: "historyEntriesListTpl" + } diff --git a/public/coffee/ide/history/components/historyEntry.coffee b/public/coffee/ide/history/components/historyEntry.coffee new file mode 100644 index 0000000000..fbfd4dab08 --- /dev/null +++ b/public/coffee/ide/history/components/historyEntry.coffee @@ -0,0 +1,15 @@ +define [ + "base" + "ide/history/util/displayNameForUser" +], (App, displayNameForUser) -> + historyEntryController = ($scope, $element, $attrs) -> + ctrl = @ + ctrl.displayName = displayNameForUser + return + + App.component "historyEntry", { + bindings: + entry: "<" + controller: historyEntryController + templateUrl: "historyEntryTpl" + } \ No newline at end of file diff --git a/public/coffee/ide/history/controllers/HistoryV2ListController.coffee b/public/coffee/ide/history/controllers/HistoryV2ListController.coffee new file mode 100644 index 0000000000..772f360a80 --- /dev/null +++ b/public/coffee/ide/history/controllers/HistoryV2ListController.coffee @@ -0,0 +1,110 @@ +define [ + "base", + "ide/history/util/displayNameForUser" +], (App, displayNameForUser) -> + + App.controller "HistoryV2ListController", ["$scope", "ide", ($scope, ide) -> + $scope.hoveringOverListSelectors = false + + $scope.loadMore = () => + ide.historyManager.fetchNextBatchOfUpdates() + + $scope.recalculateSelectedUpdates = () -> + beforeSelection = true + afterSelection = false + $scope.history.selection.updates = [] + for update in $scope.history.updates + if update.selectedTo + inSelection = true + beforeSelection = false + + update.beforeSelection = beforeSelection + update.inSelection = inSelection + update.afterSelection = afterSelection + + if inSelection + $scope.history.selection.updates.push update + + if update.selectedFrom + inSelection = false + afterSelection = true + + $scope.recalculateHoveredUpdates = () -> + hoverSelectedFrom = false + hoverSelectedTo = false + for update in $scope.history.updates + # Figure out whether the to or from selector is hovered over + if update.hoverSelectedFrom + hoverSelectedFrom = true + if update.hoverSelectedTo + hoverSelectedTo = true + + if hoverSelectedFrom + # We want to 'hover select' everything between hoverSelectedFrom and selectedTo + inHoverSelection = false + for update in $scope.history.updates + if update.selectedTo + update.hoverSelectedTo = true + inHoverSelection = true + update.inHoverSelection = inHoverSelection + if update.hoverSelectedFrom + inHoverSelection = false + if hoverSelectedTo + # We want to 'hover select' everything between hoverSelectedTo and selectedFrom + inHoverSelection = false + for update in $scope.history.updates + if update.hoverSelectedTo + inHoverSelection = true + update.inHoverSelection = inHoverSelection + if update.selectedFrom + update.hoverSelectedFrom = true + inHoverSelection = false + + $scope.resetHoverState = () -> + for update in $scope.history.updates + delete update.hoverSelectedFrom + delete update.hoverSelectedTo + delete update.inHoverSelection + + $scope.$watch "history.updates.length", () -> + $scope.recalculateSelectedUpdates() + ] + + App.controller "HistoryListItemController", ["$scope", "event_tracking", ($scope, event_tracking) -> + $scope.$watch "update.selectedFrom", (selectedFrom, oldSelectedFrom) -> + if selectedFrom + for update in $scope.history.updates + update.selectedFrom = false unless update == $scope.update + $scope.recalculateSelectedUpdates() + + $scope.$watch "update.selectedTo", (selectedTo, oldSelectedTo) -> + if selectedTo + for update in $scope.history.updates + update.selectedTo = false unless update == $scope.update + $scope.recalculateSelectedUpdates() + + $scope.select = () -> + event_tracking.sendMB "history-view-change" + $scope.update.selectedTo = true + $scope.update.selectedFrom = true + + $scope.mouseOverSelectedFrom = () -> + $scope.history.hoveringOverListSelectors = true + $scope.update.hoverSelectedFrom = true + $scope.recalculateHoveredUpdates() + + $scope.mouseOutSelectedFrom = () -> + $scope.history.hoveringOverListSelectors = false + $scope.resetHoverState() + + $scope.mouseOverSelectedTo = () -> + $scope.history.hoveringOverListSelectors = true + $scope.update.hoverSelectedTo = true + $scope.recalculateHoveredUpdates() + + $scope.mouseOutSelectedTo = () -> + $scope.history.hoveringOverListSelectors = false + $scope.resetHoverState() + + $scope.displayName = displayNameForUser + ] From 54f17f2c2ee92e2f63a15fbe33d52482729dc903 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Fri, 27 Apr 2018 15:59:28 +0100 Subject: [PATCH 02/19] Style the history entries components. --- .../project/editor/history/entriesListV2.pug | 69 ++-- .../components/historyEntriesList.coffee | 1 + .../history/components/historyEntry.coffee | 9 + public/stylesheets/_ol_style_includes.less | 2 +- public/stylesheets/_style_includes.less | 1 + public/stylesheets/app/editor/history-v2.less | 384 ++++++++++++++++++ .../stylesheets/core/_common-variables.less | 9 +- public/stylesheets/core/ol-variables.less | 8 + 8 files changed, 450 insertions(+), 33 deletions(-) create mode 100644 public/stylesheets/app/editor/history-v2.less diff --git a/app/views/project/editor/history/entriesListV2.pug b/app/views/project/editor/history/entriesListV2.pug index e5bc339c51..a19273bfb9 100644 --- a/app/views/project/editor/history/entriesListV2.pug +++ b/app/views/project/editor/history/entriesListV2.pug @@ -4,6 +4,7 @@ aside.change-list( ) history-entries-list( entries="history.updates" + current-user="user" load-entries="loadMore()" load-disabled="history.loading || history.atEnd" load-initialize="ui.view == 'history'" @@ -12,7 +13,7 @@ aside.change-list( script(type="text/ng-template", id="historyEntriesListTpl") - div( + .history-entries( infinite-scroll="$ctrl.loadEntries()" infinite-scroll-disabled="$ctrl.loadDisabled" infinite-scroll-initialize="$ctrl.loadInitialize" @@ -21,13 +22,14 @@ script(type="text/ng-template", id="historyEntriesListTpl") history-entry( ng-repeat="entry in $ctrl.entries" entry="entry" + current-user="$ctrl.currentUser" ) .loading(ng-show="history.loading") i.fa.fa-spin.fa-refresh |    #{translate("loading")}... script(type="text/ng-template", id="historyEntryTpl") - .change( + .history-entry( ng-class="{\ 'first-in-day': $ctrl.entry.meta.first_in_day,\ 'selected': $ctrl.entry.inSelection,\ @@ -39,7 +41,7 @@ script(type="text/ng-template", id="historyEntryTpl") }" ) - div.day(ng-show="$ctrl.entry.meta.first_in_day") {{ $ctrl.entry.meta.end_ts | relativeDate }} + time.history-entry-day(ng-if="::$ctrl.entry.meta.first_in_day") {{ ::$ctrl.entry.meta.end_ts | relativeDate }} //- div.selectors //- div.range @@ -64,31 +66,36 @@ script(type="text/ng-template", id="historyEntryTpl") //- ng-show="$ctrl.entry.beforeSelection || $ctrl.entry.inSelection" ) - div.description(ng-click="select()") - div.time {{ $ctrl.entry.meta.end_ts | formatDate:'h:mm a' }} - div.action.action-edited(ng-if="history.isV2 && $ctrl.entry.pathnames.length > 0") - | Edited - div.docs(ng-repeat="pathname in $ctrl.entry.pathnames") - div - .action Edited - .doc {{ pathname }} - div.docs(ng-repeat="project_op in $ctrl.entry.project_ops") - div(ng-if="project_op.rename") - .action Renamed - .doc {{ project_op.rename.pathname }} → {{ project_op.rename.newPathname }} - div(ng-if="project_op.add") - .action Created - .doc {{ project_op.add.pathname }} - div(ng-if="project_op.remove") - .action Deleted - .doc {{ project_op.remove.pathname }} - div.users - div.user(ng-repeat="update_user in $ctrl.entry.meta.users") - .color-square(ng-if="update_user != null", ng-style="{'background-color': 'hsl({{ update_user.hue }}, 70%, 50%)'}") - .color-square(ng-if="update_user == null", ng-style="{'background-color': 'hsl(100, 70%, 50%)'}") - .name(ng-if="update_user && update_user.id != user.id" ng-bind="$ctrl.displayName(update_user)") - .name(ng-if="update_user && update_user.id == user.id") You - .name(ng-if="update_user == null") #{translate("anonymous")} - div.user(ng-if="$ctrl.entry.meta.users.length == 0") - .color-square(style="background-color: hsl(100, 100%, 50%)") - span #{translate("anonymous")} \ No newline at end of file + .history-entry-details(ng-click="select()") + ol.history-entry-changes + li.history-entry-change( + ng-repeat="pathname in ::$ctrl.entry.pathnames" + ) + span.history-entry-change-action Edited + span.history-entry-change-doc {{ ::pathname }} + li.history-entry-change( + ng-repeat="project_op in ::$ctrl.entry.project_ops" + ) + span.history-entry-change-action {{ ::$ctrl.getProjectOpAction(project_op) }} + span.history-entry-change-doc {{ ::$ctrl.getProjectOpDoc(project_op) }} + .history-entry-metadata + time.history-entry-metadata-time {{ ::$ctrl.entry.meta.end_ts | formatDate:'h:mm a' }} + span  •  + ol.history-entry-metadata-users + li.history-entry-metadata-user(ng-repeat="update_user in ::$ctrl.entry.meta.users") + span.name( + ng-if="::update_user && update_user.id != $ctrl.currentUser.id" + ng-style="::{'color': 'hsl({{ update_user.hue }}, 70%, 50%)'}" + ) {{ ::$ctrl.displayName(update_user) }} + span.name( + ng-if="::update_user && update_user.id == $ctrl.currentUser.id" + ng-style="::{'color': 'hsl({{ update_user.hue }}, 70%, 50%)'}" + ) You + span.name( + ng-if="::update_user == null" + ng-style="::{'color': 'hsl(100, 70%, 50%)'}" + ) #{translate("anonymous")} + li.history-entry-metadata-user(ng-if="::$ctrl.entry.meta.users.length == 0") + span.name( + ng-style="::{'color': 'hsl(100, 70%, 50%)'}" + ) #{translate("anonymous")} \ No newline at end of file diff --git a/public/coffee/ide/history/components/historyEntriesList.coffee b/public/coffee/ide/history/components/historyEntriesList.coffee index 11ee4e73de..8eabf38ebc 100644 --- a/public/coffee/ide/history/components/historyEntriesList.coffee +++ b/public/coffee/ide/history/components/historyEntriesList.coffee @@ -12,6 +12,7 @@ define [ loadDisabled: "<" loadInitialize: "<" isLoading: "<" + currentUser: "<" controller: historyEntriesListController templateUrl: "historyEntriesListTpl" } diff --git a/public/coffee/ide/history/components/historyEntry.coffee b/public/coffee/ide/history/components/historyEntry.coffee index fbfd4dab08..dbc63a105b 100644 --- a/public/coffee/ide/history/components/historyEntry.coffee +++ b/public/coffee/ide/history/components/historyEntry.coffee @@ -5,11 +5,20 @@ define [ historyEntryController = ($scope, $element, $attrs) -> ctrl = @ ctrl.displayName = displayNameForUser + ctrl.getProjectOpAction = (projectOp) -> + if projectOp.rename? then "Renamed" + else if projectOp.add? then "Created" + else if projectOp.remove? then "Deleted" + ctrl.getProjectOpDoc = (projectOp) -> + if projectOp.rename? then "#{ projectOp.rename.pathname} → #{ projectOp.rename.newPathname }" + else if projectOp.add? then "#{ projectOp.add.pathname}" + else if projectOp.remove? then "#{ projectOp.remove.pathname}" return App.component "historyEntry", { bindings: entry: "<" + currentUser: "<" controller: historyEntryController templateUrl: "historyEntryTpl" } \ No newline at end of file diff --git a/public/stylesheets/_ol_style_includes.less b/public/stylesheets/_ol_style_includes.less index 921b20f727..cc03279a73 100644 --- a/public/stylesheets/_ol_style_includes.less +++ b/public/stylesheets/_ol_style_includes.less @@ -1,2 +1,2 @@ @import "app/sidebar-v2-dash-pane.less"; -@import "app/front-chat-widget.less"; +@import "app/front-chat-widget.less"; \ No newline at end of file diff --git a/public/stylesheets/_style_includes.less b/public/stylesheets/_style_includes.less index 7f6070e69c..39ba48d94a 100644 --- a/public/stylesheets/_style_includes.less +++ b/public/stylesheets/_style_includes.less @@ -79,6 +79,7 @@ @import "app/review-features-page.less"; @import "app/error-pages.less"; @import "app/v1-badge.less"; +@import "app/editor/history-v2.less"; // Vendor CSS @import "../js/libs/pdfListView/TextLayer.css"; diff --git a/public/stylesheets/app/editor/history-v2.less b/public/stylesheets/app/editor/history-v2.less new file mode 100644 index 0000000000..426ac70232 --- /dev/null +++ b/public/stylesheets/app/editor/history-v2.less @@ -0,0 +1,384 @@ +.history-entries { + font-size: @history-base-font-size; + color: @history-base-color; + height: 100%; + background-color: @history-base-bg; +} + +.history-entry-day { + display: block; + background-color: @history-entry-day-bg; + color: #FFF; + padding: 5px 10px; + line-height: 1; +} + +.history-entry-details { + background-color: #FFF; + margin-bottom: 2px; + padding: 5px 10px; +} + .history-entry-changes { + .list-unstyled; + margin-bottom: 3px; + } + .history-entry-change { + display: flex; + } + .history-entry-change-action { + margin-right: 0.5em; + } + + .history-entry-change-doc { + color: @history-highlight-color; + font-weight: bold; + word-break: break-all; + } + .history-entry-metadata { + + } + .history-entry-metadata-time { + + } + + .history-entry-metadata-users { + display: inline; + padding: 0; + } + .history-entry-metadata-user { + display: inline; + &::after { + content: ', '; + } + &:last-of-type::after { + content: none; + } + } + +// @changesListWidth: 250px; +// @changesListPadding: @line-height-computed / 2; + +// @selector-padding-vertical: 10px; +// @selector-padding-horizontal: @line-height-computed / 2; +// @day-header-height: 24px; + +// @range-bar-color: @link-color; +// @range-bar-selected-offset: 14px; + +// #history { +// .upgrade-prompt { +// position: absolute; +// top: 0; +// bottom: 0; +// left: 0; +// right: 0; +// z-index: 100; +// background-color: rgba(128,128,128,0.4); +// .message { +// margin: auto; +// margin-top: 100px; +// padding: (@line-height-computed / 2) @line-height-computed; +// width: 400px; +// background-color: white; +// border-radius: 8px; +// } +// .message-wider { +// width: 650px; +// margin-top: 60px; +// padding: 0; +// } + +// .message-header { +// .modal-header; +// } + +// .message-body { +// .modal-body; +// } +// } + +// .diff-panel { +// .full-size; +// margin-right: @changesListWidth; +// } + +// .diff { +// .full-size; +// .toolbar { +// padding: 3px; +// .name { +// float: left; +// padding: 3px @line-height-computed / 4; +// display: inline-block; +// } +// } +// .diff-editor { +// .full-size; +// top: 40px; +// } +// .hide-ace-cursor { +// .ace_active-line, .ace_cursor-layer, .ace_gutter-active-line { +// display: none; +// } +// } +// .diff-deleted { +// padding: @line-height-computed; +// } +// .deleted-warning { +// background-color: @brand-danger; +// color: white; +// padding: @line-height-computed / 2; +// margin-right: @line-height-computed / 4; +// } +// &-binary { +// .alert { +// margin: @line-height-computed / 2; +// } +// } +// } + +// aside.change-list { +// border-left: 1px solid @editor-border-color; +// height: 100%; +// width: @changesListWidth; +// position: absolute; +// right: 0; + +// .loading { +// text-align: center; +// font-family: @font-family-serif; +// } + +// ul { +// li.change { +// position: relative; +// user-select: none; +// -ms-user-select: none; +// -moz-user-select: none; +// -webkit-user-select: none; + +// .day { +// background-color: #fafafa; +// border-bottom: 1px solid @editor-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 @editor-border-color; +// cursor: pointer; +// &:hover { +// background-color: @gray-lightest; +// } +// } +// .users { +// .user { +// font-size: 0.8rem; +// color: @gray; +// text-transform: capitalize; +// position: relative; +// padding-left: 16px; +// .color-square { +// height: 12px; +// width: 12px; +// border-radius: 3px; +// position: absolute; +// left: 0; +// bottom: 3px; +// } +// .name { +// width: 94%; +// white-space: nowrap; +// overflow: hidden; +// text-overflow: ellipsis; +// } +// } +// } +// .time { +// float: right; +// color: @gray; +// display: inline-block; +// padding-right: (@line-height-computed / 2); +// font-size: 0.8rem; +// line-height: @line-height-computed; +// } +// .doc { +// font-size: 0.9rem; +// font-weight: bold; +// } +// .action { +// color: @gray; +// text-transform: uppercase; +// font-size: 0.7em; +// margin-bottom: -2px; +// margin-top: 2px; +// &-edited { +// margin-top: 0; +// } +// } +// } +// li.loading-changes, li.empty-message { +// padding: 6px; +// cursor: default; +// &:hover { +// background-color: inherit; +// } +// } +// li.selected { +// border-left: 4px solid @range-bar-color; +// .day { +// padding-left: 0; +// } +// .description { +// padding-left: 34px; +// } +// .selectors { +// left: @selector-padding-horizontal - 4px; +// .range { +// background-color: @range-bar-color; +// } +// } +// } +// li.selected-to { +// .selectors { +// .range { +// top: @range-bar-selected-offset; +// } +// .selector-to { +// opacity: 1; +// } +// } +// } +// li.selected-from { +// .selectors { +// .range { +// bottom: @range-bar-selected-offset; +// } +// .selector-from { +// opacity: 1; +// } +// } +// } +// li.first-in-day { +// .selectors { +// .selector-to { +// top: @day-header-height + @selector-padding-vertical; +// } +// } +// } +// li.first-in-day.selected-to { +// .selectors { +// .range { +// top: @day-header-height + @range-bar-selected-offset; +// } +// } +// } +// } +// ul.hover-state { +// li { +// .selectors { +// .range { +// background-color: transparent; +// top: 0; +// bottom: 0; +// } +// } +// } +// li.hover-selected { +// .selectors { +// .range { +// top: 0; +// background-color: @gray-light; +// } +// } +// } +// li.hover-selected-to { +// .selectors { +// .range { +// top: @range-bar-selected-offset; +// } +// .selector-to { +// opacity: 1; +// } +// } +// } +// li.hover-selected-from { +// .selectors { +// .range { +// bottom: @range-bar-selected-offset; +// } +// .selector-from { +// opacity: 1; +// } +// } +// } +// li.first-in-day.hover-selected-to { +// .selectors { +// .range { +// top: @day-header-height + @range-bar-selected-offset; +// } +// } +// } +// } +// } +// } + +// .diff-deleted { +// padding-top: 15px; +// } + +// .editor-dark { +// #history { +// aside.change-list { +// border-color: @editor-dark-toolbar-border-color; + +// ul li.change { +// .day { +// background-color: darken(@editor-dark-background-color, 10%); +// border-bottom: 1px solid @editor-dark-toolbar-border-color; +// } +// .description { +// border-bottom: 1px solid @editor-dark-toolbar-border-color; +// &:hover { +// background-color: black; +// } +// } +// } +// } +// } +// } diff --git a/public/stylesheets/core/_common-variables.less b/public/stylesheets/core/_common-variables.less index 9cb074c754..3c1f6b34b2 100644 --- a/public/stylesheets/core/_common-variables.less +++ b/public/stylesheets/core/_common-variables.less @@ -972,4 +972,11 @@ // System messages @sys-msg-background : @state-warning-bg; @sys-msg-color : #333; -@sys-msg-border : 1px solid @common-border-color; \ No newline at end of file +@sys-msg-border : 1px solid @common-border-color; + +// v2 History +@history-base-font-size : @font-size-small; +@history-base-bg : @gray-lightest; +@history-entry-day-bg : @gray-dark; +@history-base-color : @gray-light; +@history-highlight-color : @gray; \ No newline at end of file diff --git a/public/stylesheets/core/ol-variables.less b/public/stylesheets/core/ol-variables.less index e9125e0143..76b89d9fb5 100644 --- a/public/stylesheets/core/ol-variables.less +++ b/public/stylesheets/core/ol-variables.less @@ -265,6 +265,14 @@ @log-line-no-color : #FFF; @log-hints-color : @ol-blue-gray-4; + +// v2 History +@history-base-font-size : @font-size-small; +@history-base-bg : @ol-blue-gray-1; +@history-entry-day-bg : @ol-blue-gray-2; +@history-base-color : @ol-blue-gray-2; +@history-highlight-color : @ol-type-color; + // System messages @sys-msg-background : @ol-blue; @sys-msg-color : #FFF; From f4f30d939901032618fa006881952b3ec1069c95 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Tue, 1 May 2018 17:27:51 +0100 Subject: [PATCH 03/19] Add custom styling; add code to handle point-in-time selection. --- .../project/editor/history/entriesListV2.pug | 18 +++-- .../ide/history/HistoryV2Manager.coffee | 37 +++++++-- .../components/historyEntriesList.coffee | 3 +- .../history/components/historyEntry.coffee | 1 + .../HistoryV2ListController.coffee | 81 ++++++++++--------- .../ide/history/util/HistoryViewModes.coffee | 4 + public/stylesheets/app/editor/history-v2.less | 9 +++ .../stylesheets/core/_common-variables.less | 11 +-- public/stylesheets/core/ol-variables.less | 11 +-- 9 files changed, 110 insertions(+), 65 deletions(-) create mode 100644 public/coffee/ide/history/util/HistoryViewModes.coffee diff --git a/app/views/project/editor/history/entriesListV2.pug b/app/views/project/editor/history/entriesListV2.pug index a19273bfb9..746beb67f1 100644 --- a/app/views/project/editor/history/entriesListV2.pug +++ b/app/views/project/editor/history/entriesListV2.pug @@ -9,6 +9,7 @@ aside.change-list( load-disabled="history.loading || history.atEnd" load-initialize="ui.view == 'history'" is-loading="history.loading" + on-entry-select="handleEntrySelect(selectedEntry)" ) @@ -23,6 +24,7 @@ script(type="text/ng-template", id="historyEntriesListTpl") ng-repeat="entry in $ctrl.entries" entry="entry" current-user="$ctrl.currentUser" + on-select="$ctrl.onEntrySelect({ selectedEntry: selectedEntry })" ) .loading(ng-show="history.loading") i.fa.fa-spin.fa-refresh @@ -31,13 +33,13 @@ script(type="text/ng-template", id="historyEntriesListTpl") script(type="text/ng-template", id="historyEntryTpl") .history-entry( ng-class="{\ - 'first-in-day': $ctrl.entry.meta.first_in_day,\ - 'selected': $ctrl.entry.inSelection,\ - 'selected-to': $ctrl.entry.selectedTo,\ - 'selected-from': $ctrl.entry.selectedFrom,\ - 'hover-selected': $ctrl.entry.inHoverSelection,\ - 'hover-selected-to': $ctrl.entry.hoverSelectedTo,\ - 'hover-selected-from': $ctrl.entry.hoverSelectedFrom,\ + 'history-entry-first-in-day': $ctrl.entry.meta.first_in_day,\ + 'history-entry-selected': $ctrl.entry.inSelection,\ + 'history-entry-selected-to': $ctrl.entry.selectedTo,\ + 'history-entry-selected-from': $ctrl.entry.selectedFrom,\ + 'history-entry-hover-selected': $ctrl.entry.inHoverSelection,\ + 'history-entry-hover-selected-to': $ctrl.entry.hoverSelectedTo,\ + 'history-entry-hover-selected-from': $ctrl.entry.hoverSelectedFrom,\ }" ) @@ -66,7 +68,7 @@ script(type="text/ng-template", id="historyEntryTpl") //- ng-show="$ctrl.entry.beforeSelection || $ctrl.entry.inSelection" ) - .history-entry-details(ng-click="select()") + .history-entry-details(ng-click="$ctrl.onSelect({ selectedEntry: $ctrl.entry })") ol.history-entry-changes li.history-entry-change( ng-repeat="pathname in ::$ctrl.entry.pathnames" diff --git a/public/coffee/ide/history/HistoryV2Manager.coffee b/public/coffee/ide/history/HistoryV2Manager.coffee index c2c75a0373..16861d5848 100644 --- a/public/coffee/ide/history/HistoryV2Manager.coffee +++ b/public/coffee/ide/history/HistoryV2Manager.coffee @@ -2,12 +2,13 @@ define [ "moment" "ide/colors/ColorManager" "ide/history/util/displayNameForUser" + "ide/history/util/HistoryViewModes" "ide/history/controllers/HistoryListController" "ide/history/controllers/HistoryDiffController" "ide/history/directives/infiniteScroll" "ide/history/components/historyEntriesList" "ide/history/components/historyEntry" -], (moment, ColorManager, displayNameForUser) -> +], (moment, ColorManager, displayNameForUser, HistoryViewModes) -> class HistoryManager constructor: (@ide, @$scope) -> @reset() @@ -18,13 +19,13 @@ define [ else @show() - @$scope.$watch "history.selection.updates", (updates) => - if updates? and updates.length > 0 - @_selectDocFromUpdates() - @reloadDiff() + # @$scope.$watch "history.selection.updates", (updates) => + # if updates? and updates.length > 0 + # @_selectDocFromUpdates() + # @reloadDiff() - @$scope.$watch "history.selection.pathname", () => - @reloadDiff() + # @$scope.$watch "history.selection.pathname", () => + # @reloadDiff() show: () -> @$scope.ui.view = "history" @@ -37,6 +38,7 @@ define [ @$scope.history = { isV2: true updates: [] + viewMode: HistoryViewModes.POINT_IN_TIME nextBeforeTimestamp: null atEnd: false selection: { @@ -72,6 +74,21 @@ define [ @$scope.history.updates[indexOfLastUpdateNotByMe].selectedFrom = true + autoSelectLastUpdate: () -> + return if @$scope.history.updates.length == 0 + @$scope.history.updates[0].selectedTo = true + @$scope.history.updates[0].selectedFrom = true + + selectUpdate: (update) -> + selectedUpdateIndex = @$scope.history.updates.indexOf update + if selectedUpdateIndex == -1 + selectedUpdateIndex = 0 + for update in @$scope.history.updates + update.selectedTo = false + update.selectedFrom = false + @$scope.history.updates[selectedUpdateIndex].selectedTo = true + @$scope.history.updates[selectedUpdateIndex].selectedFrom = true + BATCH_SIZE: 10 fetchNextBatchOfUpdates: () -> url = "/project/#{@ide.project_id}/updates?min_count=#{@BATCH_SIZE}" @@ -202,7 +219,11 @@ define [ @$scope.history.updates = @$scope.history.updates.concat(updates) - @autoSelectRecentUpdates() if firstLoad + if firstLoad + if @$scope.history.viewMode == HistoryViewModes.COMPARE + @autoSelectRecentUpdates() + else + @autoSelectLastUpdate() _perDocSummaryOfUpdates: (updates) -> # Track current_pathname -> original_pathname diff --git a/public/coffee/ide/history/components/historyEntriesList.coffee b/public/coffee/ide/history/components/historyEntriesList.coffee index 8eabf38ebc..5022724714 100644 --- a/public/coffee/ide/history/components/historyEntriesList.coffee +++ b/public/coffee/ide/history/components/historyEntriesList.coffee @@ -2,7 +2,7 @@ define [ "base" ], (App) -> historyEntriesListController = ($scope, $element, $attrs) -> - ctrl = @ + ctrl = @ return App.component "historyEntriesList", { @@ -13,6 +13,7 @@ define [ loadInitialize: "<" isLoading: "<" currentUser: "<" + onEntrySelect: "&" controller: historyEntriesListController templateUrl: "historyEntriesListTpl" } diff --git a/public/coffee/ide/history/components/historyEntry.coffee b/public/coffee/ide/history/components/historyEntry.coffee index dbc63a105b..90b607a628 100644 --- a/public/coffee/ide/history/components/historyEntry.coffee +++ b/public/coffee/ide/history/components/historyEntry.coffee @@ -19,6 +19,7 @@ define [ bindings: entry: "<" currentUser: "<" + onSelect: "&" controller: historyEntryController templateUrl: "historyEntryTpl" } \ No newline at end of file diff --git a/public/coffee/ide/history/controllers/HistoryV2ListController.coffee b/public/coffee/ide/history/controllers/HistoryV2ListController.coffee index 772f360a80..4ea91d7cc8 100644 --- a/public/coffee/ide/history/controllers/HistoryV2ListController.coffee +++ b/public/coffee/ide/history/controllers/HistoryV2ListController.coffee @@ -9,6 +9,11 @@ define [ $scope.loadMore = () => ide.historyManager.fetchNextBatchOfUpdates() + $scope.handleEntrySelect = (entry) -> + # $scope.$applyAsync () -> + ide.historyManager.selectUpdate(entry) + $scope.recalculateSelectedUpdates() + $scope.recalculateSelectedUpdates = () -> beforeSelection = true afterSelection = false @@ -70,41 +75,41 @@ define [ $scope.recalculateSelectedUpdates() ] - App.controller "HistoryListItemController", ["$scope", "event_tracking", ($scope, event_tracking) -> - $scope.$watch "update.selectedFrom", (selectedFrom, oldSelectedFrom) -> - if selectedFrom - for update in $scope.history.updates - update.selectedFrom = false unless update == $scope.update - $scope.recalculateSelectedUpdates() - - $scope.$watch "update.selectedTo", (selectedTo, oldSelectedTo) -> - if selectedTo - for update in $scope.history.updates - update.selectedTo = false unless update == $scope.update - $scope.recalculateSelectedUpdates() - - $scope.select = () -> - event_tracking.sendMB "history-view-change" - $scope.update.selectedTo = true - $scope.update.selectedFrom = true - - $scope.mouseOverSelectedFrom = () -> - $scope.history.hoveringOverListSelectors = true - $scope.update.hoverSelectedFrom = true - $scope.recalculateHoveredUpdates() - - $scope.mouseOutSelectedFrom = () -> - $scope.history.hoveringOverListSelectors = false - $scope.resetHoverState() - - $scope.mouseOverSelectedTo = () -> - $scope.history.hoveringOverListSelectors = true - $scope.update.hoverSelectedTo = true - $scope.recalculateHoveredUpdates() - - $scope.mouseOutSelectedTo = () -> - $scope.history.hoveringOverListSelectors = false - $scope.resetHoverState() - - $scope.displayName = displayNameForUser - ] + # App.controller "HistoryListItemController", ["$scope", "event_tracking", ($scope, event_tracking) -> + # $scope.$watch "update.selectedFrom", (selectedFrom, oldSelectedFrom) -> + # if selectedFrom + # for update in $scope.history.updates + # update.selectedFrom = false unless update == $scope.update + # $scope.recalculateSelectedUpdates() + + # $scope.$watch "update.selectedTo", (selectedTo, oldSelectedTo) -> + # if selectedTo + # for update in $scope.history.updates + # update.selectedTo = false unless update == $scope.update + # $scope.recalculateSelectedUpdates() + + # $scope.select = () -> + # event_tracking.sendMB "history-view-change" + # $scope.update.selectedTo = true + # $scope.update.selectedFrom = true + + # $scope.mouseOverSelectedFrom = () -> + # $scope.history.hoveringOverListSelectors = true + # $scope.update.hoverSelectedFrom = true + # $scope.recalculateHoveredUpdates() + + # $scope.mouseOutSelectedFrom = () -> + # $scope.history.hoveringOverListSelectors = false + # $scope.resetHoverState() + + # $scope.mouseOverSelectedTo = () -> + # $scope.history.hoveringOverListSelectors = true + # $scope.update.hoverSelectedTo = true + # $scope.recalculateHoveredUpdates() + + # $scope.mouseOutSelectedTo = () -> + # $scope.history.hoveringOverListSelectors = false + # $scope.resetHoverState() + + # $scope.displayName = displayNameForUser + # ] diff --git a/public/coffee/ide/history/util/HistoryViewModes.coffee b/public/coffee/ide/history/util/HistoryViewModes.coffee new file mode 100644 index 0000000000..125dd87060 --- /dev/null +++ b/public/coffee/ide/history/util/HistoryViewModes.coffee @@ -0,0 +1,4 @@ +define [], () -> + HistoryViewModes = + POINT_IN_TIME : 'point_in_time' + COMPARE : 'compare' diff --git a/public/stylesheets/app/editor/history-v2.less b/public/stylesheets/app/editor/history-v2.less index 426ac70232..6232caf180 100644 --- a/public/stylesheets/app/editor/history-v2.less +++ b/public/stylesheets/app/editor/history-v2.less @@ -17,6 +17,12 @@ background-color: #FFF; margin-bottom: 2px; padding: 5px 10px; + cursor: pointer; + + .history-entry-selected & { + background-color: @history-entry-selected-bg; + color: #FFF; + } } .history-entry-changes { .list-unstyled; @@ -33,6 +39,9 @@ color: @history-highlight-color; font-weight: bold; word-break: break-all; + .history-entry-selected & { + color: #FFF; + } } .history-entry-metadata { diff --git a/public/stylesheets/core/_common-variables.less b/public/stylesheets/core/_common-variables.less index 3c1f6b34b2..3afb428692 100644 --- a/public/stylesheets/core/_common-variables.less +++ b/public/stylesheets/core/_common-variables.less @@ -975,8 +975,9 @@ @sys-msg-border : 1px solid @common-border-color; // v2 History -@history-base-font-size : @font-size-small; -@history-base-bg : @gray-lightest; -@history-entry-day-bg : @gray-dark; -@history-base-color : @gray-light; -@history-highlight-color : @gray; \ No newline at end of file +@history-base-font-size : @font-size-small; +@history-base-bg : @gray-lightest; +@history-entry-day-bg : @gray-dark; +@history-entry-selected-bg : @red; +@history-base-color : @gray-light; +@history-highlight-color : @gray; \ No newline at end of file diff --git a/public/stylesheets/core/ol-variables.less b/public/stylesheets/core/ol-variables.less index 76b89d9fb5..cd5b035fc4 100644 --- a/public/stylesheets/core/ol-variables.less +++ b/public/stylesheets/core/ol-variables.less @@ -267,11 +267,12 @@ // v2 History -@history-base-font-size : @font-size-small; -@history-base-bg : @ol-blue-gray-1; -@history-entry-day-bg : @ol-blue-gray-2; -@history-base-color : @ol-blue-gray-2; -@history-highlight-color : @ol-type-color; +@history-base-font-size : @font-size-small; +@history-base-bg : @ol-blue-gray-1; +@history-entry-day-bg : @ol-blue-gray-2; +@history-entry-selected-bg : @ol-green; +@history-base-color : @ol-blue-gray-2; +@history-highlight-color : @ol-type-color; // System messages @sys-msg-background : @ol-blue; From 9911534b73f3bda02f1d4547ce8927d14e813555 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Mon, 21 May 2018 15:10:46 +0100 Subject: [PATCH 04/19] Proxy history filetree requests through web. --- app/coffee/router.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/app/coffee/router.coffee b/app/coffee/router.coffee index 7ec4dafbf4..38e3f8ea57 100644 --- a/app/coffee/router.coffee +++ b/app/coffee/router.coffee @@ -200,6 +200,7 @@ module.exports = class Router webRouter.get "/project/:Project_id/updates", AuthorizationMiddlewear.ensureUserCanReadProject, HistoryController.selectHistoryApi, HistoryController.proxyToHistoryApiAndInjectUserDetails webRouter.get "/project/:Project_id/doc/:doc_id/diff", AuthorizationMiddlewear.ensureUserCanReadProject, HistoryController.selectHistoryApi, HistoryController.proxyToHistoryApi webRouter.get "/project/:Project_id/diff", AuthorizationMiddlewear.ensureUserCanReadProject, HistoryController.selectHistoryApi, HistoryController.proxyToHistoryApiAndInjectUserDetails + webRouter.get "/project/:Project_id/filetree/diff", AuthorizationMiddlewear.ensureUserCanReadProject, HistoryController.selectHistoryApi, HistoryController.proxyToHistoryApi webRouter.post "/project/:Project_id/doc/:doc_id/version/:version_id/restore", AuthorizationMiddlewear.ensureUserCanReadProject, HistoryController.selectHistoryApi, HistoryController.proxyToHistoryApi webRouter.post '/project/:project_id/doc/:doc_id/restore', AuthorizationMiddlewear.ensureUserCanWriteProjectContent, HistoryController.restoreDocFromDeletedDoc webRouter.post "/project/:project_id/restore_file", AuthorizationMiddlewear.ensureUserCanWriteProjectContent, HistoryController.restoreFileFromV2 From 405d0a674d63994aab1b1f5cdfd40ad1291a8b93 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Mon, 21 May 2018 15:12:03 +0100 Subject: [PATCH 05/19] Add history file tree components. --- .../history/components/historyEntry.coffee | 6 ++++ .../components/historyFileEntity.coffee | 34 +++++++++++++++++++ .../history/components/historyFileTree.coffee | 17 ++++++++++ 3 files changed, 57 insertions(+) create mode 100644 public/coffee/ide/history/components/historyFileEntity.coffee create mode 100644 public/coffee/ide/history/components/historyFileTree.coffee diff --git a/public/coffee/ide/history/components/historyEntry.coffee b/public/coffee/ide/history/components/historyEntry.coffee index 90b607a628..53824c1317 100644 --- a/public/coffee/ide/history/components/historyEntry.coffee +++ b/public/coffee/ide/history/components/historyEntry.coffee @@ -13,6 +13,12 @@ define [ if projectOp.rename? then "#{ projectOp.rename.pathname} → #{ projectOp.rename.newPathname }" else if projectOp.add? then "#{ projectOp.add.pathname}" else if projectOp.remove? then "#{ projectOp.remove.pathname}" + ctrl.getUserCSSStyle = (user) -> + hue = user?.hue or 100 + if ctrl.entry.inSelection + color : "#FFF" + else + color: "hsl(#{ hue }, 70%, 50%)" return App.component "historyEntry", { diff --git a/public/coffee/ide/history/components/historyFileEntity.coffee b/public/coffee/ide/history/components/historyFileEntity.coffee new file mode 100644 index 0000000000..bf99348c62 --- /dev/null +++ b/public/coffee/ide/history/components/historyFileEntity.coffee @@ -0,0 +1,34 @@ +define [ + "base" + "ide/file-tree/util/iconTypeFromName" +], (App, iconTypeFromName) -> + # TODO Add arrows in folders + historyFileEntityController = ($scope, $element, $attrs) -> + ctrl = @ + _handleFolderClick = () -> + ctrl.isOpen = !ctrl.isOpen + ctrl.iconClass = _getFolderIcon() + _handleFileClick = () -> + ctrl.historyFileTreeController.handleEntityClick ctrl.fileEntity + _getFolderIcon = () -> + if ctrl.isOpen then "fa-folder-open" else "fa-folder" + ctrl.$onInit = () -> + if ctrl.fileEntity.type == "folder" + ctrl.isOpen = true + ctrl.iconClass = _getFolderIcon() + ctrl.handleClick = _handleFolderClick + else + ctrl.iconClass = "fa-#{ iconTypeFromName(ctrl.fileEntity.name) }" + ctrl.handleClick = _handleFileClick + $scope.$watch (() -> ctrl.historyFileTreeController.selectedPathname), (newPathname) -> + ctrl.isSelected = ctrl.fileEntity.pathname == newPathname + return + + App.component "historyFileEntity", { + require: + historyFileTreeController: "^historyFileTree" + bindings: + fileEntity: "<" + controller: historyFileEntityController + templateUrl: "historyFileEntityTpl" + } \ No newline at end of file diff --git a/public/coffee/ide/history/components/historyFileTree.coffee b/public/coffee/ide/history/components/historyFileTree.coffee new file mode 100644 index 0000000000..e8daf13af9 --- /dev/null +++ b/public/coffee/ide/history/components/historyFileTree.coffee @@ -0,0 +1,17 @@ +define [ + "base" +], (App) -> + historyFileTreeController = ($scope, $element, $attrs) -> + ctrl = @ + ctrl.handleEntityClick = (file) -> + ctrl.onSelectedFileChange file: file + return + + App.component "historyFileTree", { + bindings: + fileTree: "<" + selectedPathname: "<" + onSelectedFileChange: "&" + controller: historyFileTreeController + templateUrl: "historyFileTreeTpl" + } \ No newline at end of file From 419b1b188a0487fd7406338521b1a2264a050797 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Mon, 21 May 2018 15:12:47 +0100 Subject: [PATCH 06/19] Integrate history file tree in the UI. --- .../file-tree/util/iconTypeFromName.coffee | 13 ++++++ .../HistoryV2FileTreeController.coffee | 45 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 public/coffee/ide/file-tree/util/iconTypeFromName.coffee create mode 100644 public/coffee/ide/history/controllers/HistoryV2FileTreeController.coffee diff --git a/public/coffee/ide/file-tree/util/iconTypeFromName.coffee b/public/coffee/ide/file-tree/util/iconTypeFromName.coffee new file mode 100644 index 0000000000..01c11f395a --- /dev/null +++ b/public/coffee/ide/file-tree/util/iconTypeFromName.coffee @@ -0,0 +1,13 @@ +define [], () -> + return iconTypeFromName = (name) -> + ext = name.split(".").pop()?.toLowerCase() + if ext in ["png", "pdf", "jpg", "jpeg", "gif"] + return "image" + else if ext in ["csv", "xls", "xlsx"] + return "table" + else if ext in ["py", "r"] + return "file-text" + else if ext in ['bib'] + return 'book' + else + return "file" \ No newline at end of file diff --git a/public/coffee/ide/history/controllers/HistoryV2FileTreeController.coffee b/public/coffee/ide/history/controllers/HistoryV2FileTreeController.coffee new file mode 100644 index 0000000000..fc9caaa6e4 --- /dev/null +++ b/public/coffee/ide/history/controllers/HistoryV2FileTreeController.coffee @@ -0,0 +1,45 @@ +define [ + "base" +], (App) -> + + App.controller "HistoryV2FileTreeController", ["$scope", "ide", "_", ($scope, ide, _) -> + $scope.currentFileTree = [] + _selectedDefaultPathname = (files) -> + # TODO: Improve heuristic to determine the default pathname to show. + if files? and files.length > 0 + mainFile = files.find (file) -> /main\.tex$/.test file.pathname + if mainFile? + mainFile.pathname + else + files[0].pathname + + $scope.handleFileSelection = (file) -> + $scope.history.selection.pathname = file.pathname + + $scope.$watch 'history.files', (files) -> + $scope.currentFileTree = _.reduce files, reducePathsToTree, [] + $scope.history.selection.pathname = _selectedDefaultPathname(files) + + reducePathsToTree = (currentFileTree, fileObject) -> + filePathParts = fileObject.pathname.split "/" + currentFileTreeLocation = currentFileTree + for pathPart, index in filePathParts + isFile = index == filePathParts.length - 1 + if isFile + fileTreeEntity = + name: pathPart + pathname: fileObject.pathname + type: "file" + operation: fileObject.operation || "edited" + currentFileTreeLocation.push fileTreeEntity + else + fileTreeEntity = _.find currentFileTreeLocation, (entity) => entity.name == pathPart + if !fileTreeEntity? + fileTreeEntity = + name: pathPart + type: "folder" + children: [] + currentFileTreeLocation.push fileTreeEntity + currentFileTreeLocation = fileTreeEntity.children + return currentFileTree + ] \ No newline at end of file From 19398f562544b2b112841c7edbf03835913f2937 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Mon, 21 May 2018 15:13:16 +0100 Subject: [PATCH 07/19] History file tree styles. --- public/stylesheets/app/editor/history-v2.less | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/public/stylesheets/app/editor/history-v2.less b/public/stylesheets/app/editor/history-v2.less index 6232caf180..4741399007 100644 --- a/public/stylesheets/app/editor/history-v2.less +++ b/public/stylesheets/app/editor/history-v2.less @@ -64,6 +64,55 @@ } } +.history-file-tree { +} + .history-file-entity-wrapper { + color: #FFF; + margin-left: (@line-height-computed / 2); + } + .history-file-entity-link { + display: block; + position: relative; + color: @file-tree-item-color; + line-height: @file-tree-line-height; + &:hover { + background-color: @file-tree-item-hover-bg; + color: @file-tree-item-color; + text-decoration: none; + } + &:focus { + color: @file-tree-item-color; + outline: none; + text-decoration: none; + } + &:hover when (@is-overleaf = true) { + .fake-full-width-bg(@file-tree-item-hover-bg); + } + } + .history-file-entity-link-selected { + background-color: @file-tree-item-selected-bg; + font-weight: bold; + padding-right: 32px; + .fake-full-width-bg(@file-tree-item-selected-bg); + &:hover { + background-color: @file-tree-item-hover-bg; + } + } + .history-file-entity-icon { + color: @file-tree-item-icon-color; + font-size: 14px; + margin-right: .5em; + .history-file-entity-link-selected & { + color: #FFF; + } + } + .history-file-entity-name { + display: block; + max-width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } // @changesListWidth: 250px; // @changesListPadding: @line-height-computed / 2; From 7210f5cd459a2e585a9fa71e255fe58c6d585524 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Mon, 21 May 2018 15:13:34 +0100 Subject: [PATCH 08/19] History file tree integration with the backend. --- .../project/editor/history-file-tree.pug | 53 ++++++++++++++----- .../project/editor/history/entriesListV2.pug | 9 ++-- .../FileTreeEntityController.coffee | 16 ++---- .../coffee/ide/history/HistoryManager.coffee | 2 - .../ide/history/HistoryV2Manager.coffee | 40 ++++++++++++-- .../controllers/HistoryListController.coffee | 2 +- .../HistoryV2ListController.coffee | 2 +- 7 files changed, 85 insertions(+), 39 deletions(-) diff --git a/app/views/project/editor/history-file-tree.pug b/app/views/project/editor/history-file-tree.pug index 3356dc2249..fd6dc7c205 100644 --- a/app/views/project/editor/history-file-tree.pug +++ b/app/views/project/editor/history-file-tree.pug @@ -1,17 +1,46 @@ -aside.file-tree.file-tree-history(ng-controller="FileTreeController", ng-class="{ 'multi-selected': multiSelectedCount > 0 }", ng-show="ui.view == 'history' && history.isV2").full-size +aside.file-tree.file-tree-history.full-size( + ng-controller="HistoryV2FileTreeController" + ng-if="ui.view == 'history' && history.isV2" +) .toolbar.toolbar-filetree span Modified files .file-tree-inner - ul.list-unstyled.file-tree-list - li( - ng-repeat="(pathname, doc) in history.selection.docs" - ng-class="{ 'selected': history.selection.pathname == pathname }" + history-file-tree( + file-tree="currentFileTree" + selected-pathname="history.selection.pathname" + on-selected-file-change="handleFileSelection(file)" + ) + +script(type="text/ng-template", id="historyFileTreeTpl") + .history-file-tree + history-file-entity( + ng-repeat="fileEntity in $ctrl.fileTree" + file-entity="fileEntity" + ) + +script(type="text/ng-template", id="historyFileEntityTpl") + .history-file-entity-wrapper + a.history-file-entity-link( + href + ng-click="$ctrl.handleClick()" + ng-class="{ 'history-file-entity-link-selected': $ctrl.isSelected }" + ) + span.history-file-entity-name + i.history-file-entity-icon.history-file-entity-icon-folder-state.fa.fa-fw( + ng-class="{\ + 'fa-chevron-down': ($ctrl.fileEntity.type === 'folder' && $ctrl.isOpen),\ + 'fa-chevron-right': ($ctrl.fileEntity.type === 'folder' && !$ctrl.isOpen)\ + }" + ) + i.history-file-entity-icon.fa( + ng-class="$ctrl.iconClass" + ) + | {{ ::$ctrl.fileEntity.name }} + div( + ng-show="$ctrl.isOpen" + ) + history-file-entity( + ng-repeat="childEntity in $ctrl.fileEntity.children" + file-entity="childEntity" ) - .entity - .entity-name.entity-name-history( - ng-click="history.selection.pathname = pathname", - ng-class="{ 'deleted': !!doc.deletedAtV }" - ) - i.fa.fa-fw.fa-pencil - span {{ pathname }} diff --git a/app/views/project/editor/history/entriesListV2.pug b/app/views/project/editor/history/entriesListV2.pug index 746beb67f1..2414deb5eb 100644 --- a/app/views/project/editor/history/entriesListV2.pug +++ b/app/views/project/editor/history/entriesListV2.pug @@ -12,7 +12,6 @@ aside.change-list( on-entry-select="handleEntrySelect(selectedEntry)" ) - script(type="text/ng-template", id="historyEntriesListTpl") .history-entries( infinite-scroll="$ctrl.loadEntries()" @@ -87,17 +86,17 @@ script(type="text/ng-template", id="historyEntryTpl") li.history-entry-metadata-user(ng-repeat="update_user in ::$ctrl.entry.meta.users") span.name( ng-if="::update_user && update_user.id != $ctrl.currentUser.id" - ng-style="::{'color': 'hsl({{ update_user.hue }}, 70%, 50%)'}" + ng-style="$ctrl.getUserCSSStyle(update_user);" ) {{ ::$ctrl.displayName(update_user) }} span.name( ng-if="::update_user && update_user.id == $ctrl.currentUser.id" - ng-style="::{'color': 'hsl({{ update_user.hue }}, 70%, 50%)'}" + ng-style="$ctrl.getUserCSSStyle(update_user);" ) You span.name( ng-if="::update_user == null" - ng-style="::{'color': 'hsl(100, 70%, 50%)'}" + ng-style="$ctrl.getUserCSSStyle(update_user);" ) #{translate("anonymous")} li.history-entry-metadata-user(ng-if="::$ctrl.entry.meta.users.length == 0") span.name( - ng-style="::{'color': 'hsl(100, 70%, 50%)'}" + ng-style="$ctrl.getUserCSSStyle();" ) #{translate("anonymous")} \ No newline at end of file diff --git a/public/coffee/ide/file-tree/controllers/FileTreeEntityController.coffee b/public/coffee/ide/file-tree/controllers/FileTreeEntityController.coffee index 735d065cd8..0dcbac31c1 100644 --- a/public/coffee/ide/file-tree/controllers/FileTreeEntityController.coffee +++ b/public/coffee/ide/file-tree/controllers/FileTreeEntityController.coffee @@ -1,6 +1,7 @@ define [ "base" -], (App) -> + "ide/file-tree/util/iconTypeFromName" +], (App, iconTypeFromName) -> App.controller "FileTreeEntityController", ["$scope", "ide", "$modal", ($scope, ide, $modal) -> $scope.select = (e) -> if e.ctrlKey or e.metaKey @@ -70,18 +71,7 @@ define [ $scope.$on "delete:selected", () -> $scope.openDeleteModal() if $scope.entity.selected - $scope.iconTypeFromName = (name) -> - ext = name.split(".").pop()?.toLowerCase() - if ext in ["png", "pdf", "jpg", "jpeg", "gif"] - return "image" - else if ext in ["csv", "xls", "xlsx"] - return "table" - else if ext in ["py", "r"] - return "file-text" - else if ext in ['bib'] - return 'book' - else - return "file" + $scope.iconTypeFromName = iconTypeFromName ] App.controller "DeleteEntityModalController", [ diff --git a/public/coffee/ide/history/HistoryManager.coffee b/public/coffee/ide/history/HistoryManager.coffee index e79f0ad116..8c77d97965 100644 --- a/public/coffee/ide/history/HistoryManager.coffee +++ b/public/coffee/ide/history/HistoryManager.coffee @@ -3,9 +3,7 @@ define [ "ide/colors/ColorManager" "ide/history/util/displayNameForUser" "ide/history/controllers/HistoryListController" - "ide/history/controllers/HistoryV2ListController" "ide/history/controllers/HistoryDiffController" - "ide/history/controllers/HistoryV2DiffController" "ide/history/directives/infiniteScroll" ], (moment, ColorManager, displayNameForUser) -> class HistoryManager diff --git a/public/coffee/ide/history/HistoryV2Manager.coffee b/public/coffee/ide/history/HistoryV2Manager.coffee index 16861d5848..7173cf5b51 100644 --- a/public/coffee/ide/history/HistoryV2Manager.coffee +++ b/public/coffee/ide/history/HistoryV2Manager.coffee @@ -3,16 +3,19 @@ define [ "ide/colors/ColorManager" "ide/history/util/displayNameForUser" "ide/history/util/HistoryViewModes" - "ide/history/controllers/HistoryListController" - "ide/history/controllers/HistoryDiffController" + "ide/history/controllers/HistoryV2ListController" + "ide/history/controllers/HistoryV2DiffController" + "ide/history/controllers/HistoryV2FileTreeController" "ide/history/directives/infiniteScroll" "ide/history/components/historyEntriesList" "ide/history/components/historyEntry" + "ide/history/components/historyFileTree" + "ide/history/components/historyFileEntity" ], (moment, ColorManager, displayNameForUser, HistoryViewModes) -> class HistoryManager constructor: (@ide, @$scope) -> @reset() - + @$scope.toggleHistory = () => if @$scope.ui.view == "history" @hide() @@ -26,6 +29,9 @@ define [ # @$scope.$watch "history.selection.pathname", () => # @reloadDiff() + @$scope.$watch "history.selection.pathname", (pathname) => + if pathname? + @loadFileAtPointInTime() show: () -> @$scope.ui.view = "history" @@ -50,16 +56,28 @@ define [ toV: null } } + files: [] diff: null } restoreFile: (version, pathname) -> url = "/project/#{@$scope.project_id}/restore_file" + @ide.$http.post(url, { version, pathname, _csrf: window.csrfToken }) + loadFileTreeForUpdate: (update) -> + {fromV, toV} = update + url = "/project/#{@$scope.project_id}/filetree/diff" + query = [ "from=#{toV}", "to=#{toV}" ] + url += "?" + query.join("&") + @ide.$http + .get(url) + .then (response) => + @$scope.history.files = response.data.diff + MAX_RECENT_UPDATES_TO_SELECT: 5 autoSelectRecentUpdates: () -> return if @$scope.history.updates.length == 0 @@ -76,8 +94,7 @@ define [ autoSelectLastUpdate: () -> return if @$scope.history.updates.length == 0 - @$scope.history.updates[0].selectedTo = true - @$scope.history.updates[0].selectedFrom = true + @selectUpdate @$scope.history.updates[0] selectUpdate: (update) -> selectedUpdateIndex = @$scope.history.updates.indexOf update @@ -88,6 +105,7 @@ define [ update.selectedFrom = false @$scope.history.updates[selectedUpdateIndex].selectedTo = true @$scope.history.updates[selectedUpdateIndex].selectedFrom = true + @loadFileTreeForUpdate @$scope.history.updates[selectedUpdateIndex] BATCH_SIZE: 10 fetchNextBatchOfUpdates: () -> @@ -105,6 +123,18 @@ define [ @$scope.history.atEnd = true @$scope.history.loading = false + loadFileAtPointInTime: () -> + pathname = @$scope.history.selection.pathname + toV = @$scope.history.selection.updates[0].toV + url = "/project/#{@$scope.project_id}/diff" + query = ["pathname=#{encodeURIComponent(pathname)}", "from=#{toV}", "to=#{toV}"] + url += "?" + query.join("&") + @ide.$http + .get(url) + .then (response) => + { data } = response + .catch () -> + reloadDiff: () -> diff = @$scope.history.diff {updates} = @$scope.history.selection diff --git a/public/coffee/ide/history/controllers/HistoryListController.coffee b/public/coffee/ide/history/controllers/HistoryListController.coffee index f16cace816..4b0786d259 100644 --- a/public/coffee/ide/history/controllers/HistoryListController.coffee +++ b/public/coffee/ide/history/controllers/HistoryListController.coffee @@ -5,7 +5,7 @@ define [ App.controller "HistoryListController", ["$scope", "ide", ($scope, ide) -> $scope.hoveringOverListSelectors = false - + $scope.loadMore = () => ide.historyManager.fetchNextBatchOfUpdates() diff --git a/public/coffee/ide/history/controllers/HistoryV2ListController.coffee b/public/coffee/ide/history/controllers/HistoryV2ListController.coffee index 4ea91d7cc8..823461d16a 100644 --- a/public/coffee/ide/history/controllers/HistoryV2ListController.coffee +++ b/public/coffee/ide/history/controllers/HistoryV2ListController.coffee @@ -5,7 +5,7 @@ define [ App.controller "HistoryV2ListController", ["$scope", "ide", ($scope, ide) -> $scope.hoveringOverListSelectors = false - + $scope.loadMore = () => ide.historyManager.fetchNextBatchOfUpdates() From 35a946e44ad4bad77ad8ab339ec3a09ff9dd0c55 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Tue, 22 May 2018 15:40:57 +0100 Subject: [PATCH 09/19] Add history toolbar (just scaffolding); show files at point in time. --- app/views/project/editor.pug | 3 +++ .../project/editor/history-file-tree.pug | 7 ++---- app/views/project/editor/history.pug | 2 +- .../{diffPanelV2.pug => previewPanelV2.pug} | 22 +++++++++++++++++-- .../project/editor/history/toolbarV2.pug | 4 ++++ .../ide/history/HistoryV2Manager.coffee | 9 +++++--- public/stylesheets/app/editor.less | 6 ++++- public/stylesheets/app/editor/history-v2.less | 19 +++++++++++++++- public/stylesheets/app/editor/history.less | 15 ++++++++----- .../stylesheets/core/_common-variables.less | 1 + 10 files changed, 69 insertions(+), 19 deletions(-) rename app/views/project/editor/history/{diffPanelV2.pug => previewPanelV2.pug} (76%) create mode 100644 app/views/project/editor/history/toolbarV2.pug diff --git a/app/views/project/editor.pug b/app/views/project/editor.pug index a9ba703a32..45600c4a8f 100644 --- a/app/views/project/editor.pug +++ b/app/views/project/editor.pug @@ -57,9 +57,12 @@ block content include ./editor/share != moduleIncludes("publish:body", locals) + include ./editor/history/toolbarV2.pug + main#ide-body( ng-cloak, role="main", + ng-class="{ 'ide-history-open' : (ui.view == 'history' && history.isV2) }", layout="main", ng-hide="state.loading", resize-on="layout:chat:resize", diff --git a/app/views/project/editor/history-file-tree.pug b/app/views/project/editor/history-file-tree.pug index fd6dc7c205..1944974ce2 100644 --- a/app/views/project/editor/history-file-tree.pug +++ b/app/views/project/editor/history-file-tree.pug @@ -1,11 +1,8 @@ -aside.file-tree.file-tree-history.full-size( +aside.file-tree.full-size( ng-controller="HistoryV2FileTreeController" ng-if="ui.view == 'history' && history.isV2" ) - .toolbar.toolbar-filetree - span Modified files - - .file-tree-inner + .history-file-tree-inner history-file-tree( file-tree="currentFileTree" selected-pathname="history.selection.pathname" diff --git a/app/views/project/editor/history.pug b/app/views/project/editor/history.pug index f237aff89e..a7a52d2927 100644 --- a/app/views/project/editor/history.pug +++ b/app/views/project/editor/history.pug @@ -44,7 +44,7 @@ div#history(ng-show="ui.view == 'history'") include ./history/entriesListV2 include ./history/diffPanelV1 - include ./history/diffPanelV2 + include ./history/previewPanelV2 script(type="text/ng-template", id="historyRestoreDiffModalTemplate") .modal-header diff --git a/app/views/project/editor/history/diffPanelV2.pug b/app/views/project/editor/history/previewPanelV2.pug similarity index 76% rename from app/views/project/editor/history/diffPanelV2.pug rename to app/views/project/editor/history/previewPanelV2.pug index 415d587155..704cc2e0a7 100644 --- a/app/views/project/editor/history/diffPanelV2.pug +++ b/app/views/project/editor/history/previewPanelV2.pug @@ -1,4 +1,7 @@ -.diff-panel.full-size(ng-if="history.isV2", ng-controller="HistoryV2DiffController") +.diff-panel.full-size( + ng-if="history.isV2 && history.viewMode === HistoryViewModes.COMPARE" + ng-controller="HistoryV2DiffController" +) .diff( ng-if="!!history.diff && !history.diff.loading && !history.diff.error", ng-class="{ 'diff-binary': history.diff.binary }" @@ -47,4 +50,19 @@ i.fa.fa-spin.fa-refresh |   #{translate("loading")}... .error-panel(ng-show="history.diff.error") - .alert.alert-danger #{translate("generic_something_went_wrong")} \ No newline at end of file + .alert.alert-danger #{translate("generic_something_went_wrong")} + +.point-in-time-panel.full-size( + ng-if="history.isV2 && history.viewMode === HistoryViewModes.POINT_IN_TIME" +) + .point-in-time-editor-container( + ng-if="!!history.selectedFile" + ) + .hide-ace-cursor( + ace-editor="history-pointintime", + theme="settings.theme", + font-size="settings.fontSize", + text="history.selectedFile.text", + read-only="true", + resize-on="layout:main:resize", + ) \ No newline at end of file diff --git a/app/views/project/editor/history/toolbarV2.pug b/app/views/project/editor/history/toolbarV2.pug new file mode 100644 index 0000000000..a66fab3ee3 --- /dev/null +++ b/app/views/project/editor/history/toolbarV2.pug @@ -0,0 +1,4 @@ +.history-toolbar( + ng-if="ui.view == 'history' && history.isV2" +) Browsing project as of  + time.history-toolbar-time {{ history.selection.updates[0].meta.end_ts | formatDate:'Do MMM YYYY, h:mm a' }} \ No newline at end of file diff --git a/public/coffee/ide/history/HistoryV2Manager.coffee b/public/coffee/ide/history/HistoryV2Manager.coffee index 7173cf5b51..aac9c11367 100644 --- a/public/coffee/ide/history/HistoryV2Manager.coffee +++ b/public/coffee/ide/history/HistoryV2Manager.coffee @@ -15,7 +15,8 @@ define [ class HistoryManager constructor: (@ide, @$scope) -> @reset() - + @$scope.HistoryViewModes = HistoryViewModes + @$scope.toggleHistory = () => if @$scope.ui.view == "history" @hide() @@ -57,7 +58,8 @@ define [ } } files: [] - diff: null + diff: null # When history.viewMode == HistoryViewModes.COMPARE + selectedFile: null # When history.viewMode == HistoryViewModes.POINT_IN_TIME } restoreFile: (version, pathname) -> @@ -132,7 +134,8 @@ define [ @ide.$http .get(url) .then (response) => - { data } = response + @$scope.history.selectedFile = + text : response.data.diff[0].u .catch () -> reloadDiff: () -> diff --git a/public/stylesheets/app/editor.less b/public/stylesheets/app/editor.less index 46a35c440f..8b07bd9263 100644 --- a/public/stylesheets/app/editor.less +++ b/public/stylesheets/app/editor.less @@ -73,9 +73,13 @@ #ide-body { .full-size; - top: 40px; + top: @ide-body-top-offset; + &.ide-history-open { + top: @ide-body-top-offset + @editor-toolbar-height; + } } + #editor, #editor-rich-text { .full-size; } diff --git a/public/stylesheets/app/editor/history-v2.less b/public/stylesheets/app/editor/history-v2.less index 4741399007..9ff03e55f5 100644 --- a/public/stylesheets/app/editor/history-v2.less +++ b/public/stylesheets/app/editor/history-v2.less @@ -1,3 +1,17 @@ +.history-toolbar { + position: absolute; + width: 100%; + top: @ide-body-top-offset; + height: @editor-toolbar-height; + line-height: @editor-toolbar-height; + background-color: @editor-toolbar-bg; + z-index: 1; + color: #FFF; + padding-left: (@line-height-computed / 2); +} + .history-toolbar-time { + font-weight: bold; + } .history-entries { font-size: @history-base-font-size; color: @history-base-color; @@ -64,7 +78,10 @@ } } -.history-file-tree { +.history-file-tree-inner { + .full-size; + overflow-y: auto; + background-color: @file-tree-bg; } .history-file-entity-wrapper { color: #FFF; diff --git a/public/stylesheets/app/editor/history.less b/public/stylesheets/app/editor/history.less index 68616f6100..ba4e1e142e 100644 --- a/public/stylesheets/app/editor/history.less +++ b/public/stylesheets/app/editor/history.less @@ -40,7 +40,8 @@ } } - .diff-panel { + .diff-panel, + .point-in-time-panel { .full-size; margin-right: @changesListWidth; } @@ -59,11 +60,7 @@ .full-size; top: 40px; } - .hide-ace-cursor { - .ace_active-line, .ace_cursor-layer, .ace_gutter-active-line { - display: none; - } - } + .diff-deleted { padding: @line-height-computed; } @@ -305,6 +302,12 @@ padding-top: 15px; } +.hide-ace-cursor { + .ace_active-line, .ace_cursor-layer, .ace_gutter-active-line { + display: none; + } +} + .editor-dark { #history { aside.change-list { diff --git a/public/stylesheets/core/_common-variables.less b/public/stylesheets/core/_common-variables.less index 3afb428692..543e169b1e 100644 --- a/public/stylesheets/core/_common-variables.less +++ b/public/stylesheets/core/_common-variables.less @@ -888,6 +888,7 @@ @footer-padding : 2em; // Editor header +@ide-body-top-offset : 40px; @toolbar-header-bg-color : transparent; @toolbar-header-shadow : 0 0 2px #ccc; @toolbar-btn-color : @link-color; From 600894a5cccc5d4a902e5e8df1ee7cba1e38f97a Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Wed, 23 May 2018 12:14:27 +0100 Subject: [PATCH 10/19] Add loading indicators; handle binary files; keep selected file across points in time. --- .../project/editor/history-file-tree.pug | 5 ++++ .../project/editor/history/entriesListV2.pug | 3 +- .../project/editor/history/previewPanelV2.pug | 12 ++++++-- .../project/editor/history/toolbarV2.pug | 5 ++-- .../ide/history/HistoryV2Manager.coffee | 15 ++++++++-- .../history/components/historyFileTree.coffee | 1 + .../HistoryV2FileTreeController.coffee | 29 ++++++++++++------- public/stylesheets/app/editor/history-v2.less | 8 +++++ 8 files changed, 61 insertions(+), 17 deletions(-) diff --git a/app/views/project/editor/history-file-tree.pug b/app/views/project/editor/history-file-tree.pug index 1944974ce2..9d9a784678 100644 --- a/app/views/project/editor/history-file-tree.pug +++ b/app/views/project/editor/history-file-tree.pug @@ -7,6 +7,7 @@ aside.file-tree.full-size( file-tree="currentFileTree" selected-pathname="history.selection.pathname" on-selected-file-change="handleFileSelection(file)" + is-loading="history.loadingFileTree" ) script(type="text/ng-template", id="historyFileTreeTpl") @@ -14,7 +15,11 @@ script(type="text/ng-template", id="historyFileTreeTpl") history-file-entity( ng-repeat="fileEntity in $ctrl.fileTree" file-entity="fileEntity" + ng-show="!$ctrl.isLoading" ) + .loading(ng-show="$ctrl.isLoading") + i.fa.fa-spin.fa-refresh + |    #{translate("loading")}... script(type="text/ng-template", id="historyFileEntityTpl") .history-file-entity-wrapper diff --git a/app/views/project/editor/history/entriesListV2.pug b/app/views/project/editor/history/entriesListV2.pug index 2414deb5eb..6a9c75e08f 100644 --- a/app/views/project/editor/history/entriesListV2.pug +++ b/app/views/project/editor/history/entriesListV2.pug @@ -24,8 +24,9 @@ script(type="text/ng-template", id="historyEntriesListTpl") entry="entry" current-user="$ctrl.currentUser" on-select="$ctrl.onEntrySelect({ selectedEntry: selectedEntry })" + ng-show="!$ctrl.isLoading" ) - .loading(ng-show="history.loading") + .loading(ng-show="$ctrl.isLoading") i.fa.fa-spin.fa-refresh |    #{translate("loading")}... diff --git a/app/views/project/editor/history/previewPanelV2.pug b/app/views/project/editor/history/previewPanelV2.pug index 704cc2e0a7..597dc8b0bf 100644 --- a/app/views/project/editor/history/previewPanelV2.pug +++ b/app/views/project/editor/history/previewPanelV2.pug @@ -56,13 +56,21 @@ ng-if="history.isV2 && history.viewMode === HistoryViewModes.POINT_IN_TIME" ) .point-in-time-editor-container( - ng-if="!!history.selectedFile" + ng-if="!!history.selectedFile && !history.selectedFile.loading && !history.selectedFile.error" ) .hide-ace-cursor( + ng-if="!history.selectedFile.binary" ace-editor="history-pointintime", theme="settings.theme", font-size="settings.fontSize", text="history.selectedFile.text", read-only="true", resize-on="layout:main:resize", - ) \ No newline at end of file + ) + .alert.alert-info(ng-if="history.selectedFile.binary") + | We're still working on showing image and binary changes, sorry. Stay tuned! + .loading-panel(ng-show="history.selectedFile.loading") + i.fa.fa-spin.fa-refresh + |   #{translate("loading")}... + .error-panel(ng-show="history.selectedFile.error") + .alert.alert-danger #{translate("generic_something_went_wrong")} diff --git a/app/views/project/editor/history/toolbarV2.pug b/app/views/project/editor/history/toolbarV2.pug index a66fab3ee3..58b94dcaf2 100644 --- a/app/views/project/editor/history/toolbarV2.pug +++ b/app/views/project/editor/history/toolbarV2.pug @@ -1,4 +1,5 @@ .history-toolbar( ng-if="ui.view == 'history' && history.isV2" -) Browsing project as of  - time.history-toolbar-time {{ history.selection.updates[0].meta.end_ts | formatDate:'Do MMM YYYY, h:mm a' }} \ No newline at end of file +) + span(ng-show="!history.loadingFileTree") Browsing project as of  + time.history-toolbar-time {{ history.selection.updates[0].meta.end_ts | formatDate:'Do MMM YYYY, h:mm a' }} \ No newline at end of file diff --git a/public/coffee/ide/history/HistoryV2Manager.coffee b/public/coffee/ide/history/HistoryV2Manager.coffee index aac9c11367..1bc533d665 100644 --- a/public/coffee/ide/history/HistoryV2Manager.coffee +++ b/public/coffee/ide/history/HistoryV2Manager.coffee @@ -30,6 +30,7 @@ define [ # @$scope.$watch "history.selection.pathname", () => # @reloadDiff() + @$scope.$watch "history.selection.pathname", (pathname) => if pathname? @loadFileAtPointInTime() @@ -75,10 +76,14 @@ define [ url = "/project/#{@$scope.project_id}/filetree/diff" query = [ "from=#{toV}", "to=#{toV}" ] url += "?" + query.join("&") + @$scope.history.loadingFileTree = true + @$scope.history.selectedFile = null + @$scope.history.selection.pathname = null @ide.$http .get(url) .then (response) => @$scope.history.files = response.data.diff + @$scope.history.loadingFileTree = false MAX_RECENT_UPDATES_TO_SELECT: 5 autoSelectRecentUpdates: () -> @@ -115,6 +120,7 @@ define [ if @$scope.history.nextBeforeTimestamp? url += "&before=#{@$scope.history.nextBeforeTimestamp}" @$scope.history.loading = true + @$scope.history.loadingFileTree = true @ide.$http .get(url) .then (response) => @@ -131,11 +137,16 @@ define [ url = "/project/#{@$scope.project_id}/diff" query = ["pathname=#{encodeURIComponent(pathname)}", "from=#{toV}", "to=#{toV}"] url += "?" + query.join("&") + @$scope.history.selectedFile = + loading: true @ide.$http .get(url) .then (response) => - @$scope.history.selectedFile = - text : response.data.diff[0].u + {text, binary} = @_parseDiff(response.data.diff) + @$scope.history.selectedFile.binary = binary + @$scope.history.selectedFile.text = text + @$scope.history.selectedFile.loading = false + console.log @$scope.history.selectedFile .catch () -> reloadDiff: () -> diff --git a/public/coffee/ide/history/components/historyFileTree.coffee b/public/coffee/ide/history/components/historyFileTree.coffee index e8daf13af9..7e3c636470 100644 --- a/public/coffee/ide/history/components/historyFileTree.coffee +++ b/public/coffee/ide/history/components/historyFileTree.coffee @@ -12,6 +12,7 @@ define [ fileTree: "<" selectedPathname: "<" onSelectedFileChange: "&" + isLoading: "<" controller: historyFileTreeController templateUrl: "historyFileTreeTpl" } \ No newline at end of file diff --git a/public/coffee/ide/history/controllers/HistoryV2FileTreeController.coffee b/public/coffee/ide/history/controllers/HistoryV2FileTreeController.coffee index fc9caaa6e4..47f5c07c4c 100644 --- a/public/coffee/ide/history/controllers/HistoryV2FileTreeController.coffee +++ b/public/coffee/ide/history/controllers/HistoryV2FileTreeController.coffee @@ -3,24 +3,33 @@ define [ ], (App) -> App.controller "HistoryV2FileTreeController", ["$scope", "ide", "_", ($scope, ide, _) -> + _previouslySelectedPathname = null $scope.currentFileTree = [] - _selectedDefaultPathname = (files) -> - # TODO: Improve heuristic to determine the default pathname to show. - if files? and files.length > 0 - mainFile = files.find (file) -> /main\.tex$/.test file.pathname + + _pathnameExistsInFiles = (pathname, files) -> + _.any files, (file) -> file.pathname == pathname + + _getSelectedDefaultPathname = (files) -> + selectedPathname = null + if _previouslySelectedPathname? and _pathnameExistsInFiles _previouslySelectedPathname, files + selectedPathname = _previouslySelectedPathname + else + mainFile = _.find files, (file) -> /main\.tex$/.test file.pathname if mainFile? - mainFile.pathname + selectedPathname = _previouslySelectedPathname = mainFile.pathname else - files[0].pathname + selectedPathname = _previouslySelectedPathname = files[0].pathname + return selectedPathname $scope.handleFileSelection = (file) -> - $scope.history.selection.pathname = file.pathname + $scope.history.selection.pathname = _previouslySelectedPathname = file.pathname $scope.$watch 'history.files', (files) -> - $scope.currentFileTree = _.reduce files, reducePathsToTree, [] - $scope.history.selection.pathname = _selectedDefaultPathname(files) + if files? and files.length > 0 + $scope.currentFileTree = _.reduce files, _reducePathsToTree, [] + $scope.history.selection.pathname = _getSelectedDefaultPathname(files) - reducePathsToTree = (currentFileTree, fileObject) -> + _reducePathsToTree = (currentFileTree, fileObject) -> filePathParts = fileObject.pathname.split "/" currentFileTreeLocation = currentFileTree for pathPart, index in filePathParts diff --git a/public/stylesheets/app/editor/history-v2.less b/public/stylesheets/app/editor/history-v2.less index 9ff03e55f5..478f939d71 100644 --- a/public/stylesheets/app/editor/history-v2.less +++ b/public/stylesheets/app/editor/history-v2.less @@ -12,6 +12,7 @@ .history-toolbar-time { font-weight: bold; } + .history-entries { font-size: @history-base-font-size; color: @history-base-color; @@ -82,6 +83,13 @@ .full-size; overflow-y: auto; background-color: @file-tree-bg; + + .loading { + color: #FFF; + font-size: @history-base-font-size; + text-align: center; + font-family: @font-family-serif; + } } .history-file-entity-wrapper { color: #FFF; From 04b07f6ecb4f192ea63ec384a41f500c505debe5 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Tue, 29 May 2018 16:50:15 +0100 Subject: [PATCH 11/19] Support using both point-in-time and compare modes. --- app/views/project/editor.pug | 2 +- .../project/editor/history-file-tree.pug | 32 +++++- .../project/editor/history/entriesListV2.pug | 108 ++++++++++++++---- .../project/editor/history/previewPanelV2.pug | 7 +- .../project/editor/history/toolbarV2.pug | 12 +- .../ide/history/HistoryV2Manager.coffee | 29 +++-- public/stylesheets/app/editor/history-v2.less | 20 +++- public/stylesheets/app/editor/history.less | 5 +- .../stylesheets/core/_common-variables.less | 6 +- public/stylesheets/core/ol-variables.less | 2 + 10 files changed, 174 insertions(+), 49 deletions(-) diff --git a/app/views/project/editor.pug b/app/views/project/editor.pug index 45600c4a8f..b34b9f690d 100644 --- a/app/views/project/editor.pug +++ b/app/views/project/editor.pug @@ -62,7 +62,7 @@ block content main#ide-body( ng-cloak, role="main", - ng-class="{ 'ide-history-open' : (ui.view == 'history' && history.isV2) }", + ng-class="{ 'ide-history-open' : (ui.view == 'history' && history.isV2 && history.viewMode === HistoryViewModes.POINT_IN_TIME) }", layout="main", ng-hide="state.loading", resize-on="layout:chat:resize", diff --git a/app/views/project/editor/history-file-tree.pug b/app/views/project/editor/history-file-tree.pug index 9d9a784678..f7d4afb18d 100644 --- a/app/views/project/editor/history-file-tree.pug +++ b/app/views/project/editor/history-file-tree.pug @@ -1,6 +1,6 @@ aside.file-tree.full-size( ng-controller="HistoryV2FileTreeController" - ng-if="ui.view == 'history' && history.isV2" + ng-if="ui.view == 'history' && history.isV2 && history.viewMode === HistoryViewModes.POINT_IN_TIME" ) .history-file-tree-inner history-file-tree( @@ -10,6 +10,32 @@ aside.file-tree.full-size( is-loading="history.loadingFileTree" ) + + +aside.file-tree.file-tree-history.full-size( + ng-controller="FileTreeController" + ng-class="{ 'multi-selected': multiSelectedCount > 0 }" + ng-show="ui.view == 'history' && history.isV2 && history.viewMode === HistoryViewModes.COMPARE") + .toolbar.toolbar-filetree + span Modified files + + .file-tree-inner + ul.list-unstyled.file-tree-list + li( + ng-repeat="(pathname, doc) in history.selection.docs" + ng-class="{ 'selected': history.selection.pathname == pathname }" + ) + .entity + .entity-name.entity-name-history( + ng-click="history.selection.pathname = pathname", + ng-class="{ 'deleted': !!doc.deletedAtV }" + ) + i.fa.fa-fw.fa-pencil + span {{ pathname }} + + + + script(type="text/ng-template", id="historyFileTreeTpl") .history-file-tree history-file-entity( @@ -17,9 +43,7 @@ script(type="text/ng-template", id="historyFileTreeTpl") file-entity="fileEntity" ng-show="!$ctrl.isLoading" ) - .loading(ng-show="$ctrl.isLoading") - i.fa.fa-spin.fa-refresh - |    #{translate("loading")}... + script(type="text/ng-template", id="historyFileEntityTpl") .history-file-entity-wrapper diff --git a/app/views/project/editor/history/entriesListV2.pug b/app/views/project/editor/history/entriesListV2.pug index 6a9c75e08f..0256824293 100644 --- a/app/views/project/editor/history/entriesListV2.pug +++ b/app/views/project/editor/history/entriesListV2.pug @@ -1,5 +1,5 @@ aside.change-list( - ng-if="history.isV2" + ng-if="history.isV2 && history.viewMode === HistoryViewModes.POINT_IN_TIME" ng-controller="HistoryV2ListController" ) history-entries-list( @@ -12,6 +12,89 @@ aside.change-list( on-entry-select="handleEntrySelect(selectedEntry)" ) +aside.change-list( + ng-if="history.isV2 && history.viewMode === HistoryViewModes.COMPARE" + ng-controller="HistoryListController" + infinite-scroll="loadMore()" + infinite-scroll-disabled="history.loading || history.atEnd" + infinite-scroll-initialize="ui.view == 'history'" +) + .infinite-scroll-inner + ul.list-unstyled( + ng-class="{\ + 'hover-state': history.hoveringOverListSelectors\ + }" + ) + li.change( + ng-repeat="update in history.updates" + ng-class="{\ + 'first-in-day': update.meta.first_in_day,\ + 'selected': update.inSelection,\ + 'selected-to': update.selectedTo,\ + 'selected-from': update.selectedFrom,\ + 'hover-selected': update.inHoverSelection,\ + 'hover-selected-to': update.hoverSelectedTo,\ + 'hover-selected-from': update.hoverSelectedFrom,\ + }" + ng-controller="HistoryListItemController" + ) + + 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" + ng-mouseover="mouseOverSelectedFrom()" + ng-mouseout="mouseOutSelectedFrom()" + ng-show="update.afterSelection || update.inSelection" + ) + form + input.selector-to( + type="radio" + name="toVersion" + ng-model="update.selectedTo" + ng-value="true" + ng-mouseover="mouseOverSelectedTo()" + ng-mouseout="mouseOutSelectedTo()" + ng-show="update.beforeSelection || update.inSelection" + ) + + div.description(ng-click="select()") + div.time {{ update.meta.end_ts | formatDate:'h:mm a' }} + div.action.action-edited(ng-if="history.isV2 && update.pathnames.length > 0") + | Edited + div.docs(ng-repeat="pathname in update.pathnames") + .doc {{ pathname }} + div.docs(ng-repeat="project_op in update.project_ops") + div(ng-if="project_op.rename") + .action Renamed + .doc {{ project_op.rename.pathname }} → {{ project_op.rename.newPathname }} + div(ng-if="project_op.add") + .action Created + .doc {{ project_op.add.pathname }} + div(ng-if="project_op.remove") + .action Deleted + .doc {{ project_op.remove.pathname }} + div.users + div.user(ng-repeat="update_user in update.meta.users") + .color-square(ng-if="update_user != null", ng-style="{'background-color': 'hsl({{ update_user.hue }}, 70%, 50%)'}") + .color-square(ng-if="update_user == null", ng-style="{'background-color': 'hsl(100, 70%, 50%)'}") + .name(ng-if="update_user && update_user.id != user.id" ng-bind="displayName(update_user)") + .name(ng-if="update_user && update_user.id == user.id") You + .name(ng-if="update_user == null") #{translate("anonymous")} + div.user(ng-if="update.meta.users.length == 0") + .color-square(style="background-color: hsl(100, 100%, 50%)") + span #{translate("anonymous")} + + .loading(ng-show="history.loading") + i.fa.fa-spin.fa-refresh + |    #{translate("loading")}... + script(type="text/ng-template", id="historyEntriesListTpl") .history-entries( infinite-scroll="$ctrl.loadEntries()" @@ -45,29 +128,6 @@ script(type="text/ng-template", id="historyEntryTpl") time.history-entry-day(ng-if="::$ctrl.entry.meta.first_in_day") {{ ::$ctrl.entry.meta.end_ts | relativeDate }} - //- div.selectors - //- div.range - //- form - //- input.selector-from( - //- type="radio" - //- name="fromVersion" - //- ng-model="$ctrl.entry.selectedFrom" - //- ng-value="true" - //- ng-mouseover="mouseOverSelectedFrom()" - //- ng-mouseout="mouseOutSelectedFrom()" - //- ng-show="$ctrl.entry.afterSelection || $ctrl.entry.inSelection" - //- ) - //- form - //- input.selector-to( - //- type="radio" - //- name="toVersion" - //- ng-model="$ctrl.entry.selectedTo" - //- ng-value="true" - //- ng-mouseover="mouseOverSelectedTo()" - //- ng-mouseout="mouseOutSelectedTo()" - //- ng-show="$ctrl.entry.beforeSelection || $ctrl.entry.inSelection" - ) - .history-entry-details(ng-click="$ctrl.onSelect({ selectedEntry: $ctrl.entry })") ol.history-entry-changes li.history-entry-change( diff --git a/app/views/project/editor/history/previewPanelV2.pug b/app/views/project/editor/history/previewPanelV2.pug index 597dc8b0bf..caca523f14 100644 --- a/app/views/project/editor/history/previewPanelV2.pug +++ b/app/views/project/editor/history/previewPanelV2.pug @@ -19,8 +19,13 @@ }" ) | in {{history.diff.pathname}} + .btn.btn-info.btn-xs( + ng-click="toggleHistoryViewMode();" + ) + i.fa + | Enter "Point-in-time" mode .toolbar-right(ng-if="history.selection.docs[history.selection.pathname].deletedAtV") - button.btn.btn-danger.btn-sm( + button.btn.btn-danger.btn-xs( ng-click="restoreDeletedFile()" ng-show="!restoreState.error" ng-disabled="restoreState.inflight" diff --git a/app/views/project/editor/history/toolbarV2.pug b/app/views/project/editor/history/toolbarV2.pug index 58b94dcaf2..2b1b344324 100644 --- a/app/views/project/editor/history/toolbarV2.pug +++ b/app/views/project/editor/history/toolbarV2.pug @@ -1,5 +1,13 @@ .history-toolbar( - ng-if="ui.view == 'history' && history.isV2" + ng-if="ui.view == 'history' && history.isV2 && history.viewMode === HistoryViewModes.POINT_IN_TIME" ) + span(ng-show="history.loadingFileTree") + i.fa.fa-spin.fa-refresh + |    #{translate("loading")}... span(ng-show="!history.loadingFileTree") Browsing project as of  - time.history-toolbar-time {{ history.selection.updates[0].meta.end_ts | formatDate:'Do MMM YYYY, h:mm a' }} \ No newline at end of file + time.history-toolbar-time {{ history.selection.updates[0].meta.end_ts | formatDate:'Do MMM YYYY, h:mm a' }} + .history-toolbar-btn( + ng-click="toggleHistoryViewMode();" + ) + i.fa + | Enter "Compare" mode \ No newline at end of file diff --git a/public/coffee/ide/history/HistoryV2Manager.coffee b/public/coffee/ide/history/HistoryV2Manager.coffee index 1bc533d665..7c8f476e39 100644 --- a/public/coffee/ide/history/HistoryV2Manager.coffee +++ b/public/coffee/ide/history/HistoryV2Manager.coffee @@ -23,21 +23,31 @@ define [ else @show() - # @$scope.$watch "history.selection.updates", (updates) => - # if updates? and updates.length > 0 - # @_selectDocFromUpdates() - # @reloadDiff() + @$scope.toggleHistoryViewMode = () => + if @$scope.history.viewMode == HistoryViewModes.COMPARE + @reset() + @$scope.history.viewMode = HistoryViewModes.POINT_IN_TIME + else + @reset() + @$scope.history.viewMode = HistoryViewModes.COMPARE - # @$scope.$watch "history.selection.pathname", () => - # @reloadDiff() + @$scope.$watch "history.selection.updates", (updates) => + if @$scope.history.viewMode == HistoryViewModes.COMPARE + if updates? and updates.length > 0 + @_selectDocFromUpdates() + @reloadDiff() @$scope.$watch "history.selection.pathname", (pathname) => - if pathname? - @loadFileAtPointInTime() + if @$scope.history.viewMode == HistoryViewModes.POINT_IN_TIME + if pathname? + @loadFileAtPointInTime() + else + @reloadDiff() show: () -> @$scope.ui.view = "history" @reset() + @$scope.history.viewMode = HistoryViewModes.POINT_IN_TIME hide: () -> @$scope.ui.view = "editor" @@ -46,7 +56,7 @@ define [ @$scope.history = { isV2: true updates: [] - viewMode: HistoryViewModes.POINT_IN_TIME + viewMode: null nextBeforeTimestamp: null atEnd: false selection: { @@ -146,7 +156,6 @@ define [ @$scope.history.selectedFile.binary = binary @$scope.history.selectedFile.text = text @$scope.history.selectedFile.loading = false - console.log @$scope.history.selectedFile .catch () -> reloadDiff: () -> diff --git a/public/stylesheets/app/editor/history-v2.less b/public/stylesheets/app/editor/history-v2.less index 478f939d71..f3d92a2838 100644 --- a/public/stylesheets/app/editor/history-v2.less +++ b/public/stylesheets/app/editor/history-v2.less @@ -1,17 +1,31 @@ .history-toolbar { + display: flex; + align-items: center; position: absolute; width: 100%; top: @ide-body-top-offset; height: @editor-toolbar-height; - line-height: @editor-toolbar-height; - background-color: @editor-toolbar-bg; + line-height: 1; + font-size: @font-size-small; + background-color: @history-toolbar-bg-color; z-index: 1; - color: #FFF; + color: @history-toolbar-color; padding-left: (@line-height-computed / 2); +} +.history-toolbar when (@is-overleaf = false) { + border-bottom: @toolbar-border-bottom; } .history-toolbar-time { font-weight: bold; } + .history-toolbar-btn { + .btn; + .btn-info; + .btn-xs; + padding-left: @padding-small-horizontal; + padding-right: @padding-small-horizontal; + margin-left: (@line-height-computed / 2); + } .history-entries { font-size: @history-base-font-size; diff --git a/public/stylesheets/app/editor/history.less b/public/stylesheets/app/editor/history.less index ba4e1e142e..a8d876bc52 100644 --- a/public/stylesheets/app/editor/history.less +++ b/public/stylesheets/app/editor/history.less @@ -1,4 +1,4 @@ -@changesListWidth: 250px; +@changesListWidth: 250px; @changesListPadding: @line-height-computed / 2; @selector-padding-vertical: 10px; @@ -50,6 +50,7 @@ .full-size; .toolbar { padding: 3px; + height: 32px; .name { float: left; padding: 3px @line-height-computed / 4; @@ -58,7 +59,7 @@ } .diff-editor { .full-size; - top: 40px; + top: 32px; } .diff-deleted { diff --git a/public/stylesheets/core/_common-variables.less b/public/stylesheets/core/_common-variables.less index 543e169b1e..cdee262789 100644 --- a/public/stylesheets/core/_common-variables.less +++ b/public/stylesheets/core/_common-variables.less @@ -978,7 +978,9 @@ // v2 History @history-base-font-size : @font-size-small; @history-base-bg : @gray-lightest; -@history-entry-day-bg : @gray-dark; +@history-entry-day-bg : @gray; @history-entry-selected-bg : @red; @history-base-color : @gray-light; -@history-highlight-color : @gray; \ No newline at end of file +@history-highlight-color : @gray; +@history-toolbar-bg-color : @toolbar-alt-bg-color; +@history-toolbar-color : @text-color; diff --git a/public/stylesheets/core/ol-variables.less b/public/stylesheets/core/ol-variables.less index cd5b035fc4..61e7a93498 100644 --- a/public/stylesheets/core/ol-variables.less +++ b/public/stylesheets/core/ol-variables.less @@ -273,6 +273,8 @@ @history-entry-selected-bg : @ol-green; @history-base-color : @ol-blue-gray-2; @history-highlight-color : @ol-type-color; +@history-toolbar-bg-color : @editor-toolbar-bg; +@history-toolbar-color : #FFF; // System messages @sys-msg-background : @ol-blue; From 870519afeff6db4887bab1b2c4b9629512c9d567 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Wed, 30 May 2018 14:21:01 +0100 Subject: [PATCH 12/19] Rename history file tree and move it around. --- app/views/project/editor.pug | 2 +- .../editor/{history-file-tree.pug => history/fileTreeV2.pug} | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) rename app/views/project/editor/{history-file-tree.pug => history/fileTreeV2.pug} (99%) diff --git a/app/views/project/editor.pug b/app/views/project/editor.pug index 3b611440dd..602b9af86b 100644 --- a/app/views/project/editor.pug +++ b/app/views/project/editor.pug @@ -73,7 +73,7 @@ block content ) .ui-layout-west include ./editor/file-tree - include ./editor/history-file-tree + include ./editor/history/fileTreeV2 .ui-layout-center include ./editor/editor diff --git a/app/views/project/editor/history-file-tree.pug b/app/views/project/editor/history/fileTreeV2.pug similarity index 99% rename from app/views/project/editor/history-file-tree.pug rename to app/views/project/editor/history/fileTreeV2.pug index f7d4afb18d..0f3a2c1203 100644 --- a/app/views/project/editor/history-file-tree.pug +++ b/app/views/project/editor/history/fileTreeV2.pug @@ -10,8 +10,6 @@ aside.file-tree.full-size( is-loading="history.loadingFileTree" ) - - aside.file-tree.file-tree-history.full-size( ng-controller="FileTreeController" ng-class="{ 'multi-selected': multiSelectedCount > 0 }" From c2ba824c43bdb4cd220fbf3d1decb0166a61f603 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Wed, 30 May 2018 15:00:20 +0100 Subject: [PATCH 13/19] Make history file tree more like the editor file tree in SL. --- public/stylesheets/app/editor/history-v2.less | 17 +++++++++++++++++ public/stylesheets/core/_common-variables.less | 17 +++++++++-------- public/stylesheets/core/ol-variables.less | 16 ++++++++-------- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/public/stylesheets/app/editor/history-v2.less b/public/stylesheets/app/editor/history-v2.less index f3d92a2838..abb92d72b6 100644 --- a/public/stylesheets/app/editor/history-v2.less +++ b/public/stylesheets/app/editor/history-v2.less @@ -105,6 +105,11 @@ font-family: @font-family-serif; } } + +.history-file-tree-inner when (@is-overleaf = false) { + font-size: 0.8rem; +} + .history-file-entity-wrapper { color: #FFF; margin-left: (@line-height-computed / 2); @@ -132,6 +137,7 @@ background-color: @file-tree-item-selected-bg; font-weight: bold; padding-right: 32px; + color: #FFF; .fake-full-width-bg(@file-tree-item-selected-bg); &:hover { background-color: @file-tree-item-hover-bg; @@ -152,6 +158,17 @@ overflow: hidden; text-overflow: ellipsis; } + + .history-file-entity-link-selected when (@is-overleaf = false) { + color: @brand-primary; + &:hover, + &:focus { + color: @brand-primary; + } + .history-file-entity-icon { + color: @brand-primary; + } + } // @changesListWidth: 250px; // @changesListPadding: @line-height-computed / 2; diff --git a/public/stylesheets/core/_common-variables.less b/public/stylesheets/core/_common-variables.less index cdee262789..033ce9c1bf 100644 --- a/public/stylesheets/core/_common-variables.less +++ b/public/stylesheets/core/_common-variables.less @@ -976,11 +976,12 @@ @sys-msg-border : 1px solid @common-border-color; // v2 History -@history-base-font-size : @font-size-small; -@history-base-bg : @gray-lightest; -@history-entry-day-bg : @gray; -@history-entry-selected-bg : @red; -@history-base-color : @gray-light; -@history-highlight-color : @gray; -@history-toolbar-bg-color : @toolbar-alt-bg-color; -@history-toolbar-color : @text-color; +@history-base-font-size : @font-size-small; +@history-base-bg : @gray-lightest; +@history-entry-day-bg : @gray; +@history-entry-selected-bg : @red; +@history-base-color : @gray-light; +@history-highlight-color : @gray; +@history-toolbar-bg-color : @toolbar-alt-bg-color; +@history-toolbar-color : @text-color; + diff --git a/public/stylesheets/core/ol-variables.less b/public/stylesheets/core/ol-variables.less index 61e7a93498..3d3d4468fd 100644 --- a/public/stylesheets/core/ol-variables.less +++ b/public/stylesheets/core/ol-variables.less @@ -267,14 +267,14 @@ // v2 History -@history-base-font-size : @font-size-small; -@history-base-bg : @ol-blue-gray-1; -@history-entry-day-bg : @ol-blue-gray-2; -@history-entry-selected-bg : @ol-green; -@history-base-color : @ol-blue-gray-2; -@history-highlight-color : @ol-type-color; -@history-toolbar-bg-color : @editor-toolbar-bg; -@history-toolbar-color : #FFF; +@history-base-font-size : @font-size-small; +@history-base-bg : @ol-blue-gray-1; +@history-entry-day-bg : @ol-blue-gray-2; +@history-entry-selected-bg : @ol-green; +@history-base-color : @ol-blue-gray-2; +@history-highlight-color : @ol-type-color; +@history-toolbar-bg-color : @editor-toolbar-bg; +@history-toolbar-color : #FFF; // System messages @sys-msg-background : @ol-blue; From a453140cf6c8b00fb5afd0e4588ce6742acc7db0 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Wed, 30 May 2018 15:03:22 +0100 Subject: [PATCH 14/19] Change buttons copy. --- app/views/project/editor/history/previewPanelV2.pug | 2 +- app/views/project/editor/history/toolbarV2.pug | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/project/editor/history/previewPanelV2.pug b/app/views/project/editor/history/previewPanelV2.pug index caca523f14..89a89c0e23 100644 --- a/app/views/project/editor/history/previewPanelV2.pug +++ b/app/views/project/editor/history/previewPanelV2.pug @@ -23,7 +23,7 @@ ng-click="toggleHistoryViewMode();" ) i.fa - | Enter "Point-in-time" mode + | Browse project versions .toolbar-right(ng-if="history.selection.docs[history.selection.pathname].deletedAtV") button.btn.btn-danger.btn-xs( ng-click="restoreDeletedFile()" diff --git a/app/views/project/editor/history/toolbarV2.pug b/app/views/project/editor/history/toolbarV2.pug index 2b1b344324..48f2292a16 100644 --- a/app/views/project/editor/history/toolbarV2.pug +++ b/app/views/project/editor/history/toolbarV2.pug @@ -10,4 +10,4 @@ ng-click="toggleHistoryViewMode();" ) i.fa - | Enter "Compare" mode \ No newline at end of file + | Compare project versions \ No newline at end of file From aa1dc3a60cd0a74f5ad1abc466de38660e3cc9d3 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Wed, 30 May 2018 15:18:15 +0100 Subject: [PATCH 15/19] Remove commented-out code. --- .../HistoryV2ListController.coffee | 41 +------------------ 1 file changed, 1 insertion(+), 40 deletions(-) diff --git a/public/coffee/ide/history/controllers/HistoryV2ListController.coffee b/public/coffee/ide/history/controllers/HistoryV2ListController.coffee index 823461d16a..eaf7fbc884 100644 --- a/public/coffee/ide/history/controllers/HistoryV2ListController.coffee +++ b/public/coffee/ide/history/controllers/HistoryV2ListController.coffee @@ -73,43 +73,4 @@ define [ $scope.$watch "history.updates.length", () -> $scope.recalculateSelectedUpdates() - ] - - # App.controller "HistoryListItemController", ["$scope", "event_tracking", ($scope, event_tracking) -> - # $scope.$watch "update.selectedFrom", (selectedFrom, oldSelectedFrom) -> - # if selectedFrom - # for update in $scope.history.updates - # update.selectedFrom = false unless update == $scope.update - # $scope.recalculateSelectedUpdates() - - # $scope.$watch "update.selectedTo", (selectedTo, oldSelectedTo) -> - # if selectedTo - # for update in $scope.history.updates - # update.selectedTo = false unless update == $scope.update - # $scope.recalculateSelectedUpdates() - - # $scope.select = () -> - # event_tracking.sendMB "history-view-change" - # $scope.update.selectedTo = true - # $scope.update.selectedFrom = true - - # $scope.mouseOverSelectedFrom = () -> - # $scope.history.hoveringOverListSelectors = true - # $scope.update.hoverSelectedFrom = true - # $scope.recalculateHoveredUpdates() - - # $scope.mouseOutSelectedFrom = () -> - # $scope.history.hoveringOverListSelectors = false - # $scope.resetHoverState() - - # $scope.mouseOverSelectedTo = () -> - # $scope.history.hoveringOverListSelectors = true - # $scope.update.hoverSelectedTo = true - # $scope.recalculateHoveredUpdates() - - # $scope.mouseOutSelectedTo = () -> - # $scope.history.hoveringOverListSelectors = false - # $scope.resetHoverState() - - # $scope.displayName = displayNameForUser - # ] + ] \ No newline at end of file From 0e8c704d1e231220bdee39318e3172271a8f9e29 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Wed, 30 May 2018 17:34:46 +0100 Subject: [PATCH 16/19] Margin and padding adjustments. --- app/views/project/editor/history/previewPanelV2.pug | 2 +- public/stylesheets/app/editor/history.less | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/project/editor/history/previewPanelV2.pug b/app/views/project/editor/history/previewPanelV2.pug index 89a89c0e23..596912d109 100644 --- a/app/views/project/editor/history/previewPanelV2.pug +++ b/app/views/project/editor/history/previewPanelV2.pug @@ -19,7 +19,7 @@ }" ) | in {{history.diff.pathname}} - .btn.btn-info.btn-xs( + .history-toolbar-btn( ng-click="toggleHistoryViewMode();" ) i.fa diff --git a/public/stylesheets/app/editor/history.less b/public/stylesheets/app/editor/history.less index a8d876bc52..3e558b6c5f 100644 --- a/public/stylesheets/app/editor/history.less +++ b/public/stylesheets/app/editor/history.less @@ -88,6 +88,7 @@ .loading { text-align: center; font-family: @font-family-serif; + margin-top: (@line-height-computed / 2); } ul { From ec4091417e5c5bf1432f5cd35fd4aa1ed9fe2827 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 30 May 2018 17:55:02 +0100 Subject: [PATCH 17/19] Wrap text like normal --- app/views/project/editor/history/entriesListV2.pug | 5 ++++- public/stylesheets/app/editor/history-v2.less | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/views/project/editor/history/entriesListV2.pug b/app/views/project/editor/history/entriesListV2.pug index 0256824293..b17adbce67 100644 --- a/app/views/project/editor/history/entriesListV2.pug +++ b/app/views/project/editor/history/entriesListV2.pug @@ -142,7 +142,10 @@ script(type="text/ng-template", id="historyEntryTpl") span.history-entry-change-doc {{ ::$ctrl.getProjectOpDoc(project_op) }} .history-entry-metadata time.history-entry-metadata-time {{ ::$ctrl.entry.meta.end_ts | formatDate:'h:mm a' }} - span  •  + span + | + | • + | ol.history-entry-metadata-users li.history-entry-metadata-user(ng-repeat="update_user in ::$ctrl.entry.meta.users") span.name( diff --git a/public/stylesheets/app/editor/history-v2.less b/public/stylesheets/app/editor/history-v2.less index abb92d72b6..9089ed1ae9 100644 --- a/public/stylesheets/app/editor/history-v2.less +++ b/public/stylesheets/app/editor/history-v2.less @@ -58,7 +58,7 @@ margin-bottom: 3px; } .history-entry-change { - display: flex; + } .history-entry-change-action { margin-right: 0.5em; @@ -76,7 +76,7 @@ } .history-entry-metadata-time { - + white-space: nowrap; } .history-entry-metadata-users { From 144bdc3db18981aa104269cfe4d9b6ecc3611f4c Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Tue, 5 Jun 2018 10:14:16 +0100 Subject: [PATCH 18/19] Add i18n. --- .../project/editor/history/entriesListV1.pug | 8 ++++---- .../project/editor/history/entriesListV2.pug | 20 +++++++++++++------ .../project/editor/history/toolbarV2.pug | 4 ++-- .../history/components/historyEntry.coffee | 4 ---- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/app/views/project/editor/history/entriesListV1.pug b/app/views/project/editor/history/entriesListV1.pug index 2db6b9e533..361bca3679 100644 --- a/app/views/project/editor/history/entriesListV1.pug +++ b/app/views/project/editor/history/entriesListV1.pug @@ -53,18 +53,18 @@ aside.change-list( div.description(ng-click="select()") div.time {{ update.meta.end_ts | formatDate:'h:mm a' }} div.action.action-edited(ng-if="history.isV2 && update.pathnames.length > 0") - | Edited + | #{translate("file-action-edited")} div.docs(ng-repeat="pathname in update.pathnames") .doc {{ pathname }} div.docs(ng-repeat="project_op in update.project_ops") div(ng-if="project_op.rename") - .action Renamed + .action #{translate("file-action-renamed")} .doc {{ project_op.rename.pathname }} → {{ project_op.rename.newPathname }} div(ng-if="project_op.add") - .action Created + .action #{translate("file-action-created")} .doc {{ project_op.add.pathname }} div(ng-if="project_op.remove") - .action Deleted + .action #{translate("file-action-deleted")} .doc {{ project_op.remove.pathname }} div.users div.user(ng-repeat="update_user in update.meta.users") diff --git a/app/views/project/editor/history/entriesListV2.pug b/app/views/project/editor/history/entriesListV2.pug index 0256824293..088f1d2741 100644 --- a/app/views/project/editor/history/entriesListV2.pug +++ b/app/views/project/editor/history/entriesListV2.pug @@ -67,18 +67,18 @@ aside.change-list( div.description(ng-click="select()") div.time {{ update.meta.end_ts | formatDate:'h:mm a' }} div.action.action-edited(ng-if="history.isV2 && update.pathnames.length > 0") - | Edited + | #{translate("file-action-edited")} div.docs(ng-repeat="pathname in update.pathnames") .doc {{ pathname }} div.docs(ng-repeat="project_op in update.project_ops") div(ng-if="project_op.rename") - .action Renamed + .action #{translate("file-action-renamed")} .doc {{ project_op.rename.pathname }} → {{ project_op.rename.newPathname }} div(ng-if="project_op.add") - .action Created + .action #{translate("file-action-created")} .doc {{ project_op.add.pathname }} div(ng-if="project_op.remove") - .action Deleted + .action #{translate("file-action-deleted")} .doc {{ project_op.remove.pathname }} div.users div.user(ng-repeat="update_user in update.meta.users") @@ -133,12 +133,20 @@ script(type="text/ng-template", id="historyEntryTpl") li.history-entry-change( ng-repeat="pathname in ::$ctrl.entry.pathnames" ) - span.history-entry-change-action Edited + span.history-entry-change-action #{translate("file-action-edited")} span.history-entry-change-doc {{ ::pathname }} li.history-entry-change( ng-repeat="project_op in ::$ctrl.entry.project_ops" ) - span.history-entry-change-action {{ ::$ctrl.getProjectOpAction(project_op) }} + span.history-entry-change-action( + ng-if="::project_op.rename" + ) #{translate("file-action-renamed")} + span.history-entry-change-action( + ng-if="::project_op.add" + ) #{translate("file-action-created")} + span.history-entry-change-action( + ng-if="::project_op.remove" + ) #{translate("file-action-deleted")} span.history-entry-change-doc {{ ::$ctrl.getProjectOpDoc(project_op) }} .history-entry-metadata time.history-entry-metadata-time {{ ::$ctrl.entry.meta.end_ts | formatDate:'h:mm a' }} diff --git a/app/views/project/editor/history/toolbarV2.pug b/app/views/project/editor/history/toolbarV2.pug index 48f2292a16..f737798089 100644 --- a/app/views/project/editor/history/toolbarV2.pug +++ b/app/views/project/editor/history/toolbarV2.pug @@ -4,10 +4,10 @@ span(ng-show="history.loadingFileTree") i.fa.fa-spin.fa-refresh |    #{translate("loading")}... - span(ng-show="!history.loadingFileTree") Browsing project as of  + span(ng-show="!history.loadingFileTree") #{translate("browsing-project-as-of")}  time.history-toolbar-time {{ history.selection.updates[0].meta.end_ts | formatDate:'Do MMM YYYY, h:mm a' }} .history-toolbar-btn( ng-click="toggleHistoryViewMode();" ) i.fa - | Compare project versions \ No newline at end of file + | #{translate("compare-project-versions")} \ No newline at end of file diff --git a/public/coffee/ide/history/components/historyEntry.coffee b/public/coffee/ide/history/components/historyEntry.coffee index 53824c1317..e2692b7dee 100644 --- a/public/coffee/ide/history/components/historyEntry.coffee +++ b/public/coffee/ide/history/components/historyEntry.coffee @@ -5,10 +5,6 @@ define [ historyEntryController = ($scope, $element, $attrs) -> ctrl = @ ctrl.displayName = displayNameForUser - ctrl.getProjectOpAction = (projectOp) -> - if projectOp.rename? then "Renamed" - else if projectOp.add? then "Created" - else if projectOp.remove? then "Deleted" ctrl.getProjectOpDoc = (projectOp) -> if projectOp.rename? then "#{ projectOp.rename.pathname} → #{ projectOp.rename.newPathname }" else if projectOp.add? then "#{ projectOp.add.pathname}" From e0e73150b7b8763a0afe9de23851bc9cdb6871ac Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Tue, 5 Jun 2018 11:15:39 +0100 Subject: [PATCH 19/19] Update translations; use underscores for keys. --- .../project/editor/history/entriesListV1.pug | 8 ++++---- .../project/editor/history/entriesListV2.pug | 16 ++++++++-------- .../project/editor/history/previewPanelV2.pug | 2 +- app/views/project/editor/history/toolbarV2.pug | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/views/project/editor/history/entriesListV1.pug b/app/views/project/editor/history/entriesListV1.pug index 361bca3679..27f9e66fe1 100644 --- a/app/views/project/editor/history/entriesListV1.pug +++ b/app/views/project/editor/history/entriesListV1.pug @@ -53,18 +53,18 @@ aside.change-list( div.description(ng-click="select()") div.time {{ update.meta.end_ts | formatDate:'h:mm a' }} div.action.action-edited(ng-if="history.isV2 && update.pathnames.length > 0") - | #{translate("file-action-edited")} + | #{translate("file_action_edited")} div.docs(ng-repeat="pathname in update.pathnames") .doc {{ pathname }} div.docs(ng-repeat="project_op in update.project_ops") div(ng-if="project_op.rename") - .action #{translate("file-action-renamed")} + .action #{translate("file_action_renamed")} .doc {{ project_op.rename.pathname }} → {{ project_op.rename.newPathname }} div(ng-if="project_op.add") - .action #{translate("file-action-created")} + .action #{translate("file_action_created")} .doc {{ project_op.add.pathname }} div(ng-if="project_op.remove") - .action #{translate("file-action-deleted")} + .action #{translate("file_action_deleted")} .doc {{ project_op.remove.pathname }} div.users div.user(ng-repeat="update_user in update.meta.users") diff --git a/app/views/project/editor/history/entriesListV2.pug b/app/views/project/editor/history/entriesListV2.pug index a7d078b5c8..fa7a90b20e 100644 --- a/app/views/project/editor/history/entriesListV2.pug +++ b/app/views/project/editor/history/entriesListV2.pug @@ -67,18 +67,18 @@ aside.change-list( div.description(ng-click="select()") div.time {{ update.meta.end_ts | formatDate:'h:mm a' }} div.action.action-edited(ng-if="history.isV2 && update.pathnames.length > 0") - | #{translate("file-action-edited")} + | #{translate("file_action_edited")} div.docs(ng-repeat="pathname in update.pathnames") .doc {{ pathname }} div.docs(ng-repeat="project_op in update.project_ops") div(ng-if="project_op.rename") - .action #{translate("file-action-renamed")} + .action #{translate("file_action_renamed")} .doc {{ project_op.rename.pathname }} → {{ project_op.rename.newPathname }} div(ng-if="project_op.add") - .action #{translate("file-action-created")} + .action #{translate("file_action_created")} .doc {{ project_op.add.pathname }} div(ng-if="project_op.remove") - .action #{translate("file-action-deleted")} + .action #{translate("file_action_deleted")} .doc {{ project_op.remove.pathname }} div.users div.user(ng-repeat="update_user in update.meta.users") @@ -133,20 +133,20 @@ script(type="text/ng-template", id="historyEntryTpl") li.history-entry-change( ng-repeat="pathname in ::$ctrl.entry.pathnames" ) - span.history-entry-change-action #{translate("file-action-edited")} + span.history-entry-change-action #{translate("file_action_edited")} span.history-entry-change-doc {{ ::pathname }} li.history-entry-change( ng-repeat="project_op in ::$ctrl.entry.project_ops" ) span.history-entry-change-action( ng-if="::project_op.rename" - ) #{translate("file-action-renamed")} + ) #{translate("file_action_renamed")} span.history-entry-change-action( ng-if="::project_op.add" - ) #{translate("file-action-created")} + ) #{translate("file_action_created")} span.history-entry-change-action( ng-if="::project_op.remove" - ) #{translate("file-action-deleted")} + ) #{translate("file_action_deleted")} span.history-entry-change-doc {{ ::$ctrl.getProjectOpDoc(project_op) }} .history-entry-metadata time.history-entry-metadata-time {{ ::$ctrl.entry.meta.end_ts | formatDate:'h:mm a' }} diff --git a/app/views/project/editor/history/previewPanelV2.pug b/app/views/project/editor/history/previewPanelV2.pug index 596912d109..3d7a1ac3df 100644 --- a/app/views/project/editor/history/previewPanelV2.pug +++ b/app/views/project/editor/history/previewPanelV2.pug @@ -23,7 +23,7 @@ ng-click="toggleHistoryViewMode();" ) i.fa - | Browse project versions + | #{translate("view_single_version")} .toolbar-right(ng-if="history.selection.docs[history.selection.pathname].deletedAtV") button.btn.btn-danger.btn-xs( ng-click="restoreDeletedFile()" diff --git a/app/views/project/editor/history/toolbarV2.pug b/app/views/project/editor/history/toolbarV2.pug index f737798089..799a7136f3 100644 --- a/app/views/project/editor/history/toolbarV2.pug +++ b/app/views/project/editor/history/toolbarV2.pug @@ -4,10 +4,10 @@ span(ng-show="history.loadingFileTree") i.fa.fa-spin.fa-refresh |    #{translate("loading")}... - span(ng-show="!history.loadingFileTree") #{translate("browsing-project-as-of")}  + span(ng-show="!history.loadingFileTree") #{translate("browsing_project_as_of")}  time.history-toolbar-time {{ history.selection.updates[0].meta.end_ts | formatDate:'Do MMM YYYY, h:mm a' }} .history-toolbar-btn( ng-click="toggleHistoryViewMode();" ) i.fa - | #{translate("compare-project-versions")} \ No newline at end of file + | #{translate("compare_to_another_version")} \ No newline at end of file