feat: enable sorting of notifications

Signed-off-by: Marek Libra <marek.libra@gmail.com>
This commit is contained in:
Marek Libra
2024-02-28 16:19:19 +01:00
parent 1f553d2728
commit 6e6d096b3e
9 changed files with 224 additions and 76 deletions
+2
View File
@@ -23,6 +23,8 @@ export type GetNotificationsOptions = {
search?: string;
read?: boolean;
createdAfter?: Date;
sort?: 'created' | 'topic' | 'origin';
sortOrder?: 'asc' | 'desc';
};
// @public (undocumented)
@@ -31,6 +31,8 @@ export type GetNotificationsOptions = {
search?: string;
read?: boolean;
createdAfter?: Date;
sort?: 'created' | 'topic' | 'origin';
sortOrder?: 'asc' | 'desc';
};
/** @public */
@@ -49,6 +49,12 @@ export class NotificationsClient implements NotificationsApi {
if (options?.offset !== undefined) {
queryString.append('offset', options.offset.toString(10));
}
if (options?.sort !== undefined) {
queryString.append('sort', options.sort);
}
if (options?.sortOrder !== undefined) {
queryString.append('sort_order', options.sortOrder);
}
if (options?.search) {
queryString.append('search', options.search);
}
@@ -24,24 +24,19 @@ import {
Select,
Typography,
} from '@material-ui/core';
import { GetNotificationsOptions } from '../../api';
export type SortBy = Required<
Pick<GetNotificationsOptions, 'sort' | 'sortOrder'>
>;
export type NotificationsFiltersProps = {
unreadOnly?: boolean;
onUnreadOnlyChanged: (checked: boolean | undefined) => void;
createdAfter?: string;
onCreatedAfterChanged: (value: string) => void;
// sorting?: {
// orderBy: GetNotificationsOrderByEnum;
// orderByDirec: GetNotificationsOrderByDirecEnum;
// };
// setSorting: ({
// orderBy,
// orderByDirec,
// }: {
// orderBy: GetNotificationsOrderByEnum;
// orderByDirec: GetNotificationsOrderByDirecEnum;
// }) => void;
sorting: SortBy;
onSortingChanged: (sortBy: SortBy) => void;
};
export const CreatedAfterOptions: {
@@ -61,62 +56,65 @@ export const CreatedAfterOptions: {
},
};
// export const SortByOptions: {
// [key: string]: {
// label: string;
// orderBy: GetNotificationsOrderByEnum;
// orderByDirec: GetNotificationsOrderByDirecEnum;
// };
// } = {
// newest: {
// label: 'Newest on top',
// orderBy: GetNotificationsOrderByEnum.Created,
// orderByDirec: GetNotificationsOrderByDirecEnum.Asc,
// },
// oldest: {
// label: 'Oldest on top',
// orderBy: GetNotificationsOrderByEnum.Created,
// orderByDirec: GetNotificationsOrderByDirecEnum.Desc,
// },
// topic: {
// label: 'Topic',
// orderBy: GetNotificationsOrderByEnum.Topic,
// orderByDirec: GetNotificationsOrderByDirecEnum.Asc,
// },
// origin: {
// label: 'Origin',
// orderBy: GetNotificationsOrderByEnum.Origin,
// orderByDirec: GetNotificationsOrderByDirecEnum.Asc,
// },
// };
export const SortByOptions: {
[key: string]: {
label: string;
sortBy: SortBy;
};
} = {
newest: {
label: 'Newest on top',
sortBy: {
sort: 'created',
sortOrder: 'desc',
},
},
oldest: {
label: 'Oldest on top',
sortBy: {
sort: 'created',
sortOrder: 'asc',
},
},
topic: {
label: 'Topic',
sortBy: {
sort: 'topic',
sortOrder: 'asc',
},
},
origin: {
label: 'Origin',
sortBy: {
sort: 'origin',
sortOrder: 'asc',
},
},
};
// TODO: Implement sorting on server (to work with pagination)
// const getSortBy = (sorting: NotificationsFiltersProps['sorting']): string => {
// if (
// sorting?.orderBy === GetNotificationsOrderByEnum.Created &&
// sorting.orderByDirec === GetNotificationsOrderByDirecEnum.Desc
// ) {
// return 'oldest';
// }
// if (sorting?.orderBy === GetNotificationsOrderByEnum.Topic) {
// return 'topic';
// }
// if (sorting?.orderBy === GetNotificationsOrderByEnum.Origin) {
// return 'origin';
// }
const getSortByText = (sortBy?: SortBy): string => {
if (sortBy?.sort === 'created' && sortBy?.sortOrder === 'asc') {
return 'oldest';
}
if (sortBy?.sort === 'topic') {
return 'topic';
}
if (sortBy?.sort === 'origin') {
return 'origin';
}
// return 'newest';
// };
return 'newest';
};
export const NotificationsFilters = ({
// sorting,
// setSorting,
sorting,
onSortingChanged,
unreadOnly,
onUnreadOnlyChanged,
createdAfter,
onCreatedAfterChanged,
}: NotificationsFiltersProps) => {
// const sortBy = getSortBy(sorting);
const sortByText = getSortByText(sorting);
const handleOnCreatedAfterChanged = (
event: React.ChangeEvent<{ name?: string; value: unknown }>,
@@ -133,16 +131,13 @@ export const NotificationsFilters = ({
onUnreadOnlyChanged(value);
};
// const handleOnSortByChanged = (
// event: React.ChangeEvent<{ name?: string; value: unknown }>,
// ) => {
// const idx = (event.target.value as string) || 'newest';
// const option = SortByOptions[idx];
// setSorting({
// orderBy: option.orderBy,
// orderByDirec: option.orderByDirec,
// });
// };
const handleOnSortByChanged = (
event: React.ChangeEvent<{ name?: string; value: unknown }>,
) => {
const idx = (event.target.value as string) || 'newest';
const option = SortByOptions[idx];
onSortingChanged({ ...option.sortBy });
};
let unreadOnlyValue = 'all';
if (unreadOnly) unreadOnlyValue = 'unread';
@@ -191,7 +186,6 @@ export const NotificationsFilters = ({
</FormControl>
</Grid>
{/*
<Grid item xs={12}>
<FormControl fullWidth variant="outlined" size="small">
<InputLabel id="notifications-filter-sort">Sort by</InputLabel>
@@ -199,7 +193,7 @@ export const NotificationsFilters = ({
<Select
label="Sort by"
placeholder="Field to sort by"
value={sortBy}
value={sortByText}
onChange={handleOnSortByChanged}
>
{Object.keys(SortByOptions).map((key: string) => (
@@ -209,7 +203,7 @@ export const NotificationsFilters = ({
))}
</Select>
</FormControl>
</Grid> */}
</Grid>
</Grid>
</>
);
@@ -28,6 +28,8 @@ import { useNotificationsApi } from '../../hooks';
import {
CreatedAfterOptions,
NotificationsFilters,
SortBy,
SortByOptions,
} from '../NotificationsFilters';
import { GetNotificationsOptions } from '../../api';
@@ -39,6 +41,9 @@ export const NotificationsPage = () => {
const [pageSize, setPageSize] = React.useState(5);
const [containsText, setContainsText] = React.useState<string>();
const [createdAfter, setCreatedAfter] = React.useState<string>('lastWeek');
const [sorting, setSorting] = React.useState<SortBy>(
SortByOptions.newest.sortBy,
);
const { error, value, retry, loading } = useNotificationsApi(
api => {
@@ -46,6 +51,7 @@ export const NotificationsPage = () => {
search: containsText,
limit: pageSize,
offset: pageNumber * pageSize,
...(sorting || {}),
};
if (unreadOnly !== undefined) {
options.read = !unreadOnly;
@@ -58,7 +64,7 @@ export const NotificationsPage = () => {
return api.getNotifications(options);
},
[containsText, unreadOnly, createdAfter, pageNumber, pageSize],
[containsText, unreadOnly, createdAfter, pageNumber, pageSize, sorting],
);
useEffect(() => {
@@ -92,8 +98,8 @@ export const NotificationsPage = () => {
onUnreadOnlyChanged={setUnreadOnly}
createdAfter={createdAfter}
onCreatedAfterChanged={setCreatedAfter}
// setSorting={setSorting}
// sorting={sorting}
onSortingChanged={setSorting}
sorting={sorting}
/>
</Grid>
<Grid item xs={10}>