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 cdde30d412b7aed8477f5902167cda3ef744da2e
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Tue Oct 3 20:06:52 2023 -0400

    Kamelets Dependencies UI #315
---
 .../src/core/model/IntegrationDefinition.ts        |  21 ++-
 karavan-core/test/kamelet.spec.ts                  |   3 +-
 .../public/example/aws-s3-source.kamelet.yaml      | 190 +++++++++++++++++++
 .../src/designer/kamelet/KameletTypesOutCard.tsx   | 113 +++++++++++
 .../src/main/resources/application.properties      |   2 +-
 .../kamelet/KameletDefinitionPropertyCard.tsx      | 125 +++++++++++-
 .../designer/kamelet/KameletDefinitionsPanel.tsx   |  59 +++++-
 .../designer/kamelet/KameletDependenciesCard.tsx   | 113 +++++++++++
 .../src/designer/kamelet/KameletProperties.tsx     | 209 +--------------------
 .../src/designer/kamelet/KameletTypesOutCard.tsx   | 113 +++++++++++
 .../main/webui/src/designer/kamelet/kamelet.css    |   1 +
 11 files changed, 723 insertions(+), 226 deletions(-)

diff --git a/karavan-core/src/core/model/IntegrationDefinition.ts 
b/karavan-core/src/core/model/IntegrationDefinition.ts
index 974f8e5e..fb1c11f3 100644
--- a/karavan-core/src/core/model/IntegrationDefinition.ts
+++ b/karavan-core/src/core/model/IntegrationDefinition.ts
@@ -32,6 +32,23 @@ export class DefinitionProperty {
     }
 }
 
+export class MediaType {
+    mediaType: string = '';
+
+    public constructor(init?: Partial<MediaType>) {
+        Object.assign(this, init);
+    }
+}
+
+export class Types {
+    in?: MediaType = new MediaType();
+    out?: MediaType = new MediaType();
+
+    public constructor(init?: Partial<Types>) {
+        Object.assign(this, init);
+    }
+}
+
 export class Definition {
     title: string = '';
     description: string = '';
@@ -46,7 +63,7 @@ export class Definition {
 
 export class Spec {
     definition?: Definition;
-    types?: any;
+    types?: Types;
     flows?: any[] = [];
     template?: any;
     dependencies?: string[];
@@ -107,7 +124,7 @@ export class Integration {
         if (type === 'kamelet') {
             i.metadata.annotations = new MetadataAnnotations({})
             i.spec.definition = new Definition({})
-            i.spec.types = {}
+            i.spec.types = new Types();
         }
 
         return i;
diff --git a/karavan-core/test/kamelet.spec.ts 
b/karavan-core/test/kamelet.spec.ts
index 65e94987..750d9295 100644
--- a/karavan-core/test/kamelet.spec.ts
+++ b/karavan-core/test/kamelet.spec.ts
@@ -28,7 +28,6 @@ describe('Kamelet <=> YAML', () => {
     it('Yaml to Kamelet', () => {
         const yaml = 
fs.readFileSync('test/postgresql-source.kamelet.yaml',{encoding:'utf8', 
flag:'r'});
         const i = 
CamelDefinitionYaml.yamlToIntegration("postgresql-source.kamelet.yaml", yaml);
-        // console.log(i)
     });
 
     it('Kamelet to YAML with beans', () => {
@@ -44,6 +43,8 @@ describe('Kamelet <=> YAML', () => {
         i.spec.flows?.push(b);
         const a = new MetadataAnnotations({"camel.apache.org/kamelet.group" : 
"hello world"})
         i.metadata.annotations = a
+
+        // console.log(CamelDefinitionYaml.integrationToYaml(i))
     });
 
     it('Kamelet to YAML without beans', () => {
diff --git a/karavan-designer/public/example/aws-s3-source.kamelet.yaml 
b/karavan-designer/public/example/aws-s3-source.kamelet.yaml
new file mode 100644
index 00000000..e20d11d7
--- /dev/null
+++ b/karavan-designer/public/example/aws-s3-source.kamelet.yaml
@@ -0,0 +1,190 @@
+apiVersion: camel.apache.org/v1
+kind: Kamelet
+metadata:
+  name: aws-s3-source
+  annotations:
+    camel.apache.org/kamelet.support.level: "Stable"
+    camel.apache.org/catalog.version: "4.1.0-SNAPSHOT"
+    camel.apache.org/kamelet.icon: 
"data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJMYXllcl8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHg9IjAiIHk9IjAiIHZpZXdCb3g9IjAgMCAyNDguMiAzMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxzdHlsZT4uc3QyOHtmaWxsOiM4YzMxMjN9LnN0Mjl7ZmlsbDojZTA1MjQzfTwvc3R5bGU+PHBhdGggY2xhc3M9InN0MjgiIGQ9Ik0yMCA1Mi4xTDAgNjJ2MTc1LjVsMjAgOS45LjEtLjFWNTIuMmwtLjEtLjEiLz48cGF0aCBjbGFzcz0ic3QyOSIgZD0iTTEyNyAyMjJMMjAgMjQ3LjVWNTIuMUwxMjcgNzd2MTQ1Ii8+PHBhdGggY2xhc3M9InN0MjgiIG
 [...]
+    camel.apache.org/provider: "Apache Software Foundation"
+    camel.apache.org/kamelet.group: "AWS S3"
+    camel.apache.org/kamelet.namespace: "AWS"
+  labels:
+    camel.apache.org/kamelet.type: "source"
+spec:
+  definition:
+    title: "AWS S3 Source"
+    description: |-
+      Receive data from an Amazon S3 Bucket.
+
+      The basic authentication method for the S3 service is to specify an 
access key and a secret key. These parameters are optional because the Kamelet 
provides a default credentials provider.
+      
+      If you use the default credentials provider, the S3 client loads the 
credentials through this provider and doesn't use the basic authentication 
method.
+
+      Two headers will be duplicated with different names for clarity at sink 
level, CamelAwsS3Key will be duplicated into aws.s3.key and 
CamelAwsS3BucketName will be duplicated in aws.s3.bucket.name
+    required:
+      - bucketNameOrArn
+      - region
+    type: object
+    properties:
+      bucketNameOrArn:
+        title: Bucket Name
+        description: The S3 Bucket name or Amazon Resource Name (ARN).
+        type: string
+      deleteAfterRead:
+        title: Auto-delete Objects
+        description: Specifies to delete objects after consuming them.
+        type: boolean
+        x-descriptors:
+          - 'urn:alm:descriptor:com.tectonic.ui:checkbox'
+        default: true
+      accessKey:
+        title: Access Key
+        description: The access key obtained from AWS.
+        type: string
+        format: password
+        x-descriptors:
+          - urn:alm:descriptor:com.tectonic.ui:password
+          - urn:camel:group:credentials
+      secretKey:
+        title: Secret Key
+        description: The secret key obtained from AWS.
+        type: string
+        format: password
+        x-descriptors:
+          - urn:alm:descriptor:com.tectonic.ui:password
+          - urn:camel:group:credentials
+      region:
+        title: AWS Region
+        description: The AWS region to access.
+        type: string
+        enum: ["ap-south-1", "eu-south-1", "us-gov-east-1", "me-central-1", 
"ca-central-1", "eu-central-1", "us-iso-west-1", "us-west-1", "us-west-2", 
"af-south-1", "eu-north-1", "eu-west-3", "eu-west-2", "eu-west-1", 
"ap-northeast-3", "ap-northeast-2", "ap-northeast-1", "me-south-1", 
"sa-east-1", "ap-east-1", "cn-north-1", "us-gov-west-1", "ap-southeast-1", 
"ap-southeast-2", "us-iso-east-1", "ap-southeast-3", "us-east-1", "us-east-2", 
"cn-northwest-1", "us-isob-east-1", "aws-global", "a [...]
+      autoCreateBucket:
+        title: Autocreate Bucket
+        description: Specifies to automatically create the S3 bucket.
+        type: boolean
+        x-descriptors:
+          - 'urn:alm:descriptor:com.tectonic.ui:checkbox'
+        default: false
+      prefix:
+        title: Prefix
+        description: The AWS S3 bucket prefix to consider while searching.
+        type: string
+        example: 'folder/'
+      ignoreBody:
+        title: Ignore Body
+        description: If true, the S3 Object body is ignored. Setting this to 
true overrides any behavior defined by the `includeBody` option. If false, the 
S3 object is put in the body.
+        type: boolean
+        x-descriptors:
+          - 'urn:alm:descriptor:com.tectonic.ui:checkbox'
+        default: false
+      useDefaultCredentialsProvider:
+        title: Default Credentials Provider
+        description: If true, the S3 client loads credentials through a 
default credentials provider. If false, it uses the basic authentication method 
(access key and secret key).
+        type: boolean
+        x-descriptors:
+          - 'urn:alm:descriptor:com.tectonic.ui:checkbox'
+        default: false
+      uriEndpointOverride:
+        title: Overwrite Endpoint URI
+        description: The overriding endpoint URI. To use this option, you must 
also select the `overrideEndpoint` option.
+        type: string
+      overrideEndpoint:
+        title: Endpoint Overwrite
+        description: Select this option to override the endpoint URI. To use 
this option, you must also provide a URI for the `uriEndpointOverride` option.
+        type: boolean
+        x-descriptors:
+          - 'urn:alm:descriptor:com.tectonic.ui:checkbox'
+        default: false
+      delay:
+        title: Delay
+        description: The number of milliseconds before the next poll of the 
selected bucket.
+        type: integer
+        default: 500
+  dataTypes:
+    out:
+      default: binary
+      headers:
+        CamelAwsS3BucketName:
+          title: S3 Bucket Name
+          description: The bucket name which has been used to retrieve objects
+          type: string
+        CamelAwsS3Key:
+          title: S3 Key
+          description: The key under which the retrieved object is stored
+          type: string
+        CamelAwsS3ContentType:
+          title: Content Type
+          description: The content type of the retrieved object.
+          default: application/octet-stream
+          type: string
+        CamelAwsS3ETag:
+          title: ETag Value
+          description: |-
+            The hex encoded 128-bit MD5 digest of the associated object 
according to RFC 1864. 
+            This data is used as an integrity check to verify that the data 
received by the caller is the same data that was sent by Amazon S3.
+          type: string
+      types:
+        binary:
+          format: "application-octet-stream"
+          description: Default binary representation of the S3 object 
retrieved from the bucket.
+          mediaType: application/octet-stream
+        cloudevents:
+          format: "aws2-s3:application-cloudevents"
+          description: |-
+            Output data type represents AWS S3 get object response as 
CloudEvent V1. The data type sets Camel specific CloudEvent headers on the 
exchange with
+            respective data from the S3 bucket and its derived object.
+          headers:
+            CamelCloudEventID:
+              title: CloudEvent ID
+              description: The Camel exchange id set as event id
+              type: string
+            CamelCloudEventType:
+              title: CloudEvent Type
+              description: The event type
+              default: "org.apache.camel.event.aws.s3.getObject"
+              type: string
+            CamelCloudEventSource:
+              title: CloudEvent Source
+              description: The event source. By default, the S3 bucket name 
with prefix "aws.s3.bucket.".
+              type: string
+            CamelCloudEventSubject:
+              title: CloudEvent Subject
+              description: The event subject. Usually the S3 key.
+              type: string
+            CamelCloudEventTime:
+              title: CloudEvent Time
+              description: The exchange creation timestamp as event time.
+              type: string
+  dependencies:
+    - "camel:core"
+    - "camel:aws2-s3"
+    - "mvn:org.apache.camel.kamelets:camel-kamelets-utils:4.1.0-SNAPSHOT"
+    - "camel:kamelet"
+  template:
+    beans:
+      - name: renameHeaders
+        type: 
"#class:org.apache.camel.kamelets.utils.headers.DuplicateNamingHeaders"
+        properties:
+          prefix: 'CamelAwsS3'
+          renamingPrefix: 'aws.s3.'
+          mode: 'filtering'
+          selectedHeaders: 'CamelAwsS3Key,CamelAwsS3BucketName'
+    from:
+      uri: "aws2-s3:{{bucketNameOrArn}}"
+      parameters:
+        autoCreateBucket: "{{autoCreateBucket}}"
+        secretKey: "{{?secretKey}}"
+        accessKey: "{{?accessKey}}"
+        region: "{{region}}"
+        ignoreBody: "{{ignoreBody}}"
+        deleteAfterRead: "{{deleteAfterRead}}"
+        prefix: "{{?prefix}}"
+        useDefaultCredentialsProvider: "{{useDefaultCredentialsProvider}}"
+        uriEndpointOverride: "{{?uriEndpointOverride}}"
+        overrideEndpoint: "{{overrideEndpoint}}"
+        delay: "{{delay}}"
+      steps:
+        - process:
+            ref: "{{renameHeaders}}"
+        - to: "kamelet:sink"
\ No newline at end of file
diff --git a/karavan-designer/src/designer/kamelet/KameletTypesOutCard.tsx 
b/karavan-designer/src/designer/kamelet/KameletTypesOutCard.tsx
new file mode 100644
index 00000000..76b590ee
--- /dev/null
+++ b/karavan-designer/src/designer/kamelet/KameletTypesOutCard.tsx
@@ -0,0 +1,113 @@
+/*
+ * 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 React from 'react';
+import {
+    Button,
+    Card,
+    CardBody,
+    CardTitle,
+    FormGroup, FormHelperText, HelperText, HelperTextItem,
+    Label,
+    LabelGroup,
+} from '@patternfly/react-core';
+import '../karavan.css';
+import './kamelet.css';
+import {useIntegrationStore} from "../DesignerStore";
+import {shallow} from "zustand/shallow";
+import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-circle-icon";
+import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
+
+export function KameletTypesOutCard() {
+
+    const [integration, setIntegration] = useIntegrationStore((s) => 
[s.integration, s.setIntegration], shallow)
+
+    const dependencies: string[] = [...(integration.spec.dependencies || [])];
+
+
+    function setDependencies(deps: string[]) {
+        const i = CamelUtil.cloneIntegration(integration);
+        i.spec.dependencies = deps;
+        setIntegration(i, true);
+    }
+
+    function addDepencency() {
+        dependencies.push("dependency")
+        setDependencies(dependencies);
+    }
+
+    function deleteDependency(val: string) {
+        setDependencies(dependencies.filter(e => e !== val));
+    }
+
+    function renameDependency(index: number, newVal: string) {
+        dependencies[index] = newVal;
+        setDependencies(dependencies);
+    }
+
+    return (
+        <Card isClickable isCompact isFlat ouiaId="PropertyCard" 
className="property-card">
+            <CardTitle>
+                Dependencies
+            </CardTitle>
+            <CardBody>
+                <FormHelperText>
+                    <HelperText>
+                        <HelperTextItem>Dependencies required, ex: 
camel:component or mvn:groupId:artifactId:version</HelperTextItem>
+                    </HelperText>
+                </FormHelperText>
+            </CardBody>
+            <CardBody>
+                <FormGroup fieldId={'dependencies'}>
+                    <LabelGroup
+                        // categoryName={"Dependencies"}
+                        numLabels={dependencies.length}
+                        isEditable
+                        addLabelControl={
+                            <Button variant="link" icon={<AddIcon/>} 
onClick={event => addDepencency()}>
+                                Add
+                            </Button>
+                        }
+                    >
+                        {dependencies.map((val: string, index: number) => (
+                            <Label
+                                key={val}
+                                id={val}
+                                color="grey"
+                                isEditable
+                                onClose={() => deleteDependency(val)}
+                                onEditCancel={(_event, prevText) => {}}
+                                onEditComplete={(event, newText) => {
+                                    if (event.type === 'mousedown') {
+                                        renameDependency(index, val)
+                                    } else if (event.type === 'keydown' && 
(event as KeyboardEvent).key === 'Tab') {
+                                        renameDependency(index, newText)
+                                    } else if (event.type === 'keydown' && 
(event as KeyboardEvent).key === 'Enter') {
+                                        renameDependency(index, newText)
+                                    } else {
+                                        renameDependency(index, val)
+                                    }
+                                }}
+                            >
+                                {val}
+                            </Label>
+                        ))}
+                    </LabelGroup>
+                </FormGroup>
+            </CardBody>
+        </Card>
+    )
+}
diff --git a/karavan-web/karavan-app/src/main/resources/application.properties 
b/karavan-web/karavan-app/src/main/resources/application.properties
index 67990ecb..13a50355 100644
--- a/karavan-web/karavan-app/src/main/resources/application.properties
+++ b/karavan-web/karavan-app/src/main/resources/application.properties
@@ -121,7 +121,7 @@ quarkus.quinoa.enable-spa-routing=true
 quarkus.http.enable-compression=true
 quarkus.log.level=INFO
 quarkus.banner.enabled=false
-quarkus.package.type=uber-jar
+quarkus.package.type=fast-jar
 quarkus.docker.dockerfile-jvm-path=src/main/docker/Dockerfile.jdk
 #quarkus.docker.dockerfile-jvm-path=src/main/docker/Dockerfile.minimal
 quarkus.container-image.builder=docker
diff --git 
a/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletDefinitionPropertyCard.tsx
 
b/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletDefinitionPropertyCard.tsx
index d8933df4..cf42ef6c 100644
--- 
a/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletDefinitionPropertyCard.tsx
+++ 
b/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletDefinitionPropertyCard.tsx
@@ -19,10 +19,18 @@ import {
     Button,
     Card,
     CardBody,
-    CardTitle, Flex, FlexItem,
-    FormGroup, FormSelect, FormSelectOption,
+    CardTitle,
+    Flex,
+    FlexItem,
+    FormGroup,
+    FormSelect,
+    FormSelectOption,
     Grid,
-    GridItem, Label, Modal, Switch,
+    GridItem,
+    Label,
+    LabelGroup,
+    Modal,
+    Switch,
     TextInput,
 } from '@patternfly/react-core';
 import '../karavan.css';
@@ -30,6 +38,8 @@ import './kamelet.css';
 import {useIntegrationStore} from "../DesignerStore";
 import {shallow} from "zustand/shallow";
 import {DefinitionProperty} from 
"karavan-core/lib/model/IntegrationDefinition";
+import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
+import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-circle-icon";
 
 interface Props {
     index: number
@@ -45,7 +55,7 @@ export function KameletDefinitionPropertyCard(props: Props) {
     const key = props.propKey;
     const required = integration.spec.definition?.required || [];
 
-    function setPropertyValue(field: string, value: string) {
+    function setPropertyValue(field: string, value: any) {
         if (integration.spec.definition?.properties) {
             (integration.spec.definition?.properties as any)[key][field] = 
value;
             setIntegration(integration, true);
@@ -83,8 +93,9 @@ export function KameletDefinitionPropertyCard(props: Props) {
                         aria-label="FormSelect Input"
                         ouiaId="BasicFormSelect"
                     >
-                        {['string', 'number', 'boolean'].map((option, index) 
=> (
-                            <FormSelectOption key={option} isDisabled={false} 
id={key + field} name={key + field} value={option} label={option} />
+                        {['string', 'number', 'integer', 
'boolean'].map((option, index) => (
+                            <FormSelectOption key={option} isDisabled={false} 
id={key + field} name={key + field}
+                                              value={option} label={option}/>
                         ))}
                     </FormSelect>
                 </FormGroup>
@@ -92,9 +103,106 @@ export function KameletDefinitionPropertyCard(props: 
Props) {
         )
     }
 
+    function sortEnum(source: string, dest: string) {
+        const i = CamelUtil.cloneIntegration(integration);
+        if (i.spec.definition && integration.spec.definition?.properties[key]) 
{
+            const enums: string [] = i.spec.definition.properties[key].enum;
+            console.log(enums)
+            if (enums && Array.isArray(enums)) {
+                console.log("isArray")
+                const from = enums.findIndex(e => source);
+                const to = enums.findIndex(e => dest);
+                if (from > -1 && to > -1) {
+                    console.log("exchange");
+                    [enums[from], enums[to]] = [enums[to], enums[from]];
+                    i.spec.definition.properties[key].enum = enums;
+                    console.log("i.spec.definition.properties[key].enum", 
i.spec.definition.properties[key].enum);
+                    setIntegration(i, true);
+                }
+            }
+        }
+    }
+
+    function addEnum() {
+        const i = CamelUtil.cloneIntegration(integration);
+        if (i.spec.definition && integration.spec.definition?.properties[key]) 
{
+            let enums: string [] = i.spec.definition.properties[key].enum;
+            if (enums && Array.isArray(enums)) {
+                enums.push("enum")
+            } else {
+                enums = ['enum'];
+            }
+            i.spec.definition.properties[key].enum = enums;
+            setIntegration(i, true);
+        }
+    }
+
+    function deleteEnum(val: string) {
+        const enumVal = getPropertyValue('enum');
+        const i = CamelUtil.cloneIntegration(integration);
+        if (enumVal && Array.isArray(enumVal) && i.spec.definition) {
+            const enums: string[] = [...enumVal];
+            setPropertyValue('enum', enums.filter(e => e !== val));
+        }
+    }
+
+    function renameEnum(index: number, newVal: string) {
+        const enumVal = getPropertyValue('enum');
+        const i = CamelUtil.cloneIntegration(integration);
+        if (enumVal && Array.isArray(enumVal) && i.spec.definition) {
+            const enums: string[] = [...enumVal];
+            enums[index] = newVal;
+            setPropertyValue('enum', enums);
+        }
+    }
+
+    function getPropertyEnumField(field: string, label: string, isRequired: 
boolean, span: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12) {
+        const enumVal = getPropertyValue(field);
+        return (
+            <GridItem span={span}>
+                <FormGroup fieldId={key + field} isRequired={isRequired}>
+                    <LabelGroup
+                        categoryName={label}
+                        numLabels={enumVal?.length || 0}
+                        isEditable
+                        addLabelControl={
+                            <Button variant="link" icon={<AddIcon/>} 
onClick={event => addEnum()}>
+                                Add
+                            </Button>
+                        }
+                    >
+                        {enumVal && enumVal.map((val: string, index: number) 
=> (
+                            <Label
+                                key={val}
+                                id={val}
+                                color="grey"
+                                isEditable
+                                onClose={() => deleteEnum(val)}
+                                onEditCancel={(_event, prevText) => {}}
+                                onEditComplete={(event, newText) => {
+                                    if (event.type === 'mousedown') {
+                                        renameEnum(index, val)
+                                    } else if (event.type === 'keydown' && 
(event as KeyboardEvent).key === 'Tab') {
+                                        renameEnum(index, newText)
+                                    } else if (event.type === 'keydown' && 
(event as KeyboardEvent).key === 'Enter') {
+                                        renameEnum(index, newText)
+                                    } else {
+                                        renameEnum(index, val)
+                                    }
+                                }}
+                            >
+                                {val}
+                            </Label>
+                        ))}
+                    </LabelGroup>
+                </FormGroup>
+            </GridItem>
+        )
+    }
+
     function renameProperty(newKey: string) {
         const oldKey = key;
-        newKey = newKey.replace(/[\W_]+/g,'');
+        newKey = newKey.replace(/[\W_]+/g, '');
         if (oldKey !== newKey) {
             if (integration.spec.definition?.properties) {
                 const o = (integration.spec.definition?.properties as any)
@@ -138,7 +246,6 @@ export function KameletDefinitionPropertyCard(props: Props) 
{
     }
 
     function setRequired(checked: boolean) {
-        console.log(required, key)
         const newRequired = [...required];
         if (checked && !newRequired.includes(key)) {
             newRequired.push(key);
@@ -146,7 +253,6 @@ export function KameletDefinitionPropertyCard(props: Props) 
{
             const index = newRequired.findIndex(r => r === key);
             newRequired.splice(index, 1);
         }
-        // console.log(newRequired)
         if (integration.spec.definition?.required) {
             integration.spec.definition.required.length = 0;
             integration.spec.definition.required.push(...newRequired)
@@ -212,6 +318,7 @@ export function KameletDefinitionPropertyCard(props: Props) 
{
                     {getPropertyField("format", "Format", false, 3)}
                     {getPropertyField("example", "Example", false, 6)}
                     {getPropertyField("default", "Default", false, 3)}
+                    {getPropertyValue('type') === 'string' && 
getPropertyEnumField("enum", "Enum", true, 12)}
                     {/*{getPropertyField("x-descriptors", "Descriptors", 
false, 12)}*/}
                 </Grid>
             </CardBody>
diff --git 
a/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletDefinitionsPanel.tsx
 
b/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletDefinitionsPanel.tsx
index 009a54ac..0d3f04a4 100644
--- 
a/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletDefinitionsPanel.tsx
+++ 
b/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletDefinitionsPanel.tsx
@@ -19,11 +19,13 @@ import {
     Button,
     Card,
     CardBody,
-    CardTitle, Flex, FlexItem,
+    CardTitle,
+    Flex,
+    FlexItem,
     Form,
     FormGroup,
     Grid,
-    GridItem,
+    GridItem, TextArea,
     TextInput,
 } from '@patternfly/react-core';
 import '../karavan.css';
@@ -32,6 +34,9 @@ import {useIntegrationStore} from "../DesignerStore";
 import {shallow} from "zustand/shallow";
 import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-circle-icon";
 import {KameletDefinitionPropertyCard} from "./KameletDefinitionPropertyCard";
+import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
+import {DefinitionProperty} from 
"karavan-core/lib/model/IntegrationDefinition";
+import {KameletDependenciesCard} from "./KameletDependenciesCard";
 
 export function KameletDefinitionsPanel() {
 
@@ -53,7 +58,7 @@ export function KameletDefinitionsPanel() {
         }
     }
 
-    function getElement(key: string, label: string, span: 1 | 2 | 3 | 4 | 5 | 
6 | 7 | 8 | 9 | 10 | 11 | 12) {
+    function getElementTextInput(key: string, label: string, span: 1 | 2 | 3 | 
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12) {
         return (
             <GridItem span={span}>
                 <FormGroup label={label} fieldId={key} isRequired>
@@ -65,7 +70,43 @@ export function KameletDefinitionsPanel() {
         )
     }
 
+    function getElementTextArea(key: string, label: string, span: 1 | 2 | 3 | 
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12) {
+        return (
+            <GridItem span={span}>
+                <FormGroup label={label} fieldId={key} isRequired>
+                    <TextArea type="text" id={key} name={key} autoResize
+                               onChange={(_, value) => setValue(key, value)}
+                               value={getValue(key)}/>
+                </FormGroup>
+            </GridItem>
+        )
+    }
+
     const properties = integration.spec.definition?.properties ? 
Object.keys(integration.spec.definition?.properties) : [];
+
+    function addNewProperty() {
+        const i = CamelUtil.cloneIntegration(integration);
+        if (i.spec.definition && integration.spec.definition?.properties) {
+            const propertyName = generatePropertyName();
+            i.spec.definition.properties = Object.assign({[propertyName]: new 
DefinitionProperty()}, integration.spec.definition.properties);
+            setIntegration(i, true);
+        }
+    }
+
+    function generatePropertyName(count: number = 0): string {
+        const prefix = 'property';
+        const propName = 'property' + count;
+        if (integration.spec.definition?.properties) {
+            const keys = Object.keys(integration.spec.definition?.properties);
+            if (keys.includes(propName)) {
+                return generatePropertyName(count + 1);
+            } else {
+                return propName;
+            }
+        }
+        return prefix;
+    }
+
     return (
         <>
             <Card isCompact ouiaId="DefinitionsCard">
@@ -73,9 +114,9 @@ export function KameletDefinitionsPanel() {
                 <CardBody>
                     <Form>
                         <Grid hasGutter>
-                            {getElement('title', 'Title', 4)}
-                            {getElement('description', 'Description', 6)}
-                            {getElement('type', 'Type', 2)}
+                            {getElementTextInput('title', 'Title', 3)}
+                            {getElementTextArea('description', 'Description', 
9)}
+                            {/*{getElementTextInput('type', 'Type', 2)}*/}
                         </Grid>
                     </Form>
                 </CardBody>
@@ -86,7 +127,9 @@ export function KameletDefinitionsPanel() {
                     <Flex>
                         <FlexItem>Properties</FlexItem>
                         <FlexItem align={{default: "alignRight"}}>
-                            <Button variant={"link"} icon={<AddIcon/>}>Add 
property</Button>
+                            <Button variant={"link"} icon={<AddIcon/>} 
onClick={event => addNewProperty()}>
+                                Add property
+                            </Button>
                         </FlexItem>
                     </Flex>
                 </CardTitle>
@@ -102,6 +145,8 @@ export function KameletDefinitionsPanel() {
                     </Form>
                 </CardBody>
             </Card>
+            <div style={{height: "20px"}}/>
+            <KameletDependenciesCard/>
         </>
 
     )
diff --git 
a/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletDependenciesCard.tsx
 
b/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletDependenciesCard.tsx
new file mode 100644
index 00000000..893c897b
--- /dev/null
+++ 
b/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletDependenciesCard.tsx
@@ -0,0 +1,113 @@
+/*
+ * 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 React from 'react';
+import {
+    Button,
+    Card,
+    CardBody,
+    CardTitle,
+    FormGroup, FormHelperText, HelperText, HelperTextItem,
+    Label,
+    LabelGroup,
+} from '@patternfly/react-core';
+import '../karavan.css';
+import './kamelet.css';
+import {useIntegrationStore} from "../DesignerStore";
+import {shallow} from "zustand/shallow";
+import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-circle-icon";
+import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
+
+export function KameletDependenciesCard() {
+
+    const [integration, setIntegration] = useIntegrationStore((s) => 
[s.integration, s.setIntegration], shallow)
+
+    const dependencies: string[] = [...(integration.spec.dependencies || [])];
+
+
+    function setDependencies(deps: string[]) {
+        const i = CamelUtil.cloneIntegration(integration);
+        i.spec.dependencies = deps;
+        setIntegration(i, true);
+    }
+
+    function addDepencency() {
+        dependencies.push("dependency")
+        setDependencies(dependencies);
+    }
+
+    function deleteDependency(val: string) {
+        setDependencies(dependencies.filter(e => e !== val));
+    }
+
+    function renameDependency(index: number, newVal: string) {
+        dependencies[index] = newVal;
+        setDependencies(dependencies);
+    }
+
+    return (
+        <Card isClickable isCompact isFlat ouiaId="PropertyCard" 
className="property-card">
+            <CardTitle>
+                Dependencies
+            </CardTitle>
+            <CardBody>
+                <FormHelperText>
+                    <HelperText>
+                        <HelperTextItem>Dependencies required, ex: 
camel:component or mvn:groupId:artifactId:version</HelperTextItem>
+                    </HelperText>
+                </FormHelperText>
+            </CardBody>
+            <CardBody>
+                <FormGroup fieldId={'dependencies'}>
+                    <LabelGroup
+                        // categoryName={"Dependencies"}
+                        numLabels={dependencies.length}
+                        isEditable
+                        addLabelControl={
+                            <Button variant="link" icon={<AddIcon/>} 
onClick={event => addDepencency()}>
+                                Add
+                            </Button>
+                        }
+                    >
+                        {dependencies.map((val: string, index: number) => (
+                            <Label
+                                key={val}
+                                id={val}
+                                color="grey"
+                                isEditable
+                                onClose={() => deleteDependency(val)}
+                                onEditCancel={(_event, prevText) => {}}
+                                onEditComplete={(event, newText) => {
+                                    if (event.type === 'mousedown') {
+                                        renameDependency(index, val)
+                                    } else if (event.type === 'keydown' && 
(event as KeyboardEvent).key === 'Tab') {
+                                        renameDependency(index, newText)
+                                    } else if (event.type === 'keydown' && 
(event as KeyboardEvent).key === 'Enter') {
+                                        renameDependency(index, newText)
+                                    } else {
+                                        renameDependency(index, val)
+                                    }
+                                }}
+                            >
+                                {val}
+                            </Label>
+                        ))}
+                    </LabelGroup>
+                </FormGroup>
+            </CardBody>
+        </Card>
+    )
+}
diff --git 
a/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletProperties.tsx
 
b/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletProperties.tsx
index fc8f188f..e5a8cfc5 100644
--- 
a/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletProperties.tsx
+++ 
b/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletProperties.tsx
@@ -14,11 +14,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import React, {useEffect, useState} from 'react';
+import React from 'react';
 import {
     Form,
-    FormGroup,
-    TextInput, Button, Title, Tooltip, Popover, InputGroup, InputGroupItem,
 } from '@patternfly/react-core';
 import '../karavan.css';
 import "@patternfly/patternfly/patternfly.css";
@@ -26,21 +24,6 @@ import {
     RegistryBeanDefinition,
 } from "karavan-core/lib/model/CamelDefinition";
 import {Integration} from "karavan-core/lib/model/IntegrationDefinition";
-import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
-import {SensitiveKeys} from "karavan-core/lib/model/CamelMetadata";
-import {v4 as uuidv4} from "uuid";
-import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-icon";
-import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-circle-icon";
-import CloneIcon from '@patternfly/react-icons/dist/esm/icons/clone-icon'
-import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon";
-import {InfrastructureSelector} from 
"../route/property/InfrastructureSelector";
-import KubernetesIcon from 
"@patternfly/react-icons/dist/js/icons/openshift-icon";
-import {InfrastructureAPI} from "../utils/InfrastructureAPI";
-import ShowIcon from "@patternfly/react-icons/dist/js/icons/eye-icon";
-import HideIcon from "@patternfly/react-icons/dist/js/icons/eye-slash-icon";
-import DockerIcon from "@patternfly/react-icons/dist/js/icons/docker-icon";
-import {useDesignerStore} from "../DesignerStore";
-import {shallow} from "zustand/shallow";
 import {IntegrationHeader} from "../utils/IntegrationHeader";
 
 
@@ -53,197 +36,11 @@ interface Props {
 
 export function KameletProperties (props: Props) {
 
-    const [selectedStep] = useDesignerStore((s) => [s.selectedStep], shallow);
-    const [infrastructureSelector, setInfrastructureSelector] = 
useState<boolean>(false);
-    const [infrastructureSelectorProperty, setInfrastructureSelectorProperty] 
= useState<string | undefined>(undefined);
-    const [infrastructureSelectorUuid, setInfrastructureSelectorUuid] = 
useState<string | undefined>(undefined);
-    const [properties, setProperties] = useState<Map<string, [string, string, 
boolean]>>(new Map<string, [string, string, boolean]>());
-
-    useEffect(()=> {
-        setProperties(preparePropertiesMap((selectedStep as 
RegistryBeanDefinition)?.properties))
-    }, [selectedStep?.uuid])
-
-    function preparePropertiesMap (properties: any): Map<string, [string, 
string, boolean]>  {
-        const result = new Map<string, [string, string, boolean]>();
-        if (properties) {
-            Object.keys(properties).forEach((k, i, a) => result.set(uuidv4(), 
[k, properties[k], false]));
-        }
-        return result;
-    }
-
-    function onBeanPropertyUpdate ()  {
-        if (selectedStep) {
-            const bean = CamelUtil.cloneBean(selectedStep);
-            const beanProperties: any = {};
-            properties.forEach((p: any) => beanProperties[p[0]] = p[1]);
-            bean.properties = beanProperties;
-            props.onChange(bean);
-        }
-    }
-
-    function beanFieldChanged (fieldId: string, value: string) {
-        if (selectedStep) {
-            const bean = CamelUtil.cloneBean(selectedStep);
-            (bean as any)[fieldId] = value;
-            props.onChange(bean);
-        }
-    }
-
-    function propertyChanged (uuid: string, key: string, value: string, 
showPassword: boolean)  {
-        setProperties(prevState => {
-            prevState.set(uuid, [key, value, showPassword]);
-            return prevState;
-        });
-        onBeanPropertyUpdate();
-    }
-
-    function propertyDeleted (uuid: string)  {
-        setProperties(prevState => {
-            prevState.delete(uuid);
-            return prevState;
-        })
-        onBeanPropertyUpdate();
-    }
-
-    function selectInfrastructure (value: string)  {
-        const propertyId = infrastructureSelectorProperty;
-        const uuid = infrastructureSelectorUuid;
-        if (propertyId && uuid){
-            if (value.startsWith("config") || value.startsWith("secret")) 
value = "{{" + value + "}}";
-            propertyChanged(uuid, propertyId, value, false);
-            setInfrastructureSelector(false);
-            setInfrastructureSelectorProperty(undefined);
-        }
-    }
-
-    function openInfrastructureSelector (uuid: string, propertyName: string)  {
-        setInfrastructureSelector(true);
-        setInfrastructureSelectorProperty(propertyName);
-        setInfrastructureSelectorUuid(uuid);
-    }
-
-    function closeInfrastructureSelector ()  {
-        setInfrastructureSelector(false);
-    }
-
-    function getInfrastructureSelectorModal() {
-        return (
-            <InfrastructureSelector
-                dark={false}
-                isOpen={infrastructureSelector}
-                onClose={() => closeInfrastructureSelector()}
-                onSelect={selectInfrastructure}/>)
-    }
-
-    function cloneBean ()  {
-        if (selectedStep) {
-            const bean = CamelUtil.cloneBean(selectedStep);
-            bean.uuid = uuidv4();
-            props.onClone(bean);
-        }
-    }
-
-    function getLabelIcon (displayName: string, description: string)  {
-        return (
-            <Popover
-                    position={"left"}
-                    headerContent={displayName}
-                    bodyContent={description}
-                    footerContent={
-                        <div>
-                            <b>Required</b>
-                        </div>
-                    }>
-                    <button type="button" aria-label="More info" onClick={e => 
{
-                        e.preventDefault();
-                        e.stopPropagation();
-                    }} className="pf-v5-c-form__group-label-help">
-                        <HelpIcon />
-                    </button>
-                </Popover>
-        )
-    }
-    function getBeanForm() {
-        const bean = (selectedStep as RegistryBeanDefinition);
-        return (
-            <>
-                <div className="headers">
-                    <div className="top">
-                        <Title headingLevel="h1" size="md">Bean</Title>
-                        <Tooltip content="Clone bean" position="bottom">
-                            <Button variant="link" onClick={() => cloneBean()} 
icon={<CloneIcon/>}/>
-                        </Tooltip>
-                    </div>
-                </div>
-                <FormGroup label="Name" fieldId="name" isRequired 
labelIcon={getLabelIcon("Name", "Bean name used as a reference ex: myBean")}>
-                    <TextInput className="text-field" isRequired type="text" 
id="name" name="name" value={bean?.name}
-                                onChange={(_, value)=> 
beanFieldChanged("name", value)}/>
-                </FormGroup>
-                <FormGroup label="Type" fieldId="type" isRequired 
labelIcon={getLabelIcon("Type", "Bean class Canonical Name ex: 
org.demo.MyBean")}>
-                    <TextInput className="text-field" isRequired type="text" 
id="type" name="type" value={bean?.type}
-                        onChange={(_, value) => beanFieldChanged("type", 
value)}/>
-                </FormGroup>
-                <FormGroup label="Properties" fieldId="properties" 
className="bean-properties">
-                    {Array.from(properties.entries()).map((v, index, array) => 
{
-                        const i = v[0];
-                        const key = v[1][0];
-                        const value = v[1][1];
-                        const showPassword = v[1][2];
-                        const isSecret = key !== undefined && 
SensitiveKeys.includes(key.toLowerCase());
-                        const inInfrastructure = 
InfrastructureAPI.infrastructure !== 'local';
-                        const icon = InfrastructureAPI.infrastructure === 
'kubernetes' ? <KubernetesIcon/> : <DockerIcon/>
-                        return (
-                            <div key={"key-" + i} className="bean-property">
-                                <TextInput placeholder="Bean Field Name" 
className="text-field" isRequired type="text" id={"key-" + i}
-                                           name={"key-" + i} value={key}
-                                            onChange={(_, beanFieldName) => {
-                                                propertyChanged(i, 
beanFieldName, value, showPassword)
-                                            }}/>
-                                <InputGroup>
-                                    {inInfrastructure &&
-                                        <Tooltip position="bottom-end" 
content="Select value from Infrastructure">
-                                        <Button variant="control" onClick={e 
=> openInfrastructureSelector(i, key)}>
-                                            {icon}
-                                        </Button>
-                                    </Tooltip>}
-                                    <InputGroupItem isFill>
-                                        <TextInput
-                                            placeholder="Bean Field Value"
-                                            type={isSecret && !showPassword ? 
"password" : "text"}
-                                            className="text-field"
-                                            isRequired
-                                            id={"value-" + i}
-                                            name={"value-" + i}
-                                            value={value}
-                                            onChange={(_, value) => {
-                                                propertyChanged(i, key, value, 
showPassword)
-                                            }}/>
-                                    </InputGroupItem>
-                                    {isSecret && <Tooltip 
position="bottom-end" content={showPassword ? "Hide" : "Show"}>
-                                        <Button variant="control" onClick={e 
=> propertyChanged(i, key, value, !showPassword)}>
-                                            {showPassword ? <ShowIcon/> : 
<HideIcon/>}
-                                        </Button>
-                                    </Tooltip>}
-                                </InputGroup>
-                                <Button variant="link" 
className="delete-button" onClick={e => 
propertyDeleted(i)}><DeleteIcon/></Button>
-                            </div>
-                        )
-                    })}
-                    <Button variant="link" className="add-button" onClick={e 
=> propertyChanged(uuidv4(), '', '', false)}>
-                        <AddIcon/>Add property</Button>
-                </FormGroup>
-            </>
-        )
-    }
-
-    const bean = (selectedStep as RegistryBeanDefinition);
     return (
-        <div className='properties' key={bean ? bean.uuid : 'integration'}>
+        <div className='properties' key={'integration'}>
             <Form autoComplete="off" onSubmit={event => 
event.preventDefault()}>
-                {bean === undefined && <IntegrationHeader/>}
-                {bean !== undefined && getBeanForm()}
+                <IntegrationHeader/>
             </Form>
-            {getInfrastructureSelectorModal()}
         </div>
     )
 }
diff --git 
a/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletTypesOutCard.tsx
 
b/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletTypesOutCard.tsx
new file mode 100644
index 00000000..76b590ee
--- /dev/null
+++ 
b/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/KameletTypesOutCard.tsx
@@ -0,0 +1,113 @@
+/*
+ * 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 React from 'react';
+import {
+    Button,
+    Card,
+    CardBody,
+    CardTitle,
+    FormGroup, FormHelperText, HelperText, HelperTextItem,
+    Label,
+    LabelGroup,
+} from '@patternfly/react-core';
+import '../karavan.css';
+import './kamelet.css';
+import {useIntegrationStore} from "../DesignerStore";
+import {shallow} from "zustand/shallow";
+import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-circle-icon";
+import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
+
+export function KameletTypesOutCard() {
+
+    const [integration, setIntegration] = useIntegrationStore((s) => 
[s.integration, s.setIntegration], shallow)
+
+    const dependencies: string[] = [...(integration.spec.dependencies || [])];
+
+
+    function setDependencies(deps: string[]) {
+        const i = CamelUtil.cloneIntegration(integration);
+        i.spec.dependencies = deps;
+        setIntegration(i, true);
+    }
+
+    function addDepencency() {
+        dependencies.push("dependency")
+        setDependencies(dependencies);
+    }
+
+    function deleteDependency(val: string) {
+        setDependencies(dependencies.filter(e => e !== val));
+    }
+
+    function renameDependency(index: number, newVal: string) {
+        dependencies[index] = newVal;
+        setDependencies(dependencies);
+    }
+
+    return (
+        <Card isClickable isCompact isFlat ouiaId="PropertyCard" 
className="property-card">
+            <CardTitle>
+                Dependencies
+            </CardTitle>
+            <CardBody>
+                <FormHelperText>
+                    <HelperText>
+                        <HelperTextItem>Dependencies required, ex: 
camel:component or mvn:groupId:artifactId:version</HelperTextItem>
+                    </HelperText>
+                </FormHelperText>
+            </CardBody>
+            <CardBody>
+                <FormGroup fieldId={'dependencies'}>
+                    <LabelGroup
+                        // categoryName={"Dependencies"}
+                        numLabels={dependencies.length}
+                        isEditable
+                        addLabelControl={
+                            <Button variant="link" icon={<AddIcon/>} 
onClick={event => addDepencency()}>
+                                Add
+                            </Button>
+                        }
+                    >
+                        {dependencies.map((val: string, index: number) => (
+                            <Label
+                                key={val}
+                                id={val}
+                                color="grey"
+                                isEditable
+                                onClose={() => deleteDependency(val)}
+                                onEditCancel={(_event, prevText) => {}}
+                                onEditComplete={(event, newText) => {
+                                    if (event.type === 'mousedown') {
+                                        renameDependency(index, val)
+                                    } else if (event.type === 'keydown' && 
(event as KeyboardEvent).key === 'Tab') {
+                                        renameDependency(index, newText)
+                                    } else if (event.type === 'keydown' && 
(event as KeyboardEvent).key === 'Enter') {
+                                        renameDependency(index, newText)
+                                    } else {
+                                        renameDependency(index, val)
+                                    }
+                                }}
+                            >
+                                {val}
+                            </Label>
+                        ))}
+                    </LabelGroup>
+                </FormGroup>
+            </CardBody>
+        </Card>
+    )
+}
diff --git 
a/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/kamelet.css 
b/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/kamelet.css
index bbdf28a9..c72acad2 100644
--- a/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/kamelet.css
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/kamelet/kamelet.css
@@ -23,6 +23,7 @@
     padding-bottom: 106px;
 }
 
+.karavan .kamelet-designer .pf-v5-c-drawer__content,
 .karavan .kamelet-designer .main {
     background-color: var(--pf-v5-global--BackgroundColor--light-300);
 }

Reply via email to