diff --git a/src/components/CanvasWidget.tsx b/src/components/CanvasWidget.tsx index 1d6b112..f68f2de 100644 --- a/src/components/CanvasWidget.tsx +++ b/src/components/CanvasWidget.tsx @@ -1,14 +1,12 @@ import { makeStyles } from '@mui/styles'; import { Box } from '@mui/system'; -import { - CanvasEngine, - CanvasWidget as Canvas, -} from '@projectstorm/react-canvas-core'; +import { CanvasWidget as Canvas } 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: { @@ -25,7 +23,7 @@ const useStyles = makeStyles(_ => ({ const { canvasBg } = vars; interface ICanvasWidgetProps { - engine: CanvasEngine; + engine: DiagramEngine; className?: string; } diff --git a/src/components/sidebar/Sidebar.tsx b/src/components/sidebar/Sidebar.tsx index 982258a..ad97b97 100644 --- a/src/components/sidebar/Sidebar.tsx +++ b/src/components/sidebar/Sidebar.tsx @@ -10,7 +10,9 @@ import { PanningState } from './states/PanningState'; import { CreateLinkState } from './states/CreateLinkState'; const Sidebar = ({ engine, sidebarNodes, updateSelection }: ISidebarProps) => { - const [currentState, setCurrentState] = useState(null); + const [currentState, setCurrentState] = useState( + () => DefaultSidebarNodeTypes.CREATE_LINK + ); const reactDiagramsState = engine .getStateMachine() diff --git a/src/components/sidebar/states/CreateLinkState.ts b/src/components/sidebar/states/CreateLinkState.ts index 5d28c25..2053712 100644 --- a/src/components/sidebar/states/CreateLinkState.ts +++ b/src/components/sidebar/states/CreateLinkState.ts @@ -2,11 +2,14 @@ import { State } from './State'; import { updateCanvasMouseCursor } from '../../../utils'; import { CursorTypes } from '../../../constants'; import { DefaultState } from '../../../react-diagrams/state/DefaultState'; +import { DefaultDiagramState } from '@projectstorm/react-diagrams'; export class CreateLinkState extends State { onExit() { if (this.state instanceof DefaultState) { this.state.createLink.config.allowCreate = false; + } else if (this.state instanceof DefaultDiagramState) { + this.state.dragNewLink.config.allowLinksFromLockedPorts = false; } else { this.state.config.allowCreate = false; } @@ -16,6 +19,8 @@ export class CreateLinkState extends State { onEnter() { if (this.state instanceof DefaultState) { this.state.createLink.config.allowCreate = true; + } else if (this.state instanceof DefaultDiagramState) { + this.state.dragNewLink.config.allowLinksFromLockedPorts = true; } else { this.state.config.allowCreate = true; } diff --git a/src/components/sidebar/states/PanningState.ts b/src/components/sidebar/states/PanningState.ts index cde634e..a4e010b 100644 --- a/src/components/sidebar/states/PanningState.ts +++ b/src/components/sidebar/states/PanningState.ts @@ -2,10 +2,14 @@ import { State } from './State'; import { updateCanvasMouseCursor } from '../../../utils'; import { CursorTypes } from '../../../constants'; import { DefaultState } from '../../../react-diagrams/state/DefaultState'; +import { DefaultDiagramState } from '@projectstorm/react-diagrams'; export class PanningState extends State { onExit() { - if (this.state instanceof DefaultState) { + if ( + this.state instanceof DefaultState || + this.state instanceof DefaultDiagramState + ) { this.state.dragCanvas.config.allowDrag = false; } else { this.state.config.allowDrag = false; @@ -14,7 +18,10 @@ export class PanningState extends State { } onEnter() { - if (this.state instanceof DefaultState) { + if ( + this.state instanceof DefaultState || + this.state instanceof DefaultDiagramState + ) { this.state.dragCanvas.config.allowDrag = true; } else { this.state.config.allowDrag = true; diff --git a/src/components/sidebar/states/State.ts b/src/components/sidebar/states/State.ts index 50ef43e..c770596 100644 --- a/src/components/sidebar/states/State.ts +++ b/src/components/sidebar/states/State.ts @@ -1,10 +1,13 @@ +import { DefaultDiagramState } from '@projectstorm/react-diagrams'; import { CreateLinkState } from '../../../react-diagrams/state/CreateLinkState'; import { DefaultState } from '../../../react-diagrams/state/DefaultState'; export class State { - protected state: DefaultState | CreateLinkState; + protected state: DefaultState | CreateLinkState | DefaultDiagramState; - constructor(reactDiagramsState: DefaultState | CreateLinkState) { + constructor( + reactDiagramsState: DefaultState | CreateLinkState | DefaultDiagramState + ) { this.state = reactDiagramsState; } diff --git a/src/index.tsx b/src/index.tsx index 92d82ac..ae0e2b6 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -71,7 +71,8 @@ const MetaDiagram = forwardRef( const linkRef = React.useRef(); // initialize custom diagram state - const state = new DefaultState(globalProps?.createLink); + let state = new DefaultState(globalProps?.createLink); + state.isSelection = false; // Sets up the diagram engine // By using useMemo, we ensure that the createEngine() function is only called when the component mounts, @@ -144,9 +145,10 @@ const MetaDiagram = forwardRef( const sourcePort = link.getSourcePort(); const targetPort = link.getTargetPort(); if (sourcePort && !targetPort) { - model.removeLink(link); + engine.getModel().removeLink(link); } linkRef.current = null; + engine.getStateMachine().popState(); }; let registerNodeListeners = (node: any) => { @@ -181,18 +183,26 @@ const MetaDiagram = forwardRef( .toLowerCase() .startsWith(DefaultSidebarNodeTypes.SELECT); + if (startsWithSelect && Boolean(state.isSelection)) { + return; + } + if (id !== DefaultSidebarNodeTypes.CREATE_LINK && !!linkRef.current) { removeNotValidLink(); } if (startsWithSelect && !Boolean(state.isSelection)) { state.isSelection = true; - } else if (startsWithSelect && Boolean(state.isSelection)) { - return; - } else if (state.isSelection) { + } else if ( + state.isSelection || + (!startsWithSelect && Boolean(state.isSelection)) + ) { clearSelection(); state.isSelection = false; } + if (engine) { + repaintCanvas(); + } }; // load model into engine diff --git a/src/react-diagrams/state/DefaultState.ts b/src/react-diagrams/state/DefaultState.ts index 3fc55ce..22989f0 100644 --- a/src/react-diagrams/state/DefaultState.ts +++ b/src/react-diagrams/state/DefaultState.ts @@ -66,8 +66,12 @@ export class DefaultState extends State { .getActionEventBus() .getModelForEvent(event); - if (element instanceof PortModel || element instanceof MetaNodeModel) + if ( + element instanceof PortModel || + element instanceof MetaNodeModel + ) { this.transitionWithEvent(this.createLink, event); + } }, }) );