From d6b5990cd28a8efafc97bf0fa3a8a01a7dbb9195 Mon Sep 17 00:00:00 2001 From: nixocio Date: Mon, 8 Feb 2021 16:35:28 -0500 Subject: [PATCH] Migrate EE list to tables Migrate EE list to tables. See:https://github.com/ansible/awx/issues/7884 --- .../ExecutionEnviromentList.test.jsx | 60 ++++++----- .../ExecutionEnvironmentList.jsx | 20 +++- .../ExecutionEnvironmentListItem.jsx | 102 +++++++++--------- .../ExecutionEnvironmentListItem.test.jsx | 54 +++++++--- 4 files changed, 135 insertions(+), 101 deletions(-) diff --git a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnviromentList.test.jsx b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnviromentList.test.jsx index 475dd1a8b5..1490ff49e3 100644 --- a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnviromentList.test.jsx +++ b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnviromentList.test.jsx @@ -15,6 +15,7 @@ const executionEnvironments = { data: { results: [ { + name: 'Foo', id: 1, image: 'https://registry.com/r/image/manifest', organization: null, @@ -23,6 +24,7 @@ const executionEnvironments = { summary_fields: { user_capabilities: { edit: true, delete: true } }, }, { + name: 'Bar', id: 2, image: 'https://registry.com/r/image2/manifest', organization: null, @@ -38,6 +40,14 @@ const executionEnvironments = { const options = { data: { actions: { POST: true } } }; describe('', () => { + beforeEach(() => { + ExecutionEnvironmentsAPI.read.mockResolvedValue(executionEnvironments); + ExecutionEnvironmentsAPI.readOptions.mockResolvedValue(options); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); let wrapper; test('should mount successfully', async () => { @@ -52,9 +62,6 @@ describe('', () => { }); test('should have data fetched and render 2 rows', async () => { - ExecutionEnvironmentsAPI.read.mockResolvedValue(executionEnvironments); - ExecutionEnvironmentsAPI.readOptions.mockResolvedValue(options); - await act(async () => { wrapper = mountWithContexts(); }); @@ -69,10 +76,7 @@ describe('', () => { expect(ExecutionEnvironmentsAPI.readOptions).toBeCalled(); }); - test('should delete item successfully', async () => { - ExecutionEnvironmentsAPI.read.mockResolvedValue(executionEnvironments); - ExecutionEnvironmentsAPI.readOptions.mockResolvedValue(options); - + test('should delete items successfully', async () => { await act(async () => { wrapper = mountWithContexts(); }); @@ -82,27 +86,25 @@ describe('', () => { el => el.length > 0 ); - wrapper - .find('input#select-execution-environment-1') - .simulate('change', executionEnvironments.data.results[0]); - wrapper.update(); - - expect( - wrapper.find('input#select-execution-environment-1').prop('checked') - ).toBe(true); - await act(async () => { - wrapper.find('Button[aria-label="Delete"]').prop('onClick')(); + wrapper + .find('ExecutionEnvironmentListItem') + .at(0) + .invoke('onSelect')(); }); wrapper.update(); - await act(async () => { - wrapper.find('Button[aria-label="confirm delete"]').prop('onClick')(); + wrapper + .find('ExecutionEnvironmentListItem') + .at(1) + .invoke('onSelect')(); + }); + wrapper.update(); + await act(async () => { + wrapper.find('ToolbarDeleteButton').invoke('onDelete')(); }); - expect(ExecutionEnvironmentsAPI.destroy).toBeCalledWith( - executionEnvironments.data.results[0].id - ); + expect(ExecutionEnvironmentsAPI.destroy).toHaveBeenCalledTimes(2); }); test('should render deletion error modal', async () => { @@ -117,19 +119,24 @@ describe('', () => { }, }) ); - ExecutionEnvironmentsAPI.read.mockResolvedValue(executionEnvironments); - ExecutionEnvironmentsAPI.readOptions.mockResolvedValue(options); await act(async () => { wrapper = mountWithContexts(); }); waitForElement(wrapper, 'ExecutionEnvironmentList', el => el.length > 0); wrapper - .find('input#select-execution-environment-1') + .find('ExecutionEnvironmentListItem') + .at(0) + .find('input') .simulate('change', 'a'); wrapper.update(); + expect( - wrapper.find('input#select-execution-environment-1').prop('checked') + wrapper + .find('ExecutionEnvironmentListItem') + .at(0) + .find('input') + .prop('checked') ).toBe(true); await act(async () => @@ -156,7 +163,6 @@ describe('', () => { }, }) ); - ExecutionEnvironmentsAPI.readOptions.mockResolvedValue(options); await act(async () => { wrapper = mountWithContexts(); }); diff --git a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentList.jsx b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentList.jsx index 749fe8893e..9d94085520 100644 --- a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentList.jsx +++ b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentList.jsx @@ -8,10 +8,14 @@ import { ExecutionEnvironmentsAPI } from '../../../api'; import { getQSConfig, parseQueryString } from '../../../util/qs'; import useRequest, { useDeleteItems } from '../../../util/useRequest'; import useSelected from '../../../util/useSelected'; -import PaginatedDataList, { +import { ToolbarDeleteButton, ToolbarAddButton, } from '../../../components/PaginatedDataList'; +import PaginatedTable, { + HeaderRow, + HeaderCell, +} from '../../../components/PaginatedTable'; import ErrorDetail from '../../../components/ErrorDetail'; import AlertModal from '../../../components/AlertModal'; import DatalistToolbar from '../../../components/DataListToolbar'; @@ -21,7 +25,7 @@ import ExecutionEnvironmentsListItem from './ExecutionEnvironmentListItem'; const QS_CONFIG = getQSConfig('execution_environments', { page: 1, page_size: 20, - order_by: 'image', + order_by: 'name', }); function ExecutionEnvironmentList({ i18n }) { @@ -106,7 +110,7 @@ function ExecutionEnvironmentList({ i18n }) { <> - + {i18n._(t`Name`)} + {i18n._(t`Image`)} + {i18n._(t`Organization`)} + + } renderToolbar={props => ( )} - renderItem={executionEnvironment => ( + renderRow={(executionEnvironment, index) => ( handleSelect(executionEnvironment)} diff --git a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentListItem.jsx b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentListItem.jsx index 8e41c5a0f8..fbc8387d84 100644 --- a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentListItem.jsx +++ b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentListItem.jsx @@ -3,18 +3,11 @@ import { string, bool, func } from 'prop-types'; import { withI18n } from '@lingui/react'; import { t } from '@lingui/macro'; import { Link } from 'react-router-dom'; -import { - Button, - DataListAction, - DataListCheck, - DataListItem, - DataListItemRow, - DataListItemCells, - Tooltip, -} from '@patternfly/react-core'; +import { Button } from '@patternfly/react-core'; +import { Tr, Td } from '@patternfly/react-table'; import { PencilAltIcon } from '@patternfly/react-icons'; -import DataListCell from '../../../components/DataListCell'; +import { ActionsTd, ActionItem } from '../../../components/PaginatedTable'; import { ExecutionEnvironment } from '../../../types'; function ExecutionEnvironmentListItem({ @@ -23,55 +16,56 @@ function ExecutionEnvironmentListItem({ isSelected, onSelect, i18n, + rowIndex, }) { const labelId = `check-action-${executionEnvironment.id}`; return ( - - - - - - {executionEnvironment.image} - - , - ]} - /> - - + + + + {executionEnvironment.name} + + + + {executionEnvironment.image} + + + {executionEnvironment.organization ? ( + - - - - - + {executionEnvironment?.summary_fields?.organization?.name} + + ) : ( + i18n._(t`Globally Available`) + )} + + + + + + + ); } diff --git a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentListItem.test.jsx b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentListItem.test.jsx index 4f51a51672..0e7c037aed 100644 --- a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentListItem.test.jsx +++ b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentListItem.test.jsx @@ -8,21 +8,27 @@ import ExecutionEnvironmentListItem from './ExecutionEnvironmentListItem'; describe('', () => { let wrapper; const executionEnvironment = { + name: 'Foo', id: 1, image: 'https://registry.com/r/image/manifest', organization: null, credential: null, + summary_fields: { user_capabilities: { edit: true } }, }; test('should mount successfully', async () => { await act(async () => { wrapper = mountWithContexts( - {}} - /> + + + {}} + /> + +
); }); expect(wrapper.find('ExecutionEnvironmentListItem').length).toBe(1); @@ -31,22 +37,38 @@ describe('', () => { test('should render the proper data', async () => { await act(async () => { wrapper = mountWithContexts( - {}} - /> + + + {}} + /> + +
); }); expect( wrapper - .find('DataListCell[aria-label="execution environment image"]') + .find('Td') + .at(1) + .text() + ).toBe(executionEnvironment.name); + expect( + wrapper + .find('Td') + .at(2) .text() ).toBe(executionEnvironment.image); - expect(wrapper.find('PencilAltIcon').length).toBe(1); + expect( - wrapper.find('input#select-execution-environment-1').prop('checked') - ).toBe(false); + wrapper + .find('Td') + .at(3) + .text() + ).toBe('Globally Available'); + + expect(wrapper.find('PencilAltIcon').exists()).toBeTruthy(); }); });