diff options
Diffstat (limited to 'app/assets/javascripts/filtered_search')
4 files changed, 59 insertions, 17 deletions
diff --git a/app/assets/javascripts/filtered_search/available_dropdown_mappings.js b/app/assets/javascripts/filtered_search/available_dropdown_mappings.js index 5450abf4cbd..692b41da965 100644 --- a/app/assets/javascripts/filtered_search/available_dropdown_mappings.js +++ b/app/assets/javascripts/filtered_search/available_dropdown_mappings.js @@ -9,7 +9,7 @@ import DropdownUtils from './dropdown_utils'; import { mergeUrlParams } from '../lib/utils/url_utility'; export default class AvailableDropdownMappings { - constructor( + constructor({ container, runnerTagsEndpoint, labelsEndpoint, @@ -18,7 +18,7 @@ export default class AvailableDropdownMappings { groupsOnly, includeAncestorGroups, includeDescendantGroups, - ) { + }) { this.container = container; this.runnerTagsEndpoint = runnerTagsEndpoint; this.labelsEndpoint = labelsEndpoint; 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 566fb295588..03f65612b60 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js @@ -13,6 +13,7 @@ export default class FilteredSearchDropdownManager { labelsEndpoint = '', milestonesEndpoint = '', releasesEndpoint = '', + epicsEndpoint = '', tokenizer, page, isGroup, @@ -27,6 +28,7 @@ export default class FilteredSearchDropdownManager { this.labelsEndpoint = removeTrailingSlash(labelsEndpoint); this.milestonesEndpoint = removeTrailingSlash(milestonesEndpoint); this.releasesEndpoint = removeTrailingSlash(releasesEndpoint); + this.epicsEndpoint = removeTrailingSlash(epicsEndpoint); this.tokenizer = tokenizer; this.filteredSearchTokenKeys = filteredSearchTokenKeys || FilteredSearchTokenKeys; this.filteredSearchInput = this.container.querySelector('.filtered-search'); @@ -54,16 +56,8 @@ export default class FilteredSearchDropdownManager { setupMapping() { const supportedTokens = this.filteredSearchTokenKeys.getKeys(); - const availableMappings = new AvailableDropdownMappings( - this.container, - this.runnerTagsEndpoint, - this.labelsEndpoint, - this.milestonesEndpoint, - this.releasesEndpoint, - this.groupsOnly, - this.includeAncestorGroups, - this.includeDescendantGroups, - ); + + const availableMappings = new AvailableDropdownMappings({ ...this }); this.mapping = availableMappings.getAllowedMappings(supportedTokens); } diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js b/app/assets/javascripts/filtered_search/filtered_search_manager.js index 0b4f9457c54..e9a714605c7 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js @@ -45,6 +45,11 @@ export default class FilteredSearchManager { this.filteredSearchTokenKeys.enableMultipleAssignees(); } + const { epicsEndpoint } = this.filteredSearchInput.dataset; + if (!epicsEndpoint && this.filteredSearchTokenKeys.removeEpicToken) { + this.filteredSearchTokenKeys.removeEpicToken(); + } + this.recentSearchesStore = new RecentSearchesStore({ isLocalStorageAvailable: RecentSearchesService.isAvailable(), allowedKeys: this.filteredSearchTokenKeys.getKeys(), @@ -88,12 +93,20 @@ export default class FilteredSearchManager { if (this.filteredSearchInput) { this.tokenizer = FilteredSearchTokenizer; + const { + runnerTagsEndpoint = '', + labelsEndpoint = '', + milestonesEndpoint = '', + releasesEndpoint = '', + epicsEndpoint = '', + } = this.filteredSearchInput.dataset; + this.dropdownManager = new FilteredSearchDropdownManager({ - runnerTagsEndpoint: - this.filteredSearchInput.getAttribute('data-runner-tags-endpoint') || '', - labelsEndpoint: this.filteredSearchInput.getAttribute('data-labels-endpoint') || '', - milestonesEndpoint: this.filteredSearchInput.getAttribute('data-milestones-endpoint') || '', - releasesEndpoint: this.filteredSearchInput.getAttribute('data-releases-endpoint') || '', + runnerTagsEndpoint, + labelsEndpoint, + milestonesEndpoint, + releasesEndpoint, + epicsEndpoint, 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 9f3cf881af4..b7ac655b619 100644 --- a/app/assets/javascripts/filtered_search/visual_token_value.js +++ b/app/assets/javascripts/filtered_search/visual_token_value.js @@ -28,6 +28,8 @@ export default class VisualTokenValue { this.updateUserTokenAppearance(tokenValueContainer, tokenValueElement); } else if (tokenType === 'my-reaction') { this.updateEmojiTokenAppearance(tokenValueContainer, tokenValueElement); + } else if (tokenType === 'epic') { + this.updateEpicLabel(tokenValueContainer, tokenValueElement); } } @@ -83,6 +85,39 @@ export default class VisualTokenValue { .catch(() => new Flash(__('An error occurred while fetching label colors.'))); } + updateEpicLabel(tokenValueContainer) { + const tokenValue = this.tokenValue.replace(/^&/, ''); + const filteredSearchInput = FilteredSearchContainer.container.querySelector('.filtered-search'); + const { epicsEndpoint } = filteredSearchInput.dataset; + const epicsEndpointWithParams = FilteredSearchVisualTokens.getEndpointWithQueryParams( + `${epicsEndpoint}.json`, + filteredSearchInput.dataset.endpointQueryParams, + ); + + return AjaxCache.retrieve(epicsEndpointWithParams) + .then(epics => { + const matchingEpic = (epics || []).find(epic => epic.id === Number(tokenValue)); + + if (!matchingEpic) { + return; + } + + VisualTokenValue.replaceEpicTitle(tokenValueContainer, matchingEpic.title, matchingEpic.id); + }) + .catch(() => new Flash(__('An error occurred while adding formatted title for epic'))); + } + + static replaceEpicTitle(tokenValueContainer, epicTitle, epicId) { + const tokenContainer = tokenValueContainer; + + const valueContainer = tokenContainer.querySelector('.value'); + + if (valueContainer) { + tokenContainer.dataset.originalValue = valueContainer.innerText; + valueContainer.innerText = `"${epicTitle}"::&${epicId}`; + } + } + static setTokenStyle(tokenValueContainer, backgroundColor, textColor) { const token = tokenValueContainer; |