"use client" import { useEffect, useState } from "react" import { zodResolver } from "@hookform/resolvers/zod" import { Controller, Resolver, useForm } from "react-hook-form" import { z } from "zod/v4" import { ProjectDialog } from "@/components/project-dialog" import { ContentEditor } from "@/components/content-editor" import { Button } from "@/components/ui/button" import { Field, FieldContent, FieldError, FieldLabel, } from "@/components/ui/field" import { Input } from "@/components/ui/input" import { type KnowledgeDocument, type CreateKnowledgeDocumentPayload, fetchKnowledgeDocument, } from "@/lib/api/admin" import { KnowledgeDocumentContentType, } from "@/lib/generated/enums" type DocumentEditDialogProps = { open: boolean saving: boolean itemId: number | null knowledgeBaseId: number | null onOpenChange: (open: boolean) => void onSubmit: (payload: CreateKnowledgeDocumentPayload) => Promise } const emptyForm: EditForm = { title: "", contentType: KnowledgeDocumentContentType.Markdown, content: "", } const knowledgeDocumentFormSchema = z.object({ title: z.string().trim().min(1, "标题不能为空").max(255, "标题最多255个字符"), contentType: z.string().trim().min(1, "请选择内容类型"), content: z.string().trim().min(1, "内容不能为空"), }) type EditForm = z.infer const editFormResolver = zodResolver(knowledgeDocumentFormSchema as never) as Resolver< z.input, undefined, z.output > function buildForm(item: KnowledgeDocument | null): EditForm { if (!item) { return emptyForm } return { title: item.title, contentType: item.contentType || KnowledgeDocumentContentType.Markdown, content: item.content || "", } } function buildPayload(form: EditForm, knowledgeBaseId: number): CreateKnowledgeDocumentPayload { return { knowledgeBaseId, title: form.title.trim(), contentType: form.contentType, content: form.content.trim(), } } export function DocumentEditDialog({ open, saving, itemId, knowledgeBaseId, onOpenChange, onSubmit, }: DocumentEditDialogProps) { if (!open || !knowledgeBaseId) { return null } return ( ) } type DocumentFormDialogBodyProps = { saving: boolean itemId: number | null knowledgeBaseId: number onOpenChange: (open: boolean) => void onSubmit: (payload: CreateKnowledgeDocumentPayload) => Promise } function DocumentFormDialogBody({ saving, itemId, knowledgeBaseId, onOpenChange, onSubmit, }: DocumentFormDialogBodyProps) { const formId = "knowledge-document-edit-form" const [loading, setLoading] = useState(false) const form = useForm< z.input, undefined, z.output >({ resolver: editFormResolver, defaultValues: emptyForm, }) const { control, handleSubmit, reset, register, setValue, watch, formState: { errors }, } = form const contentType = watch("contentType") const content = watch("content") useEffect(() => { async function loadDetail() { if (!itemId) { reset(emptyForm) return } setLoading(true) try { const data = await fetchKnowledgeDocument(itemId) reset(buildForm(data)) } catch (error) { console.error("Failed to load knowledge document:", error) } finally { setLoading(false) } } void loadDetail() }, [itemId, reset]) async function onFormSubmit(values: EditForm) { const payload = buildPayload({ ...values, contentType, content }, knowledgeBaseId) await onSubmit(payload) } return ( } > {loading ? (
加载中...
) : (
标题 内容 ( { field.onChange(next.raw) setValue("contentType", next.mode, { shouldDirty: true, shouldValidate: true, }) }} placeholder="请输入文档内容" disabled={saving} /> )} />
)}
) }