From 8249f4e17e573e02ac862be787be1737e260e738 Mon Sep 17 00:00:00 2001 From: Paulo Reis Date: Fri, 27 Apr 2018 11:22:20 +0100 Subject: [PATCH] Wrap copies of existing history UI elements in components. --- .../web/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 services/web/app/views/project/editor/history/entriesListV1.pug create mode 100644 services/web/app/views/project/editor/history/entriesListV2.pug create mode 100644 services/web/public/coffee/ide/history/components/historyEntriesList.coffee create mode 100644 services/web/public/coffee/ide/history/components/historyEntry.coffee create mode 100644 services/web/public/coffee/ide/history/controllers/HistoryV2ListController.coffee diff --git a/services/web/app/views/project/editor/history.pug b/services/web/app/views/project/editor/history.pug index d366d5f41a..f237aff89e 100644 --- a/services/web/app/views/project/editor/history.pug +++ b/services/web/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/services/web/app/views/project/editor/history/entriesListV1.pug b/services/web/app/views/project/editor/history/entriesListV1.pug new file mode 100644 index 0000000000..2db6b9e533 --- /dev/null +++ b/services/web/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/services/web/app/views/project/editor/history/entriesListV2.pug b/services/web/app/views/project/editor/history/entriesListV2.pug new file mode 100644 index 0000000000..e5bc339c51 --- /dev/null +++ b/services/web/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/services/web/public/coffee/ide/history/HistoryManager.coffee b/services/web/public/coffee/ide/history/HistoryManager.coffee index cdc39ffd05..e79f0ad116 100644 --- a/services/web/public/coffee/ide/history/HistoryManager.coffee +++ b/services/web/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/services/web/public/coffee/ide/history/HistoryV2Manager.coffee b/services/web/public/coffee/ide/history/HistoryV2Manager.coffee index 72f4c79bdd..c2c75a0373 100644 --- a/services/web/public/coffee/ide/history/HistoryV2Manager.coffee +++ b/services/web/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/services/web/public/coffee/ide/history/components/historyEntriesList.coffee b/services/web/public/coffee/ide/history/components/historyEntriesList.coffee new file mode 100644 index 0000000000..11ee4e73de --- /dev/null +++ b/services/web/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/services/web/public/coffee/ide/history/components/historyEntry.coffee b/services/web/public/coffee/ide/history/components/historyEntry.coffee new file mode 100644 index 0000000000..fbfd4dab08 --- /dev/null +++ b/services/web/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/services/web/public/coffee/ide/history/controllers/HistoryV2ListController.coffee b/services/web/public/coffee/ide/history/controllers/HistoryV2ListController.coffee new file mode 100644 index 0000000000..772f360a80 --- /dev/null +++ b/services/web/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 + ]