mirror of
https://github.com/ansible/awx.git
synced 2026-01-11 01:57:35 -03:30
Migrate EE list to tables
Migrate EE list to tables. See:https://github.com/ansible/awx/issues/7884
This commit is contained in:
parent
26f7a2ba81
commit
d6b5990cd2
@ -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('<ExecutionEnvironmentList/>', () => {
|
||||
beforeEach(() => {
|
||||
ExecutionEnvironmentsAPI.read.mockResolvedValue(executionEnvironments);
|
||||
ExecutionEnvironmentsAPI.readOptions.mockResolvedValue(options);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
let wrapper;
|
||||
|
||||
test('should mount successfully', async () => {
|
||||
@ -52,9 +62,6 @@ describe('<ExecutionEnvironmentList/>', () => {
|
||||
});
|
||||
|
||||
test('should have data fetched and render 2 rows', async () => {
|
||||
ExecutionEnvironmentsAPI.read.mockResolvedValue(executionEnvironments);
|
||||
ExecutionEnvironmentsAPI.readOptions.mockResolvedValue(options);
|
||||
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(<ExecutionEnvironmentList />);
|
||||
});
|
||||
@ -69,10 +76,7 @@ describe('<ExecutionEnvironmentList/>', () => {
|
||||
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(<ExecutionEnvironmentList />);
|
||||
});
|
||||
@ -82,27 +86,25 @@ describe('<ExecutionEnvironmentList/>', () => {
|
||||
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('<ExecutionEnvironmentList/>', () => {
|
||||
},
|
||||
})
|
||||
);
|
||||
ExecutionEnvironmentsAPI.read.mockResolvedValue(executionEnvironments);
|
||||
ExecutionEnvironmentsAPI.readOptions.mockResolvedValue(options);
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(<ExecutionEnvironmentList />);
|
||||
});
|
||||
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('<ExecutionEnvironmentList/>', () => {
|
||||
},
|
||||
})
|
||||
);
|
||||
ExecutionEnvironmentsAPI.readOptions.mockResolvedValue(options);
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(<ExecutionEnvironmentList />);
|
||||
});
|
||||
|
||||
@ -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 }) {
|
||||
<>
|
||||
<PageSection>
|
||||
<Card>
|
||||
<PaginatedDataList
|
||||
<PaginatedTable
|
||||
contentError={contentError}
|
||||
hasContentLoading={isLoading || deleteLoading}
|
||||
items={executionEnvironments}
|
||||
@ -141,6 +145,13 @@ function ExecutionEnvironmentList({ i18n }) {
|
||||
key: 'description',
|
||||
},
|
||||
]}
|
||||
headerRow={
|
||||
<HeaderRow qsConfig={QS_CONFIG}>
|
||||
<HeaderCell sortKey="name">{i18n._(t`Name`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Image`)}</HeaderCell>
|
||||
<HeaderCell>{i18n._(t`Organization`)}</HeaderCell>
|
||||
</HeaderRow>
|
||||
}
|
||||
renderToolbar={props => (
|
||||
<DatalistToolbar
|
||||
{...props}
|
||||
@ -168,9 +179,10 @@ function ExecutionEnvironmentList({ i18n }) {
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
renderItem={executionEnvironment => (
|
||||
renderRow={(executionEnvironment, index) => (
|
||||
<ExecutionEnvironmentsListItem
|
||||
key={executionEnvironment.id}
|
||||
rowIndex={index}
|
||||
executionEnvironment={executionEnvironment}
|
||||
detailUrl={`${match.url}/${executionEnvironment.id}/details`}
|
||||
onSelect={() => handleSelect(executionEnvironment)}
|
||||
|
||||
@ -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 (
|
||||
<DataListItem
|
||||
key={executionEnvironment.id}
|
||||
aria-labelledby={labelId}
|
||||
id={`${executionEnvironment.id} `}
|
||||
>
|
||||
<DataListItemRow>
|
||||
<DataListCheck
|
||||
id={`select-execution-environment-${executionEnvironment.id}`}
|
||||
checked={isSelected}
|
||||
onChange={onSelect}
|
||||
aria-labelledby={labelId}
|
||||
/>
|
||||
<DataListItemCells
|
||||
dataListCells={[
|
||||
<DataListCell
|
||||
key="image"
|
||||
aria-label={i18n._(t`execution environment image`)}
|
||||
>
|
||||
<Link to={`${detailUrl}`}>
|
||||
<b>{executionEnvironment.image}</b>
|
||||
</Link>
|
||||
</DataListCell>,
|
||||
]}
|
||||
/>
|
||||
<DataListAction
|
||||
aria-label={i18n._(t`actions`)}
|
||||
aria-labelledby={labelId}
|
||||
id={labelId}
|
||||
>
|
||||
<Tooltip
|
||||
content={i18n._(t`Edit execution environment`)}
|
||||
position="top"
|
||||
<Tr id={`ee-row-${executionEnvironment.id}`}>
|
||||
<Td
|
||||
select={{
|
||||
rowIndex,
|
||||
isSelected,
|
||||
onSelect,
|
||||
disable: false,
|
||||
}}
|
||||
dataLabel={i18n._(t`Selected`)}
|
||||
/>
|
||||
<Td id={labelId} dataLabel={i18n._(t`Name`)}>
|
||||
<Link to={`${detailUrl}`}>
|
||||
<b>{executionEnvironment.name}</b>
|
||||
</Link>
|
||||
</Td>
|
||||
<Td id={labelId} dataLabel={i18n._(t`Image`)}>
|
||||
{executionEnvironment.image}
|
||||
</Td>
|
||||
<Td id={labelId} dataLabel={i18n._(t`Organization`)}>
|
||||
{executionEnvironment.organization ? (
|
||||
<Link
|
||||
to={`/organizations/${executionEnvironment?.summary_fields?.organization?.id}/details`}
|
||||
>
|
||||
<Button
|
||||
aria-label={i18n._(t`Edit execution environment`)}
|
||||
variant="plain"
|
||||
component={Link}
|
||||
to={`/execution_environments/${executionEnvironment.id}/edit`}
|
||||
>
|
||||
<PencilAltIcon />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</DataListAction>
|
||||
</DataListItemRow>
|
||||
</DataListItem>
|
||||
<b>{executionEnvironment?.summary_fields?.organization?.name}</b>
|
||||
</Link>
|
||||
) : (
|
||||
i18n._(t`Globally Available`)
|
||||
)}
|
||||
</Td>
|
||||
<ActionsTd dataLabel={i18n._(t`Actions`)}>
|
||||
<ActionItem
|
||||
visible={executionEnvironment.summary_fields.user_capabilities.edit}
|
||||
tooltip={i18n._(t`Edit Execution Environment`)}
|
||||
>
|
||||
<Button
|
||||
aria-label={i18n._(t`Edit Execution Environment`)}
|
||||
variant="plain"
|
||||
component={Link}
|
||||
to={`/execution_environments/${executionEnvironment.id}/edit`}
|
||||
>
|
||||
<PencilAltIcon />
|
||||
</Button>
|
||||
</ActionItem>
|
||||
</ActionsTd>
|
||||
</Tr>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -8,21 +8,27 @@ import ExecutionEnvironmentListItem from './ExecutionEnvironmentListItem';
|
||||
describe('<ExecutionEnvironmentListItem/>', () => {
|
||||
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(
|
||||
<ExecutionEnvironmentListItem
|
||||
executionEnvironment={executionEnvironment}
|
||||
detailUrl="execution_environments/1/details"
|
||||
isSelected={false}
|
||||
onSelect={() => {}}
|
||||
/>
|
||||
<table>
|
||||
<tbody>
|
||||
<ExecutionEnvironmentListItem
|
||||
executionEnvironment={executionEnvironment}
|
||||
detailUrl="execution_environments/1/details"
|
||||
isSelected={false}
|
||||
onSelect={() => {}}
|
||||
/>
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
});
|
||||
expect(wrapper.find('ExecutionEnvironmentListItem').length).toBe(1);
|
||||
@ -31,22 +37,38 @@ describe('<ExecutionEnvironmentListItem/>', () => {
|
||||
test('should render the proper data', async () => {
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
<ExecutionEnvironmentListItem
|
||||
executionEnvironment={executionEnvironment}
|
||||
detailUrl="execution_environments/1/details"
|
||||
isSelected={false}
|
||||
onSelect={() => {}}
|
||||
/>
|
||||
<table>
|
||||
<tbody>
|
||||
<ExecutionEnvironmentListItem
|
||||
executionEnvironment={executionEnvironment}
|
||||
detailUrl="execution_environments/1/details"
|
||||
isSelected={false}
|
||||
onSelect={() => {}}
|
||||
/>
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
});
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user