feat(frontend): 编辑器内联工具箱——就地调生成器(含金手指),结果一键插入正文

Phase 1(写作工作台重构):编辑器「工具箱」按钮打开内联面板,不离开写作界面即可调用
全部生成器(含金手指——后端 golden-finger 早已齐全,此处首次露出)。复用 GeneratorRunner,
为其加可选 onInsertText:文本类产物(开篇/简介/续写/扩写等)点「插入正文」直接追加到章末,
可入库类仍走既有 ingest。useToolboxTools 客户端拉描述符(已单测)。润色/续写/工具箱三卡互斥。
This commit is contained in:
Yaojia Wang
2026-07-07 19:48:13 +02:00
parent 9195cf36f3
commit 04f4785292
5 changed files with 245 additions and 4 deletions

View File

@@ -30,6 +30,8 @@ interface GeneratorRunnerProps {
projectId: string;
tool: ToolDescriptorView;
onClose: () => void;
// 可选:把某条预览文本插入正文(编辑器内联工具箱场景)。工具箱页不传 → 不显示「插入正文」。
onInsertText?: (text: string) => void;
}
// 声明驱动的通用生成器(核心):按 descriptor.input_fields 渲染表单 → 调通用 generate →
@@ -39,6 +41,7 @@ export function GeneratorRunner({
projectId,
tool,
onClose,
onInsertText,
}: GeneratorRunnerProps) {
const gen = useGenerator();
const toast = useToast();
@@ -202,6 +205,11 @@ export function GeneratorRunner({
selectable={canIngest && !singleObject}
checked={selected.has(i)}
onToggle={toggle}
onInsert={
onInsertText
? () => onInsertText(item.body ?? item.heading ?? "")
: undefined
}
/>
))}
</ul>
@@ -276,6 +284,8 @@ interface PreviewRowProps {
selectable: boolean;
checked: boolean;
onToggle: (index: number) => void;
// 可选:把本条插入正文(编辑器内联工具箱)。有可插入文本时才渲染按钮。
onInsert?: () => void;
}
// 统一预览行渲染heading + 次要字段 + 正文段),由 mapPreview 归一,跨工具复用。
@@ -285,7 +295,9 @@ function PreviewRow({
selectable,
checked,
onToggle,
onInsert,
}: PreviewRowProps) {
const canInsert = onInsert && (item.body || item.heading);
return (
<li className="flex gap-2 rounded border border-line bg-bg p-3 text-sm">
{selectable ? (
@@ -310,6 +322,17 @@ function PreviewRow({
{item.body ? (
<p className="whitespace-pre-wrap text-ink">{item.body}</p>
) : null}
{canInsert ? (
<Button
onClick={onInsert}
variant="outline"
size="sm"
className="mt-2"
>
<ArrowLeft className="h-4 w-4 rotate-90" aria-hidden="true" />
</Button>
) : null}
</div>
</li>
);