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
The following commit(s) were added to refs/heads/main by this push:
new 197b4f5d Fix #1362
197b4f5d is described below
commit 197b4f5d856dd665e75eb1d6dd3918c6dd3a153b
Author: Marat Gubaidullin <[email protected]>
AuthorDate: Fri Aug 16 13:58:31 2024 -0400
Fix #1362
---
.../src/main/webui/src/project/ProjectPanel.tsx | 2 +
.../src/main/webui/src/topology/CustomGroup.tsx | 6 +-
.../src/main/webui/src/topology/TopologyApi.tsx | 119 ++++++++++++---------
.../src/main/webui/src/topology/TopologyTab.tsx | 5 +-
.../main/webui/src/topology/TopologyToolbar.tsx | 7 ++
.../src/main/webui/src/topology/topology.css | 4 +
karavan-core/src/core/api/TopologyUtils.ts | 12 +--
karavan-designer/src/topology/CustomGroup.tsx | 6 +-
karavan-designer/src/topology/TopologyApi.tsx | 119 ++++++++++++---------
karavan-designer/src/topology/TopologyTab.tsx | 5 +-
karavan-designer/src/topology/TopologyToolbar.tsx | 7 ++
karavan-designer/src/topology/topology.css | 4 +
karavan-space/src/topology/CustomGroup.tsx | 6 +-
karavan-space/src/topology/TopologyApi.tsx | 119 ++++++++++++---------
karavan-space/src/topology/TopologyTab.tsx | 5 +-
karavan-space/src/topology/TopologyToolbar.tsx | 7 ++
karavan-space/src/topology/topology.css | 4 +
17 files changed, 269 insertions(+), 168 deletions(-)
diff --git a/karavan-app/src/main/webui/src/project/ProjectPanel.tsx
b/karavan-app/src/main/webui/src/project/ProjectPanel.tsx
index f41d5710..9b46a45c 100644
--- a/karavan-app/src/main/webui/src/project/ProjectPanel.tsx
+++ b/karavan-app/src/main/webui/src/project/ProjectPanel.tsx
@@ -45,6 +45,7 @@ export function ProjectPanel() {
const [setFile] = useFileStore((s) => [s.setFile], shallow);
const [files, setFiles] = useFilesStore((s) => [s.files, s.setFiles],
shallow);
const [setShowWizard] = useWizardStore((s) => [s.setShowWizard], shallow)
+ const isDev = config.environment === 'dev';
useEffect(() => {
onRefresh();
@@ -90,6 +91,7 @@ export function ProjectPanel() {
setShowWizard(true)
}}
onSetFile={(fileName) => selectFile(fileName)}
+ isDev={isDev}
/>
<CreateIntegrationModal/>
<BeanWizard/>
diff --git a/karavan-app/src/main/webui/src/topology/CustomGroup.tsx
b/karavan-app/src/main/webui/src/topology/CustomGroup.tsx
index 9e366c7c..595250a8 100644
--- a/karavan-app/src/main/webui/src/topology/CustomGroup.tsx
+++ b/karavan-app/src/main/webui/src/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-app/src/main/webui/src/topology/TopologyApi.tsx
b/karavan-app/src/main/webui/src/topology/TopologyApi.tsx
index 174ad6a6..a5342a37 100644
--- a/karavan-app/src/main/webui/src/topology/TopologyApi.tsx
+++ b/karavan-app/src/main/webui/src/topology/TopologyApi.tsx
@@ -33,13 +33,7 @@ import CustomNode from "./CustomNode";
import {Integration, IntegrationFile} from
"karavan-core/lib/model/IntegrationDefinition";
import {CamelDefinitionYaml} from "karavan-core/lib/api/CamelDefinitionYaml";
import {TopologyUtils} from "karavan-core/lib/api/TopologyUtils";
-import {
- TopologyIncomingNode,
- TopologyOutgoingNode,
- TopologyRestNode,
- TopologyRouteConfigurationNode,
- TopologyRouteNode
-} from "karavan-core/lib/model/TopologyDefinition";
+import {TopologyIncomingNode, TopologyOutgoingNode, TopologyRestNode,
TopologyRouteConfigurationNode, TopologyRouteNode} from
"karavan-core/lib/model/TopologyDefinition";
import CustomEdge from "./CustomEdge";
import CustomGroup from "./CustomGroup";
@@ -174,16 +168,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;
@@ -280,33 +276,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 +284,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-app/src/main/webui/src/topology/TopologyTab.tsx
b/karavan-app/src/main/webui/src/topology/TopologyTab.tsx
index cc189e29..d8408a99 100644
--- a/karavan-app/src/main/webui/src/topology/TopologyTab.tsx
+++ b/karavan-app/src/main/webui/src/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-app/src/main/webui/src/topology/TopologyToolbar.tsx
b/karavan-app/src/main/webui/src/topology/TopologyToolbar.tsx
index 0b23c542..2ac6eda9 100644
--- a/karavan-app/src/main/webui/src/topology/TopologyToolbar.tsx
+++ b/karavan-app/src/main/webui/src/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-app/src/main/webui/src/topology/topology.css
b/karavan-app/src/main/webui/src/topology/topology.css
index 1828bd1e..6edc633d 100644
--- a/karavan-app/src/main/webui/src/topology/topology.css
+++ b/karavan-app/src/main/webui/src/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
diff --git a/karavan-core/src/core/api/TopologyUtils.ts
b/karavan-core/src/core/api/TopologyUtils.ts
index 1788f740..bfe60e22 100644
--- a/karavan-core/src/core/api/TopologyUtils.ts
+++ b/karavan-core/src/core/api/TopologyUtils.ts
@@ -38,6 +38,7 @@ import { ComponentApi } from './ComponentApi';
import { CamelDefinitionApiExt } from './CamelDefinitionApiExt';
import { CamelDisplayUtil } from './CamelDisplayUtil';
import { CamelUtil } from './CamelUtil';
+import { notDeepEqual } from 'node:assert';
const outgoingDefinitions: string[] = ['ToDefinition', 'KameletDefinition',
'ToDynamicDefinition', "PollEnrichDefinition", "EnrichDefinition",
"WireTapDefinition", "SagaDefinition"];
@@ -342,12 +343,11 @@ export class TopologyUtils {
}
}
- static getNodeIdByUniqueUri(tins: TopologyIncomingNode[], uniqueUri:
string): string | undefined {
- const node = tins
- .filter(r => r.uniqueUri === uniqueUri).at(0);
- if (node) {
- return node.id;
- }
+ static getNodeIdByUniqueUri(tins: TopologyIncomingNode[], uniqueUri:
string): string [] {
+ const result: string[] = [];
+ tins.filter(r => r.uniqueUri === uniqueUri)
+ ?.forEach(node => result.push(node.id))
+ return result;
}
static getRouteIdByUri(tins: TopologyIncomingNode[], uri: string): string
| undefined {
diff --git a/karavan-designer/src/topology/CustomGroup.tsx
b/karavan-designer/src/topology/CustomGroup.tsx
index 9e366c7c..595250a8 100644
--- a/karavan-designer/src/topology/CustomGroup.tsx
+++ b/karavan-designer/src/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-designer/src/topology/TopologyApi.tsx
b/karavan-designer/src/topology/TopologyApi.tsx
index 174ad6a6..a5342a37 100644
--- a/karavan-designer/src/topology/TopologyApi.tsx
+++ b/karavan-designer/src/topology/TopologyApi.tsx
@@ -33,13 +33,7 @@ import CustomNode from "./CustomNode";
import {Integration, IntegrationFile} from
"karavan-core/lib/model/IntegrationDefinition";
import {CamelDefinitionYaml} from "karavan-core/lib/api/CamelDefinitionYaml";
import {TopologyUtils} from "karavan-core/lib/api/TopologyUtils";
-import {
- TopologyIncomingNode,
- TopologyOutgoingNode,
- TopologyRestNode,
- TopologyRouteConfigurationNode,
- TopologyRouteNode
-} from "karavan-core/lib/model/TopologyDefinition";
+import {TopologyIncomingNode, TopologyOutgoingNode, TopologyRestNode,
TopologyRouteConfigurationNode, TopologyRouteNode} from
"karavan-core/lib/model/TopologyDefinition";
import CustomEdge from "./CustomEdge";
import CustomGroup from "./CustomGroup";
@@ -174,16 +168,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;
@@ -280,33 +276,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 +284,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-designer/src/topology/TopologyTab.tsx
b/karavan-designer/src/topology/TopologyTab.tsx
index cc189e29..d8408a99 100644
--- a/karavan-designer/src/topology/TopologyTab.tsx
+++ b/karavan-designer/src/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-designer/src/topology/TopologyToolbar.tsx
b/karavan-designer/src/topology/TopologyToolbar.tsx
index 0b23c542..2ac6eda9 100644
--- a/karavan-designer/src/topology/TopologyToolbar.tsx
+++ b/karavan-designer/src/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-designer/src/topology/topology.css
b/karavan-designer/src/topology/topology.css
index 1828bd1e..6edc633d 100644
--- a/karavan-designer/src/topology/topology.css
+++ b/karavan-designer/src/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
diff --git a/karavan-space/src/topology/CustomGroup.tsx
b/karavan-space/src/topology/CustomGroup.tsx
index 9e366c7c..595250a8 100644
--- a/karavan-space/src/topology/CustomGroup.tsx
+++ b/karavan-space/src/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-space/src/topology/TopologyApi.tsx
b/karavan-space/src/topology/TopologyApi.tsx
index 174ad6a6..a5342a37 100644
--- a/karavan-space/src/topology/TopologyApi.tsx
+++ b/karavan-space/src/topology/TopologyApi.tsx
@@ -33,13 +33,7 @@ import CustomNode from "./CustomNode";
import {Integration, IntegrationFile} from
"karavan-core/lib/model/IntegrationDefinition";
import {CamelDefinitionYaml} from "karavan-core/lib/api/CamelDefinitionYaml";
import {TopologyUtils} from "karavan-core/lib/api/TopologyUtils";
-import {
- TopologyIncomingNode,
- TopologyOutgoingNode,
- TopologyRestNode,
- TopologyRouteConfigurationNode,
- TopologyRouteNode
-} from "karavan-core/lib/model/TopologyDefinition";
+import {TopologyIncomingNode, TopologyOutgoingNode, TopologyRestNode,
TopologyRouteConfigurationNode, TopologyRouteNode} from
"karavan-core/lib/model/TopologyDefinition";
import CustomEdge from "./CustomEdge";
import CustomGroup from "./CustomGroup";
@@ -174,16 +168,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;
@@ -280,33 +276,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 +284,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-space/src/topology/TopologyTab.tsx
b/karavan-space/src/topology/TopologyTab.tsx
index cc189e29..d8408a99 100644
--- a/karavan-space/src/topology/TopologyTab.tsx
+++ b/karavan-space/src/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-space/src/topology/TopologyToolbar.tsx
b/karavan-space/src/topology/TopologyToolbar.tsx
index 0b23c542..2ac6eda9 100644
--- a/karavan-space/src/topology/TopologyToolbar.tsx
+++ b/karavan-space/src/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-space/src/topology/topology.css
b/karavan-space/src/topology/topology.css
index 1828bd1e..6edc633d 100644
--- a/karavan-space/src/topology/topology.css
+++ b/karavan-space/src/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