diff --git a/src/Components/CreateImageWizard/CreateImageWizard.tsx b/src/Components/CreateImageWizard/CreateImageWizard.tsx index 0fd25fce..13295bbc 100644 --- a/src/Components/CreateImageWizard/CreateImageWizard.tsx +++ b/src/Components/CreateImageWizard/CreateImageWizard.tsx @@ -40,7 +40,6 @@ import { useDetailsValidation, useRegistrationValidation, useHostnameValidation, - useKernelValidation, } from './utilities/useValidation'; import { isAwsAccountIdValid, @@ -224,8 +223,6 @@ const CreateImageWizard = ({ isEdit }: CreateImageWizardProps) => { const fileSystemValidation = useFilesystemValidation(); // Hostname const hostnameValidation = useHostnameValidation(); - // Kernel - const kernelValidation = useKernelValidation(); // Firstboot const firstBootValidation = useFirstBootValidation(); // Details @@ -513,12 +510,8 @@ const CreateImageWizard = ({ isEdit }: CreateImageWizardProps) => { key="wizard-kernel" navItem={customStatusNavItem} isHidden={!isKernelEnabled} - status={kernelValidation.disabledNext ? 'error' : 'default'} footer={ - + } > diff --git a/src/Components/CreateImageWizard/steps/Kernel/components/KernelName.tsx b/src/Components/CreateImageWizard/steps/Kernel/components/KernelName.tsx index 602209b3..b2b89506 100644 --- a/src/Components/CreateImageWizard/steps/Kernel/components/KernelName.tsx +++ b/src/Components/CreateImageWizard/steps/Kernel/components/KernelName.tsx @@ -1,35 +1,86 @@ -import React from 'react'; +import React, { useState } from 'react'; import { FormGroup } from '@patternfly/react-core'; +import { + MenuToggle, + MenuToggleElement, + Select, + SelectList, + SelectOption, +} from '@patternfly/react-core/dist/esm'; import { useAppDispatch, useAppSelector } from '../../../../../store/hooks'; import { changeKernelName, selectKernel, } from '../../../../../store/wizardSlice'; -import { useKernelValidation } from '../../../utilities/useValidation'; -import { HookValidatedInput } from '../../../ValidatedTextInput'; + +const kernelOptions = ['kernel', 'kernel-debug']; const KernelName = () => { const dispatch = useAppDispatch(); const kernel = useAppSelector(selectKernel); - const stepValidation = useKernelValidation(); + const [isOpen, setIsOpen] = useState(false); - const handleChange = (e: React.FormEvent, value: string) => { - dispatch(changeKernelName(value)); + const onToggle = () => { + setIsOpen(!isOpen); }; + const onSelect = (_event: React.MouseEvent, value: string) => { + if (value === 'default') { + dispatch(changeKernelName('')); + } else { + dispatch(changeKernelName(value)); + } + setIsOpen(false); + }; + + const defaultOption = () => { + return ( + + Default kernel package + + ); + }; + + const prepareSelectOptions = () => { + const kernelSelectOptions = kernelOptions.map((option) => ( + + {option} + + )); + + if (kernel.name) { + return [defaultOption()].concat(kernelSelectOptions); + } else return kernelSelectOptions; + }; + + const toggle = (toggleRef: React.Ref) => ( + + {kernel.name} + + ); + return ( - + ); }; diff --git a/src/Components/CreateImageWizard/utilities/useValidation.tsx b/src/Components/CreateImageWizard/utilities/useValidation.tsx index c7902392..2307c6d2 100644 --- a/src/Components/CreateImageWizard/utilities/useValidation.tsx +++ b/src/Components/CreateImageWizard/utilities/useValidation.tsx @@ -19,7 +19,6 @@ import { selectActivationKey, selectRegistrationType, selectHostname, - selectKernel, } from '../../../store/wizardSlice'; import { getDuplicateMountPoints, @@ -28,7 +27,6 @@ import { isMountpointMinSizeValid, isSnapshotValid, isHostnameValid, - isKernelNameValid, } from '../validators'; export type StepValidation = { @@ -43,7 +41,6 @@ export function useIsBlueprintValid(): boolean { const filesystem = useFilesystemValidation(); const snapshot = useSnapshotValidation(); const hostname = useHostnameValidation(); - const kernel = useKernelValidation(); const firstBoot = useFirstBootValidation(); const details = useDetailsValidation(); return ( @@ -51,7 +48,6 @@ export function useIsBlueprintValid(): boolean { !filesystem.disabledNext && !snapshot.disabledNext && !hostname.disabledNext && - !kernel.disabledNext && !firstBoot.disabledNext && !details.disabledNext ); @@ -159,20 +155,6 @@ export function useHostnameValidation(): StepValidation { return { errors: {}, disabledNext: false }; } -export function useKernelValidation(): StepValidation { - const kernel = useAppSelector(selectKernel); - - if (!isKernelNameValid(kernel.name)) { - return { - errors: { - kernel: 'Invalid kernel name', - }, - disabledNext: true, - }; - } - return { errors: {}, disabledNext: false }; -} - export function useDetailsValidation(): StepValidation { const name = useAppSelector(selectBlueprintName); const description = useAppSelector(selectBlueprintDescription); diff --git a/src/test/Components/CreateImageWizard/steps/Kernel/Kernel.test.tsx b/src/test/Components/CreateImageWizard/steps/Kernel/Kernel.test.tsx index 451218b7..e27d688d 100644 --- a/src/test/Components/CreateImageWizard/steps/Kernel/Kernel.test.tsx +++ b/src/test/Components/CreateImageWizard/steps/Kernel/Kernel.test.tsx @@ -8,7 +8,6 @@ import { clickBack, clickNext, enterBlueprintName, - getNextButton, interceptBlueprintRequest, openAndDismissSaveAndBuildModal, verifyCancelButton, @@ -38,26 +37,20 @@ const goToKernelStep = async () => { }; const goToReviewStep = async () => { + await clickNext(); // Firewall await clickNext(); // First boot script await clickNext(); // Details await enterBlueprintName(); await clickNext(); // Review }; -const enterKernelName = async (kernelName: string) => { +const selectKernelName = async (kernelName: string) => { const user = userEvent.setup(); - const kernelNameInput = await screen.findByPlaceholderText( - /Add a kernel name/i - ); - await waitFor(() => user.type(kernelNameInput, kernelName)); -}; + const kernelNameDropdown = await screen.findByTestId('kernel-name-dropdown'); + await waitFor(() => user.click(kernelNameDropdown)); -const clearKernelName = async () => { - const user = userEvent.setup(); - const kernelNameInput = await screen.findByPlaceholderText( - /Add a kernel name/i - ); - await waitFor(() => user.clear(kernelNameInput)); + const kernelOption = await screen.findByText(kernelName); + await waitFor(() => user.click(kernelOption)); }; describe('Step Kernel', () => { @@ -87,27 +80,6 @@ describe('Step Kernel', () => { await goToKernelStep(); await verifyCancelButton(router); }); - - test('validation works', async () => { - await renderCreateMode(); - await goToKernelStep(); - - // with empty kernel name input - const nextButton = await getNextButton(); - expect(nextButton).toBeEnabled(); - - // invalid name - await enterKernelName('INVALID/NAME'); - expect(nextButton).toBeDisabled(); - await clickNext(); // dummy click to blur and render error (doesn't render when pristine) - await screen.findByText(/Invalid kernel name/); - - // valid name - await clearKernelName(); - await enterKernelName('valid-kernel-name'); - expect(nextButton).toBeEnabled(); - expect(screen.queryByText(/Invalid kernel name/)).not.toBeInTheDocument(); - }); }); describe('Kernel request generated correctly', () => { @@ -115,10 +87,10 @@ describe('Kernel request generated correctly', () => { vi.clearAllMocks(); }); - test('with valid kernel name', async () => { + test('with kernel name', async () => { await renderCreateMode(); await goToKernelStep(); - await enterKernelName('kernel-name'); + await selectKernelName('kernel-debug'); await goToReviewStep(); // informational modal pops up in the first test only as it's tied // to a 'imageBuilder.saveAndBuildModalSeen' variable in localStorage @@ -129,7 +101,7 @@ describe('Kernel request generated correctly', () => { ...blueprintRequest, customizations: { kernel: { - name: 'kernel-name', + name: 'kernel-debug', }, }, }; @@ -138,6 +110,23 @@ describe('Kernel request generated correctly', () => { expect(receivedRequest).toEqual(expectedRequest); }); }); + + test('when unselecting kernel name', async () => { + await renderCreateMode(); + await goToKernelStep(); + await selectKernelName('kernel-debug'); + await selectKernelName('Default kernel package'); + await goToReviewStep(); + const receivedRequest = await interceptBlueprintRequest(CREATE_BLUEPRINT); + + const expectedRequest = { + ...blueprintRequest, + }; + + await waitFor(() => { + expect(receivedRequest).toEqual(expectedRequest); + }); + }); }); // TO DO 'Kernel step' -> 'revisit step button on Review works'