From 442d88a4ce1bc667b9808f66c420a6b3ac18d86f Mon Sep 17 00:00:00 2001 From: Amir Date: Tue, 2 Apr 2024 21:00:04 +0300 Subject: [PATCH] fix(HMS-3850): V2Wizard:use menu toggle for save and build --- .../steps/Review/Footer/CreateDropdown.tsx | 52 ++++++++++++---- .../steps/Review/Footer/EditDropdown.tsx | 59 ++++++++++++++----- .../steps/Review/Footer/Footer.tsx | 51 ++++++++-------- .../CreateImageWizard.test.tsx | 3 +- .../CreateImageWizardV2/wizardTestUtils.tsx | 6 +- 5 files changed, 113 insertions(+), 58 deletions(-) diff --git a/src/Components/CreateImageWizardV2/steps/Review/Footer/CreateDropdown.tsx b/src/Components/CreateImageWizardV2/steps/Review/Footer/CreateDropdown.tsx index dbfdb470..f94f6067 100644 --- a/src/Components/CreateImageWizardV2/steps/Review/Footer/CreateDropdown.tsx +++ b/src/Components/CreateImageWizardV2/steps/Review/Footer/CreateDropdown.tsx @@ -1,6 +1,13 @@ import React from 'react'; -import { DropdownList, DropdownItem } from '@patternfly/react-core'; +import { + DropdownList, + DropdownItem, + MenuToggleAction, + Spinner, + Flex, + FlexItem, +} from '@patternfly/react-core'; import { CreateBlueprintRequest, @@ -13,7 +20,7 @@ type CreateDropdownProps = { setIsOpen: (isOpen: boolean) => void; }; -const CreateDropdown = ({ +export const CreateSaveAndBuildBtn = ({ getBlueprintPayload, setIsOpen, }: CreateDropdownProps) => { @@ -22,12 +29,6 @@ const CreateDropdown = ({ fixedCacheKey: 'createBlueprintKey', }); - const onSave = async () => { - const requestBody = await getBlueprintPayload(); - setIsOpen(false); - requestBody && createBlueprint({ createBlueprintRequest: requestBody }); - }; - const onSaveAndBuild = async () => { const requestBody = await getBlueprintPayload(); setIsOpen(false); @@ -41,9 +42,6 @@ const CreateDropdown = ({ return ( - - Save changes - Save and build images @@ -51,4 +49,34 @@ const CreateDropdown = ({ ); }; -export default CreateDropdown; +export const CreateSaveButton = ({ + setIsOpen, + getBlueprintPayload, +}: CreateDropdownProps) => { + const [createBlueprint, { isLoading }] = useCreateBlueprintMutation({ + fixedCacheKey: 'createBlueprintKey', + }); + const onSave = async () => { + const requestBody = await getBlueprintPayload(); + setIsOpen(false); + requestBody && createBlueprint({ createBlueprintRequest: requestBody }); + }; + return ( + + + {isLoading && ( + + + + )} + Save changes + + + ); +}; diff --git a/src/Components/CreateImageWizardV2/steps/Review/Footer/EditDropdown.tsx b/src/Components/CreateImageWizardV2/steps/Review/Footer/EditDropdown.tsx index 9694576c..ef5d70b2 100644 --- a/src/Components/CreateImageWizardV2/steps/Review/Footer/EditDropdown.tsx +++ b/src/Components/CreateImageWizardV2/steps/Review/Footer/EditDropdown.tsx @@ -1,6 +1,13 @@ import React from 'react'; -import { DropdownList, DropdownItem } from '@patternfly/react-core'; +import { + DropdownList, + DropdownItem, + MenuToggleAction, + Spinner, + Flex, + FlexItem, +} from '@patternfly/react-core'; import { CreateBlueprintRequest, @@ -8,29 +15,22 @@ import { useUpdateBlueprintMutation, } from '../../../../../store/imageBuilderApi'; -type CreateDropdownProps = { +type EditDropdownProps = { getBlueprintPayload: () => Promise<'' | CreateBlueprintRequest | undefined>; setIsOpen: (isOpen: boolean) => void; blueprintId: string; }; -const EditDropdown = ({ +export const EditSaveAndBuildBtn = ({ getBlueprintPayload, setIsOpen, blueprintId, -}: CreateDropdownProps) => { +}: EditDropdownProps) => { const [buildBlueprint] = useComposeBlueprintMutation(); const [updateBlueprint] = useUpdateBlueprintMutation({ fixedCacheKey: 'updateBlueprintKey', }); - const onSave = async () => { - const requestBody = await getBlueprintPayload(); - setIsOpen(false); - requestBody && - updateBlueprint({ id: blueprintId, createBlueprintRequest: requestBody }); - }; - const onSaveAndBuild = async () => { const requestBody = await getBlueprintPayload(); setIsOpen(false); @@ -44,9 +44,6 @@ const EditDropdown = ({ return ( - - Save changes - Save and build images @@ -54,4 +51,36 @@ const EditDropdown = ({ ); }; -export default EditDropdown; +export const EditSaveButton = ({ + setIsOpen, + getBlueprintPayload, + blueprintId, +}: EditDropdownProps) => { + const [updateBlueprint, { isLoading }] = useUpdateBlueprintMutation({ + fixedCacheKey: 'updateBlueprintKey', + }); + const onSave = async () => { + const requestBody = await getBlueprintPayload(); + setIsOpen(false); + requestBody && + updateBlueprint({ id: blueprintId, createBlueprintRequest: requestBody }); + }; + return ( + + + {isLoading && ( + + + + )} + Save changes + + + ); +}; diff --git a/src/Components/CreateImageWizardV2/steps/Review/Footer/Footer.tsx b/src/Components/CreateImageWizardV2/steps/Review/Footer/Footer.tsx index 97eb9cac..8cd97975 100644 --- a/src/Components/CreateImageWizardV2/steps/Review/Footer/Footer.tsx +++ b/src/Components/CreateImageWizardV2/steps/Review/Footer/Footer.tsx @@ -8,13 +8,12 @@ import { WizardFooterWrapper, useWizardContext, } from '@patternfly/react-core'; -import { SpinnerIcon } from '@patternfly/react-icons'; import { useChrome } from '@redhat-cloud-services/frontend-components/useChrome'; import { useStore } from 'react-redux'; import { useNavigate, useParams } from 'react-router-dom'; -import CreateDropdown from './CreateDropdown'; -import EditDropdown from './EditDropdown'; +import { CreateSaveAndBuildBtn, CreateSaveButton } from './CreateDropdown'; +import { EditSaveAndBuildBtn, EditSaveButton } from './EditDropdown'; import { useServerStore } from '../../../../../store/hooks'; import { @@ -26,25 +25,13 @@ import { mapRequestFromState } from '../../../utilities/requestMapper'; const ReviewWizardFooter = () => { const { goToPrevStep, close } = useWizardContext(); - const [ - , - { - isLoading: isCreationLoading, - isSuccess: isCreateSuccess, - reset: resetCreate, - }, - ] = useCreateBlueprintMutation({ fixedCacheKey: 'createBlueprintKey' }); + const [, { isSuccess: isCreateSuccess, reset: resetCreate }] = + useCreateBlueprintMutation({ fixedCacheKey: 'createBlueprintKey' }); // initialize the server store with the data from RTK query const serverStore = useServerStore(); - const [ - , - { - isLoading: isUpdateLoading, - isSuccess: isUpdateSuccess, - reset: resetUpdate, - }, - ] = useUpdateBlueprintMutation({ fixedCacheKey: 'updateBlueprintKey' }); + const [, { isSuccess: isUpdateSuccess, reset: resetUpdate }] = + useUpdateBlueprintMutation({ fixedCacheKey: 'updateBlueprintKey' }); const { auth } = useChrome(); const { composeId } = useParams(); const [isOpen, setIsOpen] = useState(false); @@ -69,8 +56,6 @@ const ReviewWizardFooter = () => { return requestBody; }; - const isLoadingState = isCreationLoading || isUpdateLoading; - return (
@@ -83,7 +68,25 @@ const ReviewWizardFooter = () => { ref={toggleRef} onClick={onToggleClick} isExpanded={isOpen} - icon={isLoadingState && } + splitButtonOptions={{ + variant: 'action', + items: composeId + ? [ + , + ] + : [ + , + ], + }} > Save @@ -92,13 +95,13 @@ const ReviewWizardFooter = () => { shouldFocusToggleOnSelect > {composeId ? ( - ) : ( - diff --git a/src/test/Components/CreateImageWizardV2/CreateImageWizard.test.tsx b/src/test/Components/CreateImageWizardV2/CreateImageWizard.test.tsx index 390f681c..b6e065c8 100644 --- a/src/test/Components/CreateImageWizardV2/CreateImageWizard.test.tsx +++ b/src/test/Components/CreateImageWizardV2/CreateImageWizard.test.tsx @@ -435,9 +435,8 @@ describe('Step Upload to AWS', () => { await enterBlueprintName(); await clickNext(); - await user.click(await screen.findByRole('button', { name: /Save/ })); await user.click( - await screen.findByRole('menuitem', { name: /Save changes/ }) + await screen.findByRole('button', { name: /Save changes/ }) ); // returns back to the landing page diff --git a/src/test/Components/CreateImageWizardV2/wizardTestUtils.tsx b/src/test/Components/CreateImageWizardV2/wizardTestUtils.tsx index 99b0b20b..e69fd34d 100644 --- a/src/test/Components/CreateImageWizardV2/wizardTestUtils.tsx +++ b/src/test/Components/CreateImageWizardV2/wizardTestUtils.tsx @@ -105,13 +105,9 @@ export const interceptBlueprintRequest = async (requestPathname: string) => { const receivedRequestPromise = spyOnRequest(requestPathname); const saveButton = await screen.findByRole('button', { - name: 'Save', - }); - await userEvent.click(saveButton); - const saveChangesButton = await screen.findByRole('menuitem', { name: 'Save changes', }); - await userEvent.click(saveChangesButton); + await userEvent.click(saveButton); return await receivedRequestPromise; };