refactor(add-service): Refactor ServiceForm.tsx to support internationalization
- Extract ServiceForm.tsx validation logic into the custom hook useServiceSchema - Add internationalization support and move error messages to translation files
This commit is contained in:
@@ -3,7 +3,7 @@ import { useForm } from "react-hook-form";
|
|||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { useToast } from "@/hooks/use-toast";
|
import { useToast } from "@/hooks/use-toast";
|
||||||
import { serviceSchema, ServiceFormData } from "./types";
|
import { useServiceSchema, ServiceFormData } from "./types";
|
||||||
import { ServiceBasicFields } from "./ServiceBasicFields";
|
import { ServiceBasicFields } from "./ServiceBasicFields";
|
||||||
import { ServiceTypeField } from "./ServiceTypeField";
|
import { ServiceTypeField } from "./ServiceTypeField";
|
||||||
import { ServiceConfigFields } from "./ServiceConfigFields";
|
import { ServiceConfigFields } from "./ServiceConfigFields";
|
||||||
@@ -36,6 +36,8 @@ export function ServiceForm({
|
|||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
const serviceSchema = useServiceSchema();
|
||||||
|
|
||||||
// Initialize form with default values
|
// Initialize form with default values
|
||||||
const form = useForm<ServiceFormData>({
|
const form = useForm<ServiceFormData>({
|
||||||
resolver: zodResolver(serviceSchema),
|
resolver: zodResolver(serviceSchema),
|
||||||
|
|||||||
@@ -1,22 +1,42 @@
|
|||||||
|
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import type { ZodSchema } from "zod";
|
||||||
|
import { useLanguage } from "@/contexts/LanguageContext";
|
||||||
|
|
||||||
export const serviceSchema = z.object({
|
|
||||||
name: z.string().min(1, "Service name is required"),
|
|
||||||
type: z.enum(["http", "ping", "tcp", "dns"]),
|
|
||||||
url: z.string().min(1, "URL/Domain/Host is required").refine((value) => {
|
|
||||||
// Basic validation - more specific validation can be added per type
|
|
||||||
return value.trim().length > 0;
|
|
||||||
}, "Please enter a valid URL, hostname, or domain"),
|
|
||||||
port: z.string().optional(),
|
|
||||||
interval: z.string(),
|
|
||||||
retries: z.string(),
|
|
||||||
notificationStatus: z.enum(["enabled", "disabled"]).optional(),
|
|
||||||
notificationChannels: z.array(z.string()).optional(),
|
|
||||||
alertTemplate: z.string().optional(),
|
|
||||||
// Regional monitoring fields - now supports multiple agents
|
|
||||||
regionalMonitoringEnabled: z.boolean().optional(),
|
|
||||||
regionalAgents: z.array(z.string()).optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export type ServiceFormData = z.infer<typeof serviceSchema>;
|
export type ServiceFormData = {
|
||||||
|
name: string;
|
||||||
|
type: "http" | "ping" | "tcp" | "dns";
|
||||||
|
url: string;
|
||||||
|
port?: string;
|
||||||
|
interval: string;
|
||||||
|
retries: string;
|
||||||
|
notificationStatus?: "enabled" | "disabled";
|
||||||
|
notificationChannels?: string[];
|
||||||
|
alertTemplate?: string;
|
||||||
|
regionalMonitoringEnabled?: boolean;
|
||||||
|
regionalAgents?: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Hook to use the schema with translations
|
||||||
|
export const useServiceSchema = () => {
|
||||||
|
const { t } = useLanguage();
|
||||||
|
return z.object({
|
||||||
|
name: z.string().min(1, t("serviceNameRequired")),
|
||||||
|
type: z.enum(["http", "ping", "tcp", "dns"]),
|
||||||
|
url: z.string()
|
||||||
|
.min(1, t("urlDomainHostRequired"))
|
||||||
|
.refine(
|
||||||
|
(value) => value.trim().length > 0,
|
||||||
|
t("enterValidUrlHostnameDomain")
|
||||||
|
),
|
||||||
|
port: z.string().optional(),
|
||||||
|
interval: z.string(),
|
||||||
|
retries: z.string(),
|
||||||
|
notificationStatus: z.enum(["enabled", "disabled"]).optional(),
|
||||||
|
notificationChannels: z.array(z.string()).optional(),
|
||||||
|
alertTemplate: z.string().optional(),
|
||||||
|
// Regional monitoring fields - now supports multiple agents
|
||||||
|
regionalMonitoringEnabled: z.boolean().optional(),
|
||||||
|
regionalAgents: z.array(z.string()).optional(),
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -84,4 +84,9 @@ export const servicesTranslations: ServicesTranslations = {
|
|||||||
targetDNSDesc: "Enter domain name for DNS record monitoring (A, AAAA, MX, etc.)",
|
targetDNSDesc: "Enter domain name for DNS record monitoring (A, AAAA, MX, etc.)",
|
||||||
targetDefaultDesc: "Enter the target URL or hostname for monitoring",
|
targetDefaultDesc: "Enter the target URL or hostname for monitoring",
|
||||||
targetDefaultPlaceholder: "Enter URL or hostname",
|
targetDefaultPlaceholder: "Enter URL or hostname",
|
||||||
|
|
||||||
|
// types.ts
|
||||||
|
serviceNameRequired: "Service name is required",
|
||||||
|
urlDomainHostRequired: "URL/Domain/Host is required",
|
||||||
|
enterValidUrlHostnameDomain: "Please enter a valid URL, hostname, or domain",
|
||||||
};
|
};
|
||||||
@@ -82,4 +82,9 @@ export interface ServicesTranslations {
|
|||||||
targetDNSDesc: string;
|
targetDNSDesc: string;
|
||||||
targetDefaultDesc: string;
|
targetDefaultDesc: string;
|
||||||
targetDefaultPlaceholder: string;
|
targetDefaultPlaceholder: string;
|
||||||
|
|
||||||
|
// types.ts
|
||||||
|
serviceNameRequired: string;
|
||||||
|
urlDomainHostRequired: string;
|
||||||
|
enterValidUrlHostnameDomain: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,4 +84,9 @@ export const servicesTranslations: ServicesTranslations = {
|
|||||||
targetDNSDesc: "输入要监控的 DNS 记录域名(A、AAAA、MX等)",
|
targetDNSDesc: "输入要监控的 DNS 记录域名(A、AAAA、MX等)",
|
||||||
targetDefaultDesc: "输入要监控的目标 URL 或主机名",
|
targetDefaultDesc: "输入要监控的目标 URL 或主机名",
|
||||||
targetDefaultPlaceholder: "输入 URL 或主机名",
|
targetDefaultPlaceholder: "输入 URL 或主机名",
|
||||||
|
|
||||||
|
// types.ts
|
||||||
|
serviceNameRequired: "服务名称是必填项",
|
||||||
|
urlDomainHostRequired: "URL/域名/主机名是必填项",
|
||||||
|
enterValidUrlHostnameDomain: "请输入有效的URL、主机名或域名",
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user