convert TeamsList to tables

This commit is contained in:
Keith Grant
2021-01-27 15:56:30 -08:00
parent e886ce57aa
commit 4ca8862b51
3 changed files with 122 additions and 127 deletions

View File

@@ -9,7 +9,11 @@ import useRequest, { useDeleteItems } from '../../../util/useRequest';
import AlertModal from '../../../components/AlertModal'; import AlertModal from '../../../components/AlertModal';
import DataListToolbar from '../../../components/DataListToolbar'; import DataListToolbar from '../../../components/DataListToolbar';
import ErrorDetail from '../../../components/ErrorDetail'; import ErrorDetail from '../../../components/ErrorDetail';
import PaginatedDataList, { import PaginatedTable, {
HeaderRow,
HeaderCell,
} from '../../../components/PaginatedTable';
import {
ToolbarAddButton, ToolbarAddButton,
ToolbarDeleteButton, ToolbarDeleteButton,
} from '../../../components/PaginatedDataList'; } from '../../../components/PaginatedDataList';
@@ -112,7 +116,7 @@ function TeamList({ i18n }) {
<Fragment> <Fragment>
<PageSection> <PageSection>
<Card> <Card>
<PaginatedDataList <PaginatedTable
contentError={contentError} contentError={contentError}
hasContentLoading={hasContentLoading} hasContentLoading={hasContentLoading}
items={teams} items={teams}
@@ -143,14 +147,14 @@ function TeamList({ i18n }) {
key: 'modified_by__username__icontains', key: 'modified_by__username__icontains',
}, },
]} ]}
toolbarSortColumns={[
{
name: i18n._(t`Name`),
key: 'name',
},
]}
toolbarSearchableKeys={searchableKeys} toolbarSearchableKeys={searchableKeys}
toolbarRelatedSearchableKeys={relatedSearchableKeys} toolbarRelatedSearchableKeys={relatedSearchableKeys}
headerRow={
<HeaderRow qsConfig={QS_CONFIG}>
<HeaderCell sortKey="name">{i18n._(t`Name`)}</HeaderCell>
<HeaderCell>{i18n._(t`Organization`)}</HeaderCell>
</HeaderRow>
}
renderToolbar={props => ( renderToolbar={props => (
<DataListToolbar <DataListToolbar
{...props} {...props}
@@ -176,13 +180,14 @@ function TeamList({ i18n }) {
]} ]}
/> />
)} )}
renderItem={o => ( renderRow={(team, index) => (
<TeamListItem <TeamListItem
key={o.id} key={team.id}
team={o} team={team}
detailUrl={`${match.url}/${o.id}`} detailUrl={`${match.url}/${team.id}`}
isSelected={selected.some(row => row.id === o.id)} isSelected={selected.some(row => row.id === team.id)}
onSelect={() => handleSelect(o)} onSelect={() => handleSelect(team)}
rowIndex={index}
/> />
)} )}
emptyStateControls={ emptyStateControls={

View File

@@ -3,31 +3,21 @@ import React, { Fragment } from 'react';
import { string, bool, func } from 'prop-types'; import { string, bool, func } from 'prop-types';
import { withI18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { import { Button } from '@patternfly/react-core';
Button, import { Tr, Td } from '@patternfly/react-table';
DataListAction as _DataListAction,
DataListCheck,
DataListItem,
DataListItemCells,
DataListItemRow,
Tooltip,
} from '@patternfly/react-core';
import styled from 'styled-components';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { PencilAltIcon } from '@patternfly/react-icons'; import { PencilAltIcon } from '@patternfly/react-icons';
import DataListCell from '../../../components/DataListCell'; import { ActionsTd, ActionItem } from '../../../components/PaginatedTable';
import { Team } from '../../../types'; import { Team } from '../../../types';
const DataListAction = styled(_DataListAction)` function TeamListItem({
align-items: center; team,
display: grid; isSelected,
grid-gap: 16px; onSelect,
grid-template-columns: 40px; detailUrl,
`; rowIndex,
i18n,
function TeamListItem({ team, isSelected, onSelect, detailUrl, i18n }) { }) {
TeamListItem.propTypes = { TeamListItem.propTypes = {
team: Team.isRequired, team: Team.isRequired,
detailUrl: string.isRequired, detailUrl: string.isRequired,
@@ -38,57 +28,45 @@ function TeamListItem({ team, isSelected, onSelect, detailUrl, i18n }) {
const labelId = `check-action-${team.id}`; const labelId = `check-action-${team.id}`;
return ( return (
<DataListItem key={team.id} aria-labelledby={labelId} id={`${team.id}`}> <Tr id={`team-row-${team.id}`}>
<DataListItemRow> <Td
<DataListCheck select={{
id={`select-team-${team.id}`} rowIndex,
checked={isSelected} isSelected,
onChange={onSelect} onSelect,
aria-labelledby={labelId} }}
/> dataLabel={i18n._(t`Selected`)}
<DataListItemCells />
dataListCells={[ <Td id={labelId} dataLabel={i18n._(t`Name`)}>
<DataListCell key="name"> <Link id={labelId} to={`${detailUrl}`}>
<Link id={labelId} to={`${detailUrl}`}> <b>{team.name}</b>
<b>{team.name}</b> </Link>
</Link> </Td>
</DataListCell>, <Td dataLabel={i18n._(t`Organization`)}>
<DataListCell key="organization"> {team.summary_fields.organization && (
{team.summary_fields.organization && ( <Link
<Fragment> to={`/organizations/${team.summary_fields.organization.id}/details`}
<b>{i18n._(t`Organization`)}</b>{' '} >
<Link <b>{team.summary_fields.organization.name}</b>
to={`/organizations/${team.summary_fields.organization.id}/details`} </Link>
> )}
<b>{team.summary_fields.organization.name}</b> </Td>
</Link> <ActionsTd dataLabel={i18n._(t`Actions`)}>
</Fragment> <ActionItem
)} visible={team.summary_fields.user_capabilities.edit}
</DataListCell>, tooltip={i18n._(t`Edit Team`)}
]}
/>
<DataListAction
aria-label={i18n._(t`Actions`)}
aria-labelledby={labelId}
id={labelId}
> >
{team.summary_fields.user_capabilities.edit ? ( <Button
<Tooltip content={i18n._(t`Edit Team`)} position="top"> aria-label={i18n._(t`Edit Team`)}
<Button variant="plain"
aria-label={i18n._(t`Edit Team`)} component={Link}
variant="plain" to={`/teams/${team.id}/edit`}
component={Link} >
to={`/teams/${team.id}/edit`} <PencilAltIcon />
> </Button>
<PencilAltIcon /> </ActionItem>
</Button> </ActionsTd>
</Tooltip> </Tr>
) : (
''
)}
</DataListAction>
</DataListItemRow>
</DataListItem>
); );
} }
export default withI18n()(TeamListItem); export default withI18n()(TeamListItem);

View File

@@ -11,20 +11,24 @@ describe('<TeamListItem />', () => {
mountWithContexts( mountWithContexts(
<I18nProvider> <I18nProvider>
<MemoryRouter initialEntries={['/teams']} initialIndex={0}> <MemoryRouter initialEntries={['/teams']} initialIndex={0}>
<TeamListItem <table>
team={{ <tbody>
id: 1, <TeamListItem
name: 'Team 1', team={{
summary_fields: { id: 1,
user_capabilities: { name: 'Team 1',
edit: true, summary_fields: {
}, user_capabilities: {
}, edit: true,
}} },
detailUrl="/team/1" },
isSelected }}
onSelect={() => {}} detailUrl="/team/1"
/> isSelected
onSelect={() => {}}
/>
</tbody>
</table>
</MemoryRouter> </MemoryRouter>
</I18nProvider> </I18nProvider>
); );
@@ -33,20 +37,24 @@ describe('<TeamListItem />', () => {
const wrapper = mountWithContexts( const wrapper = mountWithContexts(
<I18nProvider> <I18nProvider>
<MemoryRouter initialEntries={['/teams']} initialIndex={0}> <MemoryRouter initialEntries={['/teams']} initialIndex={0}>
<TeamListItem <table>
team={{ <tbody>
id: 1, <TeamListItem
name: 'Team', team={{
summary_fields: { id: 1,
user_capabilities: { name: 'Team',
edit: true, summary_fields: {
}, user_capabilities: {
}, edit: true,
}} },
detailUrl="/team/1" },
isSelected }}
onSelect={() => {}} detailUrl="/team/1"
/> isSelected
onSelect={() => {}}
/>
</tbody>
</table>
</MemoryRouter> </MemoryRouter>
</I18nProvider> </I18nProvider>
); );
@@ -56,20 +64,24 @@ describe('<TeamListItem />', () => {
const wrapper = mountWithContexts( const wrapper = mountWithContexts(
<I18nProvider> <I18nProvider>
<MemoryRouter initialEntries={['/teams']} initialIndex={0}> <MemoryRouter initialEntries={['/teams']} initialIndex={0}>
<TeamListItem <table>
team={{ <tbody>
id: 1, <TeamListItem
name: 'Team', team={{
summary_fields: { id: 1,
user_capabilities: { name: 'Team',
edit: false, summary_fields: {
}, user_capabilities: {
}, edit: false,
}} },
detailUrl="/team/1" },
isSelected }}
onSelect={() => {}} detailUrl="/team/1"
/> isSelected
onSelect={() => {}}
/>
</tbody>
</table>
</MemoryRouter> </MemoryRouter>
</I18nProvider> </I18nProvider>
); );