diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-18 13:50:51 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-18 13:50:51 +0300 |
commit | db384e6b19af03b4c3c82a5760d83a3fd79f7982 (patch) | |
tree | 34beaef37df5f47ccbcf5729d7583aae093cffa0 /app/assets/javascripts/import_entities/components/import_target_dropdown.vue | |
parent | 54fd7b1bad233e3944434da91d257fa7f63c3996 (diff) |
Add latest changes from gitlab-org/gitlab@16-3-stable-eev16.3.0-rc42
Diffstat (limited to 'app/assets/javascripts/import_entities/components/import_target_dropdown.vue')
-rw-r--r-- | app/assets/javascripts/import_entities/components/import_target_dropdown.vue | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/app/assets/javascripts/import_entities/components/import_target_dropdown.vue b/app/assets/javascripts/import_entities/components/import_target_dropdown.vue new file mode 100644 index 00000000000..b18a106608a --- /dev/null +++ b/app/assets/javascripts/import_entities/components/import_target_dropdown.vue @@ -0,0 +1,119 @@ +<script> +import { GlCollapsibleListbox } from '@gitlab/ui'; +import { debounce } from 'lodash'; + +import { __, s__ } from '~/locale'; +import { createAlert } from '~/alert'; +import { truncate } from '~/lib/utils/text_utility'; +import searchNamespacesWhereUserCanImportProjectsQuery from '~/import_entities/import_projects/graphql/queries/search_namespaces_where_user_can_import_projects.query.graphql'; +import { DEBOUNCE_DELAY } from '~/vue_shared/components/filtered_search_bar/constants'; +import { MINIMUM_SEARCH_LENGTH } from '~/graphql_shared/constants'; +import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; + +// This is added outside the component as each dropdown on the page triggers a query, +// so if multiple queries fail, we only show 1 error. +const reportNamespaceLoadError = debounce( + () => + createAlert({ + message: s__('ImportProjects|Requesting namespaces failed'), + }), + DEFAULT_DEBOUNCE_AND_THROTTLE_MS, +); + +export default { + components: { + GlCollapsibleListbox, + }, + + props: { + selected: { + type: String, + required: true, + }, + userNamespace: { + type: String, + required: true, + }, + }, + + MAX_IMPORT_TARGET_LENGTH: 24, + + data() { + return { + searchTerm: '', + }; + }, + + apollo: { + namespaces: { + query: searchNamespacesWhereUserCanImportProjectsQuery, + variables() { + return { + search: this.searchTerm, + }; + }, + skip() { + const hasNotEnoughSearchCharacters = + this.searchTerm.length > 0 && this.searchTerm.length < MINIMUM_SEARCH_LENGTH; + return hasNotEnoughSearchCharacters; + }, + update(data) { + return data.currentUser.groups.nodes; + }, + error: reportNamespaceLoadError, + debounce: DEBOUNCE_DELAY, + }, + }, + + computed: { + filteredNamespaces() { + return (this.namespaces ?? []).filter((ns) => + ns.fullPath.toLowerCase().includes(this.searchTerm.toLowerCase()), + ); + }, + + toggleText() { + return truncate(this.selected, this.$options.MAX_IMPORT_TARGET_LENGTH); + }, + + items() { + return [ + { + text: __('Users'), + options: [{ text: this.userNamespace, value: this.userNamespace }], + }, + { + text: __('Groups'), + options: this.filteredNamespaces.map((namespace) => { + return { text: namespace.fullPath, value: namespace.fullPath }; + }), + }, + ]; + }, + }, + + methods: { + onSelect(value) { + this.$emit('select', value); + }, + + onSearch(value) { + this.searchTerm = value.trim(); + }, + }, +}; +</script> + +<template> + <gl-collapsible-listbox + :items="items" + :selected="selected" + :toggle-text="toggleText" + searchable + fluid-width + toggle-class="gl-rounded-top-right-none! gl-rounded-bottom-right-none!" + data-qa-selector="target_namespace_selector_dropdown" + @select="onSelect" + @search="onSearch" + /> +</template> |