From 14b0a4627211dd123afe1381da5fe093408836ee Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 13 Jun 2019 23:39:39 +0000 Subject: Use scoped routes for labels and milestones Update frontend code to use /-/ scope for milestones and labels routes Signed-off-by: Dmitriy Zaporozhets --- .../filtered_search/available_dropdown_mappings.js | 16 +++++++++++++--- .../filtered_search/filtered_search_dropdown_manager.js | 6 ++++++ .../filtered_search/filtered_search_manager.js | 2 ++ .../javascripts/filtered_search/visual_token_value.js | 8 ++++---- app/helpers/search_helper.rb | 6 ++++++ spec/helpers/search_helper_spec.rb | 12 +++++++++--- .../filtered_search_visual_tokens_spec.js | 4 ++-- .../filtered_search/visual_token_value_spec.js | 4 +++- .../components/sidebar/labels_select/mock_data.js | 4 ++-- 9 files changed, 47 insertions(+), 15 deletions(-) diff --git a/app/assets/javascripts/filtered_search/available_dropdown_mappings.js b/app/assets/javascripts/filtered_search/available_dropdown_mappings.js index be867a3838d..891086b4142 100644 --- a/app/assets/javascripts/filtered_search/available_dropdown_mappings.js +++ b/app/assets/javascripts/filtered_search/available_dropdown_mappings.js @@ -8,9 +8,19 @@ import DropdownUtils from './dropdown_utils'; import { mergeUrlParams } from '../lib/utils/url_utility'; export default class AvailableDropdownMappings { - constructor(container, baseEndpoint, groupsOnly, includeAncestorGroups, includeDescendantGroups) { + constructor( + container, + baseEndpoint, + labelsEndpoint, + milestonesEndpoint, + groupsOnly, + includeAncestorGroups, + includeDescendantGroups, + ) { this.container = container; this.baseEndpoint = baseEndpoint; + this.labelsEndpoint = labelsEndpoint; + this.milestonesEndpoint = milestonesEndpoint; this.groupsOnly = groupsOnly; this.includeAncestorGroups = includeAncestorGroups; this.includeDescendantGroups = includeDescendantGroups; @@ -117,11 +127,11 @@ export default class AvailableDropdownMappings { } getMilestoneEndpoint() { - return `${this.baseEndpoint}/milestones.json`; + return `${this.milestonesEndpoint}.json`; } getLabelsEndpoint() { - let endpoint = `${this.baseEndpoint}/labels.json?`; + let endpoint = `${this.labelsEndpoint}.json?`; if (this.groupsOnly) { endpoint = `${endpoint}only_group_labels=true&`; diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js index cb0a84b490b..1cbfd7f9bb9 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js @@ -9,6 +9,8 @@ import FilteredSearchVisualTokens from './filtered_search_visual_tokens'; export default class FilteredSearchDropdownManager { constructor({ baseEndpoint = '', + labelsEndpoint = '', + milestonesEndpoint = '', tokenizer, page, isGroup, @@ -18,6 +20,8 @@ export default class FilteredSearchDropdownManager { }) { this.container = FilteredSearchContainer.container; this.baseEndpoint = baseEndpoint.replace(/\/$/, ''); + this.labelsEndpoint = labelsEndpoint.replace(/\/$/, ''); + this.milestonesEndpoint = milestonesEndpoint.replace(/\/$/, ''); this.tokenizer = tokenizer; this.filteredSearchTokenKeys = filteredSearchTokenKeys || FilteredSearchTokenKeys; this.filteredSearchInput = this.container.querySelector('.filtered-search'); @@ -48,6 +52,8 @@ export default class FilteredSearchDropdownManager { const availableMappings = new AvailableDropdownMappings( this.container, this.baseEndpoint, + this.labelsEndpoint, + this.milestonesEndpoint, this.groupsOnly, this.includeAncestorGroups, this.includeDescendantGroups, diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js b/app/assets/javascripts/filtered_search/filtered_search_manager.js index 78fbb3696cc..450e0725f2e 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js @@ -86,6 +86,8 @@ export default class FilteredSearchManager { this.tokenizer = FilteredSearchTokenizer; this.dropdownManager = new FilteredSearchDropdownManager({ baseEndpoint: this.filteredSearchInput.getAttribute('data-base-endpoint') || '', + labelsEndpoint: this.filteredSearchInput.getAttribute('data-labels-endpoint') || '', + milestonesEndpoint: this.filteredSearchInput.getAttribute('data-milestones-endpoint') || '', tokenizer: this.tokenizer, page: this.page, isGroup: this.isGroup, diff --git a/app/assets/javascripts/filtered_search/visual_token_value.js b/app/assets/javascripts/filtered_search/visual_token_value.js index 38327472cb3..a54b445fb0a 100644 --- a/app/assets/javascripts/filtered_search/visual_token_value.js +++ b/app/assets/javascripts/filtered_search/visual_token_value.js @@ -56,13 +56,13 @@ export default class VisualTokenValue { updateLabelTokenColor(tokenValueContainer) { const { tokenValue } = this; const filteredSearchInput = FilteredSearchContainer.container.querySelector('.filtered-search'); - const { baseEndpoint } = filteredSearchInput.dataset; - const labelsEndpoint = FilteredSearchVisualTokens.getEndpointWithQueryParams( - `${baseEndpoint}/labels.json`, + const { labelsEndpoint } = filteredSearchInput.dataset; + const labelsEndpointWithParams = FilteredSearchVisualTokens.getEndpointWithQueryParams( + `${labelsEndpoint}.json`, filteredSearchInput.dataset.endpointQueryParams, ); - return AjaxCache.retrieve(labelsEndpoint) + return AjaxCache.retrieve(labelsEndpointWithParams) .then(labels => { const matchingLabel = (labels || []).find( label => `~${DropdownUtils.getEscapedText(label.title)}` === tokenValue, diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index 4594f5a31b9..dfa34ad7020 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -172,11 +172,17 @@ module SearchHelper if @project.present? opts[:data]['project-id'] = @project.id opts[:data]['base-endpoint'] = project_path(@project) + opts[:data]['labels-endpoint'] = project_labels_path(@project) + opts[:data]['milestones-endpoint'] = project_milestones_path(@project) elsif @group.present? opts[:data]['group-id'] = @group.id opts[:data]['base-endpoint'] = group_canonical_path(@group) + opts[:data]['labels-endpoint'] = group_labels_path(@group) + opts[:data]['milestones-endpoint'] = group_milestones_path(@group) else opts[:data]['base-endpoint'] = root_dashboard_path + opts[:data]['labels-endpoint'] = dashboard_labels_path + opts[:data]['milestones-endpoint'] = dashboard_milestones_path end opts diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb index 2f59cfda0a0..da14f7f16fb 100644 --- a/spec/helpers/search_helper_spec.rb +++ b/spec/helpers/search_helper_spec.rb @@ -113,8 +113,10 @@ describe SearchHelper do expect(search_filter_input_options('')[:data]['project-id']).to eq(@project.id) end - it 'includes project base-endpoint' do + it 'includes project endpoints' do expect(search_filter_input_options('')[:data]['base-endpoint']).to eq(project_path(@project)) + expect(search_filter_input_options('')[:data]['labels-endpoint']).to eq(project_labels_path(@project)) + expect(search_filter_input_options('')[:data]['milestones-endpoint']).to eq(project_milestones_path(@project)) end it 'includes autocomplete=off flag' do @@ -131,8 +133,10 @@ describe SearchHelper do expect(search_filter_input_options('')[:data]['project-id']).to eq(nil) end - it 'includes group base-endpoint' do + it 'includes group endpoints' do expect(search_filter_input_options('')[:data]['base-endpoint']).to eq("/groups#{group_path(@group)}") + expect(search_filter_input_options('')[:data]['labels-endpoint']).to eq(group_labels_path(@group)) + expect(search_filter_input_options('')[:data]['milestones-endpoint']).to eq(group_milestones_path(@group)) end end @@ -142,8 +146,10 @@ describe SearchHelper do expect(search_filter_input_options('')[:data]['group-id']).to eq(nil) end - it 'includes dashboard base-endpoint' do + it 'includes dashboard endpoints' do expect(search_filter_input_options('')[:data]['base-endpoint']).to eq("/dashboard") + expect(search_filter_input_options('')[:data]['labels-endpoint']).to eq(dashboard_labels_path) + expect(search_filter_input_options('')[:data]['milestones-endpoint']).to eq(dashboard_milestones_path) end end end diff --git a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js index a72ea6ab547..0ee13faf841 100644 --- a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js @@ -118,7 +118,7 @@ describe('Filtered Search Visual Tokens', () => { describe('getEndpointWithQueryParams', () => { it('returns `endpoint` string as is when second param `endpointQueryParams` is undefined, null or empty string', () => { - const endpoint = 'foo/bar/labels.json'; + const endpoint = 'foo/bar/-/labels.json'; expect(subject.getEndpointWithQueryParams(endpoint)).toBe(endpoint); expect(subject.getEndpointWithQueryParams(endpoint, null)).toBe(endpoint); @@ -126,7 +126,7 @@ describe('Filtered Search Visual Tokens', () => { }); it('returns `endpoint` string with values of `endpointQueryParams`', () => { - const endpoint = 'foo/bar/labels.json'; + const endpoint = 'foo/bar/-/labels.json'; const singleQueryParams = '{"foo":"true"}'; const multipleQueryParams = '{"foo":"true","bar":"true"}'; diff --git a/spec/javascripts/filtered_search/visual_token_value_spec.js b/spec/javascripts/filtered_search/visual_token_value_spec.js index 14217d460cc..d1d16afc977 100644 --- a/spec/javascripts/filtered_search/visual_token_value_spec.js +++ b/spec/javascripts/filtered_search/visual_token_value_spec.js @@ -156,9 +156,11 @@ describe('Filtered Search Visual Tokens', () => { const filteredSearchInput = document.querySelector('.filtered-search'); filteredSearchInput.dataset.baseEndpoint = dummyEndpoint; + filteredSearchInput.dataset.labelsEndpoint = `${dummyEndpoint}/-/labels`; + filteredSearchInput.dataset.milestonesEndpoint = `${dummyEndpoint}/-/milestones`; AjaxCache.internalStorage = {}; - AjaxCache.internalStorage[`${dummyEndpoint}/labels.json`] = labelData; + AjaxCache.internalStorage[`${filteredSearchInput.dataset.labelsEndpoint}.json`] = labelData; }); const parseColor = color => { diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/mock_data.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/mock_data.js index 70025f041a7..6564c012e67 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/mock_data.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/mock_data.js @@ -48,8 +48,8 @@ export const mockConfig = { }, namespace: 'gitlab-org', updatePath: '/gitlab-org/my-project/issue/1', - labelsPath: '/gitlab-org/my-project/labels.json', - labelsWebUrl: '/gitlab-org/my-project/labels', + labelsPath: '/gitlab-org/my-project/-/labels.json', + labelsWebUrl: '/gitlab-org/my-project/-/labels', labelFilterBasePath: '/gitlab-org/my-project/issues', canEdit: true, suggestedColors: mockSuggestedColors, -- cgit v1.2.1