Wizard: Add additional information for an activation key in Review step

Fixes #822. This adds component `ActivationKeyInformation` with additional information for an activation key on a Registration tab of Review step.
The added fields are:
- Name
- Role
- SLA
- Usage
- Additional repositories

Organization ID is added to the Activation key popover.

Function `getActivationKey` was added to `api` to get an additional information about activation key from RHSM api based on the name of the key.
This commit is contained in:
regexowl 2022-11-07 09:53:33 +01:00 committed by Lucas Garfield
parent 47d99a3903
commit b2a6c403bf
4 changed files with 221 additions and 3 deletions

View file

@ -0,0 +1,139 @@
import React, { useEffect, useState } from 'react';
import {
Text,
TextContent,
TextList,
TextListItem,
TextListItemVariants,
TextListVariants,
TextVariants,
} from '@patternfly/react-core';
import { useFormApi } from '@data-driven-forms/react-form-renderer';
import { Button, Popover } from '@patternfly/react-core';
import { HelpIcon } from '@patternfly/react-icons';
import {
TableComposable,
Tbody,
Td,
Th,
Thead,
Tr,
} from '@patternfly/react-table';
import api from '../../../api';
const ActivationKeyInformation = () => {
const { getState } = useFormApi();
const activationKey = getState()?.values?.['subscription-activation-key'];
const [role, setRole] = useState(undefined);
const [serviceLevel, setServiceLevel] = useState(undefined);
const [usage, setUsage] = useState(undefined);
const [additionalRepositories, setRepositories] = useState(undefined);
useEffect(() => {
const fetchKeyInformation = async () => {
const data = await api.getActivationKey(activationKey);
setRole(data?.role);
setServiceLevel(data?.serviceLevel);
setUsage(data?.usage);
setRepositories(data?.additionalRepositories);
};
fetchKeyInformation();
}, []);
return (
<>
<TextContent>
<TextList component={TextListVariants.dl}>
<TextListItem component={TextListItemVariants.dt}>Name:</TextListItem>
<TextListItem component={TextListItemVariants.dd}>
{activationKey}
</TextListItem>
<TextListItem component={TextListItemVariants.dt}>Role:</TextListItem>
<TextListItem component={TextListItemVariants.dd}>
{role || 'Not defined'}
</TextListItem>
<TextListItem component={TextListItemVariants.dt}>SLA:</TextListItem>
<TextListItem component={TextListItemVariants.dd}>
{serviceLevel || 'Not defined'}
</TextListItem>
<TextListItem component={TextListItemVariants.dt}>
Usage:
</TextListItem>
<TextListItem component={TextListItemVariants.dd}>
{usage || 'Not defined'}
</TextListItem>
<TextListItem component={TextListItemVariants.dt}>
Additional <br /> repositories:
<Popover
bodyContent={
<TextContent>
<Text>
The core repositories for your operating system version are
always enabled and do not need to be explicitly added to the
activation key.
</Text>
</TextContent>
}
>
<Button
variant="plain"
aria-label="About additional repositories"
className="pf-u-pl-sm pf-u-pt-0 pf-u-pb-0"
isSmall
>
<HelpIcon />
</Button>
</Popover>
</TextListItem>
<TextListItem
component={TextListItemVariants.dd}
className="pf-u-display-flex pf-u-align-items-flex-end"
>
{additionalRepositories?.length > 0 ? (
<Popover
bodyContent={
<TextContent>
<Text component={TextVariants.h3}>
Additional repositories
</Text>
<TableComposable
aria-label="Additional repositories table"
variant="compact"
>
<Thead>
<Tr>
<Th>Name</Th>
</Tr>
</Thead>
<Tbody data-testid="additional-repositories-table">
{additionalRepositories?.map((repo, index) => (
<Tr key={index}>
<Td>{repo.repositoryLabel}</Td>
</Tr>
))}
</Tbody>
</TableComposable>
</TextContent>
}
>
<Button
data-testid="repositories-popover-button"
variant="link"
aria-label="Show additional repositories"
className="pf-u-pl-0 pf-u-pt-0 pf-u-pb-0"
>
{additionalRepositories?.length} repositories
</Button>
</Popover>
) : (
'None'
)}
</TextListItem>
</TextList>
</TextContent>
</>
);
};
export default ActivationKeyInformation;

View file

@ -9,6 +9,7 @@ import {
List,
ListItem,
Popover,
Spinner,
Tab,
Tabs,
TabTitleText,
@ -30,6 +31,7 @@ import {
} from '@patternfly/react-table';
import { HelpIcon } from '@patternfly/react-icons';
import useFormApi from '@data-driven-forms/react-form-renderer/use-form-api';
import ActivationKeyInformation from './ActivationKeyInformation';
import { googleAccType } from '../steps/googleCloud';
import { RELEASES, UNIT_GIB, UNIT_MIB } from '../../../constants';
import isRhel from '../../../Utilities/isRhel';
@ -315,7 +317,17 @@ const ReviewStep = () => {
<br />
If using an activation key with command line
registration, you must provide your
organization&apos;s ID.
organization&apos;s ID. Your organization&apos;s ID
is{' '}
{getState()?.values?.[
'subscription-organization-id'
] !== undefined ? (
getState()?.values?.[
'subscription-organization-id'
]
) : (
<Spinner size="md" />
)}
</Text>
</TextContent>
}
@ -323,14 +335,15 @@ const ReviewStep = () => {
<Button
variant="plain"
aria-label="About activation key"
className="pf-c-form__group-label-help"
className="pf-u-pl-sm pf-u-pt-0 pf-u-pb-0"
isSmall
>
<HelpIcon />
</Button>
</Popover>
</TextListItem>
<TextListItem component={TextListItemVariants.dd}>
{getState()?.values?.['subscription-activation-key']}
<ActivationKeyInformation />
</TextListItem>
</TextList>
</TextContent>

View file

@ -76,6 +76,12 @@ async function getActivationKeys() {
return request.data.body;
}
async function getActivationKey(name) {
const path = `/activation_keys/${name}`;
const request = await axios.get(RHSM_API.concat(path));
return request.data.body;
}
// get clones of a compose
async function getClones(id, limit, offset) {
const params = new URLSearchParams({
@ -114,4 +120,5 @@ export default {
getPackagesContentSources,
getVersion,
getActivationKeys,
getActivationKey,
};

View file

@ -141,6 +141,11 @@ beforeAll(() => {
.spyOn(api, 'getActivationKeys')
.mockImplementation(() => Promise.resolve(mockActivationKeys));
const mockActivationKey = { body: [{ name: 'name0' }, { name: 'name1' }] };
jest.spyOn(api, 'getActivationKey').mockImplementation((name) => {
return Promise.resolve(mockActivationKey[name]);
});
global.insights = {
chrome: {
auth: {
@ -1445,6 +1450,49 @@ describe('Click through all steps', () => {
jest
.spyOn(api, 'getActivationKeys')
.mockImplementation(() => Promise.resolve(mockActivationKeys));
const mockActivationKey = {
name0: {
additionalRepositories: [
{
repositoryLabel: 'repository0',
},
{
repositoryLabel: 'repository1',
},
{
repositoryLabel: 'repository2',
},
],
id: '0',
name: 'name0',
releaseVersion: '',
role: '',
serviceLevel: 'Self-Support',
usage: 'Production',
},
name1: {
additionalRepositories: [
{
repositoryLabel: 'repository3',
},
{
repositoryLabel: 'repository4',
},
{
repositoryLabel: 'repository5',
},
],
id: '1',
name: 'name1',
releaseVersion: '',
role: '',
serviceLevel: 'Premium',
usage: 'Production',
},
};
jest.spyOn(api, 'getActivationKey').mockImplementation((name) => {
return Promise.resolve(mockActivationKey[name]);
});
const registrationRadio = screen.getByLabelText(
'Register and connect image instances with Red Hat'
@ -1537,6 +1585,17 @@ describe('Click through all steps', () => {
await screen.findByText('Register with Subscriptions and Red Hat Insights');
await screen.findByText('MyImageName');
screen.getByTestId('tab-registration').click();
await screen.findByText('name0');
await screen.findByText('Self-Support');
await screen.findByText('Production');
screen.getByTestId('repositories-popover-button').click();
const repotbody = await screen.findByTestId(
'additional-repositories-table'
);
expect(within(repotbody).getAllByRole('row')).toHaveLength(3);
screen.getByTestId('file-system-configuration-popover').click();
const revtbody = await screen.findByTestId(
'file-system-configuration-tbody-review'