Wizard: Improve in-page wizard cosmetically
This commit: 1. Removes the header from the Data Driven Forms wizard 2. Adds padding around the in-page wizard so it is visually consistent with the images table 3. Refactors the images table header into a re-usable component that is now used in both the images table and the wizard 4. Allows the repositories table to fill the available vertical space in the wizard 5. Adjusts the package dual list selectors so that they fill the available horizontal space in the wizard
This commit is contained in:
parent
1c1290f7ed
commit
c4d411efa4
9 changed files with 169 additions and 174 deletions
|
|
@ -34,7 +34,7 @@ import {
|
|||
import isRhel from '../../Utilities/isRhel';
|
||||
import { resolveRelPath } from '../../Utilities/path';
|
||||
import { useGetEnvironment } from '../../Utilities/useGetEnvironment';
|
||||
import DocumentationButton from '../sharedComponents/DocumentationButton';
|
||||
import { ImageBuilderHeader } from '../sharedComponents/ImageBuilderHeader';
|
||||
|
||||
const handleKeyDown = (e, handleClose) => {
|
||||
if (e.key === 'Escape') {
|
||||
|
|
@ -597,75 +597,73 @@ const CreateImageWizard = () => {
|
|||
const currentDate = new Date();
|
||||
|
||||
return (
|
||||
<ImageCreator
|
||||
onClose={handleClose}
|
||||
onSubmit={async ({ values, setIsSaving }) => {
|
||||
setIsSaving(true);
|
||||
const requests = onSave(values);
|
||||
await Promise.allSettled(
|
||||
requests.map((composeRequest) => composeImage({ composeRequest }))
|
||||
);
|
||||
navigate(resolveRelPath(''));
|
||||
}}
|
||||
defaultArch="x86_64"
|
||||
customValidatorMapper={{
|
||||
fileSystemConfigurationValidator,
|
||||
targetEnvironmentValidator,
|
||||
}}
|
||||
schema={{
|
||||
fields: [
|
||||
{
|
||||
component: componentTypes.WIZARD,
|
||||
name: 'image-builder-wizard',
|
||||
className: 'imageBuilder',
|
||||
isDynamic: true,
|
||||
inModal: false,
|
||||
onKeyDown: (e) => {
|
||||
handleKeyDown(e, handleClose);
|
||||
},
|
||||
buttonLabels: {
|
||||
submit: 'Create image',
|
||||
},
|
||||
showTitles: true,
|
||||
title: 'Image Builder',
|
||||
crossroads: [
|
||||
'target-environment',
|
||||
'release',
|
||||
'payload-repositories',
|
||||
],
|
||||
description: (
|
||||
<>
|
||||
Image builder allows you to create a custom image and push it to
|
||||
target environments. <DocumentationButton />
|
||||
</>
|
||||
),
|
||||
// order in this array does not reflect order in wizard nav, this order is managed inside
|
||||
// of each step by `nextStep` property!
|
||||
<>
|
||||
<ImageBuilderHeader />
|
||||
<section className="pf-l-page__main-section pf-c-page__main-section">
|
||||
<ImageCreator
|
||||
onClose={handleClose}
|
||||
onSubmit={async ({ values, setIsSaving }) => {
|
||||
setIsSaving(true);
|
||||
const requests = onSave(values);
|
||||
await Promise.allSettled(
|
||||
requests.map((composeRequest) => composeImage({ composeRequest }))
|
||||
);
|
||||
navigate(resolveRelPath(''));
|
||||
}}
|
||||
defaultArch="x86_64"
|
||||
customValidatorMapper={{
|
||||
fileSystemConfigurationValidator,
|
||||
targetEnvironmentValidator,
|
||||
}}
|
||||
schema={{
|
||||
fields: [
|
||||
imageOutput,
|
||||
awsTarget,
|
||||
googleCloudTarget,
|
||||
msAzureTarget,
|
||||
registration,
|
||||
packages,
|
||||
packagesContentSources,
|
||||
repositories,
|
||||
fileSystemConfiguration,
|
||||
imageName,
|
||||
review,
|
||||
oscap,
|
||||
{
|
||||
component: componentTypes.WIZARD,
|
||||
name: 'image-builder-wizard',
|
||||
className: 'imageBuilder',
|
||||
isDynamic: true,
|
||||
inModal: false,
|
||||
onKeyDown: (e) => {
|
||||
handleKeyDown(e, handleClose);
|
||||
},
|
||||
buttonLabels: {
|
||||
submit: 'Create image',
|
||||
},
|
||||
showTitles: true,
|
||||
crossroads: [
|
||||
'target-environment',
|
||||
'release',
|
||||
'payload-repositories',
|
||||
],
|
||||
// order in this array does not reflect order in wizard nav, this order is managed inside
|
||||
// of each step by `nextStep` property!
|
||||
fields: [
|
||||
imageOutput,
|
||||
awsTarget,
|
||||
googleCloudTarget,
|
||||
msAzureTarget,
|
||||
registration,
|
||||
packages,
|
||||
packagesContentSources,
|
||||
repositories,
|
||||
fileSystemConfiguration,
|
||||
imageName,
|
||||
review,
|
||||
oscap,
|
||||
],
|
||||
initialState: {
|
||||
activeStep: 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
|
||||
},
|
||||
},
|
||||
],
|
||||
initialState: {
|
||||
activeStep: 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
|
||||
},
|
||||
},
|
||||
],
|
||||
}}
|
||||
initialValues={initialState}
|
||||
/>
|
||||
}}
|
||||
initialValues={initialState}
|
||||
/>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
.pf-c-dual-list-selector {
|
||||
--pf-c-dual-list-selector__menu--MinHeight: 18rem;
|
||||
--pf-c-dual-list-selector__menu--MaxHeight: 18rem;
|
||||
--pf-c-dual-list-selector--GridTemplateColumns--pane--MinMax--max: 100vw;
|
||||
}
|
||||
|
||||
.pf-c-form {
|
||||
|
|
@ -59,20 +59,3 @@ ul.pf-m-plain {
|
|||
padding-left: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
// [2023-09] Wizard height should not be limited see
|
||||
// https://github.com/data-driven-forms/react-forms/issues/1402
|
||||
// TODO remove me after DDF is not used anymore
|
||||
.pf-c-wizard__main {
|
||||
overflow-x: unset;
|
||||
overflow-y: unset;
|
||||
}
|
||||
// TODO remove me after DDF is not used anymore
|
||||
.pf-c-wizard__footer {
|
||||
z-index: unset;
|
||||
}
|
||||
// [2023-10] Wizard closing cross shouldn't get displayed
|
||||
// TODO remove me after DDF is not used anymore
|
||||
.pf-c-wizard__header .pf-c-button.pf-m-plain {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -399,7 +399,7 @@ const Repositories = (props) => {
|
|||
</ToolbarItem>
|
||||
</ToolbarContent>
|
||||
</Toolbar>
|
||||
<Panel isScrollable>
|
||||
<Panel>
|
||||
<PanelMain>
|
||||
<RepositoryUnavailable />
|
||||
<TableComposable
|
||||
|
|
|
|||
|
|
@ -1,7 +1,3 @@
|
|||
.title {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.pf-c-form__group-label-help {
|
||||
color: var(--pf-global--icon--Color--light);
|
||||
}
|
||||
|
|
@ -10,10 +6,6 @@
|
|||
color: var(--pf-global--icon--Color--dark);
|
||||
}
|
||||
|
||||
.header-button {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.expand-section {
|
||||
background-color: var(--pf-global--palette--white);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,12 +12,6 @@ import {
|
|||
TabAction,
|
||||
} from '@patternfly/react-core';
|
||||
import { ExternalLinkAltIcon, HelpIcon } from '@patternfly/react-icons';
|
||||
// eslint-disable-next-line rulesdir/disallow-fec-relative-imports
|
||||
import {
|
||||
OpenSourceBadge,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
} from '@redhat-cloud-services/frontend-components';
|
||||
import { useFlag } from '@unleash/proxy-client-react';
|
||||
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
|
||||
|
||||
|
|
@ -29,6 +23,7 @@ import { manageEdgeImagesUrlName } from '../../Utilities/edge';
|
|||
import { resolveRelPath } from '../../Utilities/path';
|
||||
import EdgeImagesTable from '../edge/ImagesTable';
|
||||
import ImagesTable from '../ImagesTable/ImagesTable';
|
||||
import { ImageBuilderHeader } from '../sharedComponents/ImageBuilderHeader';
|
||||
|
||||
export const LandingPage = () => {
|
||||
const { pathname } = useLocation();
|
||||
|
|
@ -61,65 +56,7 @@ export const LandingPage = () => {
|
|||
);
|
||||
return (
|
||||
<>
|
||||
{/*@ts-ignore*/}
|
||||
<PageHeader>
|
||||
<PageHeaderTitle className="title" title="Image Builder" />
|
||||
<Popover
|
||||
minWidth="35rem"
|
||||
headerContent={'About image builder'}
|
||||
bodyContent={
|
||||
<TextContent>
|
||||
<Text>
|
||||
Image builder is a tool for creating deployment-ready customized
|
||||
system images: installation disks, virtual machines, cloud
|
||||
vendor-specific images, and others. By using image builder, you
|
||||
can make these images faster than manual procedures because it
|
||||
eliminates the specific configurations required for each output
|
||||
type.
|
||||
</Text>
|
||||
<Text>
|
||||
<Button
|
||||
component="a"
|
||||
target="_blank"
|
||||
variant="link"
|
||||
icon={<ExternalLinkAltIcon />}
|
||||
iconPosition="right"
|
||||
isInline
|
||||
href={
|
||||
'https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/creating_customized_rhel_images_using_the_image_builder_service'
|
||||
}
|
||||
>
|
||||
Image builder for RPM-DNF documentation
|
||||
</Button>
|
||||
</Text>
|
||||
<Text>
|
||||
<Button
|
||||
component="a"
|
||||
target="_blank"
|
||||
variant="link"
|
||||
icon={<ExternalLinkAltIcon />}
|
||||
iconPosition="right"
|
||||
isInline
|
||||
href={
|
||||
'https://access.redhat.com/documentation/en-us/edge_management/2022/html/create_rhel_for_edge_images_and_configure_automated_management/index'
|
||||
}
|
||||
>
|
||||
Image builder for OSTree documentation
|
||||
</Button>
|
||||
</Text>
|
||||
</TextContent>
|
||||
}
|
||||
>
|
||||
<Button
|
||||
variant="plain"
|
||||
aria-label="About image builder"
|
||||
className="pf-u-pl-sm header-button"
|
||||
>
|
||||
<HelpIcon />
|
||||
</Button>
|
||||
</Popover>
|
||||
<OpenSourceBadge repositoriesURL="https://www.osbuild.org/guides/image-builder-service/architecture.html" />
|
||||
</PageHeader>
|
||||
<ImageBuilderHeader />
|
||||
{edgeParityFlag ? (
|
||||
<Tabs
|
||||
className="pf-c-tabs pf-c-page-header pf-c-table"
|
||||
|
|
|
|||
7
src/Components/sharedComponents/ImageBuilderHeader.scss
Normal file
7
src/Components/sharedComponents/ImageBuilderHeader.scss
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
.title {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.header-button {
|
||||
padding-right: 0;
|
||||
}
|
||||
78
src/Components/sharedComponents/ImageBuilderHeader.tsx
Normal file
78
src/Components/sharedComponents/ImageBuilderHeader.tsx
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
import React from 'react';
|
||||
|
||||
import { Button, Popover, Text, TextContent } from '@patternfly/react-core';
|
||||
import { ExternalLinkAltIcon, HelpIcon } from '@patternfly/react-icons';
|
||||
// eslint-disable-next-line rulesdir/disallow-fec-relative-imports
|
||||
import {
|
||||
OpenSourceBadge,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
} from '@redhat-cloud-services/frontend-components';
|
||||
|
||||
import './ImageBuilderHeader.scss';
|
||||
|
||||
export const ImageBuilderHeader = () => {
|
||||
return (
|
||||
<>
|
||||
{/*@ts-ignore*/}
|
||||
<PageHeader>
|
||||
<PageHeaderTitle className="title" title="Image Builder" />
|
||||
<Popover
|
||||
minWidth="35rem"
|
||||
headerContent={'About image builder'}
|
||||
bodyContent={
|
||||
<TextContent>
|
||||
<Text>
|
||||
Image builder is a tool for creating deployment-ready customized
|
||||
system images: installation disks, virtual machines, cloud
|
||||
vendor-specific images, and others. By using image builder, you
|
||||
can make these images faster than manual procedures because it
|
||||
eliminates the specific configurations required for each output
|
||||
type.
|
||||
</Text>
|
||||
<Text>
|
||||
<Button
|
||||
component="a"
|
||||
target="_blank"
|
||||
variant="link"
|
||||
icon={<ExternalLinkAltIcon />}
|
||||
iconPosition="right"
|
||||
isInline
|
||||
href={
|
||||
'https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/creating_customized_rhel_images_using_the_image_builder_service'
|
||||
}
|
||||
>
|
||||
Image builder for RPM-DNF documentation
|
||||
</Button>
|
||||
</Text>
|
||||
<Text>
|
||||
<Button
|
||||
component="a"
|
||||
target="_blank"
|
||||
variant="link"
|
||||
icon={<ExternalLinkAltIcon />}
|
||||
iconPosition="right"
|
||||
isInline
|
||||
href={
|
||||
'https://access.redhat.com/documentation/en-us/edge_management/2022/html/create_rhel_for_edge_images_and_configure_automated_management/index'
|
||||
}
|
||||
>
|
||||
Image builder for OSTree documentation
|
||||
</Button>
|
||||
</Text>
|
||||
</TextContent>
|
||||
}
|
||||
>
|
||||
<Button
|
||||
variant="plain"
|
||||
aria-label="About image builder"
|
||||
className="pf-u-pl-sm header-button"
|
||||
>
|
||||
<HelpIcon />
|
||||
</Button>
|
||||
</Popover>
|
||||
<OpenSourceBadge repositoriesURL="https://www.osbuild.org/guides/image-builder-service/architecture.html" />
|
||||
</PageHeader>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
@ -85,9 +85,9 @@ describe('Step Upload to Azure', () => {
|
|||
|
||||
await clickNext();
|
||||
|
||||
expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent(
|
||||
'Target environment - Microsoft Azure'
|
||||
);
|
||||
await screen.findByRole('heading', {
|
||||
name: 'Target environment - Microsoft Azure',
|
||||
});
|
||||
};
|
||||
|
||||
test('clicking Next loads Registration', async () => {
|
||||
|
|
|
|||
|
|
@ -143,9 +143,7 @@ describe('Step Image output', () => {
|
|||
// select aws as upload destination
|
||||
await user.click(await screen.findByTestId('upload-aws'));
|
||||
|
||||
expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent(
|
||||
'Image output'
|
||||
);
|
||||
await screen.findByRole('heading', { name: 'Image output' });
|
||||
};
|
||||
|
||||
test('clicking Next loads Upload to AWS', async () => {
|
||||
|
|
@ -282,9 +280,9 @@ describe('Step Upload to AWS', () => {
|
|||
|
||||
await clickNext();
|
||||
|
||||
expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent(
|
||||
'Target environment - Amazon Web Services'
|
||||
);
|
||||
await screen.findByRole('heading', {
|
||||
name: 'Target environment - Amazon Web Services',
|
||||
});
|
||||
};
|
||||
|
||||
test('clicking Next loads Registration', async () => {
|
||||
|
|
@ -450,9 +448,9 @@ describe('Step Upload to Google', () => {
|
|||
|
||||
await clickNext();
|
||||
|
||||
expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent(
|
||||
'Target environment - Google Cloud Platform'
|
||||
);
|
||||
await screen.findByRole('heading', {
|
||||
name: 'Target environment - Google Cloud Platform',
|
||||
});
|
||||
};
|
||||
|
||||
test('clicking Next loads Registration', async () => {
|
||||
|
|
@ -549,7 +547,9 @@ describe('Step Registration', () => {
|
|||
|
||||
await clickNext();
|
||||
|
||||
screen.getByRole('heading', { name: /file system configuration/i });
|
||||
await screen.findByRole('heading', {
|
||||
name: 'File system configuration',
|
||||
});
|
||||
});
|
||||
|
||||
test('clicking Back loads Upload to AWS', async () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue