diff options
author | Douwe Maan <douwe@selenight.nl> | 2016-08-04 18:01:32 -0700 |
---|---|---|
committer | Douwe Maan <douwe@selenight.nl> | 2016-08-04 18:01:32 -0700 |
commit | ffbba55bc822c6cd019ff6b1495335cc1426def0 (patch) | |
tree | 04018133a71b72a19edd0ec53c68e1730957f8ac /app/assets/javascripts/diff_notes | |
parent | 9b115ce4d3ccdd03043f070935d3a25e96f537f4 (diff) | |
download | gitlab-ce-ffbba55bc822c6cd019ff6b1495335cc1426def0.tar.gz |
Implement Jump behavior for Changes tab
Diffstat (limited to 'app/assets/javascripts/diff_notes')
4 files changed, 127 insertions, 28 deletions
diff --git a/app/assets/javascripts/diff_notes/components/jump_to_discussion.js.es6 b/app/assets/javascripts/diff_notes/components/jump_to_discussion.js.es6 index 83417a2703e..a2998add26c 100644 --- a/app/assets/javascripts/diff_notes/components/jump_to_discussion.js.es6 +++ b/app/assets/javascripts/diff_notes/components/jump_to_discussion.js.es6 @@ -43,37 +43,137 @@ }, methods: { jumpToNextUnresolvedDiscussion: function () { - let unresolvedIds = CommentsStore.unresolvedDiscussionIds(), - nextUnresolvedDiscussionId; - const activePage = $('.merge-request-tabs .active a').attr('data-action'), - $diffDiscussions = $('.discussion').filter(function () { - return unresolvedIds.indexOf($(this).attr('data-discussion-id')) !== -1; - }); - - unresolvedIds = unresolvedIds.sort(function (a, b) { - return $diffDiscussions.index(`[data-discussion-id="${b}"]`) > $diffDiscussions.index(`[data-discussion-id="${a}"]`); - }); + let discussionsSelector, + discussionIdsInScope, + firstUnresolvedDiscussionId, + nextUnresolvedDiscussionId, + activeTab = window.mrTabs.currentAction, + hasDiscussionsToJumpTo = true, + jumpToFirstDiscussion = !this.discussionId; + + const discussionIdsForElements = function(elements) { + return elements.map(function() { + return $(this).attr('data-discussion-id'); + }).toArray(); + }; + + const discussions = this.discussions; + + if (activeTab === 'diffs') { + discussionsSelector = '.diffs .notes[data-discussion-id]'; + discussionIdsInScope = discussionIdsForElements($(discussionsSelector)); - unresolvedIds.forEach(function (discussionId, i) { - if (this.discussionId && discussionId === this.discussionId) { - nextUnresolvedDiscussionId = unresolvedIds[i + 1]; - return; + let unresolvedDiscussionCount = 0; + for (const discussionId of discussionIdsInScope) { + const discussion = discussions[discussionId]; + if (discussion && !discussion.isResolved()) { + unresolvedDiscussionCount++; + } } - }.bind(this)); - nextUnresolvedDiscussionId = nextUnresolvedDiscussionId || unresolvedIds[0]; + if (this.discussionId && !this.discussion.isResolved()) { + // If this is the last unresolved discussion on the diffs tab, + // there are no discussions to jump to. + if (unresolvedDiscussionCount === 1) { + hasDiscussionsToJumpTo = false; + } + } else { + // If there are no unresolved discussions on the diffs tab at all, + // there are no discussions to jump to. + if (unresolvedDiscussionCount === 0) { + hasDiscussionsToJumpTo = false; + } + } + } else if (activeTab !== 'notes') { + // If we are on the commits or builds tabs, + // there are no discussions to jump to. + hasDiscussionsToJumpTo = false; + } - if (nextUnresolvedDiscussionId) { - let selector = '.discussion'; + if (!hasDiscussionsToJumpTo) { + // If there are no discussions to jump to on the current page, + // switch to the notes tab and jump to the first disucssion there. + window.mrTabs.activateTab('notes'); + activeTab = 'notes'; + jumpToFirstDiscussion = true; + } - if (activePage === 'diffs' && $(`${selector}[data-discussion-id="${nextUnresolvedDiscussionId}"]`).length) { - selector = '.diffs .notes'; + if (activeTab === 'notes') { + discussionsSelector = '.discussion[data-discussion-id]'; + discussionIdsInScope = discussionIdsForElements($(discussionsSelector)); + } + + let currentDiscussionFound = false; + for (const discussionId of discussionIdsInScope) { + const discussion = discussions[discussionId]; + + if (!discussion) { + // Discussions for comments on commits in this MR don't have a resolved status. + continue; } - $.scrollTo(`${selector}[data-discussion-id="${nextUnresolvedDiscussionId}"]`, { - offset: -($('.navbar-gitlab').outerHeight() + $('.layout-nav').outerHeight()) - }); + if (!firstUnresolvedDiscussionId && !discussion.isResolved()) { + firstUnresolvedDiscussionId = discussionId; + + if (jumpToFirstDiscussion) { + break; + } + } + + if (!jumpToFirstDiscussion) { + if (currentDiscussionFound) { + if (!discussion.isResolved()) { + nextUnresolvedDiscussionId = discussionId; + break; + } + else { + continue; + } + } + + if (discussionId === this.discussionId) { + currentDiscussionFound = true; + } + } + } + + nextUnresolvedDiscussionId = nextUnresolvedDiscussionId || firstUnresolvedDiscussionId; + + if (!nextUnresolvedDiscussionId) { + return; + } + + let $target = $(`${discussionsSelector}[data-discussion-id="${nextUnresolvedDiscussionId}"]`); + + if (activeTab === 'notes') { + $target = $target.closest('.note-discussion'); + } else if (activeTab === 'diffs') { + // Resolved discussions are hidden in the diffs tab by default. + // If they are marked unresolved on the notes tab, they will still be hidden on the diffs tab. + // When jumping between unresolved discussions on the diffs tab, we show them. + $target.closest(".content").show(); + + $target = $target.closest("tr.notes_holder"); + $target.show(); + + // If we are on the diffs tab, we don't scroll to the discussion itself, but to + // 4 diff lines above it: the line the discussion was in response to + 3 context + let prevEl; + for (let i = 0; i < 4; i++) { + prevEl = $target.prev(); + + // If the discussion doesn't have 4 lines above it, we'll have to do with fewer. + if (!prevEl.hasClass("line_holder")) { + break; + } + + $target = prevEl; + } } + + $.scrollTo($target, { + offset: -($('.navbar-gitlab').outerHeight() + $('.layout-nav').outerHeight()) + }); } } }); diff --git a/app/assets/javascripts/diff_notes/components/resolve_count.js.es6 b/app/assets/javascripts/diff_notes/components/resolve_count.js.es6 index c69a8a4542f..9e383b14a3e 100644 --- a/app/assets/javascripts/diff_notes/components/resolve_count.js.es6 +++ b/app/assets/javascripts/diff_notes/components/resolve_count.js.es6 @@ -11,7 +11,7 @@ }, computed: { allResolved: function () { - return this.resolved === this.discussionCount; + return this.resolvedDiscussionCount === this.discussionCount; } } }); diff --git a/app/assets/javascripts/diff_notes/mixins/discussion.js.es6 b/app/assets/javascripts/diff_notes/mixins/discussion.js.es6 index 34f3b200e48..a05f885201d 100644 --- a/app/assets/javascripts/diff_notes/mixins/discussion.js.es6 +++ b/app/assets/javascripts/diff_notes/mixins/discussion.js.es6 @@ -4,7 +4,7 @@ discussionCount: function () { return Object.keys(this.discussions).length; }, - resolved: function () { + resolvedDiscussionCount: function () { let resolvedCount = 0; for (const discussionId in this.discussions) { @@ -19,6 +19,7 @@ }, unresolvedDiscussionCount: function () { let unresolvedCount = 0; + for (const discussionId in this.discussions) { const discussion = this.discussions[discussionId]; diff --git a/app/assets/javascripts/diff_notes/services/resolve.js.es6 b/app/assets/javascripts/diff_notes/services/resolve.js.es6 index 5e5c476b514..de771ff814b 100644 --- a/app/assets/javascripts/diff_notes/services/resolve.js.es6 +++ b/app/assets/javascripts/diff_notes/services/resolve.js.es6 @@ -11,9 +11,7 @@ prepareRequest(namespace) { this.setCSRF(); - if (Vue.http.options.root !== `/${namespace}`) { - Vue.http.options.root = `/${namespace}`; - } + Vue.http.options.root = `/${namespace}`; } resolve(namespace, noteId) { |