summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConstance Okoghenun <cokoghenun@gitlab.com>2019-01-10 14:00:36 +0000
committerPhil Hughes <me@iamphill.com>2019-01-10 14:00:36 +0000
commit211c946a672c1500cb512d13438d60658b07b9cd (patch)
tree52f1d814f5c999a8c9340a94f42114685a8eb8e2
parentbe855cc6a2b85da2ec3e51e0f767099dc87991e6 (diff)
downloadgitlab-ce-211c946a672c1500cb512d13438d60658b07b9cd.tar.gz
Discussion filters - ensured note links resolves to the right note
-rw-r--r--app/assets/javascripts/notes/components/discussion_filter.vue23
-rw-r--r--changelogs/unreleased/54484-anchor-links-to-comments-or-system-notes-can-break-with-discussion-filters.yml5
-rw-r--r--spec/javascripts/notes/components/discussion_filter_spec.js46
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();
+ });
+ });
+ });
});