Wizard: Drop the WizardV1

This commit is contained in:
Ondrej Ezr 2024-06-12 15:04:19 +02:00 committed by Klara Simickova
parent 54d09d636e
commit 5fcc80d2db
75 changed files with 103 additions and 11588 deletions

View file

@ -1,189 +0,0 @@
import React from 'react';
import componentTypes from '@data-driven-forms/react-form-renderer/component-types';
import validatorTypes from '@data-driven-forms/react-form-renderer/validator-types';
import {
Button,
HelperText,
HelperTextItem,
Title,
} from '@patternfly/react-core';
import { ExternalLinkAltIcon } from '@patternfly/react-icons';
import nextStepMapper from './imageOutputStepMapper';
import StepTemplate from './stepTemplate';
import { DEFAULT_AWS_REGION } from '../../../constants';
import CustomButtons from '../formComponents/CustomButtons';
const SourcesButton = () => {
return (
<Button
component="a"
target="_blank"
variant="link"
icon={<ExternalLinkAltIcon />}
iconPosition="right"
isInline
href={'settings/sources'}
>
Create and manage sources here
</Button>
);
};
const awsStep = {
StepTemplate,
id: 'wizard-target-aws',
title: 'Amazon Web Services',
customTitle: (
<Title headingLevel="h1" size="xl">
Target environment - Amazon Web Services
</Title>
),
name: 'aws-target-env',
substepOf: 'Target environment',
nextStep: ({ values }) => nextStepMapper(values, { skipAws: true }),
buttons: CustomButtons,
fields: [
{
component: componentTypes.PLAIN_TEXT,
name: 'plain-text-component',
label: (
<p>
Your image will be uploaded to AWS and shared with the account you
provide below.
</p>
),
},
{
component: componentTypes.PLAIN_TEXT,
name: 'plain-text-component',
label: (
<p>
<b>The shared image will expire within 14 days.</b> To permanently
access the image, copy the image, which will be shared to your account
by Red Hat, to your own AWS account.
</p>
),
},
{
component: componentTypes.RADIO,
label: 'Share method:',
name: 'aws-target-type',
initialValue: 'aws-target-type-source',
autoFocus: true,
options: [
{
label: 'Use an account configured from Sources.',
description:
'Use a configured source to launch environments directly from the console.',
value: 'aws-target-type-source',
'data-testid': 'aws-radio-source',
autoFocus: true,
},
{
label: 'Manually enter an account ID.',
value: 'aws-target-type-account-id',
'data-testid': 'aws-radio-account-id',
className: 'pf-u-mt-sm',
},
],
},
{
component: 'aws-sources-select',
name: 'aws-sources-select',
className: 'pf-u-max-width',
label: 'Source Name',
isRequired: true,
validate: [
{
type: validatorTypes.REQUIRED,
},
],
condition: {
when: 'aws-target-type',
is: 'aws-target-type-source',
},
},
{
component: componentTypes.PLAIN_TEXT,
name: 'aws-sources-select-description',
label: <SourcesButton />,
condition: {
when: 'aws-target-type',
is: 'aws-target-type-source',
},
},
{
component: componentTypes.TEXT_FIELD,
name: 'aws-account-id',
className: 'pf-u-w-25',
'data-testid': 'aws-account-id',
type: 'text',
label: 'AWS account ID',
isRequired: true,
validate: [
{
type: validatorTypes.REQUIRED,
},
{
type: validatorTypes.EXACT_LENGTH,
threshold: 12,
},
],
condition: {
when: 'aws-target-type',
is: 'aws-target-type-account-id',
},
},
{
name: 'gallery-layout',
component: 'gallery-layout',
minWidths: { default: '12.5rem' },
maxWidths: { default: '12.5rem' },
fields: [
{
component: componentTypes.TEXT_FIELD,
name: 'aws-default-region',
value: DEFAULT_AWS_REGION,
'data-testid': 'aws-default-region',
type: 'text',
label: 'Default Region',
isReadOnly: true,
isRequired: true,
helperText: (
<HelperText>
<HelperTextItem component="div" variant="indeterminate">
Images are built in the default region but can be copied to
other regions later.
</HelperTextItem>
</HelperText>
),
},
{
component: componentTypes.TEXT_FIELD,
name: 'aws-associated-account-id',
'data-testid': 'aws-associated-account-id',
type: 'text',
label: 'Associated Account ID',
isReadOnly: true,
isRequired: true,
helperText: (
<HelperText>
<HelperTextItem component="div" variant="indeterminate">
This is the account associated with the source.
</HelperTextItem>
</HelperText>
),
condition: {
when: 'aws-target-type',
is: 'aws-target-type-source',
},
},
],
},
],
};
export default awsStep;

View file

@ -1,136 +0,0 @@
import React from 'react';
import componentTypes from '@data-driven-forms/react-form-renderer/component-types';
import validatorTypes from '@data-driven-forms/react-form-renderer/validator-types';
import {
Button,
Label,
Text,
TextContent,
TextVariants,
} from '@patternfly/react-core';
import { ExternalLinkAltIcon } from '@patternfly/react-icons';
import StepTemplate from './stepTemplate';
import { FILE_SYSTEM_CUSTOMIZATION_URL } from '../../../constants';
import FileSystemConfigButtons from '../formComponents/FileSystemConfigButtons';
export const reinitFileSystemConfiguratioStep = (change) => {
change('file-system-configuration', undefined);
change('file-system-config-radio', 'automatic');
};
const fileSystemConfigurationStep = {
StepTemplate,
id: 'wizard-systemconfiguration-filesystem',
title: 'File system configuration',
name: 'File system configuration',
buttons: FileSystemConfigButtons,
nextStep: 'packages',
fields: [
{
component: componentTypes.PLAIN_TEXT,
name: 'file-system-configuration-text-component',
label: (
<>
<Text>Define the partitioning of the image</Text>
</>
),
},
{
component: componentTypes.RADIO,
name: 'file-system-config-radio',
initialValue: 'automatic',
options: [
{
label: (
<>
<Text>
<Label isCompact color="blue">
Recommended
</Label>{' '}
Use automatic partitioning
</Text>
</>
),
description:
'Automatically partition your image to what is best, depending on the target environment(s)',
value: 'automatic',
'data-testid': 'file-system-config-radio-automatic',
autoFocus: true,
},
{
label: 'Manually configure partitions',
description:
'Manually configure the file system of your image by adding, removing, and editing partitions',
value: 'manual',
'data-testid': 'file-system-config-radio-manual',
className: 'pf-u-mt-sm',
},
],
condition: {
when: 'oscap-profile',
is: undefined,
},
},
{
component: 'file-system-configuration',
name: 'file-system-configuration',
label: 'File system configurations',
validate: [
{ type: 'fileSystemConfigurationValidator' },
{ type: validatorTypes.REQUIRED },
],
condition: {
or: [
{
when: 'file-system-config-radio',
is: 'manual',
},
{ not: [{ when: 'oscap-profile', is: undefined }] },
],
},
},
{
component: componentTypes.PLAIN_TEXT,
name: 'automatic-partitioning-info',
label: (
<TextContent>
<Text component={TextVariants.h3}>Automatic partitioning</Text>
<Text>
Red Hat will automatically partition your image to what is best,
depending on the target environment(s).
</Text>
<Text>
The target environment sometimes dictates the partitioning scheme or
parts of it, and sometimes the target environment is unknown (e.g.,
for the .qcow2 generic cloud image).
</Text>
<Text>
Using automatic partitioning will apply the most current supported
configuration.
<br></br>
<Button
component="a"
target="_blank"
variant="link"
icon={<ExternalLinkAltIcon />}
iconPosition="right"
href={FILE_SYSTEM_CUSTOMIZATION_URL}
className="pf-u-pl-0"
>
Customizing file systems during the image creation
</Button>
</Text>
</TextContent>
),
condition: {
when: 'file-system-config-radio',
is: 'automatic',
},
},
],
};
export default fileSystemConfigurationStep;

View file

@ -1,225 +0,0 @@
import React from 'react';
import componentTypes from '@data-driven-forms/react-form-renderer/component-types';
import validatorTypes from '@data-driven-forms/react-form-renderer/validator-types';
import {
Button,
Popover,
Text,
TextContent,
TextList,
TextListItem,
Title,
} from '@patternfly/react-core';
import { HelpIcon } from '@patternfly/react-icons';
import PropTypes from 'prop-types';
import nextStepMapper from './imageOutputStepMapper';
import StepTemplate from './stepTemplate';
import CustomButtons from '../formComponents/CustomButtons';
export const googleAccType = {
googleAccount: 'Google account',
serviceAccount: 'Service account',
googleGroup: 'Google group',
domain: 'Domain',
};
const PopoverInfo = ({ appendTo }) => {
return (
<Popover
appendTo={appendTo}
hasAutoWidth
maxWidth="35rem"
headerContent={'Valid account types'}
flipBehavior={['right', 'bottom', 'top', 'left']}
bodyContent={
<TextContent>
<Text>
The following account types can have an image shared with them:
</Text>
<TextList className="pf-u-ml-0">
<TextListItem>
<strong>Google account:</strong> A Google account represents a
developer, an administrator, or any other person who interacts
with Google Cloud. For example: <em>`alice@gmail.com`</em>.
</TextListItem>
<TextListItem>
<strong>Service account:</strong> A service account is an account
for an application instead of an individual end user. For example:{' '}
<em>`myapp@appspot.gserviceaccount.com`</em>.
</TextListItem>
<TextListItem>
<strong>Google group:</strong> A Google group is a named
collection of Google accounts and service accounts. For example:{' '}
<em>`admins@example.com`</em>.
</TextListItem>
<TextListItem>
<strong>Google Workspace domain or Cloud Identity domain:</strong>{' '}
A Google workspace or cloud identity domain represents a virtual
group of all the Google accounts in an organization. These domains
represent your organization&apos;s internet domain name. For
example: <em>`mycompany.com`</em>.
</TextListItem>
</TextList>
</TextContent>
}
>
<Button
variant="plain"
aria-label="Account info"
aria-describedby="google-account-type"
className="pf-c-form__group-label-help"
>
<HelpIcon />
</Button>
</Popover>
);
};
PopoverInfo.propTypes = {
appendTo: PropTypes.any,
};
const googleCloudStep = {
StepTemplate,
id: 'wizard-target-gcp',
title: 'Google Cloud Platform',
customTitle: (
<Title headingLevel="h1" size="xl">
Target environment - Google Cloud Platform
</Title>
),
name: 'google-cloud-target-env',
substepOf: 'Target environment',
nextStep: ({ values }) =>
nextStepMapper(values, { skipGoogle: true, skipAws: true }),
buttons: CustomButtons,
fields: [
{
component: componentTypes.PLAIN_TEXT,
name: 'google-cloud-text-component',
label: (
<p>
Select how to share your image. The image you create can be used to
launch instances on GCP, regardless of which method you select.
</p>
),
},
{
component: componentTypes.RADIO,
label: 'Select image sharing',
isRequired: true,
name: 'image-sharing',
initialValue: 'gcp-account',
autoFocus: true,
options: [
{
label: 'Share image with a Google account',
'data-testid': 'account-sharing',
autoFocus: true,
description: (
<p>
Your image will be uploaded to GCP and shared with the account you
provide below.
<b>The image expires in 14 days.</b> To keep permanent access to
your image, copy it to your GCP project.
</p>
),
value: 'gcp-account',
},
{
label: 'Share image with Red Hat Insights only',
'data-testid': 'insights-only-sharing',
description: (
<p>
Your image will be uploaded to GCP and shared with Red Hat
Insights.
<b> The image expires in 14 days.</b> You cannot access or
recreate this image in your GCP project.
</p>
),
value: 'insights',
autoFocus: true,
},
],
},
{
component: 'radio-popover',
label: 'Account type',
isRequired: true,
Popover: PopoverInfo,
name: 'google-account-type',
initialValue: 'googleAccount',
options: Object.entries(googleAccType).map(([value, label]) => ({
label:
value === 'domain'
? 'Google Workspace domain or Cloud Identity domain'
: label,
value,
autoFocus: value === 'googleAccount' ? true : false,
})),
validate: [
{
type: validatorTypes.REQUIRED,
},
],
condition: {
when: 'image-sharing',
is: 'gcp-account',
},
},
{
component: componentTypes.TEXT_FIELD,
name: 'google-email',
'data-testid': 'input-google-email',
type: 'text',
label: 'Principal (e.g. e-mail address)',
condition: {
and: [
{ when: 'image-sharing', is: 'gcp-account' },
{
or: [
{ when: 'google-account-type', is: 'googleAccount' },
{ when: 'google-account-type', is: 'serviceAccount' },
{ when: 'google-account-type', is: 'googleGroup' },
{ when: 'google-account-type', is: null },
],
},
],
},
isRequired: true,
validate: [
{
type: validatorTypes.REQUIRED,
},
{
type: validatorTypes.PATTERN,
pattern: '^[a-z0-9._%+-]+@[a-z0-9.-]+.[a-z]{2,}$',
message: 'Please enter a valid email address',
},
],
},
{
component: componentTypes.TEXT_FIELD,
name: 'google-domain',
type: 'text',
label: 'Domain',
condition: {
and: [
{ when: 'image-sharing', is: 'gcp-account' },
{ when: 'google-account-type', is: 'domain' },
],
},
isRequired: true,
validate: [
{
type: validatorTypes.REQUIRED,
},
],
},
],
};
export default googleCloudStep;

View file

@ -1,75 +0,0 @@
import React from 'react';
import { useFormApi } from '@data-driven-forms/react-form-renderer';
import componentTypes from '@data-driven-forms/react-form-renderer/component-types';
import validatorTypes from '@data-driven-forms/react-form-renderer/validator-types';
import { Flex, FlexItem, Text } from '@patternfly/react-core';
import StepTemplate from './stepTemplate';
import CustomButtons from '../formComponents/CustomButtons';
const CharacterCount = () => {
const { getState } = useFormApi();
const description = getState().values?.['image-description'];
return <h1>{description?.length || 0}/250</h1>;
};
const imageNameStep = {
StepTemplate,
id: 'wizard-details',
name: 'details',
title: 'Details',
nextStep: 'review',
buttons: CustomButtons,
fields: [
{
component: componentTypes.PLAIN_TEXT,
name: 'plain-text-component',
label: (
<p>
Optionally enter a name to identify your image later quickly. If you
do not provide one, the UUID will be used as the name.
</p>
),
},
{
component: componentTypes.TEXT_FIELD,
name: 'image-name',
type: 'text',
label: 'Image Name',
placeholder: 'Image Name',
helperText:
'The image name can be 3-63 characters long. It can contain lowercase letters, digits and hyphens, has to start with a letter and cannot end with a hyphen.',
autoFocus: true,
validate: [
{
type: validatorTypes.PATTERN,
pattern: /^[a-z][-a-z0-9]{1,61}[a-z0-9]$/,
message:
'The image name can be 3-63 characters long. It can contain lowercase letters, digits and hyphens, has to start with a letter and cannot end with a hyphen.',
},
],
},
{
component: componentTypes.TEXTAREA,
name: 'image-description',
type: 'text',
label: (
<Flex justifyContent={{ default: 'justifyContentSpaceBetween' }}>
<FlexItem>
<Text component={'b'}>Description</Text>
</FlexItem>
<FlexItem>
<CharacterCount />
</FlexItem>
</Flex>
),
placeholder: 'Add Description',
resizeOrientation: 'vertical',
validate: [{ type: validatorTypes.MAX_LENGTH, threshold: 250 }],
},
],
};
export default imageNameStep;

View file

@ -1,90 +0,0 @@
import React from 'react';
import componentTypes from '@data-driven-forms/react-form-renderer/component-types';
import validatorTypes from '@data-driven-forms/react-form-renderer/validator-types';
import { Text } from '@patternfly/react-core';
import nextStepMapper from './imageOutputStepMapper';
import StepTemplate from './stepTemplate';
import { RHEL_9, X86_64 } from '../../../constants';
import DocumentationButton from '../../sharedComponents/DocumentationButton';
import CustomButtons from '../formComponents/CustomButtons';
const imageOutputStep = {
StepTemplate,
id: 'wizard-imageoutput',
title: 'Image output',
name: 'image-output',
nextStep: ({ values }) => nextStepMapper(values),
buttons: CustomButtons,
fields: [
{
component: componentTypes.PLAIN_TEXT,
name: 'image-output-plain-text',
label: (
<Text>
Image builder allows you to create a custom image and push it to
target environments.
<br />
<DocumentationButton />
</Text>
),
},
{
component: 'image-output-release-select',
label: 'Release',
name: 'release',
initialValue: RHEL_9,
isRequired: true,
validate: [
{
type: validatorTypes.REQUIRED,
},
],
},
{
component: 'image-output-release-lifecycle',
label: 'Release lifecycle',
name: 'release-lifecycle',
},
{
component: 'image-output-arch-select',
label: 'Architecture',
name: 'arch',
initialValue: X86_64,
isRequired: true,
validate: [
{
type: validatorTypes.REQUIRED,
},
],
},
{
component: 'centos-acknowledgement',
name: 'centos-acknowledgement',
condition: {
when: 'release',
pattern: /centos-*/,
then: { set: { 'register-system': null } },
else: { visible: false },
},
},
{
component: 'output',
name: 'target-environment',
label: 'Select target environments',
isRequired: true,
validate: [
{
type: validatorTypes.REQUIRED,
},
{
type: 'targetEnvironmentValidator',
},
],
},
],
};
export default imageOutputStep;

View file

@ -1,28 +0,0 @@
import isRhel from '../../../Utilities/isRhel';
const imageOutputStepMapper = (
{ 'target-environment': targetEnv, release, enableOscap } = {},
{ skipAws, skipGoogle, skipAzure } = {}
) => {
if (!skipAws && targetEnv?.aws) {
return 'aws-target-env';
}
if (!skipGoogle && targetEnv?.gcp) {
return 'google-cloud-target-env';
}
if (!skipAzure && targetEnv?.azure) {
return 'ms-azure-target-env';
}
if (isRhel(release)) {
return 'registration';
}
if (enableOscap) {
return 'Compliance';
}
return 'File system configuration';
};
export default imageOutputStepMapper;

View file

@ -1,13 +0,0 @@
export { default as awsTarget } from './aws';
export { default as googleCloudTarget } from './googleCloud';
export { default as msAzureTarget } from './msAzure';
export { default as oscap } from './oscap';
export { default as packages } from './packages';
export { default as packagesContentSources } from './packagesContentSources';
export { default as registration } from './registration';
export { default as repositories } from './repositories';
export { default as review } from './review';
export { default as imageOutput } from './imageOutput';
export { default as nextStepMapper } from './imageOutputStepMapper';
export { default as fileSystemConfiguration } from './fileSystemConfiguration';
export { default as imageName } from './imageName';

View file

@ -1,265 +0,0 @@
import React from 'react';
import componentTypes from '@data-driven-forms/react-form-renderer/component-types';
import validatorTypes from '@data-driven-forms/react-form-renderer/validator-types';
import { Button, Text, TextContent, Title } from '@patternfly/react-core';
import { ExternalLinkAltIcon } from '@patternfly/react-icons';
import nextStepMapper from './imageOutputStepMapper';
import StepTemplate from './stepTemplate';
import { AZURE_AUTH_URL } from '../../../constants';
import CustomButtons from '../formComponents/CustomButtons';
const SourcesButton = () => {
return (
<Button
component="a"
target="_blank"
variant="link"
icon={<ExternalLinkAltIcon />}
iconPosition="right"
isInline
href={'settings/sources'}
>
Create and manage sources here
</Button>
);
};
const msAzureStep = {
StepTemplate,
id: 'wizard-target-msazure',
title: 'Microsoft Azure',
customTitle: (
<Title headingLevel="h1" size="xl">
Target environment - Microsoft Azure
</Title>
),
name: 'ms-azure-target-env',
substepOf: 'Target environment',
nextStep: ({ values }) =>
nextStepMapper(values, {
skipAws: true,
skipGoogle: true,
skipAzure: true,
}),
buttons: CustomButtons,
fields: [
{
component: componentTypes.PLAIN_TEXT,
name: 'azure-description',
label: (
<TextContent>
<Text>
Upon build, Image Builder sends the image to the selected authorized
Azure account. The image will be uploaded to the resource group in
the subscription you specify.
</Text>
<Text>
To authorize Image Builder to push images to Microsoft Azure, the
account owner must configure Image Builder as an authorized
application for a specific tenant ID and give it the role of
&quot;Contributor&quot; for the resource group you want to upload
to. This applies even when defining target by Source selection.
<br />
<Button
component="a"
target="_blank"
variant="link"
icon={<ExternalLinkAltIcon />}
iconPosition="right"
isInline
href={AZURE_AUTH_URL}
>
Learn more about OAuth 2.0
</Button>
</Text>
</TextContent>
),
},
{
component: componentTypes.RADIO,
label: 'Share method:',
name: 'azure-type',
initialValue: 'azure-type-source',
autoFocus: true,
options: [
{
label: 'Use an account configured from Sources.',
description:
'Use a configured source to launch environments directly from the console.',
value: 'azure-type-source',
'data-testid': 'azure-radio-source',
autoFocus: true,
},
{
label: 'Manually enter the account information.',
value: 'azure-type-manual',
'data-testid': 'azure-radio-manual',
className: 'pf-u-mt-sm',
},
],
},
{
component: 'azure-sources-select',
name: 'azure-sources-select',
className: 'pf-u-max-width',
label: 'Source Name',
isRequired: true,
validate: [
{
type: validatorTypes.REQUIRED,
},
],
condition: {
when: 'azure-type',
is: 'azure-type-source',
},
},
{
component: componentTypes.PLAIN_TEXT,
name: 'azure-sources-select-description',
label: <SourcesButton />,
condition: {
when: 'azure-type',
is: 'azure-type-source',
},
},
{
name: 'gallery-layout',
component: 'gallery-layout',
minWidths: { default: '12.5rem' },
maxWidths: { default: '12.5rem' },
fields: [
{
component: componentTypes.TEXT_FIELD,
name: 'azure-tenant-id',
'data-testid': 'azure-tenant-id-source',
type: 'text',
label: 'Azure Tenant GUID',
isRequired: true,
isReadOnly: true,
},
{
component: componentTypes.TEXT_FIELD,
name: 'azure-subscription-id',
'data-testid': 'azure-subscription-id-source',
type: 'text',
label: 'Subscription ID',
isRequired: true,
isReadOnly: true,
condition: {
when: 'azure-type',
is: 'azure-type-source',
},
},
],
condition: {
when: 'azure-type',
is: 'azure-type-source',
},
},
{
component: componentTypes.TEXT_FIELD,
name: 'azure-tenant-id',
className: 'pf-u-w-50',
'data-testid': 'azure-tenant-id-manual',
type: 'text',
label: 'Azure Tenant GUID',
isRequired: true,
autoFocus: true,
validate: [
{
type: validatorTypes.REQUIRED,
},
{
type: validatorTypes.PATTERN,
pattern:
/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
message: 'Please enter a valid tenant ID',
},
],
condition: {
when: 'azure-type',
is: 'azure-type-manual',
},
},
{
component: 'azure-auth-button',
name: 'azure-auth-button',
'data-testid': 'azure-auth-button',
required: true,
isRequired: true,
},
{
component: componentTypes.TEXT_FIELD,
name: 'azure-subscription-id',
className: 'pf-u-w-50',
'data-testid': 'azure-subscription-id-manual',
type: 'text',
label: 'Subscription ID',
isRequired: true,
validate: [
{
type: validatorTypes.REQUIRED,
},
{
type: validatorTypes.PATTERN,
pattern:
/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
message: 'Please enter a valid subscription ID',
},
],
condition: {
when: 'azure-type',
is: 'azure-type-manual',
},
},
{
component: 'azure-resource-groups',
name: 'azure-resource-group',
className: 'pf-u-max-width',
'data-testid': 'azure-resource-group-select',
label: 'Resource group',
isRequired: true,
validate: [
{
type: validatorTypes.REQUIRED,
},
],
condition: {
when: 'azure-type',
is: 'azure-type-source',
},
},
{
component: componentTypes.TEXT_FIELD,
name: 'azure-resource-group',
className: 'pf-u-w-50',
'data-testid': 'azure-resource-group-manual',
type: 'text',
label: 'Resource group',
isRequired: true,
validate: [
{
type: validatorTypes.REQUIRED,
},
{
type: validatorTypes.PATTERN,
pattern: /^[-\w._()]+[-\w_()]$/,
message:
'Resource group names only allow alphanumeric characters, ' +
'periods, underscores, hyphens, and parenthesis and cannot end in a period',
},
],
condition: {
when: 'azure-type',
is: 'azure-type-manual',
},
},
// TODO check oauth2 thing too here?
],
};
export default msAzureStep;

View file

@ -1,42 +0,0 @@
import React from 'react';
import componentTypes from '@data-driven-forms/react-form-renderer/component-types';
import { Text, Title } from '@patternfly/react-core';
import StepTemplate from './stepTemplate';
import DocumentationButton from '../../sharedComponents/DocumentationButton';
import CustomButtons from '../formComponents/CustomButtons';
const oscapStep = {
StepTemplate,
id: 'wizard-systemconfiguration-oscap',
title: 'OpenSCAP',
name: 'Compliance',
customTitle: (
<Title headingLevel="h1" size="xl">
OpenSCAP profile
</Title>
),
nextStep: 'File system configuration',
buttons: CustomButtons,
fields: [
{
component: componentTypes.PLAIN_TEXT,
name: 'oscap-text-component',
label: (
<Text>
Use OpenSCAP to monitor the adherence of your registered RHEL systems
to a selected regulatory compliance profile. <DocumentationButton />
</Text>
),
},
{
component: 'oscap-profile-selector',
name: 'oscap-profile',
label: 'Available profiles for the distribution',
},
],
};
export default oscapStep;

View file

@ -1,46 +0,0 @@
import React from 'react';
import componentTypes from '@data-driven-forms/react-form-renderer/component-types';
import { Text } from '@patternfly/react-core';
import StepTemplate from './stepTemplate';
import CustomButtons from '../formComponents/CustomButtons';
export const reinitPackagesStep = (change) => {
change('selected-packages', undefined);
};
const packagesStep = {
StepTemplate,
id: 'wizard-systemconfiguration-packages',
title: 'Additional Red Hat packages',
name: 'packages',
substepOf: 'Content',
nextStep: ({ values }) => {
if (values.contentSourcesEnabled) {
return 'repositories';
} else {
return 'details';
}
},
buttons: CustomButtons,
fields: [
{
component: componentTypes.PLAIN_TEXT,
name: 'packages-text-component',
label: (
<Text>
Images built with Image Builder include all required packages.
</Text>
),
},
{
component: 'package-selector',
name: 'selected-packages',
label: 'Available options',
},
],
};
export default packagesStep;

View file

@ -1,37 +0,0 @@
import React from 'react';
import componentTypes from '@data-driven-forms/react-form-renderer/component-types';
import { Text } from '@patternfly/react-core';
import StepTemplate from './stepTemplate';
import CustomButtons from '../formComponents/CustomButtons';
const packagesContentSourcesStep = {
StepTemplate,
id: 'wizard-systemconfiguration-content-sources-packages',
title: 'Additional custom packages',
name: 'packages-content-sources',
substepOf: 'Content',
nextStep: 'details',
buttons: CustomButtons,
fields: [
{
component: componentTypes.PLAIN_TEXT,
name: 'packages-text-component',
label: (
<Text>
The available packages will return results from all repositories
chosen on the previous page.
</Text>
),
},
{
component: 'package-selector-content-sources',
name: 'selected-packages-content-sources',
label: 'Available options',
},
],
};
export default packagesContentSourcesStep;

View file

@ -1,206 +0,0 @@
import React, { useEffect, useState } from 'react';
import componentTypes from '@data-driven-forms/react-form-renderer/component-types';
import validatorTypes from '@data-driven-forms/react-form-renderer/validator-types';
import {
Button,
Popover,
Text,
TextContent,
TextVariants,
Title,
} from '@patternfly/react-core';
import { ExternalLinkAltIcon, HelpIcon } from '@patternfly/react-icons';
import { useChrome } from '@redhat-cloud-services/frontend-components/useChrome';
import StepTemplate from './stepTemplate';
import {
ACTIVATION_KEYS_PROD_URL,
ACTIVATION_KEYS_STAGE_URL,
RHC_URL,
} from '../../../constants';
import { useGetEnvironment } from '../../../Utilities/useGetEnvironment';
import CustomButtons from '../formComponents/CustomButtons';
const ManageKeysButton = () => {
const { isProd } = useGetEnvironment();
return (
<Button
component="a"
target="_blank"
variant="link"
icon={<ExternalLinkAltIcon />}
iconPosition="right"
isInline
href={isProd() ? ACTIVATION_KEYS_PROD_URL : ACTIVATION_KEYS_STAGE_URL}
>
Activation keys page
</Button>
);
};
const PopoverActivation = () => {
const [orgId, setOrgId] = useState(null);
const { auth } = useChrome();
useEffect(() => {
(async () => {
const userData = await auth?.getUser();
const id = userData?.identity?.internal?.org_id;
setOrgId(id);
})();
});
return (
<Popover
hasAutoWidth
maxWidth="35rem"
bodyContent={
<TextContent>
<Text>
Activation keys enable you to register a system with appropriate
subscriptions, system purpose, and repositories attached.
</Text>
<Text>
If using an activation key with command line registration, you must
provide your organization&apos;s ID.
{orgId && <br />}
{orgId && "Your organization's ID is " + orgId}
</Text>
</TextContent>
}
>
<Button
variant="plain"
aria-label="Activation key popover"
aria-describedby="subscription-activation-key"
className="pf-c-form__group-label-help"
>
<HelpIcon />
</Button>
</Popover>
);
};
const registrationStep = {
StepTemplate,
id: 'wizard-registration',
title: 'Register',
customTitle: (
<Title headingLevel="h1" size="xl">
Register systems using this image
</Title>
),
name: 'registration',
nextStep: ({ values }) => {
if (values.enableOscap) {
return 'Compliance';
} else {
return 'File system configuration';
}
},
buttons: CustomButtons,
fields: [
{
component: componentTypes.PLAIN_TEXT,
name: 'registration-general-description',
label:
'Automatically register your systems with Red Hat to enhance security and track your spending.',
},
{
name: 'register-system',
component: 'registration',
label: 'Registration method',
initialValue: 'register-now-rhc',
},
{
component: 'activation-keys',
name: 'subscription-activation-key',
required: true,
label: (
<>
Activation key to use for this image
<PopoverActivation />
</>
),
condition: {
or: [
{ when: 'register-system', is: 'register-now-rhc' },
{ when: 'register-system', is: 'register-now-insights' },
{ when: 'register-system', is: 'register-now' },
],
},
isRequired: true,
validate: [
{
type: validatorTypes.REQUIRED,
},
],
},
{
component: componentTypes.PLAIN_TEXT,
name: 'subscription-activation-description',
label: (
<span>
By default, activation key is generated and preset for you. Admins can
create and manage keys by visiting the&nbsp;
<ManageKeysButton />
</span>
),
condition: {
or: [
{ when: 'register-system', is: 'register-now-rhc' },
{ when: 'register-system', is: 'register-now-insights' },
{ when: 'register-system', is: 'register-now' },
],
},
},
{
component: componentTypes.PLAIN_TEXT,
name: 'subscription-register-later',
label: (
<TextContent>
<Text component={TextVariants.h3}>Register Later</Text>
<Text>
On initial boot, systems will need to be registered manually before
having access to updates or Red Hat services. Registering and
connecting your systems during the image creation is recommended.
</Text>
<Text>
If you prefer to register later, review the instructions for manual
registration with remote host configuration.
</Text>
<Button
component="a"
target="_blank"
variant="link"
icon={<ExternalLinkAltIcon />}
iconPosition="right"
isInline
href={RHC_URL}
>
Registering with remote host configuration
</Button>
</TextContent>
),
condition: {
or: [{ when: 'register-system', is: 'register-later' }],
},
},
{
component: 'activation-key-information',
name: 'subscription-activation-key-information',
label: 'Selected activation key',
valueReference: 'subscription-activation-key',
condition: {
or: [
{ when: 'register-system', is: 'register-now-rhc' },
{ when: 'register-system', is: 'register-now-insights' },
{ when: 'register-system', is: 'register-now' },
],
},
},
],
};
export default registrationStep;

View file

@ -1,59 +0,0 @@
import React from 'react';
import componentTypes from '@data-driven-forms/react-form-renderer/component-types';
import { Button, Text } from '@patternfly/react-core';
import { ExternalLinkAltIcon } from '@patternfly/react-icons';
import nextStepMapper from './repositoriesStepMapper';
import StepTemplate from './stepTemplate';
import { useGetEnvironment } from '../../../Utilities/useGetEnvironment';
import CustomButtons from '../formComponents/CustomButtons';
const VisitButton = () => {
const { isBeta } = useGetEnvironment();
return (
<Button
component="a"
target="_blank"
variant="link"
iconPosition="right"
isInline
icon={<ExternalLinkAltIcon />}
href={isBeta() ? '/preview/settings/content' : '/settings/content'}
>
Create and manage repositories here
</Button>
);
};
const repositoriesStep = {
StepTemplate,
id: 'wizard-repositories',
title: 'Custom repositories',
name: 'repositories',
substepOf: 'Content',
nextStep: ({ values }) => nextStepMapper(values),
buttons: CustomButtons,
fields: [
{
component: componentTypes.PLAIN_TEXT,
name: 'packages-text-component',
label: (
<Text>
Select from linked custom repositories from which to search and add
packages to this image.
<br />
<VisitButton />
</Text>
),
},
{
component: 'repositories-table',
name: 'payload-repositories',
label: 'Custom repositories',
},
],
};
export default repositoriesStep;

View file

@ -1,11 +0,0 @@
const repositoriesStepMapper = ({
'payload-repositories': customRepositories,
} = {}) => {
if (customRepositories?.length > 0) {
return 'packages-content-sources';
}
return 'details';
};
export default repositoriesStepMapper;

View file

@ -1,19 +0,0 @@
import StepTemplate from './stepTemplate';
import CustomButtons from '../formComponents/CustomButtons';
const reviewStep = {
StepTemplate,
id: 'wizard-review',
name: 'review',
title: 'Review',
buttons: CustomButtons,
fields: [
{
name: 'review',
component: 'review',
},
],
};
export default reviewStep;

View file

@ -1,44 +0,0 @@
import React from 'react';
import { Title } from '@patternfly/react-core';
import PropTypes from 'prop-types';
const StepTemplate = ({
id,
formFields,
formRef,
title,
customTitle,
showTitle,
showTitles,
}) => (
<div id={id} ref={formRef} className="pf-c-form">
{((showTitles && showTitle !== false) || showTitle) &&
(customTitle ? (
customTitle
) : (
<Title headingLevel="h1" size="xl">
{title}
</Title>
))}
{formFields}
</div>
);
StepTemplate.propTypes = {
id: PropTypes.string,
title: PropTypes.node,
customTitle: PropTypes.node,
formFields: PropTypes.array.isRequired,
formOptions: PropTypes.shape({
renderForm: PropTypes.func.isRequired,
}).isRequired,
showTitles: PropTypes.bool,
showTitle: PropTypes.bool,
formRef: PropTypes.oneOfType([
PropTypes.func,
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
]),
};
export default StepTemplate;