feat: add createdAfter filtering to the Notifications

Signed-off-by: Marek Libra <marek.libra@gmail.com>
This commit is contained in:
Marek Libra
2024-02-22 12:06:47 +01:00
parent 94c4fe2782
commit 5d9c5ba0a6
9 changed files with 71 additions and 36 deletions
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-notifications-backend': patch
'@backstage/plugin-notifications': patch
---
The Notifications can be newly filtered based on the Created Date.
@@ -106,6 +106,10 @@ export class DatabaseNotificationsStore implements NotificationsStore {
query.orderBy('created', options.sortOrder ?? 'desc');
}
if (options.createdAfter) {
query.where('created', '>=', options.createdAfter.valueOf());
}
if (options.limit) {
query.limit(options.limit);
}
@@ -31,6 +31,7 @@ export type NotificationGetOptions = {
sortOrder?: 'asc' | 'desc';
read?: boolean;
saved?: boolean;
createdAfter?: Date;
};
/** @internal */
@@ -204,6 +204,13 @@ export async function createRouter(
opts.read = false;
// or keep undefined
}
if (req.query.created_after) {
const sinceEpoch = Date.parse(req.query.created_after.toString());
if (isNaN(sinceEpoch)) {
throw new InputError('Unexpected date format');
}
opts.createdAfter = new Date(sinceEpoch);
}
const notifications = await store.getNotifications(opts);
res.send(notifications);
+1
View File
@@ -21,6 +21,7 @@ export type GetNotificationsOptions = {
limit?: number;
search?: string;
read?: boolean;
createdAfter?: Date;
};
// @public (undocumented)
@@ -30,6 +30,7 @@ export type GetNotificationsOptions = {
limit?: number;
search?: string;
read?: boolean;
createdAfter?: Date;
};
/** @public */
@@ -54,7 +54,9 @@ export class NotificationsClient implements NotificationsApi {
if (options?.read !== undefined) {
queryString.append('read', options.read ? 'true' : 'false');
}
if (options?.createdAfter !== undefined) {
queryString.append('created_after', options.createdAfter.toISOString());
}
const urlSegment = `?${queryString}`;
return await this.request<Notification[]>(urlSegment);
@@ -28,12 +28,13 @@ import {
export type NotificationsFiltersProps = {
unreadOnly?: boolean;
onUnreadOnlyChanged: (checked: boolean | undefined) => void;
// createdAfter?: string;
createdAfter?: string;
onCreatedAfterChanged: (value: string) => void;
// sorting?: {
// orderBy: GetNotificationsOrderByEnum;
// orderByDirec: GetNotificationsOrderByDirecEnum;
// };
// onCreatedAfterChanged: (value: string) => void;
// setSorting: ({
// orderBy,
// orderByDirec,
@@ -43,22 +44,22 @@ export type NotificationsFiltersProps = {
// }) => void;
};
// export const CreatedAfterOptions: {
// [key: string]: { label: string; getDate: () => Date };
// } = {
// last24h: {
// label: 'Last 24h',
// getDate: () => new Date(Date.now() - 24 * 3600 * 1000),
// },
// lastWeek: {
// label: 'Last week',
// getDate: () => new Date(Date.now() - 7 * 24 * 3600 * 1000),
// },
// all: {
// label: 'Any time',
// getDate: () => new Date(0),
// },
// };
export const CreatedAfterOptions: {
[key: string]: { label: string; getDate: () => Date };
} = {
last24h: {
label: 'Last 24h',
getDate: () => new Date(Date.now() - 24 * 3600 * 1000),
},
lastWeek: {
label: 'Last week',
getDate: () => new Date(Date.now() - 7 * 24 * 3600 * 1000),
},
all: {
label: 'Any time',
getDate: () => new Date(0),
},
};
// export const SortByOptions: {
// [key: string]: {
@@ -108,20 +109,20 @@ export type NotificationsFiltersProps = {
// };
export const NotificationsFilters = ({
unreadOnly,
// createdAfter,
// sorting,
// onCreatedAfterChanged,
// setSorting,
unreadOnly,
onUnreadOnlyChanged,
}: // setSorting,
NotificationsFiltersProps) => {
createdAfter,
onCreatedAfterChanged,
}: NotificationsFiltersProps) => {
// const sortBy = getSortBy(sorting);
// const handleOnCreatedAfterChanged = (
// event: React.ChangeEvent<{ name?: string; value: unknown }>,
// ) => {
// onCreatedAfterChanged(event.target.value as string);
// };
const handleOnCreatedAfterChanged = (
event: React.ChangeEvent<{ name?: string; value: unknown }>,
) => {
onCreatedAfterChanged(event.target.value as string);
};
const handleOnUnreadOnlyChanged = (
event: React.ChangeEvent<{ name?: string; value: unknown }>,
@@ -169,7 +170,6 @@ NotificationsFiltersProps) => {
</Select>
</FormControl>
</Grid>
{/* TODO: extend BE to support following:
<Grid item xs={12}>
<FormControl fullWidth variant="outlined" size="small">
<InputLabel id="notifications-filter-view">
@@ -190,6 +190,8 @@ NotificationsFiltersProps) => {
</Select>
</FormControl>
</Grid>
{/*
<Grid item xs={12}>
<FormControl fullWidth variant="outlined" size="small">
<InputLabel id="notifications-filter-sort">Sort by</InputLabel>
@@ -20,11 +20,15 @@ import {
PageWithHeader,
ResponseErrorPanel,
} from '@backstage/core-components';
import { NotificationsTable } from '../NotificationsTable';
import { useNotificationsApi } from '../../hooks';
import { Grid } from '@material-ui/core';
import { useSignal } from '@backstage/plugin-signals-react';
import { NotificationsFilters } from '../NotificationsFilters';
import { NotificationsTable } from '../NotificationsTable';
import { useNotificationsApi } from '../../hooks';
import {
CreatedAfterOptions,
NotificationsFilters,
} from '../NotificationsFilters';
import { GetNotificationsOptions } from '../../api';
export const NotificationsPage = () => {
@@ -32,6 +36,7 @@ export const NotificationsPage = () => {
const { lastSignal } = useSignal('notifications');
const [unreadOnly, setUnreadOnly] = React.useState<boolean | undefined>(true);
const [containsText, setContainsText] = React.useState<string>();
const [createdAfter, setCreatedAfter] = React.useState<string>('lastWeek');
const { error, value, retry, loading } = useNotificationsApi(
// TODO: add pagination and other filters
@@ -40,9 +45,15 @@ export const NotificationsPage = () => {
if (unreadOnly !== undefined) {
options.read = !unreadOnly;
}
const createdAfterDate = CreatedAfterOptions[createdAfter].getDate();
if (createdAfterDate.valueOf() > 0) {
options.createdAfter = createdAfterDate;
}
return api.getNotifications(options);
},
[containsText, unreadOnly],
[containsText, unreadOnly, createdAfter],
);
useEffect(() => {
@@ -72,10 +83,10 @@ export const NotificationsPage = () => {
<Grid container>
<Grid item xs={2}>
<NotificationsFilters
// createdAfter={createdAfter}
unreadOnly={unreadOnly}
onUnreadOnlyChanged={setUnreadOnly}
// onCreatedAfterChanged={setCreatedAfter}
createdAfter={createdAfter}
onCreatedAfterChanged={setCreatedAfter}
// setSorting={setSorting}
// sorting={sorting}
/>