@@ -13,20 +13,14 @@ import {
1313 ControlButton ,
1414 Controls ,
1515 ReactFlow ,
16- ReactFlowInstance ,
1716 useReactFlow ,
1817} from "@xyflow/react"
1918import "@xyflow/react/dist/style.css"
2019import { KeyboardEvent , useEffect } from "react"
21- import { DropTargetMonitor , useDrop } from "react-dnd"
22- import { NativeTypes } from "react-dnd-html5-backend"
2320import { CustomNodeType , DYNAMIC_EDGE_TYPE } from "../../api/flow"
24- import { EipId } from "../../api/generated/eipFlow"
2521import {
2622 clearFlow ,
2723 clearSelectedChildNode ,
28- createDroppedNode ,
29- importFlowFromJson ,
3024 toggleLayoutDensity ,
3125 updateLayoutOrientation ,
3226} from "../../singletons/store/appActions"
@@ -40,19 +34,13 @@ import {
4034 onEdgesChange ,
4135 onNodesChange ,
4236} from "../../singletons/store/reactFlowActions"
43- import { DragTypes } from "../palette/dragTypes"
4437import DynamicEdge from "./DynamicEdge"
4538import { EipNode , FollowerNode } from "./EipNode"
39+ import { useCanvasDrop } from "./canvasDropHook"
4640
4741const FLOW_ERROR_MESSAGE =
4842 "Failed to load the canvas - the stored flow is malformed. Clearing the flow from the state store."
4943
50- interface FileDrop {
51- files : File [ ]
52- }
53-
54- type DropType = EipId | FileDrop
55-
5644interface ErrorHandlerProps {
5745 message : string
5846 callback : ( ) => void
@@ -64,29 +52,6 @@ const ErrorHandler = ({ message, callback }: ErrorHandlerProps) => {
6452 return null
6553}
6654
67- const acceptDroppedFile = ( file : File , importFlow : ( json : string ) => void ) => {
68- const reader = new FileReader ( )
69- reader . onload = ( e ) => {
70- try {
71- e . target && importFlow ( e . target . result as string )
72- } catch ( e ) {
73- // TODO: Display an error pop-up on failed import
74- // https://github.com/codice/keip-canvas/issues/7
75- console . error ( ( e as Error ) . message )
76- }
77- }
78- reader . readAsText ( file )
79- }
80-
81- const getDropPosition = (
82- monitor : DropTargetMonitor ,
83- reactFlowInstance : ReactFlowInstance
84- ) => {
85- let offset = monitor . getClientOffset ( )
86- offset = offset ?? { x : 0 , y : 0 }
87- return reactFlowInstance . screenToFlowPosition ( offset )
88- }
89-
9055const nodeTypes = {
9156 [ CustomNodeType . EipNode ] : EipNode ,
9257 [ CustomNodeType . FollowerNode ] : FollowerNode ,
@@ -123,40 +88,14 @@ const FlowCanvas = () => {
12388 const flowStore = useFlowStore ( )
12489 const layout = useGetLayout ( )
12590 const { undo, redo } = useUndoRedo ( )
91+ const drop = useCanvasDrop ( reactFlowInstance )
12692
12793 useEffect ( ( ) => {
12894 reactFlowInstance
12995 . fitView ( )
13096 . catch ( ( e ) => console . warn ( "failed to call fitView" , e ) )
13197 } , [ layout , reactFlowInstance ] )
13298
133- const [ , drop ] = useDrop (
134- ( ) => ( {
135- accept : [ DragTypes . FLOWNODE , NativeTypes . FILE ] ,
136- drop : ( item : DropType , monitor ) => {
137- if ( "namespace" in item ) {
138- // Dropping a FLOWNODE creates a new node in the flow.
139- const pos = getDropPosition ( monitor , reactFlowInstance )
140- createDroppedNode ( item , pos )
141- } else if ( "files" in item ) {
142- // Dropping a JSON file imports it as a flow.
143- acceptDroppedFile ( item . files [ 0 ] , importFlowFromJson )
144- } else {
145- console . warn ( "unknown drop type: " , item )
146- }
147- } ,
148- canDrop : ( item : DropType ) => {
149- if ( "files" in item ) {
150- return (
151- item . files . length == 1 && item . files [ 0 ] . type == "application/json"
152- )
153- }
154- return true
155- } ,
156- } ) ,
157- [ reactFlowInstance ]
158- )
159-
16099 // TODO: See if there is a better way to select and clear child nodes,
161100 // to avoid having to clear the selection in multiple components.
162101
0 commit comments