mirror of
https://github.com/langgenius/dify.git
synced 2026-01-07 23:04:12 +00:00
feat: Implement Zod schema generation for form validation and update form component usage
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import React from 'react'
|
||||
import React, { useMemo } from 'react'
|
||||
import { useAppForm } from '../..'
|
||||
import BaseField from './field'
|
||||
import type { BaseFormProps } from './types'
|
||||
import { generateZodSchema } from './utils'
|
||||
|
||||
const BaseForm = <T,>({
|
||||
initialData,
|
||||
@@ -9,11 +10,22 @@ const BaseForm = <T,>({
|
||||
onSubmit,
|
||||
CustomActions,
|
||||
}: BaseFormProps<T>) => {
|
||||
const schema = useMemo(() => {
|
||||
const schema = generateZodSchema<T>(configurations)
|
||||
return schema
|
||||
}, [configurations])
|
||||
|
||||
const baseForm = useAppForm({
|
||||
defaultValues: initialData,
|
||||
validators: {
|
||||
onSubmit: ({ value }) => {
|
||||
console.log('onSubmit', value)
|
||||
onChange: ({ value }) => {
|
||||
const result = schema.safeParse(value)
|
||||
if (!result.success) {
|
||||
const issues = result.error.issues
|
||||
const firstIssue = issues[0].message
|
||||
return firstIssue
|
||||
}
|
||||
return undefined
|
||||
},
|
||||
},
|
||||
onSubmit: ({ value }) => {
|
||||
|
||||
56
web/app/components/base/form/form-scenarios/base/utils.ts
Normal file
56
web/app/components/base/form/form-scenarios/base/utils.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import type { ZodSchema, ZodString } from 'zod'
|
||||
import { z } from 'zod'
|
||||
import { type BaseConfiguration, BaseVarType } from './types'
|
||||
|
||||
export const generateZodSchema = <T>(fields: BaseConfiguration<T>[]) => {
|
||||
const shape: Record<string, ZodSchema> = {}
|
||||
|
||||
fields.forEach((field) => {
|
||||
let zodType
|
||||
|
||||
switch (field.type) {
|
||||
case BaseVarType.textInput:
|
||||
zodType = z.string()
|
||||
break
|
||||
case BaseVarType.numberInput:
|
||||
zodType = z.number()
|
||||
break
|
||||
case BaseVarType.checkbox:
|
||||
zodType = z.boolean()
|
||||
break
|
||||
case BaseVarType.select:
|
||||
zodType = z.string()
|
||||
break
|
||||
default:
|
||||
zodType = z.any()
|
||||
break
|
||||
}
|
||||
|
||||
if (field.required) {
|
||||
if ([BaseVarType.textInput].includes(field.type))
|
||||
zodType = (zodType as ZodString).nonempty(`${field.label} is required`)
|
||||
}
|
||||
else {
|
||||
zodType = zodType.optional()
|
||||
}
|
||||
|
||||
if (field.maxLength) {
|
||||
if ([BaseVarType.textInput].includes(field.type))
|
||||
zodType = (zodType as ZodString).max(field.maxLength, `${field.label} exceeds max length of ${field.maxLength}`)
|
||||
}
|
||||
|
||||
if (field.min) {
|
||||
if ([BaseVarType.numberInput].includes(field.type))
|
||||
zodType = (zodType as ZodString).min(field.min, `${field.label} must be at least ${field.min}`)
|
||||
}
|
||||
|
||||
if (field.max) {
|
||||
if ([BaseVarType.numberInput].includes(field.type))
|
||||
zodType = (zodType as ZodString).max(field.max, `${field.label} exceeds max value of ${field.max}`)
|
||||
}
|
||||
|
||||
shape[field.variable] = zodType
|
||||
})
|
||||
|
||||
return z.object(shape)
|
||||
}
|
||||
@@ -1,16 +1,17 @@
|
||||
'use client'
|
||||
import InputFieldForm from '../components/base/form/form-scenarios/base'
|
||||
import BaseForm from '../components/base/form/form-scenarios/base'
|
||||
import { BaseVarType } from '../components/base/form/form-scenarios/base/types'
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div className='flex h-screen w-full items-center justify-center p-20'>
|
||||
<div className='w-[400px] rounded-lg border border-components-panel-border bg-components-panel-bg'>
|
||||
<InputFieldForm
|
||||
<BaseForm
|
||||
initialData={{
|
||||
type: 'option_1',
|
||||
variable: 'test',
|
||||
label: 'Test',
|
||||
maxLength: 48,
|
||||
required: true,
|
||||
}}
|
||||
configurations={[
|
||||
@@ -19,14 +20,18 @@ export default function Page() {
|
||||
variable: 'variable',
|
||||
label: 'Variable',
|
||||
required: true,
|
||||
showConditions: [{
|
||||
variable: 'type',
|
||||
value: 'option_1',
|
||||
}],
|
||||
showConditions: [],
|
||||
},
|
||||
{
|
||||
type: BaseVarType.textInput,
|
||||
variable: 'label',
|
||||
label: 'Label',
|
||||
required: true,
|
||||
showConditions: [],
|
||||
},
|
||||
{
|
||||
type: BaseVarType.numberInput,
|
||||
variable: 'max_length',
|
||||
variable: 'maxLength',
|
||||
label: 'Max Length',
|
||||
required: true,
|
||||
showConditions: [],
|
||||
|
||||
Reference in New Issue
Block a user