From 87c40a31cb5b29d6c68e4dffc8c41ebe73aaa7b2 Mon Sep 17 00:00:00 2001 From: Sascha Eggenberger <seggenberger@gitlab.com> Date: Mon, 29 Jan 2024 17:07:50 +0100 Subject: [PATCH] Pipeline manual action: Migrate dropdown to GlDisclosureDropdown Changelog: changed --- .../components/pipelines_manual_actions.vue | 83 ++++++++++++------- .../projects/pipelines/pipelines_spec.rb | 13 +-- .../pipelines_manual_actions_spec.js | 20 +++-- 3 files changed, 72 insertions(+), 44 deletions(-) diff --git a/app/assets/javascripts/ci/pipelines_page/components/pipelines_manual_actions.vue b/app/assets/javascripts/ci/pipelines_page/components/pipelines_manual_actions.vue index ebf1744aee21..2251a53b9bc3 100644 --- a/app/assets/javascripts/ci/pipelines_page/components/pipelines_manual_actions.vue +++ b/app/assets/javascripts/ci/pipelines_page/components/pipelines_manual_actions.vue @@ -1,5 +1,11 @@ <script> -import { GlDropdown, GlDropdownItem, GlIcon, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui'; +import { + GlDisclosureDropdown, + GlDisclosureDropdownItem, + GlIcon, + GlLoadingIcon, + GlTooltipDirective, +} from '@gitlab/ui'; import { createAlert } from '~/alert'; import axios from '~/lib/utils/axios_utils'; import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal'; @@ -16,8 +22,8 @@ export default { }, components: { GlCountdown, - GlDropdown, - GlDropdownItem, + GlDisclosureDropdown, + GlDisclosureDropdownItem, GlIcon, GlLoadingIcon, }, @@ -52,6 +58,7 @@ export default { isLoading: false, actions: [], hasDropdownBeenShown: false, + isDropdownVisible: false, }; }, computed: { @@ -101,58 +108,76 @@ export default { }); }, fetchActions() { + this.isDropdownVisible = true; this.hasDropdownBeenShown = true; this.$apollo.queries.actions.refetch(); this.trackClick(); }, + hideAction() { + this.isDropdownVisible = false; + }, trackClick() { this.track('click_manual_actions', { label: TRACKING_CATEGORIES.table }); }, + jobItem(job) { + return { + text: job.name, + extraAttrs: { + disabled: !job.canPlayJob, + }, + }; + }, }, }; </script> <template> - <gl-dropdown - v-gl-tooltip - :title="__('Run manual or delayed jobs')" + <gl-disclosure-dropdown + v-gl-tooltip.left="isDropdownVisible ? '' : __('Run manual or delayed jobs')" :loading="isLoading" data-testid="pipelines-manual-actions-dropdown" right lazy icon="play" @shown="fetchActions" + @hidden="hideAction" > - <gl-dropdown-item v-if="isActionsLoading"> - <div class="gl-display-flex"> - <gl-loading-icon class="mr-2" /> - <span>{{ __('Loading...') }}</span> - </div> - </gl-dropdown-item> + <gl-disclosure-dropdown-item v-if="isActionsLoading"> + <template #list-item> + <div class="gl-display-flex"> + <gl-loading-icon class="mr-2" /> + <span>{{ __('Loading...') }}</span> + </div> + </template> + </gl-disclosure-dropdown-item> - <gl-dropdown-item + <gl-disclosure-dropdown-item v-for="action in actions" v-else :key="action.id" - :disabled="!action.canPlayJob" - @click="onClickAction(action)" + :item="jobItem(action)" + @action="onClickAction(action)" > - <div class="gl-display-flex gl-justify-content-space-between gl-flex-wrap"> - {{ action.name }} - <span v-if="action.scheduledAt"> - <gl-icon name="clock" /> - <gl-countdown :end-date-string="action.scheduledAt" /> - </span> - </div> - </gl-dropdown-item> + <template #list-item> + <div class="gl-display-flex gl-justify-content-space-between gl-flex-wrap"> + {{ action.name }} + <span v-if="action.scheduledAt"> + <gl-icon name="clock" /> + <gl-countdown :end-date-string="action.scheduledAt" /> + </span> + </div> + </template> + </gl-disclosure-dropdown-item> <template #footer> - <gl-dropdown-item v-if="isDropdownLimitReached"> - <span class="gl-font-sm gl-text-gray-300!" data-testid="limit-reached-msg"> - {{ __('Showing first 50 actions.') }} - </span> - </gl-dropdown-item> + <gl-disclosure-dropdown-item v-if="isDropdownLimitReached"> + <template #list-item> + <span class="gl-font-sm gl-text-gray-300!" data-testid="limit-reached-msg"> + {{ __('Showing first 50 actions.') }} + </span> + </template> + </gl-disclosure-dropdown-item> </template> - </gl-dropdown> + </gl-disclosure-dropdown> </template> diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 9c052b150bec..00bb9141aa04 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -295,7 +295,7 @@ context 'when manual action was played' do before do - find('[data-testid="pipelines-manual-actions-dropdown"]').click + find('[data-testid="pipelines-manual-actions-dropdown"] button').click wait_for_requests @@ -326,7 +326,7 @@ end it "has link to the delayed job's action" do - find('[data-testid="pipelines-manual-actions-dropdown"]').click + find('[data-testid="pipelines-manual-actions-dropdown"] button').click wait_for_requests @@ -345,7 +345,7 @@ end it "shows 00:00:00 as the remaining time" do - find('[data-testid="pipelines-manual-actions-dropdown"]').click + find('[data-testid="pipelines-manual-actions-dropdown"] button').click wait_for_requests @@ -354,7 +354,8 @@ end context 'when user played a delayed job immediately' do - let(:manual_action_selector) { '[data-testid="pipelines-manual-actions-dropdown"]' } + let(:manual_action_selector) { '[data-testid="pipelines-manual-actions-dropdown"] button' } + let(:manual_action_dropdown) { '[data-testid="pipelines-manual-actions-dropdown"]' } before do find(manual_action_selector).click @@ -363,8 +364,8 @@ end # Wait for UI to transition to ensure a request has been made - within(manual_action_selector) { find('.gl-spinner') } - within(manual_action_selector) { find('[data-testid="play-icon"]') } + within(manual_action_dropdown) { find('.gl-spinner') } + within(manual_action_dropdown) { find('[data-testid="play-icon"]') } wait_for_requests end diff --git a/spec/frontend/ci/pipelines_page/components/pipelines_manual_actions_spec.js b/spec/frontend/ci/pipelines_page/components/pipelines_manual_actions_spec.js index a24e136f1ff0..04d9735640cb 100644 --- a/spec/frontend/ci/pipelines_page/components/pipelines_manual_actions_spec.js +++ b/spec/frontend/ci/pipelines_page/components/pipelines_manual_actions_spec.js @@ -1,4 +1,4 @@ -import { GlDropdown, GlDropdownItem, GlLoadingIcon } from '@gitlab/ui'; +import { GlDisclosureDropdown, GlDisclosureDropdownItem, GlLoadingIcon } from '@gitlab/ui'; import MockAdapter from 'axios-mock-adapter'; import Vue, { nextTick } from 'vue'; import VueApollo from 'vue-apollo'; @@ -48,14 +48,14 @@ describe('Pipeline manual actions', () => { iid: 100, }, stubs: { - GlDropdown, + GlDisclosureDropdown, }, apolloProvider: createMockApollo([[getPipelineActionsQuery, queryHandler]]), }); }; - const findDropdown = () => wrapper.findComponent(GlDropdown); - const findAllDropdownItems = () => wrapper.findAllComponents(GlDropdownItem); + const findDropdown = () => wrapper.findComponent(GlDisclosureDropdown); + const findAllDropdownItems = () => wrapper.findAllComponents(GlDisclosureDropdownItem); const findAllCountdowns = () => wrapper.findAllComponents(GlCountdown); const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon); const findLimitMessage = () => wrapper.findByTestId('limit-reached-msg'); @@ -101,14 +101,16 @@ describe('Pipeline manual actions', () => { }); it("displays a disabled action when it's not playable", () => { - expect(findAllDropdownItems().at(0).attributes('disabled')).toBeDefined(); + expect(findAllDropdownItems().at(0).props('item')).toMatchObject({ + extraAttrs: { disabled: true }, + }); }); describe('on action click', () => { it('makes a request and toggles the loading state', async () => { mock.onPost(mockPath).reply(HTTP_STATUS_OK); - findAllDropdownItems().at(1).vm.$emit('click'); + findAllDropdownItems().at(1).vm.$emit('action'); await nextTick(); @@ -122,7 +124,7 @@ describe('Pipeline manual actions', () => { it('makes a failed request and toggles the loading state', async () => { mock.onPost(mockPath).reply(HTTP_STATUS_INTERNAL_SERVER_ERROR); - findAllDropdownItems().at(1).vm.$emit('click'); + findAllDropdownItems().at(1).vm.$emit('action'); await nextTick(); @@ -163,7 +165,7 @@ describe('Pipeline manual actions', () => { confirmAction.mockResolvedValueOnce(true); - findAllDropdownItems().at(2).vm.$emit('click'); + findAllDropdownItems().at(2).vm.$emit('action'); expect(confirmAction).toHaveBeenCalled(); @@ -177,7 +179,7 @@ describe('Pipeline manual actions', () => { confirmAction.mockResolvedValueOnce(false); - findAllDropdownItems().at(2).vm.$emit('click'); + findAllDropdownItems().at(2).vm.$emit('action'); expect(confirmAction).toHaveBeenCalled(); -- GitLab