settings
This commit is contained in:
1 parent
a2454cbab6
commit
8fb13273bf
7 files changed
+69
-83
No files matched your search
@@ -1,11 +1,12 @@
|
||||
import { systemSettingsSchema } from "@/validation/zod";
|
||||
import { systemSettingsSchema } from "@/validation";
|
||||
import { useMemo } from "react";
|
||||
import type { FormValues } from "@/pages/settings/SettingsForm";
|
||||
|
||||
import { z } from "zod";
|
||||
export const useInitForm = ({
|
||||
initialData,
|
||||
}: {
|
||||
initialData: Partial<z.infer<typeof systemSettingsSchema>> | undefined;
|
||||
initialData: Partial<FormValues> | undefined;
|
||||
}) => {
|
||||
return useMemo(() => {
|
||||
const defaults: z.infer<typeof systemSettingsSchema> = {
|
||||
|
||||
@@ -7,12 +7,9 @@ import {} from "react-i18next";
|
||||
import { useAppSelector } from "@/hooks/AppHooks";
|
||||
import { useGet, usePatch, usePost } from "@/hooks/UseApi";
|
||||
import type { ApiResponse } from "@/types/api";
|
||||
import { z } from "zod";
|
||||
import { systemSettingsSchema } from "@/validation/zod";
|
||||
import type { FormValues } from "@/pages/settings/SettingsForm";
|
||||
|
||||
const AdminSettingsPage = () => {
|
||||
type FormValues = z.infer<typeof systemSettingsSchema>;
|
||||
|
||||
const user = useAppSelector((state) => state.auth.user);
|
||||
|
||||
const orgPermissions = user?.org?.permissions || [];
|
||||
|
||||
@@ -6,14 +6,14 @@ import { ConfigBox } from "@/components/design-elements";
|
||||
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { systemSettingsSchema } from "@/validation/zod";
|
||||
import { systemSettingsSchema } from "@/validation";
|
||||
import { z } from "zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useForm, Controller, type SubmitHandler } from "react-hook-form";
|
||||
import { useInitForm } from "@/hooks/forms/UseInitSettingsForm";
|
||||
import { useEffect } from "react";
|
||||
|
||||
type FormValues = z.infer<typeof systemSettingsSchema>;
|
||||
export type FormValues = z.infer<typeof systemSettingsSchema>;
|
||||
|
||||
export const SettingsForm = ({
|
||||
initialData,
|
||||
|
||||
@@ -8,3 +8,4 @@ export * from "./utils";
|
||||
export * from "./notification-channel";
|
||||
export * from "./maintenance";
|
||||
export * from "./team";
|
||||
export * from "./system-settings";
|
||||
@@ -0,0 +1,55 @@
|
||||
import { z } from "zod";
|
||||
import { optionalString } from "@/validation/utils";
|
||||
|
||||
export const systemSettingsSchema = z.object({
|
||||
systemEmailHost: optionalString(
|
||||
z.string().trim().min(1, { message: "SMTP host is required" }).max(255, {
|
||||
message: "SMTP host must be 255 characters or fewer",
|
||||
})
|
||||
),
|
||||
systemEmailPort: optionalString(
|
||||
z
|
||||
.union([z.number().int(), z.string().regex(/^\d+$/)])
|
||||
.transform((val) => (typeof val === "string" ? Number(val) : val))
|
||||
.refine(
|
||||
(val) =>
|
||||
val === undefined ||
|
||||
(Number.isInteger(val) && val > 0 && val < 65536),
|
||||
{
|
||||
message: "Port must be a number between 1 and 65535",
|
||||
}
|
||||
)
|
||||
),
|
||||
systemEmailAddress: optionalString(
|
||||
z.string().email({ message: "SMTP email must be valid" })
|
||||
),
|
||||
systemEmailPassword: optionalString(
|
||||
z.string().max(255, {
|
||||
message: "SMTP password must be 255 characters or fewer",
|
||||
})
|
||||
),
|
||||
systemEmailUser: optionalString(
|
||||
z.string().trim().max(255, {
|
||||
message: "SMTP username must be 255 characters or fewer",
|
||||
})
|
||||
),
|
||||
systemEmailConnectionHost: optionalString(
|
||||
z.string().trim().max(255, {
|
||||
message: "Connection host must be 255 characters or fewer",
|
||||
})
|
||||
),
|
||||
systemEmailTLSServername: optionalString(
|
||||
z.string().trim().max(255, {
|
||||
message: "TLS server name must be 255 characters or fewer",
|
||||
})
|
||||
),
|
||||
systemEmailSecure: z.boolean().optional(),
|
||||
systemEmailPool: z.boolean().optional(),
|
||||
systemEmailIgnoreTLS: z.boolean().optional(),
|
||||
systemEmailRequireTLS: z.boolean().optional(),
|
||||
systemEmailRejectUnauthorized: z.boolean().optional(),
|
||||
checksRetentionDays: z.coerce
|
||||
.number({ message: "Number required" })
|
||||
.min(1, "Retention days must be at least 1")
|
||||
.max(365, "Retention days cannot exceed 365 days"),
|
||||
});
|
||||
@@ -21,3 +21,10 @@ export const durationSchema = (minInterval: number) =>
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export const optionalString = <T extends z.ZodTypeAny>(schema: T) =>
|
||||
z.preprocess(
|
||||
(val) =>
|
||||
val === "" || val === null || val === undefined ? undefined : val,
|
||||
schema.optional()
|
||||
);
|
||||
@@ -1,26 +1,4 @@
|
||||
import { z } from "zod";
|
||||
// humanInterval moved to split schema files
|
||||
// MaintenanceRepeats moved to maintenance schema
|
||||
|
||||
// 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
|
||||
// infra duration schema moved to client/src/validation/infra.ts
|
||||
|
||||
const optionalString = <T extends z.ZodTypeAny>(schema: T) =>
|
||||
z.preprocess(
|
||||
(val) =>
|
||||
val === "" || val === null || val === undefined ? undefined : val,
|
||||
schema.optional()
|
||||
);
|
||||
|
||||
// moved to client/src/validation/monitor.ts
|
||||
|
||||
// moved to client/src/validation/pagespeed.ts
|
||||
// moved to client/src/validation/infra.ts
|
||||
|
||||
// moved to client/src/validation/team.ts
|
||||
|
||||
export const inviteSchema = z.object({
|
||||
email: z.email("Invalid email address"),
|
||||
@@ -29,59 +7,6 @@ export const inviteSchema = z.object({
|
||||
orgRoleId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const systemSettingsSchema = z.object({
|
||||
systemEmailHost: optionalString(
|
||||
z.string().trim().min(1, { message: "SMTP host is required" }).max(255, {
|
||||
message: "SMTP host must be 255 characters or fewer",
|
||||
})
|
||||
),
|
||||
systemEmailPort: optionalString(
|
||||
z
|
||||
.union([z.number().int(), z.string().regex(/^\d+$/)])
|
||||
.transform((val) => (typeof val === "string" ? Number(val) : val))
|
||||
.refine(
|
||||
(val) =>
|
||||
val === undefined ||
|
||||
(Number.isInteger(val) && val > 0 && val < 65536),
|
||||
{
|
||||
message: "Port must be a number between 1 and 65535",
|
||||
}
|
||||
)
|
||||
),
|
||||
systemEmailAddress: optionalString(
|
||||
z.string().email({ message: "SMTP email must be valid" })
|
||||
),
|
||||
systemEmailPassword: optionalString(
|
||||
z.string().max(255, {
|
||||
message: "SMTP password must be 255 characters or fewer",
|
||||
})
|
||||
),
|
||||
systemEmailUser: optionalString(
|
||||
z.string().trim().max(255, {
|
||||
message: "SMTP username must be 255 characters or fewer",
|
||||
})
|
||||
),
|
||||
systemEmailConnectionHost: optionalString(
|
||||
z.string().trim().max(255, {
|
||||
message: "Connection host must be 255 characters or fewer",
|
||||
})
|
||||
),
|
||||
systemEmailTLSServername: optionalString(
|
||||
z.string().trim().max(255, {
|
||||
message: "TLS server name must be 255 characters or fewer",
|
||||
})
|
||||
),
|
||||
systemEmailSecure: z.boolean().optional(),
|
||||
systemEmailPool: z.boolean().optional(),
|
||||
systemEmailIgnoreTLS: z.boolean().optional(),
|
||||
systemEmailRequireTLS: z.boolean().optional(),
|
||||
systemEmailRejectUnauthorized: z.boolean().optional(),
|
||||
checksRetentionDays: z.coerce
|
||||
.number({ message: "Number required" })
|
||||
.min(1, "Retention days must be at least 1")
|
||||
.max(365, "Retention days cannot exceed 365 days"),
|
||||
});
|
||||
|
||||
const statusPageUrlRegex = /^[A-Za-z0-9]+$/;
|
||||
|
||||
export const statusPageSchema = z.object({
|
||||
|
||||
Reference in new issue
Block a user