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 828e234ffabc729377a1d469e97a7ac0dff28845
Author: Marat Gubaidullin <[email protected]>
AuthorDate: Sun Sep 1 14:45:27 2024 -0400

    Sync with designer
---
 karavan-vscode/webview/topology/CustomGroup.tsx    |   6 +-
 karavan-vscode/webview/topology/CustomNode.tsx     |  23 ++--
 karavan-vscode/webview/topology/TopologyApi.tsx    | 126 ++++++++++++---------
 .../webview/topology/TopologyPropertiesPanel.tsx   |   4 +-
 karavan-vscode/webview/topology/TopologyTab.tsx    |   5 +-
 .../webview/topology/TopologyToolbar.tsx           |   7 ++
 karavan-vscode/webview/topology/topology.css       |   4 +
 7 files changed, 110 insertions(+), 65 deletions(-)

diff --git a/karavan-vscode/webview/topology/CustomGroup.tsx 
b/karavan-vscode/webview/topology/CustomGroup.tsx
index 9e366c7c..595250a8 100644
--- a/karavan-vscode/webview/topology/CustomGroup.tsx
+++ b/karavan-vscode/webview/topology/CustomGroup.tsx
@@ -18,13 +18,11 @@
 import * as React from 'react';
 
 import './topology.css';
-import { DefaultGroup, observer} from '@patternfly/react-topology';
-
+import {DefaultGroup, observer} from '@patternfly/react-topology';
 
 const CustomGroup: React.FC<any> = observer(({ element, ...rest }) => {
-
     return (
-        <DefaultGroup element={element} {...rest}>
+        <DefaultGroup element={element} className={"topology-group"} {...rest}>
         </DefaultGroup>
     )
 })
diff --git a/karavan-vscode/webview/topology/CustomNode.tsx 
b/karavan-vscode/webview/topology/CustomNode.tsx
index e0a022d0..fd8d12e6 100644
--- a/karavan-vscode/webview/topology/CustomNode.tsx
+++ b/karavan-vscode/webview/topology/CustomNode.tsx
@@ -22,6 +22,8 @@ import {DefaultNode, observer} from 
'@patternfly/react-topology';
 import {getDesignerIcon} from "../designer/icons/KaravanIcons";
 import {CamelUi} from "../designer/utils/CamelUi";
 import './topology.css';
+import {RouteDefinition} from "core/model/CamelDefinition";
+import {AutoStartupIcon, ErrorHandlerIcon} from "../designer/icons/OtherIcons";
 
 function getIcon(data: any) {
     if (['route', 'rest', 'routeConfiguration'].includes(data.icon)) {
@@ -41,15 +43,22 @@ function getIcon(data: any) {
 }
 
 function getAttachments(data: any) {
-    if (data?.step?.dslName === 'RouteDefinition' && data?.step?.autoStartup 
!== false) {
-        const x = 0;
-        const y = 0;
-        const rx = x + 9;
-        const ry = y + 9;
+    if (data && data?.step?.dslName === 'RouteDefinition') {
+        const route: RouteDefinition = data?.step;
+        const autoStartup =  route?.autoStartup !== false;
+        const errorHandler =  route?.errorHandler !== undefined;
         return (
             <g className="pf-topology__node__label__badge auto-start" 
transform="translate(-4, -4)">
-                <rect className="badge" x={x} width="22" y={y} height="17" 
rx={rx} ry={ry}></rect>
-                <text className='text' x={rx + 2} y={ry} textAnchor="middle" 
dy="0.35em">A</text>
+                {errorHandler &&
+                    <g className="" transform="translate(13, -4)">
+                        {ErrorHandlerIcon()}
+                    </g>
+                }
+                {autoStartup &&
+                    <g className="" transform="translate(-4, -4)">
+                        {AutoStartupIcon()}
+                    </g>
+                }
             </g>
         )
     } else <></>
diff --git a/karavan-vscode/webview/topology/TopologyApi.tsx 
b/karavan-vscode/webview/topology/TopologyApi.tsx
index a6385542..fda10d1f 100644
--- a/karavan-vscode/webview/topology/TopologyApi.tsx
+++ b/karavan-vscode/webview/topology/TopologyApi.tsx
@@ -33,15 +33,10 @@ import CustomNode from "./CustomNode";
 import {Integration, IntegrationFile} from "core/model/IntegrationDefinition";
 import {CamelDefinitionYaml} from "core/api/CamelDefinitionYaml";
 import {TopologyUtils} from "core/api/TopologyUtils";
-import {
-    TopologyIncomingNode,
-    TopologyOutgoingNode,
-    TopologyRestNode,
-    TopologyRouteConfigurationNode,
-    TopologyRouteNode
-} from "core/model/TopologyDefinition";
+import {TopologyIncomingNode, TopologyOutgoingNode, TopologyRestNode, 
TopologyRouteConfigurationNode, TopologyRouteNode} from 
"core/model/TopologyDefinition";
 import CustomEdge from "./CustomEdge";
 import CustomGroup from "./CustomGroup";
+import {INTERNAL_COMPONENTS} from "core/api/ComponentApi";
 
 const NODE_DIAMETER = 60;
 
@@ -174,16 +169,18 @@ export function getExternalEdges(tons: 
TopologyOutgoingNode[], tins: TopologyInc
     tons.filter(ton => ton.type === 'external').forEach((ton, index) => {
         const uniqueUri = ton.uniqueUri;
         if (uniqueUri) {
-            const target = TopologyUtils.getNodeIdByUniqueUri(tins, uniqueUri);
-            const node: EdgeModel = {
-                id: 'external-' + ton.id + '-' + index,
-                type: 'edge',
-                source: ton.id,
-                target: target,
-                edgeStyle: EdgeStyle.dotted,
-                animationSpeed: EdgeAnimationSpeed.slow
-            }
-            if (target) result.push(node);
+            TopologyUtils.getNodeIdByUniqueUri(tins, uniqueUri).forEach(target 
=> {
+                const node: EdgeModel = {
+                    id: 'external-' + ton.id + '-' + target,
+                    type: 'edge',
+                    source: ton.id,
+                    target: target,
+                    edgeStyle: EdgeStyle.dotted,
+                    animationSpeed: EdgeAnimationSpeed.medium,
+                    data : {groupName: uniqueUri}
+                }
+                result.push(node);
+            });
         }
     });
     return result;
@@ -251,8 +248,10 @@ export function getInternalEdges(tons: 
TopologyOutgoingNode[], tins: TopologyInc
             if (target) result.push(node);
         } else {
             const uri: string = (ton.step as any).uri;
-            if (uri?.startsWith("direct") || uri?.startsWith("seda")) {
-                const name = (ton.step as any).parameters.name;
+            const component = uri?.split(":")?.[0];
+            if (INTERNAL_COMPONENTS.includes(component)) {
+                const step = (ton.step as any);
+                const name = step.parameters.name || step.parameters.address;
                 const target = TopologyUtils.getRouteIdByUriAndName(tins, uri, 
name);
                 const node: EdgeModel = {
                     id: 'internal-' + ton.id + '-' + index,
@@ -280,33 +279,6 @@ export function getModel(files: IntegrationFile[], 
grouping?: boolean): Model {
     const trcons = 
TopologyUtils.findTopologyRouteConfigurationOutgoingNodes(integrations);
 
     const nodes: NodeModel[] = [];
-    const groups: NodeModel[] = [];
-
-    const children1: string[] = [];
-    children1.push(...tins.filter(i => i.type === 'external').map(i => i.id));
-    children1.push(...trestns.map(i => i.id));
-    groups.push({
-        id: 'consumer-group',
-        children: children1,
-        type: 'group',
-        group: true,
-        label: 'Consumer group',
-        style: {
-            padding: 25,
-        }
-    })
-
-    const children2 = [...tons.filter(i => i.type === 'external').map(i => 
i.id)];
-    groups.push({
-        id: 'producer-group',
-        children: children2,
-        type: 'group',
-        group: true,
-        label: 'Producer group',
-        style: {
-            padding: 25,
-        }
-    })
 
     nodes.push(...getRestNodes(trestns))
     nodes.push(...getIncomingNodes(tins))
@@ -315,17 +287,69 @@ export function getModel(files: IntegrationFile[], 
grouping?: boolean): Model {
     nodes.push(...getOutgoingNodes(tons))
     nodes.push(...getOutgoingNodes(trcons))
 
-    if (grouping === true) {
-        nodes.push(...groups)
-    }
-
     const edges: EdgeModel[] = [];
     edges.push(...getIncomingEdges(tins));
     edges.push(...getOutgoingEdges(tons));
     edges.push(...getRestEdges(trestns, tins));
     edges.push(...getInternalEdges(tons, tins));
     edges.push(...getInternalEdges(trcons, tins));
-    // edges.push(...getExternalEdges(tons,tins));
+
+
+    // Groups
+    const groups: NodeModel[] = [];
+    if (grouping === true) {
+        const children1: string[] = [];
+        children1.push(...tins.filter(i => i.type === 'external').map(i => 
i.id));
+        children1.push(...trestns.map(i => i.id));
+        groups.push({
+            id: 'consumer-group',
+            children: children1,
+            type: 'group',
+            group: true,
+            label: 'Consumer group',
+            style: {
+                padding: 20,
+            }
+        })
+
+        const children2 = [...tons.filter(i => i.type === 'external').map(i => 
i.id)];
+        groups.push({
+            id: 'producer-group',
+            children: children2,
+            type: 'group',
+            group: true,
+            label: 'Producer group',
+            style: {
+                padding: 20,
+            },
+        })
+    } else {
+        const externalEdges = getExternalEdges(tons,tins);
+        edges.push(...externalEdges);
+        // const uniqueGroups: Map<string, string[]> = new Map();
+        //
+        // externalEdges.forEach(edge => {
+        //     const groupName =  edge.data.groupName;
+        //     const children = uniqueGroups.get(groupName) || [];
+        //     if (edge.source) children.push(edge.source)
+        //     if (edge.target) children.push(edge.target)
+        //     uniqueGroups.set(groupName, [...new Set(children)]);
+        // });
+        //
+        // uniqueGroups.forEach((children, groupName) => {
+        //     groups.push({
+        //         id: groupName + '-group',
+        //         children: children,
+        //         type: 'group',
+        //         group: true,
+        //         // label: edge.id + ' group',
+        //         style: {
+        //             padding: 20,
+        //         }
+        //     })
+        // })
+    }
+    nodes.push(...groups)
 
     return {nodes: nodes, edges: edges, graph: {id: 'g1', type: 'graph', 
layout: 'Dagre'}};
 }
diff --git a/karavan-vscode/webview/topology/TopologyPropertiesPanel.tsx 
b/karavan-vscode/webview/topology/TopologyPropertiesPanel.tsx
index 0fd93b3d..60ae9a50 100644
--- a/karavan-vscode/webview/topology/TopologyPropertiesPanel.tsx
+++ b/karavan-vscode/webview/topology/TopologyPropertiesPanel.tsx
@@ -30,7 +30,7 @@ import {
     TooltipPosition
 } from "@patternfly/react-core";
 import CloseIcon from "@patternfly/react-icons/dist/esm/icons/times-icon";
-import {NAV_COMPONENTS} from "../designer/utils/CamelUi";
+import {INTERNAL_COMPONENTS} from "core/api/ComponentApi";
 
 interface Props {
     onSetFile: (fileName: string) => void
@@ -69,7 +69,7 @@ export function TopologyPropertiesPanel(props: Props) {
         if (isRoute()) {
             const uri: string = nodeData?.step?.from.uri || '';
             const name: string = nodeData?.step?.from.parameters?.name || '';
-            if (NAV_COMPONENTS.includes(uri)) {
+            if (INTERNAL_COMPONENTS.includes(uri)) {
                 return uri.concat(":").concat(name);
             } else {
                 return uri;
diff --git a/karavan-vscode/webview/topology/TopologyTab.tsx 
b/karavan-vscode/webview/topology/TopologyTab.tsx
index 51f5d24e..a98703b4 100644
--- a/karavan-vscode/webview/topology/TopologyTab.tsx
+++ b/karavan-vscode/webview/topology/TopologyTab.tsx
@@ -45,6 +45,7 @@ interface Props {
     onClickAddREST: () => void
     onClickAddKamelet: () => void
     onClickAddBean: () => void
+    isDev?: boolean
 }
 
 export function TopologyTab(props: Props) {
@@ -146,7 +147,9 @@ export function TopologyTab(props: Props) {
                 ? <TopologyToolbar onClickAddRoute={props.onClickAddRoute}
                                    onClickAddBean={props.onClickAddBean}
                                    onClickAddKamelet={props.onClickAddKamelet}
-                                   onClickAddREST={props.onClickAddREST}/>
+                                   onClickAddREST={props.onClickAddREST}
+                                   isDev={props.isDev}
+                />
                 : undefined}
             sideBar={<TopologyPropertiesPanel onSetFile={props.onSetFile}/>}
             controlBar={
diff --git a/karavan-vscode/webview/topology/TopologyToolbar.tsx 
b/karavan-vscode/webview/topology/TopologyToolbar.tsx
index 0b23c542..2ac6eda9 100644
--- a/karavan-vscode/webview/topology/TopologyToolbar.tsx
+++ b/karavan-vscode/webview/topology/TopologyToolbar.tsx
@@ -24,17 +24,20 @@ import PlusIcon from 
"@patternfly/react-icons/dist/esm/icons/plus-icon";
 import {useTopologyStore} from "./TopologyStore";
 import {shallow} from "zustand/shallow";
 
+
 interface Props {
     onClickAddRoute: () => void
     onClickAddREST: () => void
     onClickAddKamelet: () => void
     onClickAddBean: () => void
+    isDev?: boolean
 }
 
 export function TopologyToolbar (props: Props) {
 
     const [showGroups, setShowGroups] = useTopologyStore((s) =>
         [s.showGroups, s.setShowGroups], shallow);
+    const isDev = props.isDev
 
     return (
         <div className='topology-toolbar'>
@@ -52,6 +55,7 @@ export function TopologyToolbar (props: Props) {
             <ToolbarItem align={{default:"alignRight"}}>
                 <Tooltip content={"Add Integration Route"} position={"bottom"}>
                     <Button className="dev-action-button" size="sm"
+                            isDisabled={!isDev}
                             variant={"primary"}
                             icon={<PlusIcon/>}
                             onClick={e => props.onClickAddRoute()}
@@ -63,6 +67,7 @@ export function TopologyToolbar (props: Props) {
             <ToolbarItem align={{default:"alignRight"}}>
                 <Tooltip content={"Add REST API"} position={"bottom"}>
                     <Button className="dev-action-button" size="sm"
+                            isDisabled={!isDev}
                             variant={"secondary"}
                             icon={<PlusIcon/>}
                             onClick={e => props.onClickAddREST()}
@@ -74,6 +79,7 @@ export function TopologyToolbar (props: Props) {
             <ToolbarItem align={{default:"alignRight"}}>
                 <Tooltip content={"Add Kamelet"} position={"bottom"}>
                     <Button className="dev-action-button" size="sm"
+                            isDisabled={!isDev}
                             variant={"secondary"}
                             icon={<PlusIcon/>}
                             onClick={e => props.onClickAddKamelet()}
@@ -85,6 +91,7 @@ export function TopologyToolbar (props: Props) {
             <ToolbarItem align={{default:"alignRight"}}>
                 <Tooltip content={"Add Bean"} position={"bottom"}>
                     <Button className="dev-action-button" size="sm"
+                            isDisabled={!isDev}
                             variant={"secondary"}
                             icon={<PlusIcon/>}
                             onClick={e => props.onClickAddBean()}
diff --git a/karavan-vscode/webview/topology/topology.css 
b/karavan-vscode/webview/topology/topology.css
index 1828bd1e..6edc633d 100644
--- a/karavan-vscode/webview/topology/topology.css
+++ b/karavan-vscode/webview/topology/topology.css
@@ -115,4 +115,8 @@
 
 .karavan .topology-panel .auto-start .text {
     fill: var(--pf-topology__node__label__text--Fill);
+}
+
+.karavan .topology-group .pf-topology__group__label {
+    display: none;
 }
\ No newline at end of file

Reply via email to