mirror of
https://github.com/ansible/awx.git
synced 2026-05-19 23:07:42 -02:30
convert PaginatedTable to function component
This commit is contained in:
@@ -23,7 +23,7 @@ export default function HeaderRow({
|
|||||||
const onSort = (key, order) => {
|
const onSort = (key, order) => {
|
||||||
console.log({ key, order });
|
console.log({ key, order });
|
||||||
const newParams = replaceParams(params, {
|
const newParams = replaceParams(params, {
|
||||||
order_by: order === 'desc' ? key : `-${key}`,
|
order_by: order === 'asc' ? key : `-${key}`,
|
||||||
page: null,
|
page: null,
|
||||||
});
|
});
|
||||||
const encodedParams = encodeNonDefaultQueryString(qsConfig, newParams);
|
const encodedParams = encodeNonDefaultQueryString(qsConfig, newParams);
|
||||||
@@ -37,7 +37,7 @@ export default function HeaderRow({
|
|||||||
const sortKey = params.order_by?.replace('-', '');
|
const sortKey = params.order_by?.replace('-', '');
|
||||||
const sortBy = {
|
const sortBy = {
|
||||||
index: sortKey || defaultSortKey,
|
index: sortKey || defaultSortKey,
|
||||||
direction: params.order_by?.startsWith('-') ? 'asc' : 'desc',
|
direction: params.order_by?.startsWith('-') ? 'desc' : 'asc',
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|||||||
import { TableComposable, Tbody } from '@patternfly/react-table';
|
import { TableComposable, Tbody } from '@patternfly/react-table';
|
||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { withRouter } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
import ListHeader from '../ListHeader';
|
import ListHeader from '../ListHeader';
|
||||||
import ContentEmpty from '../ContentEmpty';
|
import ContentEmpty from '../ContentEmpty';
|
||||||
@@ -17,173 +17,155 @@ import {
|
|||||||
parseQueryString,
|
parseQueryString,
|
||||||
replaceParams,
|
replaceParams,
|
||||||
} from '../../util/qs';
|
} from '../../util/qs';
|
||||||
|
import PaginatedTableRow from './PaginatedTableRow';
|
||||||
import { QSConfig, SearchColumns, SortColumns } from '../../types';
|
import { QSConfig, SearchColumns, SortColumns } from '../../types';
|
||||||
|
|
||||||
import PaginatedTableRow from './PaginatedTableRow';
|
function PaginatedTable({
|
||||||
|
contentError,
|
||||||
|
hasContentLoading,
|
||||||
|
emptyStateControls,
|
||||||
|
items,
|
||||||
|
itemCount,
|
||||||
|
qsConfig,
|
||||||
|
headerRow,
|
||||||
|
renderRow,
|
||||||
|
toolbarSearchColumns,
|
||||||
|
toolbarSearchableKeys,
|
||||||
|
toolbarRelatedSearchableKeys,
|
||||||
|
toolbarSortColumns,
|
||||||
|
pluralizedItemName,
|
||||||
|
showPageSizeOptions,
|
||||||
|
i18n,
|
||||||
|
renderToolbar,
|
||||||
|
// onRowClick,
|
||||||
|
}) {
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
class PaginatedTable extends React.Component {
|
// const handleListItemSelect = (id = 0) => {
|
||||||
constructor(props) {
|
// const match = items.find(item => item.id === Number(id));
|
||||||
super(props);
|
// onRowClick(match);
|
||||||
this.handleSetPage = this.handleSetPage.bind(this);
|
// };
|
||||||
this.handleSetPageSize = this.handleSetPageSize.bind(this);
|
|
||||||
this.handleListItemSelect = this.handleListItemSelect.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleListItemSelect = (id = 0) => {
|
const pushHistoryState = params => {
|
||||||
const { items, onRowClick } = this.props;
|
|
||||||
const match = items.find(item => item.id === Number(id));
|
|
||||||
onRowClick(match);
|
|
||||||
};
|
|
||||||
|
|
||||||
handleSetPage(event, pageNumber) {
|
|
||||||
const { history, qsConfig } = this.props;
|
|
||||||
const { search } = history.location;
|
|
||||||
const oldParams = parseQueryString(qsConfig, search);
|
|
||||||
this.pushHistoryState(replaceParams(oldParams, { page: pageNumber }));
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSetPageSize(event, pageSize, page) {
|
|
||||||
const { history, qsConfig } = this.props;
|
|
||||||
const { search } = history.location;
|
|
||||||
const oldParams = parseQueryString(qsConfig, search);
|
|
||||||
this.pushHistoryState(
|
|
||||||
replaceParams(oldParams, { page_size: pageSize, page })
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pushHistoryState(params) {
|
|
||||||
const { history, qsConfig } = this.props;
|
|
||||||
const { pathname } = history.location;
|
const { pathname } = history.location;
|
||||||
const encodedParams = encodeNonDefaultQueryString(qsConfig, params);
|
const encodedParams = encodeNonDefaultQueryString(qsConfig, params);
|
||||||
history.push(encodedParams ? `${pathname}?${encodedParams}` : pathname);
|
history.push(encodedParams ? `${pathname}?${encodedParams}` : pathname);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSetPage = (event, pageNumber) => {
|
||||||
|
const oldParams = parseQueryString(qsConfig, history.location.search);
|
||||||
|
pushHistoryState(replaceParams(oldParams, { page: pageNumber }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSetPageSize = (event, pageSize, page) => {
|
||||||
|
const oldParams = parseQueryString(qsConfig, history.location.search);
|
||||||
|
pushHistoryState(replaceParams(oldParams, { page_size: pageSize, page }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const searchColumns = toolbarSearchColumns.length
|
||||||
|
? toolbarSearchColumns
|
||||||
|
: [
|
||||||
|
{
|
||||||
|
name: i18n._(t`Name`),
|
||||||
|
key: 'name',
|
||||||
|
isDefault: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const sortColumns = toolbarSortColumns.length
|
||||||
|
? toolbarSortColumns
|
||||||
|
: [
|
||||||
|
{
|
||||||
|
name: i18n._(t`Name`),
|
||||||
|
key: 'name',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const queryParams = parseQueryString(qsConfig, history.location.search);
|
||||||
|
|
||||||
|
const dataListLabel = i18n._(t`${pluralizedItemName} List`);
|
||||||
|
const emptyContentMessage = i18n._(
|
||||||
|
t`Please add ${pluralizedItemName} to populate this list `
|
||||||
|
);
|
||||||
|
const emptyContentTitle = i18n._(t`No ${pluralizedItemName} Found `);
|
||||||
|
|
||||||
|
let Content;
|
||||||
|
if (hasContentLoading && items.length <= 0) {
|
||||||
|
Content = <ContentLoading />;
|
||||||
|
} else if (contentError) {
|
||||||
|
Content = <ContentError error={contentError} />;
|
||||||
|
} else if (items.length <= 0) {
|
||||||
|
Content = (
|
||||||
|
<ContentEmpty title={emptyContentTitle} message={emptyContentMessage} />
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Content = (
|
||||||
|
<TableComposable
|
||||||
|
aria-label={dataListLabel}
|
||||||
|
// onSelectDataListItem={handleListItemSelect}
|
||||||
|
>
|
||||||
|
{headerRow}
|
||||||
|
<Tbody>{items.map(renderRow)}</Tbody>
|
||||||
|
</TableComposable>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
const ToolbarPagination = (
|
||||||
const {
|
<Pagination
|
||||||
contentError,
|
isCompact
|
||||||
hasContentLoading,
|
dropDirection="down"
|
||||||
emptyStateControls,
|
itemCount={itemCount}
|
||||||
items,
|
page={queryParams.page || 1}
|
||||||
itemCount,
|
perPage={queryParams.page_size}
|
||||||
qsConfig,
|
perPageOptions={
|
||||||
headerRow,
|
showPageSizeOptions
|
||||||
renderRow,
|
? [
|
||||||
toolbarSearchColumns,
|
{ title: '5', value: 5 },
|
||||||
toolbarSearchableKeys,
|
{ title: '10', value: 10 },
|
||||||
toolbarRelatedSearchableKeys,
|
{ title: '20', value: 20 },
|
||||||
toolbarSortColumns,
|
{ title: '50', value: 50 },
|
||||||
pluralizedItemName,
|
]
|
||||||
showPageSizeOptions,
|
: []
|
||||||
location,
|
}
|
||||||
i18n,
|
onSetPage={handleSetPage}
|
||||||
renderToolbar,
|
onPerPageSelect={handleSetPageSize}
|
||||||
} = this.props;
|
/>
|
||||||
const searchColumns = toolbarSearchColumns.length
|
);
|
||||||
? toolbarSearchColumns
|
|
||||||
: [
|
|
||||||
{
|
|
||||||
name: i18n._(t`Name`),
|
|
||||||
key: 'name',
|
|
||||||
isDefault: true,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const sortColumns = toolbarSortColumns.length
|
|
||||||
? toolbarSortColumns
|
|
||||||
: [
|
|
||||||
{
|
|
||||||
name: i18n._(t`Name`),
|
|
||||||
key: 'name',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const queryParams = parseQueryString(qsConfig, location.search);
|
|
||||||
|
|
||||||
const dataListLabel = i18n._(t`${pluralizedItemName} List`);
|
return (
|
||||||
const emptyContentMessage = i18n._(
|
<Fragment>
|
||||||
t`Please add ${pluralizedItemName} to populate this list `
|
<ListHeader
|
||||||
);
|
|
||||||
const emptyContentTitle = i18n._(t`No ${pluralizedItemName} Found `);
|
|
||||||
|
|
||||||
let Content;
|
|
||||||
if (hasContentLoading && items.length <= 0) {
|
|
||||||
Content = <ContentLoading />;
|
|
||||||
} else if (contentError) {
|
|
||||||
Content = <ContentError error={contentError} />;
|
|
||||||
} else if (items.length <= 0) {
|
|
||||||
Content = (
|
|
||||||
<ContentEmpty title={emptyContentTitle} message={emptyContentMessage} />
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
Content = (
|
|
||||||
<TableComposable
|
|
||||||
aria-label={dataListLabel}
|
|
||||||
onSelectDataListItem={id => this.handleListItemSelect(id)}
|
|
||||||
>
|
|
||||||
{headerRow}
|
|
||||||
<Tbody>{items.map(renderRow)}</Tbody>
|
|
||||||
</TableComposable>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const ToolbarPagination = (
|
|
||||||
<Pagination
|
|
||||||
isCompact
|
|
||||||
dropDirection="down"
|
|
||||||
itemCount={itemCount}
|
itemCount={itemCount}
|
||||||
page={queryParams.page || 1}
|
renderToolbar={renderToolbar}
|
||||||
perPage={queryParams.page_size}
|
emptyStateControls={emptyStateControls}
|
||||||
perPageOptions={
|
searchColumns={searchColumns}
|
||||||
showPageSizeOptions
|
sortColumns={sortColumns}
|
||||||
? [
|
searchableKeys={toolbarSearchableKeys}
|
||||||
{ title: '5', value: 5 },
|
relatedSearchableKeys={toolbarRelatedSearchableKeys}
|
||||||
{ title: '10', value: 10 },
|
qsConfig={qsConfig}
|
||||||
{ title: '20', value: 20 },
|
pagination={ToolbarPagination}
|
||||||
{ title: '50', value: 50 },
|
|
||||||
]
|
|
||||||
: []
|
|
||||||
}
|
|
||||||
onSetPage={this.handleSetPage}
|
|
||||||
onPerPageSelect={this.handleSetPageSize}
|
|
||||||
/>
|
/>
|
||||||
);
|
{Content}
|
||||||
|
{items.length ? (
|
||||||
return (
|
<Pagination
|
||||||
<Fragment>
|
variant="bottom"
|
||||||
<ListHeader
|
|
||||||
itemCount={itemCount}
|
itemCount={itemCount}
|
||||||
renderToolbar={renderToolbar}
|
page={queryParams.page || 1}
|
||||||
emptyStateControls={emptyStateControls}
|
perPage={queryParams.page_size}
|
||||||
searchColumns={searchColumns}
|
perPageOptions={
|
||||||
sortColumns={sortColumns}
|
showPageSizeOptions
|
||||||
searchableKeys={toolbarSearchableKeys}
|
? [
|
||||||
relatedSearchableKeys={toolbarRelatedSearchableKeys}
|
{ title: '5', value: 5 },
|
||||||
qsConfig={qsConfig}
|
{ title: '10', value: 10 },
|
||||||
pagination={ToolbarPagination}
|
{ title: '20', value: 20 },
|
||||||
|
{ title: '50', value: 50 },
|
||||||
|
]
|
||||||
|
: []
|
||||||
|
}
|
||||||
|
onSetPage={handleSetPage}
|
||||||
|
onPerPageSelect={handleSetPageSize}
|
||||||
/>
|
/>
|
||||||
{Content}
|
) : null}
|
||||||
{items.length ? (
|
</Fragment>
|
||||||
<Pagination
|
);
|
||||||
variant="bottom"
|
|
||||||
itemCount={itemCount}
|
|
||||||
page={queryParams.page || 1}
|
|
||||||
perPage={queryParams.page_size}
|
|
||||||
perPageOptions={
|
|
||||||
showPageSizeOptions
|
|
||||||
? [
|
|
||||||
{ title: '5', value: 5 },
|
|
||||||
{ title: '10', value: 10 },
|
|
||||||
{ title: '20', value: 20 },
|
|
||||||
{ title: '50', value: 50 },
|
|
||||||
]
|
|
||||||
: []
|
|
||||||
}
|
|
||||||
onSetPage={this.handleSetPage}
|
|
||||||
onPerPageSelect={this.handleSetPageSize}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Item = PropTypes.shape({
|
const Item = PropTypes.shape({
|
||||||
@@ -206,7 +188,7 @@ PaginatedTable.propTypes = {
|
|||||||
renderToolbar: PropTypes.func,
|
renderToolbar: PropTypes.func,
|
||||||
hasContentLoading: PropTypes.bool,
|
hasContentLoading: PropTypes.bool,
|
||||||
contentError: PropTypes.shape(),
|
contentError: PropTypes.shape(),
|
||||||
onRowClick: PropTypes.func,
|
// onRowClick: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
PaginatedTable.defaultProps = {
|
PaginatedTable.defaultProps = {
|
||||||
@@ -220,8 +202,8 @@ PaginatedTable.defaultProps = {
|
|||||||
showPageSizeOptions: true,
|
showPageSizeOptions: true,
|
||||||
renderRow: item => <PaginatedTableRow key={item.id} item={item} />,
|
renderRow: item => <PaginatedTableRow key={item.id} item={item} />,
|
||||||
renderToolbar: props => <DataListToolbar {...props} />,
|
renderToolbar: props => <DataListToolbar {...props} />,
|
||||||
onRowClick: () => null,
|
// onRowClick: () => null,
|
||||||
};
|
};
|
||||||
|
|
||||||
export { PaginatedTable as _PaginatedTable };
|
export { PaginatedTable as _PaginatedTable };
|
||||||
export default withI18n()(withRouter(PaginatedTable));
|
export default withI18n()(PaginatedTable);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { useLocation, useRouteMatch } from 'react-router-dom';
|
|||||||
import { withI18n } from '@lingui/react';
|
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 { Thead, Tr, Th } from '@patternfly/react-table';
|
|
||||||
|
|
||||||
import { OrganizationsAPI } from '../../../api';
|
import { OrganizationsAPI } from '../../../api';
|
||||||
import useRequest, { useDeleteItems } from '../../../util/useRequest';
|
import useRequest, { useDeleteItems } from '../../../util/useRequest';
|
||||||
@@ -118,10 +117,6 @@ function OrganizationsList({ i18n }) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSort = (e, index, direction) => {
|
|
||||||
console.log(index, direction);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageSection>
|
<PageSection>
|
||||||
@@ -174,55 +169,6 @@ function OrganizationsList({ i18n }) {
|
|||||||
<HeaderCell>{i18n._(t`Teams`)}</HeaderCell>
|
<HeaderCell>{i18n._(t`Teams`)}</HeaderCell>
|
||||||
</HeaderRow>
|
</HeaderRow>
|
||||||
}
|
}
|
||||||
_headerRow={
|
|
||||||
// TODO: move sorting into <PaginatedTableHeader> w/ friendly API
|
|
||||||
<Thead>
|
|
||||||
<Tr>
|
|
||||||
<Th
|
|
||||||
select={{
|
|
||||||
onSelect: handleSelectAll,
|
|
||||||
isSelected: isAllSelected,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<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>
|
|
||||||
}
|
|
||||||
renderToolbar={props => (
|
renderToolbar={props => (
|
||||||
<DataListToolbar
|
<DataListToolbar
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
Reference in New Issue
Block a user