diff --git a/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostList.jsx b/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostList.jsx index 6ebe0778d7..562f717f95 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostList.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostList.jsx @@ -14,7 +14,10 @@ import useSelected from '../../../util/useSelected'; import AlertModal from '../../../components/AlertModal'; import DataListToolbar from '../../../components/DataListToolbar'; import ErrorDetail from '../../../components/ErrorDetail'; -import PaginatedDataList from '../../../components/PaginatedDataList'; +import PaginatedTable, { + HeaderCell, + HeaderRow, +} from '../../../components/PaginatedTable'; import AssociateModal from '../../../components/AssociateModal'; import DisassociateButton from '../../../components/DisassociateButton'; import AdHocCommands from '../../../components/AdHocCommands/AdHocCommands'; @@ -172,7 +175,7 @@ function InventoryGroupHostList() { ); return ( <> - + {t`Name`} + {t`Activity`} + {t`Actions`} + + } toolbarSearchableKeys={searchableKeys} toolbarRelatedSearchableKeys={relatedSearchableKeys} renderToolbar={props => ( @@ -235,14 +245,15 @@ function InventoryGroupHostList() { ]} /> )} - renderItem={o => ( + renderRow={(host, index) => ( row.id === o.id)} - onSelect={() => handleSelect(o)} + key={host.id} + rowIndex={index} + host={host} + detailUrl={`/inventories/inventory/${inventoryId}/hosts/${host.id}/details`} + editUrl={`/inventories/inventory/${inventoryId}/hosts/${host.id}/edit`} + isSelected={selected.some(row => row.id === host.id)} + onSelect={() => handleSelect(host)} /> )} emptyStateControls={canAdd && addButton} diff --git a/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostList.test.jsx b/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostList.test.jsx index c48baf955e..0ff7be6cc5 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostList.test.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostList.test.jsx @@ -58,21 +58,21 @@ describe('', () => { test('should check and uncheck the row item', async () => { expect( - wrapper.find('DataListCheck[id="select-host-2"]').props().checked + wrapper.find('input[aria-label="Select row 2"]').props().checked ).toBe(false); await act(async () => { - wrapper.find('DataListCheck[id="select-host-2"]').invoke('onChange')(); + wrapper.find('input[aria-label="Select row 2"]').invoke('onChange')(); }); wrapper.update(); expect( - wrapper.find('DataListCheck[id="select-host-2"]').props().checked + wrapper.find('input[aria-label="Select row 2"]').props().checked ).toBe(true); await act(async () => { - wrapper.find('DataListCheck[id="select-host-2"]').invoke('onChange')(); + wrapper.find('input[aria-label="Select row 2"]').invoke('onChange')(); }); wrapper.update(); expect( - wrapper.find('DataListCheck[id="select-host-2"]').props().checked + wrapper.find('input[aria-label="Select row 2"]').props().checked ).toBe(false); }); diff --git a/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostListItem.jsx b/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostListItem.jsx index e68da5542c..5ca57fd662 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostListItem.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostListItem.jsx @@ -1,38 +1,22 @@ import 'styled-components/macro'; import React from 'react'; import { Link } from 'react-router-dom'; -import { string, bool, func } from 'prop-types'; - +import { string, bool, func, number } from 'prop-types'; import { t } from '@lingui/macro'; - -import { - Button, - DataListAction as _DataListAction, - DataListCheck, - DataListItem, - DataListItemCells, - DataListItemRow, - Tooltip, -} from '@patternfly/react-core'; +import { Button, Tooltip } from '@patternfly/react-core'; import { PencilAltIcon } from '@patternfly/react-icons'; -import styled from 'styled-components'; -import DataListCell from '../../../components/DataListCell'; +import { Td, Tr } from '@patternfly/react-table'; +import { ActionItem, ActionsTd } from '../../../components/PaginatedTable'; import HostToggle from '../../../components/HostToggle'; import Sparkline from '../../../components/Sparkline'; import { Host } from '../../../types'; -const DataListAction = styled(_DataListAction)` - align-items: center; - display: grid; - grid-gap: 24px; - grid-template-columns: min-content 40px; -`; - function InventoryGroupHostListItem({ detailUrl, editUrl, host, + rowIndex, isSelected, onSelect, }) { @@ -44,55 +28,55 @@ function InventoryGroupHostListItem({ const labelId = `check-action-${host.id}`; return ( - - - - - - {host.name} - - , - - - , - ]} - /> - + + + + {host.name} + + + + + + + - - {host.summary_fields.user_capabilities?.edit && ( - - - - )} - - - + + + + + + + + + ); } InventoryGroupHostListItem.propTypes = { detailUrl: string.isRequired, editUrl: string.isRequired, + rowIndex: number.isRequired, host: Host.isRequired, isSelected: bool.isRequired, onSelect: func.isRequired, diff --git a/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostListItem.test.jsx b/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostListItem.test.jsx index d16173868e..c5225346fb 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostListItem.test.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryGroupHosts/InventoryGroupHostListItem.test.jsx @@ -17,6 +17,7 @@ describe('', () => { host={mockHost} isSelected={false} onSelect={() => {}} + rowIndex={0} /> ); }); @@ -26,12 +27,9 @@ describe('', () => { }); test('should display expected row item content', () => { - expect( - wrapper - .find('DataListCell') - .first() - .text() - ).toBe('.host-000001.group-00000.dummy'); + expect(wrapper.find('b').text()).toContain( + '.host-000001.group-00000.dummy' + ); expect(wrapper.find('Sparkline').length).toBe(1); expect(wrapper.find('HostToggle').length).toBe(1); }); @@ -50,6 +48,7 @@ describe('', () => { host={mockHost} isSelected={false} onSelect={() => {}} + rowIndex={0} /> ); expect(wrapper.find('PencilAltIcon').exists()).toBeFalsy(); diff --git a/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupList.jsx b/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupList.jsx index 1074e616fc..f435d4b745 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupList.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupList.jsx @@ -10,7 +10,10 @@ import { getQSConfig, parseQueryString, mergeParams } from '../../../util/qs'; import useSelected from '../../../util/useSelected'; import DataListToolbar from '../../../components/DataListToolbar'; -import PaginatedDataList from '../../../components/PaginatedDataList'; +import PaginatedTable, { + HeaderCell, + HeaderRow, +} from '../../../components/PaginatedTable'; import InventoryGroupRelatedGroupListItem from './InventoryRelatedGroupListItem'; import AddDropDownButton from '../../../components/AddDropDownButton'; import AdHocCommands from '../../../components/AdHocCommands/AdHocCommands'; @@ -131,6 +134,7 @@ function InventoryRelatedGroupList() { const addButton = ( , - )} - renderItem={o => ( + headerRow={ + + {t`Name`} + {t`Actions`} + + } + renderRow={(group, index) => ( row.id === o.id)} - onSelect={() => handleSelect(o)} + key={group.id} + rowIndex={index} + group={group} + detailUrl={`/inventories/inventory/${inventoryId}/groups/${group.id}/details`} + editUrl={`/inventories/inventory/${inventoryId}/groups/${group.id}/edit`} + isSelected={selected.some(row => row.id === group.id)} + onSelect={() => handleSelect(group)} /> )} emptyStateControls={canAdd && addButton} diff --git a/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupList.test.jsx b/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupList.test.jsx index e3879c560a..277a53413e 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupList.test.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupList.test.jsx @@ -110,21 +110,21 @@ describe('', () => { test('should check and uncheck the row item', async () => { expect( - wrapper.find('DataListCheck[id="select-group-2"]').props().checked + wrapper.find('input[aria-label="Select row 0"]').props().checked ).toBe(false); await act(async () => { - wrapper.find('DataListCheck[id="select-group-2"]').invoke('onChange')(); + wrapper.find('input[aria-label="Select row 0"]').invoke('onChange')(); }); wrapper.update(); expect( - wrapper.find('DataListCheck[id="select-group-2"]').props().checked + wrapper.find('input[aria-label="Select row 0"]').props().checked ).toBe(true); await act(async () => { - wrapper.find('DataListCheck[id="select-group-2"]').invoke('onChange')(); + wrapper.find('input[aria-label="Select row 0"]').invoke('onChange')(); }); wrapper.update(); expect( - wrapper.find('DataListCheck[id="select-group-2"]').props().checked + wrapper.find('input[aria-label="Select row 0"]').props().checked ).toBe(false); }); diff --git a/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupListItem.jsx b/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupListItem.jsx index 3c3c03a3d0..8cbe5f6b17 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupListItem.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupListItem.jsx @@ -1,81 +1,59 @@ import 'styled-components/macro'; import React from 'react'; import { Link } from 'react-router-dom'; -import { string, bool, func } from 'prop-types'; +import { string, bool, func, number } from 'prop-types'; import { t } from '@lingui/macro'; -import { - Button, - DataListAction as _DataListAction, - DataListCheck, - DataListItem, - DataListItemCells, - DataListItemRow, - Tooltip, -} from '@patternfly/react-core'; +import { Td, Tr } from '@patternfly/react-table'; +import { Button } from '@patternfly/react-core'; import { PencilAltIcon } from '@patternfly/react-icons'; -import styled from 'styled-components'; -import DataListCell from '../../../components/DataListCell'; import { Group } from '../../../types'; - -const DataListAction = styled(_DataListAction)` - align-items: center; - display: grid; - grid-gap: 24px; - grid-template-columns: min-content 40px; -`; +import { ActionItem, ActionsTd } from '../../../components/PaginatedTable'; function InventoryRelatedGroupListItem({ detailUrl, editUrl, group, + rowIndex, isSelected, onSelect, }) { const labelId = `check-action-${group.id}`; return ( - - - - - - {group.name} - - , - ]} - /> - + + + + {group.name} + + + + - {group.summary_fields.user_capabilities?.edit && ( - - - - )} - - - + + + + ); } @@ -83,6 +61,7 @@ InventoryRelatedGroupListItem.propTypes = { detailUrl: string.isRequired, editUrl: string.isRequired, group: Group.isRequired, + rowIndex: number.isRequired, isSelected: bool.isRequired, onSelect: func.isRequired, }; diff --git a/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupListItem.test.jsx b/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupListItem.test.jsx index f52eaad866..bafe3524af 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupListItem.test.jsx +++ b/awx/ui_next/src/screens/Inventory/InventoryRelatedGroups/InventoryRelatedGroupListItem.test.jsx @@ -17,6 +17,7 @@ describe('', () => { group={mockGroup} isSelected={false} onSelect={() => {}} + rowIndex={0} /> ); }); @@ -26,12 +27,7 @@ describe('', () => { }); test('should display expected row item content', () => { - expect( - wrapper - .find('DataListCell') - .first() - .text() - ).toBe(' Group 2 Inventory 0'); + expect(wrapper.find('b').text()).toContain('Group 2 Inventory 0'); }); test('edit button shown to users with edit capabilities', () => { @@ -46,6 +42,7 @@ describe('', () => { group={mockRelatedGroups.results[2]} isSelected={false} onSelect={() => {}} + rowIndex={0} /> ); expect(wrapper.find('PencilAltIcon').exists()).toBeFalsy();