feat: support rich ticket descriptions

This commit is contained in:
mlogclub
2026-05-03 12:55:27 +08:00
parent 494bf919b2
commit 44319446b7
+16 -10
View File
@@ -9,6 +9,8 @@ import { z } from "zod/v4"
import { OptionCombobox } from "@/components/option-combobox" import { OptionCombobox } from "@/components/option-combobox"
import { ProjectDialog } from "@/components/project-dialog" import { ProjectDialog } from "@/components/project-dialog"
import { RichTextEditor } from "@/components/rich-text-editor"
import { isRichTextEmpty } from "@/components/safe-rich-html"
import { Badge } from "@/components/ui/badge" import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button" import { Button } from "@/components/ui/button"
import { import {
@@ -28,7 +30,6 @@ import {
} from "@/components/ui/field" } from "@/components/ui/field"
import { Input } from "@/components/ui/input" import { Input } from "@/components/ui/input"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover" import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
import { Textarea } from "@/components/ui/textarea"
import { import {
fetchAgentProfilesAll, fetchAgentProfilesAll,
fetchTagsAll, fetchTagsAll,
@@ -57,7 +58,7 @@ type EditDialogProps = {
const schema = z.object({ const schema = z.object({
title: z.string().trim().min(1, "请输入工单标题"), title: z.string().trim().min(1, "请输入工单标题"),
description: z.string().trim().min(1, "请输入问题描述"), description: z.string().refine((value) => !isRichTextEmpty(value), "请输入问题描述"),
currentAssigneeId: z.coerce.number().int().min(0).optional(), currentAssigneeId: z.coerce.number().int().min(0).optional(),
tagIds: z.array(z.number().int().positive()).default([]), tagIds: z.array(z.number().int().positive()).default([]),
}) })
@@ -92,7 +93,7 @@ function buildForm(item: TicketItem | null): EditForm {
function buildInitialForm(initialValues?: Partial<CreateTicketPayload>): EditForm { function buildInitialForm(initialValues?: Partial<CreateTicketPayload>): EditForm {
return { return {
title: initialValues?.title?.trim() ?? "", title: initialValues?.title?.trim() ?? "",
description: initialValues?.description?.trim() ?? "", description: initialValues?.description ?? "",
currentAssigneeId: initialValues?.currentAssigneeId ?? 0, currentAssigneeId: initialValues?.currentAssigneeId ?? 0,
tagIds: initialValues?.tagIds ?? [], tagIds: initialValues?.tagIds ?? [],
} }
@@ -368,14 +369,19 @@ function TicketEditDialogBody({
</Field> </Field>
<Field data-invalid={!!errors.description}> <Field data-invalid={!!errors.description}>
<FieldLabel htmlFor="ticket-description"></FieldLabel> <FieldLabel></FieldLabel>
<FieldContent> <FieldContent>
<Textarea <Controller
id="ticket-description" control={control}
rows={5} name="description"
placeholder="请输入问题描述" render={({ field }) => (
aria-invalid={!!errors.description} <RichTextEditor
{...register("description")} content={field.value ?? ""}
onChange={field.onChange}
placeholder="请输入问题描述"
disabled={saving || loading}
/>
)}
/> />
<FieldError errors={[errors.description]} /> <FieldError errors={[errors.description]} />
</FieldContent> </FieldContent>