Wizard: add region selector for on-prem AWS

We need to be able to select the region for AWS targets in the frontend
image builder. This commit adds the field to the wizard, but doesn't
wire this up to the api call just yet.
This commit is contained in:
Gianluca Zuccarelli 2025-07-01 16:19:09 +01:00 committed by Klara Simickova
parent fe5abaeb45
commit 4339420cb8
3 changed files with 132 additions and 54 deletions

View file

@ -404,9 +404,13 @@ const CreateImageWizard = ({ isEdit }: CreateImageWizardProps) => {
footer={
<CustomWizardFooter
disableNext={
awsShareMethod === 'manual'
? !isAwsAccountIdValid(awsAccountId)
: awsSourceId === undefined
// we don't need the account id for
// on-prem aws.
process.env.IS_ON_PREMISE
? false
: awsShareMethod === 'manual'
? !isAwsAccountIdValid(awsAccountId)
: awsSourceId === undefined
}
/>
}

View file

@ -44,6 +44,7 @@ import {
selectActivationKey,
selectArchitecture,
selectAwsAccountId,
selectAwsRegion,
selectAwsShareMethod,
selectAwsSourceId,
selectAzureResourceGroup,
@ -225,6 +226,7 @@ export const TargetEnvAWSList = () => {
const awsAccountId = useAppSelector(selectAwsAccountId);
const awsShareMethod = useAppSelector(selectAwsShareMethod);
const sourceId = useAppSelector(selectAwsSourceId);
const region = useAppSelector(selectAwsRegion);
const { source } = useGetSourceListQuery(
{
provider: 'aws',
@ -261,7 +263,9 @@ export const TargetEnvAWSList = () => {
<Content component={ContentVariants.dt} className="pf-v6-u-min-width">
Default region
</Content>
<Content component={ContentVariants.dd}>us-east-1</Content>
<Content component={ContentVariants.dd}>
{region || 'us-east-1'}
</Content>
</Content>
</Content>
);

View file

@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import {
Button,
@ -9,7 +9,11 @@ import {
GalleryItem,
HelperText,
HelperTextItem,
MenuToggle,
MenuToggleElement,
Radio,
Select,
SelectOption,
TextInput,
Title,
} from '@patternfly/react-core';
@ -18,12 +22,15 @@ import { ExternalLinkAltIcon } from '@patternfly/react-icons';
import { AwsAccountId } from './AwsAccountId';
import { AwsSourcesSelect } from './AwsSourcesSelect';
import { AWS_REGIONS } from '../../../../../constants';
import { useAppDispatch, useAppSelector } from '../../../../../store/hooks';
import {
changeAwsAccountId,
changeAwsRegion,
changeAwsShareMethod,
changeAwsSourceId,
selectAwsAccountId,
selectAwsRegion,
selectAwsShareMethod,
} from '../../../../../store/wizardSlice';
import { ValidatedInput } from '../../../ValidatedInput';
@ -47,11 +54,60 @@ const SourcesButton = () => {
);
};
type FormGroupProps<T> = {
value: string;
onChange: (value: T) => void;
};
const AWSRegion = ({ value, onChange }: FormGroupProps<string>) => {
const [isOpen, setIsOpen] = useState(false);
const onSelect = (
_event: React.MouseEvent<Element, MouseEvent> | undefined,
value: string | number | undefined,
) => {
onChange(value as string);
setIsOpen(false);
};
const toggle = (toggleRef: React.Ref<MenuToggleElement>) => (
<MenuToggle
ref={toggleRef}
onClick={() => setIsOpen(!isOpen)}
isExpanded={isOpen}
style={
{
width: '100%',
} as React.CSSProperties
}
>
{value}
</MenuToggle>
);
return (
<Select
isOpen={isOpen}
selected={value}
onSelect={onSelect}
onOpenChange={() => setIsOpen(!isOpen)}
toggle={toggle}
>
{AWS_REGIONS.map(({ description, value: region }) => (
<SelectOption key={description} value={region}>
{region}
</SelectOption>
))}
</Select>
);
};
const Aws = () => {
const dispatch = useAppDispatch();
const shareMethod = useAppSelector(selectAwsShareMethod);
const shareWithAccount = useAppSelector(selectAwsAccountId);
const region = useAppSelector(selectAwsRegion);
return (
<Form>
@ -62,40 +118,42 @@ const Aws = () => {
Your image will be uploaded to AWS and shared with the account you
provide below.
</Content>
<Content>
<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.
</Content>
<FormGroup label="Share method:">
{!process.env.IS_ON_PREMISE && (
<Radio
id="radio-with-description"
label="Use an account configured from Sources."
name="radio-7"
description="Use a configured source to launch environments directly from the console."
isChecked={shareMethod === 'sources'}
onChange={() => {
dispatch(changeAwsSourceId(undefined));
dispatch(changeAwsAccountId(''));
dispatch(changeAwsShareMethod('sources'));
}}
autoFocus
/>
)}
<Radio
id="radio"
label="Manually enter an account ID."
name="radio-8"
isChecked={shareMethod === 'manual'}
onChange={() => {
dispatch(changeAwsSourceId(undefined));
dispatch(changeAwsAccountId(''));
dispatch(changeAwsShareMethod('manual'));
}}
autoFocus={!!process.env.IS_ON_PREMISE}
/>
</FormGroup>
{!process.env.IS_ON_PREMISE && (
<>
<Content>
<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.
</Content>
<FormGroup label="Share method:">
<Radio
id="radio-with-description"
label="Use an account configured from Sources."
name="radio-7"
description="Use a configured source to launch environments directly from the console."
isChecked={shareMethod === 'sources'}
onChange={() => {
dispatch(changeAwsSourceId(undefined));
dispatch(changeAwsAccountId(''));
dispatch(changeAwsShareMethod('sources'));
}}
autoFocus
/>
<Radio
id="radio"
label="Manually enter an account ID."
name="radio-8"
isChecked={shareMethod === 'manual'}
onChange={() => {
dispatch(changeAwsSourceId(undefined));
dispatch(changeAwsAccountId(''));
dispatch(changeAwsShareMethod('manual'));
}}
autoFocus={!!process.env.IS_ON_PREMISE}
/>
</FormGroup>
</>
)}
{shareMethod === 'sources' && (
<>
<AwsSourcesSelect />
@ -125,22 +183,34 @@ const Aws = () => {
)}
{shareMethod === 'manual' && (
<>
<FormGroup label="AWS account ID" isRequired>
<ValidatedInput
ariaLabel="aws account id"
value={shareWithAccount || ''}
validator={isAwsAccountIdValid}
onChange={(_event, value) => dispatch(changeAwsAccountId(value))}
helperText="Should be 12 characters long."
/>
</FormGroup>
{!process.env.IS_ON_PREMISE && (
<FormGroup label="AWS account ID" isRequired>
<ValidatedInput
ariaLabel="aws account id"
value={shareWithAccount || ''}
validator={isAwsAccountIdValid}
onChange={(_event, value) =>
dispatch(changeAwsAccountId(value))
}
helperText="Should be 12 characters long."
/>
</FormGroup>
)}
<FormGroup label="Default region" isRequired>
<TextInput
value={'us-east-1'}
type="text"
aria-label="default region"
readOnlyVariant="default"
/>
{!process.env.IS_ON_PREMISE && (
<TextInput
value={'us-east-1'}
type="text"
aria-label="default region"
readOnlyVariant="default"
/>
)}
{process.env.IS_ON_PREMISE && (
<AWSRegion
value={region || ''}
onChange={(v) => dispatch(changeAwsRegion(v))}
/>
)}
</FormGroup>
</>
)}