diff --git a/api/config/rhsm.ts b/api/config/rhsm.ts
index d2b362a1..5626d8b9 100644
--- a/api/config/rhsm.ts
+++ b/api/config/rhsm.ts
@@ -7,7 +7,7 @@ const config: ConfigFile = {
outputFile: '../../src/store/rhsmApi.ts',
exportName: 'rhsmApi',
hooks: true,
- filterEndpoints: ['listActivationKeys', 'showActivationKey'],
+ filterEndpoints: ['listActivationKeys', 'showActivationKey', 'createActivationKeys'],
};
export default config;
diff --git a/src/Components/CreateImageWizard/formComponents/ActivationKeys.js b/src/Components/CreateImageWizard/formComponents/ActivationKeys.js
index 7287f8d7..1b798d7b 100644
--- a/src/Components/CreateImageWizard/formComponents/ActivationKeys.js
+++ b/src/Components/CreateImageWizard/formComponents/ActivationKeys.js
@@ -2,17 +2,66 @@ import React, { useEffect, useState } from 'react';
import useFieldApi from '@data-driven-forms/react-form-renderer/use-field-api';
import useFormApi from '@data-driven-forms/react-form-renderer/use-form-api';
-import { Alert, FormGroup, Spinner } from '@patternfly/react-core';
+import {
+ Alert,
+ FormGroup,
+ Spinner,
+ EmptyState,
+ Button,
+ EmptyStateIcon,
+ EmptyStateBody,
+ EmptyStateHeader,
+ EmptyStateFooter,
+ EmptyStateActions,
+} from '@patternfly/react-core';
import {
Select,
SelectOption,
SelectVariant,
} from '@patternfly/react-core/deprecated';
+import { WrenchIcon, AddCircleOIcon } from '@patternfly/react-icons';
+import { addNotification } from '@redhat-cloud-services/frontend-components-notifications/redux';
import PropTypes from 'prop-types';
+import { useDispatch } from 'react-redux';
-import { useListActivationKeysQuery } from '../../../store/rhsmApi';
+import {
+ useListActivationKeysQuery,
+ useCreateActivationKeysMutation,
+} from '../../../store/rhsmApi';
import { useGetEnvironment } from '../../../Utilities/useGetEnvironment';
+const EmptyActivationsKeyState = ({ handleActivationKeyFn, isLoading }) => (
+
+ }
+ />
+
+ Get started by building a default key, which will be generated and present
+ for you.
+
+
+
+ }
+ isLoading={isLoading}
+ iconPosition="left"
+ variant="link"
+ >
+ Create activation key
+
+
+
+
+);
+
+EmptyActivationsKeyState.propTypes = {
+ handleActivationKeyFn: PropTypes.func.isRequired,
+ isLoading: PropTypes.bool,
+};
+
const ActivationKeys = ({ label, isRequired, ...props }) => {
const { isProd } = useGetEnvironment();
const { change, getState } = useFormApi();
@@ -22,6 +71,8 @@ const ActivationKeys = ({ label, isRequired, ...props }) => {
getState()?.values?.['subscription-activation-key']
);
+ const dispatch = useDispatch();
+
const {
data: activationKeys,
isFetching: isFetchingActivationKeys,
@@ -30,6 +81,8 @@ const ActivationKeys = ({ label, isRequired, ...props }) => {
refetch,
} = useListActivationKeysQuery();
+ const [createActivationKey, { isLoading: isLoadingActivationKey }] =
+ useCreateActivationKeysMutation();
useEffect(() => {
if (isProd()) {
change('subscription-server-url', 'subscription.rhsm.redhat.com');
@@ -58,6 +111,28 @@ const ActivationKeys = ({ label, isRequired, ...props }) => {
setIsOpen(!isOpen);
};
+ const handleCreateActivationKey = async () => {
+ const res = await createActivationKey({
+ body: {
+ name: 'activation-key-default',
+ serviceLevel: 'Self-Support',
+ },
+ });
+ refetch();
+ if (res.error) {
+ dispatch(
+ addNotification({
+ variant: 'danger',
+ title: 'Error creating activation key',
+ description: res.error?.data?.error?.message,
+ })
+ );
+ }
+ };
+
+ const isActivationKeysEmpty =
+ isSuccessActivationKeys && activationKeys.body.length === 0;
+
return (
<>
{
typeAheadAriaLabel="Select activation key"
isDisabled={!isSuccessActivationKeys}
>
+ {isActivationKeysEmpty && (
+
+ )}
{isSuccessActivationKeys &&
activationKeys.body.map((key, index) => (
))}
- {isFetchingActivationKeys && (
+ {!isSuccessActivationKeys && isFetchingActivationKeys && (
}
- iconPosition="right"
- isInline
- href="https://console.redhat.com/insights/connector/activation-keys"
- >
- Create and manage activation keys here
-
+
+ By default, activation key is generated and preset for you. Admins can
+ create and manage keys by visiting the
+ }
+ iconPosition="right"
+ isInline
+ href="https://console.redhat.com/insights/connector/activation-keys"
+ >
+ Activation keys page
+
+
),
condition: {
or: [
diff --git a/src/store/rhsmApi.ts b/src/store/rhsmApi.ts
index 84c028de..19440440 100644
--- a/src/store/rhsmApi.ts
+++ b/src/store/rhsmApi.ts
@@ -7,6 +7,16 @@ const injectedRtkApi = api.injectEndpoints({
>({
query: () => ({ url: `/activation_keys` }),
}),
+ createActivationKeys: build.mutation<
+ CreateActivationKeysApiResponse,
+ CreateActivationKeysApiArg
+ >({
+ query: (queryArg) => ({
+ url: `/activation_keys`,
+ method: "POST",
+ body: queryArg.body,
+ }),
+ }),
showActivationKey: build.query<
ShowActivationKeyApiResponse,
ShowActivationKeyApiArg
@@ -22,6 +32,22 @@ export type ListActivationKeysApiResponse =
body?: ActivationKeys[];
};
export type ListActivationKeysApiArg = void;
+export type CreateActivationKeysApiResponse = /** status 200 Activation key */ {
+ body?: ActivationKeys;
+};
+export type CreateActivationKeysApiArg = {
+ /** Create an activation key */
+ body: {
+ additionalRepositories?: {
+ repositoryLabel?: string;
+ }[];
+ name: string;
+ releaseVersion?: string;
+ role?: string;
+ serviceLevel?: string;
+ usage?: string;
+ };
+};
export type ShowActivationKeyApiResponse = /** status 200 Activation key */ {
body?: ActivationKeys;
};
@@ -45,5 +71,8 @@ export type ErrorDetails = {
code?: number;
message?: string;
};
-export const { useListActivationKeysQuery, useShowActivationKeyQuery } =
- injectedRtkApi;
+export const {
+ useListActivationKeysQuery,
+ useCreateActivationKeysMutation,
+ useShowActivationKeyQuery,
+} = injectedRtkApi;
diff --git a/src/test/Components/CreateImageWizard/CreateImageWizard.test.js b/src/test/Components/CreateImageWizard/CreateImageWizard.test.js
index f7b6ab98..5b4b075f 100644
--- a/src/test/Components/CreateImageWizard/CreateImageWizard.test.js
+++ b/src/test/Components/CreateImageWizard/CreateImageWizard.test.js
@@ -13,7 +13,7 @@ import { rest } from 'msw';
import CreateImageWizard from '../../../Components/CreateImageWizard/CreateImageWizard';
import ShareImageModal from '../../../Components/ShareImageModal/ShareImageModal';
-import { PROVISIONING_API } from '../../../constants.js';
+import { PROVISIONING_API, RHSM_API } from '../../../constants.js';
import { server } from '../../mocks/server.js';
import {
clickBack,
@@ -574,6 +574,20 @@ describe('Step Registration', () => {
await verifyCancelButton(router);
});
+ test('activation key dropdown empty state', async () => {
+ server.use(
+ rest.get(`${RHSM_API}/activation_keys`, (req, res, ctx) =>
+ res(ctx.status(200), ctx.json({ body: [] }))
+ )
+ );
+ await setUp();
+ const activationKeyDropdown = await screen.findByRole('textbox', {
+ name: 'Select activation key',
+ });
+ await user.click(activationKeyDropdown);
+ await screen.findByText('No activation keys found');
+ });
+
test('should allow registering with rhc', async () => {
await setUp();