From 5df85377f14a2d45ecbce9d70cb86eb7b4c6a5b9 Mon Sep 17 00:00:00 2001 From: emekauja Date: Wed, 5 Jul 2023 14:23:51 +0100 Subject: [PATCH 1/6] fix: added class to sub sidebar to use style --- src/components/sidebar/SubSiderBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/sidebar/SubSiderBar.tsx b/src/components/sidebar/SubSiderBar.tsx index 602f89b..b210c1d 100644 --- a/src/components/sidebar/SubSiderBar.tsx +++ b/src/components/sidebar/SubSiderBar.tsx @@ -11,7 +11,7 @@ export const SubSiderBar = ({ nodes, show = false }: ISubSidebar) => { return ( <> - + {nodes.map(node => ( From 7b6ea430919abab3e690b2f8af065bce6c614e20 Mon Sep 17 00:00:00 2001 From: emekauja Date: Wed, 12 Jul 2023 14:48:16 +0100 Subject: [PATCH 2/6] fix: revert canva engine type x sub sidebar class --- src/components/CanvasWidget.tsx | 8 +++++--- src/components/sidebar/SubSiderBar.tsx | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/CanvasWidget.tsx b/src/components/CanvasWidget.tsx index f68f2de..a1f2675 100644 --- a/src/components/CanvasWidget.tsx +++ b/src/components/CanvasWidget.tsx @@ -1,12 +1,14 @@ import { makeStyles } from '@mui/styles'; import { Box } from '@mui/system'; -import { CanvasWidget as Canvas } from '@projectstorm/react-canvas-core'; +import { + CanvasWidget as Canvas, + CanvasEngine, +} from '@projectstorm/react-canvas-core'; import React, { useCallback } from 'react'; import { DropTargetMonitor, useDrop } from 'react-dnd'; import { CanvasDropTypes } from '../constants'; import vars from './assets/styles/variables'; import { INode, ISidebarNodeProps } from '../types/sidebar'; -import { DiagramEngine } from '@projectstorm/react-diagrams'; const useStyles = makeStyles(_ => ({ container: { @@ -23,7 +25,7 @@ const useStyles = makeStyles(_ => ({ const { canvasBg } = vars; interface ICanvasWidgetProps { - engine: DiagramEngine; + engine: CanvasEngine; className?: string; } diff --git a/src/components/sidebar/SubSiderBar.tsx b/src/components/sidebar/SubSiderBar.tsx index 602f89b..b210c1d 100644 --- a/src/components/sidebar/SubSiderBar.tsx +++ b/src/components/sidebar/SubSiderBar.tsx @@ -11,7 +11,7 @@ export const SubSiderBar = ({ nodes, show = false }: ISubSidebar) => { return ( <> - + {nodes.map(node => ( From e292e606712cc22dd3480416f24884dce33c4b9d Mon Sep 17 00:00:00 2001 From: emekauja Date: Wed, 12 Jul 2023 14:49:29 +0100 Subject: [PATCH 3/6] chore: added custom port model --- src/react-diagrams/MetaLinkFactory.tsx | 4 ++-- src/react-diagrams/MetaNodeModel.ts | 11 +++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/react-diagrams/MetaLinkFactory.tsx b/src/react-diagrams/MetaLinkFactory.tsx index 2b941fa..4180653 100644 --- a/src/react-diagrams/MetaLinkFactory.tsx +++ b/src/react-diagrams/MetaLinkFactory.tsx @@ -5,9 +5,9 @@ import React from 'react'; import { DefaultLinkFactory } from '@projectstorm/react-diagrams'; export class MetaLinkFactory extends DefaultLinkFactory { - componentsMap: Map; + componentsMap: Map; - constructor(componentsMap: Map) { + constructor(componentsMap: Map) { super(ReactDiagramMetaTypes.META_LINK); this.componentsMap = componentsMap; } diff --git a/src/react-diagrams/MetaNodeModel.ts b/src/react-diagrams/MetaNodeModel.ts index 9bf80af..cb2276d 100644 --- a/src/react-diagrams/MetaNodeModel.ts +++ b/src/react-diagrams/MetaNodeModel.ts @@ -3,6 +3,13 @@ import { PortTypes, ReactDiagramMetaTypes, CallbackTypes } from '../constants'; import { DefaultPortModel, NodeModel } from '@projectstorm/react-diagrams'; import { Point } from '@projectstorm/geometry'; import { subPoints } from '../utils'; +import { MetaLinkModel } from './MetaLinkModel'; + +export class MetaPortModel extends DefaultPortModel { + createLinkModel(): MetaLinkModel { + return new MetaLinkModel(); + } +} export class MetaNodeModel extends NodeModel { constructor(options = {}) { @@ -21,7 +28,7 @@ export class MetaNodeModel extends NodeModel { switch (port.getType()) { case PortTypes.INPUT_PORT: this.addPort( - new DefaultPortModel({ + new MetaPortModel({ in: true, name: port.getName(), }) @@ -29,7 +36,7 @@ export class MetaNodeModel extends NodeModel { break; case PortTypes.OUTPUT_PORT: this.addPort( - new DefaultPortModel({ + new MetaPortModel({ in: false, name: port.getName(), }) From c9ceff46b2b66961f62a752d110828d19e777e25 Mon Sep 17 00:00:00 2001 From: emekauja Date: Wed, 12 Jul 2023 14:50:34 +0100 Subject: [PATCH 4/6] chore: added condition link factory port --- src/index.tsx | 37 +++++++++++++++++++----- src/react-diagrams/state/DefaultState.ts | 23 +++++++++++++-- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index ae0e2b6..7e4fca0 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -6,7 +6,7 @@ import { MetaPort } from './models/MetaPort'; import CssBaseline from '@mui/material/CssBaseline'; import { ComponentsMap } from './models/ComponentsMap'; import { LinkModel, PortWidget } from '@projectstorm/react-diagrams'; -import { MetaNodeModel } from './react-diagrams/MetaNodeModel'; +import { MetaNodeModel, MetaPortModel } from './react-diagrams/MetaNodeModel'; import { MetaNodeFactory } from './react-diagrams/MetaNodeFactory'; import { MetaLinkFactory } from './react-diagrams/MetaLinkFactory'; import createEngine, { DiagramModel } from '@projectstorm/react-diagrams'; @@ -72,6 +72,7 @@ const MetaDiagram = forwardRef( // initialize custom diagram state let state = new DefaultState(globalProps?.createLink); + state.isSelection = false; // Sets up the diagram engine @@ -94,7 +95,18 @@ const MetaDiagram = forwardRef( engine .getLinkFactories() // @ts-ignore - .registerFactory(new MetaLinkFactory(componentsMap.links)); + .registerFactory( + !!globalProps.CustomLinkFactory + ? new globalProps.CustomLinkFactory(componentsMap.links) + : new MetaLinkFactory(componentsMap.links) + ); + + if (!!globalProps.CustomPortFactory) { + engine + .getPortFactories() + // @ts-ignore + .registerFactory(new globalProps.CustomPortFactory()); + } // set up the diagram model const model = new DiagramModel(); @@ -193,10 +205,7 @@ const MetaDiagram = forwardRef( if (startsWithSelect && !Boolean(state.isSelection)) { state.isSelection = true; - } else if ( - state.isSelection || - (!startsWithSelect && Boolean(state.isSelection)) - ) { + } else if (Boolean(state.isSelection) || !startsWithSelect) { clearSelection(); state.isSelection = false; } @@ -283,9 +292,21 @@ const MetaDiagram = forwardRef( ); export default MetaDiagram; -export { MetaNode, MetaLink, MetaPort, MetaNodeModel, ComponentsMap }; +export { + MetaNode, + MetaLink, + MetaPort, + MetaNodeModel, + ComponentsMap, + MetaPortModel, +}; export { PortWidget }; export { MetaLinkModel } from './react-diagrams/MetaLinkModel'; +export { MetaLinkFactory } from './react-diagrams/MetaLinkFactory'; export { PortTypes } from './constants'; export { CallbackTypes } from './constants'; -export { EventTypes, DefaultSidebarNodeTypes } from './constants'; +export { + EventTypes, + DefaultSidebarNodeTypes, + ReactDiagramMetaTypes, +} from './constants'; diff --git a/src/react-diagrams/state/DefaultState.ts b/src/react-diagrams/state/DefaultState.ts index 22989f0..05ca077 100644 --- a/src/react-diagrams/state/DefaultState.ts +++ b/src/react-diagrams/state/DefaultState.ts @@ -1,4 +1,4 @@ -import { MouseEvent } from 'react'; +import { MouseEvent, TouchEvent } from 'react'; import { SelectingState, State, @@ -27,7 +27,7 @@ export class DefaultState extends State { this.dragCanvas = new DragCanvasState(); this.dragItems = new DragDiagramItemsState(); this.createLink = customCreateLink ?? new CreateLinkState(); - this.isSelection = true; + this.isSelection = false; // determine what was clicked on this.registerAction( @@ -68,12 +68,29 @@ export class DefaultState extends State { if ( element instanceof PortModel || - element instanceof MetaNodeModel + (element instanceof MetaNodeModel && !this.isSelection) ) { this.transitionWithEvent(this.createLink, event); } }, }) ); + + // touch drags the canvas + this.registerAction( + new Action({ + type: InputType.TOUCH_START, + fire: (event: ActionEvent) => { + const element = this.engine + .getActionEventBus() + .getModelForEvent(event); + // the canvas was clicked on, transition to the dragging canvas state + if (!!this.dragCanvas.config.allowDrag && !element) { + this.transitionWithEvent(this.dragCanvas, event); + } + // this.transitionWithEvent(this.dragCanvas, event); + }, + }) + ); } } From 106a44fd50fd4b44cd54b25c3c36bf3bfb4a866e Mon Sep 17 00:00:00 2001 From: emekauja Date: Mon, 17 Jul 2023 12:39:09 +0100 Subject: [PATCH 5/6] fix: linting problems --- src/components/CanvasWidget.tsx | 4 ++-- src/components/sidebar/Sidebar.tsx | 23 ++++++++++++--------- src/components/sidebar/SidebarItem.tsx | 2 +- src/components/sidebar/SubSidebarItem.tsx | 2 +- src/index.tsx | 11 +++++----- src/react-diagrams/state/CreateLinkState.ts | 2 +- 6 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/components/CanvasWidget.tsx b/src/components/CanvasWidget.tsx index f68f2de..2818b24 100644 --- a/src/components/CanvasWidget.tsx +++ b/src/components/CanvasWidget.tsx @@ -40,11 +40,11 @@ export const CanvasWidget = ({ if (!!node.onNodeDrop) node?.onNodeDrop(monitor, node, engine); }, - [] + [engine] ); // can drop custom hook - const [{}, dropRef] = useDrop({ + const [, dropRef] = useDrop({ accept: CanvasDropTypes.CANVAS_NODE, // canDrop: () => true, drop: onDrop, diff --git a/src/components/sidebar/Sidebar.tsx b/src/components/sidebar/Sidebar.tsx index ad97b97..0938995 100644 --- a/src/components/sidebar/Sidebar.tsx +++ b/src/components/sidebar/Sidebar.tsx @@ -1,4 +1,4 @@ -import React, { Fragment, useEffect, useState } from 'react'; +import React, { Fragment, useCallback, useEffect, useState } from 'react'; import { Box, List } from '@mui/material'; import SidebarItem from './SidebarItem'; @@ -25,19 +25,22 @@ const Sidebar = ({ engine, sidebarNodes, updateSelection }: ISidebarProps) => { ), }; - const handleSelection = (selectedID: DefaultSidebarNodeTypes) => { - if (currentState) { - stateMap[currentState as DefaultSidebarNodeTypes]?.onExit(); - } + const handleSelection = useCallback( + (selectedID: DefaultSidebarNodeTypes) => { + if (currentState) { + stateMap[currentState as DefaultSidebarNodeTypes]?.onExit(); + } - setCurrentState(selectedID); - stateMap[selectedID]?.onEnter(); - updateSelection(selectedID); - }; + setCurrentState(selectedID); + stateMap[selectedID]?.onEnter(); + updateSelection(selectedID); + }, + [currentState, stateMap, updateSelection] + ); useEffect(() => { handleSelection(DefaultSidebarNodeTypes.PANNING); - }, []); + }, [handleSelection]); return ( <> diff --git a/src/components/sidebar/SidebarItem.tsx b/src/components/sidebar/SidebarItem.tsx index 058eade..4f7ea9e 100644 --- a/src/components/sidebar/SidebarItem.tsx +++ b/src/components/sidebar/SidebarItem.tsx @@ -29,7 +29,7 @@ export const SidebarItem = ({ selected, handleSelection, }: SidebarItemProps) => { - const [{}, dragRef, dragPreview] = useDrag( + const [, dragRef, dragPreview] = useDrag( () => ({ type: CanvasDropTypes.CANVAS_NODE, item: node, diff --git a/src/components/sidebar/SubSidebarItem.tsx b/src/components/sidebar/SubSidebarItem.tsx index 6d8c8ee..fa60096 100644 --- a/src/components/sidebar/SubSidebarItem.tsx +++ b/src/components/sidebar/SubSidebarItem.tsx @@ -13,7 +13,7 @@ export const SubSidebarItem = ({ selected, handleSelection, }: ISubSidebarItemProps) => { - const [{}, dragRef, dragPreview] = useDrag( + const [, dragRef, dragPreview] = useDrag( () => ({ type: CanvasDropTypes.CANVAS_NODE, item: node, diff --git a/src/index.tsx b/src/index.tsx index ae0e2b6..30fcdc7 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -69,6 +69,7 @@ const MetaDiagram = forwardRef( ) => { const classes = useStyles(); const linkRef = React.useRef(); + const onMountRef = React.useRef(onMount); // initialize custom diagram state let state = new DefaultState(globalProps?.createLink); @@ -77,7 +78,7 @@ const MetaDiagram = forwardRef( // Sets up the diagram engine // By using useMemo, we ensure that the createEngine() function is only called when the component mounts, // and the same engine instance is reused on subsequent re-renders. - const engine = useMemo(() => createEngine(), [metaNodes, metaLinks]); + const engine = useMemo(() => createEngine(), []); if (metaCallback === undefined) { metaCallback = (node: any) => { @@ -227,13 +228,13 @@ const MetaDiagram = forwardRef( } useEffect(() => { - if (onMount === undefined) { - onMount = (engine: any) => { + if (onMountRef.current === undefined) { + onMountRef.current = (engine: any) => { console.log(engine); }; } - onMount(engine); - }, []); + onMountRef.current(engine); + }, [engine]); // expose api const addNode = (node: any) => { diff --git a/src/react-diagrams/state/CreateLinkState.ts b/src/react-diagrams/state/CreateLinkState.ts index a080915..54f7de3 100644 --- a/src/react-diagrams/state/CreateLinkState.ts +++ b/src/react-diagrams/state/CreateLinkState.ts @@ -64,7 +64,7 @@ export class CreateLinkState extends State { } else if ( element instanceof PortModel && this.sourcePort && - element != this.sourcePort + element !== this.sourcePort ) { if (this.sourcePort.canLinkToPort(element)) { if (!this.link) return; From 6fae8dcf22a16795a6c58236a9e0e828d1570c9f Mon Sep 17 00:00:00 2001 From: emekauja Date: Mon, 17 Jul 2023 14:45:45 +0100 Subject: [PATCH 6/6] fix: revert needed effect dependency --- src/components/sidebar/Sidebar.tsx | 23 ++++++++++------------- src/index.tsx | 2 +- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/components/sidebar/Sidebar.tsx b/src/components/sidebar/Sidebar.tsx index 0938995..ad97b97 100644 --- a/src/components/sidebar/Sidebar.tsx +++ b/src/components/sidebar/Sidebar.tsx @@ -1,4 +1,4 @@ -import React, { Fragment, useCallback, useEffect, useState } from 'react'; +import React, { Fragment, useEffect, useState } from 'react'; import { Box, List } from '@mui/material'; import SidebarItem from './SidebarItem'; @@ -25,22 +25,19 @@ const Sidebar = ({ engine, sidebarNodes, updateSelection }: ISidebarProps) => { ), }; - const handleSelection = useCallback( - (selectedID: DefaultSidebarNodeTypes) => { - if (currentState) { - stateMap[currentState as DefaultSidebarNodeTypes]?.onExit(); - } + const handleSelection = (selectedID: DefaultSidebarNodeTypes) => { + if (currentState) { + stateMap[currentState as DefaultSidebarNodeTypes]?.onExit(); + } - setCurrentState(selectedID); - stateMap[selectedID]?.onEnter(); - updateSelection(selectedID); - }, - [currentState, stateMap, updateSelection] - ); + setCurrentState(selectedID); + stateMap[selectedID]?.onEnter(); + updateSelection(selectedID); + }; useEffect(() => { handleSelection(DefaultSidebarNodeTypes.PANNING); - }, [handleSelection]); + }, []); return ( <> diff --git a/src/index.tsx b/src/index.tsx index 85fbf53..3f2b541 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -79,7 +79,7 @@ const MetaDiagram = forwardRef( // Sets up the diagram engine // By using useMemo, we ensure that the createEngine() function is only called when the component mounts, // and the same engine instance is reused on subsequent re-renders. - const engine = useMemo(() => createEngine(), []); + const engine = useMemo(() => createEngine(), [metaNodes, metaLinks]); if (metaCallback === undefined) { metaCallback = (node: any) => {