From 4c14cd1ae0c913c8660909db18d6201e8025fc43 Mon Sep 17 00:00:00 2001 From: mgold1234 Date: Tue, 23 Jan 2024 15:55:08 +0200 Subject: [PATCH] V2Wizard: add components to the review step --- .../CreateImageWizardV2/CreateImageWizard.tsx | 9 +- .../steps/Review/ReviewStep.tsx | 108 +++++----- .../steps/Review/ReviewStepTables.tsx | 62 ++---- .../steps/Review/ReviewStepTextLists.tsx | 200 +++++++++--------- .../steps/Review/index.tsx | 16 ++ src/store/helpers.ts | 5 +- 6 files changed, 187 insertions(+), 213 deletions(-) create mode 100644 src/Components/CreateImageWizardV2/steps/Review/index.tsx diff --git a/src/Components/CreateImageWizardV2/CreateImageWizard.tsx b/src/Components/CreateImageWizardV2/CreateImageWizard.tsx index 25e6cf57f3..98527e4efb 100644 --- a/src/Components/CreateImageWizardV2/CreateImageWizard.tsx +++ b/src/Components/CreateImageWizardV2/CreateImageWizard.tsx @@ -14,6 +14,7 @@ import ImageOutputStep from './steps/ImageOutput'; import OscapStep from './steps/Oscap'; import RegistrationStep from './steps/Registration'; import RepositoriesStep from './steps/Repositories'; +import ReviewStep from './steps/Review'; import Aws from './steps/TargetEnvironment/Aws'; import Gcp from './steps/TargetEnvironment/Gcp'; import { @@ -208,11 +209,9 @@ const CreateImageWizard = () => { > - } - > + + + diff --git a/src/Components/CreateImageWizardV2/steps/Review/ReviewStep.tsx b/src/Components/CreateImageWizardV2/steps/Review/ReviewStep.tsx index 8e159cb574..771e78ef9c 100644 --- a/src/Components/CreateImageWizardV2/steps/Review/ReviewStep.tsx +++ b/src/Components/CreateImageWizardV2/steps/Review/ReviewStep.tsx @@ -1,15 +1,12 @@ import React, { useEffect, useState } from 'react'; -import useFormApi from '@data-driven-forms/react-form-renderer/use-form-api'; import { ExpandableSection, Text, TextContent, TextVariants, } from '@patternfly/react-core'; -import { useChrome } from '@redhat-cloud-services/frontend-components/useChrome'; -import RepositoryUnavailable from './RepositoryUnavailable'; import { ContentList, FSCList, @@ -24,12 +21,26 @@ import { TargetEnvOciList, TargetEnvOtherList, } from './ReviewStepTextLists'; -import UsrSubDirectoriesDisabled from './UsrSubDirectoriesDisabled'; -import isRhel from '../../../Utilities/isRhel'; +import isRhel from '../../../../../src/Utilities/isRhel'; +import { useAppSelector } from '../../../../store/hooks'; +import { + selectBlueprintDescription, + selectBlueprintName, + selectDistribution, + selectImageTypes, + selectProfile, + selectRegistrationType, +} from '../../../../store/wizardSlice'; -const ReviewStep = () => { - const { auth } = useChrome(); +const Review = () => { + const registrationType = useAppSelector((state) => + selectRegistrationType(state) + ); + // const configurationType = useAppSelector((state) => + // selectConfigurationType(state) + // ); + const distribution = useAppSelector((state) => selectDistribution(state)); const [isExpandedImageOutput, setIsExpandedImageOutput] = useState(false); const [isExpandedTargetEnvs, setIsExpandedTargetEnvs] = useState(false); const [isExpandedFSC, setIsExpandedFSC] = useState(false); @@ -37,39 +48,43 @@ const ReviewStep = () => { const [isExpandedRegistration, setIsExpandedRegistration] = useState(false); const [isExpandedImageDetail, setIsExpandedImageDetail] = useState(false); const [isExpandedOscapDetail, setIsExpandedOscapDetail] = useState(false); - const { change, getState } = useFormApi(); - + const environments = useAppSelector((state) => selectImageTypes(state)); + const blueprintName = useAppSelector((state) => selectBlueprintName(state)); + const blueprintDescription = useAppSelector((state) => + selectBlueprintDescription(state) + ); + const oscapProfile = useAppSelector((state) => selectProfile(state)); useEffect(() => { - const registerSystem = getState()?.values?.['register-system']; - if (registerSystem?.startsWith('register-now')) { + if (registrationType?.startsWith('register-now')) { (async () => { - const userData = await auth?.getUser(); - const id = userData?.identity?.internal?.org_id; - change('subscription-organization-id', id); + // const userData = await auth?.getUser(); + // const id = userData?.identity?.internal?.org_id; + // dispatch(changeOrganizationId(id)); })(); } }); - const onToggleImageOutput = (isExpandedImageOutput) => + const onToggleImageOutput = (isExpandedImageOutput: boolean) => setIsExpandedImageOutput(isExpandedImageOutput); - const onToggleTargetEnvs = (isExpandedTargetEnvs) => + const onToggleTargetEnvs = (isExpandedTargetEnvs: boolean) => setIsExpandedTargetEnvs(isExpandedTargetEnvs); - const onToggleFSC = (isExpandedFSC) => setIsExpandedFSC(isExpandedFSC); - const onToggleContent = (isExpandedContent) => + const onToggleFSC = (isExpandedFSC: boolean) => + setIsExpandedFSC(isExpandedFSC); + const onToggleContent = (isExpandedContent: boolean) => setIsExpandedContent(isExpandedContent); - const onToggleRegistration = (isExpandedRegistration) => + const onToggleRegistration = (isExpandedRegistration: boolean) => setIsExpandedRegistration(isExpandedRegistration); - const onToggleImageDetail = (isExpandedImageDetail) => + const onToggleImageDetail = (isExpandedImageDetail: boolean) => setIsExpandedImageDetail(isExpandedImageDetail); - const onToggleOscapDetails = (isExpandedOscapDetail) => + const onToggleOscapDetails = (isExpandedOscapDetail: boolean) => setIsExpandedOscapDetail(isExpandedOscapDetail); return ( <> - - {getState()?.values?.['file-system-configuration']?.find((mp) => - mp.mountpoint.includes('/usr') - ) && } + {/* } + {getState()?.values?.['file-system-configuration']?.find((mp) => + mp.mountpoint.includes('/usr') + ) && }*/} @@ -90,31 +105,23 @@ const ReviewStep = () => { isIndented data-testid="target-environments-expandable" > - {getState()?.values?.['target-environment']?.aws && ( - - )} - {getState()?.values?.['target-environment']?.gcp && ( - - )} - {getState()?.values?.['target-environment']?.azure && ( - - )} - {getState()?.values?.['target-environment']?.oci && ( - - )} - {getState()?.values?.['target-environment']?.vsphere && ( + {environments.includes('aws') && } + {environments.includes('gcp') && } + {environments.includes('azure') && } + {environments.includes('oci') && } + {environments.includes('vsphere') && ( VMware vSphere (.vmdk) )} - {getState()?.values?.['target-environment']?.['vsphere-ova'] && ( + {environments.includes('vsphere-ova') && ( VMware vSphere (.ova) )} - {getState()?.values?.['target-environment']?.['guest-image'] && ( + {environments.includes('guest-image') && ( Virtualization - Guest image (.qcow2) @@ -122,7 +129,7 @@ const ReviewStep = () => { )} - {getState()?.values?.['target-environment']?.['image-installer'] && ( + {environments.includes('image-installer') && ( Bare metal - Installer (.iso) @@ -130,7 +137,7 @@ const ReviewStep = () => { )} - {getState()?.values?.['target-environment']?.wsl && ( + {environments.includes('wsl') && ( WSL - Windows Subsystem for Linux (.tar.gz) @@ -159,7 +166,7 @@ const ReviewStep = () => { > - {isRhel(getState()?.values?.release) && ( + {isRhel(distribution) && ( @@ -169,16 +176,11 @@ const ReviewStep = () => { isIndented data-testid="registration-expandable" > - {getState()?.values?.['register-system'] === 'register-later' && ( - - )} - {getState()?.values?.['register-system']?.startsWith( - 'register-now' - ) && } + {registrationType === 'register-later' && } + {registrationType.startsWith('register-now') && } )} - {(getState()?.values?.['image-name'] || - getState()?.values?.['image-description']) && ( + {(blueprintName || blueprintDescription) && ( @@ -191,7 +193,7 @@ const ReviewStep = () => { )} - {getState()?.values?.['oscap-profile'] && ( + {oscapProfile && ( @@ -208,4 +210,4 @@ const ReviewStep = () => { ); }; -export default ReviewStep; +export default Review; diff --git a/src/Components/CreateImageWizardV2/steps/Review/ReviewStepTables.tsx b/src/Components/CreateImageWizardV2/steps/Review/ReviewStepTables.tsx index fb84e64f79..8c66ad01d1 100644 --- a/src/Components/CreateImageWizardV2/steps/Review/ReviewStepTables.tsx +++ b/src/Components/CreateImageWizardV2/steps/Review/ReviewStepTables.tsx @@ -1,15 +1,19 @@ import React from 'react'; -import { useFormApi } from '@data-driven-forms/react-form-renderer'; import { Alert, Panel, PanelMain, Spinner } from '@patternfly/react-core'; import { Table, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table'; -import PropTypes from 'prop-types'; -import { UNIT_GIB, UNIT_MIB } from '../../../constants'; -import { useListRepositoriesQuery } from '../../../store/contentSourcesApi'; +import { useListRepositoriesQuery } from '../../../../store/contentSourcesApi'; +import { useAppSelector } from '../../../../store/hooks'; +import { selectCustomRepositories } from '../../../../store/wizardSlice'; -const RepoName = ({ repoUrl }) => { +type repoPropType = { + repoUrl: string[] | undefined; +}; + +const RepoName = ({ repoUrl }: repoPropType) => { const { data, isSuccess, isFetching, isError } = useListRepositoriesQuery({ + // @ts-ignore url: repoUrl, contentType: 'rpm', origin: 'external', @@ -46,8 +50,6 @@ const RepoName = ({ repoUrl }) => { }; export const FSReviewTable = () => { - const { getState } = useFormApi(); - const fsc = getState().values['file-system-configuration']; return ( @@ -59,22 +61,6 @@ export const FSReviewTable = () => { Minimum size - - {fsc.map((partition, partitionIndex) => ( - - {partition.mountpoint} - xfs - - {partition.size}{' '} - {partition.unit === UNIT_GIB - ? 'GiB' - : partition.unit === UNIT_MIB - ? 'MiB' - : 'KiB'} - - - ))} - @@ -82,33 +68,17 @@ export const FSReviewTable = () => { }; export const PackagesTable = () => { - const { getState } = useFormApi(); - const packages = getState()?.values['selected-packages']; return ( - - - - - - - - - {packages.map((pkg, pkgIndex) => ( - - - - ))} - -
Name
{pkg.name}
-
+
); }; export const RepositoriesTable = () => { - const { getState } = useFormApi(); - const repositories = getState()?.values?.['payload-repositories']; + const repositoriesList = useAppSelector((state) => + selectCustomRepositories(state) + ); return ( @@ -119,7 +89,7 @@ export const RepositoriesTable = () => { - {repositories.map((repo, repoIndex) => ( + {repositoriesList?.map((repo, repoIndex) => ( @@ -132,7 +102,3 @@ export const RepositoriesTable = () => { ); }; - -RepoName.propTypes = { - repoUrl: PropTypes.string, -}; diff --git a/src/Components/CreateImageWizardV2/steps/Review/ReviewStepTextLists.tsx b/src/Components/CreateImageWizardV2/steps/Review/ReviewStepTextLists.tsx index 2b6650031f..2552938b3e 100644 --- a/src/Components/CreateImageWizardV2/steps/Review/ReviewStepTextLists.tsx +++ b/src/Components/CreateImageWizardV2/steps/Review/ReviewStepTextLists.tsx @@ -1,11 +1,9 @@ import React from 'react'; -import { useFormApi } from '@data-driven-forms/react-form-renderer'; import { Alert, Button, Popover, - Spinner, Text, TextContent, TextList, @@ -15,24 +13,31 @@ import { TextVariants, } from '@patternfly/react-core'; import { ExclamationTriangleIcon, HelpIcon } from '@patternfly/react-icons'; -import PropTypes from 'prop-types'; -import ActivationKeyInformation from './ActivationKeyInformation'; -import { AwsAccountId } from './AwsAccountId'; -import ReleaseLifecycle from './ReleaseLifecycle'; -import { - FSReviewTable, - PackagesTable, - RepositoriesTable, -} from './ReviewStepTables'; +import ReleaseLifecycle from './../ImageOutput/ReleaseLifecycle'; +import ActivationKeyInformation from './../Registration/ActivationKeyInformation'; +import { AwsAccountId } from './../TargetEnvironment/Aws/AwsAccountId'; -import { RELEASES, UNIT_GIB } from '../../../constants'; -import { extractProvisioningList } from '../../../store/helpers'; -import { useGetOscapCustomizationsQuery } from '../../../store/imageBuilderApi'; -import { useGetSourceListQuery } from '../../../store/provisioningApi'; -import { useShowActivationKeyQuery } from '../../../store/rhsmApi'; -import { useGetEnvironment } from '../../../Utilities/useGetEnvironment'; -import { googleAccType } from '../steps/googleCloud'; +import { RELEASES } from '../../../../constants'; +import { extractProvisioningList } from '../../../../store/helpers'; +import { useAppSelector } from '../../../../store/hooks'; +import { useGetOscapCustomizationsQuery } from '../../../../store/imageBuilderApi'; +import { useGetSourceListQuery } from '../../../../store/provisioningApi'; +import { useShowActivationKeyQuery } from '../../../../store/rhsmApi'; +import { + selectActivationKey, + selectArchitecture, + selectAwsAccountId, + selectAwsShareMethod, + selectBlueprintDescription, + selectBlueprintName, + selectDistribution, + selectGcpAccountType, + selectGcpEmail, + selectProfile, + selectRegistrationType, +} from '../../../../store/wizardSlice'; +import { useGetEnvironment } from '../../../../Utilities/useGetEnvironment'; const ExpirationWarning = () => { return ( @@ -43,7 +48,8 @@ const ExpirationWarning = () => { }; export const ImageOutputList = () => { - const { getState } = useFormApi(); + const distribution = useAppSelector((state) => selectDistribution(state)); + const arch = useAppSelector((state) => selectArchitecture(state)); return ( @@ -55,14 +61,12 @@ export const ImageOutputList = () => { Release - {RELEASES.get(getState()?.values?.release)} + {RELEASES.get(distribution)} Architecture - - {getState()?.values?.arch} - + {arch}
@@ -73,10 +77,12 @@ export const TargetEnvAWSList = () => { const { data: rawAWSSources, isSuccess } = useGetSourceListQuery({ provider: 'aws', }); + const awsAccountId = useAppSelector((state) => selectAwsAccountId(state)); + const awsShareMethod = useAppSelector((state) => selectAwsShareMethod(state)); + const awsSources = extractProvisioningList(rawAWSSources); const { isBeta } = useGetEnvironment(); - const { getState } = useFormApi(); return ( AWS @@ -96,32 +102,18 @@ export const TargetEnvAWSList = () => { Shared to account - {!isBeta() && getState()?.values?.['aws-account-id']} - {isBeta() && - getState()?.values?.['aws-target-type'] === - 'aws-target-type-source' && - isSuccess && ( - - )} - {isBeta() && - getState()?.values?.['aws-target-type'] === - 'aws-target-type-account-id' && - getState()?.values?.['aws-account-id']} + {!isBeta() && awsAccountId} + {isBeta() && awsShareMethod === 'sources' && isSuccess && ( + + )} + {isBeta() && awsShareMethod === 'manual' && awsAccountId} - {getState()?.values?.['aws-target-type'] === 'aws-target-type-source' - ? 'Source' - : null} + {awsShareMethod === 'sources' ? 'Source' : null} - {isSuccess && - getState()?.values?.['aws-target-type'] === 'aws-target-type-source' - ? awsSources.find( - (source) => - source.id === getState()?.values?.['aws-sources-select'] - )?.name + {isSuccess && awsShareMethod === 'sources' + ? awsSources?.find((source) => source.id === source)?.name : null} @@ -137,7 +129,8 @@ export const TargetEnvAWSList = () => { }; export const TargetEnvGCPList = () => { - const { getState } = useFormApi(); + const accountType = useAppSelector((state) => selectGcpAccountType(state)); + const email = useAppSelector((state) => selectGcpEmail(state)); return ( GCP @@ -157,17 +150,13 @@ export const TargetEnvGCPList = () => { Account type - {googleAccType?.[getState()?.values?.['google-account-type']]} + {accountType} - {googleAccType?.[getState()?.values?.['google-account-type']] === - 'Domain' - ? 'Domain' - : 'Principal'} + {accountType === 'domain' ? 'Domain' : 'Principal'} - {getState()?.values?.['google-email'] || - getState()?.values?.['google-domain']} + {email || accountType}
@@ -176,10 +165,6 @@ export const TargetEnvGCPList = () => { }; export const TargetEnvAzureList = () => { - const { getState } = useFormApi(); - const { data: rawAzureSources, isSuccess: isSuccessAzureSources } = - useGetSourceListQuery({ provider: 'azure' }); - const azureSources = extractProvisioningList(rawAzureSources); return ( Microsoft Azure @@ -190,12 +175,12 @@ export const TargetEnvAzureList = () => { > Image type - + {/* Red Hat hosted image
-
- {getState()?.values?.['azure-type'] === 'azure-type-source' && +
*/} + {/* {getState()?.values?.['azure-type'] === 'azure-type-source' && isSuccessAzureSources && ( <> @@ -232,7 +217,7 @@ export const TargetEnvAzureList = () => { {getState()?.values?.['azure-resource-group']} - + */}
@@ -280,14 +265,14 @@ export const TargetEnvOtherList = () => { }; export const FSCList = () => { - const { getState } = useFormApi(); - const isManual = - getState()?.values?.['file-system-config-radio'] === 'manual'; - const partitions = getState()?.values?.['file-system-configuration']; + // const { getState } = useFormApi(); + // const isManual = + // getState()?.values?.['file-system-config-radio'] === 'manual'; + // const partitions = getState()?.values?.['file-system-configuration']; return ( - + {/*} { )} - + */}
); }; -export const MinSize = ({ isManual, partitions }) => { +{ + /* export const MinSize = ({ isManual, partitions }) => { let minSize = ''; if (isManual && partitions) { let size = 0; @@ -380,10 +366,10 @@ export const MinSize = ({ isManual, partitions }) => { MinSize.propTypes = { isManual: PropTypes.bool, partitions: PropTypes.arrayOf(PropTypes.object), -}; +}; */ +} export const ContentList = () => { - const { getState } = useFormApi(); return ( @@ -399,7 +385,7 @@ export const ContentList = () => { component={TextListItemVariants.dd} data-testid="chosen-packages-count" > - {getState()?.values?.['selected-packages']?.length > 0 ? ( + {/*} {getState()?.values?.['selected-packages']?.length > 0 ? ( { ) : ( 0 - )} + )}{*/}
@@ -472,9 +458,12 @@ export const RegisterLaterList = () => { }; export const RegisterNowList = () => { - const { getState } = useFormApi(); - const activationKey = getState()?.values?.['subscription-activation-key']; + const activationKey = useAppSelector((state) => selectActivationKey(state)); + const registrationType = useAppSelector((state) => + selectRegistrationType(state) + ); const { isError } = useShowActivationKeyQuery( + // @ts-ignore - type of 'activationKey' might not be strictly compatible with the expected type for 'name'. { name: activationKey }, { skip: !activationKey, @@ -495,25 +484,20 @@ export const RegisterNowList = () => { data-testid="review-registration" > - {getState()?.values?.['register-system']?.startsWith( - 'register-now' - ) && ( + {registrationType?.startsWith('register-now') && ( Register with Red Hat Subscription Manager (RHSM)
)} - {(getState()?.values?.['register-system'] === - 'register-now-insights' || - getState()?.values?.['register-system'] === - 'register-now-rhc') && ( - - Connect to Red Hat Insights -
-
- )} - {getState()?.values?.['register-system'] === - 'register-now-rhc' && ( + {registrationType === 'register-now-insights' || + (registrationType === 'register-now-rhc' && ( + + Connect to Red Hat Insights +
+
+ ))} + {registrationType === 'register-now-rhc' && ( Use remote host configuration (rhc) utility
@@ -535,12 +519,12 @@ export const RegisterNowList = () => { If using an activation key with command line registration, you must provide your organization's ID. Your organization's ID is{' '} - {getState()?.values?.['subscription-organization-id'] !== + {/* {getState()?.values?.['subscription-organization-id'] !== undefined ? ( getState()?.values?.['subscription-organization-id'] ) : ( - )} + )}*/}
} @@ -577,14 +561,15 @@ export const RegisterNowList = () => { }; export const ImageDetailsList = () => { - const { getState } = useFormApi(); - const imageName = getState()?.values?.['image-name']; - const imageDescription = getState()?.values?.['image-description']; + const blueprintName = useAppSelector((state) => selectBlueprintName(state)); + const blueprintDescription = useAppSelector((state) => + selectBlueprintDescription(state) + ); return ( - {imageName && ( + {blueprintName && ( <> { Image name - {imageName} + {blueprintName} )} - {imageDescription && ( + {blueprintDescription && ( <> { Description - {imageDescription} + {blueprintDescription} )} @@ -617,13 +602,18 @@ export const ImageDetailsList = () => { }; export const OscapList = () => { - const { getState } = useFormApi(); - const oscapProfile = getState()?.values?.['oscap-profile']; - const { data } = useGetOscapCustomizationsQuery({ - distribution: getState()?.values?.['release'], - profile: oscapProfile, - }); - + const oscapProfile = useAppSelector((state) => selectProfile(state)); + const release = useAppSelector((state) => selectDistribution(state)); + const { data } = useGetOscapCustomizationsQuery( + { + distribution: release, + // @ts-ignore if oscapProfile is undefined the query is going to get skipped, so it's safe here to ignore the linter here + profile: oscapProfile, + }, + { + skip: !oscapProfile, + } + ); return ( diff --git a/src/Components/CreateImageWizardV2/steps/Review/index.tsx b/src/Components/CreateImageWizardV2/steps/Review/index.tsx new file mode 100644 index 0000000000..aed8606ff2 --- /dev/null +++ b/src/Components/CreateImageWizardV2/steps/Review/index.tsx @@ -0,0 +1,16 @@ +import React from 'react'; + +import { Form, Title } from '@patternfly/react-core'; + +import Review from './ReviewStep'; + +const ReviewsStep = () => { + return ( +
+ Review + + + ); +}; + +export default ReviewsStep; diff --git a/src/store/helpers.ts b/src/store/helpers.ts index 5f3c996c3a..4b72380b86 100644 --- a/src/store/helpers.ts +++ b/src/store/helpers.ts @@ -1,4 +1,5 @@ import type { V1ListSourceResponse } from './provisioningApi'; -export const extractProvisioningList = (list: V1ListSourceResponse) => - list?.data; +export const extractProvisioningList = ( + list: V1ListSourceResponse | undefined +) => list?.data;