diff options
author | Constance Okoghenun <cokoghenun@gitlab.com> | 2019-01-10 14:00:36 +0000 |
---|---|---|
committer | Phil Hughes <me@iamphill.com> | 2019-01-10 14:00:36 +0000 |
commit | 211c946a672c1500cb512d13438d60658b07b9cd (patch) | |
tree | 52f1d814f5c999a8c9340a94f42114685a8eb8e2 | |
parent | be855cc6a2b85da2ec3e51e0f767099dc87991e6 (diff) | |
download | gitlab-ce-211c946a672c1500cb512d13438d60658b07b9cd.tar.gz |
Discussion filters - ensured note links resolves to the right note
3 files changed, 67 insertions, 7 deletions
diff --git a/app/assets/javascripts/notes/components/discussion_filter.vue b/app/assets/javascripts/notes/components/discussion_filter.vue index f5c410211b6..2d7c04ea614 100644 --- a/app/assets/javascripts/notes/components/discussion_filter.vue +++ b/app/assets/javascripts/notes/components/discussion_filter.vue @@ -1,6 +1,7 @@ <script> import $ from 'jquery'; import { mapGetters, mapActions } from 'vuex'; +import { getLocationHash } from '../../lib/utils/url_utility'; import Icon from '~/vue_shared/components/icon.vue'; import { DISCUSSION_FILTERS_DEFAULT_VALUE, @@ -44,29 +45,47 @@ export default { eventHub.$on('MergeRequestTabChange', this.toggleFilters); this.toggleFilters(currentTab); } + + window.addEventListener('hashchange', this.handleLocationHash); + this.handleLocationHash(); }, mounted() { this.toggleCommentsForm(); }, + destroyed() { + window.removeEventListener('hashchange', this.handleLocationHash); + }, methods: { - ...mapActions(['filterDiscussion', 'setCommentsDisabled']), + ...mapActions(['filterDiscussion', 'setCommentsDisabled', 'setTargetNoteHash']), selectFilter(value) { const filter = parseInt(value, 10); // close dropdown - $(this.$refs.dropdownToggle).dropdown('toggle'); + this.toggleDropdown(); if (filter === this.currentValue) return; this.currentValue = filter; this.filterDiscussion({ path: this.getNotesDataByProp('discussionsPath'), filter }); this.toggleCommentsForm(); }, + toggleDropdown() { + $(this.$refs.dropdownToggle).dropdown('toggle'); + }, toggleCommentsForm() { this.setCommentsDisabled(this.currentValue === HISTORY_ONLY_FILTER_VALUE); }, toggleFilters(tab) { this.displayFilters = tab === DISCUSSION_TAB_LABEL; }, + handleLocationHash() { + const hash = getLocationHash(); + + if (/^note_/.test(hash) && this.currentValue !== DISCUSSION_FILTERS_DEFAULT_VALUE) { + this.selectFilter(this.defaultValue); + this.toggleDropdown(); // close dropdown + this.setTargetNoteHash(hash); + } + }, }, }; </script> diff --git a/changelogs/unreleased/54484-anchor-links-to-comments-or-system-notes-can-break-with-discussion-filters.yml b/changelogs/unreleased/54484-anchor-links-to-comments-or-system-notes-can-break-with-discussion-filters.yml new file mode 100644 index 00000000000..4d543db567d --- /dev/null +++ b/changelogs/unreleased/54484-anchor-links-to-comments-or-system-notes-can-break-with-discussion-filters.yml @@ -0,0 +1,5 @@ +--- +title: Ensured links to a comment or system note anchor resolves to the right note if a user has a discussion filter. +merge_request: 24228 +author: +type: changed diff --git a/spec/javascripts/notes/components/discussion_filter_spec.js b/spec/javascripts/notes/components/discussion_filter_spec.js index 5efcab436e4..91dab58ba7f 100644 --- a/spec/javascripts/notes/components/discussion_filter_spec.js +++ b/spec/javascripts/notes/components/discussion_filter_spec.js @@ -1,6 +1,7 @@ import Vue from 'vue'; import createStore from '~/notes/stores'; import DiscussionFilter from '~/notes/components/discussion_filter.vue'; +import { DISCUSSION_FILTERS_DEFAULT_VALUE } from '~/notes/constants'; import { mountComponentWithStore } from '../../helpers/vue_mount_component_helper'; import { discussionFiltersMock, discussionMock } from '../mock_data'; @@ -20,16 +21,14 @@ describe('DiscussionFilter component', () => { }, ]; const Component = Vue.extend(DiscussionFilter); - const selectedValue = discussionFiltersMock[0].value; + const selectedValue = DISCUSSION_FILTERS_DEFAULT_VALUE; + const props = { filters: discussionFiltersMock, selectedValue }; store.state.discussions = discussions; return mountComponentWithStore(Component, { el: null, store, - props: { - filters: discussionFiltersMock, - selectedValue, - }, + props, }); }; @@ -115,4 +114,41 @@ describe('DiscussionFilter component', () => { }); }); }); + + describe('URL with Links to notes', () => { + afterEach(() => { + window.location.hash = ''; + }); + + it('updates the filter when the URL links to a note', done => { + window.location.hash = `note_${discussionMock.notes[0].id}`; + vm.currentValue = discussionFiltersMock[2].value; + vm.handleLocationHash(); + + vm.$nextTick(() => { + expect(vm.currentValue).toEqual(DISCUSSION_FILTERS_DEFAULT_VALUE); + done(); + }); + }); + + it('does not update the filter when the current filter is "Show all activity"', done => { + window.location.hash = `note_${discussionMock.notes[0].id}`; + vm.handleLocationHash(); + + vm.$nextTick(() => { + expect(vm.currentValue).toEqual(DISCUSSION_FILTERS_DEFAULT_VALUE); + done(); + }); + }); + + it('only updates filter when the URL links to a note', done => { + window.location.hash = `testing123`; + vm.handleLocationHash(); + + vm.$nextTick(() => { + expect(vm.currentValue).toEqual(DISCUSSION_FILTERS_DEFAULT_VALUE); + done(); + }); + }); + }); }); |