Merging dev into main #49
@@ -1,4 +1,4 @@
|
||||
import { Link } from 'react-router'
|
||||
import {Link} from "react-router";
|
||||
import VisProgUI from "./visualProgrammingUI/VisProgUI.tsx";
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ function VisProgPage() {
|
||||
return (
|
||||
<>
|
||||
<VisProgUI/>
|
||||
<Link to = {"/"}> {/* here you link to the homepage, in App.tsx you can link new pages */}
|
||||
<button className= 'movePage left' onClick={() :void => {}}>
|
||||
<Link to={'/'}> {/* here you link to the homepage, in App.tsx you can link new pages */}
|
||||
<button className="movePage left" onClick={(): void => {}}>
|
||||
Page {'<'}-- Go Home
|
||||
</button>
|
||||
</Link>
|
||||
|
||||
@@ -8,6 +8,10 @@ import {
|
||||
|
||||
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 = [
|
||||
{
|
||||
id: 'start',
|
||||
@@ -29,6 +33,9 @@ const initialNodes = [
|
||||
}
|
||||
];
|
||||
|
||||
/**
|
||||
* contains the initial edges that are created when the editor is loaded
|
||||
*/
|
||||
const initialEdges = [
|
||||
{
|
||||
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) => ({
|
||||
nodes: initialNodes,
|
||||
edges: initialEdges,
|
||||
|
||||
@@ -7,11 +7,19 @@ import {
|
||||
type OnReconnect,
|
||||
} 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;
|
||||
|
||||
|
||||
/**
|
||||
* The type for the Zustand store object used to manage the state of the ReactFlow editor
|
||||
*/
|
||||
export type FlowState = {
|
||||
nodes: Node[];
|
||||
nodes: AppNode[];
|
||||
edges: Edge[];
|
||||
edgeReconnectSuccessful: boolean;
|
||||
onNodesChange: OnNodesChange;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import './VisProgUI.css'
|
||||
|
||||
import {
|
||||
Background,
|
||||
Controls,
|
||||
@@ -9,18 +7,18 @@ import {
|
||||
MarkerType,
|
||||
} from '@xyflow/react';
|
||||
import '@xyflow/react/dist/style.css';
|
||||
import {useShallow} from 'zustand/react/shallow';
|
||||
|
||||
import {
|
||||
StartNode,
|
||||
EndNode,
|
||||
PhaseNode,
|
||||
NormNode
|
||||
} from './components/NodeDefinitions.tsx';
|
||||
|
||||
import {Sidebar} from './components/DragDropSidebar.tsx';
|
||||
|
||||
import {DndToolbar} from './components/DragDropSidebar.tsx';
|
||||
import useFlowStore from './VisProgStores.tsx';
|
||||
import {useShallow} from 'zustand/react/shallow';
|
||||
import type {FlowState} from './VisProgTypes.tsx';
|
||||
import './VisProgUI.css'
|
||||
|
||||
// --| 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) => ({
|
||||
nodes: state.nodes,
|
||||
edges: state.edges,
|
||||
@@ -58,6 +61,12 @@ const selector = (state: FlowState) => ({
|
||||
|
||||
// --| 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 {
|
||||
nodes, edges,
|
||||
@@ -70,8 +79,8 @@ const VisProgUI = () => {
|
||||
} = useFlowStore(useShallow(selector)); // instructs the editor to use the corresponding functions from the FlowStore
|
||||
|
||||
return (
|
||||
<div className={'outer-editor-container'}>
|
||||
<div className={'inner-editor-container'}>
|
||||
<div className={"outer-editor-container"}>
|
||||
<div className={"inner-editor-container"}>
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
@@ -87,8 +96,8 @@ const VisProgUI = () => {
|
||||
fitView
|
||||
proOptions={{hideAttribution: true}}
|
||||
>
|
||||
<Panel position="top-center" className={'dnd-panel'}>
|
||||
<Sidebar/> {/* contains the drag and drop panel for nodes */}
|
||||
<Panel position="top-center" className={"dnd-panel"}>
|
||||
<DndToolbar/> {/* contains the drag and drop panel for nodes */}
|
||||
</Panel>
|
||||
<Controls/>
|
||||
<Background/>
|
||||
|
||||
@@ -10,11 +10,14 @@ import {
|
||||
useState
|
||||
} 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;
|
||||
const getId = () => `dndnode_${id++}`;
|
||||
|
||||
|
||||
/**
|
||||
* DraggableNodeProps dictates the type properties of a DraggableNode
|
||||
*/
|
||||
interface DraggableNodeProps {
|
||||
className?: string;
|
||||
children: ReactNode;
|
||||
@@ -22,11 +25,21 @@ interface DraggableNodeProps {
|
||||
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) {
|
||||
const draggableRef = useRef<HTMLDivElement>(null);
|
||||
const [position, setPosition] = useState<XYPosition>({x: 0, y: 0});
|
||||
|
||||
|
||||
// @ts-ignore
|
||||
useDraggable(draggableRef, {
|
||||
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();
|
||||
|
||||
/**
|
||||
* handleNodeDrop implements the default onDrop behavior
|
||||
*/
|
||||
const handleNodeDrop = useCallback(
|
||||
(nodeType: string, screenPosition: XYPosition) => {
|
||||
const flow = document.querySelector('.react-flow');
|
||||
@@ -120,7 +141,7 @@ export function Sidebar() {
|
||||
);
|
||||
|
||||
return (
|
||||
<aside style={{
|
||||
<div style={{
|
||||
padding: '10px 10px',
|
||||
outline: '2.5pt solid black',
|
||||
borderRadius: '0pt 0pt 5pt 5pt',
|
||||
@@ -147,6 +168,6 @@ export function Sidebar() {
|
||||
norm Node
|
||||
</DraggableNode>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -2,7 +2,9 @@ import {Handle, NodeToolbar, Position, useReactFlow} from '@xyflow/react';
|
||||
import '@xyflow/react/dist/style.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 = {
|
||||
label: string;
|
||||
|
||||
Reference in New Issue
Block a user