mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-06-30 11:35:22 +02:00
- Introduced new test files for permission checks, including `check-permission.test.ts`, `enterprise-only-resources.test.ts`, `resolve-permissions.test.ts`, and `service-access.test.ts`. - Implemented permission checks in various components to ensure actions are gated by user permissions, including `ShowTraefikConfig`, `UpdateTraefikConfig`, `ShowVolumes`, `ShowDomains`, and others. - Enhanced the logic for displaying UI elements based on user permissions, ensuring that only authorized users can access or modify resources.
186 lines
6.8 KiB
TypeScript
186 lines
6.8 KiB
TypeScript
import { Bell, Loader2, Mail, PenBoxIcon, Trash2 } from "lucide-react";
|
|
import { toast } from "sonner";
|
|
import {
|
|
DiscordIcon,
|
|
GotifyIcon,
|
|
LarkIcon,
|
|
NtfyIcon,
|
|
ResendIcon,
|
|
SlackIcon,
|
|
TeamsIcon,
|
|
TelegramIcon,
|
|
} from "@/components/icons/notification-icons";
|
|
import { DialogAction } from "@/components/shared/dialog-action";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from "@/components/ui/card";
|
|
import { api } from "@/utils/api";
|
|
import { HandleNotifications } from "./handle-notifications";
|
|
|
|
export const ShowNotifications = () => {
|
|
const { data, isPending, refetch } = api.notification.all.useQuery();
|
|
const { mutateAsync, isPending: isRemoving } =
|
|
api.notification.remove.useMutation();
|
|
const { data: permissions } = api.user.getPermissions.useQuery();
|
|
|
|
return (
|
|
<div className="w-full">
|
|
<Card className="h-full bg-sidebar p-2.5 rounded-xl max-w-5xl mx-auto">
|
|
<div className="rounded-xl bg-background shadow-md ">
|
|
<CardHeader className="">
|
|
<CardTitle className="text-xl flex flex-row gap-2">
|
|
<Bell className="size-6 text-muted-foreground self-center" />
|
|
Notifications
|
|
</CardTitle>
|
|
<CardDescription>
|
|
Add your providers to receive notifications, like Discord, Slack,
|
|
Telegram, Teams, Email, Resend, Lark.
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="space-y-2 py-8 border-t">
|
|
{isPending ? (
|
|
<div className="flex flex-row gap-2 items-center justify-center text-sm text-muted-foreground min-h-[25vh]">
|
|
<span>Loading...</span>
|
|
<Loader2 className="animate-spin size-4" />
|
|
</div>
|
|
) : (
|
|
<>
|
|
{data?.length === 0 ? (
|
|
<div className="flex flex-col items-center gap-3 min-h-[25vh] justify-center">
|
|
<Bell />
|
|
<span className="text-base text-muted-foreground text-center">
|
|
To send notifications it is required to set at least 1
|
|
provider.
|
|
</span>
|
|
{permissions?.notification.create && (
|
|
<HandleNotifications />
|
|
)}
|
|
</div>
|
|
) : (
|
|
<div className="flex flex-col gap-4 min-h-[25vh]">
|
|
<div className="flex flex-col gap-4 rounded-lg ">
|
|
{data?.map((notification, _index) => (
|
|
<div
|
|
key={notification.notificationId}
|
|
className="flex items-center justify-between bg-sidebar p-1 w-full rounded-lg"
|
|
>
|
|
<div className="flex items-center justify-between p-3.5 rounded-lg bg-background border w-full">
|
|
<span className="text-sm flex flex-row items-center gap-4">
|
|
{notification.notificationType === "slack" && (
|
|
<div className="flex items-center justify-center rounded-lg">
|
|
<SlackIcon className="size-6" />
|
|
</div>
|
|
)}
|
|
{notification.notificationType === "telegram" && (
|
|
<div className="flex items-center justify-center rounded-lg ">
|
|
<TelegramIcon className="size-7 " />
|
|
</div>
|
|
)}
|
|
{notification.notificationType === "discord" && (
|
|
<div className="flex items-center justify-center rounded-lg">
|
|
<DiscordIcon className="size-7 " />
|
|
</div>
|
|
)}
|
|
{notification.notificationType === "email" && (
|
|
<div className="flex items-center justify-center rounded-lg ">
|
|
<Mail className="size-6 text-muted-foreground" />
|
|
</div>
|
|
)}
|
|
{notification.notificationType === "resend" && (
|
|
<div className="flex items-center justify-center rounded-lg ">
|
|
<ResendIcon className="size-6 text-muted-foreground" />
|
|
</div>
|
|
)}
|
|
{notification.notificationType === "gotify" && (
|
|
<div className="flex items-center justify-center rounded-lg ">
|
|
<GotifyIcon className="size-6" />
|
|
</div>
|
|
)}
|
|
{notification.notificationType === "ntfy" && (
|
|
<div className="flex items-center justify-center rounded-lg ">
|
|
<NtfyIcon className="size-6" />
|
|
</div>
|
|
)}
|
|
{notification.notificationType === "custom" && (
|
|
<div className="flex items-center justify-center rounded-lg ">
|
|
<PenBoxIcon className="size-6 text-muted-foreground" />
|
|
</div>
|
|
)}
|
|
{notification.notificationType === "lark" && (
|
|
<div className="flex items-center justify-center rounded-lg">
|
|
<LarkIcon className="size-7 text-muted-foreground" />
|
|
</div>
|
|
)}
|
|
{notification.notificationType === "teams" && (
|
|
<div className="flex items-center justify-center rounded-lg">
|
|
<TeamsIcon className="size-7 text-muted-foreground" />
|
|
</div>
|
|
)}
|
|
|
|
{notification.name}
|
|
</span>
|
|
<div className="flex flex-row gap-1">
|
|
<HandleNotifications
|
|
notificationId={notification.notificationId}
|
|
/>
|
|
|
|
{permissions?.notification.delete && (
|
|
<DialogAction
|
|
title="Delete Notification"
|
|
description="Are you sure you want to delete this notification?"
|
|
type="destructive"
|
|
onClick={async () => {
|
|
await mutateAsync({
|
|
notificationId:
|
|
notification.notificationId,
|
|
})
|
|
.then(() => {
|
|
toast.success(
|
|
"Notification deleted successfully",
|
|
);
|
|
refetch();
|
|
})
|
|
.catch(() => {
|
|
toast.error(
|
|
"Error deleting notification",
|
|
);
|
|
});
|
|
}}
|
|
>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
className="group hover:bg-red-500/10 "
|
|
isLoading={isRemoving}
|
|
>
|
|
<Trash2 className="size-4 text-primary group-hover:text-red-500" />
|
|
</Button>
|
|
</DialogAction>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{permissions?.notification.create && (
|
|
<div className="flex flex-row gap-2 flex-wrap w-full justify-end mr-4">
|
|
<HandleNotifications />
|
|
</div>
|
|
)}
|
|
</div>
|
|
)}
|
|
</>
|
|
)}
|
|
</CardContent>
|
|
</div>
|
|
</Card>
|
|
</div>
|
|
);
|
|
};
|