diff --git a/src/Components/CreateImageWizardV2/steps/Registration/ActivationKeyInformation.tsx b/src/Components/CreateImageWizardV2/steps/Registration/ActivationKeyInformation.tsx new file mode 100644 index 00000000..8d72b420 --- /dev/null +++ b/src/Components/CreateImageWizardV2/steps/Registration/ActivationKeyInformation.tsx @@ -0,0 +1,174 @@ +import React, { useContext } from 'react'; + +import { useFormApi } from '@data-driven-forms/react-form-renderer'; +import WizardContext from '@data-driven-forms/react-form-renderer/wizard-context'; +import { + Alert, + Spinner, + Text, + TextContent, + TextList, + TextListItem, + TextListItemVariants, + TextListVariants, + TextVariants, +} from '@patternfly/react-core'; +import { Button, Popover } from '@patternfly/react-core'; +import { HelpIcon } from '@patternfly/react-icons'; +import { Table, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table'; + +import { useShowActivationKeyQuery } from '../../../store/rhsmApi'; + +const ActivationKeyInformation = (): JSX.Element => { + const { getState } = useFormApi(); + const { currentStep } = useContext(WizardContext); + + const activationKey = getState()?.values?.['subscription-activation-key']; + + const { + data: activationKeyInfo, + isFetching: isFetchingActivationKeyInfo, + isSuccess: isSuccessActivationKeyInfo, + isError: isErrorActivationKeyInfo, + } = useShowActivationKeyQuery( + { name: activationKey }, + { + skip: !activationKey, + } + ); + + return ( + <> + {isFetchingActivationKeyInfo && } + {isSuccessActivationKeyInfo && ( + + + + Name: + + + {activationKey} + + + Role: + + + {activationKeyInfo.body?.role || 'Not defined'} + + + SLA: + + + {activationKeyInfo.body?.serviceLevel || 'Not defined'} + + + Usage: + + + {activationKeyInfo.body?.usage || 'Not defined'} + + + Additional repositories: + + + The core repositories for your operating system version + are always enabled and do not need to be explicitly added + to the activation key. + + + } + > + + + + + {activationKeyInfo.body?.additionalRepositories && + activationKeyInfo.body?.additionalRepositories?.length > 0 ? ( + + + Additional repositories + + + + + + + + + {activationKeyInfo.body?.additionalRepositories?.map( + (repo, index) => ( + + + + ) + )} + +
Name
{repo.repositoryLabel}
+ + } + > + +
+ ) : ( + 'None' + )} +
+ + + )} + {isErrorActivationKeyInfo && ( + + + + Name: + + + {activationKey} + + + + )} + {isErrorActivationKeyInfo && currentStep.name === 'registration' && ( + <> +
+ + Information about the activation key cannot be loaded. Please check + the key was not removed and try again later. + + + )} + + ); +}; + +export default ActivationKeyInformation; diff --git a/src/Components/CreateImageWizardV2/steps/Registration/ActivationKeysList.tsx b/src/Components/CreateImageWizardV2/steps/Registration/ActivationKeysList.tsx new file mode 100644 index 00000000..b6bb35ac --- /dev/null +++ b/src/Components/CreateImageWizardV2/steps/Registration/ActivationKeysList.tsx @@ -0,0 +1,199 @@ +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, + 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, + 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. + + + + + + + +); + +EmptyActivationsKeyState.propTypes = { + handleActivationKeyFn: PropTypes.func.isRequired, + isLoading: PropTypes.bool, +}; + +const ActivationKeys = ({ label, isRequired, ...props }) => { + const { isProd } = useGetEnvironment(); + const { change, getState } = useFormApi(); + const { input } = useFieldApi(props); + const [isOpen, setIsOpen] = useState(false); + const [activationKeySelected, selectActivationKey] = useState( + getState()?.values?.['subscription-activation-key'] + ); + + const dispatch = useDispatch(); + + const { + data: activationKeys, + isFetching: isFetchingActivationKeys, + isSuccess: isSuccessActivationKeys, + isError: isErrorActivationKeys, + refetch, + } = useListActivationKeysQuery(); + + const [createActivationKey, { isLoading: isLoadingActivationKey }] = + useCreateActivationKeysMutation(); + useEffect(() => { + if (isProd()) { + change('subscription-server-url', 'subscription.rhsm.redhat.com'); + change('subscription-base-url', 'https://cdn.redhat.com/'); + } else { + change('subscription-server-url', 'subscription.rhsm.stage.redhat.com'); + change('subscription-base-url', 'https://cdn.stage.redhat.com/'); + } + }, [isProd, change]); + + const setActivationKey = (_, selection) => { + selectActivationKey(selection); + setIsOpen(false); + change(input.name, selection); + }; + + const handleClear = () => { + selectActivationKey(); + change(input.name, undefined); + }; + + const handleToggle = () => { + if (!isOpen) { + refetch(); + } + 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 ( + <> + + + + {isErrorActivationKeys && ( + + Activation keys cannot be reached, try again later. + + )} + + ); +}; + +ActivationKeys.propTypes = { + label: PropTypes.node, + isRequired: PropTypes.bool, +}; + +ActivationKeys.defaultProps = { + label: '', + isRequired: false, +}; + +export default ActivationKeys; diff --git a/src/Components/CreateImageWizardV2/steps/Registration/Registration.tsx b/src/Components/CreateImageWizardV2/steps/Registration/Registration.tsx new file mode 100644 index 00000000..13f285b2 --- /dev/null +++ b/src/Components/CreateImageWizardV2/steps/Registration/Registration.tsx @@ -0,0 +1,252 @@ +import React, { useState } from 'react'; + +import { FormSpy } from '@data-driven-forms/react-form-renderer'; +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 { + Button, + Checkbox, + FormGroup, + Popover, + Radio, + Text, + TextContent, +} from '@patternfly/react-core'; +import { HelpIcon, ExternalLinkAltIcon } from '@patternfly/react-icons'; +import PropTypes from 'prop-types'; + +const RHSMPopover = () => { + return ( + + + Registered systems are entitled to support services, errata, + patches, and upgrades. + + + + } + > + + + ); +}; + +const InsightsPopover = () => { + return ( + + + Red Hat Insights client provides actionable intelligence about your + Red Hat Enterprise Linux environments, helping to identify and + address operational and vulnerability risks before an issue results + in downtime. + + + + } + > + + + ); +}; + +const RhcPopover = () => { + return ( + + + Remote host configuration allows Red Hat Enterprise Linux hosts to + connect to Red Hat Insights. Remote host configuration is required + to use the Red Hat Insights Remediations service. + + + + } + > + + + ); +}; + +const Registration = ({ label, ...props }) => { + const { change, getState } = useFormApi(); + const { input } = useFieldApi(props); + const registerSystem = getState()?.values?.['register-system']; + const [showOptions, setShowOptions] = useState( + registerSystem === 'register-now-insights' || + registerSystem === 'register-now' + ); + + return ( + + {() => ( + + + Monitor & manage subscriptions and access to Red Hat content + + + ) + } + data-testid="registration-radio-now" + name="register-system" + id="register-system-now" + isChecked={registerSystem.startsWith('register-now')} + onChange={() => { + change(input.name, 'register-now-rhc'); + }} + description={ + !showOptions && ( + + ) + } + body={ + showOptions && ( + + Enable predictive analytics and management capabilities + + + } + data-testid="registration-checkbox-insights" + isChecked={ + registerSystem === 'register-now-insights' || + registerSystem === 'register-now-rhc' + } + onChange={(_event, checked) => { + if (checked) { + change(input.name, 'register-now-insights'); + } else { + change(input.name, 'register-now'); + } + }} + id="register-system-now-insights" + name="register-system-insights" + body={ + + Enable remote remediations and system management with + automation + + + } + data-testid="registration-checkbox-rhc" + isChecked={registerSystem === 'register-now-rhc'} + onChange={(_event, checked) => { + if (checked) { + change(input.name, 'register-now-rhc'); + } else { + change(input.name, 'register-now-insights'); + } + }} + id="register-system-now-rhc" + name="register-system-rhc" + /> + } + /> + ) + } + /> + { + setShowOptions(false); + change(input.name, 'register-later'); + }} + /> + + )} + + ); +}; + +Registration.propTypes = { + label: PropTypes.node, +}; + +export default Registration; diff --git a/src/Components/CreateImageWizardV2/steps/Registration/RegistrationKeyInformation.tsx b/src/Components/CreateImageWizardV2/steps/Registration/RegistrationKeyInformation.tsx new file mode 100644 index 00000000..e8ea87ed --- /dev/null +++ b/src/Components/CreateImageWizardV2/steps/Registration/RegistrationKeyInformation.tsx @@ -0,0 +1,29 @@ +import React from 'react'; + +import { FormSpy } from '@data-driven-forms/react-form-renderer'; +import { FormGroup } from '@patternfly/react-core'; +import { isEmpty } from 'lodash'; +import PropTypes from 'prop-types'; + +import ActivationKeyInformation from './ActivationKeyInformation'; + +const RegistrationKeyInformation = ({ label, valueReference }) => { + return ( + + {({ values }) => + isEmpty(values[valueReference]) ? null : ( + + + + ) + } + + ); +}; + +RegistrationKeyInformation.propTypes = { + label: PropTypes.node, + valueReference: PropTypes.node, +}; + +export default RegistrationKeyInformation;