webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeCard.js in katello-4.10.0 vs webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeCard.js in katello-4.11.0.rc1

- old
+ new

@@ -1,70 +1,91 @@ import React, { useState } from 'react'; import { useSelector } from 'react-redux'; import PropTypes from 'prop-types'; import { STATUS } from 'foremanReact/constants'; +import { selectAPIStatus } from 'foremanReact/redux/API/APISelectors'; import { Button, Card, CardHeader, CardTitle, CardBody, DescriptionList, DescriptionListGroup, - DescriptionListDescription, - DescriptionListTerm, + DescriptionListDescription as Dd, + DescriptionListTerm as Dt, Flex, FlexItem, GridItem, Label, List, ListItem, Tooltip, Skeleton, + CardExpandableContent, } from '@patternfly/react-core'; import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons'; import { translate as __ } from 'foremanReact/common/I18n'; import { propsToCamelCase } from 'foremanReact/common/helpers'; import './SystemPurposeCard.scss'; import SystemPurposeEditModal from './SystemPurposeEditModal'; import { selectHostDetailsStatus } from '../../HostDetailsSelectors'; import { hasRequiredPermissions, hostIsNotRegistered } from '../../hostDetailsHelpers'; -const SystemPurposeCard = ({ hostDetails }) => { - const showEditButton = hasRequiredPermissions(['edit_hosts'], hostDetails?.permissions); - const { organization_id: orgId, name: hostName } = hostDetails; - const subscriptionFacetAttributes = hostDetails?.subscription_facet_attributes; +const SystemPurposeCard = ({ hostDetails, akDetails }) => { + const sysPurposeCardType = hostDetails?.id ? 'host' : 'ak'; + const isAKType = sysPurposeCardType === 'ak'; + const isHostType = sysPurposeCardType === 'host'; + const details = isHostType ? hostDetails : akDetails; + const requiredPermission = isHostType ? 'edit_hosts' : 'edit_activation_keys'; + const showEditButton = hasRequiredPermissions([requiredPermission], details?.permissions); + const { organization_id: orgId, name } = details; + const subscriptionFacetAttributes = details?.subscription_facet_attributes; const { purposeRole, purposeUsage, purposeAddons, releaseVersion, serviceLevel, - } = propsToCamelCase(subscriptionFacetAttributes ?? {}); + } = propsToCamelCase((subscriptionFacetAttributes || details) ?? {}); const sysPurposeProps = { purposeRole, purposeUsage, purposeAddons, releaseVersion, serviceLevel, }; - const hostDetailsStatus = useSelector(selectHostDetailsStatus); - const dataIsLoading = hostDetailsStatus === STATUS.PENDING; + const selectAKDetailsStatus = state => + selectAPIStatus(state, `ACTIVATION_KEY_${details.id}`) ?? STATUS.PENDING; + const statusSelector = isHostType ? selectHostDetailsStatus : selectAKDetailsStatus; + const detailsStatus = useSelector(statusSelector); + const dataIsLoading = detailsStatus === STATUS.PENDING; + const [editing, setEditing] = useState(false); - if (!hostDetails?.id) { + + const [isExpanded, setIsExpanded] = React.useState(true); + + const onExpand = () => { + setIsExpanded(!isExpanded); + }; + const cardHeaderProps = { + toggleButtonProps: { id: 'sys-purpose-toggle', 'aria-label': 'sys-purpose-toggle' }, + }; + if (isAKType) cardHeaderProps.onExpand = onExpand; + + if (!details?.id) { return ( <GridItem rowSpan={1} md={6} lg={4} xl2={3}> <Card ouiaId="system-purpose-card"> <Skeleton /> </Card> </GridItem> ); } - if (hostIsNotRegistered({ hostDetails })) return null; - + if (isHostType && hostIsNotRegistered({ hostDetails: details })) return null; return ( <GridItem rowSpan={1} md={6} lg={4} xl2={3}> - <Card ouiaId="system-purpose-card"> - <CardHeader> + <Card ouiaId="system-purpose-card" id="system-purpose-card" isExpanded={isHostType ? true : isExpanded}> + <CardHeader {...cardHeaderProps}> <Flex alignItems={{ default: 'alignItemsCenter' }} justifyContent={{ default: 'justifyContentSpaceBetween' }} style={{ width: '100%' }} > @@ -93,62 +114,67 @@ <Button variant="link" isSmall ouiaId="syspurpose-edit-button" onClick={() => setEditing(val => !val)}>{__('Edit')}</Button> </FlexItem>) } </Flex> </CardHeader> - <CardBody className="system-purpose-card-body"> - <DescriptionList isHorizontal> - <DescriptionListGroup> - <DescriptionListTerm>{__('Role')}</DescriptionListTerm> - <DescriptionListDescription> - {dataIsLoading ? <Skeleton /> : purposeRole} - </DescriptionListDescription> - <DescriptionListTerm>{__('SLA')}</DescriptionListTerm> - <DescriptionListDescription> - {serviceLevel && (dataIsLoading ? <Skeleton /> : ( - <Label color="blue">{serviceLevel}</Label> - ))} - </DescriptionListDescription> - <DescriptionListTerm>{__('Usage type')}</DescriptionListTerm> - <DescriptionListDescription> - {purposeUsage && (dataIsLoading ? <Skeleton /> : ( - <Label color="blue">{purposeUsage}</Label> - ))} - </DescriptionListDescription> - <DescriptionListTerm>{__('Release version')}</DescriptionListTerm> - <DescriptionListDescription> - {dataIsLoading ? <Skeleton /> : releaseVersion} - </DescriptionListDescription> - {!!purposeAddons?.length && ( - <> - <DescriptionListTerm>{__('Add-ons')}</DescriptionListTerm> - {dataIsLoading ? <Skeleton /> : ( - <DescriptionListDescription> - <List isPlain> - {purposeAddons.map(addon => ( - <ListItem key={addon}>{addon}</ListItem> - ))} - </List> - </DescriptionListDescription> - )} - </> - ) - } - </DescriptionListGroup> - </DescriptionList> - {showEditButton && ( - <SystemPurposeEditModal - key={hostName} - isOpen={editing} - orgId={orgId} - closeModal={() => setEditing(false)} - hostName={hostName} - hostId={hostDetails.id} - {...sysPurposeProps} - /> - )} - </CardBody> + <CardExpandableContent> + <CardBody className="system-purpose-card-body"> + <DescriptionList isHorizontal columnModifier={isAKType ? { default: '2Col' } : undefined}> + <DescriptionListGroup> + <Dt>{__('Role')}</Dt> + <Dd> + {dataIsLoading ? <Skeleton /> : purposeRole} + </Dd> + <Dt>{__('SLA')}</Dt> + <Dd> + {serviceLevel && (dataIsLoading ? <Skeleton /> : ( + <Label color="blue">{serviceLevel}</Label> + ))} + </Dd> + </DescriptionListGroup> + <DescriptionListGroup> + <Dt>{__('Usage type')}</Dt> + <Dd> + {purposeUsage && (dataIsLoading ? <Skeleton /> : ( + <Label color="blue">{purposeUsage}</Label> + ))} + </Dd> + <Dt>{__('Release version')}</Dt> + <Dd> + {dataIsLoading ? <Skeleton /> : releaseVersion} + </Dd> + {!!purposeAddons?.length && ( + <> + <Dt>{__('Add-ons')}</Dt> + {dataIsLoading ? <Skeleton /> : ( + <Dd> + <List isPlain> + {purposeAddons.map(addon => ( + <ListItem key={addon}>{addon}</ListItem> + ))} + </List> + </Dd> + )} + </> + ) + } + </DescriptionListGroup> + </DescriptionList> + {showEditButton && ( + <SystemPurposeEditModal + key={name} + isOpen={editing} + orgId={orgId} + closeModal={() => setEditing(false)} + name={name} + id={details.id} + {...sysPurposeProps} + type={sysPurposeCardType} + /> + )} + </CardBody> + </CardExpandableContent> </Card> </GridItem> ); }; @@ -165,12 +191,26 @@ }), permissions: PropTypes.shape({ edit_hosts: PropTypes.bool, }), }), + akDetails: PropTypes.shape({ + name: PropTypes.string, + organization_id: PropTypes.number, + id: PropTypes.number, + purpose_usage: PropTypes.string, + purpose_role: PropTypes.string, + release_version: PropTypes.string, + service_level: PropTypes.string, + purpose_addons: PropTypes.arrayOf(PropTypes.string), + permissions: PropTypes.shape({ + edit_activation_keys: PropTypes.bool, + }), + }), }; SystemPurposeCard.defaultProps = { hostDetails: {}, + akDetails: {}, }; export default SystemPurposeCard;