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'}
);
};