diff --git a/awx/ui/src/components/InstanceGroupLabels/InstanceGroupLabels.js b/awx/ui/src/components/InstanceGroupLabels/InstanceGroupLabels.js new file mode 100644 index 0000000000..e3d89f9285 --- /dev/null +++ b/awx/ui/src/components/InstanceGroupLabels/InstanceGroupLabels.js @@ -0,0 +1,49 @@ +import React from 'react'; +import { arrayOf, bool, number, shape, string } from 'prop-types'; + +import { Label, LabelGroup } from '@patternfly/react-core'; +import { Link } from 'react-router-dom'; + +function InstanceGroupLabels({ labels, isLinkable }) { + const buildLinkURL = (isContainerGroup) => + isContainerGroup + ? '/instance_groups/container_group/' + : '/instance_groups/'; + return ( + + {labels.map(({ id, name, is_container_group }) => + isLinkable ? ( + + ) : ( + + ) + )} + + ); +} + +InstanceGroupLabels.propTypes = { + labels: arrayOf(shape({ id: number.isRequired, name: string.isRequired })) + .isRequired, + isLinkable: bool, +}; + +InstanceGroupLabels.defaultProps = { isLinkable: false }; + +export default InstanceGroupLabels; diff --git a/awx/ui/src/components/InstanceGroupLabels/index.js b/awx/ui/src/components/InstanceGroupLabels/index.js new file mode 100644 index 0000000000..206daf03f2 --- /dev/null +++ b/awx/ui/src/components/InstanceGroupLabels/index.js @@ -0,0 +1 @@ +export { default } from './InstanceGroupLabels'; diff --git a/awx/ui/src/components/PromptDetail/PromptDetail.js b/awx/ui/src/components/PromptDetail/PromptDetail.js index 7122e6a63d..adb09b55f2 100644 --- a/awx/ui/src/components/PromptDetail/PromptDetail.js +++ b/awx/ui/src/components/PromptDetail/PromptDetail.js @@ -6,6 +6,7 @@ import { Link } from 'react-router-dom'; import styled from 'styled-components'; import { Chip, Divider, Title } from '@patternfly/react-core'; import { toTitleCase } from 'util/strings'; +import InstanceGroupLabels from 'components/InstanceGroupLabels'; import CredentialChip from '../CredentialChip'; import ChipGroup from '../ChipGroup'; import { DetailList, Detail, UserDateDetail } from '../DetailList'; @@ -227,21 +228,7 @@ function PromptDetail({ label={t`Instance Groups`} rows={4} value={ - - {overrides.instance_groups.map((instance_group) => ( - - {instance_group.name} - - ))} - + } /> )} diff --git a/awx/ui/src/components/Schedule/ScheduleDetail/ScheduleDetail.js b/awx/ui/src/components/Schedule/ScheduleDetail/ScheduleDetail.js index a5650ac238..074cca4fa5 100644 --- a/awx/ui/src/components/Schedule/ScheduleDetail/ScheduleDetail.js +++ b/awx/ui/src/components/Schedule/ScheduleDetail/ScheduleDetail.js @@ -10,6 +10,7 @@ import useRequest, { useDismissableError } from 'hooks/useRequest'; import { JobTemplatesAPI, SchedulesAPI, WorkflowJobTemplatesAPI } from 'api'; import { parseVariableField, jsonToYaml } from 'util/yaml'; import { useConfig } from 'contexts/Config'; +import InstanceGroupLabels from 'components/InstanceGroupLabels'; import parseRuleObj from '../shared/parseRuleObj'; import FrequencyDetails from './FrequencyDetails'; import AlertModal from '../../AlertModal'; @@ -27,11 +28,6 @@ import { VariablesDetail } from '../../CodeEditor'; import { VERBOSITY } from '../../VerbositySelectField'; import getHelpText from '../../../screens/Template/shared/JobTemplate.helptext'; -const buildLinkURL = (instance) => - instance.is_container_group - ? '/instance_groups/container_group/' - : '/instance_groups/'; - const PromptDivider = styled(Divider)` margin-top: var(--pf-global--spacer--lg); margin-bottom: var(--pf-global--spacer--lg); @@ -498,26 +494,7 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, surveyConfig }) { fullWidth label={t`Instance Groups`} value={ - - {instanceGroups.map((ig) => ( - - - {ig.name} - - - ))} - + } isEmpty={instanceGroups.length === 0} /> diff --git a/awx/ui/src/screens/Instances/InstanceDetail/InstanceDetail.js b/awx/ui/src/screens/Instances/InstanceDetail/InstanceDetail.js index 1b96fb30e9..7d727a1c88 100644 --- a/awx/ui/src/screens/Instances/InstanceDetail/InstanceDetail.js +++ b/awx/ui/src/screens/Instances/InstanceDetail/InstanceDetail.js @@ -1,6 +1,6 @@ import React, { useCallback, useEffect, useState } from 'react'; -import { Link, useHistory, useParams } from 'react-router-dom'; +import { useHistory, useParams } from 'react-router-dom'; import { t, Plural } from '@lingui/macro'; import { Button, @@ -11,7 +11,6 @@ import { CodeBlockCode, Tooltip, Slider, - Label, } from '@patternfly/react-core'; import { DownloadIcon, OutlinedClockIcon } from '@patternfly/react-icons'; import styled from 'styled-components'; @@ -34,6 +33,7 @@ import useRequest, { useDismissableError, } from 'hooks/useRequest'; import HealthCheckAlert from 'components/HealthCheckAlert'; +import InstanceGroupLabels from 'components/InstanceGroupLabels'; import RemoveInstanceButton from '../Shared/RemoveInstanceButton'; const Unavailable = styled.span` @@ -156,11 +156,6 @@ function InstanceDetail({ setBreadcrumb, isK8s }) { ); - const buildLinkURL = (inst) => - inst.is_container_group - ? '/instance_groups/container_group/' - : '/instance_groups/'; - const { error, dismissError } = useDismissableError( updateInstanceError || healthCheckError ); @@ -225,25 +220,9 @@ function InstanceDetail({ setBreadcrumb, isK8s }) { label={t`Instance Groups`} dataCy="instance-groups" helpText={t`The Instance Groups to which this instance belongs.`} - value={instanceGroups.map((ig) => ( - - {' '} - - ))} + value={ + + } isEmpty={instanceGroups.length === 0} /> )} diff --git a/awx/ui/src/screens/Inventory/InventoryDetail/InventoryDetail.js b/awx/ui/src/screens/Inventory/InventoryDetail/InventoryDetail.js index 6944707a6d..0dd7803415 100644 --- a/awx/ui/src/screens/Inventory/InventoryDetail/InventoryDetail.js +++ b/awx/ui/src/screens/Inventory/InventoryDetail/InventoryDetail.js @@ -23,6 +23,7 @@ import { InventoriesAPI } from 'api'; import useRequest, { useDismissableError } from 'hooks/useRequest'; import { Inventory } from 'types'; import { relatedResourceDeleteRequests } from 'util/getRelatedResourceDeleteDetails'; +import InstanceGroupLabels from 'components/InstanceGroupLabels'; import getHelpText from '../shared/Inventory.helptext'; function InventoryDetail({ inventory }) { @@ -105,23 +106,7 @@ function InventoryDetail({ inventory }) { - {instanceGroups?.map((ig) => ( - - {ig.name} - - ))} - - } + value={} isEmpty={instanceGroups.length === 0} /> )} diff --git a/awx/ui/src/screens/Inventory/InventoryDetail/InventoryDetail.test.js b/awx/ui/src/screens/Inventory/InventoryDetail/InventoryDetail.test.js index f22d9b3cb3..153c78d8ba 100644 --- a/awx/ui/src/screens/Inventory/InventoryDetail/InventoryDetail.test.js +++ b/awx/ui/src/screens/Inventory/InventoryDetail/InventoryDetail.test.js @@ -131,9 +131,8 @@ describe('', () => { expect(InventoriesAPI.readInstanceGroups).toHaveBeenCalledWith( mockInventory.id ); - const chip = wrapper.find('Chip').at(0); - expect(chip.prop('isReadOnly')).toEqual(true); - expect(chip.prop('children')).toEqual('Foo'); + const label = wrapper.find('Label').at(0); + expect(label.prop('children')).toEqual('Foo'); }); test('should not load instance groups', async () => { diff --git a/awx/ui/src/screens/Inventory/SmartInventoryDetail/SmartInventoryDetail.js b/awx/ui/src/screens/Inventory/SmartInventoryDetail/SmartInventoryDetail.js index e91e22b116..f738ed96c9 100644 --- a/awx/ui/src/screens/Inventory/SmartInventoryDetail/SmartInventoryDetail.js +++ b/awx/ui/src/screens/Inventory/SmartInventoryDetail/SmartInventoryDetail.js @@ -2,7 +2,7 @@ import React, { useCallback, useEffect } from 'react'; import { Link, useHistory } from 'react-router-dom'; import { t } from '@lingui/macro'; -import { Button, Chip, Label } from '@patternfly/react-core'; +import { Button, Label } from '@patternfly/react-core'; import { Inventory } from 'types'; import { InventoriesAPI, UnifiedJobsAPI } from 'api'; @@ -10,7 +10,6 @@ import useRequest, { useDismissableError } from 'hooks/useRequest'; import AlertModal from 'components/AlertModal'; import { CardBody, CardActionsRow } from 'components/Card'; -import ChipGroup from 'components/ChipGroup'; import { VariablesDetail } from 'components/CodeEditor'; import ContentError from 'components/ContentError'; import ContentLoading from 'components/ContentLoading'; @@ -18,6 +17,7 @@ import DeleteButton from 'components/DeleteButton'; import { DetailList, Detail, UserDateDetail } from 'components/DetailList'; import ErrorDetail from 'components/ErrorDetail'; import Sparkline from 'components/Sparkline'; +import InstanceGroupLabels from 'components/InstanceGroupLabels'; function SmartInventoryDetail({ inventory }) { const history = useHistory(); @@ -120,23 +120,7 @@ function SmartInventoryDetail({ inventory }) { - {instanceGroups.map((ig) => ( - - {ig.name} - - ))} - - } + value={} isEmpty={instanceGroups.length === 0} /> ; } - const buildLinkURL = (instance) => - instance.is_container_group - ? '/instance_groups/container_group/' - : '/instance_groups/'; - return ( @@ -126,25 +122,7 @@ function OrganizationDetail({ organization }) { fullWidth label={t`Instance Groups`} helpText={t`The Instance Groups for this Organization to run on.`} - value={ - - {instanceGroups.map((ig) => ( - - - {ig.name} - - - ))} - - } + value={} isEmpty={instanceGroups.length === 0} /> )} diff --git a/awx/ui/src/screens/Organization/OrganizationDetail/OrganizationDetail.test.js b/awx/ui/src/screens/Organization/OrganizationDetail/OrganizationDetail.test.js index 5141a198f8..be70bf7519 100644 --- a/awx/ui/src/screens/Organization/OrganizationDetail/OrganizationDetail.test.js +++ b/awx/ui/src/screens/Organization/OrganizationDetail/OrganizationDetail.test.js @@ -90,7 +90,7 @@ describe('', () => { await waitForElement(component, 'ContentLoading', (el) => el.length === 0); expect( component - .find('Chip') + .find('Label') .findWhere((el) => el.text() === 'One') .exists() ).toBe(true); diff --git a/awx/ui/src/screens/Template/JobTemplateDetail/JobTemplateDetail.js b/awx/ui/src/screens/Template/JobTemplateDetail/JobTemplateDetail.js index dd5fdc837a..256d4208ea 100644 --- a/awx/ui/src/screens/Template/JobTemplateDetail/JobTemplateDetail.js +++ b/awx/ui/src/screens/Template/JobTemplateDetail/JobTemplateDetail.js @@ -34,6 +34,7 @@ import useRequest, { useDismissableError } from 'hooks/useRequest'; import useBrandName from 'hooks/useBrandName'; import ExecutionEnvironmentDetail from 'components/ExecutionEnvironmentDetail'; import { relatedResourceDeleteRequests } from 'util/getRelatedResourceDeleteDetails'; +import InstanceGroupLabels from 'components/InstanceGroupLabels'; import getHelpText from '../shared/JobTemplate.helptext'; function JobTemplateDetail({ template }) { @@ -167,11 +168,6 @@ function JobTemplateDetail({ template }) { ); }; - const buildLinkURL = (instance) => - instance.is_container_group - ? '/instance_groups/container_group/' - : '/instance_groups/'; - if (instanceGroupsError) { return ; } @@ -422,25 +418,7 @@ function JobTemplateDetail({ template }) { label={t`Instance Groups`} dataCy="jt-detail-instance-groups" helpText={helpText.instanceGroups} - value={ - - {instanceGroups.map((ig) => ( - - - {ig.name} - - - ))} - - } + value={} isEmpty={instanceGroups.length === 0} /> {job_tags && (