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 8b5fb5bec65be6cadb835a0af4efc1e37c4b3cb5
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Wed Feb 26 14:13:32 2025 -0500

    Support dynamic Kamelets
---
 .../main/webui/src/designer/property/PropertiesHeader.tsx    | 12 ++++++------
 .../src/main/webui/src/designer/utils/ValidatorUtils.ts      |  4 ++++
 karavan-core/src/core/api/CamelUtil.ts                       |  4 ++--
 karavan-designer/src/designer/property/PropertiesHeader.tsx  | 12 ++++++------
 karavan-designer/src/designer/utils/ValidatorUtils.ts        |  4 ++++
 karavan-space/src/designer/property/PropertiesHeader.tsx     | 12 ++++++------
 karavan-space/src/designer/utils/ValidatorUtils.ts           |  4 ++++
 7 files changed, 32 insertions(+), 20 deletions(-)

diff --git 
a/karavan-app/src/main/webui/src/designer/property/PropertiesHeader.tsx 
b/karavan-app/src/main/webui/src/designer/property/PropertiesHeader.tsx
index 4e99422c..b876adbd 100644
--- a/karavan-app/src/main/webui/src/designer/property/PropertiesHeader.tsx
+++ b/karavan-app/src/main/webui/src/designer/property/PropertiesHeader.tsx
@@ -29,7 +29,7 @@ import {
 } from '@patternfly/react-core';
 import './DslProperties.css';
 import "@patternfly/patternfly/patternfly.css";
-import {CamelUi, RouteToCreate} from "../utils/CamelUi";
+import {CamelUi} from "../utils/CamelUi";
 import {useDesignerStore} from "../DesignerStore";
 import {shallow} from "zustand/shallow";
 import {usePropertiesHook} from "./usePropertiesHook";
@@ -243,7 +243,7 @@ export function PropertiesHeader(props: Props) {
     const component = ComponentApi.findStepComponent(selectedStep);
     const groups = (isFrom || isPoll) ? ['consumer', 'common'] : ['producer', 
'common'];
     const isKamelet = CamelUi.isKamelet(selectedStep);
-    const isStepComponent = !isFrom && selectedStep !== undefined && 
!isKamelet && ['ToDefinition', 'PollDefinition', 
'ToDynamicDefinition'].includes(selectedStep?.dslName);
+    const showSwitchers = !isFrom && selectedStep !== undefined && 
['ToDefinition', 'PollDefinition', 
'ToDynamicDefinition'].includes(selectedStep?.dslName);
 
     function changeStepType(poll: boolean, dynamic: boolean) {
         if (selectedStep) {
@@ -263,7 +263,7 @@ export function PropertiesHeader(props: Props) {
         }
     }
 
-    function getComponentStepTypeSwitch() {
+    function getStepTypeSwitch() {
         const pollSupported = !component?.component.producerOnly;
         return (<div style={{display: 'flex', flexDirection: 'row', 
justifyContent: 'end', width: '100%', gap: '10px'}}>
                 <Tooltip content='Send messages to a dynamic endpoint 
evaluated on-demand' position='top-end'>
@@ -279,7 +279,7 @@ export function PropertiesHeader(props: Props) {
                         isReversed
                     />
                 </Tooltip>
-                {pollSupported &&
+                {pollSupported && !isKamelet &&
                     <Tooltip content='Simple Polling Consumer to obtain the 
additional data' position='top-end'>
                         <Switch
                             id="step-type-poll"
@@ -303,7 +303,7 @@ export function PropertiesHeader(props: Props) {
             (selectedStep as any)?.id !== undefined
                 ? <Label isEditable color='blue' isCompact 
onEditComplete={(event, newText) => onPropertyChange("id", newText)}>
                     {(selectedStep as any)?.id || ''}
-                    </Label>
+                </Label>
                 : <Button variant="link" onClick={event => 
onPropertyChange("id", "rc-" + Math.floor(1000 + Math.random() * 
9000).toString())}>
                     Add Id
                 </Button>
@@ -316,7 +316,7 @@ export function PropertiesHeader(props: Props) {
                 <Title headingLevel="h1" size="md">{title}</Title>
                 {getIdInput()}
                 {getHeaderMenu()}
-                {isStepComponent && getComponentStepTypeSwitch()}
+                {showSwitchers && getStepTypeSwitch()}
             </div>
             <Text component={TextVariants.p}>{descriptionLines.at(0)}</Text>
             {descriptionLines.length > 1 && getDescriptionSection()}
diff --git a/karavan-app/src/main/webui/src/designer/utils/ValidatorUtils.ts 
b/karavan-app/src/main/webui/src/designer/utils/ValidatorUtils.ts
index b9240dad..89d97e55 100644
--- a/karavan-app/src/main/webui/src/designer/utils/ValidatorUtils.ts
+++ b/karavan-app/src/main/webui/src/designer/utils/ValidatorUtils.ts
@@ -23,6 +23,10 @@ export function isSensitiveFieldValid(field: string): 
boolean {
         const content = field.slice(2, -2).trim();
         return content !== "";
     }
+    if (field.startsWith("${") && field.endsWith("}")) {
+        const content = field.slice(2, -1).trim();
+        return content !== "";
+    }
     return false;
 }
 
diff --git a/karavan-core/src/core/api/CamelUtil.ts 
b/karavan-core/src/core/api/CamelUtil.ts
index ff148a5b..691e8b83 100644
--- a/karavan-core/src/core/api/CamelUtil.ts
+++ b/karavan-core/src/core/api/CamelUtil.ts
@@ -152,7 +152,7 @@ export class CamelUtil {
     static isKameletComponent = (element: CamelElement | undefined): boolean 
=> {
         if (element?.dslName === 'KameletDefinition') {
             return true;
-        } else if (element?.dslName === 'FromDefinition' || element?.dslName 
=== 'ToDefinition') {
+        } else if (element?.dslName === 'FromDefinition' || element?.dslName 
=== 'ToDefinition' || element?.dslName === 'ToDynamicDefinition') {
             const uri: string = (element as any).uri;
             return uri !== undefined && uri.startsWith('kamelet:');
         } else {
@@ -166,7 +166,7 @@ export class CamelUtil {
         } else if (element.dslName === 'ToDefinition' && (element as 
ToDefinition).uri?.startsWith('kamelet:')) {
             const kameletName = (element as 
ToDefinition).uri?.replace('kamelet:', '');
             return KameletApi.findKameletByName(kameletName);
-        } else if (['FromDefinition', 'FromDefinition', 
'ToDefinition'].includes(element.dslName)) {
+        } else if (['FromDefinition', 'ToDynamicDefinition', 
'ToDefinition'].includes(element.dslName)) {
             const uri: string = (element as any).uri;
             return uri !== undefined ? KameletApi.findKameletByUri(uri) : 
undefined;
         } else {
diff --git a/karavan-designer/src/designer/property/PropertiesHeader.tsx 
b/karavan-designer/src/designer/property/PropertiesHeader.tsx
index 4e99422c..b876adbd 100644
--- a/karavan-designer/src/designer/property/PropertiesHeader.tsx
+++ b/karavan-designer/src/designer/property/PropertiesHeader.tsx
@@ -29,7 +29,7 @@ import {
 } from '@patternfly/react-core';
 import './DslProperties.css';
 import "@patternfly/patternfly/patternfly.css";
-import {CamelUi, RouteToCreate} from "../utils/CamelUi";
+import {CamelUi} from "../utils/CamelUi";
 import {useDesignerStore} from "../DesignerStore";
 import {shallow} from "zustand/shallow";
 import {usePropertiesHook} from "./usePropertiesHook";
@@ -243,7 +243,7 @@ export function PropertiesHeader(props: Props) {
     const component = ComponentApi.findStepComponent(selectedStep);
     const groups = (isFrom || isPoll) ? ['consumer', 'common'] : ['producer', 
'common'];
     const isKamelet = CamelUi.isKamelet(selectedStep);
-    const isStepComponent = !isFrom && selectedStep !== undefined && 
!isKamelet && ['ToDefinition', 'PollDefinition', 
'ToDynamicDefinition'].includes(selectedStep?.dslName);
+    const showSwitchers = !isFrom && selectedStep !== undefined && 
['ToDefinition', 'PollDefinition', 
'ToDynamicDefinition'].includes(selectedStep?.dslName);
 
     function changeStepType(poll: boolean, dynamic: boolean) {
         if (selectedStep) {
@@ -263,7 +263,7 @@ export function PropertiesHeader(props: Props) {
         }
     }
 
-    function getComponentStepTypeSwitch() {
+    function getStepTypeSwitch() {
         const pollSupported = !component?.component.producerOnly;
         return (<div style={{display: 'flex', flexDirection: 'row', 
justifyContent: 'end', width: '100%', gap: '10px'}}>
                 <Tooltip content='Send messages to a dynamic endpoint 
evaluated on-demand' position='top-end'>
@@ -279,7 +279,7 @@ export function PropertiesHeader(props: Props) {
                         isReversed
                     />
                 </Tooltip>
-                {pollSupported &&
+                {pollSupported && !isKamelet &&
                     <Tooltip content='Simple Polling Consumer to obtain the 
additional data' position='top-end'>
                         <Switch
                             id="step-type-poll"
@@ -303,7 +303,7 @@ export function PropertiesHeader(props: Props) {
             (selectedStep as any)?.id !== undefined
                 ? <Label isEditable color='blue' isCompact 
onEditComplete={(event, newText) => onPropertyChange("id", newText)}>
                     {(selectedStep as any)?.id || ''}
-                    </Label>
+                </Label>
                 : <Button variant="link" onClick={event => 
onPropertyChange("id", "rc-" + Math.floor(1000 + Math.random() * 
9000).toString())}>
                     Add Id
                 </Button>
@@ -316,7 +316,7 @@ export function PropertiesHeader(props: Props) {
                 <Title headingLevel="h1" size="md">{title}</Title>
                 {getIdInput()}
                 {getHeaderMenu()}
-                {isStepComponent && getComponentStepTypeSwitch()}
+                {showSwitchers && getStepTypeSwitch()}
             </div>
             <Text component={TextVariants.p}>{descriptionLines.at(0)}</Text>
             {descriptionLines.length > 1 && getDescriptionSection()}
diff --git a/karavan-designer/src/designer/utils/ValidatorUtils.ts 
b/karavan-designer/src/designer/utils/ValidatorUtils.ts
index b9240dad..89d97e55 100644
--- a/karavan-designer/src/designer/utils/ValidatorUtils.ts
+++ b/karavan-designer/src/designer/utils/ValidatorUtils.ts
@@ -23,6 +23,10 @@ export function isSensitiveFieldValid(field: string): 
boolean {
         const content = field.slice(2, -2).trim();
         return content !== "";
     }
+    if (field.startsWith("${") && field.endsWith("}")) {
+        const content = field.slice(2, -1).trim();
+        return content !== "";
+    }
     return false;
 }
 
diff --git a/karavan-space/src/designer/property/PropertiesHeader.tsx 
b/karavan-space/src/designer/property/PropertiesHeader.tsx
index 4e99422c..b876adbd 100644
--- a/karavan-space/src/designer/property/PropertiesHeader.tsx
+++ b/karavan-space/src/designer/property/PropertiesHeader.tsx
@@ -29,7 +29,7 @@ import {
 } from '@patternfly/react-core';
 import './DslProperties.css';
 import "@patternfly/patternfly/patternfly.css";
-import {CamelUi, RouteToCreate} from "../utils/CamelUi";
+import {CamelUi} from "../utils/CamelUi";
 import {useDesignerStore} from "../DesignerStore";
 import {shallow} from "zustand/shallow";
 import {usePropertiesHook} from "./usePropertiesHook";
@@ -243,7 +243,7 @@ export function PropertiesHeader(props: Props) {
     const component = ComponentApi.findStepComponent(selectedStep);
     const groups = (isFrom || isPoll) ? ['consumer', 'common'] : ['producer', 
'common'];
     const isKamelet = CamelUi.isKamelet(selectedStep);
-    const isStepComponent = !isFrom && selectedStep !== undefined && 
!isKamelet && ['ToDefinition', 'PollDefinition', 
'ToDynamicDefinition'].includes(selectedStep?.dslName);
+    const showSwitchers = !isFrom && selectedStep !== undefined && 
['ToDefinition', 'PollDefinition', 
'ToDynamicDefinition'].includes(selectedStep?.dslName);
 
     function changeStepType(poll: boolean, dynamic: boolean) {
         if (selectedStep) {
@@ -263,7 +263,7 @@ export function PropertiesHeader(props: Props) {
         }
     }
 
-    function getComponentStepTypeSwitch() {
+    function getStepTypeSwitch() {
         const pollSupported = !component?.component.producerOnly;
         return (<div style={{display: 'flex', flexDirection: 'row', 
justifyContent: 'end', width: '100%', gap: '10px'}}>
                 <Tooltip content='Send messages to a dynamic endpoint 
evaluated on-demand' position='top-end'>
@@ -279,7 +279,7 @@ export function PropertiesHeader(props: Props) {
                         isReversed
                     />
                 </Tooltip>
-                {pollSupported &&
+                {pollSupported && !isKamelet &&
                     <Tooltip content='Simple Polling Consumer to obtain the 
additional data' position='top-end'>
                         <Switch
                             id="step-type-poll"
@@ -303,7 +303,7 @@ export function PropertiesHeader(props: Props) {
             (selectedStep as any)?.id !== undefined
                 ? <Label isEditable color='blue' isCompact 
onEditComplete={(event, newText) => onPropertyChange("id", newText)}>
                     {(selectedStep as any)?.id || ''}
-                    </Label>
+                </Label>
                 : <Button variant="link" onClick={event => 
onPropertyChange("id", "rc-" + Math.floor(1000 + Math.random() * 
9000).toString())}>
                     Add Id
                 </Button>
@@ -316,7 +316,7 @@ export function PropertiesHeader(props: Props) {
                 <Title headingLevel="h1" size="md">{title}</Title>
                 {getIdInput()}
                 {getHeaderMenu()}
-                {isStepComponent && getComponentStepTypeSwitch()}
+                {showSwitchers && getStepTypeSwitch()}
             </div>
             <Text component={TextVariants.p}>{descriptionLines.at(0)}</Text>
             {descriptionLines.length > 1 && getDescriptionSection()}
diff --git a/karavan-space/src/designer/utils/ValidatorUtils.ts 
b/karavan-space/src/designer/utils/ValidatorUtils.ts
index b9240dad..89d97e55 100644
--- a/karavan-space/src/designer/utils/ValidatorUtils.ts
+++ b/karavan-space/src/designer/utils/ValidatorUtils.ts
@@ -23,6 +23,10 @@ export function isSensitiveFieldValid(field: string): 
boolean {
         const content = field.slice(2, -2).trim();
         return content !== "";
     }
+    if (field.startsWith("${") && field.endsWith("}")) {
+        const content = field.slice(2, -1).trim();
+        return content !== "";
+    }
     return false;
 }
 

Reply via email to