diff options
Diffstat (limited to 'app/assets/javascripts/filtered_search')
8 files changed, 101 insertions, 55 deletions
diff --git a/app/assets/javascripts/filtered_search/add_extra_tokens_for_merge_requests.js b/app/assets/javascripts/filtered_search/add_extra_tokens_for_merge_requests.js index d9c627f5c93..397ba879866 100644 --- a/app/assets/javascripts/filtered_search/add_extra_tokens_for_merge_requests.js +++ b/app/assets/javascripts/filtered_search/add_extra_tokens_for_merge_requests.js @@ -1,9 +1,16 @@ -import { __, s__ } from '~/locale'; +import { __ } from '~/locale'; +import { + TOKEN_TITLE_APPROVED_BY, + TOKEN_TITLE_REVIEWER, + TOKEN_TYPE_APPROVED_BY, + TOKEN_TYPE_REVIEWER, + TOKEN_TYPE_TARGET_BRANCH, +} from '~/vue_shared/components/filtered_search_bar/constants'; export default (IssuableTokenKeys, disableTargetBranchFilter = false) => { const reviewerToken = { - formattedKey: s__('SearchToken|Reviewer'), - key: 'reviewer', + formattedKey: TOKEN_TITLE_REVIEWER, + key: TOKEN_TYPE_REVIEWER, type: 'string', param: 'username', symbol: '@', @@ -53,7 +60,7 @@ export default (IssuableTokenKeys, disableTargetBranchFilter = false) => { if (!disableTargetBranchFilter) { const targetBranchToken = { formattedKey: __('Target-Branch'), - key: 'target-branch', + key: TOKEN_TYPE_TARGET_BRANCH, type: 'string', param: '', symbol: '', @@ -67,8 +74,8 @@ export default (IssuableTokenKeys, disableTargetBranchFilter = false) => { const approvedBy = { token: { - formattedKey: __('Approved-By'), - key: 'approved-by', + formattedKey: TOKEN_TITLE_APPROVED_BY, + key: TOKEN_TYPE_APPROVED_BY, type: 'array', param: 'usernames[]', symbol: '@', @@ -76,8 +83,8 @@ export default (IssuableTokenKeys, disableTargetBranchFilter = false) => { tag: '@approved-by', }, tokenAlternative: { - formattedKey: __('Approved-By'), - key: 'approved-by', + formattedKey: TOKEN_TITLE_APPROVED_BY, + key: TOKEN_TYPE_APPROVED_BY, type: 'string', param: 'usernames', symbol: '@', @@ -85,25 +92,25 @@ export default (IssuableTokenKeys, disableTargetBranchFilter = false) => { condition: [ { url: 'approved_by_usernames[]=None', - tokenKey: 'approved-by', + tokenKey: TOKEN_TYPE_APPROVED_BY, value: __('None'), operator: '=', }, { url: 'not[approved_by_usernames][]=None', - tokenKey: 'approved-by', + tokenKey: TOKEN_TYPE_APPROVED_BY, value: __('None'), operator: '!=', }, { url: 'approved_by_usernames[]=Any', - tokenKey: 'approved-by', + tokenKey: TOKEN_TYPE_APPROVED_BY, value: __('Any'), operator: '=', }, { url: 'not[approved_by_usernames][]=Any', - tokenKey: 'approved-by', + tokenKey: TOKEN_TYPE_APPROVED_BY, value: __('Any'), operator: '!=', }, diff --git a/app/assets/javascripts/filtered_search/available_dropdown_mappings.js b/app/assets/javascripts/filtered_search/available_dropdown_mappings.js index 3913e4e8d81..1f8baa470d8 100644 --- a/app/assets/javascripts/filtered_search/available_dropdown_mappings.js +++ b/app/assets/javascripts/filtered_search/available_dropdown_mappings.js @@ -1,5 +1,17 @@ import { sortMilestonesByDueDate } from '~/milestones/utils'; -import { mergeUrlParams } from '../lib/utils/url_utility'; +import { mergeUrlParams } from '~/lib/utils/url_utility'; +import { + TOKEN_TYPE_APPROVED_BY, + TOKEN_TYPE_ASSIGNEE, + TOKEN_TYPE_AUTHOR, + TOKEN_TYPE_CONFIDENTIAL, + TOKEN_TYPE_LABEL, + TOKEN_TYPE_MILESTONE, + TOKEN_TYPE_MY_REACTION, + TOKEN_TYPE_RELEASE, + TOKEN_TYPE_REVIEWER, + TOKEN_TYPE_TARGET_BRANCH, +} from '~/vue_shared/components/filtered_search_bar/constants'; import DropdownEmoji from './dropdown_emoji'; import DropdownHint from './dropdown_hint'; import DropdownNonUser from './dropdown_non_user'; @@ -58,17 +70,17 @@ export default class AvailableDropdownMappings { getMappings() { return { - author: { + [TOKEN_TYPE_AUTHOR]: { reference: null, gl: DropdownUser, element: this.container.querySelector('#js-dropdown-author'), }, - assignee: { + [TOKEN_TYPE_ASSIGNEE]: { reference: null, gl: DropdownUser, element: this.container.querySelector('#js-dropdown-assignee'), }, - reviewer: { + [TOKEN_TYPE_REVIEWER]: { reference: null, gl: DropdownUser, element: this.container.querySelector('#js-dropdown-reviewer'), @@ -78,12 +90,12 @@ export default class AvailableDropdownMappings { gl: DropdownUser, element: this.container.getElementById('js-dropdown-attention-requested'), }, - 'approved-by': { + [TOKEN_TYPE_APPROVED_BY]: { reference: null, gl: DropdownUser, element: this.container.querySelector('#js-dropdown-approved-by'), }, - milestone: { + [TOKEN_TYPE_MILESTONE]: { reference: null, gl: DropdownNonUser, extraArguments: { @@ -93,7 +105,7 @@ export default class AvailableDropdownMappings { }, element: this.container.querySelector('#js-dropdown-milestone'), }, - release: { + [TOKEN_TYPE_RELEASE]: { reference: null, gl: DropdownNonUser, extraArguments: { @@ -106,7 +118,7 @@ export default class AvailableDropdownMappings { }, element: this.container.querySelector('#js-dropdown-release'), }, - label: { + [TOKEN_TYPE_LABEL]: { reference: null, gl: DropdownNonUser, extraArguments: { @@ -116,7 +128,7 @@ export default class AvailableDropdownMappings { }, element: this.container.querySelector('#js-dropdown-label'), }, - 'my-reaction': { + [TOKEN_TYPE_MY_REACTION]: { reference: null, gl: DropdownEmoji, element: this.container.querySelector('#js-dropdown-my-reaction'), @@ -126,12 +138,12 @@ export default class AvailableDropdownMappings { gl: DropdownNonUser, element: this.container.querySelector('#js-dropdown-wip'), }, - confidential: { + [TOKEN_TYPE_CONFIDENTIAL]: { reference: null, gl: DropdownNonUser, element: this.container.querySelector('#js-dropdown-confidential'), }, - 'target-branch': { + [TOKEN_TYPE_TARGET_BRANCH]: { reference: null, gl: DropdownNonUser, extraArguments: { diff --git a/app/assets/javascripts/filtered_search/constants.js b/app/assets/javascripts/filtered_search/constants.js index e07dccd11e8..b328ae6a872 100644 --- a/app/assets/javascripts/filtered_search/constants.js +++ b/app/assets/javascripts/filtered_search/constants.js @@ -1,4 +1,17 @@ -export const USER_TOKEN_TYPES = ['author', 'assignee', 'approved-by', 'reviewer', 'attention']; +import { + TOKEN_TYPE_APPROVED_BY, + TOKEN_TYPE_ASSIGNEE, + TOKEN_TYPE_AUTHOR, + TOKEN_TYPE_REVIEWER, +} from '~/vue_shared/components/filtered_search_bar/constants'; + +export const USER_TOKEN_TYPES = [ + TOKEN_TYPE_AUTHOR, + TOKEN_TYPE_ASSIGNEE, + TOKEN_TYPE_APPROVED_BY, + TOKEN_TYPE_REVIEWER, + 'attention', +]; export const DROPDOWN_TYPE = { hint: 'hint', diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js b/app/assets/javascripts/filtered_search/dropdown_utils.js index 22e1604871a..38909db0555 100644 --- a/app/assets/javascripts/filtered_search/dropdown_utils.js +++ b/app/assets/javascripts/filtered_search/dropdown_utils.js @@ -1,4 +1,5 @@ import { last } from 'lodash'; +import { TOKEN_TYPE_LABEL } from '~/vue_shared/components/filtered_search_bar/constants'; import FilteredSearchContainer from './container'; import FilteredSearchDropdownManager from './filtered_search_dropdown_manager'; import FilteredSearchTokenizer from './filtered_search_tokenizer'; @@ -113,7 +114,7 @@ export default class DropdownUtils { visualToken && visualToken.querySelector('.value') && visualToken.querySelector('.value').textContent.trim(); - if (tokenName === 'label' && tokenValue) { + if (tokenName === TOKEN_TYPE_LABEL && tokenValue) { // remove leading symbol and wrapping quotes tokenValue = tokenValue.replace(/^~("|')?(.*)/, '$2').replace(/("|')$/, ''); } diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js b/app/assets/javascripts/filtered_search/filtered_search_manager.js index bc0f5398b4c..16c70fdd069 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js @@ -10,8 +10,12 @@ import { DOWN_KEY_CODE, } from '~/lib/utils/keycodes'; import { __ } from '~/locale'; -import { addClassIfElementExists } from '../lib/utils/dom_utils'; -import { visitUrl, getUrlParamsArray, getParameterByName } from '../lib/utils/url_utility'; +import { addClassIfElementExists } from '~/lib/utils/dom_utils'; +import { visitUrl, getUrlParamsArray, getParameterByName } from '~/lib/utils/url_utility'; +import { + TOKEN_TYPE_ASSIGNEE, + TOKEN_TYPE_AUTHOR, +} from '~/vue_shared/components/filtered_search_bar/constants'; import FilteredSearchContainer from './container'; import DropdownUtils from './dropdown_utils'; import eventHub from './event_hub'; @@ -675,7 +679,7 @@ export default class FilteredSearchManager { const id = parseInt(value, 10); if (usernameParams[id]) { hasFilteredSearch = true; - const tokenName = 'assignee'; + const tokenName = TOKEN_TYPE_ASSIGNEE; const canEdit = this.canEdit && this.canEdit(tokenName); const operator = FilteredSearchVisualTokens.getOperatorToken(usernameParams[id]); const valueToken = FilteredSearchVisualTokens.getValueToken(usernameParams[id]); @@ -688,7 +692,7 @@ export default class FilteredSearchManager { const id = parseInt(value, 10); if (usernameParams[id]) { hasFilteredSearch = true; - const tokenName = 'author'; + const tokenName = TOKEN_TYPE_AUTHOR; const canEdit = this.canEdit && this.canEdit(tokenName); const operator = FilteredSearchVisualTokens.getOperatorToken(usernameParams[id]); const valueToken = FilteredSearchVisualTokens.getValueToken(usernameParams[id]); diff --git a/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js b/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js index 0c01220a7be..4994559e923 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js +++ b/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js @@ -1,5 +1,6 @@ import { spriteIcon } from '~/lib/utils/common_utils'; import { objectToQuery } from '~/lib/utils/url_utility'; +import { FILTERED_SEARCH_TERM } from '~/vue_shared/components/filtered_search_bar/constants'; import FilteredSearchContainer from './container'; import VisualTokenValue from './visual_token_value'; @@ -38,7 +39,7 @@ export default class FilteredSearchVisualTokens { lastVisualToken, isLastVisualTokenValid: lastVisualToken === null || - lastVisualToken.className.indexOf('filtered-search-term') !== -1 || + lastVisualToken.className.indexOf(FILTERED_SEARCH_TERM) !== -1 || (lastVisualToken && lastVisualToken.querySelector('.operator') !== null && lastVisualToken.querySelector('.value') !== null), @@ -113,7 +114,7 @@ export default class FilteredSearchVisualTokens { } = options; const li = document.createElement('li'); li.classList.add('js-visual-token'); - li.classList.add(isSearchTerm ? 'filtered-search-term' : 'filtered-search-token'); + li.classList.add(isSearchTerm ? FILTERED_SEARCH_TERM : 'filtered-search-token'); if (!isSearchTerm) { li.classList.add(tokenClass); @@ -239,7 +240,7 @@ export default class FilteredSearchVisualTokens { static addSearchVisualToken(searchTerm) { const { lastVisualToken } = FilteredSearchVisualTokens.getLastVisualTokenBeforeInput(); - if (lastVisualToken && lastVisualToken.classList.contains('filtered-search-term')) { + if (lastVisualToken && lastVisualToken.classList.contains(FILTERED_SEARCH_TERM)) { lastVisualToken.querySelector('.name').textContent += ` ${searchTerm}`; } else { FilteredSearchVisualTokens.addVisualTokenElement({ diff --git a/app/assets/javascripts/filtered_search/issuable_filtered_search_token_keys.js b/app/assets/javascripts/filtered_search/issuable_filtered_search_token_keys.js index d6e7887f93f..8aa99ec52f9 100644 --- a/app/assets/javascripts/filtered_search/issuable_filtered_search_token_keys.js +++ b/app/assets/javascripts/filtered_search/issuable_filtered_search_token_keys.js @@ -7,13 +7,20 @@ import { TOKEN_TITLE_MILESTONE, TOKEN_TITLE_MY_REACTION, TOKEN_TITLE_RELEASE, + TOKEN_TYPE_ASSIGNEE, + TOKEN_TYPE_AUTHOR, + TOKEN_TYPE_LABEL, + TOKEN_TYPE_MILESTONE, + TOKEN_TYPE_MY_REACTION, + TOKEN_TYPE_RELEASE, + TOKEN_TYPE_REVIEWER, } from '~/vue_shared/components/filtered_search_bar/constants'; import FilteredSearchTokenKeys from './filtered_search_token_keys'; export const tokenKeys = [ { formattedKey: TOKEN_TITLE_AUTHOR, - key: 'author', + key: TOKEN_TYPE_AUTHOR, type: 'string', param: 'username', symbol: '@', @@ -22,7 +29,7 @@ export const tokenKeys = [ }, { formattedKey: TOKEN_TITLE_ASSIGNEE, - key: 'assignee', + key: TOKEN_TYPE_ASSIGNEE, type: 'string', param: 'username', symbol: '@', @@ -31,7 +38,7 @@ export const tokenKeys = [ }, { formattedKey: TOKEN_TITLE_MILESTONE, - key: 'milestone', + key: TOKEN_TYPE_MILESTONE, type: 'string', param: 'title', symbol: '%', @@ -40,7 +47,7 @@ export const tokenKeys = [ }, { formattedKey: TOKEN_TITLE_RELEASE, - key: 'release', + key: TOKEN_TYPE_RELEASE, type: 'string', param: 'tag', symbol: '', @@ -49,7 +56,7 @@ export const tokenKeys = [ }, { formattedKey: TOKEN_TITLE_LABEL, - key: 'label', + key: TOKEN_TYPE_LABEL, type: 'array', param: 'name[]', symbol: '~', @@ -62,7 +69,7 @@ if (gon.current_user_id) { // Appending tokenkeys only logged-in tokenKeys.push({ formattedKey: TOKEN_TITLE_MY_REACTION, - key: 'my-reaction', + key: TOKEN_TYPE_MY_REACTION, type: 'string', param: 'emoji', symbol: '', @@ -74,7 +81,7 @@ if (gon.current_user_id) { export const alternativeTokenKeys = [ { formattedKey: TOKEN_TITLE_LABEL, - key: 'label', + key: TOKEN_TYPE_LABEL, type: 'string', param: 'name', symbol: '~', @@ -85,77 +92,77 @@ export const conditions = flattenDeep( [ { url: 'assignee_id=None', - tokenKey: 'assignee', + tokenKey: TOKEN_TYPE_ASSIGNEE, value: __('None'), }, { url: 'assignee_id=Any', - tokenKey: 'assignee', + tokenKey: TOKEN_TYPE_ASSIGNEE, value: __('Any'), }, { url: 'reviewer_id=None', - tokenKey: 'reviewer', + tokenKey: TOKEN_TYPE_REVIEWER, value: __('None'), }, { url: 'reviewer_id=Any', - tokenKey: 'reviewer', + tokenKey: TOKEN_TYPE_REVIEWER, value: __('Any'), }, { url: 'author_username=support-bot', - tokenKey: 'author', + tokenKey: TOKEN_TYPE_AUTHOR, value: 'support-bot', }, { url: 'milestone_title=None', - tokenKey: 'milestone', + tokenKey: TOKEN_TYPE_MILESTONE, value: __('None'), }, { url: 'milestone_title=Any', - tokenKey: 'milestone', + tokenKey: TOKEN_TYPE_MILESTONE, value: __('Any'), }, { url: 'milestone_title=%23upcoming', - tokenKey: 'milestone', + tokenKey: TOKEN_TYPE_MILESTONE, value: __('Upcoming'), }, { url: 'milestone_title=%23started', - tokenKey: 'milestone', + tokenKey: TOKEN_TYPE_MILESTONE, value: __('Started'), }, { url: 'release_tag=None', - tokenKey: 'release', + tokenKey: TOKEN_TYPE_RELEASE, value: __('None'), }, { url: 'release_tag=Any', - tokenKey: 'release', + tokenKey: TOKEN_TYPE_RELEASE, value: __('Any'), }, { url: 'label_name[]=None', - tokenKey: 'label', + tokenKey: TOKEN_TYPE_LABEL, value: __('None'), }, { url: 'label_name[]=Any', - tokenKey: 'label', + tokenKey: TOKEN_TYPE_LABEL, value: __('Any'), }, { url: 'my_reaction_emoji=None', - tokenKey: 'my-reaction', + tokenKey: TOKEN_TYPE_MY_REACTION, value: __('None'), }, { url: 'my_reaction_emoji=Any', - tokenKey: 'my-reaction', + tokenKey: TOKEN_TYPE_MY_REACTION, value: __('Any'), }, ].map((condition) => { diff --git a/app/assets/javascripts/filtered_search/visual_token_value.js b/app/assets/javascripts/filtered_search/visual_token_value.js index 1ad2006d689..33fda7533e4 100644 --- a/app/assets/javascripts/filtered_search/visual_token_value.js +++ b/app/assets/javascripts/filtered_search/visual_token_value.js @@ -8,6 +8,7 @@ import { createAlert } from '~/flash'; import AjaxCache from '~/lib/utils/ajax_cache'; import UsersCache from '~/lib/utils/users_cache'; import { __ } from '~/locale'; +import { TOKEN_TYPE_LABEL } from '~/vue_shared/components/filtered_search_bar/constants'; export default class VisualTokenValue { constructor(tokenValue, tokenType, tokenOperator) { @@ -23,7 +24,7 @@ export default class VisualTokenValue { return; } - if (tokenType === 'label') { + if (tokenType === TOKEN_TYPE_LABEL) { this.updateLabelTokenColor(tokenValueContainer); } else if (USER_TOKEN_TYPES.includes(tokenType)) { this.updateUserTokenAppearance(tokenValueContainer, tokenValueElement); |