debian-image-builder-frontend/src/Components/CreateImageWizard/steps/Review/ReviewStep.tsx
regexowl 96d68583a3 Wizard: Add kernel to Review step
This adds a kernel expandable to the Review step.
2025-01-27 13:48:39 -06:00

461 lines
15 KiB
TypeScript

import React, { useState } from 'react';
import {
Button,
ExpandableSection,
Text,
TextContent,
TextList,
TextListItem,
TextListItemVariants,
TextListVariants,
TextVariants,
useWizardContext,
} from '@patternfly/react-core';
import { ArrowRightIcon } from '@patternfly/react-icons';
import {
ContentList,
FSCList,
FirstBootList,
DetailsList,
ImageOutputList,
OscapList,
RegisterLaterList,
RegisterNowList,
TargetEnvAWSList,
TargetEnvAzureList,
TargetEnvGCPList,
TargetEnvOciList,
TargetEnvOtherList,
UsersList,
TimezoneList,
LocaleList,
HostnameList,
KernelList,
} from './ReviewStepTextLists';
import isRhel from '../../../../../src/Utilities/isRhel';
import { targetOptions } from '../../../../constants';
import { useAppSelector } from '../../../../store/hooks';
import {
selectBlueprintDescription,
selectBlueprintName,
selectComplianceType,
selectCompliancePolicyID,
selectComplianceProfileID,
selectDistribution,
selectImageTypes,
selectRegistrationType,
selectHostname,
selectLanguages,
selectKeyboard,
selectTimezone,
selectNtpServers,
} from '../../../../store/wizardSlice';
import { useFlag } from '../../../../Utilities/useGetEnvironment';
const Review = ({ snapshottingEnabled }: { snapshottingEnabled: boolean }) => {
const { goToStepById } = useWizardContext();
const blueprintName = useAppSelector(selectBlueprintName);
const blueprintDescription = useAppSelector(selectBlueprintDescription);
const distribution = useAppSelector(selectDistribution);
const environments = useAppSelector(selectImageTypes);
const complianceType = useAppSelector(selectComplianceType);
const complianceProfile = useAppSelector(selectComplianceProfileID);
const compliancePolicy = useAppSelector(selectCompliancePolicyID);
const registrationType = useAppSelector(selectRegistrationType);
const hostname = useAppSelector(selectHostname);
const languages = useAppSelector(selectLanguages);
const keyboard = useAppSelector(selectKeyboard);
const timezone = useAppSelector(selectTimezone);
const ntpServers = useAppSelector(selectNtpServers);
const [isExpandedImageOutput, setIsExpandedImageOutput] = useState(true);
const [isExpandedTargetEnvs, setIsExpandedTargetEnvs] = useState(true);
const [isExpandedFSC, setIsExpandedFSC] = useState(true);
const [isExpandedContent, setIsExpandedContent] = useState(true);
const [isExpandedRegistration, setIsExpandedRegistration] = useState(true);
const [isExpandedImageDetail, setIsExpandedImageDetail] = useState(true);
const [isExpandedOscapDetail, setIsExpandedOscapDetail] = useState(true);
const [isExpandedComplianceDetail, setIsExpandedComplianceDetail] =
useState(true);
const [isExpandedTimezone, setIsExpandedTimezone] = useState(true);
const [isExpandedLocale, setIsExpandedLocale] = useState(true);
const [isExpandedHostname, setIsExpandedHostname] = useState(true);
const [isExpandedKernel, setIsExpandedKernel] = useState(true);
const [isExpandableFirstBoot, setIsExpandedFirstBoot] = useState(true);
const [isExpandedUsers, setIsExpandedUsers] = useState(true);
const isTimezoneEnabled = useFlag('image-builder.timezone.enabled');
const isLocaleEnabled = useFlag('image-builder.locale.enabled');
const isHostnameEnabled = useFlag('image-builder.hostname.enabled');
const isKernelEnabled = useFlag('image-builder.kernel.enabled');
const onToggleImageOutput = (isExpandedImageOutput: boolean) =>
setIsExpandedImageOutput(isExpandedImageOutput);
const onToggleTargetEnvs = (isExpandedTargetEnvs: boolean) =>
setIsExpandedTargetEnvs(isExpandedTargetEnvs);
const onToggleFSC = (isExpandedFSC: boolean) =>
setIsExpandedFSC(isExpandedFSC);
const onToggleContent = (isExpandedContent: boolean) =>
setIsExpandedContent(isExpandedContent);
const onToggleRegistration = (isExpandedRegistration: boolean) =>
setIsExpandedRegistration(isExpandedRegistration);
const onToggleImageDetail = (isExpandedImageDetail: boolean) =>
setIsExpandedImageDetail(isExpandedImageDetail);
const onToggleOscapDetails = (isExpandedOscapDetail: boolean) =>
setIsExpandedOscapDetail(isExpandedOscapDetail);
const onToggleComplianceDetails = (isExpandedComplianceDetail: boolean) =>
setIsExpandedComplianceDetail(isExpandedComplianceDetail);
const onToggleTimezone = (isExpandedTimezone: boolean) =>
setIsExpandedTimezone(isExpandedTimezone);
const onToggleLocale = (isExpandedLocale: boolean) =>
setIsExpandedLocale(isExpandedLocale);
const onToggleHostname = (isExpandedHostname: boolean) =>
setIsExpandedHostname(isExpandedHostname);
const onToggleKernel = (isExpandedKernel: boolean) =>
setIsExpandedKernel(isExpandedKernel);
const onToggleFirstBoot = (isExpandableFirstBoot: boolean) =>
setIsExpandedFirstBoot(isExpandableFirstBoot);
const onToggleUsers = (isExpandedUsers: boolean) =>
setIsExpandedUsers(isExpandedUsers);
type RevisitStepButtonProps = {
ariaLabel: string;
testId: string;
stepId: string;
};
const RevisitStepButton = ({
ariaLabel,
testId,
stepId,
}: RevisitStepButtonProps) => {
return (
<Button
variant="link"
aria-label={ariaLabel}
data-testid={testId}
component="span"
onClick={() => revisitStep(stepId)}
className="pf-v5-u-p-0 pf-v5-u-font-weight-bold"
isInline
>
Revisit step <ArrowRightIcon />
</Button>
);
};
const revisitStep = (stepId: string) => {
goToStepById(stepId);
};
const composeExpandable = (label: string, testId: string, stepId: string) => {
return (
<TextContent>
<TextList component={TextListVariants.dl}>
<TextListItem
component={TextListItemVariants.dt}
className="pf-v5-u-min-width pf-v5-u-text-align-left"
>
<Button variant="link" component="span" isInline>
{label}
</Button>
</TextListItem>
<TextListItem component={TextListItemVariants.dd}>
<RevisitStepButton
ariaLabel={`Revisit ${label} step`}
testId={testId}
stepId={stepId}
/>
</TextListItem>
</TextList>
</TextContent>
);
};
const isFirstBootEnabled = useFlag('image-builder.firstboot.enabled');
const isUsersEnabled = useFlag('image-builder.users.enabled');
return (
<>
<ExpandableSection
toggleContent={composeExpandable(
'Image output',
'revisit-image-output',
'step-image-output'
)}
onToggle={(_event, isExpandedImageOutput) =>
onToggleImageOutput(isExpandedImageOutput)
}
isExpanded={isExpandedImageOutput}
isIndented
data-testid="image-output-expandable"
>
<ImageOutputList />
</ExpandableSection>
<ExpandableSection
toggleContent={composeExpandable(
'Target environments',
'revisit-target-environments',
'step-image-output'
)}
onToggle={(_event, isExpandedTargetEnvs) =>
onToggleTargetEnvs(isExpandedTargetEnvs)
}
isExpanded={isExpandedTargetEnvs}
isIndented
data-testid="target-environments-expandable"
>
{environments.includes('aws') && <TargetEnvAWSList />}
{environments.includes('gcp') && <TargetEnvGCPList />}
{environments.includes('azure') && <TargetEnvAzureList />}
{environments.includes('oci') && <TargetEnvOciList />}
{environments.includes('vsphere') && (
<TextContent>
<Text component={TextVariants.h3}>
{targetOptions.vsphere} (.vmdk)
</Text>
<TargetEnvOtherList />
</TextContent>
)}
{environments.includes('vsphere-ova') && (
<TextContent>
<Text component={TextVariants.h3}>
{targetOptions['vsphere-ova']} (.ova)
</Text>
<TargetEnvOtherList />
</TextContent>
)}
{environments.includes('guest-image') && (
<TextContent>
<Text component={TextVariants.h3}>
{targetOptions['guest-image']} (.qcow2)
</Text>
<TargetEnvOtherList />
</TextContent>
)}
{environments.includes('image-installer') && (
<TextContent>
<Text component={TextVariants.h3}>
{targetOptions['image-installer']} (.iso)
</Text>
<TargetEnvOtherList />
</TextContent>
)}
{environments.includes('wsl') && (
<TextContent>
<Text component={TextVariants.h3}>
WSL - {targetOptions.wsl} (.tar.gz)
</Text>
<TargetEnvOtherList />
</TextContent>
)}
</ExpandableSection>
{isRhel(distribution) && (
<ExpandableSection
toggleContent={composeExpandable(
'Registration',
'revisit-registration',
'step-register'
)}
onToggle={(_event, isExpandedRegistration) =>
onToggleRegistration(isExpandedRegistration)
}
isExpanded={isExpandedRegistration}
isIndented
data-testid="registration-expandable"
>
{registrationType === 'register-later' && <RegisterLaterList />}
{registrationType.startsWith('register-now') && <RegisterNowList />}
</ExpandableSection>
)}
{complianceProfile && complianceType === 'openscap' && (
<ExpandableSection
toggleContent={composeExpandable(
'OpenSCAP',
'revisit-openscap',
'step-oscap'
)}
onToggle={(_event, isExpandedOscapDetail) =>
onToggleOscapDetails(isExpandedOscapDetail)
}
isExpanded={isExpandedOscapDetail}
isIndented
data-testid="oscap-detail-expandable"
>
<OscapList />
</ExpandableSection>
)}
{compliancePolicy && complianceType === 'compliance' && (
<ExpandableSection
toggleContent={composeExpandable(
'Compliance',
'revisit-compliance',
'step-oscap'
)}
onToggle={(_event, isExpandedComplianceDetail) =>
onToggleComplianceDetails(isExpandedComplianceDetail)
}
isExpanded={isExpandedComplianceDetail}
isIndented
data-testid="compliance-detail-expandable"
>
<OscapList />
</ExpandableSection>
)}
<ExpandableSection
toggleContent={composeExpandable(
'File system configuration',
'revisit-file-system',
'step-file-system'
)}
onToggle={(_event, isExpandedFSC) => onToggleFSC(isExpandedFSC)}
isExpanded={isExpandedFSC}
isIndented
data-testid="file-system-configuration-expandable"
>
<FSCList />
</ExpandableSection>
<ExpandableSection
toggleContent={composeExpandable(
'Content',
'revisit-custom-repositories',
'wizard-custom-repositories'
)}
onToggle={(_event, isExpandedContent) =>
onToggleContent(isExpandedContent)
}
isExpanded={isExpandedContent}
isIndented
data-testid="content-expandable"
>
{/* Intentional prop drilling for simplicity - To be removed */}
<ContentList snapshottingEnabled={snapshottingEnabled} />
</ExpandableSection>
{isUsersEnabled && (
<ExpandableSection
toggleContent={composeExpandable(
'Users',
'revisit-users',
'wizard-users'
)}
onToggle={(_event, isExpandedUsers) => onToggleUsers(isExpandedUsers)}
isExpanded={isExpandedUsers}
isIndented
data-testid="users-expandable"
>
<UsersList />
</ExpandableSection>
)}
{isTimezoneEnabled &&
(timezone || (ntpServers && ntpServers.length > 0)) && (
<ExpandableSection
toggleContent={composeExpandable(
'Timezone',
'revisit-timezone',
'wizard-timezone'
)}
onToggle={(_event, isExpandedTimezone) =>
onToggleTimezone(isExpandedTimezone)
}
isExpanded={isExpandedTimezone}
isIndented
data-testid="timezone-expandable"
>
<TimezoneList />
</ExpandableSection>
)}
{isLocaleEnabled &&
((languages && languages.length > 0) ||
(keyboard && keyboard.length > 0)) && (
<ExpandableSection
toggleContent={composeExpandable(
'Locale',
'revisit-locale',
'wizard-locale'
)}
onToggle={(_event, isExpandedLocale) =>
onToggleLocale(isExpandedLocale)
}
isExpanded={isExpandedLocale}
isIndented
data-testid="locale-expandable"
>
<LocaleList />
</ExpandableSection>
)}
{isHostnameEnabled && hostname && (
<ExpandableSection
toggleContent={composeExpandable(
'Hostname',
'revisit-hostname',
'wizard-hostname'
)}
onToggle={(_event, isExpandedHostname) =>
onToggleHostname(isExpandedHostname)
}
isExpanded={isExpandedHostname}
isIndented
data-testid="hostname-expandable"
>
<HostnameList />
</ExpandableSection>
)}
{isKernelEnabled && (
<ExpandableSection
toggleContent={composeExpandable(
'Kernel',
'revisit-kernel',
'wizard-kernel'
)}
onToggle={(_event, isExpandedKernel) =>
onToggleKernel(isExpandedKernel)
}
isExpanded={isExpandedKernel}
isIndented
data-testid="kernel-expandable"
>
<KernelList />
</ExpandableSection>
)}
{isFirstBootEnabled && (
<ExpandableSection
toggleContent={composeExpandable(
'First boot',
'revisit-first-boot',
'wizard-first-boot'
)}
onToggle={(_event, isExpandableFirstBoot) =>
onToggleFirstBoot(isExpandableFirstBoot)
}
isExpanded={isExpandableFirstBoot}
isIndented
data-testid="firstboot-expandable"
>
<FirstBootList />
</ExpandableSection>
)}
{(blueprintName || blueprintDescription) && (
<ExpandableSection
toggleContent={composeExpandable(
'Details',
'revisit-details',
'step-details'
)}
onToggle={(_event, isExpandedImageDetail) =>
onToggleImageDetail(isExpandedImageDetail)
}
isExpanded={isExpandedImageDetail}
isIndented
data-testid="image-details-expandable"
>
<DetailsList />
</ExpandableSection>
)}
</>
);
};
export default Review;