diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-01 06:10:22 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-01 06:10:22 +0300 |
commit | 4be784ea00ee98983c29568bfc7914e625a98b6e (patch) | |
tree | e107d082f395615e88a287105bb6390482af15f4 /app/assets/javascripts/design_management | |
parent | 57ac0bc8f74b1e21cdc58607e217b79d307e1e40 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/design_management')
5 files changed, 54 insertions, 20 deletions
diff --git a/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue b/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue index 6a20517eed7..cd2545b48de 100644 --- a/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue +++ b/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue @@ -62,22 +62,20 @@ export default { activeDiscussion: { query: activeDiscussionQuery, result({ data }) { - const discussionId = data.activeDiscussion.id; if (this.discussion.resolved && !this.resolvedDiscussionsExpanded) { return; } - // We watch any changes to the active discussion from the design pins and scroll to this discussion if it exists - // We don't want scrollIntoView to be triggered from the discussion click itself - if ( - discussionId && - data.activeDiscussion.source === ACTIVE_DISCUSSION_SOURCE_TYPES.pin && - discussionId === this.discussion.notes[0].id - ) { - this.$el.scrollIntoView({ - behavior: 'smooth', - inline: 'start', - }); - } + + this.$nextTick(() => { + // We watch any changes to the active discussion from the design pins and scroll to this discussion if it exists. + // We don't want scrollIntoView to be triggered from the discussion click itself. + if (this.$el && this.shouldScrollToDiscussion(data.activeDiscussion)) { + this.$el.scrollIntoView({ + behavior: 'smooth', + inline: 'start', + }); + } + }); }, }, }, @@ -136,6 +134,18 @@ export default { isFormVisible() { return this.isFormRendered && this.discussionWithOpenForm === this.discussion.id; }, + shouldScrollToDiscussion(activeDiscussion) { + const ALLOWED_ACTIVE_DISCUSSION_SOURCES = [ + ACTIVE_DISCUSSION_SOURCE_TYPES.pin, + ACTIVE_DISCUSSION_SOURCE_TYPES.url, + ]; + const { id: activeDiscussionId, source: activeDiscussionSource } = activeDiscussion; + + return ( + ALLOWED_ACTIVE_DISCUSSION_SOURCES.includes(activeDiscussionSource) && + activeDiscussionId === this.discussion.notes[0].id + ); + }, }, methods: { addDiscussionComment( diff --git a/app/assets/javascripts/design_management/components/design_notes/design_note.vue b/app/assets/javascripts/design_management/components/design_notes/design_note.vue index 43165261f6b..eab19e38a45 100644 --- a/app/assets/javascripts/design_management/components/design_notes/design_note.vue +++ b/app/assets/javascripts/design_management/components/design_notes/design_note.vue @@ -60,9 +60,11 @@ export default { }, }, mounted() { - if (this.isNoteLinked) { - this.$el.scrollIntoView({ behavior: 'smooth', inline: 'start' }); - } + this.$nextTick(() => { + if (this.isNoteLinked) { + this.$el.scrollIntoView({ behavior: 'smooth', inline: 'start' }); + } + }); }, methods: { hideForm() { diff --git a/app/assets/javascripts/design_management/constants.js b/app/assets/javascripts/design_management/constants.js index 21ff361a277..63a92ef5ec0 100644 --- a/app/assets/javascripts/design_management/constants.js +++ b/app/assets/javascripts/design_management/constants.js @@ -11,6 +11,7 @@ export const VALID_DATA_TRANSFER_TYPE = 'Files'; export const ACTIVE_DISCUSSION_SOURCE_TYPES = { pin: 'pin', discussion: 'discussion', + url: 'url', }; export const DESIGN_DETAIL_LAYOUT_CLASSLIST = ['design-detail-layout', 'overflow-hidden', 'm-0']; diff --git a/app/assets/javascripts/design_management/pages/design/index.vue b/app/assets/javascripts/design_management/pages/design/index.vue index 17b72e73127..93fb9f37b72 100644 --- a/app/assets/javascripts/design_management/pages/design/index.vue +++ b/app/assets/javascripts/design_management/pages/design/index.vue @@ -19,6 +19,8 @@ import { extractDiscussions, extractDesign, updateImageDiffNoteOptimisticResponse, + toDiffNoteGid, + extractDesignNoteId, } from '../../utils/design_management_utils'; import { updateStoreAfterAddImageDiffNote, @@ -145,8 +147,11 @@ export default { mounted() { Mousetrap.bind('esc', this.closeDesign); this.trackEvent(); - // We need to reset the active discussion when opening a new design - this.updateActiveDiscussion(); + + // Set active discussion immediately. + // This will ensure that, if a note is specified in the URL hash, + // the browser will scroll to, and highlight, the note in the UI + this.updateActiveDiscussionFromUrl(); }, beforeDestroy() { Mousetrap.unbind('esc', this.closeDesign); @@ -266,15 +271,20 @@ export default { this.isLatestVersion, ); }, - updateActiveDiscussion(id) { + updateActiveDiscussion(id, source = ACTIVE_DISCUSSION_SOURCE_TYPES.discussion) { this.$apollo.mutate({ mutation: updateActiveDiscussionMutation, variables: { id, - source: ACTIVE_DISCUSSION_SOURCE_TYPES.discussion, + source, }, }); }, + updateActiveDiscussionFromUrl() { + const noteId = extractDesignNoteId(this.$route.hash); + const diffNoteGid = noteId ? toDiffNoteGid(noteId) : undefined; + return this.updateActiveDiscussion(diffNoteGid, ACTIVE_DISCUSSION_SOURCE_TYPES.url); + }, toggleResolvedComments() { this.resolvedDiscussionsExpanded = !this.resolvedDiscussionsExpanded; }, diff --git a/app/assets/javascripts/design_management/utils/design_management_utils.js b/app/assets/javascripts/design_management/utils/design_management_utils.js index da8f89ff960..a5514597fcf 100644 --- a/app/assets/javascripts/design_management/utils/design_management_utils.js +++ b/app/assets/javascripts/design_management/utils/design_management_utils.js @@ -34,6 +34,17 @@ export const extractDesigns = data => data.project.issue.designCollection.design export const extractDesign = data => (extractDesigns(data) || [])[0]; +export const toDiffNoteGid = noteId => `gid://gitlab/DiffNote/${noteId}`; + +/** + * Return the note ID from a URL hash parameter + * @param {String} urlHash URL hash, including `#` prefix + */ +export const extractDesignNoteId = urlHash => { + const [, noteId] = urlHash.match('#note_([0-9]+$)') || []; + return noteId || null; +}; + /** * Generates optimistic response for a design upload mutation * @param {Array<File>} files |