integrated sort to table list view

This commit is contained in:
Julie Plantey 2022-11-22 15:18:28 +01:00
parent 1d8d318135
commit f2fdfda42d
5 changed files with 95 additions and 14 deletions

View File

@ -2,9 +2,13 @@ import React from 'react';
import PropTypes from 'prop-types';
import { useIntl } from 'react-intl';
import { BaseCheckbox } from '@strapi/design-system/BaseCheckbox';
import { IconButton } from '@strapi/design-system/IconButton';
import { Table, Th, Thead, Tr } from '@strapi/design-system/Table';
import { Tooltip } from '@strapi/design-system/Tooltip';
import { Typography } from '@strapi/design-system/Typography';
import { VisuallyHidden } from '@strapi/design-system/VisuallyHidden';
import CarretDown from '@strapi/icons/CarretDown';
import CarretUp from '@strapi/icons/CarretUp';
import { getTrad } from '../../utils';
import { AssetDefinition, tableHeaders, FolderDefinition } from '../../constants';
@ -14,14 +18,17 @@ export const TableList = ({
assetCount,
folderCount,
indeterminate,
onChangeSort,
onEditAsset,
onEditFolder,
onSelectAll,
onSelectOne,
rows,
selected,
sortQuery,
}) => {
const { formatMessage } = useIntl();
const [sortBy, sortOrder] = sortQuery.split(':');
return (
<Table colCount={tableHeaders.length + 2} rowCount={assetCount + folderCount + 1}>
@ -40,12 +47,55 @@ export const TableList = ({
}
/>
</Th>
{tableHeaders.map(({ metadatas, key }) => {
{tableHeaders.map(({ metadatas: { label, isSortable }, name, key }) => {
const isSorted = sortBy === name;
const isUp = sortOrder === 'ASC';
const tableHeaderLabel = formatMessage(label);
const sortLabel = formatMessage(
{ id: 'list-table-header-sort', defaultMessage: 'Sort on {label}' },
{ label: tableHeaderLabel }
);
const handleClickSort = () => {
if (isSortable) {
const nextSortOrder = isSorted && sortOrder === 'ASC' ? 'DESC' : 'ASC';
const nextSort = `${name}:${nextSortOrder}`;
onChangeSort(nextSort);
}
};
return (
<Th key={key}>
<Typography textColor="neutral600" variant="sigma">
{formatMessage(metadatas.label)}
</Typography>
<Th
action={
isSorted && (
<IconButton
label={sortLabel}
onClick={handleClickSort}
icon={isUp ? <CarretUp /> : <CarretDown />}
noBorder
/>
)
}
key={key}
>
{isSortable ? (
<Tooltip label={sortLabel}>
<Typography
onClick={() => handleClickSort(!isSorted)}
as={isSorted ? 'span' : 'button'}
label={!isSorted ? sortLabel : ''}
textColor="neutral600"
variant="sigma"
>
{tableHeaderLabel}
</Typography>
</Tooltip>
) : (
<Typography textColor="neutral600" variant="sigma">
{tableHeaderLabel}
</Typography>
)}
</Th>
);
})}
@ -74,20 +124,24 @@ TableList.defaultProps = {
assetCount: 0,
folderCount: 0,
indeterminate: false,
onChangeSort: null,
onEditAsset: null,
onEditFolder: null,
rows: [],
selected: [],
sortQuery: '',
};
TableList.propTypes = {
assetCount: PropTypes.number,
folderCount: PropTypes.number,
indeterminate: PropTypes.bool,
onChangeSort: PropTypes.func,
onEditAsset: PropTypes.func,
onEditFolder: PropTypes.func,
onSelectAll: PropTypes.func.isRequired,
onSelectOne: PropTypes.func.isRequired,
rows: PropTypes.arrayOf(AssetDefinition, FolderDefinition),
selected: PropTypes.arrayOf(AssetDefinition, FolderDefinition),
sortQuery: PropTypes.string,
};

View File

@ -1,6 +1,6 @@
import React from 'react';
import { IntlProvider } from 'react-intl';
import { render } from '@testing-library/react';
import { render, fireEvent } from '@testing-library/react';
import { ThemeProvider, lightTheme } from '@strapi/design-system';
import { TableList } from '..';
@ -71,6 +71,30 @@ describe('TableList', () => {
expect(getByRole('columnheader', { name: 'actions' })).toBeInTheDocument();
});
it('should call onChangeSort callback when changing sort order', () => {
const onChangeSortSpy = jest.fn();
const { getByRole } = setup({ sortQuery: 'updatedAt:ASC', onChangeSort: onChangeSortSpy });
const sortButton = getByRole('button', { name: 'Sort on last update' });
expect(sortButton).toBeInTheDocument();
fireEvent.click(sortButton);
expect(onChangeSortSpy).toHaveBeenCalledWith('updatedAt:DESC');
});
it('should call onChangeSort callback when changing sort by', () => {
const onChangeSortSpy = jest.fn();
const { getByRole } = setup({ sortQuery: 'updatedAt:ASC', onChangeSort: onChangeSortSpy });
const sortButton = getByRole('button', { name: 'Sort on name' });
expect(sortButton).toBeInTheDocument();
fireEvent.click(sortButton);
expect(onChangeSortSpy).toHaveBeenCalledWith('name:ASC');
});
it('should render assets', () => {
const { getByText } = setup();

View File

@ -103,7 +103,7 @@ export const tableHeaders = [
key: 'preview',
metadatas: {
label: { id: getTrad('list-table-header-preview'), defaultMessage: 'preview' },
sortable: false,
isSortable: false,
},
type: 'image',
},
@ -112,7 +112,7 @@ export const tableHeaders = [
key: 'name',
metadatas: {
label: { id: getTrad('list-table-header-name'), defaultMessage: 'name' },
sortable: true,
isSortable: true,
},
type: 'text',
},
@ -121,7 +121,7 @@ export const tableHeaders = [
key: 'extension',
metadatas: {
label: { id: getTrad('list-table-header-ext'), defaultMessage: 'extension' },
sortable: false,
isSortable: false,
},
type: 'ext',
},
@ -130,7 +130,7 @@ export const tableHeaders = [
key: 'size',
metadatas: {
label: { id: getTrad('list-table-header-size'), defaultMessage: 'size' },
sortable: false,
isSortable: false,
},
type: 'size',
},
@ -139,7 +139,7 @@ export const tableHeaders = [
key: 'createdAt',
metadatas: {
label: { id: getTrad('list-table-header-createdAt'), defaultMessage: 'created' },
sortable: true,
isSortable: true,
},
type: 'date',
},
@ -148,7 +148,7 @@ export const tableHeaders = [
key: 'updatedAt',
metadatas: {
label: { id: getTrad('list-table-header-updatedAt'), defaultMessage: 'last update' },
sortable: true,
isSortable: true,
},
type: 'date',
},

View File

@ -244,6 +244,7 @@ export const MediaLibrary = () => {
assetCount={assetCount}
folderCount={folderCount}
indeterminate={indeterminateBulkSelect}
onChangeSort={handleChangeSort}
onEditAsset={setAssetToEdit}
onEditFolder={handleEditFolder}
onSelectOne={selectOne}
@ -255,6 +256,7 @@ export const MediaLibrary = () => {
!assetsLoading && !foldersLoading ? [...folders, ...assets] : []
}
selected={selected}
sortQuery={query?.sort}
/>
)}

View File

@ -119,8 +119,9 @@
"list-table-header-name": "name",
"list-table-header-ext": "extension",
"list-table-header-size": "size",
"list-table-header-createdAt": "Created",
"list-table-header-updatedAt": "Last update",
"list-table-header-createdAt": "created",
"list-table-header-updatedAt": "last update",
"list-table-header-sort": "Sort on {label}",
"tabs.title": "How do you want to upload your assets?",
"window.confirm.close-modal.file": "Are you sure? Your changes will be lost.",
"window.confirm.close-modal.files": "Are you sure? You have some files that have not been uploaded yet."