import React, { useEffect, useMemo } from 'react'; import { Alert, Button, Popover, Text, TextContent, TextList, TextListItem, TextListVariants, TextListItemVariants, TextVariants, FormGroup, } from '@patternfly/react-core'; import { ExclamationTriangleIcon } from '@patternfly/react-icons'; import ActivationKeyInformation from './../Registration/ActivationKeyInformation'; import { PackagesTable, RepositoriesTable, SnapshotTable, } from './ReviewStepTables'; import { FSReviewTable } from './ReviewStepTables'; import { RELEASES, RHEL_8, RHEL_8_FULL_SUPPORT, RHEL_8_MAINTENANCE_SUPPORT, RHEL_9, targetOptions, UNIT_GIB, } from '../../../../constants'; import { useListSnapshotsByDateMutation } from '../../../../store/contentSourcesApi'; import { useAppSelector } from '../../../../store/hooks'; import { useGetSourceListQuery } from '../../../../store/provisioningApi'; import { useShowActivationKeyQuery } from '../../../../store/rhsmApi'; import { selectActivationKey, selectArchitecture, selectAwsAccountId, selectAwsShareMethod, selectAzureShareMethod, selectAzureSource, selectAzureResourceGroup, selectAzureSubscriptionId, selectAzureTenantId, selectAwsSourceId, selectBlueprintDescription, selectBlueprintName, selectCustomRepositories, selectDistribution, selectGcpAccountType, selectGcpEmail, selectGcpShareMethod, selectPackages, selectGroups, selectRegistrationType, selectFileSystemConfigurationType, selectRecommendedRepositories, selectSnapshotDate, selectUseLatest, selectPartitions, selectFirstBootScript, } from '../../../../store/wizardSlice'; import { toMonthAndYear, yyyyMMddFormat } from '../../../../Utilities/time'; import { getConversionFactor, MinimumSizePopover, Partition, } from '../FileSystem/FileSystemTable'; import { MajorReleasesLifecyclesChart } from '../ImageOutput/ReleaseLifecycle'; import OscapProfileInformation from '../Oscap/OscapProfileInformation'; import { PopoverActivation } from '../Registration/ActivationKeysList'; const ExpirationWarning = () => { return (
Expires 14 days after creation
); }; export const ImageOutputList = () => { const distribution = useAppSelector(selectDistribution); const arch = useAppSelector(selectArchitecture); return ( {distribution === RHEL_8 && ( <> {RELEASES.get(distribution)} will be supported through{' '} {toMonthAndYear(RHEL_8_FULL_SUPPORT[1])}, with optional ELS support through {toMonthAndYear(RHEL_8_MAINTENANCE_SUPPORT[1])}. Consider building an image with {RELEASES.get(RHEL_9)} to extend the support period.
)} Release {RELEASES.get(distribution)} Architecture {arch}
); }; export const FSCList = () => { const fileSystemConfigurationType = useAppSelector( selectFileSystemConfigurationType ); const partitions = useAppSelector(selectPartitions); return ( Configuration type {fileSystemConfigurationType === 'manual' ? 'Manual' : 'Automatic'} {fileSystemConfigurationType === 'manual' && ( <> {' '} } > )} {fileSystemConfigurationType === 'manual' && ( <> Image size (minimum) )} ); }; type MinSizeProps = { partitions: Partition[]; }; export const MinSize = ({ partitions }: MinSizeProps) => { let minSize = ''; if (partitions) { let size = 0; for (const partition of partitions) { size += Number(partition.min_size) * getConversionFactor(partition.unit); } size = Number((size / UNIT_GIB).toFixed(1)); if (size < 1) { minSize = `Less than 1 GiB`; } else { minSize = `${size} GiB`; } } return ( {minSize} ); }; export const TargetEnvAWSList = () => { const { isSuccess } = useGetSourceListQuery({ provider: 'aws', }); const awsAccountId = useAppSelector(selectAwsAccountId); const awsShareMethod = useAppSelector(selectAwsShareMethod); const sourceId = useAppSelector(selectAwsSourceId); const { source } = useGetSourceListQuery( { provider: 'aws', }, { selectFromResult: ({ data }) => ({ source: data?.data?.find((source) => source.id === sourceId), }), } ); return ( {targetOptions.aws} Image type Red Hat hosted image
Shared to account {awsAccountId} {awsShareMethod === 'sources' ? 'Source' : null} {isSuccess && awsShareMethod === 'sources' ? source?.name : null} Default region us-east-1
); }; export const TargetEnvGCPList = () => { const accountType = useAppSelector(selectGcpAccountType); const sharedMethod = useAppSelector(selectGcpShareMethod); const email = useAppSelector(selectGcpEmail); return ( {targetOptions.gcp} Image type Red Hat hosted image
<> {sharedMethod === 'withInsights' ? ( <> Shared with Red Hat Insights only
) : ( <> Account type {accountType === 'group' ? 'Google group' : accountType === 'serviceAccount' ? 'Service account' : accountType === 'user' ? 'Google account' : 'Domain'} {accountType === 'domain' ? 'Domain' : 'Principal'} {email || accountType} )}
); }; export const TargetEnvAzureList = () => { const { data: rawAzureSources, isSuccess: isSuccessAzureSources } = useGetSourceListQuery({ provider: 'azure' }); const shareMethod = useAppSelector(selectAzureShareMethod); const tenantId = useAppSelector(selectAzureTenantId); const azureSource = useAppSelector(selectAzureSource); const azureResourceGroup = useAppSelector(selectAzureResourceGroup); const subscriptionId = useAppSelector(selectAzureSubscriptionId); return ( {targetOptions.azure} Image type Red Hat hosted image
{shareMethod === 'sources' && isSuccessAzureSources && ( <> Azure Source { rawAzureSources.data?.find( (source) => source.id === azureSource )?.name } )} {shareMethod === 'manual' && ( <> Azure tenant ID {tenantId} Subscription ID {subscriptionId} )} Resource group {azureResourceGroup}
); }; export const TargetEnvOciList = () => { return ( {targetOptions.oci} Object Storage URL The URL for the built image will be ready to copy ); }; export const TargetEnvOtherList = () => { return ( <> Image type Built image will be available for download ); }; export const ContentList = ({ snapshottingEnabled, }: { snapshottingEnabled: boolean; }) => { const customRepositories = useAppSelector(selectCustomRepositories); const packages = useAppSelector(selectPackages); const groups = useAppSelector(selectGroups); const recommendedRepositories = useAppSelector(selectRecommendedRepositories); const snapshotDate = useAppSelector(selectSnapshotDate); const useLatest = useAppSelector(selectUseLatest); const customAndRecommendedRepositoryUUIDS = useMemo( () => [ ...customRepositories.map(({ id }) => id), ...recommendedRepositories.map(({ uuid }) => uuid), ] as string[], [customRepositories, recommendedRepositories] ); const [listSnapshotsByDate, { data, isSuccess, isLoading, isError }] = useListSnapshotsByDateMutation(); useEffect(() => { listSnapshotsByDate({ apiListSnapshotByDateRequest: { repository_uuids: customAndRecommendedRepositoryUUIDS, date: useLatest ? yyyyMMddFormat(new Date()) : snapshotDate, }, }); }, [ customAndRecommendedRepositoryUUIDS, listSnapshotsByDate, snapshotDate, useLatest, ]); const duplicatePackages = packages.filter( (item, index) => packages.indexOf(item) !== index ); const noRepositoriesSelected = customAndRecommendedRepositoryUUIDS.length === 0; const hasSnapshotDateAfter = data?.data?.some(({ is_after }) => is_after); const snapshottingText = useMemo(() => { switch (true) { case isLoading: return ''; case useLatest: return 'Use latest'; case !!snapshotDate: return `State as of ${snapshotDate}`; default: return ''; } }, [isLoading, useLatest, snapshotDate]); return ( <> {snapshottingEnabled ? ( <> Repository snapshot } > {!useLatest && !isLoading && isSuccess && hasSnapshotDateAfter ? ( ) : ( '' )} ) : ( '' )} Custom repositories {customRepositories?.length + recommendedRepositories.length > 0 ? ( } > ) : ( 0 )} Additional packages {packages?.length > 0 || groups?.length > 0 ? ( } > ) : ( 0 )} {duplicatePackages.length > 0 && ( Some of the packages added to this image belong to multiple added repositories. We can not guarantee which repository the package will come from. )} ); }; export const RegisterLaterList = () => { return ( Registration type Register the system later ); }; export const RegisterNowList = () => { const activationKey = useAppSelector(selectActivationKey); const registrationType = useAppSelector(selectRegistrationType); const { isError } = useShowActivationKeyQuery( // @ts-ignore type of 'activationKey' might not be strictly compatible with the expected type for 'name'. { name: activationKey }, { skip: !activationKey, } ); return ( <> Registration type {registrationType?.startsWith('register-now') && ( Register with Red Hat Subscription Manager (RHSM)
)} {(registrationType === 'register-now-insights' || registrationType === 'register-now-rhc') && ( Connect to Red Hat Insights
)} {registrationType === 'register-now-rhc' && ( Use remote host configuration (rhc) utility
)}
Activation key
{isError && ( Information about the activation key cannot be loaded. Please check the key was not removed and try again later. )} ); }; export const DetailsList = () => { const blueprintName = useAppSelector(selectBlueprintName); const blueprintDescription = useAppSelector(selectBlueprintDescription); return ( {blueprintName && ( <> Blueprint name {blueprintName} )} {blueprintDescription && ( <> Description {blueprintDescription} )} ); }; export const OscapList = () => { return ; }; export const FirstBootList = () => { const isFirstbootEnabled = !!useAppSelector(selectFirstBootScript); return ( First boot script {isFirstbootEnabled ? 'Enabled' : 'Disabled'} ); };