mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-10-25 23:35:00 +03:00
refactor(frontend): read the panel's navigation from one route manifest (#6922)
The router, the sidebar, the page titles and the command palette each kept their own list of the panel's pages, so a page added to one could go missing from another without any test noticing. They all read src/routes/panelRoutes.tsx now, and a contract test holds the manifest to the router, the translation bundle and the palette keywords. The unused useZodForm helper goes, and CONTRIBUTING, frontend/CLAUDE.md and the frontend README describe the useForm + rhfZodValidate pattern the panel's forms actually use.
This commit is contained in:
@@ -2,11 +2,11 @@ import { useEffect } from 'react';
|
||||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||
import { expect, waitFor } from 'storybook/test';
|
||||
import { Button, Form, Input, InputNumber, Select, Switch, Typography } from 'antd';
|
||||
import { FormProvider } from 'react-hook-form';
|
||||
import { FormProvider, useForm, useWatch } from 'react-hook-form';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { FormField } from './FormField';
|
||||
import { useZodForm } from './useZodForm';
|
||||
|
||||
const GB = 1024 * 1024 * 1024;
|
||||
|
||||
@@ -60,7 +60,8 @@ const ClientSchema = z.object({
|
||||
});
|
||||
|
||||
function ClientDemo() {
|
||||
const methods = useZodForm(ClientSchema, {
|
||||
const methods = useForm<z.infer<typeof ClientSchema>>({
|
||||
resolver: zodResolver(ClientSchema),
|
||||
defaultValues: { email: 'user1@example.com', flow: 'xtls-rprx-vision', enable: true },
|
||||
});
|
||||
return (
|
||||
@@ -95,8 +96,11 @@ const TrafficSchema = z.object({
|
||||
});
|
||||
|
||||
function TrafficDemo() {
|
||||
const methods = useZodForm(TrafficSchema, { defaultValues: { totalBytes: 50 * GB } });
|
||||
const totalBytes = methods.watch('totalBytes');
|
||||
const methods = useForm<z.infer<typeof TrafficSchema>>({
|
||||
resolver: zodResolver(TrafficSchema),
|
||||
defaultValues: { totalBytes: 50 * GB },
|
||||
});
|
||||
const totalBytes = useWatch({ control: methods.control, name: 'totalBytes' });
|
||||
return (
|
||||
<FormProvider {...methods}>
|
||||
<Form layout="vertical" style={{ maxWidth: 360 }}>
|
||||
@@ -128,7 +132,10 @@ const InboundSchema = z.object({
|
||||
});
|
||||
|
||||
function ValidationDemo() {
|
||||
const methods = useZodForm(InboundSchema, { defaultValues: { remark: '', port: 0 } });
|
||||
const methods = useForm<z.infer<typeof InboundSchema>>({
|
||||
resolver: zodResolver(InboundSchema),
|
||||
defaultValues: { remark: '', port: 0 },
|
||||
});
|
||||
useEffect(() => {
|
||||
void methods.trigger();
|
||||
}, [methods]);
|
||||
@@ -157,7 +164,8 @@ const RealitySchema = z.object({
|
||||
});
|
||||
|
||||
function NestedDemo() {
|
||||
const methods = useZodForm(RealitySchema, {
|
||||
const methods = useForm<z.infer<typeof RealitySchema>>({
|
||||
resolver: zodResolver(RealitySchema),
|
||||
defaultValues: {
|
||||
streamSettings: {
|
||||
realitySettings: { dest: 'yahoo.com:443', serverNames: 'yahoo.com,www.yahoo.com' },
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
export { FormField, type FormFieldProps } from './FormField';
|
||||
export { useZodForm } from './useZodForm';
|
||||
export { rhfZodValidate } from './rhfZodValidate';
|
||||
export { normalizeAntdOnChange, type ValueProp } from './normalizeAntdOnChange';
|
||||
export { toDotted, type FieldName } from './toDotted';
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import { useForm } from 'react-hook-form';
|
||||
import type { FieldValues, Resolver, UseFormProps, UseFormReturn } from 'react-hook-form';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import type { z } from 'zod';
|
||||
|
||||
export function useZodForm<TFieldValues extends FieldValues>(
|
||||
schema: z.ZodType<TFieldValues>,
|
||||
options?: Omit<UseFormProps<TFieldValues>, 'resolver'>,
|
||||
): UseFormReturn<TFieldValues> {
|
||||
const resolver = zodResolver(
|
||||
schema as z.ZodType<TFieldValues, TFieldValues>,
|
||||
) as Resolver<TFieldValues>;
|
||||
return useForm<TFieldValues>({
|
||||
mode: 'onSubmit',
|
||||
reValidateMode: 'onChange',
|
||||
shouldUnregister: false,
|
||||
...options,
|
||||
resolver,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user