Skip to content

Feat/frontend canvas - #11

Merged
vedikaagarwal28 merged 2 commits into
mainfrom
feat/frontend-canvas
May 25, 2026
Merged

Feat/frontend canvas#11
vedikaagarwal28 merged 2 commits into
mainfrom
feat/frontend-canvas

Conversation

@vedikaagarwal28

Copy link
Copy Markdown
Collaborator

Description

Added small features: undo/redo, delete/save buttons and resizing/minimizing option for configuration and output panel.


Type of Change

  • Feature
  • Bug Fix
  • Documentation
  • Refactor
  • Other

Related Issues

none


Checklist

  • Code follows project guidelines
  • No secrets committed
  • Documentation updated if required
  • Tested locally

Copilot AI review requested due to automatic review settings May 25, 2026 08:15
@vedikaagarwal28
vedikaagarwal28 merged commit 3a8834d into main May 25, 2026
3 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances the frontend workflow-canvas experience by adding interaction features (undo/redo, delete/save controls, drag-to-trash deletion) and making the sidebar/config/output panels collapsible and resizable for better screen utilization.

Changes:

  • Added undo/redo state management and node/edge deletion support in the pipeline store, plus selection tracking for nodes and edges.
  • Updated the canvas and sidebar UX (edge selection, double-click delete, drag-to-trash delete, double-click-to-add from sidebar).
  • Reworked the main page layout to support collapsible/resizable sidebar/config/output panels and introduced topbar controls (undo/redo/delete/save/run) with toast notifications.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
frontend/src/store/pipelineStore.ts Adds history (past/future), selection for edges, deletion APIs, and undo/redo logic for canvas state.
frontend/src/components/TrashBin.tsx New UI component used as a visual drop target for drag-to-delete.
frontend/src/components/Sidebar.tsx Adds double-click-to-add behavior and refines node list presentation for the collapsible sidebar.
frontend/src/components/output/OutputPanel.tsx UI refinements, save button UX state, and simplified header/layout to fit the resizable output panel container.
frontend/src/components/ConfigPanel.tsx Adjusts styling/layout for the new resizable config panel and improves node type display formatting.
frontend/src/components/Canvas.tsx Adds edge selection, double-click delete, drag-to-trash delete, and drag-stop history integration.
frontend/app/page.tsx Implements new topbar controls, collapsible/resizable panels, and toast notifications around run/save actions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 92 to +111
updateNodeConfig: (nodeId, config) =>
set((state) => ({nodes: state.nodes.map((node) => node.id === nodeId ? {...node, data: {...node.data,config: {...(((node.data as Record<string, unknown>).config as Record<string, unknown>) ?? {}), ...config,},},} : node),})),
})); No newline at end of file
set((state) => ({
nodes: state.nodes.map((node) =>
node.id === nodeId
? {
...node,
data: {
...node.data,
config: {
...(((node.data as Record<string, unknown>).config as Record<
string,
unknown
>) ?? {}),
...config,
},
},
}
: node,
),
})),
Comment on lines +149 to +170
undo: () =>
set((state) => {
if (state.past.length === 0) return state;
const previous = state.past[state.past.length - 1];
return {
past: state.past.slice(0, -1),
future: [{ nodes: state.nodes, edges: state.edges }, ...state.future],
nodes: previous.nodes,
edges: previous.edges,
};
}),

redo: () =>
set((state) => {
if (state.future.length === 0) return state;
const next = state.future[0];
return {
past: [...state.past, { nodes: state.nodes, edges: state.edges }],
future: state.future.slice(1),
nodes: next.nodes,
edges: next.edges,
};
Comment on lines 60 to +65
onConnect: (connection) =>
set((state) => ({ edges: addEdge(connection, state.edges) })),
set((state) => ({
past: [...state.past, { nodes: state.nodes, edges: state.edges }],
future: [],
edges: addEdge(connection, state.edges),
})),
Comment thread frontend/app/page.tsx
}, [editingName]);

useEffect(() => {
if (selectedNodeId && !configOpen) {
Comment thread frontend/app/page.tsx
Comment on lines +167 to +179
const buildSavedRun = (result: any) => {
const output = result.output;
if (!output) return null;
return {
id: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
timestamp: new Date().toISOString(),
modelName: output.model_name ?? output.run_summary?.model ?? "unknown",
taskType: output.run_summary?.task_type ?? "unknown",
metrics: output.metrics ?? {},
configUsed: output.config_used ?? {},
executionTime: result.execution_time ?? 0,
};
};
Comment thread frontend/app/page.tsx
Comment on lines 131 to 138
} catch (e: unknown) {
setExecutionError(e instanceof Error ? e.message : "Something went wrong");
const errorMessage =
e instanceof Error ? e.message : "Something went wrong";
setExecutionError(errorMessage);
setToast({ message: errorMessage, type: "error" });
setToastVisible(true);
setTimeout(() => setToastVisible(false), 3000);
}
Comment thread frontend/app/page.tsx
Comment on lines +439 to +455
<button
onClick={() => setSidebarOpen(false)}
className="w-5 h-5 flex items-center justify-center text-white/30 hover:text-white/60 transition-colors"
>
{/* Arrow points LEFT = collapse to left */}
<svg
width="11"
height="11"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2.5"
strokeLinecap="round"
>
<polyline points="15 18 9 12 15 6" />
</svg>
</button>
Comment thread frontend/app/page.tsx
Comment on lines +493 to +514
<button
onClick={() => setOutputOpen((v) => !v)}
className="w-5 h-5 flex items-center justify-center text-white/30 hover:text-white/60 transition-colors"
>
<svg
width="11"
height="11"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2.5"
strokeLinecap="round"
style={{
transform: outputOpen ? "rotate(0deg)" : "rotate(180deg)",
transition: "transform 0.2s",
}}
>
{/* Points down when open (to collapse), up when closed (to expand) */}
<polyline points="6 9 12 15 18 9" />
</svg>
</button>
</div>
Comment on lines 433 to +438
<button
onClick={handleCopy}
onClick={async () => {
await navigator.clipboard.writeText(code);
setToast("Copied!");
setTimeout(() => setToast(null), 2000);
}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants