Convert WorkflowApprovalList to table

This commit is contained in:
Keith Grant
2021-01-07 11:54:21 -08:00
parent 953fa3fe0d
commit eb2a9baadd
4 changed files with 137 additions and 132 deletions

View File

@@ -55,7 +55,7 @@ function ScheduleListItem({ i18n, isSelected, onSelect, schedule, rowIndex }) {
onSelect, onSelect,
disable: false, disable: false,
}} }}
dataLabel={i18n._(`Selected`)} dataLabel={i18n._(t`Selected`)}
/> />
<Td id={labelId} dataLabel={i18n._(t`Name`)}> <Td id={labelId} dataLabel={i18n._(t`Name`)}>
<Link to={`${scheduleBaseUrl}/details`}> <Link to={`${scheduleBaseUrl}/details`}>

View File

@@ -4,9 +4,11 @@ import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Card, PageSection } from '@patternfly/react-core'; import { Card, PageSection } from '@patternfly/react-core';
import { WorkflowApprovalsAPI } from '../../../api'; import { WorkflowApprovalsAPI } from '../../../api';
import PaginatedDataList, { import PaginatedTable, {
ToolbarDeleteButton, HeaderRow,
} from '../../../components/PaginatedDataList'; HeaderCell,
} from '../../../components/PaginatedTable';
import { ToolbarDeleteButton } from '../../../components/PaginatedDataList';
import AlertModal from '../../../components/AlertModal'; import AlertModal from '../../../components/AlertModal';
import ErrorDetail from '../../../components/ErrorDetail'; import ErrorDetail from '../../../components/ErrorDetail';
import DataListToolbar from '../../../components/DataListToolbar'; import DataListToolbar from '../../../components/DataListToolbar';
@@ -155,7 +157,7 @@ function WorkflowApprovalsList({ i18n }) {
<> <>
<PageSection> <PageSection>
<Card> <Card>
<PaginatedDataList <PaginatedTable
contentError={contentError} contentError={contentError}
hasContentLoading={ hasContentLoading={
isWorkflowApprovalsLoading || isWorkflowApprovalsLoading ||
@@ -181,16 +183,6 @@ function WorkflowApprovalsList({ i18n }) {
]} ]}
toolbarSearchableKeys={searchableKeys} toolbarSearchableKeys={searchableKeys}
toolbarRelatedSearchableKeys={relatedSearchableKeys} toolbarRelatedSearchableKeys={relatedSearchableKeys}
toolbarSortColumns={[
{
name: i18n._(t`Name`),
key: 'name',
},
{
name: i18n._(t`Started`),
key: 'started',
},
]}
renderToolbar={props => ( renderToolbar={props => (
<DataListToolbar <DataListToolbar
{...props} {...props}
@@ -227,7 +219,15 @@ function WorkflowApprovalsList({ i18n }) {
]} ]}
/> />
)} )}
renderItem={workflowApproval => ( headerRow={
<HeaderRow qsConfig={QS_CONFIG}>
<HeaderCell sortKey="name">{i18n._(t`Name`)}</HeaderCell>
<HeaderCell>{i18n._(t`Job`)}</HeaderCell>
<HeaderCell sortKey="started">{i18n._(t`Started`)}</HeaderCell>
<HeaderCell>{i18n._(t`Status`)}</HeaderCell>
</HeaderRow>
}
renderRow={(workflowApproval, index) => (
<WorkflowApprovalListItem <WorkflowApprovalListItem
key={workflowApproval.id} key={workflowApproval.id}
workflowApproval={workflowApproval} workflowApproval={workflowApproval}
@@ -237,6 +237,7 @@ function WorkflowApprovalsList({ i18n }) {
)} )}
onSelect={() => handleSelect(workflowApproval)} onSelect={() => handleSelect(workflowApproval)}
onSuccessfulAction={fetchWorkflowApprovals} onSuccessfulAction={fetchWorkflowApprovals}
rowIndex={index}
/> />
)} )}
/> />

View File

@@ -2,27 +2,14 @@ import React from 'react';
import { withI18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { string, bool, func } from 'prop-types'; import { string, bool, func } from 'prop-types';
import { import { Label } from '@patternfly/react-core';
DataListCheck, import { Tr, Td } from '@patternfly/react-table';
DataListItem,
DataListItemCells,
DataListItemRow,
Label,
} from '@patternfly/react-core';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import styled from 'styled-components'; import styled from 'styled-components';
import DataListCell from '../../../components/DataListCell';
import { WorkflowApproval } from '../../../types'; import { WorkflowApproval } from '../../../types';
import { formatDateString } from '../../../util/dates'; import { formatDateString } from '../../../util/dates';
import WorkflowApprovalStatus from '../shared/WorkflowApprovalStatus'; import WorkflowApprovalStatus from '../shared/WorkflowApprovalStatus';
const StatusCell = styled(DataListCell)`
@media screen and (min-width: 768px) {
display: flex;
justify-content: flex-end;
}
`;
const JobLabel = styled.b` const JobLabel = styled.b`
margin-right: 24px; margin-right: 24px;
`; `;
@@ -32,6 +19,7 @@ function WorkflowApprovalListItem({
isSelected, isSelected,
onSelect, onSelect,
detailUrl, detailUrl,
rowIndex,
i18n, i18n,
}) { }) {
const labelId = `check-action-${workflowApproval.id}`; const labelId = `check-action-${workflowApproval.id}`;
@@ -62,44 +50,39 @@ function WorkflowApprovalListItem({
}; };
return ( return (
<DataListItem <Tr id={`workflow-approval-row-${workflowApproval.id}`}>
key={workflowApproval.id} <Td
aria-labelledby={labelId} select={{
id={`${workflowApproval.id}`} rowIndex,
> isSelected,
<DataListItemRow> onSelect,
<DataListCheck }}
id={`select-workflowApproval-${workflowApproval.id}`} dataLabel={i18n._(t`Selected`)}
checked={isSelected} />
onChange={onSelect} <Td id={labelId} dataLabel={i18n._(t`Name`)}>
aria-labelledby={labelId} <Link to={`${detailUrl}`}>
/> <b>{workflowApproval.name}</b>
<DataListItemCells </Link>
dataListCells={[ </Td>
<DataListCell key="title"> <Td>
<Link to={`${detailUrl}`}> <>
<b>{workflowApproval.name}</b> <JobLabel>{i18n._(t`Job`)}</JobLabel>
</Link> {workflowJob && workflowJob?.id ? (
</DataListCell>, <Link to={`/jobs/workflow/${workflowJob?.id}`}>
<DataListCell key="job"> {`${workflowJob?.id} - ${workflowJob?.name}`}
<> </Link>
<JobLabel>{i18n._(t`Job`)}</JobLabel> ) : (
{workflowJob && workflowJob?.id ? ( i18n._(t`Deleted`)
<Link to={`/jobs/workflow/${workflowJob?.id}`}> )}
{`${workflowJob?.id} - ${workflowJob?.name}`} </>
</Link> </Td>
) : ( <Td dataLabel={i18n._(t`Started`)}>
i18n._(t`Deleted`) {formatDateString(workflowApproval.started)}
)} </Td>
</> <Td dataLabel={i18n._(t`Status`)}>
</DataListCell>, <div>{getStatus()}</div>
<StatusCell key="status"> </Td>
<div>{getStatus()}</div> </Tr>
</StatusCell>,
]}
/>
</DataListItemRow>
</DataListItem>
); );
} }

View File

@@ -12,91 +12,112 @@ describe('<WorkflowApprovalListItem />', () => {
afterEach(() => { afterEach(() => {
wrapper.unmount(); wrapper.unmount();
}); });
test('should display never expires status', () => { test('should display never expires status', () => {
wrapper = mountWithContexts( wrapper = mountWithContexts(
<WorkflowApprovalListItem <table>
isSelected={false} <tbody>
detailUrl={`/workflow_approvals/${workflowApproval.id}`} <WorkflowApprovalListItem
onSelect={() => {}} isSelected={false}
workflowApproval={workflowApproval} detailUrl={`/workflow_approvals/${workflowApproval.id}`}
/> onSelect={() => {}}
workflowApproval={workflowApproval}
/>
</tbody>
</table>
); );
expect(wrapper.find('Label[children="Never expires"]').length).toBe(1); expect(wrapper.find('Label[children="Never expires"]').length).toBe(1);
}); });
test('should display timed out status', () => { test('should display timed out status', () => {
wrapper = mountWithContexts( wrapper = mountWithContexts(
<WorkflowApprovalListItem <table>
isSelected={false} <tbody>
detailUrl={`/workflow_approvals/${workflowApproval.id}`} <WorkflowApprovalListItem
onSelect={() => {}} isSelected={false}
workflowApproval={{ detailUrl={`/workflow_approvals/${workflowApproval.id}`}
...workflowApproval, onSelect={() => {}}
status: 'failed', workflowApproval={{
timed_out: true, ...workflowApproval,
}} status: 'failed',
/> timed_out: true,
}}
/>
</tbody>
</table>
); );
expect(wrapper.find('Label[children="Timed out"]').length).toBe(1); expect(wrapper.find('Label[children="Timed out"]').length).toBe(1);
}); });
test('should display canceled status', () => { test('should display canceled status', () => {
wrapper = mountWithContexts( wrapper = mountWithContexts(
<WorkflowApprovalListItem <table>
isSelected={false} <tbody>
detailUrl={`/workflow_approvals/${workflowApproval.id}`} <WorkflowApprovalListItem
onSelect={() => {}} isSelected={false}
workflowApproval={{ detailUrl={`/workflow_approvals/${workflowApproval.id}`}
...workflowApproval, onSelect={() => {}}
canceled_on: '2020-10-09T19:59:26.974046Z', workflowApproval={{
status: 'canceled', ...workflowApproval,
}} canceled_on: '2020-10-09T19:59:26.974046Z',
/> status: 'canceled',
}}
/>
</tbody>
</table>
); );
expect(wrapper.find('Label[children="Canceled"]').length).toBe(1); expect(wrapper.find('Label[children="Canceled"]').length).toBe(1);
}); });
test('should display approved status', () => { test('should display approved status', () => {
wrapper = mountWithContexts( wrapper = mountWithContexts(
<WorkflowApprovalListItem <table>
isSelected={false} <tbody>
detailUrl={`/workflow_approvals/${workflowApproval.id}`} <WorkflowApprovalListItem
onSelect={() => {}} isSelected={false}
workflowApproval={{ detailUrl={`/workflow_approvals/${workflowApproval.id}`}
...workflowApproval, onSelect={() => {}}
status: 'successful', workflowApproval={{
summary_fields: { ...workflowApproval,
...workflowApproval.summary_fields, status: 'successful',
approved_or_denied_by: { summary_fields: {
id: 1, ...workflowApproval.summary_fields,
username: 'admin', approved_or_denied_by: {
first_name: '', id: 1,
last_name: '', username: 'admin',
}, first_name: '',
}, last_name: '',
}} },
/> },
}}
/>
</tbody>
</table>
); );
expect(wrapper.find('Label[children="Approved"]').length).toBe(1); expect(wrapper.find('Label[children="Approved"]').length).toBe(1);
}); });
test('should display denied status', () => { test('should display denied status', () => {
wrapper = mountWithContexts( wrapper = mountWithContexts(
<WorkflowApprovalListItem <table>
isSelected={false} <tbody>
detailUrl={`/workflow_approvals/${workflowApproval.id}`} <WorkflowApprovalListItem
onSelect={() => {}} isSelected={false}
workflowApproval={{ detailUrl={`/workflow_approvals/${workflowApproval.id}`}
...workflowApproval, onSelect={() => {}}
failed: true, workflowApproval={{
status: 'failed', ...workflowApproval,
summary_fields: { failed: true,
...workflowApproval.summary_fields, status: 'failed',
approved_or_denied_by: { summary_fields: {
id: 1, ...workflowApproval.summary_fields,
username: 'admin', approved_or_denied_by: {
first_name: '', id: 1,
last_name: '', username: 'admin',
}, first_name: '',
}, last_name: '',
}} },
/> },
}}
/>
</tbody>
</table>
); );
expect(wrapper.find('Label[children="Denied"]').length).toBe(1); expect(wrapper.find('Label[children="Denied"]').length).toBe(1);
}); });