CreateImageWizard: add image name field

Add a details step where the user can enter a descriptive image name.
This name is displayed in the review step above the Release. Both these
fields are now horizontal to save vertical space.
This commit is contained in:
Jacob Kozol 2022-02-28 15:45:03 +01:00 committed by jkozol
parent 7b1f5c7e71
commit c257eec540
5 changed files with 107 additions and 24 deletions

View file

@ -19,6 +19,7 @@ import {
packages,
imageOutput,
fileSystemConfiguration,
details
} from './steps';
import {
@ -62,6 +63,7 @@ const onSave = (values) => {
if (values['target-environment']?.aws) {
let request = {
distribution: values.release,
image_name: values?.['image-name'],
image_requests: [
{
architecture: 'x86_64',
@ -97,6 +99,7 @@ const onSave = (values) => {
let request = {
distribution: values.release,
image_name: values?.['image-name'],
image_requests: [
{
architecture: 'x86_64',
@ -117,6 +120,7 @@ const onSave = (values) => {
if (values['target-environment']?.azure) {
let request = {
distribution: values.release,
image_name: values?.['image-name'],
image_requests: [
{
architecture: 'x86_64',
@ -138,6 +142,7 @@ const onSave = (values) => {
if (values['target-environment']?.vsphere) {
let request = {
distribution: values.release,
image_name: values?.['image-name'],
image_requests: [
{
architecture: 'x86_64',
@ -155,6 +160,7 @@ const onSave = (values) => {
if (values['target-environment']?.['guest-image']) {
let request = {
distribution: values.release,
image_name: values?.['image-name'],
image_requests: [
{
architecture: 'x86_64',
@ -172,6 +178,7 @@ const onSave = (values) => {
if (values['target-environment']?.['image-installer']) {
let request = {
distribution: values.release,
image_name: values?.['image-name'],
image_requests: [
{
architecture: 'x86_64',
@ -254,6 +261,7 @@ https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/up
// order in this array does not reflect order in wizard nav, this order is managed inside
// of each step by `nextStep` property!
fields: [
details,
imageOutput,
awsTarget,
googleCloudTarger,

View file

@ -95,8 +95,12 @@ const ReviewStep = () => {
Review the information and click "Create image"
to create the image using the following criteria.
</Text>
<DescriptionList>
<DescriptionList isCompact isHorizontal>
<DescriptionListGroup>
<DescriptionListTerm>Image name</DescriptionListTerm>
<DescriptionListDescription>
{getState()?.values?.['image-name']}
</DescriptionListDescription>
<DescriptionListTerm>Release</DescriptionListTerm>
<DescriptionListDescription>
{releaseValues?.[getState()?.values?.release]}

View file

@ -0,0 +1,31 @@
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';
export default {
name: 'details',
title: 'Details',
nextStep: 'image-output',
fields: [
{
component: componentTypes.PLAIN_TEXT,
name: 'plain-text-component',
label: <p>
Enter a name to easily identify your image later. If left empty, the image&apos;s UUID will be displayed.
</p>
},
{
component: componentTypes.TEXT_FIELD,
name: 'image-name',
type: 'text',
label: 'Image name',
validate: [
{
type: validatorTypes.PATTERN,
pattern: /^[\w-]+$/i,
message: 'Can only contain letters, numbers, hyphens (-), and underscores (_)',
}
]
}
]
};

View file

@ -7,3 +7,4 @@ 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 details } from './details';

View file

@ -156,8 +156,9 @@ describe('Create Image Wizard', () => {
// check heading
screen.getByRole('heading', { name: /Create image/ });
screen.getByRole('button', { name: 'Details' });
screen.getByRole('button', { name: 'Image output' });
screen.getByRole('button', { name: 'Registration' });
screen.getByRole('button', { name: 'Packages' });
screen.getByRole('button', { name: 'Review' });
});
});
@ -165,6 +166,10 @@ describe('Create Image Wizard', () => {
describe('Step Image output', () => {
const setUp = () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
const [ next, , ] = verifyButtons();
// Click through the details page
next.click();
const imageOutputLink = screen.getByRole('button', { name: 'Image output' });
// select aws as upload destination
@ -184,14 +189,14 @@ describe('Step Image output', () => {
screen.getByText('AWS account ID');
});
test('Back button is disabled', () => {
test('clicking Back loads Details', () => {
setUp();
const [ , back, ] = verifyButtons();
// note: there is no `disabled` attribute and
// .toBeDissabled() fails
expect(back).toHaveClass('pf-m-disabled');
back.click();
screen.getByText('Image name');
});
test('clicking Cancel loads landing page', () => {
@ -221,12 +226,15 @@ describe('Step Image output', () => {
describe('Step Upload to AWS', () => {
const setUp = () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
const [ next, , ] = verifyButtons();
// Click through the details page
next.click();
// select aws as upload destination
const awsTile = screen.getByTestId('upload-aws');
awsTile.click();
screen.getByRole('button', { name: /Next/ }).click();
next.click();
};
test('clicking Next loads Registration', async () => {
@ -272,12 +280,15 @@ describe('Step Upload to AWS', () => {
describe('Step Upload to Google', () => {
const setUp = () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
const [ next, , ] = verifyButtons();
// Click through the details page
next.click();
// select aws as upload destination
const awsTile = screen.getByTestId('upload-google');
awsTile.click();
screen.getByRole('button', { name: /Next/ }).click();
next.click();
};
test('clicking Next loads Registration', async () => {
@ -335,11 +346,14 @@ describe('Step Upload to Google', () => {
describe('Step Upload to Azure', () => {
const setUp = () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
const [ next, , ] = verifyButtons();
// Click through the details page
next.click();
// select aws as upload destination
const awsTile = screen.getByTestId('upload-azure');
awsTile.click();
screen.getByRole('button', { name: /Next/ }).click();
next.click();
};
test('clicking Next loads Registration', async () => {
@ -398,15 +412,18 @@ describe('Step Upload to Azure', () => {
describe('Step Registration', () => {
const setUp = async () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
const [ next, , ] = verifyButtons();
// Click through the details page
next.click();
// select aws as upload destination
const awsTile = screen.getByTestId('upload-aws');
awsTile.click();
screen.getByRole('button', { name: /Next/ }).click();
next.click();
userEvent.type(screen.getByTestId('aws-account-id'), '012345678901');
screen.getByRole('button', { name: /Next/ }).click();
next.click();
await screen.findByRole('textbox', {
name: 'Select activation key'
@ -517,15 +534,18 @@ describe('Step Registration', () => {
describe('Step Packages', () => {
const setUp = async () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
const [ next, , ] = verifyButtons();
// Click through the details page
next.click();
// select aws as upload destination
const awsTile = screen.getByTestId('upload-aws');
awsTile.click();
screen.getByRole('button', { name: /Next/ }).click();
next.click();
// aws step
userEvent.type(screen.getByTestId('aws-account-id'), '012345678901');
screen.getByRole('button', { name: /Next/ }).click();
next.click();
// skip registration
await screen.findByRole('textbox', {
name: 'Select activation key'
@ -533,10 +553,10 @@ describe('Step Packages', () => {
const registerLaterRadio = screen.getByLabelText('Register later');
userEvent.click(registerLaterRadio);
screen.getByRole('button', { name: /Next/ }).click();
next.click();
// skip fsc
screen.getByRole('button', { name: /Next/ }).click();
next.click();
};
test('clicking Next loads Review', async () => {
@ -850,15 +870,18 @@ describe('Step Packages', () => {
describe('Step Review', () => {
const setUp = async () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
const [ next, , ] = verifyButtons();
// Click through the details page
next.click();
// select aws as upload destination
const awsTile = screen.getByTestId('upload-aws');
awsTile.click();
screen.getByRole('button', { name: /Next/ }).click();
next.click();
// aws step
userEvent.type(screen.getByTestId('aws-account-id'), '012345678901');
screen.getByRole('button', { name: /Next/ }).click();
next.click();
await screen.findByRole('textbox', {
name: 'Select activation key'
@ -867,19 +890,23 @@ describe('Step Review', () => {
// skip registration
const registerLaterRadio = screen.getByLabelText('Register later');
userEvent.click(registerLaterRadio);
screen.getByRole('button', { name: /Next/ }).click();
next.click();
// skip fsc
screen.getByRole('button', { name: /Next/ }).click();
next.click();
// skip packages
screen.getByRole('button', { name: /Next/ }).click();
next.click();
};
// eslint-disable-next-line no-unused-vars
const setUpCentOS = () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
const [ next, , ] = verifyButtons();
// Click through the details page
next.click();
// This is the best way to open the menu since ddf doesn't support data-testid for the select
const releaseMenu = screen.getByRole('button', {
name: /open menu/i
@ -893,17 +920,17 @@ describe('Step Review', () => {
// select aws as upload destination
const awsTile = screen.getByTestId('upload-aws');
awsTile.click();
screen.getByRole('button', { name: /Next/ }).click();
next.click();
// aws step
userEvent.type(screen.getByTestId('aws-account-id'), '012345678901');
screen.getByRole('button', { name: /Next/ }).click();
next.click();
// skip fsc
screen.getByRole('button', { name: /Next/ }).click();
next.click();
// skip packages
screen.getByRole('button', { name: /Next/ }).click();
next.click();
};
test('has 3 buttons', async () => {
@ -984,6 +1011,12 @@ describe('Click through all steps', () => {
await setUp();
const next = screen.getByRole('button', { name: /Next/ });
// Enter image name
const detailsInput = screen.getByRole('textbox', {
name: 'Image name'
});
userEvent.type(detailsInput, 'MyImageName');
next.click();
// select image output
// userEvent.selectOptions(screen.getByTestId('release-select'), [ RHEL_8 ]);
@ -1088,6 +1121,7 @@ describe('Click through all steps', () => {
if (body.image_requests[0].upload_request.type === 'aws') {
expect(body).toEqual({
distribution: RHEL_8,
image_name: 'MyImageName',
image_requests: [{
architecture: 'x86_64',
image_type: 'ami',
@ -1127,6 +1161,7 @@ describe('Click through all steps', () => {
} else if (body.image_requests[0].upload_request.type === 'gcp') {
expect(body).toEqual({
distribution: RHEL_8,
image_name: 'MyImageName',
image_requests: [{
architecture: 'x86_64',
image_type: 'vhd',
@ -1166,6 +1201,7 @@ describe('Click through all steps', () => {
} else if (body.image_requests[0].upload_request.type === 'azure') {
expect(body).toEqual({
distribution: RHEL_8,
image_name: 'MyImageName',
image_requests: [{
architecture: 'x86_64',
image_type: 'vhd',
@ -1207,6 +1243,7 @@ describe('Click through all steps', () => {
} else if (body.image_requests[0].image_type === 'vsphere') {
expect(body).toEqual({
distribution: RHEL_8,
image_name: 'MyImageName',
image_requests: [{
architecture: 'x86_64',
image_type: 'vsphere',
@ -1244,6 +1281,7 @@ describe('Click through all steps', () => {
} else if (body.image_requests[0].image_type === 'guest-image') {
expect(body).toEqual({
distribution: RHEL_8,
image_name: 'MyImageName',
image_requests: [{
architecture: 'x86_64',
image_type: 'guest-image',
@ -1281,6 +1319,7 @@ describe('Click through all steps', () => {
} else if (body.image_requests[0].image_type === 'image-installer') {
expect(body).toEqual({
distribution: RHEL_8,
image_name: 'MyImageName',
image_requests: [{
architecture: 'x86_64',
image_type: 'image-installer',