feat: support rich ticket descriptions
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user