Fix panel resizing issues

This commit is contained in:
akhisud3195 2025-09-03 20:03:18 +04:00
parent 2e8e3c89cb
commit c46468be90
2 changed files with 118 additions and 109 deletions

View file

@ -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({
<div className="flex items-center gap-2">
{!isLive && <>
<button
className="p-1 text-gray-400 hover:text-black hover:cursor-pointer"
title="Undo"
disabled={!canUndo}
<CustomButton
variant="primary"
size="sm"
onClick={onUndo}
disabled={!canUndo}
className="bg-gray-50 text-gray-700 hover:bg-gray-100 disabled:bg-gray-25 disabled:text-gray-400"
showHoverContent={true}
hoverContent="Undo"
>
<UndoIcon size={16} />
</button>
<button
className="p-1 text-gray-400 hover:text-black hover:cursor-pointer"
title="Redo"
disabled={!canRedo}
<UndoIcon className="w-4 h-4" />
</CustomButton>
<CustomButton
variant="primary"
size="sm"
onClick={onRedo}
disabled={!canRedo}
className="bg-gray-50 text-gray-700 hover:bg-gray-100 disabled:bg-gray-25 disabled:text-gray-400"
showHoverContent={true}
hoverContent="Redo"
>
<RedoIcon size={16} />
</button>
<RedoIcon className="w-4 h-4" />
</CustomButton>
</>}
{/* Deploy CTA - always visible */}

View file

@ -1483,7 +1483,11 @@ export function WorkflowEditor({
{/* Content Area */}
<ResizablePanelGroup direction="horizontal" className="flex-1 flex overflow-auto gap-1 rounded-xl bg-zinc-50 dark:bg-zinc-900">
<ResizablePanel minSize={10} defaultSize={PANEL_RATIOS.entityList}>
<ResizablePanel
key={`entity-list-${state.present.selection ? '3-pane' : '2-pane'}`}
minSize={10}
defaultSize={PANEL_RATIOS.entityList}
>
<div className="flex flex-col h-full">
<EntityList
ref={entityListRef}
@ -1536,107 +1540,105 @@ export function WorkflowEditor({
/>
</div>
</ResizablePanel>
<ResizableHandle withHandle className="w-[3px] bg-transparent" />
<ResizableHandle withHandle className={`w-[3px] bg-transparent ${!state.present.selection ? 'hidden' : ''}`} />
{/* Config Panel - only show when there's a selection */}
{state.present.selection && (
<>
<ResizablePanel
minSize={20}
defaultSize={50}
className="overflow-auto"
>
{state.present.selection?.type === "agent" && <AgentConfig
key={`agent-${state.present.workflow.agents.findIndex(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 <ToolConfig
key={state.present.selection.name}
tool={selectedTool!}
usedToolNames={new Set([
...state.present.workflow.tools.filter((tool) => 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" && <PromptConfig
key={state.present.selection.name}
prompt={state.present.workflow.prompts.find((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" && <DataSourceConfig
key={state.present.selection.name}
dataSourceId={state.present.selection.name}
handleClose={() => dispatch({ type: "unselect_datasource" })}
onDataSourceUpdate={onDataSourcesUpdated}
/>}
{state.present.selection?.type === "pipeline" && <PipelineConfig
key={state.present.selection.name}
projectId={projectId}
workflow={state.present.workflow}
pipeline={state.present.workflow.pipelines?.find((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" && (
<Panel
title={
<div className="flex items-center justify-between w-full">
<div className="text-base font-semibold text-gray-900 dark:text-gray-100">
Agent Graph Visualizer
</div>
<CustomButton
variant="secondary"
size="sm"
onClick={handleHideVisualise}
showHoverContent={true}
hoverContent="Close"
>
<XIcon className="w-4 h-4" />
</CustomButton>
</div>
}
>
<div className="h-full overflow-hidden">
<AgentGraphVisualizer workflow={state.present.workflow} />
{/* Config Panel - always rendered, visibility controlled */}
<ResizablePanel
minSize={20}
defaultSize={45}
className={`overflow-auto ${!state.present.selection ? 'hidden' : ''}`}
>
{state.present.selection?.type === "agent" && <AgentConfig
key={`agent-${state.present.workflow.agents.findIndex(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 <ToolConfig
key={state.present.selection.name}
tool={selectedTool!}
usedToolNames={new Set([
...state.present.workflow.tools.filter((tool) => 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" && <PromptConfig
key={state.present.selection.name}
prompt={state.present.workflow.prompts.find((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" && <DataSourceConfig
key={state.present.selection.name}
dataSourceId={state.present.selection.name}
handleClose={() => dispatch({ type: "unselect_datasource" })}
onDataSourceUpdate={onDataSourcesUpdated}
/>}
{state.present.selection?.type === "pipeline" && <PipelineConfig
key={state.present.selection.name}
projectId={projectId}
workflow={state.present.workflow}
pipeline={state.present.workflow.pipelines?.find((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" && (
<Panel
title={
<div className="flex items-center justify-between w-full">
<div className="text-base font-semibold text-gray-900 dark:text-gray-100">
Agent Graph Visualizer
</div>
</Panel>
)}
</ResizablePanel>
<ResizableHandle withHandle className="w-[3px] bg-transparent" />
</>
)}
<CustomButton
variant="secondary"
size="sm"
onClick={handleHideVisualise}
showHoverContent={true}
hoverContent="Close"
>
<XIcon className="w-4 h-4" />
</CustomButton>
</div>
}
>
<div className="h-full overflow-hidden">
<AgentGraphVisualizer workflow={state.present.workflow} />
</div>
</Panel>
)}
</ResizablePanel>
{/* Second handle - always show (between config and chat panels) */}
<ResizableHandle withHandle className="w-[3px] bg-transparent" />
{/* ChatApp/Copilot Panel - always visible */}
<ResizablePanel
key={`chat-panel-${state.present.selection ? '3-pane' : '2-pane'}`}
minSize={20}
defaultSize={state.present.selection ? 30 : PANEL_RATIOS.chatApp + PANEL_RATIOS.copilot}
className="overflow-auto"