style: added comments to code and changed name of Sidebar to DndToolbar
BREAKING: renamed Sidebar to DndToolbar. ref: N25B-114
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { Link } from 'react-router'
|
import {Link} from "react-router";
|
||||||
import VisProgUI from "./visualProgrammingUI/VisProgUI.tsx";
|
import VisProgUI from "./visualProgrammingUI/VisProgUI.tsx";
|
||||||
|
|
||||||
|
|
||||||
@@ -9,8 +9,8 @@ function VisProgPage() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<VisProgUI/>
|
<VisProgUI/>
|
||||||
<Link to = {"/"}> {/* here you link to the homepage, in App.tsx you can link new pages */}
|
<Link to={'/'}> {/* here you link to the homepage, in App.tsx you can link new pages */}
|
||||||
<button className= 'movePage left' onClick={() :void => {}}>
|
<button className="movePage left" onClick={(): void => {}}>
|
||||||
Page {'<'}-- Go Home
|
Page {'<'}-- Go Home
|
||||||
</button>
|
</button>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ import {
|
|||||||
|
|
||||||
import {type FlowState} from './VisProgTypes.tsx';
|
import {type FlowState} from './VisProgTypes.tsx';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* contains the nodes that are created when the editor is loaded,
|
||||||
|
* should contain at least a start and an end node
|
||||||
|
*/
|
||||||
const initialNodes = [
|
const initialNodes = [
|
||||||
{
|
{
|
||||||
id: 'start',
|
id: 'start',
|
||||||
@@ -29,6 +33,9 @@ const initialNodes = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* contains the initial edges that are created when the editor is loaded
|
||||||
|
*/
|
||||||
const initialEdges = [
|
const initialEdges = [
|
||||||
{
|
{
|
||||||
id: 'start-end',
|
id: 'start-end',
|
||||||
@@ -37,7 +44,11 @@ const initialEdges = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
// this is our useStore hook that we can use in our components to get parts of the store and call actions
|
/**
|
||||||
|
* The useFlowStore hook contains the implementation for editor functionality and state
|
||||||
|
* we can use this inside our editor component to access the current state
|
||||||
|
* and use any implemented functionality
|
||||||
|
*/
|
||||||
const useFlowStore = create<FlowState>((set, get) => ({
|
const useFlowStore = create<FlowState>((set, get) => ({
|
||||||
nodes: initialNodes,
|
nodes: initialNodes,
|
||||||
edges: initialEdges,
|
edges: initialEdges,
|
||||||
|
|||||||
@@ -7,11 +7,19 @@ import {
|
|||||||
type OnReconnect,
|
type OnReconnect,
|
||||||
} from '@xyflow/react';
|
} from '@xyflow/react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a type meant to house different node types, currently not used
|
||||||
|
* but will allow us to more clearly define nodeTypes when we implement
|
||||||
|
* computation of the Graph inside the ReactFlow editor
|
||||||
|
*/
|
||||||
export type AppNode = Node;
|
export type AppNode = Node;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type for the Zustand store object used to manage the state of the ReactFlow editor
|
||||||
|
*/
|
||||||
export type FlowState = {
|
export type FlowState = {
|
||||||
nodes: Node[];
|
nodes: AppNode[];
|
||||||
edges: Edge[];
|
edges: Edge[];
|
||||||
edgeReconnectSuccessful: boolean;
|
edgeReconnectSuccessful: boolean;
|
||||||
onNodesChange: OnNodesChange;
|
onNodesChange: OnNodesChange;
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import './VisProgUI.css'
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Background,
|
Background,
|
||||||
Controls,
|
Controls,
|
||||||
@@ -9,18 +7,18 @@ import {
|
|||||||
MarkerType,
|
MarkerType,
|
||||||
} from '@xyflow/react';
|
} from '@xyflow/react';
|
||||||
import '@xyflow/react/dist/style.css';
|
import '@xyflow/react/dist/style.css';
|
||||||
|
import {useShallow} from 'zustand/react/shallow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
StartNode,
|
StartNode,
|
||||||
EndNode,
|
EndNode,
|
||||||
PhaseNode,
|
PhaseNode,
|
||||||
NormNode
|
NormNode
|
||||||
} from './components/NodeDefinitions.tsx';
|
} from './components/NodeDefinitions.tsx';
|
||||||
|
import {DndToolbar} from './components/DragDropSidebar.tsx';
|
||||||
import {Sidebar} from './components/DragDropSidebar.tsx';
|
|
||||||
|
|
||||||
import useFlowStore from './VisProgStores.tsx';
|
import useFlowStore from './VisProgStores.tsx';
|
||||||
import {useShallow} from 'zustand/react/shallow';
|
|
||||||
import type {FlowState} from './VisProgTypes.tsx';
|
import type {FlowState} from './VisProgTypes.tsx';
|
||||||
|
import './VisProgUI.css'
|
||||||
|
|
||||||
// --| config starting params for flow |--
|
// --| config starting params for flow |--
|
||||||
|
|
||||||
@@ -45,6 +43,11 @@ const DEFAULT_EDGE_OPTIONS = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* defines what functions in the FlowState store map to which names,
|
||||||
|
* @param state
|
||||||
|
*/
|
||||||
const selector = (state: FlowState) => ({
|
const selector = (state: FlowState) => ({
|
||||||
nodes: state.nodes,
|
nodes: state.nodes,
|
||||||
edges: state.edges,
|
edges: state.edges,
|
||||||
@@ -58,6 +61,12 @@ const selector = (state: FlowState) => ({
|
|||||||
|
|
||||||
// --| define ReactFlow editor |--
|
// --| define ReactFlow editor |--
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the ReactFlow visual programming editor component
|
||||||
|
* any implementations of editor logic should be encapsulated where possible
|
||||||
|
* so the Component definition stays as readable as possible
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
const VisProgUI = () => {
|
const VisProgUI = () => {
|
||||||
const {
|
const {
|
||||||
nodes, edges,
|
nodes, edges,
|
||||||
@@ -70,8 +79,8 @@ const VisProgUI = () => {
|
|||||||
} = useFlowStore(useShallow(selector)); // instructs the editor to use the corresponding functions from the FlowStore
|
} = useFlowStore(useShallow(selector)); // instructs the editor to use the corresponding functions from the FlowStore
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'outer-editor-container'}>
|
<div className={"outer-editor-container"}>
|
||||||
<div className={'inner-editor-container'}>
|
<div className={"inner-editor-container"}>
|
||||||
<ReactFlow
|
<ReactFlow
|
||||||
nodes={nodes}
|
nodes={nodes}
|
||||||
edges={edges}
|
edges={edges}
|
||||||
@@ -87,8 +96,8 @@ const VisProgUI = () => {
|
|||||||
fitView
|
fitView
|
||||||
proOptions={{hideAttribution: true}}
|
proOptions={{hideAttribution: true}}
|
||||||
>
|
>
|
||||||
<Panel position="top-center" className={'dnd-panel'}>
|
<Panel position="top-center" className={"dnd-panel"}>
|
||||||
<Sidebar/> {/* contains the drag and drop panel for nodes */}
|
<DndToolbar/> {/* contains the drag and drop panel for nodes */}
|
||||||
</Panel>
|
</Panel>
|
||||||
<Controls/>
|
<Controls/>
|
||||||
<Background/>
|
<Background/>
|
||||||
|
|||||||
@@ -10,11 +10,14 @@ import {
|
|||||||
useState
|
useState
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
|
// Is used to make sure each subsequent node gets a unique id, so the ReactFlow implementation
|
||||||
|
// can distinguish between different nodes.
|
||||||
let id = 0;
|
let id = 0;
|
||||||
const getId = () => `dndnode_${id++}`;
|
const getId = () => `dndnode_${id++}`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DraggableNodeProps dictates the type properties of a DraggableNode
|
||||||
|
*/
|
||||||
interface DraggableNodeProps {
|
interface DraggableNodeProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
@@ -22,11 +25,21 @@ interface DraggableNodeProps {
|
|||||||
onDrop: (nodeType: string, position: XYPosition) => void;
|
onDrop: (nodeType: string, position: XYPosition) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Definition of a node inside the drag and drop toolbar,
|
||||||
|
* these nodes require an onDrop function to be supplied
|
||||||
|
* that dictates how the node is created in the graph.
|
||||||
|
*
|
||||||
|
* @param className
|
||||||
|
* @param children
|
||||||
|
* @param nodeType
|
||||||
|
* @param onDrop
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
function DraggableNode({className, children, nodeType, onDrop}: DraggableNodeProps) {
|
function DraggableNode({className, children, nodeType, onDrop}: DraggableNodeProps) {
|
||||||
const draggableRef = useRef<HTMLDivElement>(null);
|
const draggableRef = useRef<HTMLDivElement>(null);
|
||||||
const [position, setPosition] = useState<XYPosition>({x: 0, y: 0});
|
const [position, setPosition] = useState<XYPosition>({x: 0, y: 0});
|
||||||
|
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
useDraggable(draggableRef, {
|
useDraggable(draggableRef, {
|
||||||
position: position,
|
position: position,
|
||||||
@@ -54,9 +67,17 @@ function DraggableNode({className, children, nodeType, onDrop}: DraggableNodePro
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Sidebar() {
|
/**
|
||||||
|
* the DndToolbar defines how the drag and drop toolbar component works
|
||||||
|
* and includes the default onDrop behavior through handleNodeDrop
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
export function DndToolbar() {
|
||||||
const {setNodes, screenToFlowPosition} = useReactFlow();
|
const {setNodes, screenToFlowPosition} = useReactFlow();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handleNodeDrop implements the default onDrop behavior
|
||||||
|
*/
|
||||||
const handleNodeDrop = useCallback(
|
const handleNodeDrop = useCallback(
|
||||||
(nodeType: string, screenPosition: XYPosition) => {
|
(nodeType: string, screenPosition: XYPosition) => {
|
||||||
const flow = document.querySelector('.react-flow');
|
const flow = document.querySelector('.react-flow');
|
||||||
@@ -120,7 +141,7 @@ export function Sidebar() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<aside style={{
|
<div style={{
|
||||||
padding: '10px 10px',
|
padding: '10px 10px',
|
||||||
outline: '2.5pt solid black',
|
outline: '2.5pt solid black',
|
||||||
borderRadius: '0pt 0pt 5pt 5pt',
|
borderRadius: '0pt 0pt 5pt 5pt',
|
||||||
@@ -147,6 +168,6 @@ export function Sidebar() {
|
|||||||
norm Node
|
norm Node
|
||||||
</DraggableNode>
|
</DraggableNode>
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,9 @@ import {Handle, NodeToolbar, Position, useReactFlow} from '@xyflow/react';
|
|||||||
import '@xyflow/react/dist/style.css';
|
import '@xyflow/react/dist/style.css';
|
||||||
import '../VisProgUI.css';
|
import '../VisProgUI.css';
|
||||||
|
|
||||||
// Datatypes for NodeTypes
|
// Contains the datatypes for the data inside our NodeTypes
|
||||||
|
// this has to be improved or adapted to suit our implementation for computing the graph
|
||||||
|
// into a format that is useful for the Control Backend
|
||||||
|
|
||||||
type defaultNodeData = {
|
type defaultNodeData = {
|
||||||
label: string;
|
label: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user