CreateImageWizard: move name image step to end
The Details step is renamed to Name Image and moved to the last step before Review. Also, the validation is removed since all utf-8 characters are supported for image names.
This commit is contained in:
parent
3a74c564de
commit
2f5f6dcc46
6 changed files with 74 additions and 86 deletions
|
|
@ -19,7 +19,7 @@ import {
|
|||
packages,
|
||||
imageOutput,
|
||||
fileSystemConfiguration,
|
||||
details
|
||||
imageName
|
||||
} from './steps';
|
||||
|
||||
import {
|
||||
|
|
@ -364,7 +364,6 @@ const formStepHistory = (composeRequest) => {
|
|||
const imageRequest = composeRequest.image_requests[0];
|
||||
const uploadRequest = imageRequest.upload_request;
|
||||
let steps = [
|
||||
'details',
|
||||
'image-output'
|
||||
];
|
||||
|
||||
|
|
@ -383,6 +382,7 @@ const formStepHistory = (composeRequest) => {
|
|||
steps = steps.concat([
|
||||
'File system configuration',
|
||||
'packages',
|
||||
'image-name'
|
||||
]);
|
||||
|
||||
return steps;
|
||||
|
|
@ -454,7 +454,6 @@ const CreateImageWizard = () => {
|
|||
// 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,
|
||||
|
|
@ -462,10 +461,11 @@ const CreateImageWizard = () => {
|
|||
registration,
|
||||
packages,
|
||||
fileSystemConfiguration,
|
||||
imageName,
|
||||
review,
|
||||
],
|
||||
initialState: {
|
||||
activeStep: location?.state?.initialStep || 'details', // name of the active step
|
||||
activeStep: location?.state?.initialStep || 'image-output', // name of the active step
|
||||
activeStepIndex: stepHistory.length, // active index
|
||||
maxStepIndex: stepHistory.length, // max achieved index
|
||||
prevSteps: stepHistory, // array with names of previously visited steps
|
||||
|
|
|
|||
|
|
@ -1,35 +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 StepTemplate from './stepTemplate';
|
||||
|
||||
export default {
|
||||
StepTemplate,
|
||||
id: 'wizard-details',
|
||||
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's UUID will be displayed.
|
||||
</p>
|
||||
},
|
||||
{
|
||||
component: componentTypes.TEXT_FIELD,
|
||||
name: 'image-name',
|
||||
type: 'text',
|
||||
label: 'Image name',
|
||||
autoFocus: true,
|
||||
validate: [
|
||||
{
|
||||
type: validatorTypes.PATTERN,
|
||||
pattern: /^[\w-]+$/i,
|
||||
message: 'Can only contain letters, numbers, hyphens (-), and underscores (_)',
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
25
src/Components/CreateImageWizard/steps/imageName.js
Normal file
25
src/Components/CreateImageWizard/steps/imageName.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import React from 'react';
|
||||
import componentTypes from '@data-driven-forms/react-form-renderer/component-types';
|
||||
import StepTemplate from './stepTemplate';
|
||||
|
||||
export default {
|
||||
StepTemplate,
|
||||
id: 'wizard-details',
|
||||
name: 'image-name',
|
||||
title: 'Name image',
|
||||
nextStep: 'review',
|
||||
fields: [
|
||||
{
|
||||
component: componentTypes.PLAIN_TEXT,
|
||||
name: 'plain-text-component',
|
||||
label: <p>Optionally enter a name for your image. All images will have a UUID.</p>
|
||||
},
|
||||
{
|
||||
component: componentTypes.TEXT_FIELD,
|
||||
name: 'image-name',
|
||||
type: 'text',
|
||||
label: 'Image name',
|
||||
autoFocus: true,
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
@ -7,4 +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';
|
||||
export { default as imageName } from './imageName';
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export default {
|
|||
title: 'Packages',
|
||||
name: 'packages',
|
||||
substepOf: 'System Configuration',
|
||||
nextStep: 'review',
|
||||
nextStep: 'image-name',
|
||||
fields: [
|
||||
{
|
||||
component: componentTypes.PLAIN_TEXT,
|
||||
|
|
|
|||
|
|
@ -156,9 +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: 'Packages' });
|
||||
screen.getByRole('button', { name: 'Name image' });
|
||||
screen.getByRole('button', { name: 'Review' });
|
||||
});
|
||||
});
|
||||
|
|
@ -166,9 +166,6 @@ 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' });
|
||||
|
||||
|
|
@ -189,16 +186,6 @@ describe('Step Image output', () => {
|
|||
screen.getByText('AWS account ID');
|
||||
});
|
||||
|
||||
test('clicking Back loads Details', () => {
|
||||
setUp();
|
||||
|
||||
const [ , back, ] = verifyButtons();
|
||||
|
||||
back.click();
|
||||
|
||||
screen.getByText('Image name');
|
||||
});
|
||||
|
||||
test('clicking Cancel loads landing page', () => {
|
||||
setUp();
|
||||
|
||||
|
|
@ -247,8 +234,6 @@ 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');
|
||||
|
|
@ -303,8 +288,6 @@ 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');
|
||||
|
|
@ -371,8 +354,6 @@ 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');
|
||||
|
|
@ -439,8 +420,6 @@ 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');
|
||||
|
|
@ -503,6 +482,7 @@ describe('Step Registration', () => {
|
|||
screen.getByRole('button', { name: /Next/ }).click();
|
||||
screen.getByRole('button', { name: /Next/ }).click();
|
||||
screen.getByRole('button', { name: /Next/ }).click();
|
||||
screen.getByRole('button', { name: /Next/ }).click();
|
||||
await waitFor(() => {
|
||||
screen.getByText('Register with Subscriptions and Red Hat Insights');
|
||||
screen.getAllByText('012345678901');
|
||||
|
|
@ -528,6 +508,7 @@ describe('Step Registration', () => {
|
|||
screen.getByRole('button', { name: /Next/ }).click();
|
||||
screen.getByRole('button', { name: /Next/ }).click();
|
||||
screen.getByRole('button', { name: /Next/ }).click();
|
||||
screen.getByRole('button', { name: /Next/ }).click();
|
||||
await waitFor(() => {
|
||||
screen.getByText('Register with Subscriptions');
|
||||
screen.getAllByText('012345678901');
|
||||
|
|
@ -553,6 +534,7 @@ describe('Step Registration', () => {
|
|||
screen.getByRole('button', { name: /Next/ }).click();
|
||||
screen.getByRole('button', { name: /Next/ }).click();
|
||||
screen.getByRole('button', { name: /Next/ }).click();
|
||||
screen.getByRole('button', { name: /Next/ }).click();
|
||||
screen.getByText('Register the system later');
|
||||
});
|
||||
});
|
||||
|
|
@ -561,8 +543,6 @@ 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');
|
||||
|
|
@ -585,13 +565,15 @@ describe('Step Packages', () => {
|
|||
next.click();
|
||||
};
|
||||
|
||||
test('clicking Next loads Review', async () => {
|
||||
test('clicking Next loads Image name', async () => {
|
||||
await setUp();
|
||||
|
||||
const [ next, , ] = verifyButtons();
|
||||
next.click();
|
||||
|
||||
screen.getByText('Review the information and click "Create image" to create the image using the following criteria.');
|
||||
screen.getByRole('heading', {
|
||||
name: 'Name image'
|
||||
});
|
||||
});
|
||||
|
||||
test('clicking Back loads file system configuration', async () => {
|
||||
|
|
@ -722,6 +704,9 @@ describe('Step Packages', () => {
|
|||
screen.getByRole('option', { name: /lib-test lib-test package summary/ }).click();
|
||||
screen.getByRole('button', { name: /Remove selected/ }).click();
|
||||
|
||||
// skip name page
|
||||
screen.getByRole('button', { name: /Next/ }).click();
|
||||
|
||||
// review page
|
||||
screen.getByRole('button', { name: /Next/ }).click();
|
||||
|
||||
|
|
@ -731,12 +716,14 @@ describe('Step Packages', () => {
|
|||
|
||||
// remove another package
|
||||
screen.getByRole('button', { name: /Back/ }).click();
|
||||
screen.getByRole('button', { name: /Back/ }).click();
|
||||
await screen.findByTestId('search-available-pkgs-input');
|
||||
screen.getByRole('option', { name: /summary for test package/ }).click();
|
||||
screen.getByRole('button', { name: /Remove selected/ }).click();
|
||||
|
||||
// review page
|
||||
screen.getByRole('button', { name: /Next/ }).click();
|
||||
screen.getByRole('button', { name: /Next/ }).click();
|
||||
|
||||
// await screen.findByTestId('chosen-packages-count');
|
||||
chosen = await screen.findByTestId('chosen-packages-count');
|
||||
|
|
@ -897,8 +884,6 @@ 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');
|
||||
|
|
@ -923,6 +908,8 @@ describe('Step Review', () => {
|
|||
|
||||
// skip packages
|
||||
next.click();
|
||||
// skip name
|
||||
next.click();
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
|
|
@ -930,8 +917,6 @@ describe('Step Review', () => {
|
|||
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', {
|
||||
|
|
@ -957,6 +942,8 @@ describe('Step Review', () => {
|
|||
|
||||
// skip packages
|
||||
next.click();
|
||||
// skip name
|
||||
next.click();
|
||||
};
|
||||
|
||||
test('has 3 buttons', async () => {
|
||||
|
|
@ -967,13 +954,15 @@ describe('Step Review', () => {
|
|||
screen.getByRole('button', { name: /Cancel/ });
|
||||
});
|
||||
|
||||
test('clicking Back loads Packages', async () => {
|
||||
test('clicking Back loads Image name', async () => {
|
||||
await setUp();
|
||||
|
||||
const back = screen.getByRole('button', { name: /Back/ });
|
||||
back.click();
|
||||
|
||||
screen.getByText('Add optional additional packages to your image by searching available packages.');
|
||||
screen.getByRole('heading', {
|
||||
name: 'Name image'
|
||||
});
|
||||
});
|
||||
|
||||
test('clicking Cancel loads landing page', async () => {
|
||||
|
|
@ -1064,12 +1053,6 @@ 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 ]);
|
||||
|
|
@ -1147,6 +1130,13 @@ describe('Click through all steps', () => {
|
|||
screen.getByRole('button', { name: /Add selected/ }).click();
|
||||
next.click();
|
||||
|
||||
// Enter image name
|
||||
const nameInput = screen.getByRole('textbox', {
|
||||
name: 'Image name'
|
||||
});
|
||||
userEvent.type(nameInput, 'MyImageName');
|
||||
next.click();
|
||||
|
||||
// review
|
||||
await screen.
|
||||
findByText('Review the information and click "Create image" to create the image using the following criteria.');
|
||||
|
|
@ -1423,7 +1413,8 @@ describe('Click through all steps', () => {
|
|||
// returns back to the landing page
|
||||
await waitFor(() => expect(history.location.pathname).toBe('/'));
|
||||
expect(store.getStore().getState().composes.allIds).toEqual(ids);
|
||||
});
|
||||
// set test timeout of 10 seconds
|
||||
}, 10000);
|
||||
});
|
||||
|
||||
describe('Keyboard accessibility', () => {
|
||||
|
|
@ -1459,11 +1450,6 @@ describe('Keyboard accessibility', () => {
|
|||
test('autofocus on each step first input element', async () => {
|
||||
setUp();
|
||||
|
||||
// Details
|
||||
const detailsInput = screen.getByRole('textbox', { name: /image name/i });
|
||||
expect(detailsInput).toHaveFocus();
|
||||
clickNext();
|
||||
|
||||
// Image output
|
||||
selectAllEnvironments();
|
||||
clickNext();
|
||||
|
|
@ -1513,6 +1499,11 @@ describe('Keyboard accessibility', () => {
|
|||
expect(availablePackagesInput).toHaveFocus();
|
||||
clickNext();
|
||||
|
||||
// Name
|
||||
const nameInput = screen.getByRole('textbox', { name: /image name/i });
|
||||
expect(nameInput).toHaveFocus();
|
||||
clickNext();
|
||||
|
||||
// Review
|
||||
const targetEnvironmentTab = screen.getByTestId('tab-target');
|
||||
expect(targetEnvironmentTab).toHaveFocus();
|
||||
|
|
@ -1521,14 +1512,21 @@ describe('Keyboard accessibility', () => {
|
|||
|
||||
test('pressing Esc closes the wizard', async () => {
|
||||
setUp();
|
||||
// wizard needs to be interacted with for the esc key to work
|
||||
const awsTile = screen.getByTestId('upload-aws');
|
||||
userEvent.click(awsTile);
|
||||
userEvent.keyboard('{esc}');
|
||||
expect(history.location.pathname).toBe('/');
|
||||
});
|
||||
|
||||
test('pressing Enter does not advance the wizard', async () => {
|
||||
setUp();
|
||||
const awsTile = screen.getByTestId('upload-aws');
|
||||
userEvent.click(awsTile);
|
||||
userEvent.keyboard('{enter}');
|
||||
screen.getByText('Image name');
|
||||
screen.getByRole('heading', {
|
||||
name: /image output/i
|
||||
});
|
||||
});
|
||||
|
||||
test('target environment tiles are keyboard selectable', async () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue