diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-11-08 12:12:25 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-11-08 12:12:25 +0300 |
commit | a130bdc4dd6f78e1605b79b77929c9315b322be3 (patch) | |
tree | 8ea70694cdfb038e8d19ea7d23bedfd2d08f212e /app/assets/javascripts/work_items/components | |
parent | e808a772e795130cb3c7c1cc9673a1205f4ccade (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/work_items/components')
-rw-r--r-- | app/assets/javascripts/work_items/components/shared/work_item_token_input.vue | 120 | ||||
-rw-r--r-- | app/assets/javascripts/work_items/components/work_item_parent.vue | 2 |
2 files changed, 89 insertions, 33 deletions
diff --git a/app/assets/javascripts/work_items/components/shared/work_item_token_input.vue b/app/assets/javascripts/work_items/components/shared/work_item_token_input.vue index ce3d4749f17..c122db6c902 100644 --- a/app/assets/javascripts/work_items/components/shared/work_item_token_input.vue +++ b/app/assets/javascripts/work_items/components/shared/work_item_token_input.vue @@ -1,21 +1,28 @@ <script> -import { GlTokenSelector } from '@gitlab/ui'; +import { GlTokenSelector, GlAlert } from '@gitlab/ui'; import { debounce } from 'lodash'; + import { getIdFromGraphQLId } from '~/graphql_shared/utils'; +import { isNumeric } from '~/lib/utils/number_utils'; import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; +import SafeHtml from '~/vue_shared/directives/safe_html'; +import { highlighter } from 'ee_else_ce/gfm_auto_complete'; import groupWorkItemsQuery from '../../graphql/group_work_items.query.graphql'; import projectWorkItemsQuery from '../../graphql/project_work_items.query.graphql'; import { WORK_ITEMS_TYPE_MAP, I18N_WORK_ITEM_SEARCH_INPUT_PLACEHOLDER, + I18N_WORK_ITEM_SEARCH_ERROR, sprintfWorkItem, } from '../../constants'; export default { components: { GlTokenSelector, + GlAlert, }, + directives: { SafeHtml }, inject: ['isGroup'], props: { value: { @@ -55,26 +62,31 @@ export default { variables() { return { fullPath: this.fullPath, - searchTerm: this.search?.title || this.search, + searchTerm: '', types: this.childrenType ? [this.childrenType] : [], - in: this.search ? 'TITLE' : undefined, + isNumber: false, }; }, skip() { return !this.searchStarted; }, update(data) { - return data.workspace.workItems.nodes.filter( - (wi) => !this.childrenIds.includes(wi.id) && this.parentWorkItemId !== wi.id, - ); + return [ + ...this.filterItems(data.workspace.workItemsByIid?.nodes), + ...this.filterItems(data.workspace.workItems.nodes), + ]; + }, + error() { + this.error = sprintfWorkItem(I18N_WORK_ITEM_SEARCH_ERROR, this.childrenTypeName); }, }, }, data() { return { availableWorkItems: [], - search: '', + query: '', searchStarted: false, + error: '', }; }, computed: { @@ -105,7 +117,24 @@ export default { methods: { getIdFromGraphQLId, setSearchKey(value) { - this.search = value; + this.query = value; + + // Query parameters for searching by text + const variables = { + searchTerm: value, + in: value ? 'TITLE' : undefined, + iid: null, + isNumber: false, + }; + + // Check if it is a number, add iid as query parameter + if (isNumeric(value) && value) { + variables.iid = value; + variables.isNumber = true; + } + + // Fetch combined results of search by iid and search by title. + this.$apollo.queries.availableWorkItems.refetch(variables); }, handleFocus() { this.searchStarted = true; @@ -129,33 +158,58 @@ export default { } }); }, + formatResults(input) { + if (!this.query) { + return input; + } + + return highlighter(`<span class="gl-text-black-normal">${input}</span>`, this.query); + }, + unsetError() { + this.error = ''; + }, + filterItems(items) { + return ( + items?.filter( + (wi) => !this.childrenIds.includes(wi.id) && this.parentWorkItemId !== wi.id, + ) || [] + ); + }, }, }; </script> <template> - <gl-token-selector - ref="tokenSelector" - v-model="workItemsToAdd" - :dropdown-items="availableWorkItems" - :loading="isLoading" - :placeholder="addInputPlaceholder" - menu-class="gl-dropdown-menu-wide dropdown-reduced-height gl-min-h-7!" - :container-class="tokenSelectorContainerClass" - data-testid="work-item-token-select-input" - @text-input="debouncedSearchKeyUpdate" - @focus="handleFocus" - @mouseover.native="handleMouseOver" - @mouseout.native="handleMouseOut" - @token-add="focusInputText" - @token-remove="focusInputText" - @blur="handleBlur" - > - <template #token-content="{ token }"> {{ token.iid }} {{ token.title }} </template> - <template #dropdown-item-content="{ dropdownItem }"> - <div class="gl-display-flex"> - <div class="gl-text-secondary gl-font-sm gl-mr-4">{{ dropdownItem.iid }}</div> - <div class="gl-text-truncate">{{ dropdownItem.title }}</div> - </div> - </template> - </gl-token-selector> + <div> + <gl-alert v-if="error" variant="danger" class="gl-mb-3" @dismiss="unsetError"> + {{ error }} + </gl-alert> + <gl-token-selector + ref="tokenSelector" + v-model="workItemsToAdd" + :dropdown-items="availableWorkItems" + :loading="isLoading" + :placeholder="addInputPlaceholder" + menu-class="gl-dropdown-menu-wide dropdown-reduced-height gl-min-h-7!" + :container-class="tokenSelectorContainerClass" + data-testid="work-item-token-select-input" + @text-input="debouncedSearchKeyUpdate" + @focus="handleFocus" + @mouseover.native="handleMouseOver" + @mouseout.native="handleMouseOut" + @token-add="focusInputText" + @token-remove="focusInputText" + @blur="handleBlur" + > + <template #token-content="{ token }"> {{ token.iid }} {{ token.title }} </template> + <template #dropdown-item-content="{ dropdownItem }"> + <div class="gl-display-flex"> + <div + v-safe-html="formatResults(dropdownItem.iid)" + class="gl-text-secondary gl-font-sm gl-mr-4" + ></div> + <div v-safe-html="formatResults(dropdownItem.title)" class="gl-text-truncate"></div> + </div> + </template> + </gl-token-selector> + </div> </template> diff --git a/app/assets/javascripts/work_items/components/work_item_parent.vue b/app/assets/javascripts/work_items/components/work_item_parent.vue index d0e83ba8c21..ce30f7985cf 100644 --- a/app/assets/javascripts/work_items/components/work_item_parent.vue +++ b/app/assets/javascripts/work_items/components/work_item_parent.vue @@ -107,6 +107,8 @@ export default { searchTerm: this.search, types: this.parentType, in: this.search ? 'TITLE' : undefined, + iid: null, + isNumber: false, }; }, skip() { |