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/06 00:51:44 UTC

(camel-karavan) branch main updated (9db6f9b0 -> b660dd40)

This is an automated email from the ASF dual-hosted git repository.

marat pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git


    from 9db6f9b0 Fix #511
     new 61f801f6 Sync camel-catalog and yamsdslschema
     new b4fbb292 First example of new Designer #1012
     new 007a3538 Second example of new Designer #1012
     new b660dd40 Preview example of new Designer #1012

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 karavan-core/src/core/model/CamelDefinition.ts     |  66 ----
 karavan-designer/public/example/demo.camel.yaml    |  92 +++++
 karavan-designer/src/designer/DesignerStore.ts     |  30 +-
 karavan-designer/src/designer/karavan.css          | 409 +--------------------
 .../src/designer/route/DslConnections.tsx          | 301 ++++++---------
 karavan-designer/src/designer/route/DslElement.css |  18 -
 .../src/designer/route/DslProperties.css           | 250 +++++++++++++
 .../src/designer/route/DslProperties.tsx           |  21 +-
 .../src/designer/route/RouteDesigner.tsx           |  24 +-
 .../src/designer/route/element/DslElement.css      | 217 +++++++++++
 .../designer/route/{ => element}/DslElement.tsx    | 173 +++++----
 .../src/designer/route/element/DslElementIcons.tsx |  80 ++++
 .../route/{ => element}/DslElementMoveModal.tsx    |   6 +-
 .../src/designer/route/usePropertiesHook.tsx       |  11 +-
 .../src/designer/route/useRouteDesignerHook.tsx    |   3 +-
 karavan-designer/src/designer/utils/CamelUi.tsx    |  11 +-
 karavan-designer/src/designer/utils/EventBus.ts    |  32 +-
 .../camel/karavan/generator/AbstractGenerator.java |  49 +++
 .../generator/CamelDefinitionGenerator.java        |   4 +
 .../karavan/generator/CamelMetadataGenerator.java  |  13 -
 20 files changed, 1016 insertions(+), 794 deletions(-)
 delete mode 100644 karavan-designer/src/designer/route/DslElement.css
 create mode 100644 karavan-designer/src/designer/route/DslProperties.css
 create mode 100644 karavan-designer/src/designer/route/element/DslElement.css
 rename karavan-designer/src/designer/route/{ => element}/DslElement.tsx (79%)
 create mode 100644 karavan-designer/src/designer/route/element/DslElementIcons.tsx
 rename karavan-designer/src/designer/route/{ => element}/DslElementMoveModal.tsx (94%)


(camel-karavan) 01/04: Sync camel-catalog and yamsdslschema

Posted by ma...@apache.org.
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 61f801f6ea303023d3d731c64432ebc0f62f87d2
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Tue Dec 5 08:28:57 2023 -0500

    Sync camel-catalog and yamsdslschema
---
 karavan-core/src/core/model/CamelDefinition.ts     | 66 ----------------------
 .../camel/karavan/generator/AbstractGenerator.java | 49 ++++++++++++++++
 .../generator/CamelDefinitionGenerator.java        |  4 ++
 .../karavan/generator/CamelMetadataGenerator.java  | 13 -----
 4 files changed, 53 insertions(+), 79 deletions(-)

diff --git a/karavan-core/src/core/model/CamelDefinition.ts b/karavan-core/src/core/model/CamelDefinition.ts
index cb0de8c7..8a8e121e 100644
--- a/karavan-core/src/core/model/CamelDefinition.ts
+++ b/karavan-core/src/core/model/CamelDefinition.ts
@@ -154,7 +154,6 @@ export class AggregateDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'aggregate-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<AggregateDefinition>) {
         super('AggregateDefinition');
@@ -171,7 +170,6 @@ export class BeanDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'bean-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<BeanDefinition>) {
         super('BeanDefinition');
         Object.assign(this, init);
@@ -185,7 +183,6 @@ export class CatchDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'doCatch-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<CatchDefinition>) {
         super('CatchDefinition');
@@ -201,7 +198,6 @@ export class ChoiceDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'choice-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<ChoiceDefinition>) {
         super('ChoiceDefinition');
         Object.assign(this, init);
@@ -217,7 +213,6 @@ export class CircuitBreakerDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'circuitBreaker-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<CircuitBreakerDefinition>) {
         super('CircuitBreakerDefinition');
@@ -235,7 +230,6 @@ export class ClaimCheckDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'claimCheck-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<ClaimCheckDefinition>) {
         super('ClaimCheckDefinition');
         Object.assign(this, init);
@@ -261,7 +255,6 @@ export class ConvertBodyDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'convertBodyTo-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<ConvertBodyDefinition>) {
         super('ConvertBodyDefinition');
         Object.assign(this, init);
@@ -286,7 +279,6 @@ export class DelayDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'delay-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<DelayDefinition>) {
         super('DelayDefinition');
         Object.assign(this, init);
@@ -302,7 +294,6 @@ export class DynamicRouterDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'dynamicRouter-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<DynamicRouterDefinition>) {
         super('DynamicRouterDefinition');
         Object.assign(this, init);
@@ -323,7 +314,6 @@ export class EnrichDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'enrich-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<EnrichDefinition>) {
         super('EnrichDefinition');
         Object.assign(this, init);
@@ -404,7 +394,6 @@ export class FilterDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'filter-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<FilterDefinition>) {
         super('FilterDefinition');
@@ -417,7 +406,6 @@ export class FinallyDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'doFinally-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<FinallyDefinition>) {
         super('FinallyDefinition');
@@ -468,7 +456,6 @@ export class IdempotentConsumerDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'idempotentConsumer-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<IdempotentConsumerDefinition>) {
         super('IdempotentConsumerDefinition');
@@ -493,7 +480,6 @@ export class InterceptDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'intercept-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<InterceptDefinition>) {
         super('InterceptDefinition');
@@ -507,7 +493,6 @@ export class InterceptFromDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'interceptFrom-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<InterceptFromDefinition>) {
         super('InterceptFromDefinition');
@@ -523,7 +508,6 @@ export class InterceptSendToEndpointDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'interceptSendToEndpoint-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<InterceptSendToEndpointDefinition>) {
         super('InterceptSendToEndpointDefinition');
@@ -534,7 +518,6 @@ export class InterceptSendToEndpointDefinition extends CamelElement {
 export class KameletDefinition extends CamelElement {
     stepName?: string = 'kamelet';
     name: string = '';
-    inheritErrorHandler?: boolean;
     parameters?: any = {};
     public constructor(init?: Partial<KameletDefinition>) {
         super('KameletDefinition');
@@ -572,7 +555,6 @@ export class LogDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'log-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<LogDefinition>) {
         super('LogDefinition');
         Object.assign(this, init);
@@ -588,7 +570,6 @@ export class LoopDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'loop-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<LoopDefinition>) {
         super('LoopDefinition');
@@ -641,7 +622,6 @@ export class MarshalDefinition extends CamelElement {
     yaml?: YAMLDataFormat;
     zipDeflater?: ZipDeflaterDataFormat;
     zipFile?: ZipFileDataFormat;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<MarshalDefinition>) {
         super('MarshalDefinition');
         Object.assign(this, init);
@@ -665,7 +645,6 @@ export class MulticastDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'multicast-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<MulticastDefinition>) {
         super('MulticastDefinition');
@@ -685,7 +664,6 @@ export class OnCompletionDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'onCompletion-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<OnCompletionDefinition>) {
         super('OnCompletionDefinition');
@@ -709,7 +687,6 @@ export class OnExceptionDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'onException-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<OnExceptionDefinition>) {
         super('OnExceptionDefinition');
@@ -723,7 +700,6 @@ export class OnFallbackDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'onFallback-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<OnFallbackDefinition>) {
         super('OnFallbackDefinition');
@@ -749,7 +725,6 @@ export class OtherwiseDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'otherwise-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<OtherwiseDefinition>) {
         super('OtherwiseDefinition');
@@ -800,7 +775,6 @@ export class PausableDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'pausable-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<PausableDefinition>) {
         super('PausableDefinition');
         Object.assign(this, init);
@@ -812,7 +786,6 @@ export class PipelineDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'pipeline-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<PipelineDefinition>) {
         super('PipelineDefinition');
@@ -826,7 +799,6 @@ export class PolicyDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'policy-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<PolicyDefinition>) {
         super('PolicyDefinition');
@@ -847,7 +819,6 @@ export class PollEnrichDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'pollEnrich-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<PollEnrichDefinition>) {
         super('PollEnrichDefinition');
         Object.assign(this, init);
@@ -860,7 +831,6 @@ export class ProcessDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'process-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<ProcessDefinition>) {
         super('ProcessDefinition');
         Object.assign(this, init);
@@ -908,7 +878,6 @@ export class RecipientListDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'recipientList-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<RecipientListDefinition>) {
         super('RecipientListDefinition');
         Object.assign(this, init);
@@ -954,7 +923,6 @@ export class RemoveHeaderDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'removeHeader-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<RemoveHeaderDefinition>) {
         super('RemoveHeaderDefinition');
         Object.assign(this, init);
@@ -968,7 +936,6 @@ export class RemoveHeadersDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'removeHeaders-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<RemoveHeadersDefinition>) {
         super('RemoveHeadersDefinition');
         Object.assign(this, init);
@@ -982,7 +949,6 @@ export class RemovePropertiesDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'removeProperties-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<RemovePropertiesDefinition>) {
         super('RemovePropertiesDefinition');
         Object.assign(this, init);
@@ -995,7 +961,6 @@ export class RemovePropertyDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'removeProperty-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<RemovePropertyDefinition>) {
         super('RemovePropertyDefinition');
         Object.assign(this, init);
@@ -1008,7 +973,6 @@ export class ResequenceDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'resequence-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<ResequenceDefinition>) {
         super('ResequenceDefinition');
@@ -1062,7 +1026,6 @@ export class ResumableDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'resumable-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<ResumableDefinition>) {
         super('ResumableDefinition');
         Object.assign(this, init);
@@ -1077,7 +1040,6 @@ export class RollbackDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'rollback-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<RollbackDefinition>) {
         super('RollbackDefinition');
         Object.assign(this, init);
@@ -1144,8 +1106,6 @@ export class RouteDefinition extends CamelElement {
     from: FromDefinition = new FromDefinition();
     inputType?: InputTypeDefinition;
     outputType?: OutputTypeDefinition;
-    routePolicy?: string;
-    streamCaching?: boolean;
     public constructor(init?: Partial<RouteDefinition>) {
         super('RouteDefinition');
         Object.assign(this, init);
@@ -1201,7 +1161,6 @@ export class RoutingSlipDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'routingSlip-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<RoutingSlipDefinition>) {
         super('RoutingSlipDefinition');
         Object.assign(this, init);
@@ -1234,7 +1193,6 @@ export class SagaDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'saga-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<SagaDefinition>) {
         super('SagaDefinition');
@@ -1249,7 +1207,6 @@ export class SamplingDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'sample-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<SamplingDefinition>) {
         super('SamplingDefinition');
         Object.assign(this, init);
@@ -1262,7 +1219,6 @@ export class ScriptDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'script-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<ScriptDefinition>) {
         super('ScriptDefinition');
         Object.assign(this, init);
@@ -1275,7 +1231,6 @@ export class SetBodyDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'setBody-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<SetBodyDefinition>) {
         super('SetBodyDefinition');
         Object.assign(this, init);
@@ -1288,7 +1243,6 @@ export class SetExchangePatternDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'setExchangePattern-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<SetExchangePatternDefinition>) {
         super('SetExchangePatternDefinition');
         Object.assign(this, init);
@@ -1302,7 +1256,6 @@ export class SetHeaderDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'setHeader-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<SetHeaderDefinition>) {
         super('SetHeaderDefinition');
         Object.assign(this, init);
@@ -1316,7 +1269,6 @@ export class SetPropertyDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'setProperty-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<SetPropertyDefinition>) {
         super('SetPropertyDefinition');
         Object.assign(this, init);
@@ -1330,7 +1282,6 @@ export class SortDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'sort-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<SortDefinition>) {
         super('SortDefinition');
         Object.assign(this, init);
@@ -1356,7 +1307,6 @@ export class SplitDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'split-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<SplitDefinition>) {
         super('SplitDefinition');
@@ -1369,7 +1319,6 @@ export class StepDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'step-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<StepDefinition>) {
         super('StepDefinition');
@@ -1382,7 +1331,6 @@ export class StopDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'stop-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<StopDefinition>) {
         super('StopDefinition');
         Object.assign(this, init);
@@ -1459,7 +1407,6 @@ export class ThreadsDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'threads-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<ThreadsDefinition>) {
         super('ThreadsDefinition');
         Object.assign(this, init);
@@ -1478,7 +1425,6 @@ export class ThrottleDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'throttle-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<ThrottleDefinition>) {
         super('ThrottleDefinition');
         Object.assign(this, init);
@@ -1493,7 +1439,6 @@ export class ThrowExceptionDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'throwException-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<ThrowExceptionDefinition>) {
         super('ThrowExceptionDefinition');
         Object.assign(this, init);
@@ -1507,7 +1452,6 @@ export class ToDefinition extends CamelElement {
     pattern?: string;
     id?: string = 'to-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     parameters?: any = {};
     public constructor(init?: Partial<ToDefinition>) {
         super('ToDefinition');
@@ -1526,7 +1470,6 @@ export class ToDynamicDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'toD-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     parameters?: any = {};
     public constructor(init?: Partial<ToDynamicDefinition>) {
         super('ToDynamicDefinition');
@@ -1540,7 +1483,6 @@ export class TransactedDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'transacted-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<TransactedDefinition>) {
         super('TransactedDefinition');
@@ -1556,7 +1498,6 @@ export class TransformDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'transform-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<TransformDefinition>) {
         super('TransformDefinition');
         Object.assign(this, init);
@@ -1570,7 +1511,6 @@ export class TryDefinition extends CamelElement {
     description?: string;
     doCatch?: CatchDefinition[] = [];
     doFinally?: FinallyDefinition;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<TryDefinition>) {
         super('TryDefinition');
@@ -1584,7 +1524,6 @@ export class UnmarshalDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'unmarshal-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     asn1?: ASN1DataFormat | string;
     avro?: AvroDataFormat | string;
     barcode?: BarcodeDataFormat;
@@ -1638,7 +1577,6 @@ export class ValidateDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'validate-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<ValidateDefinition>) {
         super('ValidateDefinition');
         Object.assign(this, init);
@@ -1660,7 +1598,6 @@ export class WhenDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'when-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<WhenDefinition>) {
         super('WhenDefinition');
@@ -1674,7 +1611,6 @@ export class WhenSkipSendToEndpointDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'whenSkipSendToEndpoint-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     steps?: CamelElement[] = [];
     public constructor(init?: Partial<WhenSkipSendToEndpointDefinition>) {
         super('WhenSkipSendToEndpointDefinition');
@@ -1697,7 +1633,6 @@ export class WireTapDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'wireTap-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     parameters?: any = {};
     public constructor(init?: Partial<WireTapDefinition>) {
         super('WireTapDefinition');
@@ -1989,7 +1924,6 @@ export class ServiceCallDefinition extends CamelElement {
     disabled?: boolean;
     id?: string = 'serviceCall-' + uuidv4().substring(0,4);
     description?: string;
-    inheritErrorHandler?: boolean;
     public constructor(init?: Partial<ServiceCallDefinition>) {
         super('ServiceCallDefinition');
         Object.assign(this, init);
diff --git a/karavan-generator/src/main/java/org/apache/camel/karavan/generator/AbstractGenerator.java b/karavan-generator/src/main/java/org/apache/camel/karavan/generator/AbstractGenerator.java
index efb2ba4c..487c7f04 100644
--- a/karavan-generator/src/main/java/org/apache/camel/karavan/generator/AbstractGenerator.java
+++ b/karavan-generator/src/main/java/org/apache/camel/karavan/generator/AbstractGenerator.java
@@ -273,6 +273,22 @@ public class AbstractGenerator {
         return Arrays.stream(name.split(separator)).map(s -> capitalize(s)).collect(Collectors.joining());
     }
 
+    protected boolean excludeProperty(String stepName, String name, String attributeType) {
+        var hasModelInCatalog = hasModelInCatalog(stepName);
+        var hasInCatalog = hasPropertyInCatalogIgnoreCase(stepName, name);
+        if (hasModelInCatalog
+                && !hasInCatalog
+                && !attributeType.contains("[]")
+                && !attributeType.contains("{}")
+                && !attributeType.contains("Definition")
+                && !attributeType.contains("DataFormat")
+                && !attributeType.contains("FilterConfiguration")
+                && !attributeType.contains("Expression")) {
+            return true;
+        }
+        return false;
+    }
+
     protected String capitalize(String str) {
         return str.length() == 0 ? str
                 : str.length() == 1 ? str.toUpperCase()
@@ -296,6 +312,39 @@ public class AbstractGenerator {
         }
     }
 
+    protected String getPropertyTypeInCatalog(String model, String property) {
+        String json = getMetaModel(model);
+        if (json != null) {
+            JsonObject props = new JsonObject(json).getJsonObject("properties");
+            JsonObject values = props.getJsonObject(property);
+            return values != null ? values.getString("type") : null;
+        }
+        return null;
+    }
+
+    protected boolean hasPropertyInCatalog(String model, String property) {
+        String json = getMetaModel(model);
+        if (json != null) {
+            JsonObject props = new JsonObject(json).getJsonObject("properties");
+            return props.containsKey(property);
+        }
+        return false;
+    }
+
+    protected boolean hasPropertyInCatalogIgnoreCase(String model, String property) {
+        String json = getMetaModel(model);
+        if (json != null) {
+            JsonObject props = new JsonObject(json).getJsonObject("properties");
+            return props.getMap().keySet().stream().map(String::toLowerCase).anyMatch(k -> Objects.equals(k, property.toLowerCase()));
+        }
+        return false;
+    }
+
+    protected boolean hasModelInCatalog(String model) {
+        String json = getMetaModel(model);
+        return json != null;
+    }
+
     protected String getMetaDataFormat(String name) {
         try {
             InputStream inputStream = RouteBuilder.class.getResourceAsStream("/org/apache/camel/model/dataformat/" + name + ".json");
diff --git a/karavan-generator/src/main/java/org/apache/camel/karavan/generator/CamelDefinitionGenerator.java b/karavan-generator/src/main/java/org/apache/camel/karavan/generator/CamelDefinitionGenerator.java
index 4f60c2a8..08951974 100644
--- a/karavan-generator/src/main/java/org/apache/camel/karavan/generator/CamelDefinitionGenerator.java
+++ b/karavan-generator/src/main/java/org/apache/camel/karavan/generator/CamelDefinitionGenerator.java
@@ -81,11 +81,15 @@ public final class CamelDefinitionGenerator extends AbstractGenerator {
             String generatedValue = ("id".equals(name) && stepName != null && !"routeConfiguration".equals(stepName)) ? "'" + stepName + "-' + uuidv4().substring(0,4)" : null;
             String attributeType = getAttributeType(name, attributeValue, req, definitions, generatedValue);
 
+            var excludeProperty  = excludeProperty(stepName, name, attributeType);
+
             String r = req ? "" : "?";
             name = name.equals("constructor") ? "_constructor" : name; // exception for YAMLDataFormat
             if (className.equals("ChoiceDefinition") && name.equals("steps")) { // exception for ChoiceDefinition
             } else if (className.equals("SwitchDefinition") && name.equals("steps")) { // exception for SwitchDefinition
             } else if (className.equals("KameletDefinition") && name.equals("steps")) { // exception for KameletDefinition
+            } else if (excludeProperty) {
+
             } else if (!Objects.equals(attributeType, "null")) {
                 attrs.add("    " + name + r + ": " + attributeType);
             }
diff --git a/karavan-generator/src/main/java/org/apache/camel/karavan/generator/CamelMetadataGenerator.java b/karavan-generator/src/main/java/org/apache/camel/karavan/generator/CamelMetadataGenerator.java
index 27905581..6f0f75ec 100644
--- a/karavan-generator/src/main/java/org/apache/camel/karavan/generator/CamelMetadataGenerator.java
+++ b/karavan-generator/src/main/java/org/apache/camel/karavan/generator/CamelMetadataGenerator.java
@@ -192,9 +192,6 @@ public final class CamelMetadataGenerator extends AbstractGenerator {
                         String labels = p != null && p.containsKey("label") ? p.getString("label") : "";
                         String javaType = getJavaType(p);
                         Boolean placeholder = Objects.equals(typeInCatalog, "string") && !Objects.equals(typeInCatalog, pm.type);
-                        if (placeholder) {
-                            System.out.println(name + " " + pname  + " " + typeInCatalog);
-                        }
                         if (name.equals("ProcessDefinition") && pname.equals("ref")) javaType = "org.apache.camel.Processor"; // exception for processor
                         code.append(String.format(
                                 "        new PropertyMeta('%s', '%s', \"%s\", '%s', '%s', '%s', %b, %b, %b, %b, '%s', '%s', %b),\n",
@@ -208,16 +205,6 @@ public final class CamelMetadataGenerator extends AbstractGenerator {
         return code.toString();
     }
 
-    private String getPropertyTypeInCatalog(String model, String property) {
-        String json = getMetaModel(model);
-        if (json != null) {
-            JsonObject props = new JsonObject(json).getJsonObject("properties");
-            JsonObject values = props.getJsonObject(property);
-            return values != null ? values.getString("type") : null;
-        }
-        return null;
-    }
-
     private String getJavaType(JsonObject p) {
         if (p != null
                 && p.containsKey("type")


(camel-karavan) 04/04: Preview example of new Designer #1012

Posted by ma...@apache.org.
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 b660dd40e59796f588c4ffb9938783efbb036199
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Tue Dec 5 19:51:34 2023 -0500

    Preview example of new Designer #1012
---
 karavan-designer/src/designer/route/element/DslElement.css | 13 +++++--------
 karavan-designer/src/designer/utils/CamelUi.tsx            |  2 +-
 2 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/karavan-designer/src/designer/route/element/DslElement.css b/karavan-designer/src/designer/route/element/DslElement.css
index 8e04b5f7..3039f422 100644
--- a/karavan-designer/src/designer/route/element/DslElement.css
+++ b/karavan-designer/src/designer/route/element/DslElement.css
@@ -19,16 +19,16 @@
     display: block;
     border: none;
     background: transparent;
-    padding: 0px 0px 0px 0px;
-    margin-bottom: 10px;
-    min-width: 160px;
+    padding: 0;
+    margin: 3px 24px 10px 24px;
+    /*min-width: 260px;*/
     z-index: 101;
 }
 
 .karavan .step-element .header-route .delete-button {
     position: absolute;
-    top: 4px;
-    right: 4px;
+    top: 5px;
+    right: 5px;
     line-height: 1;
     border: 0;
     padding: 0;
@@ -51,8 +51,6 @@
     visibility: hidden;
 }
 
-/*.karavan .step-element:hover .delete-button,*/
-/*.karavan .step-element:hover .delete-button,*/
 .karavan .step-element .header:hover .delete-button,
 .karavan .step-element .header-route:hover .delete-button,
 .element-builder .header:hover .delete-button {
@@ -135,7 +133,6 @@
     top: 5px;
     left: 5px;
     font-size: 15px;
-    height: 24px;
     line-height: 1;
     border: 0;
     padding: 0;
diff --git a/karavan-designer/src/designer/utils/CamelUi.tsx b/karavan-designer/src/designer/utils/CamelUi.tsx
index 83476b1b..61a7d27c 100644
--- a/karavan-designer/src/designer/utils/CamelUi.tsx
+++ b/karavan-designer/src/designer/utils/CamelUi.tsx
@@ -337,7 +337,7 @@ export class CamelUi {
     static getElementTitle = (element: CamelElement): string => {
         if (element.dslName === 'RouteDefinition') {
             const routeId = (element as RouteDefinition).id
-            return routeId ? routeId : CamelUtil.capitalizeName((element as any).stepName);
+            return routeId ? "Route: " + routeId : CamelUtil.capitalizeName((element as any).stepName);
         } else if (['ToDefinition', 'ToDynamicDefinition', 'FromDefinition', 'KameletDefinition'].includes(element.dslName) && (element as any).uri) {
             const uri = (element as any).uri;
             const kameletTitle = uri && uri.startsWith("kamelet:") ? KameletApi.findKameletByUri(uri)?.title() : undefined;


(camel-karavan) 03/04: Second example of new Designer #1012

Posted by ma...@apache.org.
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 007a3538c74fec2c4d53f671cabedb59193f49d5
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Tue Dec 5 19:33:54 2023 -0500

    Second example of new Designer #1012
---
 .../src/designer/route/DslConnections.tsx          | 33 +++++++++++++---------
 .../src/designer/route/element/DslElement.css      |  6 ++--
 .../src/designer/route/element/DslElement.tsx      | 14 ++++-----
 3 files changed, 29 insertions(+), 24 deletions(-)

diff --git a/karavan-designer/src/designer/route/DslConnections.tsx b/karavan-designer/src/designer/route/DslConnections.tsx
index 6bb318c2..5f9467b6 100644
--- a/karavan-designer/src/designer/route/DslConnections.tsx
+++ b/karavan-designer/src/designer/route/DslConnections.tsx
@@ -246,19 +246,10 @@ export function DslConnections() {
             const showArrow = pos.prevStep !== undefined && !['TryDefinition', 'ChoiceDefinition'].includes(pos.prevStep.dslName);
             const name = pos.prevStep?.dslName;
             if (parent && showArrow) {
-                const startX = parent.headerRect.x + parent.headerRect.width / 2 - left;
-                const startY = parent.headerRect.y + parent.headerRect.height - top;
                 if ((!pos.inSteps || (pos.inSteps && pos.position === 0)) && parent.step.dslName !== 'MulticastDefinition') {
-                    return (
-                        <path name={pos.step.dslName}
-                              d={`M ${startX},${startY} C ${startX},${endY} ${endX},${startY}   ${endX},${endY}`}
-                              className="path" key={pos.step.uuid} markerEnd="url(#arrowhead)"/>
-                    )
+                    return getArrows(pos);
                 } else if (parent.step.dslName === 'MulticastDefinition' && pos.inSteps) {
-                    return (
-                        <path d={`M ${startX},${startY} C ${startX},${endY} ${endX},${startY}   ${endX},${endY}`}
-                              name={name} className="path" key={pos.step.uuid} markerEnd="url(#arrowhead)"/>
-                    )
+                    return getArrows(pos)
                 } else if (pos.inSteps && pos.position > 0 && !hasSteps(pos.step)) {
                     const prev = getPreviousStep(pos);
                     if (prev) {
@@ -286,12 +277,28 @@ export function DslConnections() {
         }
     }
 
+    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, rect1, rect2);
+            }
+        }
+    }
+
     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, rect1, rect2);
+        }
+    }
+
+    function getComplexArrow(key: string, rect1: DOMRect, rect2: DOMRect) {
             const startX = rect1.x + rect1.width / 2 - left;
             const startY = rect1.y + rect1.height - top - 2;
             const endX = rect2.x + rect2.width / 2 - left;
@@ -328,11 +335,9 @@ export function DslConnections() {
                 + ` Q ${Q1_X1} ${Q1_Y1} ${Q1_X2} ${Q1_Y2}`
                 + ` L ${LX2} ${LY2}`
                 + ` Q ${Q2_X1} ${Q2_Y1} ${Q2_X2} ${Q2_Y2}`
-                // + ` L ${endX} ${endY}`;
             return (
-                <path key={btn.uuid} d={path} className="path" markerEnd="url(#arrowhead)"/>
+                <path key={key} d={path} className="path" markerEnd="url(#arrowhead)"/>
             )
-        }
     }
 
     function getSvg() {
diff --git a/karavan-designer/src/designer/route/element/DslElement.css b/karavan-designer/src/designer/route/element/DslElement.css
index 85f7b46a..8e04b5f7 100644
--- a/karavan-designer/src/designer/route/element/DslElement.css
+++ b/karavan-designer/src/designer/route/element/DslElement.css
@@ -41,7 +41,7 @@
 .karavan .step-element .header .delete-button,
 .element-builder .header .delete-button {
     position: absolute;
-    top: -8px;
+    top: -7px;
     line-height: 1;
     border: 0;
     padding: 0;
@@ -135,7 +135,7 @@
     top: 5px;
     left: 5px;
     font-size: 15px;
-    height: 15px;
+    height: 24px;
     line-height: 1;
     border: 0;
     padding: 0;
@@ -148,7 +148,7 @@
 
 .karavan .step-element .insert-element-button {
     position: absolute;
-    top: -8px;
+    top: -7px;
     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 ce780636..1deb46da 100644
--- a/karavan-designer/src/designer/route/element/DslElement.tsx
+++ b/karavan-designer/src/designer/route/element/DslElement.tsx
@@ -412,11 +412,10 @@ export function DslElement(props: Props) {
         const hideAddButton = step.dslName === 'StepDefinition' && !CamelDisplayUtil.isStepDefinitionExpanded(integration, step.uuid, selectedUuids.at(0));
         if (hideAddButton) return (<></>)
         else return (
-            <Tooltip position={"bottom"}
-                     content={<div>{nextStep?.dslName.replace("Definition", "")}</div>}
-                // content={<div>{"Add step to " + CamelDisplayUtil.getTitle(step)}</div>}
-            >
-                <div ref={addButtonRef}>
+            <div ref={addButtonRef}>
+                <Tooltip position={"bottom"}
+                         content={<div>{"Add step to " + CamelDisplayUtil.getTitle(step)}</div>}
+                >
                     <button type="button"
                             ref={el => sendButtonPosition(el)}
                             aria-label="Add"
@@ -424,8 +423,9 @@ export function DslElement(props: Props) {
                             className={isAddStepButtonLeft() ? "add-button add-button-left" : "add-button add-button-bottom"}>
                         <AddElementIcon/>
                     </button>
-                </div>
-            </Tooltip>
+
+                </Tooltip>
+            </div>
         )
     }
 


(camel-karavan) 02/04: First example of new Designer #1012

Posted by ma...@apache.org.
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 b4fbb2925156e811bcff97b1324ec8893d00dfef
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Tue Dec 5 19:07:19 2023 -0500

    First example of new Designer #1012
---
 karavan-designer/public/example/demo.camel.yaml    |  92 +++++
 karavan-designer/src/designer/DesignerStore.ts     |  30 +-
 karavan-designer/src/designer/karavan.css          | 409 +--------------------
 .../src/designer/route/DslConnections.tsx          | 280 +++++---------
 karavan-designer/src/designer/route/DslElement.css |  18 -
 .../src/designer/route/DslProperties.css           | 250 +++++++++++++
 .../src/designer/route/DslProperties.tsx           |  21 +-
 .../src/designer/route/RouteDesigner.tsx           |  24 +-
 .../src/designer/route/element/DslElement.css      | 220 +++++++++++
 .../designer/route/{ => element}/DslElement.tsx    | 169 +++++----
 .../src/designer/route/element/DslElementIcons.tsx |  80 ++++
 .../route/{ => element}/DslElementMoveModal.tsx    |   6 +-
 .../src/designer/route/usePropertiesHook.tsx       |  11 +-
 .../src/designer/route/useRouteDesignerHook.tsx    |   3 +-
 karavan-designer/src/designer/utils/CamelUi.tsx    |   9 +
 karavan-designer/src/designer/utils/EventBus.ts    |  32 +-
 16 files changed, 950 insertions(+), 704 deletions(-)

diff --git a/karavan-designer/public/example/demo.camel.yaml b/karavan-designer/public/example/demo.camel.yaml
index 56bd06fc..40e3c45b 100644
--- a/karavan-designer/public/example/demo.camel.yaml
+++ b/karavan-designer/public/example/demo.camel.yaml
@@ -4,3 +4,95 @@
     from:
       uri: timer
       id: from-cfa5
+      steps:
+        - choice:
+            when:
+              - expression:
+                  simple:
+                    id: simple-99bf
+                id: when-ab5e
+                steps:
+                  - to:
+                      uri: arangodb
+                      id: to-f70a
+                  - removeProperties:
+                      id: removeProperties-344a
+              - expression:
+                  simple:
+                    id: simple-d199
+                id: when-37cd
+                steps:
+                  - to:
+                      uri: amqp
+                      id: to-fbfe
+            otherwise:
+              id: otherwise-382c
+              steps:
+                - log:
+                    message: ${body}
+                    id: log-6831
+            id: choice-c1db
+        - multicast:
+            id: multicast-6a53
+            steps:
+              - log:
+                  message: ${body}
+                  id: log-799d
+              - log:
+                  message: ${body}
+                  id: log-fc8e
+              - log:
+                  message: ${body}
+                  id: log-1e42
+        - filter:
+            expression:
+              simple:
+                id: simple-7ff9
+            id: filter-8c99
+            steps:
+              - process:
+                  id: process-e1c1
+                  description: Call cutom java bean
+              - delay:
+                  expression:
+                    simple:
+                      id: simple-64a6
+                  id: delay-b1ec
+        - doTry:
+            id: doTry-46cd
+            doCatch:
+              - id: doCatch-c6e7
+                steps:
+                  - log:
+                      message: ${body}
+                      id: log-77df
+                  - wireTap:
+                      id: wireTap-a25e
+            doFinally:
+              id: doFinally-0a65
+              steps:
+                - log:
+                    message: ${body}
+                    id: log-f4fa
+                - log:
+                    message: ${body}
+                    id: log-cd30
+            steps:
+              - pollEnrich:
+                  expression:
+                    simple:
+                      id: simple-6181
+                  id: pollEnrich-a41b
+              - filter:
+                  expression:
+                    simple:
+                      id: simple-a69b
+                  id: filter-07cf
+                  steps:
+                    - setBody:
+                        expression:
+                          simple:
+                            id: simple-f0dc
+                        id: setBody-3c0c
+        - circuitBreaker:
+            id: circuitBreaker-4af8
diff --git a/karavan-designer/src/designer/DesignerStore.ts b/karavan-designer/src/designer/DesignerStore.ts
index 4831855f..f9bc38d1 100644
--- a/karavan-designer/src/designer/DesignerStore.ts
+++ b/karavan-designer/src/designer/DesignerStore.ts
@@ -16,7 +16,7 @@
  */
 
 import {CamelElement, Integration} from "karavan-core/lib/model/IntegrationDefinition";
-import {DslPosition, EventBus} from "./utils/EventBus";
+import {ButtonPosition, DslPosition, EventBus} from "./utils/EventBus";
 import {createWithEqualityFn} from "zustand/traditional";
 import {shallow} from "zustand/shallow";
 
@@ -120,6 +120,10 @@ interface ConnectionsState {
     deleteStep: (uuid: string) => void;
     clearSteps: () => void;
     setSteps: (steps: Map<string, DslPosition>) => void;
+    buttons: ButtonPosition[];
+    addButton: (button: ButtonPosition) => void;
+    deleteButton: (button: ButtonPosition) => void;
+    clearButtons: () => void;
 }
 
 export const useConnectionsStore = createWithEqualityFn<ConnectionsState>((set) => ({
@@ -148,6 +152,30 @@ 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;
+        })
+    },
+    clearButtons: () => {
+        set((state: ConnectionsState) => {
+            state.buttons.length = 0;
+            return state;
+        })
+    },
+    deleteButton: (button: ButtonPosition) => {
+        set((state: ConnectionsState) => {
+            const index = state.buttons.findIndex(b => b.uuid === button.uuid);
+            state.buttons.splice(index, 1);
+            return state;
+        })
+    },
 }), shallow)
 
 type DesignerState = {
diff --git a/karavan-designer/src/designer/karavan.css b/karavan-designer/src/designer/karavan.css
index 31aa866b..5e558152 100644
--- a/karavan-designer/src/designer/karavan.css
+++ b/karavan-designer/src/designer/karavan.css
@@ -355,241 +355,6 @@
     display: none;
 }
 
-.karavan .properties .headers {
-    grid-row-gap: 10px;
-    row-gap: 10px;
-    display: contents;
-}
-
-.karavan .properties .headers .top {
-    width: 100%;
-    display: flex;
-    flex-direction: row;
-}
-
-.karavan .properties .headers .top h1 {
-    width: 100%;
-    margin-top: auto;
-    margin-bottom: auto;
-}
-
-.karavan .properties .footer {
-    height: 100%;
-    display: contents;
-}
-
-.karavan .properties .pf-v5-c-form {
-    row-gap: 10px;
-}
-
-.karavan .properties .pf-v5-c-form__group-label {
-    padding-bottom: 3px;
-    display: flex;
-    justify-content: space-between;
-}
-
-.karavan .properties .pf-v5-c-form-control:focus-within {
-    --pf-v5-c-form-control--after--BorderBottomColor: var(--pf-v5-c-form-control--after--BorderBottomColor);
-    --pf-v5-c-form-control--after--BorderBottomWidth: var(--pf-v5-c-form-control--after--BorderBottomWidth);
-}
-
-.karavan .properties .pf-v5-c-select {
-    --pf-v5-c-select__toggle--FontSize: 14px;
-    --pf-v5-c-select__menu-item--FontSize: 14px;
-}
-
-.karavan .properties .input-group .pf-v5-c-text-input-group__text {
-    width: 100%;
-}
-
-.karavan .properties .input-group .pf-v5-c-chip-group,
-.karavan .properties .input-group .pf-v5-c-text-input-group__main,
-.karavan .properties .input-group .pf-v5-c-chip-group .pf-v5-c-chip-group__list,
-.karavan .properties .input-group .pf-v5-c-chip-group .pf-v5-c-chip-group__list .pf-v5-c-chip-group__list-item,
-.karavan .properties .input-group .pf-v5-c-chip-group .pf-v5-c-chip-group__main {
-    display: block;
-}
-
-.karavan .properties .input-group .pf-v5-c-chip-group {
-    margin-left: 0;
-}
-
-.karavan .properties .input-group .pf-v5-c-chip-group .pf-v5-c-chip .pf-v5-c-chip__text {
-    max-width: inherit;
-}
-
-.karavan .properties .input-group .pf-v5-c-chip-group .pf-v5-c-chip {
-    width: 100%;
-}
-
-.karavan .properties .input-group .pf-v5-c-text-input-group__utilities {
-    align-items: end;
-    margin-top: auto;
-}
-
-.karavan .properties .chip .pf-v5-c-button {
-    position: absolute;
-    right: 0;
-}
-
-.karavan .properties .expression-title {
-    font-size: 17px;
-    font-weight: bold;
-}
-
-.karavan .properties .text-area {
-    font-size: 13px;
-}
-
-.karavan .properties .pf-v5-c-select__menu-search {
-    padding: 0px 6px 6px 6px;
-}
-
-.karavan .properties .pf-v5-c-select__toggle-typeahead {
-    height: auto;
-}
-
-.karavan .properties .pf-v5-c-select__menu-item {
-    /*width: 280px;*/
-}
-
-.karavan .properties .pf-v5-c-select__menu-item-description {
-    overflow-wrap: anywhere;
-}
-
-.karavan .properties .number {
-    display: flex;
-    justify-content: space-between;
-}
-
-.karavan .properties .number .number-property {
-    width: 100%;
-}
-
-.karavan .properties .number .clear-button {
-    color: #b1b1b7;
-    --pf-v5-c-button--BorderRadius: var(--pf-v5-c-button--m-control--BorderRadius);
-    --pf-v5-c-button--disabled--BackgroundColor: var(--pf-v5-c-button--m-control--disabled--BackgroundColor);
-    --pf-v5-c-button--after--BorderWidth: var(--pf-v5-c-button--m-control--after--BorderWidth);
-    --pf-v5-c-button--after--BorderColor: var(--pf-v5-c-button--m-control--after--BorderTopColor) var(--pf-v5-c-button--m-control--after--BorderRightColor) var(--pf-v5-c-button--m-control--after--BorderBottomColor) var(--pf-v5-c-button--m-control--after--BorderLeftColor);
-    color: var(--pf-v5-c-button--m-control--Color);
-    background-color: var(--pf-v5-c-button--m-control--BackgroundColor);
-    padding-left: 5px;
-    padding-right: 5px;
-}
-
-.karavan .properties .help-button {
-    font-size: 12px;
-}
-
-.karavan .properties .component-selector {
-    border-width: var(--pf-v5-global--BorderWidth--sm);
-    border-top-color: var(--pf-v5-global--BorderColor--300);
-    border-right-color: var(--pf-v5-global--BorderColor--300);
-    border-bottom-color: var(--pf-v5-global--BorderColor--200);
-    border-left-color: var(--pf-v5-global--BorderColor--300);
-    border-style: solid;
-}
-
-.karavan .properties .object-value {
-    display: flex;
-    flex-direction: row;
-    margin-bottom: 3px;
-}
-
-.karavan .properties .object-key-value .object {
-    padding-top: 0;
-}
-
-.karavan .properties .object-value .delete-button {
-    margin: 0;
-    padding: 5px 3px 0px 6px;
-    height: 16px;
-    color: #909090;
-}
-
-.karavan .properties .object-key-value,
-.karavan .properties .object-key-value .object-field {
-    display: flex;
-    flex-direction: row;
-    gap: 3px;
-}
-
-.karavan .properties .object-key-value .delete-button {
-    margin: auto 0 22px 0;
-    padding: 0px 0px 0px 3px;
-    height: 16px;
-    color: #909090;
-}
-
-.karavan .properties .expression,
-.karavan .properties .object,
-.karavan .properties .dataformat,
-.karavan .properties .parameters {
-    padding-top: 6px;
-    padding-left: 16px;
-    row-gap: 6px;
-    display: grid;
-    width: 100%;
-}
-
-.karavan .properties .expression .pf-v5-c-form__group-label,
-.karavan .properties .object .pf-v5-c-form__group-label,
-.karavan .properties .dataformat .pf-v5-c-form__group-label,
-.karavan .properties .parameters .pf-v5-c-form__group-label {
-    font-weight: 100;
-}
-
-.karavan .properties .expression .pf-v5-c-form__group,
-.karavan .properties .object .pf-v5-c-form__group,
-.karavan .properties .dataformat .pf-v5-c-form__group,
-.karavan .properties .parameters .pf-v5-c-form__group {
-    margin-bottom: 10px;
-}
-
-.karavan .properties .expression .pf-v5-c-select__menu-wrapper,
-.karavan .properties .object .pf-v5-c-select__menu-wrapper,
-.karavan .properties .dataformat .pf-v5-c-select__menu-wrapper,
-.karavan .properties .parameters .pf-v5-c-select__menu-wrapper {
-    width: 350px;
-}
-
-.karavan .properties .change-button {
-    font-size: 15px;
-    height: 15px;
-    line-height: 1;
-    border: 0;
-    padding: 0;
-    margin: auto auto auto 6px;
-    background: transparent;
-}
-
-.karavan .properties .change-button svg {
-    margin-right: 6px;
-}
-
-.karavan .properties .add-button {
-    color: var(--pf-v5-global--active-color--100);
-}
-
-.karavan .properties .delete-button {
-    color: #909090;
-}
-
-.karavan .properties .pf-v5-c-expandable-section__toggle {
-    margin: 0;
-    padding: 0;
-}
-
-.karavan .properties .pf-v5-c-expandable-section__content {
-    margin: 0;
-}
-
-.karavan .properties .pf-v5-c-expandable-section__content p {
-    min-height: 6px;
-}
-
-
 /*Graph*/
 .karavan .dsl-page .graph {
     display: block;
@@ -691,7 +456,7 @@
     flex-direction: column;
     width: fit-content;
     border-color: var(--pf-v5-global--Color--200);
-    border-radius: 16px;
+    border-radius: 42px;
     border-width: 1px;
     min-width: 120px;
     padding: 3px 4px 4px 4px;
@@ -718,178 +483,6 @@
     gap: 6px;
 }
 
-.karavan .dsl-page .flows .step-element .header-route {
-    display: block;
-    border: none;
-    background: transparent;
-    padding: 0px 0px 0px 0px;
-    margin-bottom: 10px;
-    min-width: 160px;
-    z-index: 101;
-}
-
-.karavan .step-element .header-route .delete-button {
-    position: absolute;
-    top: 4px;
-    right: 4px;
-    line-height: 1;
-    border: 0;
-    padding: 0;
-    margin: 0;
-    background: transparent;
-    color: #909090;
-    visibility: hidden;
-}
-
-.karavan .step-element .header .delete-button,
-.element-builder .header .delete-button {
-    position: absolute;
-    top: -5px;
-    line-height: 1;
-    border: 0;
-    padding: 0;
-    margin: 0 0 0 10px;
-    background: transparent;
-    color: #909090;
-    visibility: hidden;
-}
-
-/*.karavan .step-element:hover .delete-button,*/
-/*.karavan .step-element:hover .delete-button,*/
-.karavan .step-element .header:hover .delete-button,
-.karavan .step-element .header-route:hover .delete-button,
-.element-builder .header:hover .delete-button {
-    visibility: visible;
-}
-
-.modal-delete {
-    width: 350px !important;
-}
-
-.karavan .step-element .header {
-    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);
-    border-width: 2px;
-}
-
-.karavan .step-element .header .header-text {
-    position: absolute;
-    top: 8px;
-    left: 0;
-    width: 100%;
-    display: flex;
-    flex-direction: row;
-}
-
-.karavan .step-element .header .spacer {
-    width: 50%
-}
-
-.karavan .step-element .header .text-bottom {
-    background-color: rgba(255, 255, 255, 0.5);
-}
-
-.karavan .step-element .header .text-right {
-    padding-left: 17px;
-    width: 50%;
-    text-align: start;
-}
-
-.karavan .step-element .header .header-text-required {
-    color: var(--pf-v5-global--danger-color--100);
-    font-weight: bold;
-}
-
-.karavan .step-element .header-icon {
-    border-color: var(--pf-v5-global--Color--200);
-    border-style: solid;
-    border-radius: 30px;
-    border-width: 1px;
-    background: white;
-    width: 30px;
-    height: 30px;
-    margin: auto;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-}
-
-.karavan .step-element .header .icon,
-.element-builder .header .icon {
-    height: 20px;
-    width: auto;
-    border: none;
-    -webkit-user-select: none;
-    -khtml-user-select: none;
-    -moz-user-select: none;
-    -o-user-select: none;
-    user-select: none;
-}
-
-.karavan .step-element .add-element-button {
-    top: 5px;
-    left: 5px;
-    font-size: 15px;
-    height: 15px;
-    line-height: 1;
-    border: 0;
-    padding: 0;
-    background: transparent;
-    color: var(--pf-v5-global--primary-color--100);
-    visibility: hidden;
-    z-index: 100;
-    position: absolute;
-}
-
-.karavan .step-element .insert-element-button {
-    position: absolute;
-    top: -5px;
-    line-height: 1;
-    border: 0;
-    padding: 0;
-    margin: 0 0 0 -25px;
-    background: transparent;
-    background: transparent;
-    color: var(--pf-v5-global--primary-color--100);
-    visibility: hidden;
-    z-index: 100;
-}
-
-.karavan .step-element .header:hover .insert-element-button {
-    visibility: visible;
-}
-
-.karavan .step-element .add-button-bottom {
-    position: relative;
-}
-
-.karavan .step-element .add-button-left {
-    position: absolute;
-    top: 4px;
-    left: 4px;
-}
-
-.karavan .step-element .add-button {
-    font-size: 15px;
-    height: 15px;
-    line-height: 1;
-    border: 0;
-    padding: 0;
-    margin: 0;
-    background: transparent;
-    color: var(--pf-v5-global--primary-color--100);
-    visibility: hidden;
-    z-index: 100;
-}
-
 .karavan .dsl-page .flows .hidden-step {
     display: none;
 }
diff --git a/karavan-designer/src/designer/route/DslConnections.tsx b/karavan-designer/src/designer/route/DslConnections.tsx
index a636339e..6bb318c2 100644
--- a/karavan-designer/src/designer/route/DslConnections.tsx
+++ b/karavan-designer/src/designer/route/DslConnections.tsx
@@ -17,9 +17,8 @@
 import React, {useEffect} from 'react';
 import '../karavan.css';
 import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition";
-import {DslPosition, EventBus} from "../utils/EventBus";
+import {ButtonPosition, DslPosition, EventBus} from "../utils/EventBus";
 import {CamelUi} from "../utils/CamelUi";
-import {SagaDefinition} from "karavan-core/lib/model/CamelDefinition";
 import {useConnectionsStore, useDesignerStore, useIntegrationStore} from "../DesignerStore";
 import {shallow} from "zustand/shallow";
 import {CamelDefinitionApiExt} from "karavan-core/lib/api/CamelDefinitionApiExt";
@@ -32,12 +31,16 @@ export function DslConnections() {
     const [integration] = useIntegrationStore((state) => [state.integration], shallow)
     const [width, height, top, left, hideLogDSL] = useDesignerStore((s) =>
         [s.width, s.height, s.top, s.left, s.hideLogDSL], shallow)
-    const [ steps, addStep, deleteStep, clearSteps] = useConnectionsStore((s) => [s.steps, s.addStep, s.deleteStep, s.clearSteps], shallow)
+    const [steps, addStep, deleteStep, clearSteps, buttons, addButton, clearButtons, deleteButton] =
+        useConnectionsStore((s) => [s.steps, s.addStep, s.deleteStep, s.clearSteps,
+            s.buttons, s.addButton, s.clearButtons, s.deleteButton], shallow)
 
     useEffect(() => {
-        const sub = EventBus.onPosition()?.subscribe((evt: DslPosition) => setPosition(evt));
+        const sub1 = EventBus.onPosition()?.subscribe((evt: DslPosition) => setPosition(evt));
+        const sub2 = EventBus.onButtonPosition()?.subscribe((btn: ButtonPosition) => setButtonPosition(btn));
         return () => {
-            sub?.unsubscribe();
+            sub1?.unsubscribe();
+            sub2?.unsubscribe();
         };
     });
 
@@ -46,14 +49,22 @@ export function DslConnections() {
         toDelete.forEach(key => deleteStep(key));
     }, [integration]);
 
+    function setButtonPosition(btn: ButtonPosition) {
+        if (btn.command === "add") {
+            addButton(btn);
+        } else if (btn.command === "delete") {
+            deleteButton(btn);
+        } else if (btn.command === "clean") {
+            clearButtons();
+        }
+    }
+
     function setPosition(evt: DslPosition) {
         if (evt.command === "add") {
             addStep(evt.step.uuid, evt);
-        }
-        else if (evt.command === "delete") {
+        } else if (evt.command === "delete") {
             deleteStep(evt.step.uuid);
-        }
-        else if (evt.command === "clean") {
+        } else if (evt.command === "clean") {
             clearSteps();
         }
     }
@@ -110,7 +121,8 @@ export function DslConnections() {
             const imageX = incomingX - r + 5;
             const imageY = fromY - r + 5;
             return (
-                <div key={pos.step.uuid + "-icon"} style={{display: "block", position: "absolute", top: imageY, left: imageX}}>
+                <div key={pos.step.uuid + "-icon"}
+                     style={{display: "block", position: "absolute", top: imageY, left: imageX}}>
                     {CamelUi.getConnectionIcon(pos.step)}
                 </div>
             )
@@ -174,16 +186,14 @@ export function DslConnections() {
             const lineXi = lineX1 + 40;
             const lineYi = lineY2;
 
-            let image = CamelUi.getConnectionIconString(pos.step);
-            const imageX = outgoingX - r + 5;
-            const imageY = outgoingY - r + 5;
             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)"/>
+                    <path
+                        d={`M ${lineX1},${lineY1} C ${lineXi - 20}, ${lineY1} ${lineX1 - 15},${lineYi} ${lineXi},${lineYi} L ${lineX2},${lineY2}`}
+                        className="path-incoming" markerEnd="url(#arrowhead)"/>
                 </g>
             )
         }
@@ -198,185 +208,25 @@ export function DslConnections() {
             const imageX = outgoingX - r + 5;
             const imageY = outgoingY - r + 5;
             return (
-                <div key={pos.step.uuid + "-icon"} style={{display: "block", position: "absolute", top: imageY, left: imageX}}>
+                <div key={pos.step.uuid + "-icon"}
+                     style={{display: "block", position: "absolute", top: imageY, left: imageX}}>
                     {CamelUi.getConnectionIcon(pos.step)}
                 </div>
             )
         }
     }
 
-    function getInternals(): [string, number, boolean][] {
-        const outgoingDefinitions = TopologyUtils.getOutgoingDefinitions();
-        let outs: [string, number, boolean][] = Array.from(steps.values())
-            .filter(pos => outgoingDefinitions.includes(pos.step.dslName) && TopologyUtils.hasInternalUri(pos.step))
-            .sort((pos1: DslPosition, pos2: DslPosition) => {
-                const y1 = pos1.headerRect.y + pos1.headerRect.height / 2;
-                const y2 = pos2.headerRect.y + pos2.headerRect.height / 2;
-                return y1 > y2 ? 1 : -1
-            })
-            .map(pos => [pos.step.uuid, pos.headerRect.y - top, pos.isSelected]);
-        return outs;
-    }
-
-    function getInternalLines(data: [string, number, boolean]) {
-        const pos = steps.get(data[0]);
-        const uri = (pos?.step as any).uri;
-        if (uri && uri.length && pos) {
-            const key = pos.step.uuid + "-outgoing"
-            const fromX = pos.headerRect.x + pos.headerRect.width / 2 - left;
-            const fromY = pos.headerRect.y + pos.headerRect.height / 2 - top;
-            const r = pos.headerRect.height / 2;
-            const className = (TopologyUtils.hasDirectUri(pos.step) ? "path-direct" : "path-seda") + (data[2] ? "-selected" : "");
-            return getInternalLine(uri, key, className, fromX, fromY, r, data[1]);
-        } else if (pos?.step.dslName === 'SagaDefinition'){
-            const saga = (pos?.step as SagaDefinition);
-            const fromX = pos.headerRect.x + pos.headerRect.width / 2 - left;
-            const fromY = pos.headerRect.y + pos.headerRect.height / 2 - top;
-            const r = pos.headerRect.height / 2;
-            const result:any[] = [];
-            if (saga.completion && (saga.completion.startsWith("direct") || saga.completion.startsWith("seda"))){
-                const key = pos.step.uuid + "-completion"
-                const className = saga.completion.startsWith("direct") ? "path-direct" : "path-seda";
-                result.push(getInternalLine(saga.completion, key, className, fromX, fromY, r, data[1]));
-            }
-            if (saga.compensation && (saga.compensation.startsWith("direct") || saga.compensation.startsWith("seda"))){
-                const key = pos.step.uuid + "-compensation"
-                const className = saga.compensation.startsWith("direct") ? "path-direct" : "path-seda";
-                result.push(getInternalLine(saga.compensation, key, className, fromX, fromY, r, data[1]));
-            }
-            return result;
-        }
-    }
-
-    function getInternalLine(uri: string, key: string, className: string, fromX: number, fromY: number, r: number, i: number) {
-        const target = Array.from(steps.values())
-            .filter(s => s.step.dslName === 'FromDefinition')
-            .filter(s => (s.step as any).uri && (s.step as any).uri === uri)[0];
-        if (target) {
-            const targetX = target.headerRect.x + target.headerRect.width / 2 - left;
-            const targetY = target.headerRect.y + target.headerRect.height / 2 - top;
-            const gap = 100;
-            const add = 0.2;
-
-            // right
-            if (targetX - fromX >= gap) {
-                const startX = fromX + r;
-                const startY = fromY;
-                const endX = targetX - r * 2 + 4;
-                const endY = targetY;
-
-                const coefX = 24 + (i * add);
-                const coefY = (targetY > fromY) ? 24 : -24;
-
-                const pointX1 = startX + coefX;
-                const pointY1 = startY;
-                const pointX2 = startX + coefX;
-                const pointY2 = startY + coefY;
-
-                const pointLX = pointX1;
-                const pointLY = targetY - coefY;
-
-                const pointX3 = pointLX;
-                const pointY3 = endY;
-                const pointX4 = pointLX + coefX;
-                const pointY4 = endY;
-
-                return getInternalPath(key, className, startX, startY, pointX1, pointY1, pointX2, pointY2, pointLX, pointLY, pointX3, pointY3, pointX4, pointY4, endX, endY);
-            } else if (targetX > fromX && targetX - fromX < gap) {
-                const startX = fromX - r;
-                const startY = fromY;
-                const endX = targetX - r * 2 + 4;
-                const endY = targetY;
-
-                const coefX = -24 - (i * add);
-                const coefY = (targetY > fromY) ? 24 : -24;
-
-                const pointX1 = startX + coefX;
-                const pointY1 = startY;
-                const pointX2 = startX + coefX;
-                const pointY2 = startY + coefY;
-
-                const pointLX = pointX1;
-                const pointLY = targetY - coefY;
-
-                const pointX3 = pointLX;
-                const pointY3 = endY;
-                const pointX4 = pointLX - coefX/2;
-                const pointY4 = endY;
-
-                return getInternalPath(key, className, startX, startY, pointX1, pointY1, pointX2, pointY2, pointLX, pointLY, pointX3, pointY3, pointX4, pointY4, endX, endY);
-            } else if (targetX <= fromX && fromX - targetX < gap) {
-                const startX = fromX + r;
-                const startY = fromY;
-                const endX = targetX + r * 2 - 4;
-                const endY = targetY;
-
-                const coefX = 24 + (i * add);
-                const coefY = (targetY > fromY) ? 24 : -24;
-
-                const pointX1 = startX + coefX;
-                const pointY1 = startY;
-                const pointX2 = startX + coefX;
-                const pointY2 = startY + coefY;
-
-                const pointLX = pointX1;
-                const pointLY = targetY - coefY;
-
-                const pointX3 = pointLX;
-                const pointY3 = endY;
-                const pointX4 = pointLX - coefX/2;
-                const pointY4 = endY;
-
-                return getInternalPath(key, className, startX, startY, pointX1, pointY1, pointX2, pointY2, pointLX, pointLY, pointX3, pointY3, pointX4, pointY4, endX, endY);
-            } else {
-                const startX = fromX - r;
-                const startY = fromY;
-                const endX = targetX + r * 2 - 4;
-                const endY = targetY;
-
-                const coefX = -24 - (i * add);
-                const coefY = (targetY > fromY) ? 24 : -24;
-
-                const pointX1 = startX + coefX;
-                const pointY1 = startY;
-                const pointX2 = startX + coefX;
-                const pointY2 = startY + coefY;
-
-                const pointLX = pointX1;
-                const pointLY = targetY - coefY;
-
-                const pointX3 = pointLX;
-                const pointY3 = endY;
-                const pointX4 = pointLX + coefX;
-                const pointY4 = endY;
-
-                return getInternalPath(key, className, startX, startY, pointX1, pointY1, pointX2, pointY2, pointLX, pointLY, pointX3, pointY3, pointX4, pointY4, endX, endY);
-            }
-        }
-    }
-
-    function getInternalPath(key: string, className: string, startX: number, startY: number, pointX1: number, pointY1: number, pointX2: number, pointY2: number, pointLX: number, pointLY: number,
-                    pointX3: number, pointY3: number, pointX4: number, pointY4: number, endX: number, endY: number) {
-        return (
-            <g key={key}>
-                <path d={`M ${startX} ${startY} 
-                        Q ${pointX1} ${pointY1} ${pointX2} ${pointY2} L ${pointLX},${pointLY}
-                        Q ${pointX3} ${pointY3} ${pointX4} ${pointY4} L ${endX},${endY}`}
-                      className={className} markerEnd="url(#arrowhead)"/>
-            </g>
-        )
-    }
-
     function getCircle(pos: DslPosition) {
         const cx = pos.headerRect.x + pos.headerRect.width / 2 - left;
         const cy = pos.headerRect.y + pos.headerRect.height / 2 - top;
         const r = pos.headerRect.height / 2;
         return (
-            <circle cx={cx} cy={cy} r={r} stroke="transparent" strokeWidth="3" fill="transparent" key={pos.step.uuid + "-circle"}/>
+            <circle cx={cx} cy={cy} r={r} stroke="transparent" strokeWidth="3" fill="transparent"
+                    key={pos.step.uuid + "-circle"}/>
         )
     }
 
-    function hasSteps  (step: CamelElement): boolean  {
+    function hasSteps(step: CamelElement): boolean {
         return (step.hasSteps() && !['FromDefinition'].includes(step.dslName))
             || ['RouteDefinition', 'TryDefinition', 'ChoiceDefinition', 'SwitchDefinition'].includes(step.dslName);
     }
@@ -393,18 +243,21 @@ export function DslConnections() {
         const endY = pos.headerRect.y - 9 - top;
         if (pos.parent) {
             const parent = steps.get(pos.parent.uuid);
-            if (parent) {
+            const showArrow = pos.prevStep !== undefined && !['TryDefinition', 'ChoiceDefinition'].includes(pos.prevStep.dslName);
+            const name = pos.prevStep?.dslName;
+            if (parent && showArrow) {
                 const startX = parent.headerRect.x + parent.headerRect.width / 2 - left;
                 const startY = parent.headerRect.y + parent.headerRect.height - top;
                 if ((!pos.inSteps || (pos.inSteps && pos.position === 0)) && parent.step.dslName !== 'MulticastDefinition') {
                     return (
-                        <path name={pos.step.dslName} d={`M ${startX},${startY} C ${startX},${endY} ${endX},${startY}   ${endX},${endY}`}
+                        <path name={pos.step.dslName}
+                              d={`M ${startX},${startY} C ${startX},${endY} ${endX},${startY}   ${endX},${endY}`}
                               className="path" key={pos.step.uuid} markerEnd="url(#arrowhead)"/>
                     )
                 } else if (parent.step.dslName === 'MulticastDefinition' && pos.inSteps) {
                     return (
                         <path d={`M ${startX},${startY} C ${startX},${endY} ${endX},${startY}   ${endX},${endY}`}
-                              className="path" key={pos.step.uuid} markerEnd="url(#arrowhead)"/>
+                              name={name} className="path" key={pos.step.uuid} markerEnd="url(#arrowhead)"/>
                     )
                 } else if (pos.inSteps && pos.position > 0 && !hasSteps(pos.step)) {
                     const prev = getPreviousStep(pos);
@@ -413,7 +266,8 @@ export function DslConnections() {
                         const prevX = r.x + r.width / 2 - left;
                         const prevY = r.y + r.height - top;
                         return (
-                            <line x1={prevX} y1={prevY} x2={endX} y2={endY} className="path" key={pos.step.uuid} markerEnd="url(#arrowhead)"/>
+                            <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)) {
@@ -423,7 +277,8 @@ export function DslConnections() {
                         const prevX = r.x + r.width / 2 - left;
                         const prevY = r.y + r.height - top;
                         return (
-                            <line x1={prevX} y1={prevY} x2={endX} y2={endY} className="path" key={pos.step.uuid} markerEnd="url(#arrowhead)"/>
+                            <line name={name} x1={prevX} y1={prevY} x2={endX} y2={endY} className="path"
+                                  key={pos.step.uuid} markerEnd="url(#arrowhead)"/>
                         )
                     }
                 }
@@ -431,6 +286,55 @@ export function DslConnections() {
         }
     }
 
+    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) {
+            const startX = rect1.x + rect1.width / 2 - left;
+            const startY = rect1.y + rect1.height - top - 2;
+            const endX = rect2.x + rect2.width / 2 - left;
+            const endTempY = rect2.y - top - 9;
+
+            const gapX = Math.abs(endX - startX);
+            const gapY = Math.abs(endTempY - startY);
+
+            const radX = gapX > 30 ? 20 : gapX/2;
+            const radY = gapY > 30 ? 20 : gapY/2;
+            const endY = rect2.y - top - 9 - radY;
+
+            const iRadX = startX > endX ? -1 * radX : radX;
+            const iRadY = startY > endY ? -1 * radY : radY;
+
+            const LX1 = startX;
+            const LY1 = endY - radY;
+
+            const Q1_X1 = startX;
+            const Q1_Y1 = LY1 + radY;
+            const Q1_X2 = startX + iRadX;
+            const Q1_Y2 = LY1 + radY;
+
+            const LX2 = startX + (endX - startX) - iRadX;
+            const LY2 = LY1 + radY;
+
+            const Q2_X1 = LX2 + iRadX;
+            const Q2_Y1 = endY;
+            const Q2_X2 = LX2 + iRadX;
+            const Q2_Y2 = endY + radY;
+
+            const path = `M ${startX} ${startY}`
+                + ` L ${LX1} ${LY1} `
+                + ` Q ${Q1_X1} ${Q1_Y1} ${Q1_X2} ${Q1_Y2}`
+                + ` L ${LX2} ${LY2}`
+                + ` Q ${Q2_X1} ${Q2_Y1} ${Q2_X2} ${Q2_Y2}`
+                // + ` L ${endX} ${endY}`;
+            return (
+                <path key={btn.uuid} d={path} className="path" markerEnd="url(#arrowhead)"/>
+            )
+        }
+    }
+
     function getSvg() {
         const stepsArray = Array.from(steps.values());
         return (
@@ -438,12 +342,14 @@ export function DslConnections() {
                 style={{width: width, height: height, position: "absolute", left: 0, top: 0}}
                 viewBox={"0 0 " + (width) + " " + (height)}>
                 <defs>
-                    <marker id="arrowhead" markerWidth="9" markerHeight="6" refX="0" refY="3" orient="auto" className="arrow">
+                    <marker id="arrowhead" markerWidth="9" markerHeight="6" refX="0" refY="3" orient="auto"
+                            className="arrow">
                         <polygon points="0 0, 9 3, 0 6"/>
                     </marker>
                 </defs>
                 {stepsArray.map(pos => getCircle(pos))}
                 {stepsArray.map(pos => getArrow(pos))}
+                {buttons.map(btn => getButtonArrow(btn)).filter(b => b !== undefined)}
                 {getIncomings().map(p => getIncoming(p))}
                 {getOutgoings().map(p => getOutgoing(p))}
                 {/*{getInternals().map((p) => getInternalLines(p)).flat()}*/}
@@ -452,7 +358,7 @@ export function DslConnections() {
     }
 
     return (
-        <div id="connections" className="connections" style={{ width: width, height: height}}>
+        <div id="connections" className="connections" style={{width: width, height: height}}>
             {getSvg()}
             {getIncomings().map(p => getIncomingIcons(p))}
             {getOutgoings().map(p => getOutgoingIcons(p))}
diff --git a/karavan-designer/src/designer/route/DslElement.css b/karavan-designer/src/designer/route/DslElement.css
deleted file mode 100644
index d3ed7177..00000000
--- a/karavan-designer/src/designer/route/DslElement.css
+++ /dev/null
@@ -1,18 +0,0 @@
-.disabled {
-    opacity: 0.5;
-}
-.menu-button {
-    position: absolute;
-    top: 26px;
-    line-height: 1;
-    border: 0;
-    padding: 0;
-    margin: 0 0 0 10px;
-    background: transparent;
-    color: var(--pf-v5-global--primary-color--100);
-    visibility: hidden;
-}
-
-.dsl-element:hover .menu-button {
-    visibility: visible;
-}
diff --git a/karavan-designer/src/designer/route/DslProperties.css b/karavan-designer/src/designer/route/DslProperties.css
new file mode 100644
index 00000000..7040fd40
--- /dev/null
+++ b/karavan-designer/src/designer/route/DslProperties.css
@@ -0,0 +1,250 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+.karavan .properties .headers {
+    grid-row-gap: 10px;
+    row-gap: 10px;
+    display: contents;
+}
+
+.karavan .properties .headers .top {
+    width: 100%;
+    display: flex;
+    flex-direction: row;
+}
+
+.karavan .properties .headers .top h1 {
+    width: 100%;
+    margin-top: auto;
+    margin-bottom: auto;
+}
+
+.karavan .properties .footer {
+    height: 100%;
+    display: contents;
+}
+
+.karavan .properties .pf-v5-c-form {
+    row-gap: 10px;
+}
+
+.karavan .properties .pf-v5-c-form__group-label {
+    padding-bottom: 3px;
+    display: flex;
+    justify-content: space-between;
+}
+
+.karavan .properties .pf-v5-c-form-control:focus-within {
+    --pf-v5-c-form-control--after--BorderBottomColor: var(--pf-v5-c-form-control--after--BorderBottomColor);
+    --pf-v5-c-form-control--after--BorderBottomWidth: var(--pf-v5-c-form-control--after--BorderBottomWidth);
+}
+
+.karavan .properties .pf-v5-c-select {
+    --pf-v5-c-select__toggle--FontSize: 14px;
+    --pf-v5-c-select__menu-item--FontSize: 14px;
+}
+
+.karavan .properties .input-group .pf-v5-c-text-input-group__text {
+    width: 100%;
+}
+
+.karavan .properties .input-group .pf-v5-c-chip-group,
+.karavan .properties .input-group .pf-v5-c-text-input-group__main,
+.karavan .properties .input-group .pf-v5-c-chip-group .pf-v5-c-chip-group__list,
+.karavan .properties .input-group .pf-v5-c-chip-group .pf-v5-c-chip-group__list .pf-v5-c-chip-group__list-item,
+.karavan .properties .input-group .pf-v5-c-chip-group .pf-v5-c-chip-group__main {
+    display: block;
+}
+
+.karavan .properties .input-group .pf-v5-c-chip-group {
+    margin-left: 0;
+}
+
+.karavan .properties .input-group .pf-v5-c-chip-group .pf-v5-c-chip .pf-v5-c-chip__text {
+    max-width: inherit;
+}
+
+.karavan .properties .input-group .pf-v5-c-chip-group .pf-v5-c-chip {
+    width: 100%;
+}
+
+.karavan .properties .input-group .pf-v5-c-text-input-group__utilities {
+    align-items: end;
+    margin-top: auto;
+}
+
+.karavan .properties .chip .pf-v5-c-button {
+    position: absolute;
+    right: 0;
+}
+
+.karavan .properties .expression-title {
+    font-size: 17px;
+    font-weight: bold;
+}
+
+.karavan .properties .text-area {
+    font-size: 13px;
+}
+
+.karavan .properties .pf-v5-c-select__menu-search {
+    padding: 0px 6px 6px 6px;
+}
+
+.karavan .properties .pf-v5-c-select__toggle-typeahead {
+    height: auto;
+}
+
+.karavan .properties .pf-v5-c-select__menu-item {
+    /*width: 280px;*/
+}
+
+.karavan .properties .pf-v5-c-select__menu-item-description {
+    overflow-wrap: anywhere;
+}
+
+.karavan .properties .number {
+    display: flex;
+    justify-content: space-between;
+}
+
+.karavan .properties .number .number-property {
+    width: 100%;
+}
+
+.karavan .properties .number .clear-button {
+    color: #b1b1b7;
+    --pf-v5-c-button--BorderRadius: var(--pf-v5-c-button--m-control--BorderRadius);
+    --pf-v5-c-button--disabled--BackgroundColor: var(--pf-v5-c-button--m-control--disabled--BackgroundColor);
+    --pf-v5-c-button--after--BorderWidth: var(--pf-v5-c-button--m-control--after--BorderWidth);
+    --pf-v5-c-button--after--BorderColor: var(--pf-v5-c-button--m-control--after--BorderTopColor) var(--pf-v5-c-button--m-control--after--BorderRightColor) var(--pf-v5-c-button--m-control--after--BorderBottomColor) var(--pf-v5-c-button--m-control--after--BorderLeftColor);
+    color: var(--pf-v5-c-button--m-control--Color);
+    background-color: var(--pf-v5-c-button--m-control--BackgroundColor);
+    padding-left: 5px;
+    padding-right: 5px;
+}
+
+.karavan .properties .help-button {
+    font-size: 12px;
+}
+
+.karavan .properties .component-selector {
+    border-width: var(--pf-v5-global--BorderWidth--sm);
+    border-top-color: var(--pf-v5-global--BorderColor--300);
+    border-right-color: var(--pf-v5-global--BorderColor--300);
+    border-bottom-color: var(--pf-v5-global--BorderColor--200);
+    border-left-color: var(--pf-v5-global--BorderColor--300);
+    border-style: solid;
+}
+
+.karavan .properties .object-value {
+    display: flex;
+    flex-direction: row;
+    margin-bottom: 3px;
+}
+
+.karavan .properties .object-key-value .object {
+    padding-top: 0;
+}
+
+.karavan .properties .object-value .delete-button {
+    margin: 0;
+    padding: 5px 3px 0px 6px;
+    height: 16px;
+    color: #909090;
+}
+
+.karavan .properties .object-key-value,
+.karavan .properties .object-key-value .object-field {
+    display: flex;
+    flex-direction: row;
+    gap: 3px;
+}
+
+.karavan .properties .object-key-value .delete-button {
+    margin: auto 0 22px 0;
+    padding: 0px 0px 0px 3px;
+    height: 16px;
+    color: #909090;
+}
+
+.karavan .properties .expression,
+.karavan .properties .object,
+.karavan .properties .dataformat,
+.karavan .properties .parameters {
+    padding-top: 6px;
+    padding-left: 16px;
+    row-gap: 6px;
+    display: grid;
+    width: 100%;
+}
+
+.karavan .properties .expression .pf-v5-c-form__group-label,
+.karavan .properties .object .pf-v5-c-form__group-label,
+.karavan .properties .dataformat .pf-v5-c-form__group-label,
+.karavan .properties .parameters .pf-v5-c-form__group-label {
+    font-weight: 100;
+}
+
+.karavan .properties .expression .pf-v5-c-form__group,
+.karavan .properties .object .pf-v5-c-form__group,
+.karavan .properties .dataformat .pf-v5-c-form__group,
+.karavan .properties .parameters .pf-v5-c-form__group {
+    margin-bottom: 10px;
+}
+
+.karavan .properties .expression .pf-v5-c-select__menu-wrapper,
+.karavan .properties .object .pf-v5-c-select__menu-wrapper,
+.karavan .properties .dataformat .pf-v5-c-select__menu-wrapper,
+.karavan .properties .parameters .pf-v5-c-select__menu-wrapper {
+    width: 350px;
+}
+
+.karavan .properties .change-button {
+    font-size: 15px;
+    height: 15px;
+    line-height: 1;
+    border: 0;
+    padding: 0;
+    margin: auto auto auto 6px;
+    background: transparent;
+}
+
+.karavan .properties .change-button svg {
+    margin-right: 6px;
+}
+
+.karavan .properties .add-button {
+    color: var(--pf-v5-global--active-color--100);
+}
+
+.karavan .properties .delete-button {
+    color: #909090;
+}
+
+.karavan .properties .pf-v5-c-expandable-section__toggle {
+    margin: 0;
+    padding: 0;
+}
+
+.karavan .properties .pf-v5-c-expandable-section__content {
+    margin: 0;
+}
+
+.karavan .properties .pf-v5-c-expandable-section__content p {
+    min-height: 6px;
+}
+
diff --git a/karavan-designer/src/designer/route/DslProperties.tsx b/karavan-designer/src/designer/route/DslProperties.tsx
index 8231759c..b958b2b3 100644
--- a/karavan-designer/src/designer/route/DslProperties.tsx
+++ b/karavan-designer/src/designer/route/DslProperties.tsx
@@ -22,6 +22,7 @@ import {
     TextVariants, ExpandableSection, Button, Tooltip,
 } from '@patternfly/react-core';
 import '../karavan.css';
+import './DslProperties.css';
 import "@patternfly/patternfly/patternfly.css";
 import {DataFormatField} from "./property/DataFormatField";
 import {DslPropertyField} from "./property/DslPropertyField";
@@ -30,6 +31,7 @@ import {CamelUi} from "../utils/CamelUi";
 import {CamelMetadataApi, DataFormats, PropertyMeta} from "karavan-core/lib/model/CamelMetadata";
 import {IntegrationHeader} from "../utils/IntegrationHeader";
 import CloneIcon from "@patternfly/react-icons/dist/esm/icons/clone-icon";
+import ConvertIcon from "@patternfly/react-icons/dist/esm/icons/optimize-icon";
 import {useDesignerStore, useIntegrationStore} from "../DesignerStore";
 import {shallow} from "zustand/shallow";
 import {usePropertiesHook} from "./usePropertiesHook";
@@ -43,7 +45,8 @@ export function DslProperties(props: Props) {
 
     const [integration] = useIntegrationStore((state) => [state.integration], shallow)
 
-    const {cloneElement, onDataFormatChange, onPropertyChange, onParametersChange, onExpressionChange} = usePropertiesHook(props.isRouteDesigner);
+    const {convertStep, cloneElement, onDataFormatChange, onPropertyChange, onParametersChange, onExpressionChange} =
+        usePropertiesHook(props.isRouteDesigner);
 
     const [selectedStep, dark] = useDesignerStore((s) => [s.selectedStep, s.dark], shallow)
 
@@ -54,10 +57,26 @@ export function DslProperties(props: Props) {
         const title = selectedStep && CamelDisplayUtil.getTitle(selectedStep)
         const description = selectedStep && CamelUi.getDescription(selectedStep);
         const descriptionLines: string [] = description ? description?.split("\n") : [""];
+        const targetDsl = CamelUi.getConvertTargetDsl(selectedStep?.dslName);
+        const targetDslTitle = targetDsl?.replace("Definition", "");
         return (
             <div className="headers">
                 <div className="top">
                     <Title headingLevel="h1" size="md">{title}</Title>
+                    {targetDsl &&
+                        <Button
+                            variant={"link"}
+                            icon={<ConvertIcon/>}
+                            iconPosition={"right"}
+                            onClick={event => {
+                                if (selectedStep) {
+                                    convertStep(selectedStep, targetDsl);
+                                }
+                            }}
+                        >
+                            Convert to {targetDslTitle}
+                        </Button>
+                    }
                 </div>
                 <Text component={TextVariants.p}>{descriptionLines.at(0)}</Text>
                 {descriptionLines.length > 1 &&
diff --git a/karavan-designer/src/designer/route/RouteDesigner.tsx b/karavan-designer/src/designer/route/RouteDesigner.tsx
index c57260db..b6b1c942 100644
--- a/karavan-designer/src/designer/route/RouteDesigner.tsx
+++ b/karavan-designer/src/designer/route/RouteDesigner.tsx
@@ -27,7 +27,7 @@ import {DslSelector} from "./DslSelector";
 import {DslProperties} from "./DslProperties";
 import {DslConnections} from "./DslConnections";
 import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
-import {DslElement} from "./DslElement";
+import {DslElement} from "./element/DslElement";
 import {CamelUi} from "../utils/CamelUi";
 import {useRouteDesignerHook} from "./useRouteDesignerHook";
 import {useConnectionsStore, useDesignerStore, useIntegrationStore, useSelectorStore} from "../DesignerStore";
@@ -36,7 +36,7 @@ import useResizeObserver from "./useResizeObserver";
 import {Command, EventBus} from "../utils/EventBus";
 import useMutationsObserver from "./useDrawerMutationsObserver";
 import {DeleteConfirmation} from "./DeleteConfirmation";
-import {DslElementMoveModal} from "./DslElementMoveModal";
+import {DslElementMoveModal} from "./element/DslElementMoveModal";
 
 export function RouteDesigner() {
 
@@ -152,15 +152,21 @@ export function RouteDesigner() {
                                     inSteps={false}
                                     position={index}
                                     step={routeConfiguration}
+                                    nextStep={undefined}
+                                    prevStep={undefined}
                                     parent={undefined}/>
                     ))}
-                    {routes?.map((route: any, index: number) => (
-                        <DslElement key={route.uuid}
-                                    inSteps={false}
-                                    position={index}
-                                    step={route}
-                                    parent={undefined}/>
-                    ))}
+                    {routes?.map((route: any, index: number) => {
+                        return (
+                            <DslElement key={route.uuid}
+                                        inSteps={false}
+                                        position={index}
+                                        step={route}
+                                        nextStep={undefined}
+                                        prevStep={undefined}
+                                        parent={undefined}/>
+                        )
+                    })}
                     {getGraphButtons()}
                 </div>
             </div>)
diff --git a/karavan-designer/src/designer/route/element/DslElement.css b/karavan-designer/src/designer/route/element/DslElement.css
new file mode 100644
index 00000000..85f7b46a
--- /dev/null
+++ b/karavan-designer/src/designer/route/element/DslElement.css
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.karavan .dsl-page .flows .step-element .header-route {
+    display: block;
+    border: none;
+    background: transparent;
+    padding: 0px 0px 0px 0px;
+    margin-bottom: 10px;
+    min-width: 160px;
+    z-index: 101;
+}
+
+.karavan .step-element .header-route .delete-button {
+    position: absolute;
+    top: 4px;
+    right: 4px;
+    line-height: 1;
+    border: 0;
+    padding: 0;
+    margin: 0;
+    background: transparent;
+    color: #909090;
+    visibility: hidden;
+}
+
+.karavan .step-element .header .delete-button,
+.element-builder .header .delete-button {
+    position: absolute;
+    top: -8px;
+    line-height: 1;
+    border: 0;
+    padding: 0;
+    margin: 0 0 0 10px;
+    background: transparent;
+    color: #909090;
+    visibility: hidden;
+}
+
+/*.karavan .step-element:hover .delete-button,*/
+/*.karavan .step-element:hover .delete-button,*/
+.karavan .step-element .header:hover .delete-button,
+.karavan .step-element .header-route:hover .delete-button,
+.element-builder .header:hover .delete-button {
+    visibility: visible;
+}
+
+.modal-delete {
+    width: 350px !important;
+}
+
+.karavan .step-element .header {
+    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);
+    border-width: 2px;
+}
+
+.karavan .step-element .header .header-text {
+    position: absolute;
+    top: 8px;
+    left: 0;
+    width: 100%;
+    display: flex;
+    flex-direction: row;
+}
+
+.karavan .step-element .header .spacer {
+    width: 50%
+}
+
+.karavan .step-element .header .text-bottom {
+    background-color: rgba(255, 255, 255, 0.5);
+}
+
+.karavan .step-element .header .text-right {
+    padding-left: 17px;
+    width: 50%;
+    text-align: start;
+}
+
+.karavan .step-element .header .header-text-required {
+    color: var(--pf-v5-global--danger-color--100);
+    font-weight: bold;
+}
+
+.karavan .step-element .header-icon {
+    border-color: var(--pf-v5-global--Color--200);
+    border-style: solid;
+    border-radius: 30px;
+    border-width: 1px;
+    background: white;
+    width: 30px;
+    height: 30px;
+    margin: auto;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+.karavan .step-element .header .icon,
+.element-builder .header .icon {
+    height: 20px;
+    width: auto;
+    border: none;
+    -webkit-user-select: none;
+    -khtml-user-select: none;
+    -moz-user-select: none;
+    -o-user-select: none;
+    user-select: none;
+}
+
+.karavan .step-element .add-element-button {
+    top: 5px;
+    left: 5px;
+    font-size: 15px;
+    height: 15px;
+    line-height: 1;
+    border: 0;
+    padding: 0;
+    background: transparent;
+    color: var(--pf-v5-global--primary-color--100);
+    visibility: hidden;
+    z-index: 100;
+    position: absolute;
+}
+
+.karavan .step-element .insert-element-button {
+    position: absolute;
+    top: -8px;
+    line-height: 1;
+    border: 0;
+    padding: 0;
+    margin: 0 0 0 -30px;
+    background: transparent;
+    color: var(--pf-v5-global--primary-color--100);
+    visibility: hidden;
+    z-index: 100;
+}
+
+.karavan .step-element .header:hover .insert-element-button {
+    visibility: visible;
+}
+
+.karavan .step-element .add-button-bottom {
+    position: relative;
+}
+
+.karavan .step-element .add-button-left {
+    position: absolute;
+    top: 4px;
+    left: 4px;
+}
+
+.karavan .step-element .add-button {
+    font-size: 15px;
+    height: 15px;
+    line-height: 1;
+    border: 0;
+    padding: 0;
+    margin: 0;
+    background: transparent;
+    color: var(--pf-v5-global--primary-color--100);
+    visibility: hidden;
+    z-index: 100;
+}
+
+.disabled {
+    opacity: 0.5;
+}
+.menu-button {
+    position: absolute;
+    top: 26px;
+    line-height: 1;
+    border: 0;
+    padding: 0;
+    margin: 0 0 0 10px;
+    background: transparent;
+    color: var(--pf-v5-global--primary-color--100);
+    visibility: hidden;
+}
+
+.dsl-element:hover .menu-button {
+    visibility: visible;
+}
+
+.add-button-icon, .insert-button-icon {
+    fill: var(--pf-v5-global--primary-color--100);
+    width: 20px;
+    height: 20px;
+    background: white;
+}
+
+.delete-button-icon {
+    fill: var(--pf-v5-global--danger-color--100);
+    width: 20px;
+    height: 20px;
+    background: white;
+}
\ No newline at end of file
diff --git a/karavan-designer/src/designer/route/DslElement.tsx b/karavan-designer/src/designer/route/element/DslElement.tsx
similarity index 79%
rename from karavan-designer/src/designer/route/DslElement.tsx
rename to karavan-designer/src/designer/route/element/DslElement.tsx
index e3dfdbfc..ce780636 100644
--- a/karavan-designer/src/designer/route/DslElement.tsx
+++ b/karavan-designer/src/designer/route/element/DslElement.tsx
@@ -15,27 +15,25 @@
  * limitations under the License.
  */
 import React, {CSSProperties, useMemo, useState} from 'react';
-import {Menu, MenuContent, MenuItem, MenuList, Popover, Text, Tooltip,} from '@patternfly/react-core';
-import '../karavan.css';
+import {Text, Tooltip,} from '@patternfly/react-core';
+import '../../karavan.css';
 import './DslElement.css';
-import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-circle-icon";
-import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-circle-icon";
-import SyncIcon from "@patternfly/react-icons/dist/js/icons/sync-icon";
-import TurnIcon from "@patternfly/react-icons/dist/js/icons/chevron-circle-right-icon";
-import InsertIcon from "@patternfly/react-icons/dist/js/icons/arrow-alt-circle-right-icon";
 import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition";
-import {CamelUi} from "../utils/CamelUi";
-import {EventBus} from "../utils/EventBus";
+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";
-import {useDesignerStore, useIntegrationStore} from "../DesignerStore";
+import {useDesignerStore, useIntegrationStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
-import {useRouteDesignerHook} from "./useRouteDesignerHook";
+import {useRouteDesignerHook} from "../useRouteDesignerHook";
+import {AddElementIcon, DeleteElementIcon, InsertElementIcon} from "./DslElementIcons";
 
 interface Props {
     step: CamelElement,
     parent: CamelElement | undefined,
+    nextStep: CamelElement | undefined,
+    prevStep: CamelElement | undefined,
     inSteps: boolean
     position: number
 }
@@ -43,7 +41,16 @@ interface Props {
 export function DslElement(props: Props) {
 
     const headerRef = React.useRef<HTMLDivElement>(null);
-    const {selectElement, moveElement, onShowDeleteConfirmation, openSelector, isKamelet, isSourceKamelet, isActionKamelet} = useRouteDesignerHook();
+    const addButtonRef = React.useRef<HTMLDivElement>(null);
+    const {
+        selectElement,
+        moveElement,
+        onShowDeleteConfirmation,
+        openSelector,
+        isKamelet,
+        isSourceKamelet,
+        isActionKamelet
+    } = useRouteDesignerHook();
 
     const [integration] = useIntegrationStore((s) => [s.integration, s.setIntegration], shallow)
 
@@ -98,12 +105,20 @@ export function DslElement(props: Props) {
     }
 
     function hasBorder(): boolean {
-        return (props.step?.hasSteps() && !['FromDefinition'].includes(props.step.dslName))
-            || ['RouteConfigurationDefinition',
-                'RouteDefinition',
-                'TryDefinition',
-                'ChoiceDefinition',
-                'SwitchDefinition'].includes(props.step.dslName);
+        const step = props.step;
+        if (['FilterDefinition'].includes(step.dslName)) {
+            return true;
+        }
+        if (['FromDefinition',
+            'RouteDefinition',
+            'TryDefinition',
+            'CatchDefinition', 'FinallyDefinition',
+            'ChoiceDefinition',
+            'SwitchDefinition', 'WhenDefinition', 'OtherwiseDefinition'
+        ].includes(step.dslName)) {
+            return false;
+        }
+        return props.step?.hasSteps();
     }
 
     function isNotDraggable(): boolean {
@@ -177,7 +192,26 @@ export function DslElement(props: Props) {
         return style;
     }
 
+    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 isSelected = isElementSelected();
         const isHidden = isElementHidden();
         if (el) {
@@ -186,15 +220,14 @@ export function DslElement(props: Props) {
                 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 (props.step.showChildren) {
+                if (step.showChildren) {
                     if (isHidden) {
-                        // EventBus.sendPosition("delete", props.step, props.parent, new DOMRect(), new DOMRect(), 0);
-                        EventBus.sendPosition("add", props.step, props.parent, rect, headerRect, props.position, props.inSteps, isSelected);
+                        EventBus.sendPosition("add", step, prevStep, parent, rect, headerRect, props.position, props.inSteps, isSelected);
                     } else {
-                        EventBus.sendPosition("add", props.step, props.parent, rect, headerRect, props.position, props.inSteps, isSelected);
+                        EventBus.sendPosition("add", step, prevStep, parent, rect, headerRect, props.position, props.inSteps, isSelected);
                     }
                 } else {
-                    EventBus.sendPosition("delete", props.step, props.parent, new DOMRect(), new DOMRect(), 0);
+                    EventBus.sendPosition("delete", step, prevStep, parent, new DOMRect(), new DOMRect(), 0);
                 }
             }
         }
@@ -237,7 +270,6 @@ export function DslElement(props: Props) {
                 </div>
                 {showInsertButton && getInsertElementButton()}
                 {getDeleteButton()}
-                {/*{getMenuButton()}*/}
                 {showAddButton && getAddElementButton()}
             </div>
         )
@@ -304,7 +336,7 @@ export function DslElement(props: Props) {
         const step = props.step;
         const isBorder = child.name === 'steps' && hasBorderOverSteps(step);
         const style: CSSProperties = {
-            borderStyle: isBorder ? "dotted" : "none",
+            // borderStyle: isBorder ? "dotted" : "none",
             borderColor: "var(--step-border-color)",
             borderWidth: "1px",
             borderRadius: "16px",
@@ -343,15 +375,25 @@ 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) => (
-                        <div key={step.uuid + child.className + index}>
-                            <DslElement
-                                inSteps={child.name === 'steps'}
-                                position={index}
-                                step={element}
-                                parent={step}/>
-                        </div>
-                    ))}
+                    {children.map((element, index) => {
+                            let prevStep = children.at(index - 1);
+                            let nextStep = undefined;
+                            if (['TryDefinition', 'ChoiceDefinition'].includes(step.dslName)) {
+                                nextStep = props.nextStep;
+                            } else {
+                                nextStep = children.at(index + 1);
+                            }
+                            return (<div key={step.uuid + child.className + index}>
+                                <DslElement
+                                    inSteps={child.name === 'steps'}
+                                    position={index}
+                                    step={element}
+                                    nextStep={nextStep}
+                                    prevStep={prevStep}
+                                    parent={step}/>
+                            </div>)
+                        }
+                    )}
                     {child.name === 'steps' && getAddStepButton()}
                 </div>
             )
@@ -366,16 +408,23 @@ export function DslElement(props: Props) {
     }
 
     function getAddStepButton() {
-        const {step} = props;
+        const {step, nextStep} = props;
         const hideAddButton = step.dslName === 'StepDefinition' && !CamelDisplayUtil.isStepDefinitionExpanded(integration, step.uuid, selectedUuids.at(0));
         if (hideAddButton) return (<></>)
         else return (
             <Tooltip position={"bottom"}
-                     content={<div>{"Add step to " + CamelDisplayUtil.getTitle(step)}</div>}>
-                <button type="button" aria-label="Add" onClick={e => onOpenSelector(e)}
-                        className={isAddStepButtonLeft() ? "add-button add-button-left" : "add-button add-button-bottom"}>
-                    <AddIcon/>
-                </button>
+                     content={<div>{nextStep?.dslName.replace("Definition", "")}</div>}
+                // content={<div>{"Add step to " + CamelDisplayUtil.getTitle(step)}</div>}
+            >
+                <div ref={addButtonRef}>
+                    <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"}>
+                        <AddElementIcon/>
+                    </button>
+                </div>
             </Tooltip>
         )
     }
@@ -389,7 +438,7 @@ export function DslElement(props: Props) {
                     aria-label="Add"
                     onClick={e => onOpenSelector(e, false)}
                     className={"add-element-button"}>
-                    <AddIcon/>
+                    <AddElementIcon/>
                 </button>
             </Tooltip>
         )
@@ -398,8 +447,11 @@ export function DslElement(props: Props) {
     function getInsertElementButton() {
         return (
             <Tooltip position={"left"} content={<div>{"Insert element before"}</div>}>
-                <button type="button" aria-label="Insert" onClick={e => onOpenSelector(e, true, true)}
-                        className={"insert-element-button"}><InsertIcon/>
+                <button type="button"
+                        aria-label="Insert"
+                        onClick={e => onOpenSelector(e, true, true)}
+                        className={"insert-element-button"}>
+                    <InsertElementIcon/>
                 </button>
             </Tooltip>
         )
@@ -409,39 +461,12 @@ export function DslElement(props: Props) {
         return (
             <Tooltip position={"right"} content={<div>{"Delete element"}</div>}>
                 <button type="button" aria-label="Delete" onClick={e => onDeleteElement(e)} className="delete-button">
-                    <DeleteIcon/>
+                    <DeleteElementIcon/>
                 </button>
             </Tooltip>
         )
     }
 
-    function getMenuButton() {
-        return (
-            <Popover
-                aria-label="Convert Popover"
-                hasNoPadding
-                position={"right"}
-                hideOnOutsideClick={true}
-                showClose={false}
-                bodyContent={
-                    <Menu activeItemId={''} onSelect={event => {}} isPlain>
-                        <MenuContent>
-                            <MenuList>
-                                <MenuItem itemId={0} icon={<SyncIcon aria-hidden />}>Convert to SetHeader</MenuItem>
-                                {/*<MenuItem itemId={1}>Action</MenuItem>*/}
-                                {/*<MenuItem itemId={2}>Action</MenuItem>*/}
-                            </MenuList>
-                        </MenuContent>
-                    </Menu>
-                }
-            >
-                <button type="button" aria-label="Menu" onClick={e => {}} className="menu-button">
-                    <TurnIcon/>
-                </button>
-            </Popover>
-        )
-    }
-
     const element: CamelElement = props.step;
     const className = "step-element"
         + (isElementSelected() ? " step-element-selected" : "") + (!props.step.showChildren ? " hidden-step" : "")
@@ -451,7 +476,7 @@ export function DslElement(props: Props) {
              className={className}
              ref={el => sendPosition(el)}
              style={{
-                 borderStyle: hasBorder() ? "dotted" : "none",
+                 borderStyle: hasBorder() ? "dashed" : "none",
                  borderColor: isElementSelected() ? "var(--step-border-color-selected)" : "var(--step-border-color)",
                  marginTop: isInStepWithChildren() ? "16px" : "8px",
                  zIndex: element.dslName === 'ToDefinition' ? 20 : 10,
diff --git a/karavan-designer/src/designer/route/element/DslElementIcons.tsx b/karavan-designer/src/designer/route/element/DslElementIcons.tsx
new file mode 100644
index 00000000..3b6b984b
--- /dev/null
+++ b/karavan-designer/src/designer/route/element/DslElementIcons.tsx
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import "./DslElement.css"
+
+export function DeleteElementIcon() {
+    return (
+        <svg
+            xmlns="http://www.w3.org/2000/svg"
+            xmlSpace="preserve"
+            viewBox="0 0 32 32"
+            className="delete-button-icon"
+        >
+            <path d="M16 2C8.2 2 2 8.2 2 16s6.2 14 14 14 14-6.2 14-14S23.8 2 16 2zm0 26C9.4 28 4 22.6 4 16S9.4 4 16 4s12 5.4 12 12-5.4 12-12 12z" />
+            <path
+                d="M0 0h32v32H0z"
+                style={{
+                    fill: "none",
+                }}
+            />
+            <path d="M21.4 23 16 17.6 10.6 23 9 21.4l5.4-5.4L9 10.6 10.6 9l5.4 5.4L21.4 9l1.6 1.6-5.4 5.4 5.4 5.4z" />
+        </svg>
+    )
+}
+
+export function AddElementIcon() {
+    return (
+        <svg
+            xmlns="http://www.w3.org/2000/svg"
+            xmlSpace="preserve"
+            viewBox="0 0 32 32"
+            className="add-button-icon"
+        >
+            <path
+                d="M16 4c6.6 0 12 5.4 12 12s-5.4 12-12 12S4 22.6 4 16 9.4 4 16 4m0-2C8.3 2 2 8.3 2 16s6.3 14 14 14 14-6.3 14-14S23.7 2 16 2z"/>
+            <path d="M24 15h-7V8h-2v7H8v2h7v7h2v-7h7z"/>
+            <path
+                d="M0 0h32v32H0z"
+                style={{
+                    fill: "none",
+                }}
+            />
+        </svg>
+    )
+}
+
+export function InsertElementIcon() {
+    return (
+        <svg
+            xmlns="http://www.w3.org/2000/svg"
+            xmlSpace="preserve"
+            viewBox="0 0 32 32"
+            className="insert-button-icon"
+        >
+            <path d="m16 8-1.43 1.393L20.15 15H8v2h12.15l-5.58 5.573L16 24l8-8-8-8z" />
+            <path d="M16 30a14 14 0 1 1 14-14 14.016 14.016 0 0 1-14 14Zm0-26a12 12 0 1 0 12 12A12.014 12.014 0 0 0 16 4Z" />
+            <path
+                d="M0 0h32v32H0z"
+                data-name="&lt;Transparent Rectangle&gt;"
+                style={{
+                    fill: "none",
+                }}
+            />
+        </svg>
+    )
+}
\ No newline at end of file
diff --git a/karavan-designer/src/designer/route/DslElementMoveModal.tsx b/karavan-designer/src/designer/route/element/DslElementMoveModal.tsx
similarity index 94%
rename from karavan-designer/src/designer/route/DslElementMoveModal.tsx
rename to karavan-designer/src/designer/route/element/DslElementMoveModal.tsx
index d1e17ecf..75d4f58f 100644
--- a/karavan-designer/src/designer/route/DslElementMoveModal.tsx
+++ b/karavan-designer/src/designer/route/element/DslElementMoveModal.tsx
@@ -20,10 +20,10 @@ import {
     Flex,
     Modal, ModalVariant,
 } from '@patternfly/react-core';
-import '../karavan.css';
-import {useDesignerStore, useIntegrationStore} from "../DesignerStore";
+import '../../karavan.css';
+import {useDesignerStore, useIntegrationStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
-import {useRouteDesignerHook} from "./useRouteDesignerHook";
+import {useRouteDesignerHook} from "../useRouteDesignerHook";
 import {CamelDefinitionApiExt} from "karavan-core/lib/api/CamelDefinitionApiExt";
 
 export function DslElementMoveModal() {
diff --git a/karavan-designer/src/designer/route/usePropertiesHook.tsx b/karavan-designer/src/designer/route/usePropertiesHook.tsx
index 87513b18..a9bd9ef9 100644
--- a/karavan-designer/src/designer/route/usePropertiesHook.tsx
+++ b/karavan-designer/src/designer/route/usePropertiesHook.tsx
@@ -126,5 +126,14 @@ export function usePropertiesHook (isRouteDesigner: boolean = true) {
         // TODO:
     }
 
-    return {cloneElement, onPropertyChange, onParametersChange, onDataFormatChange, onExpressionChange, getInternalComponentName}
+    const convertStep = (step: CamelElement, targetDslName: string ) => {
+        // const clone = CamelUtil.cloneIntegration(integration);
+        // const i = CamelDefinitionApiExt.addStepToIntegration(clone, step, parentId, position);
+        // const selectedStep = step.dslName === 'RouteDefinition' ? (step as RouteDefinition).from  : step;
+        // setIntegration(i, false);
+        // setSelectedStep(selectedStep);
+        // setSelectedUuids([selectedStep.uuid]);
+    }
+
+    return {convertStep, cloneElement, onPropertyChange, onParametersChange, onDataFormatChange, onExpressionChange, getInternalComponentName}
 }
\ No newline at end of file
diff --git a/karavan-designer/src/designer/route/useRouteDesignerHook.tsx b/karavan-designer/src/designer/route/useRouteDesignerHook.tsx
index f48fc850..b65966a0 100644
--- a/karavan-designer/src/designer/route/useRouteDesignerHook.tsx
+++ b/karavan-designer/src/designer/route/useRouteDesignerHook.tsx
@@ -105,7 +105,8 @@ export function useRouteDesignerHook () {
     }
 
     const deleteElement = () =>  {
-        EventBus.sendPosition("clean", new CamelElement(""), undefined, new DOMRect(), new DOMRect(), 0);
+        EventBus.sendPosition("clean", new CamelElement(""), undefined, undefined, new DOMRect(), new DOMRect(), 0);
+        EventBus.sendButtonPosition("clean", '',  new CamelElement(""), new DOMRect());
         let i = integration;
         selectedUuids.forEach(uuidToDelete => {
              i = CamelDefinitionApiExt.deleteStepFromIntegration(i, uuidToDelete);
diff --git a/karavan-designer/src/designer/utils/CamelUi.tsx b/karavan-designer/src/designer/utils/CamelUi.tsx
index ec4d5796..83476b1b 100644
--- a/karavan-designer/src/designer/utils/CamelUi.tsx
+++ b/karavan-designer/src/designer/utils/CamelUi.tsx
@@ -166,8 +166,17 @@ export class RouteToCreate {
 const INTEGRATION_PATTERNS = 'Integration Patterns';
 const connectorNavs = ['routing', "transformation", "error", "configuration", "endpoint", "kamelet", "component"];
 
+const stepConvertMap = new Map<string, string>([
+    ["SetBodyDefinition", "SetHeaderDefinition"],
+    ["SetHeaderDefinition", "SetBodyDefinition"],
+]);
+
 export class CamelUi {
 
+    static getConvertTargetDsl = (sourceDsl?: string): string | undefined => {
+        return sourceDsl ? stepConvertMap.get(sourceDsl) : undefined;
+    }
+
     static createNewInternalRoute = (uri: string): RouteToCreate | undefined => {
         const uris = uri.toString().split(":");
         const componentName = uris[0];
diff --git a/karavan-designer/src/designer/utils/EventBus.ts b/karavan-designer/src/designer/utils/EventBus.ts
index 0a20d3c6..55906f0f 100644
--- a/karavan-designer/src/designer/utils/EventBus.ts
+++ b/karavan-designer/src/designer/utils/EventBus.ts
@@ -18,10 +18,26 @@ import {Subject} from 'rxjs';
 import {CamelElement, Integration} from "karavan-core/lib/model/IntegrationDefinition";
 import {v4 as uuidv4} from "uuid";
 
-const positions = new Subject<DslPosition>();
+export class ButtonPosition {
+    uuid: string = '';
+    nextstep: CamelElement = new CamelElement("");
+    rect: DOMRect = new DOMRect();
+    command: "add" | "delete" | "clean" = "add";
+
+    constructor(command: "add" | "delete" | "clean",
+                uuid: string,
+                nextstep: CamelElement,
+                rect: DOMRect) {
+        this.uuid = uuid;
+        this.command = command;
+        this.nextstep = nextstep;
+        this.rect = rect;
+    }
+}
 
 export class DslPosition {
     step: CamelElement = new CamelElement("");
+    prevStep: CamelElement | undefined;
     parent: CamelElement | undefined;
     inSteps: boolean = false;
     isSelected: boolean = false;
@@ -32,6 +48,7 @@ export class DslPosition {
 
     constructor(command: "add" | "delete" | "clean",
                 step: CamelElement,
+                prevStep: CamelElement | undefined,
                 parent:CamelElement | undefined,
                 rect: DOMRect,
                 headerRect:DOMRect,
@@ -40,6 +57,7 @@ export class DslPosition {
                 isSelected: boolean = false) {
         this.command = command;
         this.step = step;
+        this.prevStep = prevStep;
         this.parent = parent;
         this.rect = rect;
         this.headerRect = headerRect;
@@ -85,17 +103,25 @@ export class ToastMessage {
         this.variant = variant;
     }
 }
+const dslPositions = new Subject<DslPosition>();
+const buttonPositions = new Subject<ButtonPosition>();
 
 export const EventBus = {
     sendPosition: (command: "add" | "delete" | "clean",
                    step: CamelElement,
+                   prevStep: CamelElement | undefined,
                    parent: CamelElement | undefined,
                    rect: DOMRect,
                    headerRect: DOMRect,
                    position: number,
                    inSteps: boolean = false,
-                   isSelected: boolean = false) => positions.next(new DslPosition(command, step, parent, rect, headerRect, position, inSteps, isSelected)),
-    onPosition: () => positions.asObservable(),
+                   isSelected: boolean = false) => dslPositions.next(new DslPosition(command, step, prevStep, parent, rect, headerRect, position, inSteps, isSelected)),
+    onPosition: () => dslPositions.asObservable(),
+
+    sendButtonPosition: (command: "add" | "delete" | "clean", uuid: string,
+                   nextStep: CamelElement,
+                   rect: DOMRect) => buttonPositions.next(new ButtonPosition(command, uuid, nextStep, rect)),
+    onButtonPosition: () => buttonPositions.asObservable(),
 
     sendIntegrationUpdate: (i: Integration, propertyOnly: boolean) => updates.next(new IntegrationUpdate(i, propertyOnly)),
     onIntegrationUpdate: () => updates.asObservable(),