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 c82c7b4423b5705ce4181923d37eafbc3aef66d6
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Tue Feb 6 19:13:30 2024 -0500

    Fix #1109
---
 karavan-designer/src/DesignerPage.tsx              |   3 +
 karavan-designer/src/designer/KaravanDesigner.tsx  |   2 +
 .../src/designer/route/DslConnections.tsx          |  14 ++-
 .../src/designer/utils/InfrastructureAPI.ts        |   5 +
 karavan-space/src/space/SpacePage.tsx              |   3 +
 karavan-vscode/webview/App.tsx                     |   3 +
 .../webview/topology/TopologyPropertiesPanel.tsx   | 103 ++++++++++++++++-----
 karavan-vscode/webview/topology/TopologyStore.ts   |   8 ++
 karavan-vscode/webview/topology/TopologyTab.tsx    |   5 +-
 karavan-vscode/webview/topology/topology.css       |  16 +++-
 .../main/webui/src/designer/KaravanDesigner.tsx    |   2 +
 .../webui/src/designer/route/DslConnections.tsx    |  14 ++-
 .../webui/src/designer/utils/InfrastructureAPI.ts  |   5 +
 .../src/main/webui/src/project/FileEditor.tsx      |   3 +
 14 files changed, 157 insertions(+), 29 deletions(-)

diff --git a/karavan-designer/src/DesignerPage.tsx 
b/karavan-designer/src/DesignerPage.tsx
index c8b3cb35..56bde9e3 100644
--- a/karavan-designer/src/DesignerPage.tsx
+++ b/karavan-designer/src/DesignerPage.tsx
@@ -82,6 +82,9 @@ export const DesignerPage = (props: Props) => {
                 ]}
                 onSavePropertyPlaceholder={(key, value) => 
console.log("onSavePropertyPlaceholder", key, value)}
                 beans={[]}
+                onInternalConsumerClick={(uri, name) => {
+                    console.log("onInternalConsumerClick", uri, name)
+                }}
             />
         )
     }
diff --git a/karavan-designer/src/designer/KaravanDesigner.tsx 
b/karavan-designer/src/designer/KaravanDesigner.tsx
index 11bf8b6c..05831a38 100644
--- a/karavan-designer/src/designer/KaravanDesigner.tsx
+++ b/karavan-designer/src/designer/KaravanDesigner.tsx
@@ -48,6 +48,7 @@ interface Props {
     onSaveCustomCode: (name: string, code: string) => void
     onGetCustomCode: (name: string, javaType: string) => Promise<string | 
undefined>
     onSavePropertyPlaceholder: (key: string, value: string) => void
+    onInternalConsumerClick: (uri: string, name: string) => void
     filename: string
     yaml: string
     dark: boolean
@@ -74,6 +75,7 @@ export function KaravanDesigner(props: Props) {
         InfrastructureAPI.setOnGetCustomCode(props.onGetCustomCode);
         InfrastructureAPI.setOnSave(props.onSave);
         
InfrastructureAPI.setOnSavePropertyPlaceholder(props.onSavePropertyPlaceholder);
+        
InfrastructureAPI.setOnInternalConsumerClick(props.onInternalConsumerClick);
 
         setSelectedStep(undefined);
         const i = makeIntegration(props.yaml, props.filename);
diff --git a/karavan-designer/src/designer/route/DslConnections.tsx 
b/karavan-designer/src/designer/route/DslConnections.tsx
index 0cfb4d78..ebb89933 100644
--- a/karavan-designer/src/designer/route/DslConnections.tsx
+++ b/karavan-designer/src/designer/route/DslConnections.tsx
@@ -24,6 +24,9 @@ import {CamelDefinitionApiExt} from 
"karavan-core/lib/api/CamelDefinitionApiExt"
 import {TopologyUtils} from "karavan-core/lib/api/TopologyUtils";
 import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition";
 import {v4 as uuidv4} from "uuid";
+import {DeleteElementIcon} from "../utils/ElementIcons";
+import {Button} from "@patternfly/react-core";
+import {InfrastructureAPI} from "../utils/InfrastructureAPI";
 
 const overlapGap: number = 40;
 
@@ -191,7 +194,7 @@ export function DslConnections() {
             const step = (pos.step as any);
             const uri = step?.uri;
             const directOrSeda = step && uri && step?.dslName === 
'ToDefinition' && ['direct','seda'].includes(uri);
-            const label = directOrSeda ? (step?.parameters?.name) : '';
+            const name = directOrSeda ? (step?.parameters?.name) : '';
             const r = pos.headerRect.height / 2;
             const outgoingX = width - 20;
             const outgoingY = data[1] + 15;
@@ -201,7 +204,14 @@ export function DslConnections() {
                 <div key={pos.step.uuid + "-icon"}
                      style={{display: "block", position: "absolute", top: 
imageY, left: imageX}}>
                     {CamelUi.getConnectionIcon(pos.step)}
-                    {directOrSeda && <div style={{position: 'absolute', right: 
27, top: -10, whiteSpace: 'nowrap'}}>{label}</div>}
+                    {directOrSeda &&
+                        <Button style={{position: 'absolute', right: 27, top: 
-12, whiteSpace: 'nowrap', zIndex: 300, padding: 0}}
+                               variant={'link'}
+                                aria-label="Goto"
+                                onClick={_ => 
InfrastructureAPI.onInternalConsumerClick(uri, name)}>
+                            {name}
+                        </Button>
+                    }
                 </div>
             )
         }
diff --git a/karavan-designer/src/designer/utils/InfrastructureAPI.ts 
b/karavan-designer/src/designer/utils/InfrastructureAPI.ts
index c2d5ca7c..77ef1bd3 100644
--- a/karavan-designer/src/designer/utils/InfrastructureAPI.ts
+++ b/karavan-designer/src/designer/utils/InfrastructureAPI.ts
@@ -21,6 +21,7 @@ export class InfrastructureAPI {
     static onSaveCustomCode: (name: string, code: string) => void;
     static onSave: (filename: string, yaml: string, propertyOnly: boolean) => 
void;
     static onSavePropertyPlaceholder: (key: string, value: string) => void;
+    static onInternalConsumerClick: (uri: string, name: string) => void;
 
     static setOnGetCustomCode(onGetCustomCode: (name: string, javaType: 
string) => Promise<string | undefined>){
         this.onGetCustomCode = onGetCustomCode
@@ -38,6 +39,10 @@ export class InfrastructureAPI {
         this.onSavePropertyPlaceholder = onSavePropertyPlaceholder
     }
 
+    static setOnInternalConsumerClick(onInternalConsumerClick:(uri: string, 
name: string) => void){
+        this.onInternalConsumerClick = onInternalConsumerClick
+    }
+
     // Kubernetes/Docker API
     static infrastructure: 'kubernetes' | 'docker' | 'local' = 'local';
     static configMaps: string[] = [];
diff --git a/karavan-space/src/space/SpacePage.tsx 
b/karavan-space/src/space/SpacePage.tsx
index f3004565..24c62b66 100644
--- a/karavan-space/src/space/SpacePage.tsx
+++ b/karavan-space/src/space/SpacePage.tsx
@@ -111,6 +111,9 @@ export class SpacePage extends React.Component<Props, 
State> {
                 propertyPlaceholders={[]}
                 beans={[]}
                 onSavePropertyPlaceholder={(key, value) => {}}
+                onInternalConsumerClick={(uri, name) => {
+                    console.log("onInternalConsumerClick", uri, name)
+                }}
             />
         )
     }
diff --git a/karavan-vscode/webview/App.tsx b/karavan-vscode/webview/App.tsx
index 8addc851..b19b03c7 100644
--- a/karavan-vscode/webview/App.tsx
+++ b/karavan-vscode/webview/App.tsx
@@ -233,6 +233,9 @@ class App extends React.Component<Props, State> {
             propertyPlaceholders={this.state.propertyPlaceholders}
             onSavePropertyPlaceholder={(key, value) => 
this.savePropertyPlaceholder(key, value)}
             beans={this.state.beans}
+            onInternalConsumerClick={(uri, name) => {
+              console.log("onInternalConsumerClick", uri, name)
+          }}
           />
         }
         {loaded && page === "knowledgebase" && <KnowledgebasePage dark={dark} 
/>}
diff --git a/karavan-vscode/webview/topology/TopologyPropertiesPanel.tsx 
b/karavan-vscode/webview/topology/TopologyPropertiesPanel.tsx
index 8387ce1f..67edb46c 100644
--- a/karavan-vscode/webview/topology/TopologyPropertiesPanel.tsx
+++ b/karavan-vscode/webview/topology/TopologyPropertiesPanel.tsx
@@ -20,32 +20,93 @@ import {shallow} from "zustand/shallow";
 import {TopologySideBar} from "@patternfly/react-topology";
 import {useTopologyStore} from "./TopologyStore";
 import {DslProperties} from "../designer/property/DslProperties";
-import {Button, Flex, FlexItem, Text, Tooltip, TooltipPosition} from 
"@patternfly/react-core";
+import {
+    Button, DescriptionList,
+    DescriptionListDescription, DescriptionListGroup, DescriptionListTerm,
+    Flex,
+    FlexItem, Panel, PanelHeader, PanelMain, PanelMainBody,
+    Text, TextContent, TextVariants,
+    Tooltip,
+    TooltipPosition
+} from "@patternfly/react-core";
 import CloseIcon from "@patternfly/react-icons/dist/esm/icons/times-icon";
 
 interface Props {
     onSetFile: (fileName: string) => void
 }
 
-export function TopologyPropertiesPanel (props: Props) {
+export function TopologyPropertiesPanel(props: Props) {
 
-    const [selectedIds, setSelectedIds, fileName] = useTopologyStore((s) =>
-        [s.selectedIds, s.setSelectedIds, s.fileName], shallow);
+    const [selectedIds, setSelectedIds, fileName, nodeData] = 
useTopologyStore((s) =>
+        [s.selectedIds, s.setSelectedIds, s.fileName, s.nodeData], shallow);
+
+    console.log(nodeData)
+
+    function isRoute() {
+        if (nodeData && nodeData.type === 'route') {
+            const uri: string = nodeData?.step?.from.uri || '';
+            return uri !== undefined;
+        }
+        return false;
+    }
+
+    function isKamelet() {
+        if (nodeData && nodeData.type === 'step') {
+            const uri: string = nodeData?.step?.uri || '';
+            return uri.startsWith("kamelet");
+        }
+        return false;
+    }
+
+    function getFromInfo() {
+        if (isRoute()) {
+            const uri: string = nodeData?.step?.from.uri || '';
+            const name: string = nodeData?.step?.from.parameters?.name || '';
+            if (['direct','seda'].includes(uri)) {
+                return uri.concat(":").concat(name);
+            } else {
+                return uri;
+            }
+        }
+        return ""
+    }
+
+    function getTitle () {
+        return isRoute() ? "Route" : (isKamelet() ? "Kamelet" : "Component");
+    }
 
     function getHeader() {
         return (
-            <Flex className="properties-header" direction={{default: "row"}} 
justifyContent={{default: "justifyContentFlexStart"}}>
+            <Flex direction={{default: "row"}} justifyContent={{default: 
"justifyContentFlexStart"}}>
                 <FlexItem spacer={{ default: 'spacerNone' }}>
-                    <Text>Filename:</Text>
-                </FlexItem>
-                <FlexItem>
-                    <Button variant="link" onClick={event => {
-                        if (fileName) {
-                            props.onSetFile(fileName);
-                        }
-                    }}
-                    >{fileName}
-                    </Button>
+                    <Panel>
+                        <PanelHeader>
+                            <TextContent>
+                                <Text 
component={TextVariants.h3}>{getTitle()}</Text>
+                            </TextContent>
+                        </PanelHeader>
+                        <PanelMain>
+                            <PanelMainBody>
+                                <DescriptionList isHorizontal>
+                                    <DescriptionListGroup>
+                                        
<DescriptionListTerm>File</DescriptionListTerm>
+                                        <DescriptionListDescription>
+                                            <Button className="file-button" 
variant="link" onClick={_ => {
+                                                if (fileName) {
+                                                    props.onSetFile(fileName);
+                                                }
+                                            }}>{fileName}
+                                            </Button>
+                                        </DescriptionListDescription>
+                                    </DescriptionListGroup>
+                                    {isRoute() && <DescriptionListGroup>
+                                        
<DescriptionListTerm>From</DescriptionListTerm>
+                                        
<DescriptionListDescription>{getFromInfo()}</DescriptionListDescription>
+                                    </DescriptionListGroup>}
+                                </DescriptionList>
+                            </PanelMainBody>
+                        </PanelMain>
+                    </Panel>
                 </FlexItem>
                 <FlexItem align={{ default: 'alignRight' }}>
                     <Tooltip content={"Close"} position={TooltipPosition.top}>
@@ -58,11 +119,11 @@ export function TopologyPropertiesPanel (props: Props) {
 
     return (
         <TopologySideBar
-        className="topology-sidebar"
-        show={selectedIds.length > 0}
-        header={getHeader()}
-    >
-        <DslProperties designerType={'routes'}/>
-    </TopologySideBar>
+            className="topology-sidebar"
+            show={selectedIds.length > 0}
+            header={getHeader()}
+        >
+            <DslProperties designerType={'routes'}/>
+        </TopologySideBar>
     )
 }
diff --git a/karavan-vscode/webview/topology/TopologyStore.ts 
b/karavan-vscode/webview/topology/TopologyStore.ts
index 73aead9f..4e9ee643 100644
--- a/karavan-vscode/webview/topology/TopologyStore.ts
+++ b/karavan-vscode/webview/topology/TopologyStore.ts
@@ -35,6 +35,8 @@ interface TopologyState {
     setFileName: (fileName?: string) => void
     ranker: string
     setRanker: (ranker: string) => void
+    nodeData: any
+    setNodeData: (nodeData: any) => void
 }
 
 export const useTopologyStore = createWithEqualityFn<TopologyState>((set) => ({
@@ -55,4 +57,10 @@ export const useTopologyStore = 
createWithEqualityFn<TopologyState>((set) => ({
             return {ranker: ranker};
         });
     },
+    nodeData: undefined,
+    setNodeData: (nodeData: any) => {
+    set((state: TopologyState) => {
+        return {nodeData: nodeData};
+    });
+},
 }), shallow)
diff --git a/karavan-vscode/webview/topology/TopologyTab.tsx 
b/karavan-vscode/webview/topology/TopologyTab.tsx
index 727905cc..1f2d165e 100644
--- a/karavan-vscode/webview/topology/TopologyTab.tsx
+++ b/karavan-vscode/webview/topology/TopologyTab.tsx
@@ -47,8 +47,8 @@ interface Props {
 
 export function TopologyTab(props: Props) {
 
-    const [selectedIds, setSelectedIds, setFileName, ranker, setRanker] = 
useTopologyStore((s) =>
-        [s.selectedIds, s.setSelectedIds, s.setFileName, s.ranker, 
s.setRanker], 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 []) {
@@ -57,6 +57,7 @@ export function TopologyTab(props: Props) {
             const node = model.nodes?.filter(node => node.id === ids[0]);
             if (node && node.length > 0) {
                 const data = node[0].data;
+                setNodeData(data);
                 setFileName(data.fileName)
                 if (data.step) {
                     setSelectedStep(data.step)
diff --git a/karavan-vscode/webview/topology/topology.css 
b/karavan-vscode/webview/topology/topology.css
index cb261e21..24fe7679 100644
--- a/karavan-vscode/webview/topology/topology.css
+++ b/karavan-vscode/webview/topology/topology.css
@@ -41,8 +41,8 @@
     overflow: auto;
 }
 
-.karavan .topology-panel .properties-header {
-    padding: 10px;
+.karavan .topology-panel .properties .headers {
+    display: none;
 }
 
 .karavan .topology-panel .common-node .icon {
@@ -50,6 +50,14 @@
     width: 32px;
 }
 
+.karavan .topology-panel .pf-v5-c-panel__header {
+    padding-bottom: 0;
+}
+
+.karavan .topology-panel .file-button {
+    padding: 0;
+}
+
 .karavan .topology-sidebar .pf-topology-side-bar__header {
     margin-right: 0;
 }
@@ -72,4 +80,8 @@
 .karavan .topology-sidebar .properties .pf-v5-c-form {
     pointer-events: none;
     opacity: 0.7;
+}
+.karavan .topology-sidebar .properties .pf-v5-c-form 
.pf-v5-c-form__group-label-help {
+    pointer-events: auto;
+    opacity: 1;
 }
\ No newline at end of file
diff --git 
a/karavan-web/karavan-app/src/main/webui/src/designer/KaravanDesigner.tsx 
b/karavan-web/karavan-app/src/main/webui/src/designer/KaravanDesigner.tsx
index 11bf8b6c..05831a38 100644
--- a/karavan-web/karavan-app/src/main/webui/src/designer/KaravanDesigner.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/KaravanDesigner.tsx
@@ -48,6 +48,7 @@ interface Props {
     onSaveCustomCode: (name: string, code: string) => void
     onGetCustomCode: (name: string, javaType: string) => Promise<string | 
undefined>
     onSavePropertyPlaceholder: (key: string, value: string) => void
+    onInternalConsumerClick: (uri: string, name: string) => void
     filename: string
     yaml: string
     dark: boolean
@@ -74,6 +75,7 @@ export function KaravanDesigner(props: Props) {
         InfrastructureAPI.setOnGetCustomCode(props.onGetCustomCode);
         InfrastructureAPI.setOnSave(props.onSave);
         
InfrastructureAPI.setOnSavePropertyPlaceholder(props.onSavePropertyPlaceholder);
+        
InfrastructureAPI.setOnInternalConsumerClick(props.onInternalConsumerClick);
 
         setSelectedStep(undefined);
         const i = makeIntegration(props.yaml, props.filename);
diff --git 
a/karavan-web/karavan-app/src/main/webui/src/designer/route/DslConnections.tsx 
b/karavan-web/karavan-app/src/main/webui/src/designer/route/DslConnections.tsx
index 0cfb4d78..ebb89933 100644
--- 
a/karavan-web/karavan-app/src/main/webui/src/designer/route/DslConnections.tsx
+++ 
b/karavan-web/karavan-app/src/main/webui/src/designer/route/DslConnections.tsx
@@ -24,6 +24,9 @@ import {CamelDefinitionApiExt} from 
"karavan-core/lib/api/CamelDefinitionApiExt"
 import {TopologyUtils} from "karavan-core/lib/api/TopologyUtils";
 import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition";
 import {v4 as uuidv4} from "uuid";
+import {DeleteElementIcon} from "../utils/ElementIcons";
+import {Button} from "@patternfly/react-core";
+import {InfrastructureAPI} from "../utils/InfrastructureAPI";
 
 const overlapGap: number = 40;
 
@@ -191,7 +194,7 @@ export function DslConnections() {
             const step = (pos.step as any);
             const uri = step?.uri;
             const directOrSeda = step && uri && step?.dslName === 
'ToDefinition' && ['direct','seda'].includes(uri);
-            const label = directOrSeda ? (step?.parameters?.name) : '';
+            const name = directOrSeda ? (step?.parameters?.name) : '';
             const r = pos.headerRect.height / 2;
             const outgoingX = width - 20;
             const outgoingY = data[1] + 15;
@@ -201,7 +204,14 @@ export function DslConnections() {
                 <div key={pos.step.uuid + "-icon"}
                      style={{display: "block", position: "absolute", top: 
imageY, left: imageX}}>
                     {CamelUi.getConnectionIcon(pos.step)}
-                    {directOrSeda && <div style={{position: 'absolute', right: 
27, top: -10, whiteSpace: 'nowrap'}}>{label}</div>}
+                    {directOrSeda &&
+                        <Button style={{position: 'absolute', right: 27, top: 
-12, whiteSpace: 'nowrap', zIndex: 300, padding: 0}}
+                               variant={'link'}
+                                aria-label="Goto"
+                                onClick={_ => 
InfrastructureAPI.onInternalConsumerClick(uri, name)}>
+                            {name}
+                        </Button>
+                    }
                 </div>
             )
         }
diff --git 
a/karavan-web/karavan-app/src/main/webui/src/designer/utils/InfrastructureAPI.ts
 
b/karavan-web/karavan-app/src/main/webui/src/designer/utils/InfrastructureAPI.ts
index c2d5ca7c..77ef1bd3 100644
--- 
a/karavan-web/karavan-app/src/main/webui/src/designer/utils/InfrastructureAPI.ts
+++ 
b/karavan-web/karavan-app/src/main/webui/src/designer/utils/InfrastructureAPI.ts
@@ -21,6 +21,7 @@ export class InfrastructureAPI {
     static onSaveCustomCode: (name: string, code: string) => void;
     static onSave: (filename: string, yaml: string, propertyOnly: boolean) => 
void;
     static onSavePropertyPlaceholder: (key: string, value: string) => void;
+    static onInternalConsumerClick: (uri: string, name: string) => void;
 
     static setOnGetCustomCode(onGetCustomCode: (name: string, javaType: 
string) => Promise<string | undefined>){
         this.onGetCustomCode = onGetCustomCode
@@ -38,6 +39,10 @@ export class InfrastructureAPI {
         this.onSavePropertyPlaceholder = onSavePropertyPlaceholder
     }
 
+    static setOnInternalConsumerClick(onInternalConsumerClick:(uri: string, 
name: string) => void){
+        this.onInternalConsumerClick = onInternalConsumerClick
+    }
+
     // Kubernetes/Docker API
     static infrastructure: 'kubernetes' | 'docker' | 'local' = 'local';
     static configMaps: string[] = [];
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/FileEditor.tsx 
b/karavan-web/karavan-app/src/main/webui/src/project/FileEditor.tsx
index 9ca0e26c..20b6a53e 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/FileEditor.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/project/FileEditor.tsx
@@ -94,6 +94,9 @@ export function FileEditor (props: Props) {
                 propertyPlaceholders={propertyPlaceholders}
                 onSavePropertyPlaceholder={onSavePropertyPlaceholder}
                 beans={beans}
+                onInternalConsumerClick={(uri, name) => {
+                    console.log("onInternalConsumerClick", uri, name)
+                }}
             />
         )
     }

Reply via email to