diff options
Diffstat (limited to 'app/assets/javascripts/ci/ci_variable_list/components/ci_environments_dropdown.vue')
-rw-r--r-- | app/assets/javascripts/ci/ci_variable_list/components/ci_environments_dropdown.vue | 97 |
1 files changed, 79 insertions, 18 deletions
diff --git a/app/assets/javascripts/ci/ci_variable_list/components/ci_environments_dropdown.vue b/app/assets/javascripts/ci/ci_variable_list/components/ci_environments_dropdown.vue index 7387a490177..09b02068388 100644 --- a/app/assets/javascripts/ci/ci_variable_list/components/ci_environments_dropdown.vue +++ b/app/assets/javascripts/ci/ci_variable_list/components/ci_environments_dropdown.vue @@ -1,16 +1,25 @@ <script> -import { GlDropdownDivider, GlDropdownItem, GlCollapsibleListbox } from '@gitlab/ui'; -import { __, sprintf } from '~/locale'; +import { debounce, uniq } from 'lodash'; +import { GlDropdownDivider, GlDropdownItem, GlCollapsibleListbox, GlSprintf } from '@gitlab/ui'; +import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; +import { __, s__, sprintf } from '~/locale'; import { convertEnvironmentScope } from '../utils'; +import { ENVIRONMENT_QUERY_LIMIT } from '../constants'; export default { name: 'CiEnvironmentsDropdown', components: { + GlCollapsibleListbox, GlDropdownDivider, GlDropdownItem, - GlCollapsibleListbox, + GlSprintf, }, + mixins: [glFeatureFlagsMixin()], props: { + areEnvironmentsLoading: { + type: Boolean, + required: true, + }, environments: { type: Array, required: true, @@ -33,24 +42,52 @@ export default { }, filteredEnvironments() { const lowerCasedSearchTerm = this.searchTerm.toLowerCase(); + return this.environments.filter((environment) => { + return environment.toLowerCase().includes(lowerCasedSearchTerm); + }); + }, + isEnvScopeLimited() { + return this.glFeatures?.ciLimitEnvironmentScope; + }, + searchedEnvironments() { + // If FF is enabled, search query will be fired so this component will already + // receive filtered environments during the refetch. + // If FF is disabled, search the existing list of environments in the frontend + let filtered = this.isEnvScopeLimited ? this.environments : this.filteredEnvironments; + + // If there is no search term, make sure to include * + if (this.isEnvScopeLimited && !this.searchTerm) { + filtered = uniq([...filtered, '*']); + } - return this.environments - .filter((environment) => { - return environment.toLowerCase().includes(lowerCasedSearchTerm); - }) - .map((environment) => ({ - value: environment, - text: environment, - })); + return filtered.sort().map((environment) => ({ + value: environment, + text: environment, + })); + }, + shouldShowSearchLoading() { + return this.areEnvironmentsLoading && this.isEnvScopeLimited; }, shouldRenderCreateButton() { return this.searchTerm && !this.environments.includes(this.searchTerm); }, + shouldRenderDivider() { + return ( + (this.isEnvScopeLimited || this.shouldRenderCreateButton) && !this.shouldShowSearchLoading + ); + }, environmentScopeLabel() { return convertEnvironmentScope(this.selectedEnvironmentScope); }, }, methods: { + debouncedSearch: debounce(function debouncedSearch(searchTerm) { + const newSearchTerm = searchTerm.trim(); + this.searchTerm = newSearchTerm; + if (this.isEnvScopeLimited) { + this.$emit('search-environment-scope', newSearchTerm); + } + }, 500), selectEnvironment(selected) { this.$emit('select-environment', selected); this.selectedEnvironment = selected; @@ -60,22 +97,46 @@ export default { this.selectEnvironment(this.searchTerm); }, }, + ENVIRONMENT_QUERY_LIMIT, + i18n: { + maxEnvsNote: s__( + 'CiVariable|Maximum of %{limit} environments listed. For more environments, enter a search query.', + ), + }, }; </script> <template> <gl-collapsible-listbox v-model="selectedEnvironment" + block searchable - :items="filteredEnvironments" + :items="searchedEnvironments" + :searching="shouldShowSearchLoading" :toggle-text="environmentScopeLabel" - @search="searchTerm = $event.trim()" + @search="debouncedSearch" @select="selectEnvironment" > - <template v-if="shouldRenderCreateButton" #footer> - <gl-dropdown-divider /> - <gl-dropdown-item data-testid="create-wildcard-button" @click="createEnvironmentScope"> - {{ composedCreateButtonLabel }} - </gl-dropdown-item> + <template #footer> + <gl-dropdown-divider v-if="shouldRenderDivider" /> + <div v-if="isEnvScopeLimited" data-testid="max-envs-notice"> + <gl-dropdown-item class="gl-list-style-none" disabled> + <gl-sprintf :message="$options.i18n.maxEnvsNote" class="gl-font-sm"> + <template #limit> + {{ $options.ENVIRONMENT_QUERY_LIMIT }} + </template> + </gl-sprintf> + </gl-dropdown-item> + </div> + <div v-if="shouldRenderCreateButton"> + <!-- TODO: Rethink create wildcard button. https://gitlab.com/gitlab-org/gitlab/-/issues/396928 --> + <gl-dropdown-item + class="gl-list-style-none" + data-testid="create-wildcard-button" + @click="createEnvironmentScope" + > + {{ composedCreateButtonLabel }} + </gl-dropdown-item> + </div> </template> </gl-collapsible-listbox> </template> |