feat: improve layout and styling of EditDialog with enhanced field organization

This commit is contained in:
mlogclub
2026-04-14 17:28:35 +08:00
parent 5b6a654b90
commit f8a3c03213
+107 -104
View File
@@ -743,114 +743,117 @@ function EditDialogBody({
title="服务策略"
description="控制 Graph Tool 转人工配置、兜底策略和自动回复边界。"
>
<div className="grid grid-cols-1 gap-4 xl:grid-cols-4">
<Field data-invalid={!!errors.handoffMode}>
<FieldLabel></FieldLabel>
<FieldContent>
<Controller
control={control}
name="handoffMode"
render={({ field }) => (
<OptionCombobox
value={field.value}
options={handoffModeOptions}
placeholder="请选择转人工模式"
searchPlaceholder="搜索转人工模式"
emptyText="未找到转人工模式"
onChange={field.onChange}
/>
)}
/>
<FieldError errors={[errors.handoffMode]} />
</FieldContent>
</Field>
<Field data-invalid={!!errors.replyTimeoutSeconds}>
<FieldLabel
htmlFor="ai-agent-reply-timeout-seconds"
className="flex items-center gap-1"
>
<Popover>
<PopoverTrigger
render={
<button
type="button"
className="inline-flex items-center justify-center text-muted-foreground hover:text-foreground"
>
<InfoIcon className="size-4" />
</button>
}
<div className="grid grid-cols-1 gap-4 xl:grid-cols-[minmax(0,1fr)_minmax(320px,1.15fr)]">
<div className="space-y-4">
<Field data-invalid={!!errors.handoffMode}>
<FieldLabel></FieldLabel>
<FieldContent>
<Controller
control={control}
name="handoffMode"
render={({ field }) => (
<OptionCombobox
value={field.value}
options={handoffModeOptions}
placeholder="请选择转人工模式"
searchPlaceholder="搜索转人工模式"
emptyText="未找到转人工模式"
onChange={field.onChange}
/>
)}
/>
<PopoverContent side="top" align="start" className="max-w-xs">
<PopoverDescription>
AI 0 使 180
</PopoverDescription>
</PopoverContent>
</Popover>
</FieldLabel>
<FieldContent>
<Input
id="ai-agent-reply-timeout-seconds"
type="number"
min={0}
step={1}
{...register("replyTimeoutSeconds", { valueAsNumber: true })}
/>
<FieldError errors={[errors.replyTimeoutSeconds]} />
</FieldContent>
</Field>
</div>
<FieldError errors={[errors.handoffMode]} />
</FieldContent>
</Field>
<div className="rounded-xl border bg-muted/10 p-4">
<div className="mb-1 text-sm font-medium"></div>
<div className="mb-4 text-xs text-muted-foreground">
{selectedHandoffModeLabel}
{handoffMode ===
String(AIAgentHandoffMode.DefaultTeamPool)
? "。该模式要求至少配置一个客服组。"
: "。仅在涉及转人工时生效。"}
</div>
<Field>
<FieldContent className="space-y-3">
<OptionCombobox
value={teamToAdd}
options={addableTeamOptions}
placeholder="请选择客服组"
searchPlaceholder="搜索客服组"
emptyText="未找到客服组"
onChange={handleAddTeam}
/>
<div className="flex flex-wrap gap-2">
{selectedTeamOptions.length === 0 ? (
<span className="text-sm text-muted-foreground">
</span>
) : (
selectedTeamOptions.map((option) => (
<Badge
key={option.value}
variant="secondary"
className="gap-1 pr-1"
>
{option.label}
<Button
<Field data-invalid={!!errors.replyTimeoutSeconds}>
<FieldLabel
htmlFor="ai-agent-reply-timeout-seconds"
className="flex items-center gap-1"
>
<Popover>
<PopoverTrigger
render={
<button
type="button"
variant="ghost"
size="icon"
className="size-5"
onClick={() =>
handleRemoveTeam(Number(option.value))
}
aria-label={`移除客服组 ${option.label}`}
className="inline-flex items-center justify-center text-muted-foreground hover:text-foreground"
>
<Trash2Icon className="size-3" />
</Button>
</Badge>
))
)}
</div>
</FieldContent>
</Field>
<InfoIcon className="size-4" />
</button>
}
/>
<PopoverContent side="top" align="start" className="max-w-xs">
<PopoverDescription>
AI 0 使 180
</PopoverDescription>
</PopoverContent>
</Popover>
</FieldLabel>
<FieldContent>
<Input
id="ai-agent-reply-timeout-seconds"
type="number"
min={0}
step={1}
{...register("replyTimeoutSeconds", { valueAsNumber: true })}
/>
<FieldError errors={[errors.replyTimeoutSeconds]} />
</FieldContent>
</Field>
</div>
<div className="rounded-lg border bg-muted/10 p-4">
<div className="mb-1 text-sm font-medium"></div>
<div className="mb-4 text-xs text-muted-foreground">
{selectedHandoffModeLabel}
{handoffMode ===
String(AIAgentHandoffMode.DefaultTeamPool)
? "。该模式要求至少配置一个客服组。"
: "。仅在涉及转人工时生效。"}
</div>
<Field>
<FieldContent className="space-y-3">
<OptionCombobox
value={teamToAdd}
options={addableTeamOptions}
placeholder="请选择客服组"
searchPlaceholder="搜索客服组"
emptyText="未找到客服组"
onChange={handleAddTeam}
/>
<div className="flex flex-wrap gap-2">
{selectedTeamOptions.length === 0 ? (
<span className="text-sm text-muted-foreground">
</span>
) : (
selectedTeamOptions.map((option) => (
<Badge
key={option.value}
variant="secondary"
className="gap-1 pr-1"
>
{option.label}
<Button
type="button"
variant="ghost"
size="icon"
className="size-5"
onClick={() =>
handleRemoveTeam(Number(option.value))
}
aria-label={`移除客服组 ${option.label}`}
>
<Trash2Icon className="size-3" />
</Button>
</Badge>
))
)}
</div>
</FieldContent>
</Field>
</div>
</div>
</SectionCard>