CM: Allow list-view to be sorted by stages

This commit is contained in:
Gustav Hansen 2023-04-27 17:10:14 +02:00
parent 9de528d7d5
commit 476821033f
2 changed files with 60 additions and 47 deletions

View File

@ -24,7 +24,7 @@ export default (layout) => {
key: '__strapi_reviewWorkflows_stage_temp_key__', key: '__strapi_reviewWorkflows_stage_temp_key__',
name: 'strapi_reviewWorkflows_stage', name: 'strapi_reviewWorkflows_stage',
fieldSchema: { fieldSchema: {
type: 'custom', type: 'relation',
}, },
metadatas: { metadatas: {
label: formatMessage({ label: formatMessage({
@ -32,7 +32,8 @@ export default (layout) => {
defaultMessage: 'Review stage', defaultMessage: 'Review stage',
}), }),
searchable: false, searchable: false,
sortable: false, sortable: true,
mainField: 'name',
}, },
cellFormatter({ strapi_reviewWorkflows_stage }) { cellFormatter({ strapi_reviewWorkflows_stage }) {
// if entities are created e.g. through lifecycle methods // if entities are created e.g. through lifecycle methods

View File

@ -26,7 +26,6 @@ const TableHead = ({
const [{ query }, setQuery] = useQueryParams(); const [{ query }, setQuery] = useQueryParams();
const sort = query?.sort || ''; const sort = query?.sort || '';
const [sortBy, sortOrder] = sort.split(':'); const [sortBy, sortOrder] = sort.split(':');
const isIndeterminate = !areAllEntriesSelected && entriesToDelete.length > 0; const isIndeterminate = !areAllEntriesSelected && entriesToDelete.length > 0;
return ( return (
@ -45,54 +44,67 @@ const TableHead = ({
/> />
</Th> </Th>
)} )}
{headers.map(({ name, metadatas: { sortable: isSortable, label } }) => { {headers.map(
const isSorted = sortBy === name; ({ fieldSchema, name, metadatas: { sortable: isSortable, label, mainField } }) => {
const isUp = sortOrder === 'ASC'; let isSorted = sortBy === name;
const isUp = sortOrder === 'ASC';
const sortLabel = formatMessage( // relations always have to be sorted by their main field instead of only the
{ id: 'components.TableHeader.sort', defaultMessage: 'Sort on {label}' }, // attribute name; sortBy e.g. looks like: &sortBy=attributeName[mainField]:ASC
{ label } if (fieldSchema?.type === 'relation' && mainField) {
); isSorted = sortBy === `${name}[${mainField}]`;
const handleClickSort = (shouldAllowClick = true) => {
if (isSortable && shouldAllowClick) {
const nextSortOrder = isSorted && sortOrder === 'ASC' ? 'DESC' : 'ASC';
const nextSort = `${name}:${nextSortOrder}`;
setQuery({
sort: nextSort,
});
} }
};
return ( const sortLabel = formatMessage(
<Th { id: 'components.TableHeader.sort', defaultMessage: 'Sort on {label}' },
key={name} { label }
action={ );
isSorted && (
<IconButton const handleClickSort = (shouldAllowClick = true) => {
label={sortLabel} if (isSortable && shouldAllowClick) {
onClick={handleClickSort} let nextSort = name;
icon={isSorted && <SortIcon isUp={isUp} />}
noBorder // relations always have to be sorted by their main field instead of only the
/> // attribute name; nextSort e.g. looks like: &nextSort=attributeName[mainField]:ASC
) if (fieldSchema?.type === 'relation' && mainField) {
nextSort = `${name}[${mainField}]`;
}
setQuery({
sort: `${nextSort}:${isSorted && sortOrder === 'ASC' ? 'DESC' : 'ASC'}`,
});
} }
> };
<Tooltip label={isSortable ? sortLabel : label}>
<Typography return (
textColor="neutral600" <Th
as={!isSorted && isSortable ? 'button' : 'span'} key={name}
label={label} action={
onClick={() => handleClickSort(!isSorted)} isSorted && (
variant="sigma" <IconButton
> label={sortLabel}
{label} onClick={handleClickSort}
</Typography> icon={isSorted && <SortIcon isUp={isUp} />}
</Tooltip> noBorder
</Th> />
); )
})} }
>
<Tooltip label={isSortable ? sortLabel : label}>
<Typography
textColor="neutral600"
as={!isSorted && isSortable ? 'button' : 'span'}
label={label}
onClick={() => handleClickSort(!isSorted)}
variant="sigma"
>
{label}
</Typography>
</Tooltip>
</Th>
);
}
)}
{withBulkActions && ( {withBulkActions && (
<Th> <Th>