From e8d1658c0a0da04184171224600a882ede6bcaab Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Thu, 2 Apr 2026 18:35:43 +0200 Subject: [PATCH] refactor: dedicated edit page for notifications --- .../components/create-notification-form.tsx | 138 ++++---- .../notification-forms/email-form.tsx | 5 +- .../notification-forms/generic-form.tsx | 11 +- .../notification-forms/ntfy-form.tsx | 5 +- .../notification-forms/pushover-form.tsx | 4 +- .../routes/edit-notification.tsx | 90 +++++ .../routes/notification-details.tsx | 322 ++++++++++++------ app/routeTree.gen.ts | 69 ++-- .../notifications/$notificationId/edit.tsx | 38 +++ .../index.tsx} | 4 +- 10 files changed, 484 insertions(+), 202 deletions(-) create mode 100644 app/client/modules/notifications/routes/edit-notification.tsx create mode 100644 app/routes/(dashboard)/notifications/$notificationId/edit.tsx rename app/routes/(dashboard)/notifications/{$notificationId.tsx => $notificationId/index.tsx} (92%) diff --git a/app/client/modules/notifications/components/create-notification-form.tsx b/app/client/modules/notifications/components/create-notification-form.tsx index b476045c..21997451 100644 --- a/app/client/modules/notifications/components/create-notification-form.tsx +++ b/app/client/modules/notifications/components/create-notification-form.tsx @@ -59,6 +59,7 @@ type Props = { initialValues?: Partial; formId?: string; className?: string; + readOnly?: boolean; }; const defaultValuesForType = { @@ -122,7 +123,14 @@ const defaultValuesForType = { }, }; -export const CreateNotificationForm = ({ onSubmit, mode = "create", initialValues, formId, className }: Props) => { +export const CreateNotificationForm = ({ + onSubmit, + mode = "create", + initialValues, + formId, + className, + readOnly = false, +}: Props) => { const form = useForm({ resolver: zodResolver(formSchema, undefined, { raw: true }), defaultValues: initialValues || { @@ -145,72 +153,74 @@ export const CreateNotificationForm = ({ onSubmit, mode = "create", initialValue onSubmit={form.handleSubmit(onSubmit, scrollToFirstError)} className={cn("space-y-4", className)} > - ( - - Name - - - - Unique identifier for this notification destination. - - - )} - /> - - ( - - Type - - - Email (SMTP) - Slack - Discord - Gotify - Ntfy - Pushover - Telegram - Generic Webhook - Custom (Shoutrrr URL) - - - Choose the notification delivery method. - - - )} - /> + Unique identifier for this notification destination. + + + )} + /> - {watchedType === "email" && } - {watchedType === "slack" && } - {watchedType === "discord" && } - {watchedType === "gotify" && } - {watchedType === "ntfy" && } - {watchedType === "pushover" && } - {watchedType === "telegram" && } - {watchedType === "generic" && } - {watchedType === "custom" && } + ( + + Type + + Choose the notification delivery method. + + + )} + /> + + {watchedType === "email" && } + {watchedType === "slack" && } + {watchedType === "discord" && } + {watchedType === "gotify" && } + {watchedType === "ntfy" && } + {watchedType === "pushover" && } + {watchedType === "telegram" && } + {watchedType === "generic" && } + {watchedType === "custom" && } + ); diff --git a/app/client/modules/notifications/components/notification-forms/email-form.tsx b/app/client/modules/notifications/components/notification-forms/email-form.tsx index 6231b5e3..9843b556 100644 --- a/app/client/modules/notifications/components/notification-forms/email-form.tsx +++ b/app/client/modules/notifications/components/notification-forms/email-form.tsx @@ -7,9 +7,10 @@ import type { NotificationFormValues } from "../create-notification-form"; type Props = { form: UseFormReturn; + readOnly?: boolean; }; -export const EmailForm = ({ form }: Props) => { +export const EmailForm = ({ form, readOnly = false }: Props) => { return ( <> { render={({ field }) => ( - +
Use TLS diff --git a/app/client/modules/notifications/components/notification-forms/generic-form.tsx b/app/client/modules/notifications/components/notification-forms/generic-form.tsx index a62ce1e7..15558340 100644 --- a/app/client/modules/notifications/components/notification-forms/generic-form.tsx +++ b/app/client/modules/notifications/components/notification-forms/generic-form.tsx @@ -10,6 +10,7 @@ import type { NotificationFormValues } from "../create-notification-form"; type Props = { form: UseFormReturn; + readOnly?: boolean; }; const WebhookPreview = ({ values }: { values: Partial }) => { @@ -48,7 +49,7 @@ ${body}`; ); }; -export const GenericForm = ({ form }: Props) => { +export const GenericForm = ({ form, readOnly = false }: Props) => { const watchedValues = useWatch({ control: form.control }); const useJson = useWatch({ control: form.control, name: "useJson" }); @@ -74,7 +75,7 @@ export const GenericForm = ({ form }: Props) => { render={({ field }) => ( Method - @@ -127,7 +128,11 @@ export const GenericForm = ({ form }: Props) => { render={({ field }) => ( - field.onChange(checked)} /> + field.onChange(checked)} + />
Use JSON Template diff --git a/app/client/modules/notifications/components/notification-forms/ntfy-form.tsx b/app/client/modules/notifications/components/notification-forms/ntfy-form.tsx index 16ecec98..979f2901 100644 --- a/app/client/modules/notifications/components/notification-forms/ntfy-form.tsx +++ b/app/client/modules/notifications/components/notification-forms/ntfy-form.tsx @@ -7,9 +7,10 @@ import type { NotificationFormValues } from "../create-notification-form"; type Props = { form: UseFormReturn; + readOnly?: boolean; }; -export const NtfyForm = ({ form }: Props) => { +export const NtfyForm = ({ form, readOnly = false }: Props) => { return ( <> { render={({ field }) => ( Priority - diff --git a/app/client/modules/notifications/components/notification-forms/pushover-form.tsx b/app/client/modules/notifications/components/notification-forms/pushover-form.tsx index e49dd2e6..1dfd1f5a 100644 --- a/app/client/modules/notifications/components/notification-forms/pushover-form.tsx +++ b/app/client/modules/notifications/components/notification-forms/pushover-form.tsx @@ -7,9 +7,10 @@ import type { NotificationFormValues } from "../create-notification-form"; type Props = { form: UseFormReturn; + readOnly?: boolean; }; -export const PushoverForm = ({ form }: Props) => { +export const PushoverForm = ({ form, readOnly = false }: Props) => { return ( <> { Priority