diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-20 21:10:05 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-20 21:10:05 +0300 |
commit | cc4e1c884cd6b8782fb6a247d840a2d1c7f4603e (patch) | |
tree | 8a54c659b82873efafe04887708140785caea153 /app/assets/javascripts/pages | |
parent | 709948b7a69597b1efe24df9b0f388cc0b493dd9 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/pages')
-rw-r--r-- | app/assets/javascripts/pages/admin/projects/components/namespace_select.vue | 143 | ||||
-rw-r--r-- | app/assets/javascripts/pages/admin/projects/index.js | 8 |
2 files changed, 69 insertions, 82 deletions
diff --git a/app/assets/javascripts/pages/admin/projects/components/namespace_select.vue b/app/assets/javascripts/pages/admin/projects/components/namespace_select.vue index c75c031b0b1..0b287c7ffd9 100644 --- a/app/assets/javascripts/pages/admin/projects/components/namespace_select.vue +++ b/app/assets/javascripts/pages/admin/projects/components/namespace_select.vue @@ -1,34 +1,31 @@ <script> -import { - GlDropdown, - GlDropdownItem, - GlDropdownDivider, - GlSearchBoxByType, - GlLoadingIcon, -} from '@gitlab/ui'; +import { debounce } from 'lodash'; +import { GlCollapsibleListbox } from '@gitlab/ui'; import Api from '~/api'; +import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; import { __ } from '~/locale'; export default { i18n: { - dropdownHeader: __('Namespaces'), + headerText: __('Namespaces'), searchPlaceholder: __('Search for Namespace'), - anyNamespace: __('Any namespace'), + reset: __('Clear'), }, components: { - GlDropdown, - GlDropdownItem, - GlDropdownDivider, - GlLoadingIcon, - GlSearchBoxByType, + GlCollapsibleListbox, }, props: { - showAny: { - type: Boolean, + origSelectedId: { + type: String, + required: false, + default: '', + }, + origSelectedText: { + type: String, required: false, - default: false, + default: '', }, - placeholder: { + toggleTextPlaceholder: { type: String, required: false, default: __('Namespace'), @@ -42,50 +39,66 @@ export default { data() { return { namespaceOptions: [], - selectedNamespaceId: null, - selectedNamespace: null, + selectedNamespaceId: this.origSelectedId, + selectedNamespaceText: this.origSelectedText, searchTerm: '', isLoading: false, }; }, computed: { - selectedNamespaceName() { - if (this.selectedNamespaceId === null) { - return this.placeholder; - } - return this.selectedNamespace; + toggleText() { + return this.selectedNamespaceText || this.toggleTextPlaceholder; }, }, watch: { - searchTerm() { - this.fetchNamespaces(this.searchTerm); + selectedNamespaceId(val) { + if (!val) { + this.selectedNamespaceText = null; + } + + this.selectedNamespaceText = this.namespaceOptions.find(({ value }) => value === val)?.text; }, }, mounted() { this.fetchNamespaces(); }, methods: { - fetchNamespaces(filter) { + fetchNamespaces() { this.isLoading = true; this.namespaceOptions = []; - return Api.namespaces(filter, (namespaces) => { - this.namespaceOptions = namespaces; + + return Api.namespaces(this.searchTerm, (namespaces) => { + this.namespaceOptions = this.formatNamespaceOptions(namespaces); this.isLoading = false; }); }, - selectNamespace(key) { - this.selectedNamespaceId = this.namespaceOptions[key].id; - this.selectedNamespace = this.getNamespaceString(this.namespaceOptions[key]); - this.$emit('setNamespace', this.selectedNamespaceId); + formatNamespaceOptions(namespaces) { + if (!namespaces) { + return []; + } + + return namespaces.map((namespace) => { + return { + value: String(namespace.id), + text: this.getNamespaceString(namespace), + }; + }); }, - selectAnyNamespace() { - this.selectedNamespaceId = null; - this.selectedNamespace = null; - this.$emit('setNamespace', null); + selectNamespace(value) { + this.selectedNamespaceId = value; + this.$emit('setNamespace', this.selectedNamespaceId); }, getNamespaceString(namespace) { return `${namespace.kind}: ${namespace.full_path}`; }, + search: debounce(function debouncedSearch(searchQuery) { + this.searchTerm = searchQuery?.trim(); + this.fetchNamespaces(); + }, DEFAULT_DEBOUNCE_AND_THROTTLE_MS), + onReset() { + this.selectedNamespaceId = null; + this.$emit('setNamespace', null); + }, }, }; </script> @@ -99,45 +112,19 @@ export default { type="hidden" data-testid="hidden-input" /> - <gl-dropdown - :text="selectedNamespaceName" - :header-text="$options.i18n.dropdownHeader" - toggle-class="dropdown-menu-toggle large" - data-testid="namespace-dropdown" - :right="true" - > - <template #header> - <gl-search-box-by-type - v-model.trim="searchTerm" - class="namespace-search-box" - debounce="250" - :placeholder="$options.i18n.searchPlaceholder" - /> - </template> - - <template v-if="showAny"> - <gl-dropdown-item @click="selectAnyNamespace"> - {{ $options.i18n.anyNamespace }} - </gl-dropdown-item> - <gl-dropdown-divider /> - </template> - - <gl-loading-icon v-if="isLoading" /> - - <gl-dropdown-item - v-for="(namespace, key) in namespaceOptions" - :key="namespace.id" - @click="selectNamespace(key)" - > - {{ getNamespaceString(namespace) }} - </gl-dropdown-item> - </gl-dropdown> + <gl-collapsible-listbox + :items="namespaceOptions" + :header-text="$options.i18n.headerText" + :reset-button-label="$options.i18n.reset" + :toggle-text="toggleText" + :search-placeholder="$options.i18n.searchPlaceholder" + :searching="isLoading" + :selected="selectedNamespaceId" + toggle-class="gl-w-full gl-flex-direction-column gl-align-items-stretch!" + searchable + @reset="onReset" + @search="search" + @select="selectNamespace" + /> </div> </template> - -<style scoped> -/* workaround position: relative imposed by .top-area .nav-controls */ -.namespace-search-box >>> input { - position: static; -} -</style> diff --git a/app/assets/javascripts/pages/admin/projects/index.js b/app/assets/javascripts/pages/admin/projects/index.js index 3098d06510b..49ee89de772 100644 --- a/app/assets/javascripts/pages/admin/projects/index.js +++ b/app/assets/javascripts/pages/admin/projects/index.js @@ -1,5 +1,4 @@ import Vue from 'vue'; -import { parseBoolean } from '~/lib/utils/common_utils'; import { mergeUrlParams } from '~/lib/utils/url_utility'; import ProjectsList from '~/projects_list'; import NamespaceSelect from './components/namespace_select.vue'; @@ -12,16 +11,17 @@ function mountNamespaceSelect() { return false; } - const { showAny, fieldName, placeholder, updateLocation } = el.dataset; + const { fieldName, toggleTextPlaceholder, selectedId, selectedText, updateLocation } = el.dataset; return new Vue({ el, render(createComponent) { return createComponent(NamespaceSelect, { props: { - showAny: parseBoolean(showAny), fieldName, - placeholder, + toggleTextPlaceholder, + origSelectedId: selectedId, + origSelectedText: selectedText, }, on: { setNamespace(newNamespace) { |