diff --git a/apps/rowboat/app/projects/[projectId]/workflow/components/TopBar.tsx b/apps/rowboat/app/projects/[projectId]/workflow/components/TopBar.tsx index 8712a2e1..2e6f350c 100644 --- a/apps/rowboat/app/projects/[projectId]/workflow/components/TopBar.tsx +++ b/apps/rowboat/app/projects/[projectId]/workflow/components/TopBar.tsx @@ -1,6 +1,7 @@ "use client"; import React from "react"; import { Button, Dropdown, DropdownItem, DropdownMenu, DropdownTrigger, Spinner, Tooltip, Input } from "@heroui/react"; +import { Button as CustomButton } from "@/components/ui/button"; import { RadioIcon, RedoIcon, UndoIcon, RocketIcon, PenLine, AlertTriangle, DownloadIcon, SettingsIcon, ChevronDownIcon, ZapIcon, Clock, Plug } from "lucide-react"; import { useParams, useRouter } from "next/navigation"; @@ -103,22 +104,28 @@ export function TopBar({
{!isLive && <> - - + + } {/* Deploy CTA - always visible */} diff --git a/apps/rowboat/app/projects/[projectId]/workflow/workflow_editor.tsx b/apps/rowboat/app/projects/[projectId]/workflow/workflow_editor.tsx index 8dfe4d19..a775e4bc 100644 --- a/apps/rowboat/app/projects/[projectId]/workflow/workflow_editor.tsx +++ b/apps/rowboat/app/projects/[projectId]/workflow/workflow_editor.tsx @@ -1483,7 +1483,11 @@ export function WorkflowEditor({ {/* Content Area */} - +
- + - {/* Config Panel - only show when there's a selection */} - {state.present.selection && ( - <> - - {state.present.selection?.type === "agent" && agent.name === state.present.selection!.name)}`} - projectId={projectId} - workflow={state.present.workflow} - agent={state.present.workflow.agents.find((agent) => agent.name === state.present.selection!.name)!} - usedAgentNames={new Set(state.present.workflow.agents.filter((agent) => agent.name !== state.present.selection!.name).map((agent) => agent.name))} - usedPipelineNames={new Set((state.present.workflow.pipelines || []).map((pipeline) => pipeline.name))} - agents={state.present.workflow.agents} - tools={state.present.workflow.tools} - prompts={state.present.workflow.prompts} - dataSources={dataSources} - handleUpdate={(update) => { dispatchGuarded({ type: "update_agent", name: state.present.selection!.name, agent: update }); }} - handleClose={handleUnselectAgent} - useRag={useRag} - triggerCopilotChat={triggerCopilotChat} - eligibleModels={eligibleModels === "*" ? "*" : eligibleModels.agentModels} - onOpenDataSourcesModal={handleOpenDataSourcesModal} - />} - {state.present.selection?.type === "tool" && (() => { - const selectedTool = state.present.workflow.tools.find( - (tool) => tool.name === state.present.selection!.name - ); - return tool.name !== state.present.selection!.name).map((tool) => tool.name), - ])} - handleUpdate={(update) => { dispatchGuarded({ type: "update_tool", name: state.present.selection!.name, tool: update }); }} - handleClose={handleUnselectTool} - />; - })()} - {state.present.selection?.type === "prompt" && prompt.name === state.present.selection!.name)!} - agents={state.present.workflow.agents} - tools={state.present.workflow.tools} - prompts={state.present.workflow.prompts} - usedPromptNames={new Set(state.present.workflow.prompts.filter((prompt) => prompt.name !== state.present.selection!.name).map((prompt) => prompt.name))} - handleUpdate={(update) => { dispatchGuarded({ type: "update_prompt", name: state.present.selection!.name, prompt: update }); }} - handleClose={handleUnselectPrompt} - />} - {state.present.selection?.type === "datasource" && dispatch({ type: "unselect_datasource" })} - onDataSourceUpdate={onDataSourcesUpdated} - />} - {state.present.selection?.type === "pipeline" && pipeline.name === state.present.selection!.name)!} - usedPipelineNames={new Set((state.present.workflow.pipelines || []).filter((pipeline) => pipeline.name !== state.present.selection!.name).map((pipeline) => pipeline.name))} - usedAgentNames={new Set(state.present.workflow.agents.map((agent) => agent.name))} - agents={state.present.workflow.agents} - pipelines={state.present.workflow.pipelines || []} - handleUpdate={handleUpdatePipeline.bind(null, state.present.selection.name)} - handleClose={() => dispatch({ type: "unselect_pipeline" })} - />} - {state.present.selection?.type === "visualise" && ( - -
- Agent Graph Visualizer -
- - - -
- } - > -
- + {/* Config Panel - always rendered, visibility controlled */} + + {state.present.selection?.type === "agent" && agent.name === state.present.selection!.name)}`} + projectId={projectId} + workflow={state.present.workflow} + agent={state.present.workflow.agents.find((agent) => agent.name === state.present.selection!.name)!} + usedAgentNames={new Set(state.present.workflow.agents.filter((agent) => agent.name !== state.present.selection!.name).map((agent) => agent.name))} + usedPipelineNames={new Set((state.present.workflow.pipelines || []).map((pipeline) => pipeline.name))} + agents={state.present.workflow.agents} + tools={state.present.workflow.tools} + prompts={state.present.workflow.prompts} + dataSources={dataSources} + handleUpdate={(update) => { dispatchGuarded({ type: "update_agent", name: state.present.selection!.name, agent: update }); }} + handleClose={handleUnselectAgent} + useRag={useRag} + triggerCopilotChat={triggerCopilotChat} + eligibleModels={eligibleModels === "*" ? "*" : eligibleModels.agentModels} + onOpenDataSourcesModal={handleOpenDataSourcesModal} + />} + {state.present.selection?.type === "tool" && (() => { + const selectedTool = state.present.workflow.tools.find( + (tool) => tool.name === state.present.selection!.name + ); + return tool.name !== state.present.selection!.name).map((tool) => tool.name), + ])} + handleUpdate={(update) => { dispatchGuarded({ type: "update_tool", name: state.present.selection!.name, tool: update }); }} + handleClose={handleUnselectTool} + />; + })()} + {state.present.selection?.type === "prompt" && prompt.name === state.present.selection!.name)!} + agents={state.present.workflow.agents} + tools={state.present.workflow.tools} + prompts={state.present.workflow.prompts} + usedPromptNames={new Set(state.present.workflow.prompts.filter((prompt) => prompt.name !== state.present.selection!.name).map((prompt) => prompt.name))} + handleUpdate={(update) => { dispatchGuarded({ type: "update_prompt", name: state.present.selection!.name, prompt: update }); }} + handleClose={handleUnselectPrompt} + />} + {state.present.selection?.type === "datasource" && dispatch({ type: "unselect_datasource" })} + onDataSourceUpdate={onDataSourcesUpdated} + />} + {state.present.selection?.type === "pipeline" && pipeline.name === state.present.selection!.name)!} + usedPipelineNames={new Set((state.present.workflow.pipelines || []).filter((pipeline) => pipeline.name !== state.present.selection!.name).map((pipeline) => pipeline.name))} + usedAgentNames={new Set(state.present.workflow.agents.map((agent) => agent.name))} + agents={state.present.workflow.agents} + pipelines={state.present.workflow.pipelines || []} + handleUpdate={handleUpdatePipeline.bind(null, state.present.selection.name)} + handleClose={() => dispatch({ type: "unselect_pipeline" })} + />} + {state.present.selection?.type === "visualise" && ( + +
+ Agent Graph Visualizer
-
- )} -
- - - )} + + + +
+ } + > +
+ +
+ + )} + + {/* Second handle - always show (between config and chat panels) */} + {/* ChatApp/Copilot Panel - always visible */}