This commit is contained in:
Alex Holliday
2026-01-29 18:14:23 +00:00
parent 6395e8a10e
commit 6ffa5ac648
4 changed files with 142 additions and 7 deletions
@@ -0,0 +1,96 @@
import { ActionsMenu, type ActionMenuItem } from "@/Components/v2/actions-menu";
import Typography from "@mui/material/Typography";
import type { Header } from "@/Components/v2/design-elements/Table";
import { Table } from "@/Components/v2/design-elements";
import type { Notification } from "@/Types/Notification";
import { useNavigate } from "react-router";
import { useTranslation } from "react-i18next";
import { useTheme } from "@mui/material";
interface NotificationsTableProps {
notifications: Notification[];
setSelectedChannel: Function;
}
export const NotificationsTable = ({
notifications,
setSelectedChannel,
}: NotificationsTableProps) => {
const navigate = useNavigate();
const { t } = useTranslation();
const theme = useTheme();
const getActions = (channel: Notification): ActionMenuItem[] => {
return [
{
id: 1,
label: t("pages.common.monitors.actions.configure"),
action: () => {
navigate(`/notification-channels/${channel.id}/configure`);
},
closeMenu: true,
},
{
id: 7,
label: (
<Typography color={theme.palette.error.main}>
{t("pages.common.monitors.actions.delete")}
</Typography>
),
action: async () => {
setSelectedChannel(channel);
},
closeMenu: true,
},
];
};
const getHeaders = () => {
const headers: Header<Notification>[] = [
{
id: "name",
content: t("common.table.headers.name"),
render: (row) => {
return <Typography>{row?.notificationName}</Typography>;
},
},
{
id: "type",
content: t("common.table.headers.type"),
render: (row) => {
return <Typography textTransform={"capitalize"}>{row?.type}</Typography>;
},
},
{
id: "destination",
content: t("pages.notifications.table.headers.destination"),
render: (row) => {
return <Typography>{row?.address}</Typography>;
},
},
{
id: "actions",
content: t("common.table.headers.actions"),
render: (row) => {
return <ActionsMenu items={getActions(row)} />;
},
},
];
return headers;
};
const headers = getHeaders();
return (
<Table
headers={headers}
data={notifications}
onRowClick={(row) => {
navigate(`/notification-channels/${row.id}/configure`);
}}
/>
);
};
+24 -7
View File
@@ -1,25 +1,42 @@
import { BasePageWithStates } from "@/Components/v2/design-elements";
import { NotificationsTable } from "@/Pages/Notifications/components/NotificationsTable";
import { useState } from "react";
import { useGet } from "@/Hooks/UseApi";
import { useTranslation } from "react-i18next";
import type { Notification } from "@/Types/Notification";
const NotificationsPage = () => {
const { t } = useTranslation();
const [selectedChannel, setSelectedChannel] = useState<Notification | null>(null);
const {
data: notifications,
isLoading,
isValidating,
error,
refetch,
} = useGet<Notification[]>("/notifications/team");
return (
<BasePageWithStates
page={t("pages.notifications.fallback.title")}
bullets={
t("pages.notifications.fallback.checks", {
returnObjects: true,
}) as string[]
t("pages.notifications.fallback.checks", { returnObjects: true }) as string[]
}
loading={false}
error={false}
items={[]}
loading={isLoading || isValidating}
error={!!error}
items={notifications ?? []}
actionButtonText={t("pages.notifications.fallback.actionButton")}
actionLink="/notifications/create"
>
Notifications
<NotificationsTable
notifications={notifications ?? []}
setSelectedChannel={setSelectedChannel}
/>
</BasePageWithStates>
);
};
export default NotificationsPage;
+17
View File
@@ -0,0 +1,17 @@
export const NotificationChannels = ["email", "slack", "discord", "webhook", "pager_duty", "matrix"] as const;
export type NotificationChannel = (typeof NotificationChannels)[number];
export interface Notification {
id: string;
userId: string;
teamId: string;
type: NotificationChannel;
notificationName: string;
address?: string;
phone?: string;
homeserverUrl?: string;
roomId?: string;
accessToken?: string;
createdAt: string;
updatedAt: string;
}
+5
View File
@@ -337,6 +337,11 @@
"Keep administrators informed of system changes"
],
"title": "Notification channles are used to:"
},
"table": {
"headers": {
"destination": "Destination"
}
}
}
},