feat(workflow): show variables in drawer
This commit is contained in:
@@ -151,6 +151,59 @@ export function DynamicVariablesDialog({
|
||||
onOpenChange: (open: boolean) => void;
|
||||
definitions: Record<string, DynamicVariableDefinition>;
|
||||
onChange: (definitions: Record<string, DynamicVariableDefinition>) => void;
|
||||
}) {
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-h-[78vh] overflow-hidden rounded-2xl border-hairline bg-card p-0 sm:max-w-[520px]">
|
||||
<DialogHeader className="border-b border-hairline px-6 py-5 text-left">
|
||||
<DialogTitle className="flex items-center gap-2 text-base font-medium">
|
||||
<Braces size={17} />
|
||||
动态变量
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-xs leading-5">
|
||||
助手配置中引用的自定义变量会自动出现在这里。
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<DynamicVariablesEditor
|
||||
definitions={definitions}
|
||||
onChange={onChange}
|
||||
layout="dialog"
|
||||
/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
export function DynamicVariablesPanel({
|
||||
definitions,
|
||||
onChange,
|
||||
}: {
|
||||
definitions: Record<string, DynamicVariableDefinition>;
|
||||
onChange: (definitions: Record<string, DynamicVariableDefinition>) => void;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex min-h-0 flex-1 flex-col bg-canvas-soft px-4 pb-5 pt-4">
|
||||
<p className="mb-3 shrink-0 text-xs leading-5 text-muted-foreground">
|
||||
助手配置中引用的自定义变量会自动出现在这里。
|
||||
</p>
|
||||
<DynamicVariablesEditor
|
||||
definitions={definitions}
|
||||
onChange={onChange}
|
||||
layout="panel"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function DynamicVariablesEditor({
|
||||
definitions,
|
||||
onChange,
|
||||
layout,
|
||||
}: {
|
||||
definitions: Record<string, DynamicVariableDefinition>;
|
||||
onChange: (definitions: Record<string, DynamicVariableDefinition>) => void;
|
||||
layout: "dialog" | "panel";
|
||||
}) {
|
||||
const entries = Object.entries(definitions);
|
||||
const [copiedSystemVariable, setCopiedSystemVariable] = useState<string | null>(
|
||||
@@ -168,20 +221,15 @@ export function DynamicVariablesDialog({
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-h-[78vh] overflow-hidden rounded-2xl border-hairline bg-card p-0 sm:max-w-[520px]">
|
||||
<DialogHeader className="border-b border-hairline px-6 py-5 text-left">
|
||||
<DialogTitle className="flex items-center gap-2 text-base font-medium">
|
||||
<Braces size={17} />
|
||||
动态变量
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-xs leading-5">
|
||||
助手配置中引用的自定义变量会自动出现在这里。
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<Tabs defaultValue="custom" className="min-h-0 px-6 pb-6">
|
||||
<TabsList className="grid w-full shrink-0 grid-cols-2 bg-surface-strong">
|
||||
<Tabs
|
||||
defaultValue="custom"
|
||||
className={
|
||||
layout === "panel"
|
||||
? "flex min-h-0 flex-1 flex-col"
|
||||
: "min-h-0 px-6 pb-6"
|
||||
}
|
||||
>
|
||||
<TabsList className="grid w-full shrink-0 grid-cols-2 bg-surface-strong">
|
||||
<TabsTrigger value="custom">
|
||||
自定义变量
|
||||
<span className="text-[11px] tabular-nums text-muted-foreground">
|
||||
@@ -198,7 +246,11 @@ export function DynamicVariablesDialog({
|
||||
|
||||
<TabsContent
|
||||
value="custom"
|
||||
className="max-h-[calc(78vh-168px)] overflow-y-auto pt-3"
|
||||
className={
|
||||
layout === "panel"
|
||||
? "scrollbar-subtle min-h-0 flex-1 overflow-y-auto pt-3"
|
||||
: "max-h-[calc(78vh-168px)] overflow-y-auto pt-3"
|
||||
}
|
||||
>
|
||||
{entries.length === 0 ? (
|
||||
<div className="rounded-xl border border-dashed border-hairline-strong bg-canvas-soft px-4 py-5 text-center">
|
||||
@@ -316,7 +368,11 @@ export function DynamicVariablesDialog({
|
||||
|
||||
<TabsContent
|
||||
value="system"
|
||||
className="max-h-[calc(78vh-168px)] space-y-3 overflow-y-auto pt-3"
|
||||
className={
|
||||
layout === "panel"
|
||||
? "scrollbar-subtle min-h-0 flex-1 space-y-3 overflow-y-auto pt-3"
|
||||
: "max-h-[calc(78vh-168px)] space-y-3 overflow-y-auto pt-3"
|
||||
}
|
||||
>
|
||||
<p className="text-[11px] leading-5 text-muted-foreground">
|
||||
将完整引用复制到提示词或开场白中,不能只填写中文名称。
|
||||
@@ -363,9 +419,7 @@ export function DynamicVariablesDialog({
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { Bug, Loader2, Save } from "lucide-react";
|
||||
|
||||
import { DebugDrawer } from "@/components/assistant-editor/debug-preview";
|
||||
import { DynamicVariablesDialog } from "@/components/assistant-editor/dynamic-variables";
|
||||
import { DynamicVariablesPanel } from "@/components/assistant-editor/dynamic-variables";
|
||||
import {
|
||||
AssistantIdentity,
|
||||
EditableTitle,
|
||||
@@ -115,6 +115,7 @@ export function WorkflowPage({
|
||||
disabled={!assistantId}
|
||||
onClick={() => {
|
||||
setWorkflowSettingsOpen(false);
|
||||
setDynamicVariablesOpen(false);
|
||||
setWorkflowEditingNodeId(null);
|
||||
setWorkflowEditingEdgeId(null);
|
||||
setWorkflowDebugOpen(true);
|
||||
@@ -144,7 +145,14 @@ export function WorkflowPage({
|
||||
onChange={setWorkflowGraph}
|
||||
settings={workflowSettings}
|
||||
onSettingsChange={setWorkflowSettings}
|
||||
onOpenDynamicVariables={() => setDynamicVariablesOpen(true)}
|
||||
dynamicVariablesOpen={dynamicVariablesOpen}
|
||||
onDynamicVariablesOpenChange={setDynamicVariablesOpen}
|
||||
dynamicVariablesPanel={
|
||||
<DynamicVariablesPanel
|
||||
definitions={dynamicVariableDefinitions}
|
||||
onChange={setWorkflowDynamicVariableDefinitions}
|
||||
/>
|
||||
}
|
||||
editingNodeId={workflowEditingNodeId}
|
||||
onEditingNodeIdChange={setWorkflowEditingNodeId}
|
||||
editingEdgeId={workflowEditingEdgeId}
|
||||
@@ -179,13 +187,6 @@ export function WorkflowPage({
|
||||
knowledgeOptions={kbOptions}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<DynamicVariablesDialog
|
||||
open={dynamicVariablesOpen}
|
||||
onOpenChange={setDynamicVariablesOpen}
|
||||
definitions={dynamicVariableDefinitions}
|
||||
onChange={setWorkflowDynamicVariableDefinitions}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -153,7 +153,9 @@ export function WorkflowCanvas({
|
||||
onSettingsChange,
|
||||
modelOptions,
|
||||
activeNodeId,
|
||||
onOpenDynamicVariables,
|
||||
dynamicVariablesOpen,
|
||||
onDynamicVariablesOpenChange,
|
||||
dynamicVariablesPanel,
|
||||
editingNodeId,
|
||||
onEditingNodeIdChange,
|
||||
editingEdgeId,
|
||||
@@ -288,6 +290,7 @@ export function WorkflowCanvas({
|
||||
setAddSourceId(null);
|
||||
setAddPosition(null);
|
||||
setSettingsOpen(false);
|
||||
onDynamicVariablesOpenChange(false);
|
||||
onDebugOpenChange(false);
|
||||
onEditingEdgeIdChange(null);
|
||||
onEditingNodeIdChange(id);
|
||||
@@ -297,6 +300,7 @@ export function WorkflowCanvas({
|
||||
addSourceId,
|
||||
nodes,
|
||||
onDebugOpenChange,
|
||||
onDynamicVariablesOpenChange,
|
||||
onEditingEdgeIdChange,
|
||||
onEditingNodeIdChange,
|
||||
screenToFlowPosition,
|
||||
@@ -456,11 +460,13 @@ export function WorkflowCanvas({
|
||||
);
|
||||
const openSettings = useCallback(() => {
|
||||
onDebugOpenChange(false);
|
||||
onDynamicVariablesOpenChange(false);
|
||||
onEditingNodeIdChange(null);
|
||||
onEditingEdgeIdChange(null);
|
||||
setSettingsOpen(true);
|
||||
}, [
|
||||
onDebugOpenChange,
|
||||
onDynamicVariablesOpenChange,
|
||||
onEditingEdgeIdChange,
|
||||
onEditingNodeIdChange,
|
||||
setSettingsOpen,
|
||||
@@ -470,6 +476,7 @@ export function WorkflowCanvas({
|
||||
() => ({
|
||||
edit: (id: string) => {
|
||||
setSettingsOpen(false);
|
||||
onDynamicVariablesOpenChange(false);
|
||||
onDebugOpenChange(false);
|
||||
onEditingEdgeIdChange(null);
|
||||
onEditingNodeIdChange(id);
|
||||
@@ -481,6 +488,7 @@ export function WorkflowCanvas({
|
||||
deleteNode,
|
||||
duplicateNode,
|
||||
onDebugOpenChange,
|
||||
onDynamicVariablesOpenChange,
|
||||
onEditingEdgeIdChange,
|
||||
onEditingNodeIdChange,
|
||||
setSettingsOpen,
|
||||
@@ -490,6 +498,7 @@ export function WorkflowCanvas({
|
||||
() => ({
|
||||
edit: (id: string) => {
|
||||
setSettingsOpen(false);
|
||||
onDynamicVariablesOpenChange(false);
|
||||
onDebugOpenChange(false);
|
||||
onEditingNodeIdChange(null);
|
||||
onEditingEdgeIdChange(id);
|
||||
@@ -499,11 +508,25 @@ export function WorkflowCanvas({
|
||||
[
|
||||
deleteEdge,
|
||||
onDebugOpenChange,
|
||||
onDynamicVariablesOpenChange,
|
||||
onEditingEdgeIdChange,
|
||||
onEditingNodeIdChange,
|
||||
setSettingsOpen,
|
||||
],
|
||||
);
|
||||
const openDynamicVariables = useCallback(() => {
|
||||
setSettingsOpen(false);
|
||||
onDebugOpenChange(false);
|
||||
onEditingNodeIdChange(null);
|
||||
onEditingEdgeIdChange(null);
|
||||
onDynamicVariablesOpenChange(true);
|
||||
}, [
|
||||
onDebugOpenChange,
|
||||
onDynamicVariablesOpenChange,
|
||||
onEditingEdgeIdChange,
|
||||
onEditingNodeIdChange,
|
||||
setSettingsOpen,
|
||||
]);
|
||||
|
||||
const editingNode = nodes.find((n) => n.id === editingNodeId);
|
||||
const editingSpec = editingNode ? specsByType[editingNode.type as string] : null;
|
||||
@@ -580,6 +603,7 @@ export function WorkflowCanvas({
|
||||
className="h-10 w-10 rounded-full shadow-sm"
|
||||
aria-label="添加节点"
|
||||
onClick={() => {
|
||||
onDynamicVariablesOpenChange(false);
|
||||
setAddSourceId(null);
|
||||
setAddPosition(null);
|
||||
setAddOpen(true);
|
||||
@@ -613,7 +637,7 @@ export function WorkflowCanvas({
|
||||
variant="outline"
|
||||
className="h-10 w-10 rounded-full border-hairline-strong bg-card text-foreground shadow-sm hover:bg-surface-strong"
|
||||
aria-label="动态变量"
|
||||
onClick={onOpenDynamicVariables}
|
||||
onClick={openDynamicVariables}
|
||||
>
|
||||
<Braces size={17} />
|
||||
</Button>
|
||||
@@ -642,6 +666,7 @@ export function WorkflowCanvas({
|
||||
/>
|
||||
|
||||
{(debugOpen ||
|
||||
dynamicVariablesOpen ||
|
||||
settingsOpen ||
|
||||
(editingNode && editingSpec) ||
|
||||
editingEdge) && (
|
||||
@@ -649,24 +674,30 @@ export function WorkflowCanvas({
|
||||
title={
|
||||
debugOpen
|
||||
? undefined
|
||||
: settingsOpen
|
||||
? "工作流设置"
|
||||
: editingEdge
|
||||
? "编辑连接条件"
|
||||
: `编辑${editingSpec?.displayName ?? "节点"}`
|
||||
: dynamicVariablesOpen
|
||||
? "动态变量"
|
||||
: settingsOpen
|
||||
? "工作流设置"
|
||||
: editingEdge
|
||||
? "编辑连接条件"
|
||||
: `编辑${editingSpec?.displayName ?? "节点"}`
|
||||
}
|
||||
closeLabel={
|
||||
settingsOpen
|
||||
? "关闭工作流设置"
|
||||
: editingEdge
|
||||
? "关闭边编辑"
|
||||
: "关闭节点编辑"
|
||||
dynamicVariablesOpen
|
||||
? "关闭动态变量"
|
||||
: settingsOpen
|
||||
? "关闭工作流设置"
|
||||
: editingEdge
|
||||
? "关闭边编辑"
|
||||
: "关闭节点编辑"
|
||||
}
|
||||
onClose={
|
||||
debugOpen
|
||||
? undefined
|
||||
: () => {
|
||||
if (settingsOpen) setSettingsOpen(false);
|
||||
if (dynamicVariablesOpen) {
|
||||
onDynamicVariablesOpenChange(false);
|
||||
} else if (settingsOpen) setSettingsOpen(false);
|
||||
else if (editingEdge) onEditingEdgeIdChange(null);
|
||||
else onEditingNodeIdChange(null);
|
||||
}
|
||||
@@ -674,6 +705,8 @@ export function WorkflowCanvas({
|
||||
>
|
||||
{debugOpen ? (
|
||||
debugPanel
|
||||
) : dynamicVariablesOpen ? (
|
||||
dynamicVariablesPanel
|
||||
) : (
|
||||
<div className="scrollbar-subtle min-h-0 flex-1 overflow-y-auto bg-canvas-soft px-4 pb-5 pt-4">
|
||||
{settingsOpen ? (
|
||||
|
||||
@@ -33,7 +33,9 @@ export type WorkflowEditorProps = {
|
||||
};
|
||||
toolOptions?: ModelOption[];
|
||||
knowledgeOptions?: ModelOption[];
|
||||
onOpenDynamicVariables: () => void;
|
||||
dynamicVariablesOpen: boolean;
|
||||
onDynamicVariablesOpenChange: (open: boolean) => void;
|
||||
dynamicVariablesPanel: ReactNode;
|
||||
editingNodeId: string | null;
|
||||
onEditingNodeIdChange: (nodeId: string | null) => void;
|
||||
editingEdgeId: string | null;
|
||||
|
||||
Reference in New Issue
Block a user