Files
UHD_Media_Tool/apps/web/app/components/schedules/draft-check-dialog.tsx
T
rootandClaude Opus 5.5 89795802b5 docs(copy): 日志、计划、运行状态文案按 human-copy 重写
- 「立即执行」统一为「立即运行」,Toast 写「已加入队列」
- 巡检不再提「待处理」:触发条件写「有需要处理的事项时」,开关叫「生成巡检报告」
- 下载巡检触发条件写清包含失败的下载

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
2026-10-07 01:46:30 +08:00

95 lines
3.5 KiB
TypeScript

import { LoaderCircle, Sparkles } from "lucide-react";
import { useState } from "react";
import { useNavigate } from "react-router";
import { toast } from "sonner";
import { useCreateAgentRun } from "~/api/agent.ts";
import { FormField } from "~/components/console/form-field.tsx";
import { consolePath } from "~/components/console/nav.ts";
import { Button } from "~/components/ui/button.tsx";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "~/components/ui/dialog.tsx";
import { Textarea } from "~/components/ui/textarea.tsx";
import { errorMessage } from "~/lib/api.ts";
// 用对话起草巡检:用户一句话描述需求 → 发起智能体对话(起草巡检 Skill)→ 智能体建成未启用的巡检,
// 对话里给「检查并启用」卡片,用户在计划页检查、修改后启用。
const EXAMPLES = [
"每天早上 9 点前看看有没有失败或卡住的下载,有就汇报",
"每隔 6 小时检查一下站点登录有没有失效",
"每周汇报一次订阅追更情况和缺集",
];
export function DraftCheckDialog({ open, onOpenChange }: { open: boolean; onOpenChange: (o: boolean) => void }) {
const [text, setText] = useState("");
const create = useCreateAgentRun();
const navigate = useNavigate();
const submit = async () => {
const need = text.trim();
if (need.length < 4) return;
try {
const run = await create.mutateAsync({ goal: `帮我起草一个巡检:${need}` });
onOpenChange(false);
navigate(consolePath("agent", run.id));
} catch (err) {
toast.error(errorMessage(err, "发起对话失败"));
}
};
return (
<Dialog open={open} onOpenChange={(o) => !create.isPending && onOpenChange(o)}>
<DialogContent className="sm:max-w-lg">
<DialogHeader>
<DialogTitle>用对话起草巡检</DialogTitle>
<DialogDescription>
说说想定期检查什么、多久一次。智能体会建一个未启用的巡检,你检查后再启用。
</DialogDescription>
</DialogHeader>
<form
onSubmit={(e) => {
e.preventDefault();
void submit();
}}
>
<FormField label="需求" htmlFor="draft-need" required>
<Textarea
id="draft-need"
rows={4}
autoFocus
value={text}
placeholder={EXAMPLES[0]}
onChange={(e) => setText(e.target.value)}
/>
</FormField>
<div className="mb-3 flex flex-wrap gap-1.5">
{EXAMPLES.map((x) => (
<button
key={x}
type="button"
onClick={() => setText(x)}
className="rounded-full border border-border/70 px-2.5 py-1 text-left text-meta text-muted-foreground transition-colors hover:border-foreground/40 hover:text-foreground"
>
{x}
</button>
))}
</div>
<DialogFooter>
<Button type="button" variant="ghost" onClick={() => onOpenChange(false)} disabled={create.isPending}>
取消
</Button>
<Button type="submit" disabled={create.isPending || text.trim().length < 4}>
{create.isPending ? <LoaderCircle className="animate-spin" /> : <Sparkles />}
开始起草
</Button>
</DialogFooter>
</form>
</DialogContent>
</Dialog>
);
}