From a481fc3cc9434caa64b0a9d9599db705d9ca3975 Mon Sep 17 00:00:00 2001 From: Keith Grant Date: Fri, 29 Jan 2021 15:41:20 -0800 Subject: [PATCH] convert instance group list to tables --- .../InstanceGroupList/InstanceGroupList.jsx | 24 ++- .../InstanceGroupList.test.jsx | 42 +++-- .../InstanceGroupListItem.jsx | 169 +++++------------- .../InstanceGroupListItem.test.jsx | 124 +++++++------ 4 files changed, 166 insertions(+), 193 deletions(-) diff --git a/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupList.jsx b/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupList.jsx index 6b3b43f637..5e1994f640 100644 --- a/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupList.jsx +++ b/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupList.jsx @@ -8,9 +8,11 @@ import { InstanceGroupsAPI } from '../../../api'; import { getQSConfig, parseQueryString } from '../../../util/qs'; import useRequest, { useDeleteItems } from '../../../util/useRequest'; import useSelected from '../../../util/useSelected'; -import PaginatedDataList, { - ToolbarDeleteButton, -} from '../../../components/PaginatedDataList'; +import PaginatedTable, { + HeaderRow, + HeaderCell, +} from '../../../components/PaginatedTable'; +import { ToolbarDeleteButton } from '../../../components/PaginatedDataList'; import ErrorDetail from '../../../components/ErrorDetail'; import AlertModal from '../../../components/AlertModal'; import DatalistToolbar from '../../../components/DataListToolbar'; @@ -189,7 +191,7 @@ function InstanceGroupList({ i18n }) { <> - )} - renderItem={instanceGroup => ( + headerRow={ + + {i18n._(t`Name`)} + {i18n._(t`Type`)} + {i18n._(t`Running Jobs`)} + {i18n._(t`Total Jobs`)} + {i18n._(t`Instances`)} + {i18n._(t`Capacity`)} + {i18n._(t`Actions`)} + + } + renderRow={(instanceGroup, index) => ( handleSelect(instanceGroup)} isSelected={selected.some(row => row.id === instanceGroup.id)} + rowIndex={index} /> )} emptyStateControls={canAdd && addButton} diff --git a/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupList.test.jsx b/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupList.test.jsx index 335089e4bc..74f397dc1c 100644 --- a/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupList.test.jsx +++ b/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupList.test.jsx @@ -71,13 +71,19 @@ describe('', () => { await waitForElement(wrapper, 'InstanceGroupList', el => el.length > 0); wrapper - .find('input#select-instance-groups-1') + .find('.pf-c-table__check') + .first() + .find('input') .simulate('change', instanceGroups); wrapper.update(); - expect(wrapper.find('input#select-instance-groups-1').prop('checked')).toBe( - true - ); + expect( + wrapper + .find('.pf-c-table__check') + .first() + .find('input') + .prop('checked') + ).toBe(true); await act(async () => { wrapper.find('Button[aria-label="Delete"]').prop('onClick')(); @@ -102,16 +108,22 @@ describe('', () => { }); await waitForElement(wrapper, 'InstanceGroupList', el => el.length > 0); - const instanceGroupIndex = [1, 2, 3]; + const instanceGroupIndex = [0, 1, 2]; instanceGroupIndex.forEach(element => { wrapper - .find(`input#select-instance-groups-${element}`) + .find('.pf-c-table__check') + .at(element) + .find('input') .simulate('change', instanceGroups); wrapper.update(); expect( - wrapper.find(`input#select-instance-groups-${element}`).prop('checked') + wrapper + .find('.pf-c-table__check') + .at(element) + .find('input') + .prop('checked') ).toBe(true); }); @@ -159,11 +171,19 @@ describe('', () => { }); waitForElement(wrapper, 'InstanceGroupList', el => el.length > 0); - wrapper.find('input#select-instance-groups-1').simulate('change', 'a'); + wrapper + .find('.pf-c-table__check') + .first() + .find('input') + .simulate('change', 'a'); wrapper.update(); - expect(wrapper.find('input#select-instance-groups-1').prop('checked')).toBe( - true - ); + expect( + wrapper + .find('.pf-c-table__check') + .first() + .find('input') + .prop('checked') + ).toBe(true); await act(async () => wrapper.find('Button[aria-label="Delete"]').prop('onClick')() diff --git a/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupListItem.jsx b/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupListItem.jsx index 670835c405..8bfcf05325 100644 --- a/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupListItem.jsx +++ b/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupListItem.jsx @@ -5,48 +5,18 @@ import { t } from '@lingui/macro'; import { Link } from 'react-router-dom'; import 'styled-components/macro'; import { - Badge as PFBadge, Button, - DataListAction as _DataListAction, - DataListCheck, - DataListItem, - DataListItemCells, - DataListItemRow, Label, Progress, ProgressMeasureLocation, ProgressSize, - Tooltip, } from '@patternfly/react-core'; +import { Tr, Td } from '@patternfly/react-table'; import { PencilAltIcon } from '@patternfly/react-icons'; import styled from 'styled-components'; - -import _DataListCell from '../../../components/DataListCell'; +import { ActionsTd, ActionItem } from '../../../components/PaginatedTable'; import { InstanceGroup } from '../../../types'; -const DataListCell = styled(_DataListCell)` - white-space: nowrap; -`; - -const Badge = styled(PFBadge)` - margin-left: 8px; -`; - -const ListGroup = styled.span` - margin-left: 12px; - - &:first-of-type { - margin-left: 0; - } -`; - -const DataListAction = styled(_DataListAction)` - align-items: center; - display: grid; - grid-gap: 16px; - grid-template-columns: 40px; -`; - const Unavailable = styled.span` color: var(--pf-global--danger-color--200); `; @@ -56,6 +26,7 @@ function InstanceGroupListItem({ detailUrl, isSelected, onSelect, + rowIndex, i18n, }) { const labelId = `check-action-${instanceGroup.id}`; @@ -104,98 +75,50 @@ function InstanceGroupListItem({ }; return ( - - - - - - - - {instanceGroup.name} - - - {verifyInstanceGroup(instanceGroup)} - , - - - {i18n._(t`Type`)} - - {isContainerGroup(instanceGroup) - ? i18n._(t`Container group`) - : i18n._(t`Instance group`)} - - , - - - {i18n._(t`Running jobs`)} - {instanceGroup.jobs_running} - - - {i18n._(t`Total jobs`)} - {instanceGroup.jobs_total} - - - {!instanceGroup.is_containerized ? ( - - {i18n._(t`Instances`)} - {instanceGroup.instances} - - ) : null} - , - - - {usedCapacity(instanceGroup)} - , - ]} - /> - + + + + {instanceGroup.name} + {verifyInstanceGroup(instanceGroup)} + + + + {isContainerGroup(instanceGroup) + ? i18n._(t`Container group`) + : i18n._(t`Instance group`)} + + {instanceGroup.jobs_running} + {instanceGroup.jobs_total} + {instanceGroup.instances} + {usedCapacity(instanceGroup)} + + - {instanceGroup.summary_fields.user_capabilities.edit && ( - - - - )} - - - + + + + ); } InstanceGroupListItem.prototype = { diff --git a/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupListItem.test.jsx b/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupListItem.test.jsx index 9c819dd964..0f22a4b6d7 100644 --- a/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupListItem.test.jsx +++ b/awx/ui_next/src/screens/InstanceGroup/InstanceGroupList/InstanceGroupListItem.test.jsx @@ -47,12 +47,16 @@ describe('', () => { test('should mount successfully', async () => { await act(async () => { wrapper = mountWithContexts( - {}} - /> + + + {}} + /> + +
); }); expect(wrapper.find('InstanceGroupListItem').length).toBe(1); @@ -61,73 +65,81 @@ describe('', () => { test('should render the proper data instance group', async () => { await act(async () => { wrapper = mountWithContexts( - {}} - /> + + + {}} + /> + +
); }); expect( - wrapper.find('PFDataListCell[aria-label="instance group name"]').text() + wrapper + .find('Td') + .at(1) + .text() ).toBe('Foo'); expect(wrapper.find('Progress').prop('value')).toBe(40); expect( - wrapper.find('PFDataListCell[aria-label="instance group type"]').text() - ).toBe('TypeInstance group'); + wrapper + .find('Td') + .at(2) + .text() + ).toBe('Instance group'); expect(wrapper.find('PencilAltIcon').length).toBe(1); - expect(wrapper.find('input#select-instance-groups-1').prop('checked')).toBe( - false + expect(wrapper.find('.pf-c-table__check input').prop('checked')).toBe( + undefined ); }); test('should render the proper data container group', async () => { await act(async () => { wrapper = mountWithContexts( - {}} - /> + + + {}} + /> + +
); }); expect( - wrapper.find('PFDataListCell[aria-label="instance group name"]').text() + wrapper + .find('Td') + .at(1) + .text() ).toBe('Bar'); expect( - wrapper.find('PFDataListCell[aria-label="instance group type"]').text() - ).toBe('TypeContainer group'); + wrapper + .find('Td') + .at(2) + .text() + ).toBe('Container group'); expect(wrapper.find('PencilAltIcon').length).toBe(0); }); - test('should be checked', async () => { - await act(async () => { - wrapper = mountWithContexts( - {}} - /> - ); - }); - expect(wrapper.find('input#select-instance-groups-1').prop('checked')).toBe( - true - ); - }); - test('edit button shown to users with edit capabilities', async () => { await act(async () => { wrapper = mountWithContexts( - {}} - /> + + + {}} + /> + +
); }); @@ -137,12 +149,16 @@ describe('', () => { test('edit button hidden from users without edit capabilities', async () => { await act(async () => { wrapper = mountWithContexts( - {}} - /> + + + {}} + /> + +
); });