Files
ai-agent/web/components/dashboard/crud/dashboard-crud-field-control.tsx
T
mlogclub e8d7565caf refactor: replace EditDialog with DashboardCrudFormDialog for companies and quick replies
- Removed the EditDialog component from companies and quick replies.
- Integrated DashboardCrudFormDialog to handle form submissions and editing for both entities.
- Updated the CompanyPicker to utilize the new form dialog for creating companies.
- Introduced DashboardCrudFieldControl for rendering form fields dynamically.
- Added utility functions for building form values and normalizing submit values.
- Updated tests to cover new form utilities and ensure correct behavior for form submissions.
2026-05-28 08:45:15 +08:00

80 lines
2.4 KiB
TypeScript

"use client"
import type { FieldError as HookFormFieldError } from "react-hook-form"
import { Controller, type Control, type UseFormRegister } from "react-hook-form"
import { OptionCombobox } from "@/components/option-combobox"
import {
Field,
FieldContent,
FieldError,
FieldLabel,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
import { cn } from "@/lib/utils"
import type { DashboardCrudFormField } from "./dashboard-crud-utils"
export function DashboardCrudFieldControl<TItem>({
field,
control,
register,
error,
}: {
field: DashboardCrudFormField<TItem>
control: Control<Record<string, string>>
register: UseFormRegister<Record<string, string>>
error?: HookFormFieldError
}) {
const inputId = `dashboard-crud-field-${field.name}`
return (
<Field
data-invalid={!!error}
className={cn(
(field.colSpan === 2 || field.type === "textarea") && "md:col-span-2"
)}
>
<FieldLabel htmlFor={field.type === "select" ? undefined : inputId}>
{field.label}
</FieldLabel>
<FieldContent>
{field.type === "select" ? (
<Controller
control={control}
name={field.name}
render={({ field: controllerField }) => (
<OptionCombobox
value={controllerField.value}
options={[...(field.options ?? [])]}
placeholder={field.placeholder ?? field.label}
onChange={controllerField.onChange}
/>
)}
/>
) : field.type === "textarea" ? (
<Textarea
id={inputId}
rows={field.rows ?? 4}
placeholder={field.placeholder}
aria-invalid={!!error}
{...register(field.name)}
/>
) : (
<Input
id={inputId}
type={field.type === "number" ? "number" : "text"}
min={field.type === "number" ? field.min : undefined}
max={field.type === "number" ? field.max : undefined}
step={field.type === "number" ? field.step : undefined}
placeholder={field.placeholder}
aria-invalid={!!error}
{...register(field.name)}
/>
)}
<FieldError errors={error ? [error] : []} />
</FieldContent>
</Field>
)
}