Skip to content

Commit 41d65c7

Browse files
feat: sort columns in discover and report tabs (#338)
* feat: enabling sort in content and updatedAt columns * chore: fix build and refresh yarn lock * chore: changed lockfile
1 parent 7d80dbe commit 41d65c7

File tree

6 files changed

+129
-81
lines changed

6 files changed

+129
-81
lines changed

admin/src/components/CommentStatusFilters/index.tsx

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { FC, useState } from "react"
1+
import { useState } from "react";
22
import { getMessage } from "../../utils";
3-
import { COMMENT_STATUS } from '../../utils/constants';
4-
import { SingleSelect, SingleSelectOption } from '@strapi/design-system';
3+
import { COMMENT_STATUS } from "../../utils/constants";
4+
import { SingleSelect, SingleSelectOption } from "@strapi/design-system";
5+
import { useQueryParams } from "@strapi/strapi/admin";
56

67
const COMMENT_OPTIONS = [
78
COMMENT_STATUS.OPEN,
@@ -10,61 +11,51 @@ const COMMENT_OPTIONS = [
1011
COMMENT_STATUS.APPROVED,
1112
COMMENT_STATUS.REJECTED,
1213
COMMENT_STATUS.PENDING,
13-
]
14+
];
1415

1516
const getFilter = (filterName: string | undefined) => {
16-
switch(filterName) {
17+
switch (filterName) {
1718
case COMMENT_STATUS.BLOCKED:
1819
return {
19-
$or: [
20-
{ blocked: { $eq: true } },
21-
{ blockedThread: { $eq: true } },
22-
],
23-
}
20+
$or: [{ blocked: { $eq: true } }, { blockedThread: { $eq: true } }],
21+
};
2422
case COMMENT_STATUS.REMOVED:
2523
return {
26-
$or: [
27-
{ blocked: { $eq: true } },
28-
{ blockedThread: { $eq: true } },
29-
],
30-
}
24+
$or: [{ blocked: { $eq: true } }, { blockedThread: { $eq: true } }],
25+
};
3126
case COMMENT_STATUS.OPEN:
3227
return {
3328
approvalStatus: { $null: true },
34-
}
29+
};
3530
case undefined:
36-
return {}
31+
return {};
3732
default:
3833
return {
3934
approvalStatus: { $eq: filterName },
40-
}
35+
};
4136
}
42-
}
43-
44-
type CommentStatusFiltersProps = {
45-
setQueryParams: (nextParams: object, method?: "push" | "remove", replace?: boolean) => void;
4637
};
4738

48-
export const CommentsStatusFilters: FC<CommentStatusFiltersProps> = ({ setQueryParams }) => {
39+
export const CommentsStatusFilters = () => {
40+
const [_, setQueryParams] = useQueryParams();
4941
const [currentFilter, setCurrentFilter] = useState<string>();
5042

5143
const handleChange = (filter: string | undefined) => {
52-
setCurrentFilter(filter)
44+
setCurrentFilter(filter);
5345
setQueryParams({
5446
page: {},
55-
pageSize: {},
56-
filters: getFilter(filter)
47+
filters: getFilter(filter),
5748
});
58-
}
49+
};
5950

6051
return (
6152
<SingleSelect
62-
placeholder={getMessage('page.common.item.status.setFilter')}
53+
placeholder={getMessage("page.common.item.status.setFilter")}
6354
value={currentFilter}
6455
onClear={() => handleChange(undefined)}
6556
onChange={handleChange}
6657
>
67-
{COMMENT_OPTIONS.map(option => (
58+
{COMMENT_OPTIONS.map((option) => (
6859
<SingleSelectOption value={option}>
6960
{getMessage(`page.common.item.status.${option}`)}
7061
</SingleSelectOption>

admin/src/components/ReportReasonBadge/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export const ReportReasonBadge: FC<Pick<CommentReport, 'reason'>> = ({ reason })
2525
>
2626
{getMessage(
2727
`page.details.panel.discussion.warnings.reports.dialog.reason.${reason}`,
28-
reason,
28+
reason || '',
2929
)}
3030
</StatusBadge>
3131
);
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { FC } from "react";
2+
import { Th, Typography } from "@strapi/design-system";
3+
import { ChevronDown, ChevronUp } from "@strapi/icons";
4+
import { useQueryParams } from "@strapi/strapi/admin";
5+
6+
type SortQueryParams = {
7+
orderBy?: string;
8+
page?: object;
9+
pageSize?: object;
10+
};
11+
12+
const getChangedOrder = (orderByKey: string, order: string | undefined) => {
13+
switch (order) {
14+
case "asc":
15+
case "ASC":
16+
return `${orderByKey}:desc`;
17+
case "desc":
18+
case "DESC":
19+
default:
20+
return `${orderByKey}:asc`;
21+
}
22+
};
23+
24+
type SortableThProps = {
25+
label: string;
26+
orderByKey: string;
27+
};
28+
29+
export const SortableTh: FC<SortableThProps> = ({ label, orderByKey }) => {
30+
const [{ query: queryParams }, setQueryParams] =
31+
useQueryParams<SortQueryParams>();
32+
33+
const { orderBy = ":" } = queryParams;
34+
const key = orderBy.split(":")[0];
35+
const order = orderBy.split(":").pop()?.toLowerCase();
36+
37+
const handleSort = () => {
38+
setQueryParams({
39+
page: {},
40+
orderBy: getChangedOrder(orderByKey, order),
41+
});
42+
};
43+
44+
return (
45+
<Th onClick={handleSort} style={{ cursor: "pointer" }}>
46+
<Typography variant="sigma" style={{ marginRight: "8px" }}>
47+
{label}
48+
</Typography>
49+
{`${key}:${order}` === `${orderByKey}:asc` && (
50+
<ChevronDown />
51+
)}
52+
{`${key}:${order}` === `${orderByKey}:desc` && (
53+
<ChevronUp />
54+
)}
55+
</Th>
56+
);
57+
};

admin/src/pages/Discover/index.tsx

Lines changed: 27 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,19 @@ import { FC } from 'react';
44
import { Config } from '../../api/schemas';
55
import { CommentRow } from '../../components/CommentRow';
66
import { CommentsStatusFilters } from '../../components/CommentStatusFilters';
7+
import { SortableTh } from '../../components/SortableTh';
78
import { useCommentsAll } from '../../hooks/useCommentsAll';
89
import { getMessage } from '../../utils';
910

11+
const tableHeaders = [
12+
{ label: "page.discover.table.header.id" },
13+
{ label: "page.discover.table.header.author" },
14+
{ label: "page.discover.table.header.message", orderBy: "content" },
15+
{ label: "page.discover.table.header.thread" },
16+
{ label: "page.discover.table.header.entry" },
17+
{ label: "page.discover.table.header.lastUpdate", orderBy: "updatedAt" },
18+
{ label: "page.discover.table.header.status" },
19+
];
1020

1121
export const Discover: FC<{ config: Config }> = ({ config }) => {
1222
const [{ query: queryParams }, setQueryParams] = useQueryParams();
@@ -33,48 +43,29 @@ export const Discover: FC<{ config: Config }> = ({ config }) => {
3343
<Layouts.Action startActions={
3444
<>
3545
<SearchInput label={getMessage('common.search', "Search")} />
36-
<CommentsStatusFilters setQueryParams={setQueryParams}/>
46+
<CommentsStatusFilters />
3747
</>
3848
}/>
3949
<Layouts.Content>
4050
<Table>
4151
<Thead>
4252
<Tr>
43-
<Th>
44-
<Typography variant="sigma">
45-
{getMessage('page.discover.table.header.id')}
46-
</Typography>
47-
</Th>
48-
<Th>
49-
<Typography variant="sigma">
50-
{getMessage('page.discover.table.header.author')}
51-
</Typography>
52-
</Th>
53-
<Th>
54-
<Typography variant="sigma">
55-
{getMessage('page.discover.table.header.message')}
56-
</Typography>
57-
</Th>
58-
<Th>
59-
<Typography variant="sigma">
60-
{getMessage('page.discover.table.header.thread')}
61-
</Typography>
62-
</Th>
63-
<Th>
64-
<Typography variant="sigma">
65-
{getMessage('page.discover.table.header.entry')}
66-
</Typography>
67-
</Th>
68-
<Th>
69-
<Typography variant="sigma">
70-
{getMessage('page.discover.table.header.lastUpdate')}
71-
</Typography>
72-
</Th>
73-
<Th>
74-
<Typography variant="sigma">
75-
{getMessage('page.discover.table.header.status')}
76-
</Typography>
77-
</Th>
53+
{tableHeaders.map(({ label, orderBy }) => (
54+
<>
55+
{!orderBy ? (
56+
<Th>
57+
<Typography variant="sigma">
58+
{getMessage(label)}
59+
</Typography>
60+
</Th>
61+
) : (
62+
<SortableTh
63+
label={getMessage(label)}
64+
orderByKey={orderBy}
65+
/>
66+
)}
67+
</>
68+
))}
7869
<Th />
7970
</Tr>
8071
</Thead>

admin/src/pages/Reports/index.tsx

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,22 @@ import { useQueryClient } from '@tanstack/react-query';
55
import React, { FC, useCallback, useState } from 'react';
66
import { Config } from '../../api/schemas';
77
import { ReportsTableRow } from '../../components/ReportsTableRow';
8+
import { SortableTh } from '../../components/SortableTh';
89
import { useAPI } from '../../hooks/useAPI';
910
import { useCommentMutations } from '../../hooks/useCommentMutations';
1011
import { useReports } from '../../hooks/useReports';
1112
import { getMessage } from '../../utils';
1213

1314
const tableHeaders = [
14-
'page.reports.table.header.id',
15-
'page.reports.table.header.reason',
16-
'page.reports.table.header.content',
17-
'page.reports.table.header.status',
18-
'page.reports.table.header.issueDate',
19-
'page.reports.table.header.relatedComment',
20-
'page.reports.table.header.actions',
15+
{ label: "page.reports.table.header.id" },
16+
{ label: "page.reports.table.header.reason" },
17+
{ label: "page.reports.table.header.content", orderBy: "content" },
18+
{ label: "page.reports.table.header.status" },
19+
{ label: "page.reports.table.header.issueDate", orderBy: "updatedAt" },
20+
{ label: "page.reports.table.header.relatedComment" },
21+
{ label: "page.reports.table.header.actions" },
2122
];
2223

23-
2424
export const Reports: FC<{ config: Config }> = ({ config }) => {
2525
const { toggleNotification } = useNotification();
2626
const api = useAPI();
@@ -106,12 +106,21 @@ export const Reports: FC<{ config: Config }> = ({ config }) => {
106106
disabled={result.filter((report) => !report.resolved).length === 0}
107107
/>
108108
</Th>
109-
{tableHeaders.map((title) => (
110-
<Th>
111-
<Typography variant="sigma">
112-
{getMessage(title)}
113-
</Typography>
114-
</Th>
109+
{tableHeaders.map(({ label, orderBy }) => (
110+
<>
111+
{!orderBy ? (
112+
<Th>
113+
<Typography variant="sigma">
114+
{getMessage(label)}
115+
</Typography>
116+
</Th>
117+
) : (
118+
<SortableTh
119+
label={getMessage(label)}
120+
orderByKey={orderBy}
121+
/>
122+
)}
123+
</>
115124
))}
116125
</Tr>
117126
</Thead>

server/src/validators/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export const qOperatorValidator = z.object({
5252
});
5353
export const orderByValidator = z.string().regex(
5454
// TODO: check sort options
55-
/^(createdAt|updatedAt|id):(desc|asc|ASC|DESC)$/,
55+
/^(content|createdAt|updatedAt|id):(desc|asc|ASC|DESC)$/,
5656
'Invalid orderBy options',
5757
);
5858

0 commit comments

Comments
 (0)