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 2024/09/12 14:58:28 UTC
(camel-karavan) 01/16: Sync with designer
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 <ma...@talismancloud.io>
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