add HeaderRow component with table sorting

This commit is contained in:
Keith Grant 2020-11-23 16:32:16 -08:00
parent cfc4c3a1a7
commit b9d3beaa7f
3 changed files with 133 additions and 5 deletions

View File

@ -0,0 +1,73 @@
import React from 'react';
import { useLocation, useHistory } from 'react-router-dom';
import { Thead, Tr, Th } from '@patternfly/react-table';
import {
encodeNonDefaultQueryString,
parseQueryString,
replaceParams,
} from '../../util/qs';
export default function HeaderRow({
handleSelectAll,
isAllSelected,
qsConfig,
defaultSortKey,
children,
}) {
const location = useLocation();
const history = useHistory();
const params = parseQueryString(qsConfig, location.search);
// TODO: asc vs desc -- correct for both alpha & numeric sorting?
const onSort = (key, order) => {
console.log({ key, order });
const newParams = replaceParams(params, {
order_by: order === 'desc' ? key : `-${key}`,
page: null,
});
const encodedParams = encodeNonDefaultQueryString(qsConfig, newParams);
history.push(
encodedParams
? `${location.pathname}?${encodedParams}`
: location.pathname
);
};
const sortKey = params.order_by?.replace('-', '');
const sortBy = {
index: sortKey || defaultSortKey,
direction: params.order_by?.startsWith('-') ? 'asc' : 'desc',
};
return (
<Thead>
<Tr>
<Th
select={{
onSelect: handleSelectAll,
isSelected: isAllSelected,
}}
/>
{React.Children.map(children, child =>
React.cloneElement(child, {
onSort,
sortBy,
columnIndex: child.props.sortKey,
})
)}
</Tr>
</Thead>
);
}
export function HeaderCell({ sortKey, onSort, sortBy, columnIndex, children }) {
const sort = sortKey
? {
onSort: (event, key, order) => onSort(sortKey, order),
sortBy,
columnIndex,
}
: null;
return <Th sort={sort}>{children}</Th>;
}

View File

@ -1,5 +1,6 @@
export { default } from './PaginatedTable';
export { default as PaginatedTableRow } from './PaginatedTableRow';
export { default as ActionsTd } from './ActionsTd';
export { default as HeaderRow, HeaderCell } from './HeaderRow';
// export { default as ToolbarDeleteButton } from './ToolbarDeleteButton';
// export { default as ToolbarAddButton } from './ToolbarAddButton';

View File

@ -14,7 +14,10 @@ import {
ToolbarAddButton,
ToolbarDeleteButton,
} from '../../../components/PaginatedDataList';
import PaginatedTable from '../../../components/PaginatedTable';
import PaginatedTable, {
HeaderRow,
HeaderCell,
} from '../../../components/PaginatedTable';
import { getQSConfig, parseQueryString } from '../../../util/qs';
import OrganizationListItem from './OrganizationListItem';
@ -115,6 +118,10 @@ function OrganizationsList({ i18n }) {
}
};
const onSort = (e, index, direction) => {
console.log(index, direction);
};
return (
<>
<PageSection>
@ -125,7 +132,7 @@ function OrganizationsList({ i18n }) {
items={organizations}
itemCount={organizationCount}
pluralizedItemName={i18n._(t`Organizations`)}
qsConfig={QS_CONFIG}
qsConfig={QS_CONFIG} // TODO: still used?
onRowClick={handleSelect}
toolbarSearchColumns={[
{
@ -155,6 +162,20 @@ function OrganizationsList({ i18n }) {
toolbarSearchableKeys={searchableKeys}
toolbarRelatedSearchableKeys={relatedSearchableKeys}
headerRow={
// TODO: move selectAll logic into HeaderRow?
<HeaderRow
handleSelectAll={handleSelectAll}
isAllSelected={isAllSelected}
defaultSortKey="name"
qsConfig={QS_CONFIG}
>
<HeaderCell sortKey="name">{i18n._(t`Name`)}</HeaderCell>
<HeaderCell>{i18n._(t`Members`)}</HeaderCell>
<HeaderCell>{i18n._(t`Teams`)}</HeaderCell>
</HeaderRow>
}
_headerRow={
// TODO: move sorting into <PaginatedTableHeader> w/ friendly API
<Thead>
<Tr>
<Th
@ -163,9 +184,42 @@ function OrganizationsList({ i18n }) {
isSelected: isAllSelected,
}}
/>
<Th>{i18n._(t`Name`)}</Th>
<Th>{i18n._(t`Members`)}</Th>
<Th>{i18n._(t`Teams`)}</Th>
<Th
sort={{
onSort,
sortBy: {
index: 'name',
direction: 'asc',
},
columnIndex: 'name',
}}
>
{i18n._(t`Name`)}
</Th>
<Th
sort={{
onSort,
sortBy: {
index: 'name',
direction: 'asc',
},
columnIndex: 'members',
}}
>
{i18n._(t`Members`)}
</Th>
<Th
sort={{
onSort,
sortBy: {
index: 'name',
direction: 'asc',
},
columnIndex: 'teams',
}}
>
{i18n._(t`Teams`)}
</Th>
</Tr>
</Thead>
}