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

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

commit 6049277081ef75432d48af4535c5bf631f6e7161
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Wed Feb 14 12:05:37 2024 -0500

    Incoming navigation for #1109
---
 karavan-core/src/core/api/TopologyUtils.ts         |  2 +-
 .../src/core/model/IntegrationDefinition.ts        | 10 +++++++
 karavan-designer/src/App.tsx                       |  6 ++---
 karavan-designer/src/DesignerPage.tsx              |  2 ++
 karavan-designer/src/designer/DesignerStore.ts     | 17 +++++++++++-
 karavan-designer/src/designer/KaravanDesigner.tsx  |  8 +++---
 .../src/designer/route/DslConnections.tsx          | 31 +++++++++++++---------
 karavan-designer/src/topology/TopologyApi.tsx      |  2 +-
 karavan-designer/src/topology/TopologyStore.ts     | 23 ----------------
 karavan-designer/src/topology/TopologyTab.tsx      | 16 ++++++-----
 10 files changed, 64 insertions(+), 53 deletions(-)

diff --git a/karavan-core/src/core/api/TopologyUtils.ts 
b/karavan-core/src/core/api/TopologyUtils.ts
index 949fe507..38932df2 100644
--- a/karavan-core/src/core/api/TopologyUtils.ts
+++ b/karavan-core/src/core/api/TopologyUtils.ts
@@ -57,7 +57,7 @@ export class TopologyUtils {
         const uri = (element as any).uri;
         const component = ComponentApi.findByName(uri);
         return component !== undefined &&
-            (TopologyUtils.isComponentInternal(component.component.label));
+            (TopologyUtils.isComponentInternal(component.component.label) || 
TopologyUtils.hasInternalUri(element));
     }
 
     static getConnectorType = (element: CamelElement): 'component' | 'kamelet' 
=> {
diff --git a/karavan-core/src/core/model/IntegrationDefinition.ts 
b/karavan-core/src/core/model/IntegrationDefinition.ts
index 18d01dc8..f5cd70cd 100644
--- a/karavan-core/src/core/model/IntegrationDefinition.ts
+++ b/karavan-core/src/core/model/IntegrationDefinition.ts
@@ -17,6 +17,16 @@
 import { v4 as uuidv4 } from 'uuid';
 import { RegistryBeanDefinition } from './CamelDefinition';
 
+export class IntegrationFile {
+    name: string = '';
+    code: string = '';
+
+    constructor(name: string, code: string) {
+        this.name = name;
+        this.code = code;
+    }
+}
+
 export class DefinitionProperty {
     title: string = '';
     description: string = '';
diff --git a/karavan-designer/src/App.tsx b/karavan-designer/src/App.tsx
index 9217fa82..46894d94 100644
--- a/karavan-designer/src/App.tsx
+++ b/karavan-designer/src/App.tsx
@@ -42,8 +42,7 @@ import {Notification} from "./designer/utils/Notification";
 import {EventBus} from "./designer/utils/EventBus";
 import {TopologyTab} from "./topology/TopologyTab";
 import {useEffect, useState} from "react";
-import {IntegrationFile, useTopologyStore} from "./topology/TopologyStore";
-import {shallow} from "zustand/shallow";
+import {IntegrationFile} from "karavan-core/lib/model/IntegrationDefinition";
 
 class MenuItem {
     pageId: string = '';
@@ -59,7 +58,6 @@ class MenuItem {
 
 export function App() {
 
-    const [setFiles] = useTopologyStore((s) => [s.setFiles], shallow);
     const [pageId, setPageId] = useState<string>('designer');
     const [name, setName] = useState<string>('example.yaml');
     const [key, setKey] = useState<string>('');
@@ -95,7 +93,6 @@ export function App() {
             if (data[4]) {
                 setYaml(data[4]);
                 setName("demo.camel.yaml");
-                setFiles([new IntegrationFile("demo.camel.yaml", yaml)]);
             }
 
             if (data[5]) {
@@ -167,6 +164,7 @@ export function App() {
             case "topology":
                 return (
                     <TopologyTab
+                        files={[new IntegrationFile("demo.camel.yaml", yaml)]}
                         onSetFile={fileName => {}}
                         onClickAddRoute={() => {}}
                         onClickAddREST={() => {}}
diff --git a/karavan-designer/src/DesignerPage.tsx 
b/karavan-designer/src/DesignerPage.tsx
index 4a30e899..d3586927 100644
--- a/karavan-designer/src/DesignerPage.tsx
+++ b/karavan-designer/src/DesignerPage.tsx
@@ -26,6 +26,7 @@ import DownloadIcon from 
"@patternfly/react-icons/dist/esm/icons/download-icon";
 import DownloadImageIcon from 
"@patternfly/react-icons/dist/esm/icons/image-icon";
 import {KaravanDesigner} from "./designer/KaravanDesigner";
 import {EventBus} from "./designer/utils/EventBus";
+import {IntegrationFile} from "karavan-core/lib/model/IntegrationDefinition";
 
 interface Props {
     name: string,
@@ -80,6 +81,7 @@ export const DesignerPage = (props: Props) => {
                 onInternalConsumerClick={(uri, name, direction: 'from' | 'to') 
=> {
                     console.log("onInternalConsumerClick", uri, name, 
direction)
                 }}
+                files={[new IntegrationFile("demo.camel.yaml", yaml)]}
             />
         )
     }
diff --git a/karavan-designer/src/designer/DesignerStore.ts 
b/karavan-designer/src/designer/DesignerStore.ts
index ef95b8d4..7a6aab41 100644
--- a/karavan-designer/src/designer/DesignerStore.ts
+++ b/karavan-designer/src/designer/DesignerStore.ts
@@ -20,6 +20,7 @@ import {DslPosition, EventBus} from "./utils/EventBus";
 import {createWithEqualityFn} from "zustand/traditional";
 import {shallow} from "zustand/shallow";
 import {RegistryBeanDefinition} from "karavan-core/lib/model/CamelDefinition";
+import {IntegrationFile} from "karavan-core/lib/model/IntegrationDefinition";
 
 interface IntegrationState {
     integration: Integration;
@@ -27,6 +28,9 @@ interface IntegrationState {
     setIntegration: (integration: Integration, propertyOnly: boolean) => void;
     propertyOnly: boolean;
     reset: () => void;
+    files: IntegrationFile []
+    setFiles: (files: IntegrationFile []) => void
+    resetFiles: (files: IntegrationFile []) => void
 }
 
 export const useIntegrationStore = 
createWithEqualityFn<IntegrationState>((set) => ({
@@ -46,7 +50,18 @@ export const useIntegrationStore = 
createWithEqualityFn<IntegrationState>((set)
     },
     reset: () => {
         set({integration: Integration.createNew("demo", "plain"), json: '{}', 
propertyOnly: false});
-    }
+    },
+    files: [],
+    setFiles: (files: IntegrationFile []) => {
+        set((state: IntegrationState) => {
+            return {files: files};
+        });
+    },
+    resetFiles: (files: IntegrationFile []) => {
+        set((state: IntegrationState) => {
+            return {files: [...files]};
+        });
+    },
 }), shallow)
 
 
diff --git a/karavan-designer/src/designer/KaravanDesigner.tsx 
b/karavan-designer/src/designer/KaravanDesigner.tsx
index 75e6c012..58dbbf6d 100644
--- a/karavan-designer/src/designer/KaravanDesigner.tsx
+++ b/karavan-designer/src/designer/KaravanDesigner.tsx
@@ -28,7 +28,7 @@ import {
 import './karavan.css';
 import {RouteDesigner} from "./route/RouteDesigner";
 import {CamelDefinitionYaml} from "karavan-core/lib/api/CamelDefinitionYaml";
-import {Integration} from "karavan-core/lib/model/IntegrationDefinition";
+import {Integration, IntegrationFile} from 
"karavan-core/lib/model/IntegrationDefinition";
 import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
 import {CamelUi} from "./utils/CamelUi";
 import {useDesignerStore, useIntegrationStore} from "./DesignerStore";
@@ -57,6 +57,7 @@ interface Props {
     tab?: "routes" | "rest" | "beans"
     propertyPlaceholders: string[]
     beans: RegistryBeanDefinition[]
+    files: IntegrationFile[]
 }
 
 export function KaravanDesigner(props: Props) {
@@ -65,8 +66,8 @@ export function KaravanDesigner(props: Props) {
     const [setDark, hideLogDSL, setHideLogDSL, setSelectedStep, reset, badge, 
message, setPropertyPlaceholders, setBeans] =
         useDesignerStore((s) =>
         [s.setDark, s.hideLogDSL, s.setHideLogDSL, s.setSelectedStep, s.reset, 
s.notificationBadge, s.notificationMessage, s.setPropertyPlaceholders, 
s.setBeans], shallow)
-    const [integration, setIntegration] = useIntegrationStore((s) =>
-        [s.integration, s.setIntegration], shallow)
+    const [integration, setIntegration, resetFiles] = useIntegrationStore((s) 
=>
+        [s.integration, s.setIntegration, s.resetFiles], shallow)
 
     useEffect(() => {
         const sub = EventBus.onIntegrationUpdate()?.subscribe((update: 
IntegrationUpdate) =>
@@ -92,6 +93,7 @@ export function KaravanDesigner(props: Props) {
         setDark(props.dark);
         setPropertyPlaceholders(props.propertyPlaceholders)
         setBeans(props.beans)
+        resetFiles(props.files)
         setHideLogDSL(props.hideLogDSL === true);
         return () => {
             sub?.unsubscribe();
diff --git a/karavan-designer/src/designer/route/DslConnections.tsx 
b/karavan-designer/src/designer/route/DslConnections.tsx
index cab339f8..072aaac9 100644
--- a/karavan-designer/src/designer/route/DslConnections.tsx
+++ b/karavan-designer/src/designer/route/DslConnections.tsx
@@ -26,15 +26,14 @@ import {CamelElement} from 
"karavan-core/lib/model/IntegrationDefinition";
 import {v4 as uuidv4} from "uuid";
 import {Button, Tooltip} from "@patternfly/react-core";
 import {InfrastructureAPI} from "../utils/InfrastructureAPI";
-import {useTopologyStore} from "../../topology/TopologyStore";
 import {getIntegrations} from "../../topology/TopologyApi";
+import {ComponentApi} from "karavan-core/lib/api/ComponentApi";
 
 const overlapGap: number = 40;
 
 export function DslConnections() {
 
-    const [integration] = useIntegrationStore((state) => [state.integration], 
shallow)
-    const [files] = useTopologyStore((s) => [s.files], shallow);
+    const [integration, files] = useIntegrationStore((s) => [s.integration, 
s.files], shallow)
     const [width, height, top, left, hideLogDSL] = useDesignerStore((s) =>
         [s.width, s.height, s.top, s.left, s.hideLogDSL], shallow)
     const [steps, addStep, deleteStep, clearSteps] =
@@ -81,10 +80,16 @@ export function DslConnections() {
         }
     }
 
+    function isElementInternalComponent (element: CamelElement): boolean {
+        const uri = (element as any).uri;
+        const component = ComponentApi.findByName(uri);
+        return component !== undefined && 
(TopologyUtils.isComponentInternal(component.component.label));
+    }
+
     function getIncomings() {
         let outs: [string, number][] = Array.from(steps.values())
             .filter(pos => ["FromDefinition"].includes(pos.step.dslName))
-            .filter(pos => !TopologyUtils.isElementInternalComponent(pos.step))
+            .filter(pos => !isElementInternalComponent(pos.step))
             // .filter(pos => !(pos.step.dslName === 'FromDefinition' && 
TopologyUtils.hasInternalUri(pos.step)))
             .filter(pos => !(pos.step.dslName === 'FromDefinition' && 
(pos.step as any).uri === 'kamelet:source'))
             .sort((pos1: DslPosition, pos2: DslPosition) => {
@@ -122,12 +127,12 @@ export function DslConnections() {
         }
     }
 
-    function getToDirectSteps(name: string) {
-        return Array.from(steps.values())
-            .filter(s => s.step.dslName === 'ToDefinition')
-            .filter(s =>  ['direct','seda'].includes((s.step as any)?.uri))
-            .filter(s =>  (s.step as any)?.parameters?.name === name)
-    }
+    // function getToDirectSteps(name: string) {
+    //     return Array.from(steps.values())
+    //         .filter(s => s.step.dslName === 'ToDefinition')
+    //         .filter(s =>  ['direct','seda'].includes((s.step as any)?.uri))
+    //         .filter(s =>  (s.step as any)?.parameters?.name === name)
+    // }
 
     function getIncomingIcons(data: [string, number]) {
         const pos = steps.get(data[0]);
@@ -137,7 +142,7 @@ export function DslConnections() {
             const directOrSeda: boolean = step && uri && step?.dslName === 
'FromDefinition' && ['direct','seda'].includes(uri);
             const name: string = directOrSeda ? (step?.parameters?.name) : 
undefined;
             const routes = directOrSeda ? tons.get(uri + ':' +name) || [] : [];
-            const localDirects = getToDirectSteps(name);
+            // const localDirects = getToDirectSteps(name);
             const fromY = pos.headerRect.y + pos.headerRect.height / 2 - top;
             const r = pos.headerRect.height / 2;
             const incomingX = 20;
@@ -152,7 +157,7 @@ export function DslConnections() {
                             <Button style={{position: 'absolute', left: 27, 
top: (index * 16) + (12), whiteSpace: 'nowrap', zIndex: 300, padding: 0}}
                                     variant={'link'}
                                     aria-label="Goto"
-                                    onClick={_ => 
InfrastructureAPI.onInternalConsumerClick(uri, name, 'from')}>
+                                    onClick={_ => 
InfrastructureAPI.onInternalConsumerClick(uri, name, 'to')}>
                                 {routeId}
                             </Button>
                         </Tooltip>
@@ -250,7 +255,7 @@ export function DslConnections() {
                             <Button style={{position: 'absolute', right: 27, 
top: -12, whiteSpace: 'nowrap', zIndex: 300, padding: 0}}
                                    variant={'link'}
                                     aria-label="Goto"
-                                    onClick={_ => 
InfrastructureAPI.onInternalConsumerClick(uri, name, 'to')}>
+                                    onClick={_ => 
InfrastructureAPI.onInternalConsumerClick(uri, name, 'from')}>
                                 {name}
                             </Button>
                         </Tooltip>
diff --git a/karavan-designer/src/topology/TopologyApi.tsx 
b/karavan-designer/src/topology/TopologyApi.tsx
index c60c197b..a640d508 100644
--- a/karavan-designer/src/topology/TopologyApi.tsx
+++ b/karavan-designer/src/topology/TopologyApi.tsx
@@ -39,7 +39,7 @@ import {
     TopologyRouteNode
 } from "karavan-core/lib/model/TopologyDefinition";
 import CustomEdge from "./CustomEdge";
-import {IntegrationFile} from "./TopologyStore";
+import {IntegrationFile} from "karavan-core/lib/model/IntegrationDefinition";
 import CustomGroup from "./CustomGroup";
 
 const NODE_DIAMETER = 60;
diff --git a/karavan-designer/src/topology/TopologyStore.ts 
b/karavan-designer/src/topology/TopologyStore.ts
index c6322f39..517e2794 100644
--- a/karavan-designer/src/topology/TopologyStore.ts
+++ b/karavan-designer/src/topology/TopologyStore.ts
@@ -18,20 +18,8 @@
 import {createWithEqualityFn} from "zustand/traditional";
 import {shallow} from "zustand/shallow";
 
-export class IntegrationFile {
-    name: string = '';
-    code: string = '';
-
-    constructor(name: string, code: string) {
-        this.name = name;
-        this.code = code;
-    }
-}
 
 interface TopologyState {
-    files: IntegrationFile []
-    setFiles: (files: IntegrationFile []) => void
-    resetFiles: (files: IntegrationFile []) => void
     selectedIds: string []
     fileName?: string
     setSelectedIds: (selectedIds: string []) => void
@@ -43,17 +31,6 @@ interface TopologyState {
 }
 
 export const useTopologyStore = createWithEqualityFn<TopologyState>((set) => ({
-    files: [],
-    setFiles: (files: IntegrationFile []) => {
-        set((state: TopologyState) => {
-            return {files: files};
-        });
-    },
-    resetFiles: (files: IntegrationFile []) => {
-        set((state: TopologyState) => {
-            return {files: [...files]};
-        });
-    },
     selectedIds: [],
     setSelectedIds: (selectedIds: string[]) => {
         set((state: TopologyState) => {
diff --git a/karavan-designer/src/topology/TopologyTab.tsx 
b/karavan-designer/src/topology/TopologyTab.tsx
index bf16124a..694eeb64 100644
--- a/karavan-designer/src/topology/TopologyTab.tsx
+++ b/karavan-designer/src/topology/TopologyTab.tsx
@@ -31,12 +31,14 @@ import {
 } from '@patternfly/react-topology';
 import {customComponentFactory, getModel} from "./TopologyApi";
 import {shallow} from "zustand/shallow";
-import {IntegrationFile, useTopologyStore} from "./TopologyStore";
+import {useTopologyStore} from "./TopologyStore";
 import {TopologyPropertiesPanel} from "./TopologyPropertiesPanel";
 import {TopologyToolbar} from "./TopologyToolbar";
 import {useDesignerStore} from "../designer/DesignerStore";
+import {IntegrationFile} from "karavan-core/lib/model/IntegrationDefinition";
 
 interface Props {
+    files: IntegrationFile[],
     onSetFile: (fileName: string) => void
     hideToolbar: boolean
     onClickAddRoute: () => void
@@ -46,8 +48,8 @@ interface Props {
 
 export function TopologyTab(props: Props) {
 
-    const [selectedIds, setSelectedIds, setFileName, ranker, setRanker, 
setNodeData, files] = useTopologyStore((s) =>
-        [s.selectedIds, s.setSelectedIds, s.setFileName, s.ranker, 
s.setRanker, s.setNodeData, s.files], shallow);
+    const [selectedIds, setSelectedIds, setFileName, ranker, setRanker, 
setNodeData] = useTopologyStore((s) =>
+        [s.selectedIds, s.setSelectedIds, s.setFileName, s.ranker, 
s.setRanker, s.setNodeData], shallow);
     const [setSelectedStep] = useDesignerStore((s) => [s.setSelectedStep], 
shallow)
 
     function setTopologySelected(model: Model, ids: string []) {
@@ -69,7 +71,7 @@ export function TopologyTab(props: Props) {
     }
 
     const controller = React.useMemo(() => {
-        const model = getModel(files);
+        const model = getModel(props.files);
         const newController = new Visualization();
         newController.registerLayoutFactory((_, graph) =>
             new DagreLayout(graph, {
@@ -96,9 +98,9 @@ export function TopologyTab(props: Props) {
 
     React.useEffect(() => {
         setSelectedIds([])
-        const model = getModel(files);
+        const model = getModel(props.files);
         controller.fromModel(model, false);
-    }, [ranker, controller, setSelectedIds, files]);
+    }, [ranker, controller, setSelectedIds, props.files]);
 
     const controlButtons = React.useMemo(() => {
         // const customButtons = [
@@ -136,7 +138,7 @@ export function TopologyTab(props: Props) {
         });
     }, [ranker, controller, setRanker]);
 
-        return (
+    return (
         <TopologyView
             className="topology-panel"
             contextToolbar={!props.hideToolbar

Reply via email to