mirror of
https://github.com/ansible/awx.git
synced 2026-03-20 18:37:39 -02:30
add HeaderRow component with table sorting
This commit is contained in:
73
awx/ui_next/src/components/PaginatedTable/HeaderRow.jsx
Normal file
73
awx/ui_next/src/components/PaginatedTable/HeaderRow.jsx
Normal 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>;
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
export { default } from './PaginatedTable';
|
export { default } from './PaginatedTable';
|
||||||
export { default as PaginatedTableRow } from './PaginatedTableRow';
|
export { default as PaginatedTableRow } from './PaginatedTableRow';
|
||||||
export { default as ActionsTd } from './ActionsTd';
|
export { default as ActionsTd } from './ActionsTd';
|
||||||
|
export { default as HeaderRow, HeaderCell } from './HeaderRow';
|
||||||
// export { default as ToolbarDeleteButton } from './ToolbarDeleteButton';
|
// export { default as ToolbarDeleteButton } from './ToolbarDeleteButton';
|
||||||
// export { default as ToolbarAddButton } from './ToolbarAddButton';
|
// export { default as ToolbarAddButton } from './ToolbarAddButton';
|
||||||
|
|||||||
@@ -14,7 +14,10 @@ import {
|
|||||||
ToolbarAddButton,
|
ToolbarAddButton,
|
||||||
ToolbarDeleteButton,
|
ToolbarDeleteButton,
|
||||||
} from '../../../components/PaginatedDataList';
|
} from '../../../components/PaginatedDataList';
|
||||||
import PaginatedTable from '../../../components/PaginatedTable';
|
import PaginatedTable, {
|
||||||
|
HeaderRow,
|
||||||
|
HeaderCell,
|
||||||
|
} from '../../../components/PaginatedTable';
|
||||||
import { getQSConfig, parseQueryString } from '../../../util/qs';
|
import { getQSConfig, parseQueryString } from '../../../util/qs';
|
||||||
import OrganizationListItem from './OrganizationListItem';
|
import OrganizationListItem from './OrganizationListItem';
|
||||||
|
|
||||||
@@ -115,6 +118,10 @@ function OrganizationsList({ i18n }) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onSort = (e, index, direction) => {
|
||||||
|
console.log(index, direction);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageSection>
|
<PageSection>
|
||||||
@@ -125,7 +132,7 @@ function OrganizationsList({ i18n }) {
|
|||||||
items={organizations}
|
items={organizations}
|
||||||
itemCount={organizationCount}
|
itemCount={organizationCount}
|
||||||
pluralizedItemName={i18n._(t`Organizations`)}
|
pluralizedItemName={i18n._(t`Organizations`)}
|
||||||
qsConfig={QS_CONFIG}
|
qsConfig={QS_CONFIG} // TODO: still used?
|
||||||
onRowClick={handleSelect}
|
onRowClick={handleSelect}
|
||||||
toolbarSearchColumns={[
|
toolbarSearchColumns={[
|
||||||
{
|
{
|
||||||
@@ -155,6 +162,20 @@ function OrganizationsList({ i18n }) {
|
|||||||
toolbarSearchableKeys={searchableKeys}
|
toolbarSearchableKeys={searchableKeys}
|
||||||
toolbarRelatedSearchableKeys={relatedSearchableKeys}
|
toolbarRelatedSearchableKeys={relatedSearchableKeys}
|
||||||
headerRow={
|
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>
|
<Thead>
|
||||||
<Tr>
|
<Tr>
|
||||||
<Th
|
<Th
|
||||||
@@ -163,9 +184,42 @@ function OrganizationsList({ i18n }) {
|
|||||||
isSelected: isAllSelected,
|
isSelected: isAllSelected,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Th>{i18n._(t`Name`)}</Th>
|
<Th
|
||||||
<Th>{i18n._(t`Members`)}</Th>
|
sort={{
|
||||||
<Th>{i18n._(t`Teams`)}</Th>
|
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>
|
</Tr>
|
||||||
</Thead>
|
</Thead>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user