diff options
4 files changed, 53 insertions, 16 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 09b02068388..eda0e8829a8 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 @@ -32,6 +32,7 @@ export default { }, data() { return { + isDropdownShown: false, selectedEnvironment: '', searchTerm: '', }; @@ -46,6 +47,12 @@ export default { return environment.toLowerCase().includes(lowerCasedSearchTerm); }); }, + isDropdownLoading() { + return this.areEnvironmentsLoading && this.isEnvScopeLimited && !this.isDropdownShown; + }, + isDropdownSearching() { + return this.areEnvironmentsLoading && this.isEnvScopeLimited && this.isDropdownShown; + }, isEnvScopeLimited() { return this.glFeatures?.ciLimitEnvironmentScope; }, @@ -65,15 +72,12 @@ export default { 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 + (this.isEnvScopeLimited || this.shouldRenderCreateButton) && !this.areEnvironmentsLoading ); }, environmentScopeLabel() { @@ -96,6 +100,9 @@ export default { this.$emit('create-environment-scope', this.searchTerm); this.selectEnvironment(this.searchTerm); }, + toggleDropdownShown(isShown) { + this.isDropdownShown = isShown; + }, }, ENVIRONMENT_QUERY_LIMIT, i18n: { @@ -111,10 +118,13 @@ export default { block searchable :items="searchedEnvironments" - :searching="shouldShowSearchLoading" + :loading="isDropdownLoading" + :searching="isDropdownSearching" :toggle-text="environmentScopeLabel" @search="debouncedSearch" @select="selectEnvironment" + @shown="toggleDropdownShown(true)" + @hidden="toggleDropdownShown(false)" > <template #footer> <gl-dropdown-divider v-if="shouldRenderDivider" /> diff --git a/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_shared.vue b/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_shared.vue index ee2c0a771cf..f87b2769de8 100644 --- a/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_shared.vue +++ b/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_shared.vue @@ -190,12 +190,8 @@ export default { return {}; }, isLoading() { - // TODO: Remove areEnvironmentsLoading and show loading icon in dropdown when - // environment query is loading and FF is enabled - // https://gitlab.com/gitlab-org/gitlab/-/issues/396990 return ( (this.$apollo.queries.ciVariables.loading && this.isInitialLoading) || - this.areEnvironmentsLoading || this.isLoadingMoreItems ); }, diff --git a/spec/frontend/ci/ci_variable_list/components/ci_environments_dropdown_spec.js b/spec/frontend/ci/ci_variable_list/components/ci_environments_dropdown_spec.js index 1937e3b34b7..415a1d0bfa3 100644 --- a/spec/frontend/ci/ci_variable_list/components/ci_environments_dropdown_spec.js +++ b/spec/frontend/ci/ci_variable_list/components/ci_environments_dropdown_spec.js @@ -1,4 +1,10 @@ -import { GlListboxItem, GlCollapsibleListbox, GlDropdownItem, GlIcon } from '@gitlab/ui'; +import { + GlListboxItem, + GlCollapsibleListbox, + GlDropdownDivider, + GlDropdownItem, + GlIcon, +} from '@gitlab/ui'; import { mountExtended } from 'helpers/vue_test_utils_helper'; import { allEnvironments, ENVIRONMENT_QUERY_LIMIT } from '~/ci/ci_variable_list/constants'; import CiEnvironmentsDropdown from '~/ci/ci_variable_list/components/ci_environments_dropdown.vue'; @@ -19,6 +25,7 @@ describe('Ci environments dropdown', () => { const findListbox = () => wrapper.findComponent(GlCollapsibleListbox); const findListboxText = () => findListbox().props('toggleText'); const findCreateWildcardButton = () => wrapper.findComponent(GlDropdownItem); + const findDropdownDivider = () => wrapper.findComponent(GlDropdownDivider); const findMaxEnvNote = () => wrapper.findByTestId('max-envs-notice'); const createComponent = ({ props = {}, searchTerm = '', enableFeatureFlag = false } = {}) => { @@ -42,6 +49,10 @@ describe('Ci environments dropdown', () => { createComponent({ searchTerm: 'stable' }); }); + it('renders dropdown divider', () => { + expect(findDropdownDivider().exists()).toBe(true); + }); + it('renders create button with search term if environments do not contain search term', () => { const button = findCreateWildcardButton(); expect(button.exists()).toBe(true); @@ -125,12 +136,32 @@ describe('Ci environments dropdown', () => { createComponent({ enableFeatureFlag: true }); }); + it('renders dropdown divider', () => { + expect(findDropdownDivider().exists()).toBe(true); + }); + it('renders environments passed down to it', async () => { await findListbox().vm.$emit('search', currentEnv); expect(findAllListboxItems()).toHaveLength(envs.length); }); + it('renders dropdown loading icon while fetch query is loading', () => { + createComponent({ enableFeatureFlag: true, props: { areEnvironmentsLoading: true } }); + + expect(findListbox().props('loading')).toBe(true); + expect(findListbox().props('searching')).toBe(false); + expect(findDropdownDivider().exists()).toBe(false); + }); + + it('renders search loading icon while search query is loading and dropdown is open', async () => { + createComponent({ enableFeatureFlag: true, props: { areEnvironmentsLoading: true } }); + await findListbox().vm.$emit('shown'); + + expect(findListbox().props('loading')).toBe(false); + expect(findListbox().props('searching')).toBe(true); + }); + it('emits event when searching', async () => { expect(wrapper.emitted('search-environment-scope')).toHaveLength(1); @@ -140,12 +171,6 @@ describe('Ci environments dropdown', () => { expect(wrapper.emitted('search-environment-scope')[1]).toEqual([currentEnv]); }); - it('renders loading icon while search query is loading', () => { - createComponent({ enableFeatureFlag: true, props: { areEnvironmentsLoading: true } }); - - expect(findListbox().props('searching')).toBe(true); - }); - it('displays note about max environments shown', () => { expect(findMaxEnvNote().exists()).toBe(true); expect(findMaxEnvNote().text()).toContain(String(ENVIRONMENT_QUERY_LIMIT)); diff --git a/spec/frontend/ci/ci_variable_list/components/ci_variable_shared_spec.js b/spec/frontend/ci/ci_variable_list/components/ci_variable_shared_spec.js index f7b90c3da30..2f4d48aacfc 100644 --- a/spec/frontend/ci/ci_variable_list/components/ci_variable_shared_spec.js +++ b/spec/frontend/ci/ci_variable_list/components/ci_variable_shared_spec.js @@ -251,6 +251,12 @@ describe('Ci Variable Shared Component', () => { expect.objectContaining({ search: 'staging' }), ); }); + + it('does not show loading icon in table while searching for environments', () => { + findCiSettings().vm.$emit('search-environment-scope', 'staging'); + + expect(findLoadingIcon().exists()).toBe(false); + }); }); describe('when Limit Environment Scope FF is disabled', () => { |