infra and notification

This commit is contained in:
Alex Holliday committed 2025-12-28 18:59:05 +00:00
1 parent 4dfeb71a9d
commit e55ae64222
8 files changed
+52 -48

No files matched your search

@@ -1,4 +1,4 @@
import { notificationChannelSchema } from "@/validation/zod";
import { notificationChannelSchema } from "@/validation";
import { useMemo } from "react";
import { z } from "zod";
@@ -1,4 +1,3 @@
import { monitorSchemaInfra } from "@/validation";
import { useGet, usePatch } from "@/hooks/UseApi";
import { InfraForm } from "@/pages/infrastructure/InfraForm";
@@ -5,7 +5,7 @@ import { useNavigate } from "react-router";
import { z } from "zod";
import { usePatch, useGet } from "@/hooks/UseApi";
import type { ApiResponse } from "@/types/api";
import { notificationChannelSchema } from "@/validation/zod";
import { notificationChannelSchema } from "@/validation";
import type { INotificationChannel } from "@/types/notification-channel";
type FormValues = z.infer<typeof notificationChannelSchema>;
@@ -3,7 +3,7 @@ import { NotificationChannelsForm } from "./NotificationChannelsForm";
import { useNavigate } from "react-router";
import { z } from "zod";
import { usePost } from "@/hooks/UseApi";
import { notificationChannelSchema } from "@/validation/zod";
import { notificationChannelSchema } from "@/validation";
import type { INotificationChannel } from "@/types/notification-channel";
type FormValues = z.infer<typeof notificationChannelSchema>;
@@ -10,7 +10,7 @@ import { ChannelTypes } from "@/types/notification-channel";
import { zodResolver } from "@hookform/resolvers/zod";
import { useTranslation } from "react-i18next";
import { z } from "zod";
import { notificationChannelSchema } from "@/validation/zod";
import { notificationChannelSchema } from "@/validation";
import { useForm, Controller, type SubmitHandler } from "react-hook-form";
import { useEffect } from "react";
import { useInitForm } from "@/hooks/forms/UseInitNotificationsChannelForm";
@@ -79,6 +79,7 @@ export const NotificationChannelsForm = ({
<Controller
name="name"
control={control}
defaultValue={defaults.name}
render={({ field }) => (
<TextInput
{...field}
+1
View File
@@ -5,3 +5,4 @@ export * from "./monitor";
export * from "./pagespeed";
export * from "./infra";
export * from "./utils";
export * from "./notification-channel";
@@ -0,0 +1,44 @@
import { z } from "zod";
import { ChannelTypes } from "@/types/notification-channel";
import { urlRegex } from "@/validation/utils";
export const notificationChannelSchema = z
.object({
name: z.string().min(1, "Channel name is required"),
type: z.enum(ChannelTypes, { error: "Invalid channel type" }),
config: z.object({
url: z
.string()
.regex(urlRegex, "Invalid URL")
.or(z.literal(""))
.optional(),
emailAddress: z
.email("Invalid email address")
.or(z.literal(""))
.optional(),
}),
})
.superRefine((data, ctx) => {
const { type, config } = data;
if (!config.url && !config.emailAddress) {
ctx.addIssue({
code: "custom",
message: "Either a URL or an email address must be provided.",
path: ["config"],
});
}
if (type === "email" && !config.emailAddress) {
ctx.addIssue({
code: "custom",
message: "Email address is required for email-type channels.",
path: ["config", "emailAddress"],
});
} else if (type !== "email" && !config.url) {
ctx.addIssue({
code: "custom",
message: "URL is required for non-email-type channels.",
path: ["config", "url"],
});
}
});
+2 -43
View File
@@ -1,10 +1,8 @@
import { z } from "zod";
// humanInterval moved to split schema files
import { ChannelTypes } from "@/types/notification-channel";
import { MaintenanceRepeats } from "@/types/maintenance";
const urlRegex =
/^(https?:\/\/)?(localhost|([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|[a-zA-Z0-9-]+|(\d{1,3}\.){3}\d{1,3})(:\d{1,5})?(\/.*)?$/;
// urlRegex moved to client/src/validation/utils.ts
// monitor duration schema moved to client/src/validation/monitor.ts
// pagespeed duration schema moved to client/src/validation/pagespeed.ts
@@ -41,46 +39,7 @@ export const inviteSchema = z.object({
orgRoleId: z.string().optional(),
});
export const notificationChannelSchema = z
.object({
name: z.string().min(1, "Channel name is required"),
type: z.enum(ChannelTypes, { error: "Invalid channel type" }),
config: z.object({
url: z
.string()
.regex(urlRegex, "Invalid URL")
.or(z.literal(""))
.optional(),
emailAddress: z
.email("Invalid email address")
.or(z.literal(""))
.optional(),
}),
})
.superRefine((data, ctx) => {
const { type, config } = data;
if (!config.url && !config.emailAddress) {
ctx.addIssue({
code: "custom",
message: "Either a URL or an email address must be provided.",
path: ["config"],
});
}
if (type === "email" && !config.emailAddress) {
ctx.addIssue({
code: "custom",
message: "Email address is required for email-type channels.",
path: ["config", "emailAddress"],
});
} else if (type !== "email" && !config.url) {
ctx.addIssue({
code: "custom",
message: "URL is required for non-email-type channels.",
path: ["config", "url"],
});
}
});
// moved to client/src/validation/notification-channel.ts
export const maintenanceSchema = z
.object({