132 lines
3.7 KiB
JavaScript
132 lines
3.7 KiB
JavaScript
import { mapGetters, mapActions, mapState } from 'vuex';
|
|
import { scrollToElementWithContext } from '~/lib/utils/common_utils';
|
|
import eventHub from '../event_hub';
|
|
|
|
/**
|
|
* @param {string} selector
|
|
* @returns {boolean}
|
|
*/
|
|
function scrollTo(selector) {
|
|
const el = document.querySelector(selector);
|
|
|
|
if (el) {
|
|
scrollToElementWithContext(el);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @param {object} self Component instance with mixin applied
|
|
* @param {string} id Discussion id we are jumping to
|
|
*/
|
|
function diffsJump({ expandDiscussion }, id) {
|
|
const selector = `ul.notes[data-discussion-id="${id}"]`;
|
|
eventHub.$once('scrollToDiscussion', () => scrollTo(selector));
|
|
expandDiscussion({ discussionId: id });
|
|
}
|
|
|
|
/**
|
|
* @param {object} self Component instance with mixin applied
|
|
* @param {string} id Discussion id we are jumping to
|
|
* @returns {boolean}
|
|
*/
|
|
function discussionJump({ expandDiscussion }, id) {
|
|
const selector = `div.discussion[data-discussion-id="${id}"]`;
|
|
expandDiscussion({ discussionId: id });
|
|
return scrollTo(selector);
|
|
}
|
|
|
|
/**
|
|
* @param {object} self Component instance with mixin applied
|
|
* @param {string} id Discussion id we are jumping to
|
|
*/
|
|
function switchToDiscussionsTabAndJumpTo(self, id) {
|
|
window.mrTabs.eventHub.$once('MergeRequestTabChange', () => {
|
|
setTimeout(() => discussionJump(self, id), 0);
|
|
});
|
|
|
|
window.mrTabs.tabShown('show');
|
|
}
|
|
|
|
/**
|
|
* @param {object} self Component instance with mixin applied
|
|
* @param {object} discussion Discussion we are jumping to
|
|
*/
|
|
function jumpToDiscussion(self, discussion) {
|
|
const { id, diff_discussion: isDiffDiscussion } = discussion;
|
|
if (id) {
|
|
const activeTab = window.mrTabs.currentAction;
|
|
|
|
if (activeTab === 'diffs' && isDiffDiscussion) {
|
|
diffsJump(self, id);
|
|
} else if (activeTab === 'show') {
|
|
discussionJump(self, id);
|
|
} else {
|
|
switchToDiscussionsTabAndJumpTo(self, id);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {object} self Component instance with mixin applied
|
|
* @param {function} fn Which function used to get the target discussion's id
|
|
* @param {string} [discussionId=this.currentDiscussionId] Current discussion id, will be null if discussions have not been traversed yet
|
|
*/
|
|
function handleDiscussionJump(self, fn, discussionId = self.currentDiscussionId) {
|
|
const isDiffView = window.mrTabs.currentAction === 'diffs';
|
|
const targetId = fn(discussionId, isDiffView);
|
|
const discussion = self.getDiscussion(targetId);
|
|
const discussionFilePath = discussion?.diff_file?.file_path;
|
|
|
|
if (discussionFilePath) {
|
|
self.scrollToFile(discussionFilePath);
|
|
}
|
|
|
|
self.$nextTick(() => {
|
|
jumpToDiscussion(self, discussion);
|
|
self.setCurrentDiscussionId(targetId);
|
|
});
|
|
}
|
|
|
|
export default {
|
|
computed: {
|
|
...mapGetters([
|
|
'nextUnresolvedDiscussionId',
|
|
'previousUnresolvedDiscussionId',
|
|
'getDiscussion',
|
|
]),
|
|
...mapState({
|
|
currentDiscussionId: state => state.notes.currentDiscussionId,
|
|
}),
|
|
},
|
|
methods: {
|
|
...mapActions(['expandDiscussion', 'setCurrentDiscussionId']),
|
|
...mapActions('diffs', ['scrollToFile']),
|
|
|
|
jumpToNextDiscussion() {
|
|
handleDiscussionJump(this, this.nextUnresolvedDiscussionId);
|
|
},
|
|
|
|
jumpToPreviousDiscussion() {
|
|
handleDiscussionJump(this, this.previousUnresolvedDiscussionId);
|
|
},
|
|
|
|
jumpToFirstUnresolvedDiscussion() {
|
|
this.setCurrentDiscussionId(null)
|
|
.then(() => {
|
|
this.jumpToNextDiscussion();
|
|
})
|
|
.catch(() => {});
|
|
},
|
|
|
|
/**
|
|
* Go to the next discussion from the given discussionId
|
|
* @param {String} discussionId The id we are jumping from
|
|
*/
|
|
jumpToNextRelativeDiscussion(discussionId) {
|
|
handleDiscussionJump(this, this.nextUnresolvedDiscussionId, discussionId);
|
|
},
|
|
},
|
|
};
|