You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ma...@apache.org on 2023/08/22 23:50:32 UTC

[camel-karavan] 01/03: Connections for #836

This is an automated email from the ASF dual-hosted git repository.

marat pushed a commit to branch feature-836
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git

commit 27f94cc80b6d4b06ed8b91c5802d3980f31f43bb
Author: Marat Gubaidullin <ma...@Marats-MacBook-Pro.local>
AuthorDate: Tue Aug 22 17:43:37 2023 -0400

    Connections for #836
---
 karavan-designer/src/designer/KaravanStore.ts      | 39 +++++++++++++++++
 .../src/designer/route/DslConnections.tsx          | 51 +++++++---------------
 karavan-designer/src/designer/route/DslElement.tsx | 51 +++++-----------------
 .../src/designer/route/RouteDesigner.tsx           | 26 ++++-------
 4 files changed, 75 insertions(+), 92 deletions(-)

diff --git a/karavan-designer/src/designer/KaravanStore.ts b/karavan-designer/src/designer/KaravanStore.ts
index a28f7f21..440c944b 100644
--- a/karavan-designer/src/designer/KaravanStore.ts
+++ b/karavan-designer/src/designer/KaravanStore.ts
@@ -19,6 +19,8 @@ import {create} from 'zustand'
 import {CamelElement, Integration} from "karavan-core/lib/model/IntegrationDefinition";
 import {createWithEqualityFn} from "zustand/traditional";
 import {shallow} from "zustand/shallow";
+import {useState} from "react";
+import {DslPosition} from "./utils/EventBus";
 
 interface IntegrationState {
     integration: Integration;
@@ -32,6 +34,43 @@ export const useIntegrationStore = createWithEqualityFn<IntegrationState>((set)
     },
 }), shallow)
 
+
+interface ConnectionsState {
+    steps: Map<string, DslPosition>;
+    addStep: (uuid: string, position: DslPosition) => void;
+    deleteStep: (uuid: string) => void;
+    clear: () => void;
+    setSteps: (steps: Map<string, DslPosition>) => void;
+}
+
+export const useConnectionsStore = createWithEqualityFn<ConnectionsState>((set) => ({
+    steps: new Map<string, DslPosition>(),
+    addStep: (uuid: string, position: DslPosition) => {
+        set(state => ({
+            steps: new Map(state.steps).set(uuid, position),
+        }))
+    },
+    deleteStep: (uuid: string) => {
+        set((state: ConnectionsState) => {
+            state.steps.clear();
+            Array.from(state.steps.entries())
+                .filter(value => value[1]?.parent?.uuid !== uuid)
+                .forEach(value => state.steps.set(value[0], value[1]));
+            state.steps.delete(uuid)
+            return state;
+        })
+    },
+    clear: () => {
+        set((state: ConnectionsState) => {
+            state.steps.clear();
+            return state;
+        })
+    },
+    setSteps: (steps: Map<string, DslPosition>) => {
+        set({steps: steps})
+    },
+}), shallow)
+
 interface DesignerState {
     shiftKeyPressed: boolean;
     showSelector: boolean;
diff --git a/karavan-designer/src/designer/route/DslConnections.tsx b/karavan-designer/src/designer/route/DslConnections.tsx
index 3b508ae3..18d37819 100644
--- a/karavan-designer/src/designer/route/DslConnections.tsx
+++ b/karavan-designer/src/designer/route/DslConnections.tsx
@@ -14,14 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import React, {useEffect, useState} from 'react';
+import React, {useEffect} from 'react';
 import '../karavan.css';
 import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition";
 import {DslPosition, EventBus} from "../utils/EventBus";
 import {CamelUi} from "../utils/CamelUi";
-import {Subscription} from "rxjs";
 import {SagaDefinition} from "karavan-core/lib/model/CamelDefinition";
-import {useDesignerStore} from "../KaravanStore";
+import {useConnectionsStore, useDesignerStore} from "../KaravanStore";
 
 
 const overlapGap: number = 40;
@@ -31,40 +30,25 @@ export const DslConnections = () => {
 
     const [ width, height, top, left] = useDesignerStore((s) =>
         [s.width, s.height, s.top, s.left])
-    const [steps, setSteps] = useState<Map<string, DslPosition>>(new Map<string, DslPosition>());
+    const [ steps, addStep, deleteStep, clear] = useConnectionsStore((s) => [s.steps, s.addStep, s.deleteStep, s.clear])
 
-    // useEffect(() => {
-    //     console.log("DslConnections Start", width, height, top, left);
-    //     const sub = EventBus.onPosition()?.subscribe((evt: DslPosition) => setPosition(evt));
-    //     return () => {
-    //         console.log("DslConnections Stop");
-    //         sub?.unsubscribe();
-    //     };
-    // }, [width, height, top, left]);
+    useEffect(() => {
+        const sub = EventBus.onPosition()?.subscribe((evt: DslPosition) => setPosition(evt));
+        return () => {
+            sub?.unsubscribe();
+        };
+    }, [width, height, top, left]);
 
     function setPosition(evt: DslPosition) {
         console.log("setPosition", evt);
         if (evt.command === "add") {
-            setSteps(prevSteps => {
-                prevSteps.set(evt.step.uuid, evt);
-                return prevSteps;
-            })
+            addStep(evt.step.uuid, evt);
         }
         else if (evt.command === "delete") {
-            setSteps(prevSteps => {
-                prevSteps.clear();
-                Array.from(prevSteps.entries())
-                    .filter(value => value[1]?.parent?.uuid !== evt.step.uuid)
-                    .forEach(value => prevSteps.set(value[0], value[1]));
-                prevSteps.delete(evt.step.uuid);
-                return prevSteps;
-            })
+            deleteStep(evt.step.uuid);
         }
         else if (evt.command === "clean") {
-            setSteps(prevSteps => {
-                prevSteps.clear();
-                return prevSteps;
-            })
+            clear();
         }
     }
 
@@ -444,7 +428,7 @@ export const DslConnections = () => {
         return (
             <svg
                 style={{width: width, height: height, position: "absolute", left: 0, top: 0}}
-                viewBox={"0 0 " + (width - 5) + " " + (height -5)}>
+                viewBox={"0 0 " + (width) + " " + (height)}>
                 <defs>
                     <marker id="arrowhead" markerWidth="9" markerHeight="6" refX="0" refY="3" orient="auto" className="arrow">
                         <polygon points="0 0, 9 3, 0 6"/>
@@ -461,13 +445,10 @@ export const DslConnections = () => {
 
     console.log("RENDER CONNECTION")
     return (
-        <div
-            id="connections"
-            style={{position: "absolute", width: width, height: height + 80, top: 0, left: 0, background: "red"}}
-        >
+        <div id="connections" className="connections" style={{ width: width, height: height + 80}}>
             {getSvg()}
-            {/*{getIncomings().map(p => getIncomingIcons(p))}*/}
-            {/*{getOutgoings().map(p => getOutgoingIcons(p))}*/}
+            {getIncomings().map(p => getIncomingIcons(p))}
+            {getOutgoings().map(p => getOutgoingIcons(p))}
         </div>
     )
 }
diff --git a/karavan-designer/src/designer/route/DslElement.tsx b/karavan-designer/src/designer/route/DslElement.tsx
index 212be87c..2e42ed03 100644
--- a/karavan-designer/src/designer/route/DslElement.tsx
+++ b/karavan-designer/src/designer/route/DslElement.tsx
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import React, {createRef, CSSProperties, useEffect, useRef, useState} from 'react';
+import React, {CSSProperties, useEffect, useRef, useState} from 'react';
 import {
     Button,
     Flex,
@@ -25,11 +25,10 @@ import '../karavan.css';
 import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-circle-icon";
 import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-circle-icon";
 import InsertIcon from "@patternfly/react-icons/dist/js/icons/arrow-alt-circle-right-icon";
-import {CamelElement, Integration} from "karavan-core/lib/model/IntegrationDefinition";
+import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition";
 import {CamelUi} from "../utils/CamelUi";
-import {DslPosition, EventBus} from "../utils/EventBus";
+import {EventBus} from "../utils/EventBus";
 import {ChildElement, CamelDefinitionApiExt} from "karavan-core/lib/api/CamelDefinitionApiExt";
-import ReactDOM from "react-dom";
 import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
 import {CamelDisplayUtil} from "karavan-core/lib/api/CamelDisplayUtil";
 import {useDesignerStore, useIntegrationStore} from "../KaravanStore";
@@ -37,14 +36,8 @@ import {shallow} from "zustand/shallow";
 import {useRouteDesignerHook} from "./useRouteDesignerHook";
 
 interface Props {
-    // integration: Integration,
     step: CamelElement,
     parent: CamelElement | undefined,
-    // deleteElement: any
-    // selectElement: any
-    // openSelector: (parentId: string | undefined, parentDsl: string | undefined, showSteps: boolean, position?: number | undefined) => void
-    // moveElement: (source: string, target: string, asChild: boolean) => void
-    // selectedUuid: string []
     inSteps: boolean
     position: number
 }
@@ -67,30 +60,10 @@ export const DslElement = (props: Props) => {
     const [isDraggedOver, setIsDraggedOver] = useState<boolean>(false);
     const [moveElements, setMoveElements] = useState<[string | undefined, string | undefined]>([undefined, undefined]);
 
-    const elementRef = useRef(null);
-    const [elementPosition, setElementPosition] = useState({ x: 0, y: 0 });
-
-    useEffect(() => {
-        // function handleResize() {
-        //     if (elementRef && elementRef.current !== undefined) {
-        //         const current: any = (elementRef.current as any);
-        //         const x = current.offsetLeft;
-        //         const y = current.offsetTop;
-        //         setElementPosition({x, y});
-        //         // console.log("setElementPosition", {x, y})
-        //     }
-        // }
-        //
-        // handleResize(); // initial call to get position of the element on mount
-        // window.addEventListener("resize", handleResize);
-        // return () => window.removeEventListener("resize", handleResize);
-    }, [elementRef]);
-    //
-    // componentDidUpdate = (prevProps: Readonly<Props>, prevState: Readonly<State>, snapshot?: any) => {
-    //     if (prevselectedUuid !== props.selectedUuid) {
-    //         setState({selectedUuid: props.selectedUuid});
-    //     }
-    // }
+    // const elementRef = useRef(null);
+
+    // useEffect(() => {
+    // }, [elementRef]);
 
     function onOpenSelector (evt: React.MouseEvent, showSteps: boolean = true, isInsert: boolean = false) {
         evt.stopPropagation();
@@ -231,7 +204,7 @@ export const DslElement = (props: Props) => {
     }
 
     function sendPosition (el: HTMLDivElement | null, isSelected: boolean) {
-        console.log("sendPosition", props.step)
+        // console.log("sendPosition", props.step)
         const node = el;
         if (node && el) {
             const header = Array.from(node.childNodes.values()).filter((n: any) => n.classList.contains("header"))[0];
@@ -239,7 +212,8 @@ export const DslElement = (props: Props) => {
                 const headerIcon: any = Array.from(header.childNodes.values()).filter((n: any) => n.classList.contains("header-icon"))[0];
                 const headerRect = headerIcon.getBoundingClientRect();
                 const rect = el.getBoundingClientRect();
-                if (props.step.show){
+                // if ()
+                if (props.step.show) {
                     EventBus.sendPosition("add", props.step, props.parent, rect, headerRect, props.position, props.inSteps, isSelected);
                 } else {
                     EventBus.sendPosition("delete", props.step, props.parent, new DOMRect(), new DOMRect(), 0);
@@ -453,12 +427,11 @@ export const DslElement = (props: Props) => {
     }
 
     const element: CamelElement = props.step;
-    const className = "step-element" + (isSelected() ? " step-element-selected" : "")
-        + (!props.step.show ? " hidden-step" : "");
+    const className = "step-element" + (isSelected() ? " step-element-selected" : "") + (!props.step.show ? " hidden-step" : "");
     return (
         <div key={"root" + element.uuid}
              className={className}
-             ref={elementRef}
+             ref={el => sendPosition(el, isSelected())}
              // ref={el => sendPosition(el, isSelected())}
              style={{
                  borderStyle: hasBorder() ? "dotted" : "none",
diff --git a/karavan-designer/src/designer/route/RouteDesigner.tsx b/karavan-designer/src/designer/route/RouteDesigner.tsx
index 69be9a48..17bc9b28 100644
--- a/karavan-designer/src/designer/route/RouteDesigner.tsx
+++ b/karavan-designer/src/designer/route/RouteDesigner.tsx
@@ -50,7 +50,7 @@ interface Props {
 
 export const RouteDesigner = (props: Props) => {
 
-    const printerRef = React.createRef()
+    const printerRef = React.createRef();
     const contentRef: React.RefObject<HTMLDivElement> = useRef(null);
 
     const {
@@ -63,13 +63,11 @@ export const RouteDesigner = (props: Props) => {
         createRouteConfiguration
     } = useRouteDesignerHook();
 
-    const [integration, setIntegration] = useIntegrationStore((state) => [state.integration, state.setIntegration], shallow)
-    const [showSelector, showDeleteConfirmation, propertyOnly, showSteps, deleteMessage, parentId, selectedUuids, clipboardSteps, parentDsl, selectedPosition, selectedStep, selectorTabIndex,
-        setShowSelector, setShowDeleteConfirmation, setPropertyOnly, setShowSteps, setDeleteMessage, setParentId, setSelectedUuids, setClipboardSteps, setPosition,
-        width, height, top, left] = useDesignerStore((s) =>
-        [s.showSelector, s.showDeleteConfirmation, s.propertyOnly, s.showSteps, s.deleteMessage, s.parentId, s.selectedUuids, s.clipboardSteps, s.parentDsl, s.selectedPosition, s.selectedStep, s.selectorTabIndex,
-            s.setShowSelector, s.setShowDeleteConfirmation, s.setPropertyOnly, s.setShowSteps, s.setDeleteMessage, s.setParentId, s.setSelectedUuids, s.setClipboardSteps, s.setPosition,
-            s.width, s.height, s.top, s.left], shallow)
+    const [integration] = useIntegrationStore((state) => [state.integration], shallow)
+    const [showSelector, showDeleteConfirmation, showSteps, deleteMessage, parentId, parentDsl, selectedPosition, selectorTabIndex,
+        setShowSelector, setShowDeleteConfirmation, setPosition, width, height, top, left] = useDesignerStore((s) =>
+        [s.showSelector, s.showDeleteConfirmation, s.showSteps, s.deleteMessage, s.parentId, s.parentDsl, s.selectedPosition, s.selectorTabIndex,
+            s.setShowSelector, s.setShowDeleteConfirmation, s.setPosition, s.width, s.height, s.top, s.left], shallow)
 
     // const [refState, setRefState] = useState<Element | null>(null);
 
@@ -176,15 +174,7 @@ export const RouteDesigner = (props: Props) => {
         )
     }
 
-    function onRef(el: HTMLDivElement | null) {
-        // console.log("onRef", el)
-        const rect = el?.getBoundingClientRect();
-        if (el && rect && (rect.width !== width || rect.height !== height || rect.top !== top || rect.left !== left)) {
-            setPosition(rect.width, rect.height, rect.top, rect.left)
-        }
-    }
-
-    console.log("RENDER ROUTE_DESIGNER")
+    console.log("RENDER ROUTE_DESIGNER");
 
     function getGraph() {
         const routes = CamelUi.getRoutes(integration);
@@ -247,5 +237,5 @@ export const RouteDesigner = (props: Props) => {
             {getSelectorModal()}
             {getDeleteConfirmation()}
         </div>
-    );
+    )
 }
\ No newline at end of file