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 2023/12/07 02:37:08 UTC
(camel-karavan) 02/04: Preview fixes of new 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 9d503ba51812e6b5e702172fd08b355005326749
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Wed Dec 6 20:35:19 2023 -0500
Preview fixes of new Designer
---
karavan-designer/public/example/demo.camel.yaml | 26 +++-
karavan-designer/src/designer/DesignerStore.ts | 31 ++--
.../src/designer/route/DslConnections.tsx | 170 ++++++++++++---------
.../src/designer/route/RouteDesigner.tsx | 6 +-
.../src/designer/route/element/DslElement.css | 19 +--
.../src/designer/route/element/DslElement.tsx | 55 ++-----
.../designer/route/element/DslElementHeader.tsx | 42 +----
.../src/designer/route/useRouteDesignerHook.tsx | 2 +-
karavan-designer/src/designer/utils/EventBus.ts | 11 +-
9 files changed, 175 insertions(+), 187 deletions(-)
diff --git a/karavan-designer/public/example/demo.camel.yaml b/karavan-designer/public/example/demo.camel.yaml
index ccd98241..1bc2b8ae 100644
--- a/karavan-designer/public/example/demo.camel.yaml
+++ b/karavan-designer/public/example/demo.camel.yaml
@@ -25,6 +25,15 @@
- to:
uri: amqp
id: to-fbfe
+ - choice:
+ when:
+ - expression:
+ simple:
+ id: simple-e78b
+ id: when-b7d0
+ otherwise:
+ id: otherwise-40d0
+ id: choice-8f6b
otherwise:
id: otherwise-382c
steps:
@@ -38,12 +47,6 @@
- to:
uri: kamelet:azure-cosmosdb-sink
id: to-1394
-- route:
- nodePrefixId: route-d10
- id: route-3ad9
- from:
- uri: kamelet:azure-storage-datalake-source
- id: from-1516
- route:
nodePrefixId: route-171
id: route-99f9
@@ -85,6 +88,15 @@
- log:
message: ${body}
id: log-77df
+ - choice:
+ when:
+ - expression:
+ simple:
+ id: simple-c7db
+ id: when-f058
+ otherwise:
+ id: otherwise-1e11
+ id: choice-8374
- wireTap:
id: wireTap-a25e
doFinally:
@@ -113,5 +125,7 @@
simple:
id: simple-f0dc
id: setBody-3c0c
+ - process:
+ id: process-6d06
- circuitBreaker:
id: circuitBreaker-4af8
diff --git a/karavan-designer/src/designer/DesignerStore.ts b/karavan-designer/src/designer/DesignerStore.ts
index f9bc38d1..815f0f68 100644
--- a/karavan-designer/src/designer/DesignerStore.ts
+++ b/karavan-designer/src/designer/DesignerStore.ts
@@ -120,9 +120,9 @@ interface ConnectionsState {
deleteStep: (uuid: string) => void;
clearSteps: () => void;
setSteps: (steps: Map<string, DslPosition>) => void;
- buttons: ButtonPosition[];
- addButton: (button: ButtonPosition) => void;
- deleteButton: (button: ButtonPosition) => void;
+ buttons: Map<string, ButtonPosition>;
+ addButton: (uuid: string, button: ButtonPosition) => void;
+ deleteButton: (uuid: string) => void;
clearButtons: () => void;
}
@@ -152,27 +152,24 @@ export const useConnectionsStore = createWithEqualityFn<ConnectionsState>((set)
setSteps: (steps: Map<string, DslPosition>) => {
set({steps: steps})
},
- buttons: [],
- addButton: (button: ButtonPosition) => {
- set((state: ConnectionsState) => {
- const index = state.buttons.findIndex(b => b.uuid === button.uuid);
- if (index !== -1) {
- state.buttons.splice(index, 1);
- }
- state.buttons.push(button);
- return state;
- })
+ buttons: new Map<string, ButtonPosition>(),
+ addButton: (uuid: string, button: ButtonPosition) => {
+ set(state => ({
+ buttons: new Map(state.buttons).set(uuid, button),
+ }))
},
clearButtons: () => {
set((state: ConnectionsState) => {
- state.buttons.length = 0;
+ state.buttons.clear();
return state;
})
},
- deleteButton: (button: ButtonPosition) => {
+ deleteButton: (uuid: string) => {
set((state: ConnectionsState) => {
- const index = state.buttons.findIndex(b => b.uuid === button.uuid);
- state.buttons.splice(index, 1);
+ Array.from(state.buttons.entries())
+ .filter(value => value[1].uuid !== uuid)
+ .forEach(value => state.buttons.set(value[0], value[1]));
+ state.buttons.delete(uuid)
return state;
})
},
diff --git a/karavan-designer/src/designer/route/DslConnections.tsx b/karavan-designer/src/designer/route/DslConnections.tsx
index a4eef251..934fd89c 100644
--- a/karavan-designer/src/designer/route/DslConnections.tsx
+++ b/karavan-designer/src/designer/route/DslConnections.tsx
@@ -14,15 +14,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import React, {useEffect} from 'react';
+import React, {JSX, useEffect} from 'react';
import '../karavan.css';
-import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition";
import {ButtonPosition, DslPosition, EventBus} from "../utils/EventBus";
import {CamelUi} from "../utils/CamelUi";
import {useConnectionsStore, useDesignerStore, useIntegrationStore} from "../DesignerStore";
import {shallow} from "zustand/shallow";
import {CamelDefinitionApiExt} from "karavan-core/lib/api/CamelDefinitionApiExt";
import {TopologyUtils} from "karavan-core/lib/api/TopologyUtils";
+import {CamelElement} from "../../../../karavan-core/lib/model/IntegrationDefinition";
const overlapGap: number = 40;
@@ -45,15 +45,17 @@ export function DslConnections() {
});
useEffect(() => {
- const toDelete: string[] = Array.from(steps.keys()).filter(k => CamelDefinitionApiExt.findElementInIntegration(integration, k) === undefined);
- toDelete.forEach(key => deleteStep(key));
+ const toDelete1: string[] = Array.from(steps.keys()).filter(k => CamelDefinitionApiExt.findElementInIntegration(integration, k) === undefined);
+ toDelete1.forEach(key => deleteStep(key));
+ const toDelete2: string[] = Array.from(buttons.keys()).filter(k => CamelDefinitionApiExt.findElementInIntegration(integration, k) === undefined);
+ toDelete2.forEach(key => deleteButton(key));
}, [integration]);
function setButtonPosition(btn: ButtonPosition) {
if (btn.command === "add") {
- addButton(btn);
+ addButton(btn.uuid, btn);
} else if (btn.command === "delete") {
- deleteButton(btn);
+ deleteButton(btn.uuid);
} else if (btn.command === "clean") {
clearButtons();
}
@@ -103,8 +105,6 @@ export function DslConnections() {
return (
<g key={pos.step.uuid + "-incoming"}>
<circle cx={incomingX} cy={fromY} r={r} className="circle-incoming"/>
- {/*<image x={imageX} y={imageY} href={CamelUi.getConnectionIconString(pos.step)} className="icon"/>*/}
- {/*<text x={imageX - 5} y={imageY + 40} className="caption" textAnchor="start">{CamelUi.getTitle(pos.step)}</text>*/}
<path d={`M ${lineX1},${lineY1} C ${lineX1},${lineY2} ${lineX2},${lineY1} ${lineX2},${lineY2}`}
className="path-incoming" markerEnd="url(#arrowhead)"/>
</g>
@@ -189,8 +189,6 @@ export function DslConnections() {
return (
<g key={pos.step.uuid + "-outgoing"}>
<circle cx={outgoingX} cy={outgoingY} r={r} className="circle-outgoing"/>
- {/*<image x={imageX} y={imageY} href={image} className="icon"/>*/}
- {/*<text x={imageX + 25} y={imageY + 40} className="caption" textAnchor="end">{CamelUi.getOutgoingTitle(pos.step)}</text>*/}
<path
d={`M ${lineX1},${lineY1} C ${lineXi - 20}, ${lineY1} ${lineX1 - 15},${lineYi} ${lineXi},${lineYi} L ${lineX2},${lineY2}`}
className="path-incoming" markerEnd="url(#arrowhead)"/>
@@ -226,79 +224,105 @@ export function DslConnections() {
)
}
- function hasSteps(step: CamelElement): boolean {
- return (step.hasSteps() && !['FromDefinition'].includes(step.dslName))
- || ['RouteDefinition', 'TryDefinition', 'ChoiceDefinition', 'SwitchDefinition'].includes(step.dslName);
+ function getNext(pos: DslPosition): CamelElement | undefined {
+ if (pos.nextstep) {
+ return pos.nextstep;
+ } else if (pos.parent) {
+ const parent = steps.get(pos.parent.uuid);
+ if (parent) return getNext(parent);
+ }
+ }
+
+ function isSpecial(pos: DslPosition): boolean {
+ return ['ChoiceDefinition', 'MulticastDefinition', 'TryDefinition'].includes(pos.step.dslName);
}
- function getPreviousStep(pos: DslPosition) {
- return Array.from(steps.values())
- .filter(p => pos.parent?.uuid === p.parent?.uuid)
- .filter(p => p.inSteps)
- .filter(p => p.position === pos.position - 1)[0];
+ function addArrowToList(list: JSX.Element[], from?: DslPosition, to?: DslPosition, fromHeader?: boolean, toHeader?: boolean): JSX.Element[] {
+ const result: JSX.Element[] = [...list];
+ if (from && to) {
+ const rect1 = fromHeader === true ? from.headerRect : from.rect;
+ const rect2 = toHeader === true ? to.headerRect : to.rect;
+ result.push(getComplexArrow(from.step.uuid + "->" + to.step.uuid, rect1, rect2, toHeader === true));
+ }
+ return result;
}
- function getArrow(pos: DslPosition) {
- const endX = pos.headerRect.x + pos.headerRect.width / 2 - left;
- const endY = pos.headerRect.y - 9 - top;
- if (pos.parent) {
+ function getArrow(pos: DslPosition): JSX.Element[] {
+ const list: JSX.Element[] = [];
+
+ if (pos.parent && pos.parent.dslName === 'FromDefinition' && pos.position === 0) {
+ // const parent = steps.get(pos.parent.uuid);
+ // list.push(...addArrowToList(list, parent, pos, true, false))
+ } else if (pos.parent && pos.parent.dslName === 'TryDefinition' && pos.position === 0) {
+ const parent = steps.get(pos.parent.uuid);
+ list.push(...addArrowToList(list, parent, pos, true, false))
+ } else if (pos.parent && ['CatchDefinition', 'FinallyDefinition'].includes(pos.parent.dslName) && pos.position === 0) {
+ const parent = steps.get(pos.parent.uuid);
+ list.push(...addArrowToList(list, parent, pos, true, true))
+ } else if (pos.parent && pos.parent.dslName === 'MulticastDefinition') {
+ const parent = steps.get(pos.parent.uuid);
+ list.push(...addArrowToList(list, parent, pos, true, false))
+ if (parent?.nextstep) {
+ const to = steps.get(parent.nextstep.uuid);
+ list.push(...addArrowToList(list, pos, to, true, true))
+ }
+ } else if (pos.parent && pos.parent.dslName === 'ChoiceDefinition') {
const parent = steps.get(pos.parent.uuid);
- const showArrow = pos.prevStep !== undefined && !['TryDefinition', 'ChoiceDefinition'].includes(pos.prevStep.dslName);
- const name = pos.prevStep?.dslName;
- if (parent && showArrow) {
- if ((!pos.inSteps || (pos.inSteps && pos.position === 0)) && parent.step.dslName !== 'MulticastDefinition') {
- return getArrows(pos);
- } else if (parent.step.dslName === 'MulticastDefinition' && pos.inSteps) {
- return getArrows(pos)
- } else if (pos.inSteps && pos.position > 0 && !hasSteps(pos.step)) {
- const prev = getPreviousStep(pos);
- if (prev) {
- const r = hasSteps(prev.step) ? prev.rect : prev.headerRect;
- const prevX = r.x + r.width / 2 - left;
- const prevY = r.y + r.height - top;
- return (
- <line name={name} x1={prevX} y1={prevY} x2={endX} y2={endY} className="path"
- key={pos.step.uuid} markerEnd="url(#arrowhead)"/>
- )
- }
- } else if (pos.inSteps && pos.position > 0 && hasSteps(pos.step)) {
- const prev = getPreviousStep(pos);
- if (prev) {
- const r = hasSteps(prev.step) ? prev.rect : prev.headerRect;
- const prevX = r.x + r.width / 2 - left;
- const prevY = r.y + r.height - top;
- return (
- <line name={name} x1={prevX} y1={prevY} x2={endX} y2={endY} className="path"
- key={pos.step.uuid} markerEnd="url(#arrowhead)"/>
- )
- }
+ list.push(...addArrowToList(list, parent, pos, true, false))
+ } else if (pos.parent && ['WhenDefinition', 'OtherwiseDefinition', 'CatchDefinition', 'FinallyDefinition'].includes(pos.parent.dslName)) {
+ if (pos.position === 0) {
+ const parent = steps.get(pos.parent.uuid);
+ list.push(...addArrowToList(list, parent, pos, true, false))
+ }
+ if (pos.position === (pos.inStepsLength - 1) && !isSpecial(pos)) {
+ const nextElement = getNext(pos);
+ if (nextElement) {
+ const next = steps.get(nextElement.uuid);
+ list.push(...addArrowToList(list, pos, next, true, true))
}
}
+ } else if (pos.step && !isSpecial(pos)) {
+ if (pos.nextstep) {
+ const next = steps.get(pos.nextstep.uuid);
+ const fromHeader = !pos.step.hasSteps();
+ list.push(...addArrowToList(list, pos, next, fromHeader, true))
+ }
+ if (pos.step.hasSteps() && (pos.step as any).steps.length > 0) {
+ const firstStep = (pos.step as any).steps[0];
+ const next = steps.get(firstStep.uuid);
+ list.push(...addArrowToList(list, pos, next, true, true))
+ }
}
- }
- function getArrows(pos: DslPosition) {
- if (pos.parent) {
- const parent = steps.get(pos?.parent.uuid);
- if (parent) {
- const rect1 = parent.headerRect;
- const rect2 = pos.headerRect;
- return getComplexArrow(pos.step.uuid + ":" + pos.parent.uuid, rect1, rect2);
+ if (['WhenDefinition', 'OtherwiseDefinition'].includes(pos.step.dslName) && pos.step.hasSteps() && (pos.step as any).steps.length === 0) {
+ if (pos.nextstep) {
+ const to = steps.get(pos.nextstep.uuid);
+ list.push(...addArrowToList(list, pos, to, true, true))
+ } else {
+ const next = getNext(pos);
+ if (next) {
+ const to = steps.get(next.uuid);
+ list.push(...addArrowToList(list, pos, to, true, true))
+ }
}
}
- }
- function getButtonArrow(btn: ButtonPosition) {
- const rect1 = btn.rect;
- const uuid = btn.nextstep.uuid;
- const nextStep = steps.get(uuid);
- const rect2 = nextStep?.rect;
- if (rect1 && rect2) {
- return getComplexArrow(uuid + "-" + btn.nextstep.uuid, rect1, rect2);
+ if (pos.parent?.dslName === 'TryDefinition' && pos.inSteps && pos.position === (pos.inStepsLength - 1)) {
+ const parent = steps.get(pos.parent.uuid);
+ if (parent && parent.nextstep) {
+ const to = steps.get(parent.nextstep.uuid);
+ list.push(...addArrowToList(list, pos, to, true, true))
+ }
}
+
+ if (!isSpecial(pos) && pos.inSteps && pos.nextstep && !pos.step.hasSteps() && pos.parent?.dslName !== 'MulticastDefinition') {
+ const to = steps.get(pos.nextstep.uuid);
+ list.push(...addArrowToList(list, pos, to, true, true))
+ }
+ return list;
}
- function getComplexArrow(key: string, rect1: DOMRect, rect2: DOMRect) {
+ function getComplexArrow(key: string, rect1: DOMRect, rect2: DOMRect, toHeader: boolean) {
const startX = rect1.x + rect1.width / 2 - left;
const startY = rect1.y + rect1.height - top - 2;
const endX = rect2.x + rect2.width / 2 - left;
@@ -309,7 +333,7 @@ export function DslConnections() {
const radX = gapX > 30 ? 20 : gapX/2;
const radY = gapY > 30 ? 20 : gapY/2;
- const endY = rect2.y - top - 9 - radY;
+ const endY = rect2.y - top - radY - (toHeader ? 9 : 6);
const iRadX = startX > endX ? -1 * radX : radX;
const iRadY = startY > endY ? -1 * radY : radY;
@@ -336,7 +360,7 @@ export function DslConnections() {
+ ` L ${LX2} ${LY2}`
+ ` Q ${Q2_X1} ${Q2_Y1} ${Q2_X2} ${Q2_Y2}`
return (
- <path key={key} d={path} className="path" markerEnd="url(#arrowhead)"/>
+ <path key={key} name={key} d={path} className="path" markerEnd="url(#arrowhead)"/>
)
}
@@ -353,11 +377,11 @@ export function DslConnections() {
</marker>
</defs>
{stepsArray.map(pos => getCircle(pos))}
- {stepsArray.map(pos => getArrow(pos))}
- {buttons.map(btn => getButtonArrow(btn)).filter(b => b !== undefined)}
+ <g>
+ {stepsArray.map(pos => getArrow(pos)).flat(1)}
+ </g>
{getIncomings().map(p => getIncoming(p))}
{getOutgoings().map(p => getOutgoing(p))}
- {/*{getInternals().map((p) => getInternalLines(p)).flat()}*/}
</svg>
)
}
diff --git a/karavan-designer/src/designer/route/RouteDesigner.tsx b/karavan-designer/src/designer/route/RouteDesigner.tsx
index b6b1c942..b02ed20b 100644
--- a/karavan-designer/src/designer/route/RouteDesigner.tsx
+++ b/karavan-designer/src/designer/route/RouteDesigner.tsx
@@ -147,16 +147,17 @@ export function RouteDesigner() {
data-click="FLOWS"
onClick={event => {unselectElement(event)}}
ref={flowRef}>
- {routeConfigurations?.map((routeConfiguration, index: number) => (
+ {routeConfigurations?.map((routeConfiguration, index: number, array) => (
<DslElement key={routeConfiguration.uuid}
inSteps={false}
position={index}
step={routeConfiguration}
nextStep={undefined}
prevStep={undefined}
+ inStepsLength={array.length}
parent={undefined}/>
))}
- {routes?.map((route: any, index: number) => {
+ {routes?.map((route: any, index: number, array) => {
return (
<DslElement key={route.uuid}
inSteps={false}
@@ -164,6 +165,7 @@ export function RouteDesigner() {
step={route}
nextStep={undefined}
prevStep={undefined}
+ inStepsLength={array.length}
parent={undefined}/>
)
})}
diff --git a/karavan-designer/src/designer/route/element/DslElement.css b/karavan-designer/src/designer/route/element/DslElement.css
index 7af5bd51..61cc5af3 100644
--- a/karavan-designer/src/designer/route/element/DslElement.css
+++ b/karavan-designer/src/designer/route/element/DslElement.css
@@ -18,14 +18,19 @@
.karavan .dsl-page .flows .step-element .header-route {
display: block;
background: transparent;
- padding: 10px;
+ border-radius: 42px;
+ padding: 20px;
margin: 0;
z-index: 101;
min-width: 260px;
}
-.karavan .dsl-page .flows .step-element .header-bottom-line {
- border-bottom: 1px dashed;
+.karavan .dsl-page .flows .step-element .header-bottom-selected {
+ border-bottom: 1px dashed var(--step-border-color-selected);
+}
+
+.karavan .dsl-page .flows .step-element .header-bottom-not-selected {
+ border-bottom: 1px dashed var(--pf-v5-global--Color--200);
}
.karavan .dsl-page .flows .step-element .header-route:hover {
@@ -48,7 +53,7 @@
.karavan .step-element .header .delete-button,
.element-builder .header .delete-button {
position: absolute;
- top: -7px;
+ top: -11px;
line-height: 1;
border: 0;
padding: 0;
@@ -72,10 +77,6 @@
height: 50px;
}
-.karavan .step-element-selected {
- background-color: rgba(var(--pf-v5-global--palette--blue-50), 1);
-}
-
.karavan .step-element .selected .header-icon {
border-color: var(--pf-v5-global--primary-color--100);
background-color: var(--pf-v5-global--palette--blue-50);
@@ -152,7 +153,7 @@
.karavan .step-element .insert-element-button {
position: absolute;
- top: -7px;
+ top: -11px;
line-height: 1;
border: 0;
padding: 0;
diff --git a/karavan-designer/src/designer/route/element/DslElement.tsx b/karavan-designer/src/designer/route/element/DslElement.tsx
index a1b63a98..8f89a0f9 100644
--- a/karavan-designer/src/designer/route/element/DslElement.tsx
+++ b/karavan-designer/src/designer/route/element/DslElement.tsx
@@ -27,6 +27,7 @@ import {shallow} from "zustand/shallow";
import {useRouteDesignerHook} from "../useRouteDesignerHook";
import {AddElementIcon} from "./DslElementIcons";
import {DslElementHeader} from "./DslElementHeader";
+import {TryDefinition} from "karavan-core/lib/model/CamelDefinition";
interface Props {
step: CamelElement,
@@ -35,12 +36,12 @@ interface Props {
prevStep: CamelElement | undefined,
inSteps: boolean
position: number
+ inStepsLength: number
}
export function DslElement(props: Props) {
const headerRef = React.useRef<HTMLDivElement>(null);
- const addButtonRef = React.useRef<HTMLDivElement>(null);
const {
selectElement,
moveElement,
@@ -94,10 +95,6 @@ export function DslElement(props: Props) {
return selectedUuids.includes(props.step.uuid);
}
- function isElementHidden(): boolean {
- return props.step.dslName === 'LogDefinition' && hideLogDSL;
- }
-
function hasBorder(): boolean {
const step = props.step;
if (['FilterDefinition', 'RouteDefinition', 'RouteConfigurationDefinition'].includes(step.dslName)) {
@@ -106,6 +103,7 @@ export function DslElement(props: Props) {
if ([
'FromDefinition',
'TryDefinition',
+ 'MulticastDefinition',
'CatchDefinition', 'FinallyDefinition',
'ChoiceDefinition',
'SwitchDefinition', 'WhenDefinition', 'OtherwiseDefinition'
@@ -119,10 +117,6 @@ export function DslElement(props: Props) {
return ['FromDefinition', 'RouteConfigurationDefinition', 'RouteDefinition', 'WhenDefinition', 'OtherwiseDefinition'].includes(props.step.dslName);
}
- function isRoute(): boolean {
- return ['RouteDefinition'].includes(props.step.dslName);
- }
-
function isAddStepButtonLeft(): boolean {
return ['MulticastDefinition']
.includes(props.step.dslName);
@@ -139,28 +133,10 @@ export function DslElement(props: Props) {
return children.filter((c: ChildElement) => c.name === 'steps' || c.multiple).length > 0 && props.inSteps;
}
- function sendButtonPosition(el: HTMLButtonElement | null) {
- const {nextStep, step, parent} = props;
- let needArrow = !hasBorder() && !['ChoiceDefinition', 'MulticastDefinition', 'TryDefinition'].includes(step.dslName);
-
- if (parent
- && ['TryDefinition'].includes(parent.dslName)
- && !['CatchDefinition', 'FinallyDefinition'].includes(step.dslName)) {
- needArrow = true;
- }
-
- if (el && nextStep && needArrow) {
- const rect = headerRef.current?.getBoundingClientRect();
-
- if (rect)
- EventBus.sendButtonPosition("add", step.uuid, nextStep, rect);
- }
- }
function sendPosition(el: HTMLDivElement | null) {
- const {step, prevStep, parent} = props;
+ const {step, prevStep, nextStep, parent, inSteps, inStepsLength} = props;
const isSelected = isElementSelected();
- const isHidden = isElementHidden();
if (el) {
const header = Array.from(el.childNodes.values()).filter((n: any) => n.classList.contains("header"))[0];
if (header) {
@@ -168,13 +144,9 @@ export function DslElement(props: Props) {
const headerRect = headerIcon.getBoundingClientRect();
const rect = el.getBoundingClientRect();
if (step.showChildren) {
- if (isHidden) {
- EventBus.sendPosition("add", step, prevStep, parent, rect, headerRect, props.position, props.inSteps, isSelected);
- } else {
- EventBus.sendPosition("add", step, prevStep, parent, rect, headerRect, props.position, props.inSteps, isSelected);
- }
+ EventBus.sendPosition("add", step, prevStep, nextStep, parent, rect, headerRect, props.position, inStepsLength, inSteps, isSelected);
} else {
- EventBus.sendPosition("delete", step, prevStep, parent, new DOMRect(), new DOMRect(), 0);
+ EventBus.sendPosition("delete", step, prevStep, nextStep, parent, new DOMRect(), new DOMRect(), 0, 0);
}
}
}
@@ -190,7 +162,6 @@ export function DslElement(props: Props) {
function getChildrenElementsStyle(child: ChildElement, notOnlySteps: boolean) {
const style: CSSProperties = {
- // borderStyle: isBorder ? "dotted" : "none",
borderColor: "var(--step-border-color)",
borderWidth: "1px",
borderRadius: "16px",
@@ -229,10 +200,12 @@ export function DslElement(props: Props) {
return (
<div className={child.name + " has-child"} style={getChildrenElementsStyle(child, notOnlySteps)}
key={step.uuid + "-child-" + index}>
- {children.map((element, index) => {
+ {children.map((element, index, array) => {
let prevStep = children.at(index - 1);
let nextStep: CamelElement | undefined = undefined;
- if (['TryDefinition', 'ChoiceDefinition'].includes(step.dslName)) {
+ if ('ChoiceDefinition' === step.dslName) {
+ nextStep = props.nextStep;
+ } else if ('TryDefinition' === step.dslName && ['CatchDefinition', 'FinallyDefinition'].includes(element.dslName)) {
nextStep = props.nextStep;
} else {
nextStep = children.at(index + 1);
@@ -244,6 +217,7 @@ export function DslElement(props: Props) {
step={element}
nextStep={nextStep}
prevStep={prevStep}
+ inStepsLength={array.length}
parent={step}/>
</div>)
}
@@ -266,12 +240,10 @@ export function DslElement(props: Props) {
const hideAddButton = step.dslName === 'StepDefinition' && !CamelDisplayUtil.isStepDefinitionExpanded(integration, step.uuid, selectedUuids.at(0));
if (hideAddButton) return (<></>)
else return (
- <div ref={addButtonRef}>
- <Tooltip position={"bottom"}
+ <Tooltip position={"left"}
content={<div>{"Add step to " + CamelDisplayUtil.getTitle(step)}</div>}
>
<button type="button"
- ref={el => sendButtonPosition(el)}
aria-label="Add"
onClick={e => onOpenSelector(e)}
className={isAddStepButtonLeft() ? "add-button add-button-left" : "add-button add-button-bottom"}>
@@ -279,13 +251,12 @@ export function DslElement(props: Props) {
</button>
</Tooltip>
- </div>
)
}
const element: CamelElement = props.step;
const className = "step-element"
- + (isElementSelected() ? " step-element-selected" : "") + (!props.step.showChildren ? " hidden-step" : "")
+ + (!props.step.showChildren ? " hidden-step" : "")
+ ((element as any).disabled ? " disabled " : "");
return (
<div key={"root" + element.uuid}
diff --git a/karavan-designer/src/designer/route/element/DslElementHeader.tsx b/karavan-designer/src/designer/route/element/DslElementHeader.tsx
index 9ac4ab99..d201d105 100644
--- a/karavan-designer/src/designer/route/element/DslElementHeader.tsx
+++ b/karavan-designer/src/designer/route/element/DslElementHeader.tsx
@@ -20,7 +20,6 @@ import '../../karavan.css';
import './DslElement.css';
import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition";
import {CamelUi} from "../../utils/CamelUi";
-import {EventBus} from "../../utils/EventBus";
import {ChildElement, CamelDefinitionApiExt} from "karavan-core/lib/api/CamelDefinitionApiExt";
import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
import {CamelDisplayUtil} from "karavan-core/lib/api/CamelDisplayUtil";
@@ -28,11 +27,7 @@ import {useDesignerStore} from "../../DesignerStore";
import {shallow} from "zustand/shallow";
import {useRouteDesignerHook} from "../useRouteDesignerHook";
import {AddElementIcon, DeleteElementIcon, InsertElementIcon} from "./DslElementIcons";
-import {
- InterceptDefinition,
- InterceptFromDefinition,
- InterceptSendToEndpointDefinition, OnCompletionDefinition, OnExceptionDefinition, RouteConfigurationDefinition
-} from "karavan-core/lib/model/CamelDefinition";
+import { RouteConfigurationDefinition} from "karavan-core/lib/model/CamelDefinition";
interface Props {
headerRef: React.RefObject<HTMLDivElement>
@@ -79,12 +74,8 @@ export function DslElementHeader(props: Props) {
return selectedUuids.includes(props.step.uuid);
}
- function isElementHidden(): boolean {
- return props.step.dslName === 'LogDefinition' && hideLogDSL;
- }
-
function isWide(): boolean {
- return ['RouteConfigurationDefinition', 'RouteDefinition', 'ChoiceDefinition', 'SwitchDefinition', 'MulticastDefinition', 'TryDefinition', 'CircuitBreakerDefinition']
+ return ['RouteConfigurationDefinition', 'RouteDefinition', 'ChoiceDefinition', 'MulticastDefinition', 'TryDefinition', 'CircuitBreakerDefinition']
.includes(props.step.dslName);
}
@@ -129,29 +120,6 @@ export function DslElementHeader(props: Props) {
return style;
}
- function sendPosition(el: HTMLDivElement | null) {
- const {step, prevStep, parent} = props;
- const isSelected = isElementSelected();
- const isHidden = isElementHidden();
- if (el) {
- const header = Array.from(el.childNodes.values()).filter((n: any) => n.classList.contains("header"))[0];
- if (header) {
- const headerIcon: any = Array.from(header.childNodes.values()).filter((n: any) => n.classList.contains("header-icon"))[0];
- const headerRect = headerIcon.getBoundingClientRect();
- const rect = el.getBoundingClientRect();
- if (step.showChildren) {
- if (isHidden) {
- EventBus.sendPosition("add", step, prevStep, parent, rect, headerRect, props.position, props.inSteps, isSelected);
- } else {
- EventBus.sendPosition("add", step, prevStep, parent, rect, headerRect, props.position, props.inSteps, isSelected);
- }
- } else {
- EventBus.sendPosition("delete", step, prevStep, parent, new DOMRect(), new DOMRect(), 0);
- }
- }
- }
- }
-
function getAvailableModels() { // TODO: make static list-of-values instead
const step: CamelElement = props.step
return CamelUi.getSelectorModelsForParent(step.dslName, false);
@@ -174,10 +142,13 @@ export function DslElementHeader(props: Props) {
const classes: string[] = [];
const step: CamelElement = props.step;
if (step.dslName === 'RouteDefinition') {
- classes.push(...'header-route', 'header-bottom-line')
+ classes.push('header-route')
+ classes.push('header-bottom-line')
+ classes.push(isElementSelected() ? 'header-bottom-selected' : 'header-bottom-not-selected')
} else if (step.dslName === 'RouteConfigurationDefinition') {
classes.push('header-route')
if (hasElements(step)) classes.push('header-bottom-line')
+ classes.push(isElementSelected() ? 'header-bottom-selected' : 'header-bottom-not-selected')
} else {
classes.push('header')
}
@@ -200,7 +171,6 @@ export function DslElementHeader(props: Props) {
<div className={"dsl-element " + headerClasses} style={getHeaderStyle()} ref={props.headerRef}>
{!['RouteConfigurationDefinition', 'RouteDefinition'].includes(props.step.dslName) &&
<div
- ref={el => sendPosition(el)}
className={"header-icon"}
style={isWide() ? {width: ""} : {}}>
{CamelUi.getIconForElement(step)}
diff --git a/karavan-designer/src/designer/route/useRouteDesignerHook.tsx b/karavan-designer/src/designer/route/useRouteDesignerHook.tsx
index b65966a0..0f90bb10 100644
--- a/karavan-designer/src/designer/route/useRouteDesignerHook.tsx
+++ b/karavan-designer/src/designer/route/useRouteDesignerHook.tsx
@@ -105,7 +105,7 @@ export function useRouteDesignerHook () {
}
const deleteElement = () => {
- EventBus.sendPosition("clean", new CamelElement(""), undefined, undefined, new DOMRect(), new DOMRect(), 0);
+ EventBus.sendPosition("clean", new CamelElement(""), undefined,undefined, undefined, new DOMRect(), new DOMRect(), 0, 0);
EventBus.sendButtonPosition("clean", '', new CamelElement(""), new DOMRect());
let i = integration;
selectedUuids.forEach(uuidToDelete => {
diff --git a/karavan-designer/src/designer/utils/EventBus.ts b/karavan-designer/src/designer/utils/EventBus.ts
index 55906f0f..2d075b00 100644
--- a/karavan-designer/src/designer/utils/EventBus.ts
+++ b/karavan-designer/src/designer/utils/EventBus.ts
@@ -38,10 +38,12 @@ export class ButtonPosition {
export class DslPosition {
step: CamelElement = new CamelElement("");
prevStep: CamelElement | undefined;
+ nextstep: CamelElement | undefined;
parent: CamelElement | undefined;
inSteps: boolean = false;
isSelected: boolean = false;
position: number = 0;
+ inStepsLength: number = 0;
rect: DOMRect = new DOMRect();
headerRect: DOMRect = new DOMRect();
command: "add" | "delete" | "clean" = "add";
@@ -49,20 +51,24 @@ export class DslPosition {
constructor(command: "add" | "delete" | "clean",
step: CamelElement,
prevStep: CamelElement | undefined,
+ nextstep: CamelElement | undefined,
parent:CamelElement | undefined,
rect: DOMRect,
headerRect:DOMRect,
position: number,
+ inStepsLength: number,
inSteps: boolean = false,
isSelected: boolean = false) {
this.command = command;
this.step = step;
+ this.nextstep = nextstep;
this.prevStep = prevStep;
this.parent = parent;
this.rect = rect;
this.headerRect = headerRect;
this.inSteps = inSteps;
this.position = position;
+ this.inStepsLength = inStepsLength;
this.isSelected = isSelected;
}
}
@@ -110,12 +116,15 @@ export const EventBus = {
sendPosition: (command: "add" | "delete" | "clean",
step: CamelElement,
prevStep: CamelElement | undefined,
+ nextstep: CamelElement | undefined,
parent: CamelElement | undefined,
rect: DOMRect,
headerRect: DOMRect,
position: number,
+ inStepsLength: number,
inSteps: boolean = false,
- isSelected: boolean = false) => dslPositions.next(new DslPosition(command, step, prevStep, parent, rect, headerRect, position, inSteps, isSelected)),
+ isSelected: boolean = false) => dslPositions.next(
+ new DslPosition(command, step, prevStep, nextstep, parent, rect, headerRect, position, inStepsLength, inSteps, isSelected)),
onPosition: () => dslPositions.asObservable(),
sendButtonPosition: (command: "add" | "delete" | "clean", uuid: string,