From 9875b0e8a6011407c2df7c8ae1717114f23fc182 Mon Sep 17 00:00:00 2001
From: Milho001 <l.milhomemfrancochristino@uu.nl>
Date: Wed, 13 Sep 2023 09:19:25 +0000
Subject: [PATCH] feat(schema): avoid edge overlap though interactivity

---
 libs/shared/lib/data-access/store/hooks.ts    |  3 +-
 .../lib/data-access/store/schemaSlice.ts      | 16 ++++-
 .../lib/querybuilder/panel/querybuilder.tsx   | 41 -----------
 libs/shared/lib/schema/panel/schema.tsx       | 25 +++++--
 libs/shared/lib/schema/panel/schemaDialog.tsx | 60 +++++++++++++---
 .../schema/pills/nodes/entity/entity-node.tsx | 15 +++-
 .../pills/nodes/entity/entity.module.scss     | 71 -------------------
 .../nodes/entity/entity.module.scss.d.ts      |  5 --
 .../pills/nodes/relation/relation-node.tsx    | 10 ++-
 .../pills/nodes/relation/relation.module.scss |  8 ---
 .../nodes/relation/relation.module.scss.d.ts  |  5 --
 .../pills/nodes/schema-pills.module.scss      | 29 --------
 .../pills/nodes/schema-pills.module.scss.d.ts |  7 +-
 .../schema/schema-utils/schema-usecases.ts    | 11 +--
 libs/shared/package.json                      |  1 +
 pnpm-lock.yaml                                | 57 +++++++++++++--
 16 files changed, 165 insertions(+), 199 deletions(-)

diff --git a/libs/shared/lib/data-access/store/hooks.ts b/libs/shared/lib/data-access/store/hooks.ts
index 05c86a700..617100672 100644
--- a/libs/shared/lib/data-access/store/hooks.ts
+++ b/libs/shared/lib/data-access/store/hooks.ts
@@ -1,6 +1,6 @@
 import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
 import { selectGraphQueryResult } from './graphQueryResultSlice';
-import { schemaGraph, schemaGraphology, selectSchemaLayout } from './schemaSlice';
+import { schemaGraph, schemaGraphology, selectSchemaLayout, schemaSettingsState } from './schemaSlice';
 import type { RootState, AppDispatch } from './store';
 import { configState } from '@graphpolaris/shared/lib/data-access/store/configSlice';
 import {
@@ -24,6 +24,7 @@ export const useGraphQueryResult = () => useAppSelector(selectGraphQueryResult);
 // Gives the schema form the store (as a graphology object)
 export const useSchemaGraphology = () => useAppSelector(schemaGraphology);
 export const useSchemaGraph = () => useAppSelector(schemaGraph);
+export const useSchemaSettings = () => useAppSelector(schemaSettingsState);
 
 // Gives the schema form the store (as a graphology object)
 export const useSchemaLayout = () => useAppSelector(selectSchemaLayout);
diff --git a/libs/shared/lib/data-access/store/schemaSlice.ts b/libs/shared/lib/data-access/store/schemaSlice.ts
index b187a78d9..082302c52 100644
--- a/libs/shared/lib/data-access/store/schemaSlice.ts
+++ b/libs/shared/lib/data-access/store/schemaSlice.ts
@@ -6,9 +6,14 @@ import { SchemaFromBackend, SchemaGraph, SchemaGraphology } from '../../schema';
 
 /**************************************************************** */
 
+export type SchemaSettings = {
+  connectionType: 'connection' | 'bezier' | 'straight' | 'step';
+};
+
 type schemaSliceI = {
   graphologySerialized: SchemaGraph;
   layoutName: AllLayoutAlgorithms;
+  settings: SchemaSettings;
 };
 
 // Define the initial state using that type
@@ -16,6 +21,9 @@ export const initialState: schemaSliceI = {
   graphologySerialized: new SchemaGraphology().export(),
   // layoutName: 'Cytoscape_fcose',
   layoutName: CytoscapeLayoutAlgorithms.KLAY as AllLayoutAlgorithms,
+  settings: {
+    connectionType: 'connection',
+  },
 };
 export const schemaSlice = createSlice({
   name: 'schema',
@@ -68,9 +76,15 @@ export const schemaSlice = createSlice({
 
       // state.graphologySerialized = schema.export();
     },
+
+    setSchemaSettings: (state, action: PayloadAction<SchemaSettings>) => {
+      state.settings = action.payload;
+    },
   },
 });
-export const { readInSchemaFromBackend, setSchema } = schemaSlice.actions;
+export const { readInSchemaFromBackend, setSchema, setSchemaSettings } = schemaSlice.actions;
+
+export const schemaSettingsState = (state: RootState) => state.schema.settings;
 
 /**
  * Select the schema and convert it to a graphology object
diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.tsx b/libs/shared/lib/querybuilder/panel/querybuilder.tsx
index 0ba2b7ece..f0955f7d5 100644
--- a/libs/shared/lib/querybuilder/panel/querybuilder.tsx
+++ b/libs/shared/lib/querybuilder/panel/querybuilder.tsx
@@ -98,45 +98,6 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => {
 
   const elements = useMemo(() => createReactFlowElements(graphologyGraph), [graph]);
 
-  /**
-   * Called when a node is dragged in querybuilder to allow for movement
-   * @param event
-   * @param node
-   */
-  const onNodeDrag = (event: React.MouseEvent<Element, MouseEvent>, node: Node<any>, nodes: Node[]) => {
-    // console.log(nodes);
-    // // Get the node in the elements list to get the previous location
-    // const pNode = elements.nodes.find((e) => e?.id === node?.id);
-    // if (!(pNode && isNode(pNode))) return;
-    // // This is then used to calculate the delta position
-    // const dx = node.position.x - pNode.position.x;
-    // const dy = node.position.y - pNode.position.y;
-    // // Check if we started dragging, if so, call the drag started usecase
-    // if (!isDraggingPill.current) {
-    //   dragPillStarted(node.id, graphologyGraph);
-    //   isDraggingPill.current = true;
-    // }
-    // // Call the drag usecase
-    // movePillTo(node.id, graphologyGraph, dx, dy, node.position);
-    // // Dispatch the new graphology object, so reactflow will get rerendered
-    // dispatch(setQuerybuilderNodes(graphologyGraph.export()));
-  };
-
-  /**
-   * Called when a node is released from dragging in querybuilder
-   * @param event
-   * @param node
-   **/
-  const onNodeDragStop = (event: React.MouseEvent<Element, MouseEvent>, node: Node<any>) => {
-    // isDraggingPill.current = false;
-    //
-    // // Call the drag pill stopped usecase
-    // dragPillStopped(node.id, graphologyGraph);
-    //
-    // // Dispatch the new graphology object, so reactflow will get rerendered
-    // dispatch(setQuerybuilderNodes(graphologyGraph.export()));
-  };
-
   /**
    * Clears all nodes in the graph.
    */
@@ -470,8 +431,6 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => {
         // connectionMode={ConnectionMode.Loose}
         onInit={onInit}
         onNodesChange={onNodesChange}
-        onNodeDrag={onNodeDrag}
-        onNodeDragStop={onNodeDragStop}
         onDragOver={onDragOver}
         onConnect={onConnect}
         onConnectStart={onConnectStart}
diff --git a/libs/shared/lib/schema/panel/schema.tsx b/libs/shared/lib/schema/panel/schema.tsx
index ac1f856e8..9a0c2c5b2 100644
--- a/libs/shared/lib/schema/panel/schema.tsx
+++ b/libs/shared/lib/schema/panel/schema.tsx
@@ -1,6 +1,13 @@
 import { AlgorithmToLayoutProvider, AllLayoutAlgorithms, LayoutFactory } from '@graphpolaris/shared/lib/graph-layout';
 import { schemaGraphology2Reactflow, schemaExpandRelation } from '@graphpolaris/shared/lib/schema/schema-utils';
-import { useSchemaGraph, useSchemaGraphology, useSchemaLayout, useSessionCache } from '@graphpolaris/shared/lib/data-access/store';
+import {
+  useSchemaGraph,
+  useSchemaGraphology,
+  useSchemaLayout,
+  useSchemaSettings,
+  useSessionCache,
+} from '@graphpolaris/shared/lib/data-access/store';
+import { SmartBezierEdge, SmartStepEdge, SmartStraightEdge } from '@tisoap/react-flow-smart-edge';
 
 import { useEffect, useMemo, useRef, useState } from 'react';
 import ReactFlow, {
@@ -12,7 +19,6 @@ import ReactFlow, {
   useNodesState,
   useEdgesState,
   ReactFlowInstance,
-  Background,
 } from 'reactflow';
 import CachedIcon from '@mui/icons-material/Cached';
 import SettingsIcon from '@mui/icons-material/Settings';
@@ -52,13 +58,17 @@ const nodeTypes = {
 const edgeTypes = {
   nodeEdge: NodeEdge,
   selfEdge: SelfEdge,
-
+  // connection: ConnectionLine,
+  bezier: SmartBezierEdge,
   connection: ConnectionLine,
+  straight: SmartStraightEdge,
+  step: SmartStepEdge,
 };
 
 export const Schema = (props: Props) => {
   const api_schema = useSchemaAPI();
   const session = useSessionCache();
+  const settings = useSchemaSettings();
 
   const [toggleSchemaSettings, setToggleSchemaSettings] = useState(false);
   const [nodes, setNodes, onNodeChanged] = useNodesState([] as Node[]);
@@ -99,7 +109,7 @@ export const Schema = (props: Props) => {
     const expandedSchema = schemaExpandRelation(schemaGraphology);
     layout.current?.layout(expandedSchema);
 
-    const schemaFlow = schemaGraphology2Reactflow(expandedSchema);
+    const schemaFlow = schemaGraphology2Reactflow(expandedSchema, settings.connectionType);
 
     // schemaFlow.nodes.forEach((n) => {
     //   n.data.toggleNodeQualityPopup = toggleNodeQualityPopup;
@@ -123,7 +133,7 @@ export const Schema = (props: Props) => {
     //   schemaGraphology.order,
     //   schemaFlow
     // );
-  }, [schemaGraph, schemaLayout]);
+  }, [schemaGraph, schemaLayout, settings]);
 
   // console.log(nodes, edges);
 
@@ -142,8 +152,10 @@ export const Schema = (props: Props) => {
       <ReactFlowProvider>
         <div className="h-[calc(100%-.8rem)] w-full">
           <ReactFlow
+            snapGrid={[10, 10]}
+            snapToGrid
             onlyRenderVisibleElements={false}
-            nodesDraggable={false}
+            nodesDraggable={true}
             nodeTypes={nodeTypes}
             edgeTypes={edgeTypes}
             connectionLineComponent={ConnectionDragLine}
@@ -152,7 +164,6 @@ export const Schema = (props: Props) => {
             nodes={nodes}
             edges={edges}
             onInit={onInit}
-            panOnDrag={false}
             attributionPosition="top-right"
           >
             <Controls showInteractive={false} showZoom={false} showFitView={true} className={styles.controls}>
diff --git a/libs/shared/lib/schema/panel/schemaDialog.tsx b/libs/shared/lib/schema/panel/schemaDialog.tsx
index 1784d9460..17a986178 100644
--- a/libs/shared/lib/schema/panel/schemaDialog.tsx
+++ b/libs/shared/lib/schema/panel/schemaDialog.tsx
@@ -2,8 +2,24 @@ import { PropsWithChildren, useEffect, useRef } from 'react';
 import { Dialog, DialogProps } from '../../components/Dialog';
 import React from 'react';
 import CloseIcon from '@mui/icons-material/Close';
+import { useAppDispatch, useSchemaSettings } from '../../data-access';
+import { SchemaSettings, setSchemaSettings } from '../../data-access/store/schemaSlice';
 
 export const SchemaDialog = React.forwardRef<HTMLDivElement, DialogProps>((props, ref) => {
+  const settings = useSchemaSettings();
+  const dispatch = useAppDispatch();
+  const [state, setState] = React.useState<SchemaSettings>(settings);
+
+  useEffect(() => {
+    setState(settings);
+  }, [settings, props.open]);
+
+  function submit() {
+    dispatch(setSchemaSettings(state));
+
+    props.onClose();
+  }
+
   return (
     <>
       {props.open && (
@@ -13,6 +29,7 @@ export const SchemaDialog = React.forwardRef<HTMLDivElement, DialogProps>((props
               className="card-body px-0 w-72 py-5"
               onSubmit={(e) => {
                 e.preventDefault();
+                submit();
               }}
             >
               <div className="card-title p-5 py-0 flex w-full">
@@ -53,21 +70,42 @@ export const SchemaDialog = React.forwardRef<HTMLDivElement, DialogProps>((props
               <div className="divider m-0"></div>
               <div className="form-control px-5">
                 <label className="label">
-                  <span className="label-text">Goal Value</span>
+                  <span className="label-text">Type of Connection</span>
                 </label>
-                <select className="select select-primary select-sm ">
-                  <option className="option">35438</option>
+                <select
+                  className="select select-primary select-sm "
+                  value={state.connectionType}
+                  onChange={(e) => {
+                    setState({ ...state, connectionType: e.target.value as any });
+                  }}
+                >
+                  <option className="option" value="connection">
+                    Default
+                  </option>
+                  <option className="option" value="step">
+                    Step
+                  </option>
+                  <option className="option" value="straight">
+                    Straight
+                  </option>
+                  <option className="option" value="bezier">
+                    Bezier
+                  </option>
                 </select>
               </div>
               <div className="divider m-0"></div>
-              <div className="card-actions w-full px-5">
-                <button className="btn btn-primary w-full">Apply</button>
-              </div>
-              <div className="card-actions w-full px-5">
-                <button className="btn btn-secondary w-full">Cancel</button>
-              </div>
-              <div className="card-actions w-full px-5">
-                <button className="btn btn-outline w-full">Advance settings</button>
+
+              <div className="card-actions mt-1 w-full px-5 flex flex-row">
+                <button
+                  className="btn btn-secondary flex-grow"
+                  onClick={(e) => {
+                    e.preventDefault();
+                    props.onClose();
+                  }}
+                >
+                  Cancel
+                </button>
+                <button className="btn btn-primary flex-grow">Apply</button>
               </div>
             </form>
           </div>
diff --git a/libs/shared/lib/schema/pills/nodes/entity/entity-node.tsx b/libs/shared/lib/schema/pills/nodes/entity/entity-node.tsx
index 81cfe7a4b..aca2c7457 100644
--- a/libs/shared/lib/schema/pills/nodes/entity/entity-node.tsx
+++ b/libs/shared/lib/schema/pills/nodes/entity/entity-node.tsx
@@ -31,6 +31,7 @@ export const EntityNode = React.memo(({ id, data }: NodeProps<SchemaReactflowNod
    * @param event React Mouse drag event
    */
   const onDragStart = (event: React.DragEvent<HTMLDivElement>) => {
+    console.log('dragging entiry', id, data);
     // console.log('dragging entiry', id, data);
     // console.log(id, data);
     event.dataTransfer.setData('application/reactflow', JSON.stringify({ type: QueryElementTypes.Entity, name: id }));
@@ -52,7 +53,15 @@ export const EntityNode = React.memo(({ id, data }: NodeProps<SchemaReactflowNod
   };
 
   return (
-    <div className={styles.entityNode} onDragStart={(event) => onDragStart(event)} draggable>
+    <div
+      className="border-l-2 bg-offwhite-200 border-l-entity-600 min-w-[8rem] text-[0.8rem]"
+      onDragStart={(event) => onDragStart(event)}
+      onDragStartCapture={(event) => onDragStart(event)}
+      onMouseDownCapture={(event) => {
+        if (!event.shiftKey) event.stopPropagation();
+      }}
+      draggable
+    >
       {/* <div
         className={styles.entityNodeAttributesBox}
         onClick={() => onClickToggleAttributeAnalyticsPopupMenu()}
@@ -156,8 +165,8 @@ export const EntityNode = React.memo(({ id, data }: NodeProps<SchemaReactflowNod
         type="target"
         // hidden={Array.from(data.handles).includes('entityTargetBottom') ? false : true}
       ></Handle> */}
-      <div className={styles.nodeWrapper}>
-        <span className={styles.nodeData}>{id}</span>
+      <div className="p-2 py-1">
+        <span className="">{id}</span>
       </div>
     </div>
   );
diff --git a/libs/shared/lib/schema/pills/nodes/entity/entity.module.scss b/libs/shared/lib/schema/pills/nodes/entity/entity.module.scss
index 6c88a9bec..ec0ccd5e8 100644
--- a/libs/shared/lib/schema/pills/nodes/entity/entity.module.scss
+++ b/libs/shared/lib/schema/pills/nodes/entity/entity.module.scss
@@ -1,13 +1,5 @@
 @import '../schema-pills.module.scss';
 
-.entityNode {
-  border-left: 3px solid;
-  @apply bg-offwhite-200;
-  @apply border-l-entity-600;
-  min-width: 8rem;
-  font-size: 13px;
-}
-
 .entityNodeAttributesBox {
   height: 20px;
   position: absolute;
@@ -40,66 +32,3 @@
   transform: rotate(90deg) translate(-50%, -45%) scale(0.65) !important;
   @apply border-b-entity-300 #{!important};
 }
-
-// nodeWrapper: {
-//   display: 'inherit',
-//   color: SchemaThemeHolder.entity.textColor,
-//   textAlign: 'center',
-//   justifyContent: 'space-between',
-//   alignItems: 'center',
-//   width: 'inherit',
-// },
-
-// nodeSpan: {
-//   margin: '0 0.5em 0 1em',
-//   float: 'right',
-// },
-
-// nodeData: {
-//   flexGrow: 2,
-// },
-
-// entityNodeAttributesBox: {
-//   height: 20,
-//   position: 'absolute',
-//   left: '115px',
-//   top: '-33%',
-//   transform: 'translateX(50%)',
-//   borderRadius: '1px',
-//   boxShadow: '-1px 2px 5px #888888',
-//   textAlign: 'right',
-// },
-
-// entityNodeNodesBox: {
-//   height: 20,
-//   position: 'absolute',
-//   left: '115px',
-//   top: '54%',
-//   transform: 'translateX(50%)',
-//   borderRadius: '1px',
-//   boxShadow: '-1px 2px 5px #888888',
-//   textAlign: 'right',
-// },
-
-// controls: {
-//   left: 'auto !important',
-//   bottom: 'auto !important',
-//   top: '10px',
-//   right: '20px',
-//   width: 'auto !important',
-// },
-
-// exportButton: {
-//   left: 'auto !important',
-//   bottom: 'auto !important',
-//   top: '10px',
-//   right: '20px',
-//   '& svg': {
-//     transform: 'scale(1.4)',
-//   },
-// },
-
-// menuText: {
-//   fontSize: 'small',
-//   fontFamily: 'Poppins, sans-serif',
-// },
diff --git a/libs/shared/lib/schema/pills/nodes/entity/entity.module.scss.d.ts b/libs/shared/lib/schema/pills/nodes/entity/entity.module.scss.d.ts
index ad5150215..6856f4d0e 100644
--- a/libs/shared/lib/schema/pills/nodes/entity/entity.module.scss.d.ts
+++ b/libs/shared/lib/schema/pills/nodes/entity/entity.module.scss.d.ts
@@ -1,9 +1,4 @@
 declare const classNames: {
-  readonly nodeSpan: 'nodeSpan';
-  readonly entityNodeNodesBox: 'entityNodeNodesBox';
-  readonly nodeWrapper: 'nodeWrapper';
-  readonly nodeData: 'nodeData';
-  readonly entityNode: 'entityNode';
   readonly entityNodeAttributesBox: 'entityNodeAttributesBox';
   readonly handleTriangle: 'handleTriangle';
   readonly handleTriangleRight: 'handleTriangleRight';
diff --git a/libs/shared/lib/schema/pills/nodes/relation/relation-node.tsx b/libs/shared/lib/schema/pills/nodes/relation/relation-node.tsx
index 760231dd8..7dbffdf3e 100644
--- a/libs/shared/lib/schema/pills/nodes/relation/relation-node.tsx
+++ b/libs/shared/lib/schema/pills/nodes/relation/relation-node.tsx
@@ -59,10 +59,14 @@ export const RelationNode = React.memo(({ id, data }: NodeProps<SchemaReactflowR
   return (
     <div
       onDragStart={(event) => onDragStart(event)}
+      onDragStartCapture={(event) => onDragStart(event)}
+      onMouseDownCapture={(event) => {
+        if (!event.shiftKey) event.stopPropagation();
+      }}
       draggable
       // style={{ width: 100, height: 100 }}
     >
-      <div className={styles.relationNode}>
+      <div className="text-[0.8rem] border-l-2 bg-offwhite-200 border-l-relation-600 min-w-[8rem]">
         <Handle
           style={{ pointerEvents: 'none' }}
           className={styles.handleTriangleTop}
@@ -113,8 +117,8 @@ export const RelationNode = React.memo(({ id, data }: NodeProps<SchemaReactflowR
           <span className={styles.nodeSpan}>{data.nodeCount}</span>
         </div> */}
 
-        <div className={styles.nodeWrapper}>
-          <span className={styles.nodeData}>{data.collection}</span>
+        <div className="p-2 py-1">
+          <span className="">{data.collection}</span>
         </div>
 
         <Handle className={styles.handleTriangleBottom} style={{ pointerEvents: 'none' }} position={Position.Bottom} type="source"></Handle>
diff --git a/libs/shared/lib/schema/pills/nodes/relation/relation.module.scss b/libs/shared/lib/schema/pills/nodes/relation/relation.module.scss
index a059d3a4b..3e8bd9bd7 100644
--- a/libs/shared/lib/schema/pills/nodes/relation/relation.module.scss
+++ b/libs/shared/lib/schema/pills/nodes/relation/relation.module.scss
@@ -2,14 +2,6 @@
 
 $width: 145;
 
-.relationNode {
-  border-left: 3px solid;
-  @apply bg-offwhite-200;
-  @apply border-l-relation-600;
-  min-width: 8rem;
-  font-size: 13px;
-}
-
 .handleTriangle {
   border-radius: 0px !important;
   background: transparent !important;
diff --git a/libs/shared/lib/schema/pills/nodes/relation/relation.module.scss.d.ts b/libs/shared/lib/schema/pills/nodes/relation/relation.module.scss.d.ts
index e2dbf0e7c..24d00a2ba 100644
--- a/libs/shared/lib/schema/pills/nodes/relation/relation.module.scss.d.ts
+++ b/libs/shared/lib/schema/pills/nodes/relation/relation.module.scss.d.ts
@@ -1,9 +1,4 @@
 declare const classNames: {
-  readonly nodeSpan: 'nodeSpan';
-  readonly entityNodeNodesBox: 'entityNodeNodesBox';
-  readonly nodeWrapper: 'nodeWrapper';
-  readonly nodeData: 'nodeData';
-  readonly relationNode: 'relationNode';
   readonly handleTriangle: 'handleTriangle';
   readonly handleTriangleBottom: 'handleTriangleBottom';
   readonly handleTriangleTop: 'handleTriangleTop';
diff --git a/libs/shared/lib/schema/pills/nodes/schema-pills.module.scss b/libs/shared/lib/schema/pills/nodes/schema-pills.module.scss
index 9ff43aef7..e69de29bb 100644
--- a/libs/shared/lib/schema/pills/nodes/schema-pills.module.scss
+++ b/libs/shared/lib/schema/pills/nodes/schema-pills.module.scss
@@ -1,29 +0,0 @@
-.nodeSpan {
-  margin: 0 0.5em 0 1em;
-  float: right;
-}
-
-.entityNodeNodesBox {
-  height: 20;
-  position: absolute;
-  left: 115px;
-  top: 54%;
-  transform: translateX(50%);
-  border-radius: 1px;
-  text-align: right;
-}
-
-.nodeWrapper {
-  display: inherit;
-  color: black;
-  @apply p-2;
-  @apply py-1;
-  // text-align: center;
-  // justify-content: space-between;
-  // align-items: center;
-  width: inherit;
-}
-
-.nodeData {
-  flex-grow: 2;
-}
diff --git a/libs/shared/lib/schema/pills/nodes/schema-pills.module.scss.d.ts b/libs/shared/lib/schema/pills/nodes/schema-pills.module.scss.d.ts
index 6414ae1bd..5fc8829cc 100644
--- a/libs/shared/lib/schema/pills/nodes/schema-pills.module.scss.d.ts
+++ b/libs/shared/lib/schema/pills/nodes/schema-pills.module.scss.d.ts
@@ -1,7 +1,2 @@
-declare const classNames: {
-  readonly nodeSpan: 'nodeSpan';
-  readonly entityNodeNodesBox: 'entityNodeNodesBox';
-  readonly nodeWrapper: 'nodeWrapper';
-  readonly nodeData: 'nodeData';
-};
+declare const classNames: {};
 export = classNames;
diff --git a/libs/shared/lib/schema/schema-utils/schema-usecases.ts b/libs/shared/lib/schema/schema-utils/schema-usecases.ts
index 780870b8b..3d5ae3482 100644
--- a/libs/shared/lib/schema/schema-utils/schema-usecases.ts
+++ b/libs/shared/lib/schema/schema-utils/schema-usecases.ts
@@ -50,7 +50,10 @@ export function schemaExpandRelation(graph: Graph): Graph {
 }
 
 // Takes the schema as an input and creates basic react flow elements for them.
-export function schemaGraphology2Reactflow(graph: Graph): {
+export function schemaGraphology2Reactflow(
+  graph: Graph,
+  defaultEdgeType: string
+): {
   nodes: Array<Node<SchemaReactflowNodeWithFunctions | SchemaReactflowRelationWithFunctions>>;
   edges: Array<Edge>;
 } {
@@ -60,7 +63,7 @@ export function schemaGraphology2Reactflow(graph: Graph): {
   };
 
   initialElements.nodes = createReactFlowNodes(graph);
-  initialElements.edges = createReactFlowEdges(graph);
+  initialElements.edges = createReactFlowEdges(graph, defaultEdgeType);
   // initialElements.push(...createReactFlowRelationNodes(graph));
   // initialElements.push(...createReactFlowRelationEdges(graph));
   // console.log(initialElements);
@@ -85,7 +88,7 @@ export function createReactFlowNodes(graph: Graph): Array<Node> {
   return nodeElements;
 }
 
-export function createReactFlowEdges(graph: Graph): Array<Edge> {
+export function createReactFlowEdges(graph: Graph, defaultEdgeType: string): Array<Edge> {
   const edgeElements: Array<Edge> = [];
 
   graph.forEachEdge((edge, attributes, source, target): void => {
@@ -98,7 +101,7 @@ export function createReactFlowEdges(graph: Graph): Array<Edge> {
         ...attributes,
       },
       // label: edge,
-      type: attributes?.type || 'smoothstep',
+      type: attributes?.type || defaultEdgeType,
       animated: ANIMATEDEDGES,
       markerEnd: MarkerType.ArrowClosed, // TODO: Check
     };
diff --git a/libs/shared/package.json b/libs/shared/package.json
index e64788f39..66a91ab1e 100644
--- a/libs/shared/package.json
+++ b/libs/shared/package.json
@@ -26,6 +26,7 @@
     "@nebula.gl/layers": "^1.0.4",
     "@reactflow/node-resizer": "^2.0.1",
     "@reduxjs/toolkit": "^1.9.2",
+    "@tisoap/react-flow-smart-edge": "^3.0.0",
     "@types/cytoscape": "^3.19.9",
     "@types/react-grid-layout": "^1.3.2",
     "@types/styled-components": "^5.1.26",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 358bed31f..61424fc30 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -241,6 +241,9 @@ importers:
       '@reduxjs/toolkit':
         specifier: ^1.9.2
         version: 1.9.3(react-redux@8.0.5)(react@18.2.0)
+      '@tisoap/react-flow-smart-edge':
+        specifier: ^3.0.0
+        version: 3.0.0(react-dom@18.2.0)(react@18.2.0)(reactflow@11.7.0)(typescript@4.9.5)
       '@types/cytoscape':
         specifier: ^3.19.9
         version: 3.19.9
@@ -451,7 +454,7 @@ importers:
         version: 8.7.0(eslint@7.32.0)
       eslint-config-turbo:
         specifier: latest
-        version: 1.10.12(eslint@7.32.0)
+        version: 1.10.13(eslint@7.32.0)
       eslint-plugin-import:
         specifier: 2.27.5
         version: 2.27.5(@typescript-eslint/parser@5.52.0)(eslint-import-resolver-typescript@2.7.1)(eslint@7.32.0)
@@ -7954,6 +7957,22 @@ packages:
       tippy.js: 6.3.7
     dev: false
 
+  /@tisoap/react-flow-smart-edge@3.0.0(react-dom@18.2.0)(react@18.2.0)(reactflow@11.7.0)(typescript@4.9.5):
+    resolution: {integrity: sha512-XtEQT0IrOqPwJvCzgEoj3Y16/EK4SOcjZO7FmOPU+qJWmgYjeTyv7J35CGm6dFeJYdZ2gHDrvQ1zwaXuo23/8g==}
+    engines: {node: '>=16', npm: ^8.0.0}
+    peerDependencies:
+      react: '>=17'
+      react-dom: '>=17'
+      reactflow: '>=11'
+      typescript: '>=4.6'
+    dependencies:
+      pathfinding: 0.4.18
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
+      reactflow: 11.7.0(immer@10.0.2)(react-dom@18.2.0)(react@18.2.0)
+      typescript: 4.9.5
+    dev: false
+
   /@tootallnate/once@2.0.0:
     resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==}
     engines: {node: '>= 10'}
@@ -12229,6 +12248,16 @@ packages:
     dependencies:
       eslint: 7.32.0
       eslint-plugin-turbo: 1.10.12(eslint@7.32.0)
+    dev: false
+
+  /eslint-config-turbo@1.10.13(eslint@7.32.0):
+    resolution: {integrity: sha512-Ffa0SxkRCPMtfUX/HDanEqsWoLwZTQTAXO9W4IsOtycb2MzJDrVcLmoFW5sMwCrg7gjqbrC4ZJoD+1SPPzIVqg==}
+    peerDependencies:
+      eslint: '>6.6.0'
+    dependencies:
+      eslint: 7.32.0
+      eslint-plugin-turbo: 1.10.13(eslint@7.32.0)
+    dev: true
 
   /eslint-import-resolver-node@0.3.7:
     resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==}
@@ -12378,6 +12407,16 @@ packages:
     dependencies:
       dotenv: 16.0.3
       eslint: 7.32.0
+    dev: false
+
+  /eslint-plugin-turbo@1.10.13(eslint@7.32.0):
+    resolution: {integrity: sha512-el4AAmn0zXmvHEyp1h0IQMfse10Vy8g5Vbg4IU3+vD9CSj5sDbX07iFVt8sCKg7og9Q5FAa9mXzlCf7t4vYgzg==}
+    peerDependencies:
+      eslint: '>6.6.0'
+    dependencies:
+      dotenv: 16.0.3
+      eslint: 7.32.0
+    dev: true
 
   /eslint-scope@5.1.1:
     resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
@@ -13577,6 +13616,10 @@ packages:
     resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
     hasBin: true
 
+  /heap@0.2.5:
+    resolution: {integrity: sha512-G7HLD+WKcrOyJP5VQwYZNC3Z6FcQ7YYjEFiFoIj8PfEr73mu421o8B1N5DKUcc8K37EsJ2XXWA8DtrDz/2dReg==}
+    dev: false
+
   /heap@0.2.7:
     resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==}
 
@@ -16089,6 +16132,12 @@ packages:
     resolution: {integrity: sha512-ODbEPR0KKHqECXW1GoxdDb+AZvULmXjVPy4rt+pGo2+TnjJTIPJQSVS6N63n8T2Ip+syHhbn52OewKicV0373w==}
     dev: true
 
+  /pathfinding@0.4.18:
+    resolution: {integrity: sha512-R0TGEQ9GRcFCDvAWlJAWC+KGJ9SLbW4c0nuZRcioVlXVTlw+F5RvXQ8SQgSqI9KXWC1ew95vgmIiyaWTlCe9Ag==}
+    dependencies:
+      heap: 0.2.5
+    dev: false
+
   /pathval@1.1.1:
     resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==}
     dev: true
@@ -16295,7 +16344,7 @@ packages:
     dependencies:
       lilconfig: 2.1.0
       postcss: 8.4.21
-      ts-node: 10.9.1(@types/node@17.0.12)(typescript@4.9.5)
+      ts-node: 10.9.1(@types/node@18.13.0)(typescript@4.9.5)
       yaml: 1.10.2
     dev: true
 
@@ -20329,8 +20378,8 @@ packages:
       tinybench: 2.4.0
       tinypool: 0.4.0
       tinyspy: 1.1.1
-      vite: 4.2.1(@types/node@17.0.12)(sass@1.59.3)
-      vite-node: 0.29.4(@types/node@17.0.12)(sass@1.64.2)
+      vite: 4.2.1(@types/node@17.0.12)(sass@1.64.2)
+      vite-node: 0.29.4(@types/node@17.0.12)(sass@1.59.3)
       why-is-node-running: 2.2.2
     transitivePeerDependencies:
       - less
-- 
GitLab