Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions src/Components/CreateImageWizard/CreateImageWizard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
parseStateFromRequest,
selectDistribution,
selectImageSource,
selectImageSourceType,
selectImageTypes,
selectIsImageMode,
selectTimezone,
Expand Down Expand Up @@ -121,6 +122,7 @@ const CreateImageWizard = () => {
const isOnPremise = useAppSelector(selectIsOnPremise);
const isImageMode = useAppSelector(selectIsImageMode);
const imageSource = useAppSelector(selectImageSource);
const imageSourceType = useAppSelector(selectImageSourceType);
const [searchParams, setSearchParams] = useSearchParams();
const resolvePath = useAppSelector(selectPathResolver);
const hasInitialized = useRef(false);
Expand Down Expand Up @@ -170,6 +172,11 @@ const CreateImageWizard = () => {
const usersHaveErrors =
usersValidation.disabledNext || userGroupsValidation.disabledNext;

// The "Local images" source is a fake door: it only shows a coming-soon
// note, so the wizard must not proceed past base settings.
const localImageSourceSelected =
isOnPremise && isImageMode && imageSourceType === 'local';

const baseSettingsHasErrors =
targetEnvironments.length === 0 ||
(isImageMode && !imageSource) ||
Expand Down Expand Up @@ -417,10 +424,11 @@ const CreateImageWizard = () => {
(s) => s.id === 'base-settings-step',
)?.isVisited;
const canNavigate =
mode === 'edit' ||
step.isVisited ||
isBaseSettingsStep ||
(hasVisitedBaseSettings && !baseSettingsHasErrors);
(isBaseSettingsStep || !localImageSourceSelected) &&
(mode === 'edit' ||
step.isVisited ||
isBaseSettingsStep ||
(hasVisitedBaseSettings && !baseSettingsHasErrors));

return (
<WizardNavItem
Expand Down Expand Up @@ -487,6 +495,7 @@ const CreateImageWizard = () => {
footer={
<CustomWizardFooter
disableBack={true}
disableNext={localImageSourceSelected}
hasErrors={baseSettingsHasErrors}
isOnPremise={isOnPremise}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ import { scrollToFirstError } from '../utilities/scrollToFirstError';

type CustomWizardFooterPropType = {
disableBack?: boolean;
disableNext?: boolean;
hasErrors: boolean;
beforeNext?: () => boolean;
isOnPremise: boolean;
};

export const CustomWizardFooter = ({
disableBack,
disableNext = false,
hasErrors,
beforeNext,
isOnPremise,
Expand Down Expand Up @@ -89,10 +91,18 @@ export const CustomWizardFooter = ({
>
Back
</Button>
<Button variant='secondary' onClick={handleNext}>
<Button
variant='secondary'
onClick={handleNext}
isDisabled={disableNext}
>
Next
</Button>
<Button variant='primary' onClick={handleReview}>
<Button
variant='primary'
onClick={handleReview}
isDisabled={disableNext}
>
Review image
</Button>
<Button
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';

import { Wizard, WizardStep } from '@patternfly/react-core';
import { screen } from '@testing-library/react';

import { renderWithRedux } from '@/test/testUtils';

import CustomWizardFooter from '../CustomWizardFooter';

const renderFooter = (
props: Partial<React.ComponentProps<typeof CustomWizardFooter>> = {},
) => {
return renderWithRedux(
<Wizard>
<WizardStep
name='Test step'
id='test-step'
footer={
<CustomWizardFooter hasErrors={false} isOnPremise={true} {...props} />
}
>
Step content
</WizardStep>
</Wizard>,
);
};

describe('CustomWizardFooter', () => {
test('Next and Review image are enabled by default', async () => {
renderFooter();

expect(await screen.findByRole('button', { name: 'Next' })).toBeEnabled();
expect(screen.getByRole('button', { name: 'Review image' })).toBeEnabled();
});

test('Next and Review image are disabled when disableNext is set', async () => {
renderFooter({ disableNext: true });

expect(await screen.findByRole('button', { name: 'Next' })).toBeDisabled();
expect(screen.getByRole('button', { name: 'Review image' })).toBeDisabled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ const HostedImageSourceSelect = () => {

return (
<FormGroup label='Image source' isRequired>
{isError && <ImageSourceError isOnPremise={false} />}
{isError && <ImageSourceError />}
<Select
isOpen={isOpen}
selected={imageSource}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,13 @@ import React from 'react';

import { Alert } from '@patternfly/react-core';

type ImageSourceErrorProps = {
isOnPremise: boolean;
};

const ImageSourceError = ({ isOnPremise }: ImageSourceErrorProps) => (
const ImageSourceError = () => (
<Alert
title='Error loading bootc images'
variant='danger'
className='pf-v6-u-mb-md'
>
{isOnPremise
? 'Unable to load available bootc images. Ensure podman is installed and accessible.'
: 'Unable to load available bootc images. Please try again later.'}
Unable to load available bootc images. Please try again later.
</Alert>
);

Expand Down

This file was deleted.

Loading
Loading