diff --git a/services/web/app/views/project/editor/review-panel.pug b/services/web/app/views/project/editor/review-panel.pug index 477d03379a..fe5ada3596 100644 --- a/services/web/app/views/project/editor/review-panel.pug +++ b/services/web/app/views/project/editor/review-panel.pug @@ -87,33 +87,45 @@ ng-if="!reviewPanel.overview.loading" ) .rp-overview-file-header( - ng-if="reviewPanel.entries[doc.doc.id] | notEmpty" + ng-if="(reviewPanel.entries[doc.doc.id] != null) && (reviewPanel.entries[doc.doc.id] | notEmpty)" + ng-click="reviewPanel.overview.docsCollapsedState[doc.doc.id] = ! reviewPanel.overview.docsCollapsedState[doc.doc.id]" ) + span.rp-overview-file-header-collapse( + ng-class="{ 'rp-overview-file-header-collapse-on': reviewPanel.overview.docsCollapsedState[doc.doc.id] }" + ) + i.fa.fa-angle-down | {{ doc.path }} - .rp-entry-wrapper( - ng-repeat="(entry_id, entry) in reviewPanel.entries[doc.doc.id] | orderOverviewEntries" - ng-if="!(entry.type === 'comment' && reviewPanel.commentThreads[entry.thread_id].resolved === true)" - ) - div(ng-if="entry.type === 'insert' || entry.type === 'delete'") - change-entry( - entry="entry" - user="users[entry.metadata.user_id]" - on-indicator-click="toggleReviewPanel();" - ng-click="gotoEntry(doc.doc.id, entry)" - permissions="permissions" - ) + span.rp-overview-file-num-entries( + ng-show="reviewPanel.overview.docsCollapsedState[doc.doc.id]" + )  ({{ reviewPanel.entries[doc.doc.id] | numKeys }}) - div(ng-if="entry.type === 'comment'") - comment-entry( - entry="entry" - threads="reviewPanel.commentThreads" - on-reply="submitReply(entry, entry_id);" - on-save-edit="saveEdit(entry.thread_id, comment)" - on-delete="deleteComment(entry.thread_id, comment)" - on-indicator-click="toggleReviewPanel();" - ng-click="gotoEntry(doc.doc.id, entry)" - permissions="permissions" - ) + .rp-overview-file-entries( + review-panel-collapse-height="reviewPanel.overview.docsCollapsedState[doc.doc.id]" + ) + .rp-entry-wrapper( + ng-repeat="(entry_id, entry) in reviewPanel.entries[doc.doc.id] | orderOverviewEntries" + ng-if="!(entry.type === 'comment' && reviewPanel.commentThreads[entry.thread_id].resolved === true)" + ) + div(ng-if="entry.type === 'insert' || entry.type === 'delete'") + change-entry( + entry="entry" + user="users[entry.metadata.user_id]" + on-indicator-click="toggleReviewPanel();" + ng-click="gotoEntry(doc.doc.id, entry)" + permissions="permissions" + ) + + div(ng-if="entry.type === 'comment'") + comment-entry( + entry="entry" + threads="reviewPanel.commentThreads" + on-reply="submitReply(entry, entry_id);" + on-save-edit="saveEdit(entry.thread_id, comment)" + on-delete="deleteComment(entry.thread_id, comment)" + on-indicator-click="toggleReviewPanel();" + ng-click="gotoEntry(doc.doc.id, entry)" + permissions="permissions" + ) .rp-nav a.rp-nav-item( diff --git a/services/web/public/coffee/ide/review-panel/ReviewPanelManager.coffee b/services/web/public/coffee/ide/review-panel/ReviewPanelManager.coffee index 1565d6db73..9b622ffa05 100644 --- a/services/web/public/coffee/ide/review-panel/ReviewPanelManager.coffee +++ b/services/web/public/coffee/ide/review-panel/ReviewPanelManager.coffee @@ -8,6 +8,8 @@ define [ "ide/review-panel/directives/addCommentEntry" "ide/review-panel/directives/resolvedCommentEntry" "ide/review-panel/directives/resolvedCommentsDropdown" + "ide/review-panel/directives/reviewPanelCollapseHeight" "ide/review-panel/filters/notEmpty" + "ide/review-panel/filters/numKeys" "ide/review-panel/filters/orderOverviewEntries" ], () -> \ No newline at end of file diff --git a/services/web/public/coffee/ide/review-panel/controllers/ReviewPanelController.coffee b/services/web/public/coffee/ide/review-panel/controllers/ReviewPanelController.coffee index 33cfae0982..5067799571 100644 --- a/services/web/public/coffee/ide/review-panel/controllers/ReviewPanelController.coffee +++ b/services/web/public/coffee/ide/review-panel/controllers/ReviewPanelController.coffee @@ -4,7 +4,7 @@ define [ "ide/colors/ColorManager" "ide/review-panel/RangesTracker" ], (App, EventEmitter, ColorManager, RangesTracker) -> - App.controller "ReviewPanelController", ($scope, $element, ide, $timeout, $http, $modal, event_tracking) -> + App.controller "ReviewPanelController", ($scope, $element, ide, $timeout, $http, $modal, event_tracking, localStorage) -> $reviewPanelEl = $element.find "#review-panel" $scope.SubViews = @@ -19,6 +19,7 @@ define [ openSubView: $scope.SubViews.CUR_FILE overview: loading: false + docsCollapsedState: JSON.parse(localStorage("docs_collapsed_state:#{$scope.project_id}")) or {} dropdown: loading: false commentThreads: {} @@ -27,6 +28,14 @@ define [ rendererData: {} loadingThreads: false + window.addEventListener "beforeunload", () -> + collapsedStates = {} + for doc, state of $scope.reviewPanel.overview.docsCollapsedState + if state + collapsedStates[doc] = state + valToStore = if Object.keys(collapsedStates).length > 0 then JSON.stringify(collapsedStates) else null + localStorage("docs_collapsed_state:#{$scope.project_id}", valToStore) + $scope.$on "layout:pdf:linked", (event, state) -> $scope.reviewPanel.layoutToLeft = (state.east?.size < 220 || state.east?.initClosed) $scope.$broadcast "review-panel:layout" @@ -174,6 +183,8 @@ define [ $http.get "/project/#{$scope.project_id}/ranges" .success (docs) -> for doc in docs + if !$scope.reviewPanel.overview.docsCollapsedState[doc.id]? + $scope.reviewPanel.overview.docsCollapsedState[doc.id] = false if doc.id != $scope.editor.open_doc_id # this is kept up to date in real-time, don't overwrite rangesTracker = getChangeTracker(doc.id) rangesTracker.comments = doc.ranges?.comments or [] diff --git a/services/web/public/coffee/ide/review-panel/directives/reviewPanelCollapseHeight.coffee b/services/web/public/coffee/ide/review-panel/directives/reviewPanelCollapseHeight.coffee new file mode 100644 index 0000000000..aef8a91a3b --- /dev/null +++ b/services/web/public/coffee/ide/review-panel/directives/reviewPanelCollapseHeight.coffee @@ -0,0 +1,18 @@ +define [ + "base" +], (App) -> + App.directive "reviewPanelCollapseHeight", ($parse) -> + return { + restrict: "A", + link: (scope, element, attrs) -> + scope.$watch (() -> $parse(attrs.reviewPanelCollapseHeight)(scope)), (shouldCollapse) -> + neededHeight = element.prop("scrollHeight") + if neededHeight > 0 + if shouldCollapse + element.animate { height: 0 }, 150 + else + element.animate { height: neededHeight }, 150 + else + if shouldCollapse + element.height 0 + } \ No newline at end of file diff --git a/services/web/public/coffee/ide/review-panel/filters/numKeys.coffee b/services/web/public/coffee/ide/review-panel/filters/numKeys.coffee new file mode 100644 index 0000000000..c1822d02c9 --- /dev/null +++ b/services/web/public/coffee/ide/review-panel/filters/numKeys.coffee @@ -0,0 +1,9 @@ +define [ + "base" +], (App) -> + app.filter "numKeys", () -> + (object) -> + if object? + return Object.keys(object).length + else + return 0 diff --git a/services/web/public/stylesheets/app/editor/review-panel.less b/services/web/public/stylesheets/app/editor/review-panel.less index 3109a200c3..71cff511d4 100644 --- a/services/web/public/stylesheets/app/editor/review-panel.less +++ b/services/web/public/stylesheets/app/editor/review-panel.less @@ -572,8 +572,28 @@ margin-top: 10px; font-weight: @rp-semibold-weight; text-align: center; + cursor: pointer; } + .rp-overview-file-num-entries { + font-weight: normal; + font-size: 0.9em; + } + .rp-overview-file-header-collapse { + display: inline-block; + float: left; + transform: rotateZ(0deg); + transition: transform 0.15s ease + } + + .rp-overview-file-header-collapse-on { + transform: rotateZ(-90deg); + } + + .rp-overview-file-entries { + overflow: hidden; + } + .rp-comment-wrapper { transition: .35s opacity ease-out .2s;