Refactor of visual programming page to fully match the CB's program schema. Includes overhaul of UI elements for plan creation. #38

Merged
9828273 merged 23 commits from refactor/nodes-match-functionality into demo 2026-01-07 15:19:47 +00:00
4 changed files with 227 additions and 205 deletions
Showing only changes of commit 111400bd82 - Show all commits

View File

@@ -48,7 +48,8 @@ const selector = (state: FlowState) => ({
undo: state.undo,
redo: state.redo,
beginBatchAction: state.beginBatchAction,
endBatchAction: state.endBatchAction
endBatchAction: state.endBatchAction,
scrollable: state.scrollable
});
// --| define ReactFlow editor |--
@@ -72,7 +73,8 @@ const VisProgUI = () => {
undo,
redo,
beginBatchAction,
endBatchAction
endBatchAction,
scrollable
} = useFlowStore(useShallow(selector)); // instructs the editor to use the corresponding functions from the FlowStore
// adds ctrl+z and ctrl+y support to respectively undo and redo actions
@@ -101,6 +103,7 @@ const VisProgUI = () => {
onConnect={onConnect}
onNodeDragStart={beginBatchAction}
onNodeDragStop={endBatchAction}
preventScrolling={scrollable}
snapToGrid
fitView
proOptions={{hideAttribution: true}}

View File

@@ -72,6 +72,15 @@ const useFlowStore = create<FlowState>(UndoRedo((set, get) => ({
nodes: initialNodes,
edges: initialEdges,
edgeReconnectSuccessful: true,
scrollable: true,
/**
* handles changing the scrollable state of the editor,
* this is used to control if scrolling is captured by the editor
* or if it's available to other components within the reactFlowProvider
* @param {boolean} val - the desired state
*/
setScrollable: (val) => set({scrollable: val}),
/**
* Handles changes to nodes triggered by ReactFlow.

View File

@@ -23,6 +23,10 @@ export type FlowState = {
nodes: Node[];
edges: Edge[];
edgeReconnectSuccessful: boolean;
scrollable: boolean;
/** Handler for managing scrollable state */
setScrollable: (value: boolean) => void;
/** Handler for changes to nodes triggered by ReactFlow */
onNodesChange: OnNodesChange;

View File

@@ -1,4 +1,5 @@
import { useRef, useState } from "react";
import {useRef, useState} from "react";
import useFlowStore from "../VisProgStores.tsx";
import styles from './PlanEditor.module.css';
import { GetActionValue, type Action, type ActionTypes, type Plan } from "../components/Plan";
import { defaultPlan } from "../components/Plan.default";
@@ -21,14 +22,17 @@ export default function PlanEditorDialog({
const [draftPlan, setDraftPlan] = useState<Plan | null>(null);
const [newActionType, setNewActionType] = useState<ActionTypes>("speech");
const [newActionValue, setNewActionValue] = useState("");
const { setScrollable } = useFlowStore();
//Button Actions
const openCreate = () => {
setScrollable(false);
setDraftPlan({...structuredClone(defaultPlan), id: crypto.randomUUID()});
dialogRef.current?.showModal();
};
const openCreateWithDescription = () => {
setScrollable(false);
setDraftPlan({...structuredClone(defaultPlan), id: crypto.randomUUID(), name: description!});
setNewActionType("llm")
setNewActionValue(description!)
@@ -36,12 +40,14 @@ export default function PlanEditorDialog({
}
const openEdit = () => {
setScrollable(false);
if (!plan) return;
setDraftPlan(structuredClone(plan));
dialogRef.current?.showModal();
};
const close = () => {
setScrollable(true);
dialogRef.current?.close();
setDraftPlan(null);
};
@@ -75,7 +81,7 @@ export default function PlanEditorDialog({
<dialog
ref={dialogRef}
className={`${styles.planDialog}`}
onWheel={(e) => e.stopPropagation()}
//onWheel={(e) => e.stopPropagation()}
data-testid={"PlanEditorDialogTestID"}
>
<form method="dialog" className="flex-col gap-md">
@@ -231,5 +237,5 @@ export default function PlanEditorDialog({
</form>
</dialog>
</>
);
);
}