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/09/29 00:05:34 UTC

[camel-karavan] branch main updated (f4d2b05b -> aa7b5078)

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 f4d2b05b Custom Kamelets in DevMode in Docker #913
     new aa99df10 Fix #915
     new aa7b5078 Read/write Kamelets in core #315

The 2 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/api/CamelDefinitionYaml.ts   | 104 +++++++++++++------
 .../src/core/model/IntegrationDefinition.ts        |  62 ++++++++++-
 karavan-core/test/integration.spec.ts              |   1 +
 karavan-core/test/kamelet.spec.ts                  |  66 ++++++++++++
 karavan-core/test/plain.spec.ts                    |   2 +-
 karavan-core/test/postgresql-source.kamelet.yaml   | 114 +++++++++++++++++++++
 .../src/designer/route/useRouteDesignerHook.tsx    |  15 +--
 .../apache/camel/karavan/api/KameletResources.java |   6 +-
 .../src/designer/route/useRouteDesignerHook.tsx    |  15 +--
 .../src/main/webui/src/project/file/FileEditor.tsx |   7 +-
 10 files changed, 335 insertions(+), 57 deletions(-)
 create mode 100644 karavan-core/test/kamelet.spec.ts
 create mode 100644 karavan-core/test/postgresql-source.kamelet.yaml


[camel-karavan] 02/02: Read/write Kamelets in core #315

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 aa7b507855f7367c91897a86bbdabca31bf2414e
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Thu Sep 28 20:05:23 2023 -0400

    Read/write Kamelets in core #315
---
 karavan-core/src/core/api/CamelDefinitionYaml.ts   | 104 +++++++++++++------
 .../src/core/model/IntegrationDefinition.ts        |  62 ++++++++++-
 karavan-core/test/integration.spec.ts              |   1 +
 karavan-core/test/kamelet.spec.ts                  |  66 ++++++++++++
 karavan-core/test/plain.spec.ts                    |   2 +-
 karavan-core/test/postgresql-source.kamelet.yaml   | 114 +++++++++++++++++++++
 .../apache/camel/karavan/api/KameletResources.java |   6 +-
 .../src/designer/route/useRouteDesignerHook.tsx    |  15 +--
 .../src/main/webui/src/project/file/FileEditor.tsx |   7 +-
 9 files changed, 327 insertions(+), 50 deletions(-)

diff --git a/karavan-core/src/core/api/CamelDefinitionYaml.ts b/karavan-core/src/core/api/CamelDefinitionYaml.ts
index ba086ef7..44feabdd 100644
--- a/karavan-core/src/core/api/CamelDefinitionYaml.ts
+++ b/karavan-core/src/core/api/CamelDefinitionYaml.ts
@@ -15,13 +15,14 @@
  * limitations under the License.
  */
 import * as yaml from 'js-yaml';
-import { Integration, CamelElement, Beans } from '../model/IntegrationDefinition';
-import { RouteDefinition, RegistryBeanDefinition, RouteConfigurationDefinition } from '../model/CamelDefinition';
+import { Beans, CamelElement, Integration } from '../model/IntegrationDefinition';
+import { RegistryBeanDefinition, RouteConfigurationDefinition, RouteDefinition } from '../model/CamelDefinition';
 import { CamelUtil } from './CamelUtil';
 import { CamelDefinitionYamlStep } from './CamelDefinitionYamlStep';
 
 export class CamelDefinitionYaml {
-    private constructor() {}
+    private constructor() {
+    }
 
     static integrationToYaml = (integration: Integration): string => {
         const clone: any = CamelUtil.cloneIntegration(integration);
@@ -32,14 +33,28 @@ export class CamelDefinitionYaml {
         if (integration.type === 'crd') {
             delete clone.type;
             const i = JSON.parse(JSON.stringify(clone, (key, value) => CamelDefinitionYaml.replacer(key, value), 3)); // fix undefined in string attributes
-            const text = CamelDefinitionYaml.yamlDump(i);
-            return text;
+            return CamelDefinitionYaml.yamlDump(i);
+        } else if (integration.type === 'kamelet') {
+            delete clone.type;
+            // turn array of flows to object properties in template for Kamelet
+            const template: any = {route: {}}
+            const route: RouteDefinition = clone.spec.flows.filter((f: any) => f.dslName === 'RouteDefinition')?.[0];
+            if (route) {
+                template.route = Object.assign(template.route, route);
+            }
+            const beans = clone.spec.flows.filter((f: any) => f.dslName === 'Beans')?.at(0)?.beans;
+            if (beans) {
+                template.beans = beans;
+            }
+            clone.spec.template = template;
+            delete clone.spec.flows;
+            const i = JSON.parse(JSON.stringify(clone, (key, value) => CamelDefinitionYaml.replacer(key, value, true), 3)); // fix undefined in string attributes
+            return CamelDefinitionYaml.yamlDump(i);
         } else {
             const f = JSON.parse(
                 JSON.stringify(clone.spec.flows, (key, value) => CamelDefinitionYaml.replacer(key, value), 3),
             );
-            const text = CamelDefinitionYaml.yamlDump(f);
-            return text;
+            return CamelDefinitionYaml.yamlDump(f);
         }
     };
 
@@ -109,7 +124,7 @@ export class CamelDefinitionYaml {
         return yaml.dump(integration, {
             noRefs: false,
             noArrayIndent: false,
-            sortKeys: function (a: any, b: any) {
+            sortKeys: function(a: any, b: any) {
                 if (a === 'steps') return 1;
                 else if (b === 'steps') return -1;
                 else return 0;
@@ -117,7 +132,7 @@ export class CamelDefinitionYaml {
         });
     };
 
-    static replacer = (key: string, value: any): any => {
+    static replacer = (key: string, value: any, isKamelet: boolean = false): any => {
         if (
             typeof value === 'object' &&
             (value.hasOwnProperty('stepName') || value.hasOwnProperty('inArray') || value.hasOwnProperty('inSteps'))
@@ -162,6 +177,10 @@ export class CamelDefinitionYaml {
                 delete newValue.inArray;
                 delete newValue.inSteps;
                 return newValue;
+            } else if (isKamelet && dslName === 'RouteDefinition') {
+                delete value?.dslName;
+                delete value?.stepName;
+                return value;
             } else {
                 delete newValue.inArray;
                 delete newValue.inSteps;
@@ -179,18 +198,37 @@ export class CamelDefinitionYaml {
         const integration: Integration = Integration.createNew(filename);
         const fromYaml: any = yaml.load(text);
         const camelized: any = CamelUtil.camelizeObject(fromYaml);
-        if (
-            camelized?.apiVersion &&
-            camelized.apiVersion.startsWith('camel.apache.org') &&
-            camelized.kind &&
-            camelized.kind === 'Integration'
-        ) {
-            integration.type = 'crd';
-            if (camelized?.metadata?.name) {
-                integration.metadata.name = camelized?.metadata?.name;
+        if (camelized?.apiVersion && camelized.apiVersion.startsWith('camel.apache.org') && camelized.kind) {
+            if (camelized?.metadata) {
+                integration.metadata = camelized?.metadata;
+            }
+            if (camelized?.spec) {
+                integration.spec.definition = camelized?.spec.definition;
+                integration.spec.dependencies = camelized?.spec.dependencies;
+                integration.spec.types = camelized?.spec.types;
             }
             const int: Integration = new Integration({ ...camelized });
-            integration.spec.flows?.push(...CamelDefinitionYaml.flowsToCamelElements(int.spec.flows || []));
+            if (camelized.kind === 'Integration') {
+                integration.type = 'crd';
+                integration.spec.flows?.push(...CamelDefinitionYaml.flowsToCamelElements(int.spec.flows || []));
+            } else if (camelized.kind === 'Kamelet') {
+                integration.type = 'kamelet';
+                integration.kind = 'Kamelet';
+                const flows: any[] = [];
+                // turn kamelet template object properties to array of flows
+                const beans = int.spec.template?.beans;
+                if (beans) {
+                    flows.push(new Beans({beans: beans}))
+                }
+                const from = int.spec.template?.from;
+                if (from) {
+                    flows.push(new RouteDefinition({from: from}))
+                } else {
+                    const route = int.spec.template?.route;
+                    flows.push(route);
+                }
+                integration.spec.flows?.push(...CamelDefinitionYaml.flowsToCamelElements(flows || []));
+            }
         } else if (Array.isArray(camelized)) {
             integration.type = 'plain';
             const flows: any[] = camelized;
@@ -200,18 +238,22 @@ export class CamelDefinitionYaml {
     };
 
     static yamlIsIntegration = (text: string): boolean => {
-        const fromYaml: any = yaml.load(text);
-        const camelized: any = CamelUtil.camelizeObject(fromYaml);
-        if (
-            camelized?.apiVersion &&
-            camelized.apiVersion.startsWith('camel.apache.org') &&
-            camelized.kind &&
-            camelized.kind === 'Integration'
-        ) {
-            return true;
-        } else if (Array.isArray(camelized)) {
-            return true;
-        } else {
+        try {
+            const fromYaml: any = yaml.load(text);
+            const camelized: any = CamelUtil.camelizeObject(fromYaml);
+            if (
+                camelized?.apiVersion &&
+                camelized.apiVersion.startsWith('camel.apache.org') &&
+                camelized.kind &&
+                camelized.kind === 'Integration'
+            ) {
+                return true;
+            } else if (Array.isArray(camelized)) {
+                return true;
+            } else {
+                return false;
+            }
+        } catch (e) {
             return false;
         }
     };
diff --git a/karavan-core/src/core/model/IntegrationDefinition.ts b/karavan-core/src/core/model/IntegrationDefinition.ts
index 3af3c6c5..c6c53d46 100644
--- a/karavan-core/src/core/model/IntegrationDefinition.ts
+++ b/karavan-core/src/core/model/IntegrationDefinition.ts
@@ -17,16 +17,69 @@
 import { v4 as uuidv4 } from 'uuid';
 import { RegistryBeanDefinition } from './CamelDefinition';
 
+export class KameletDefinitionProperty {
+    title: string = '';
+    description: string = '';
+    type: 'string' | 'integer' | 'boolean' = 'string';
+    default?: any;
+    example?: any;
+    format?: string;
+    "x-descriptors"?: string[];
+    properties: any = {};
+
+    public constructor(init?: Partial<KameletDefinition>) {
+        Object.assign(this, init);
+    }
+}
+
+export class KameletDefinition {
+    title: string = '';
+    description: string = '';
+    required: string[] = [];
+    type: string = 'object';
+    properties: any = {};
+
+    public constructor(init?: Partial<KameletDefinition>) {
+        Object.assign(this, init);
+    }
+}
+
 export class Spec {
+    definition?: KameletDefinition;
+    types?: any;
     flows?: any[] = [];
+    template?: any;
+    dependencies?: string[];
 
     public constructor(init?: Partial<Spec>) {
         Object.assign(this, init);
     }
 }
 
+export class MetadataLabel {
+    "camel.apache.org/kamelet.type": "sink" | "source" | "action"
+
+    public constructor(init?: Partial<MetadataLabel>) {
+        Object.assign(this, init);
+    }
+}
+
+export class MetadataAnnotation {
+    "camel.apache.org/catalog.version"?: string;
+    "camel.apache.org/kamelet.icon"?: string;
+    "camel.apache.org/provider"?: string;
+    "camel.apache.org/kamelet.group"?: string;
+    "camel.apache.org/kamelet.namespace"?: string;
+
+    public constructor(init?: Partial<MetadataAnnotation>) {
+        Object.assign(this, init);
+    }
+}
+
 export class Metadata {
     name: string = '';
+    annotations?: MetadataAnnotation;
+    labels?: MetadataLabel[];
 
     public constructor(init?: Partial<Metadata>) {
         Object.assign(this, init);
@@ -34,8 +87,8 @@ export class Metadata {
 }
 
 export class Integration {
-    apiVersion: string = 'camel.apache.org/v1'; // camel.apache.org/v1alpha1
-    kind: string = 'Integration'; // Kamelet
+    apiVersion: string = 'camel.apache.org/v1';
+    kind: string = 'Integration' || 'Kamelet';
     metadata: Metadata = new Metadata();
     spec: Spec = new Spec();
     type: 'crd' | 'plain' | 'kamelet' = 'crd';
@@ -45,7 +98,10 @@ export class Integration {
     }
 
     static createNew(name?: string, type: 'crd' | 'plain' | 'kamelet' = 'plain'): Integration {
-        return new Integration({ type: type, metadata: new Metadata({ name: name }), spec: new Spec({ flows: [] }) });
+        return new Integration({ type: type,
+            metadata: new Metadata({ name: name }),
+            kind : type === 'kamelet' ? 'Kamelet' : 'Integration',
+            spec: new Spec({ flows: [] }) });
     }
 }
 
diff --git a/karavan-core/test/integration.spec.ts b/karavan-core/test/integration.spec.ts
index 242f48a3..ae83d539 100644
--- a/karavan-core/test/integration.spec.ts
+++ b/karavan-core/test/integration.spec.ts
@@ -39,6 +39,7 @@ describe('CRD YAML to Integration', () => {
             expect(t.uri).to.equal("log");
             expect(t.parameters.level).to.equal("OFF");
         }
+        console.log(CamelDefinitionYaml.integrationToYaml(i))
     });
 
     it('YAML <-> Object 2', () => {
diff --git a/karavan-core/test/kamelet.spec.ts b/karavan-core/test/kamelet.spec.ts
new file mode 100644
index 00000000..691bf48e
--- /dev/null
+++ b/karavan-core/test/kamelet.spec.ts
@@ -0,0 +1,66 @@
+/*
+ * 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 {expect} from 'chai';
+import * as fs from 'fs';
+import 'mocha';
+import {CamelDefinitionYaml} from "../src/core/api/CamelDefinitionYaml";
+import {
+    ChoiceDefinition,
+    ExpressionDefinition,
+    FilterDefinition, FromDefinition, LogDefinition,
+    ToDefinition,
+    WhenDefinition,
+} from '../src/core/model/CamelDefinition';
+import { RouteDefinition} from "../src/core/model/CamelDefinition";
+import { Beans, Integration, MetadataAnnotation } from '../src/core/model/IntegrationDefinition';
+import { KameletMetadata } from '../lib/model/KameletModels';
+import { RegistryBeanDefinition } from '../lib/model/CamelDefinition';
+
+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)
+        console.log(CamelDefinitionYaml.integrationToYaml(i))
+    });
+
+    it('Kamelet to YAML with beans', () => {
+        const i = Integration.createNew("test", 'kamelet');
+
+        const flow1 = new FromDefinition({uri: "direct1"});
+        flow1.steps?.push(new LogDefinition({logName: 'log11', message: "hello11"}));
+        i.spec.flows?.push(new RouteDefinition({from:flow1}));
+
+        const b = new Beans();
+        b.beans.push(new RegistryBeanDefinition({name: "beanDS1", type: "String.class"}));
+        b.beans.push(new RegistryBeanDefinition({name: "beanDS2", type: "String.class"}));
+        i.spec.flows?.push(b);
+        const a = new MetadataAnnotation({"camel.apache.org/kamelet.group" : "hello world"})
+        i.metadata.annotations = a
+    });
+
+    it('Kamelet to YAML without beans', () => {
+        const i = Integration.createNew("test", 'kamelet');
+
+        const flow1 = new FromDefinition({uri: "direct1"});
+        flow1.steps?.push(new LogDefinition({logName: 'log11', message: "hello11"}));
+        i.spec.flows?.push(new RouteDefinition({from:flow1}));
+    });
+
+
+});
\ No newline at end of file
diff --git a/karavan-core/test/plain.spec.ts b/karavan-core/test/plain.spec.ts
index 627a6a77..8e10daef 100644
--- a/karavan-core/test/plain.spec.ts
+++ b/karavan-core/test/plain.spec.ts
@@ -59,7 +59,7 @@ describe('Plain YAML to integration', () => {
         expect(i.spec.flows?.length).to.equal(1);
         expect(i.type).to.equal('plain');
         const yaml2 = CamelDefinitionYaml.integrationToYaml(i);
-        expect(yaml.replaceAll("\r\n", "\n")).to.equal(yaml2); // replace for Windows compatibility
+        expect(yaml.replace("\r\n", "\n")).to.equal(yaml2); // replace for Windows compatibility
     });
 
 });
diff --git a/karavan-core/test/postgresql-source.kamelet.yaml b/karavan-core/test/postgresql-source.kamelet.yaml
new file mode 100644
index 00000000..2fcd541e
--- /dev/null
+++ b/karavan-core/test/postgresql-source.kamelet.yaml
@@ -0,0 +1,114 @@
+# ---------------------------------------------------------------------------
+# 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.
+# ---------------------------------------------------------------------------
+apiVersion: camel.apache.org/v1
+kind: Kamelet
+metadata:
+  name: postgresql-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,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+UG9zdGdyZVNRTCBpY29uPC90aXRsZT48cGF0aCBkPSJNMTcuMTI4IDBhMTAuMTM0IDEwLjEzNCAwIDAgMC0yLjc1NS40MDNsLS4wNjMuMDJBMTAuOTIyIDEwLjkyMiAwIDAgMCAxMi42LjI1OEMxMS40MjIuMjM4IDEwLjQxLjUyNCA5LjU5NCAxIDguNzkuNzIxIDcuMTIyLjI0IDUuMzY0LjMzNiA0LjE0LjQwMyAyLjgwNC43NzUgMS44MTQgMS44Mi44MjcgMi44NjUuMzA1IDQuNDgyLjQxNSA2LjY4MmMuMDMuNjA3LjIwMyAxLjU5Ny [...]
+    camel.apache.org/provider: "Apache Software Foundation"
+    camel.apache.org/kamelet.group: "SQL"
+    camel.apache.org/kamelet.namespace: "Database"
+  labels:
+    camel.apache.org/kamelet.type: "source"
+spec:
+  definition:
+    title: "PostgreSQL Source"
+    description: |-
+      Query data from a PostgreSQL Database.
+    required:
+      - serverName
+      - username
+      - password
+      - query
+      - databaseName
+    type: object
+    properties:
+      serverName:
+        title: Server Name
+        description: The server name for the data source.
+        type: string
+        example: localhost
+      serverPort:
+        title: Server Port
+        description: The server port for the data source.
+        type: string
+        default: 5432
+      username:
+        title: Username
+        description: The username to access a secured PostgreSQL Database.
+        type: string
+        x-descriptors:
+          - urn:camel:group:credentials
+      password:
+        title: Password
+        description: The password to access a secured PostgreSQL Database.
+        type: string
+        format: password
+        x-descriptors:
+          - urn:alm:descriptor:com.tectonic.ui:password
+          - urn:camel:group:credentials
+      query:
+        title: Query
+        description: The query to execute against the PostgreSQL Database.
+        type: string
+        example: 'INSERT INTO accounts (username,city) VALUES (:#username,:#city)'
+      databaseName:
+        title: Database Name
+        description: The name of the PostgreSQL Database.
+        type: string
+      consumedQuery:
+        title: Consumed Query
+        description: A query to run on a tuple consumed.
+        type: string
+        example: 'DELETE FROM accounts where user_id = :#user_id'
+      delay:
+        title: Delay
+        description: The number of milliseconds before the next poll
+        type: integer
+        default: 500
+  types:
+    out:
+      mediaType: application/json
+  dependencies:
+    - "camel:jackson"
+    - "camel:kamelet"
+    - "camel:sql"
+    - "mvn:org.postgresql:postgresql:42.6.0"
+    - "mvn:org.apache.commons:commons-dbcp2:2.10.0"
+  template:
+    beans:
+      - name: dsBean
+        type: "#class:org.apache.commons.dbcp2.BasicDataSource"
+        properties:
+          username: '{{username}}'
+          password: '{{password}}'
+          url: 'jdbc:postgresql://{{serverName}}:{{serverPort}}/{{databaseName}}'
+          driverClassName: 'org.postgresql.Driver'
+    from:
+      uri: "sql:{{query}}"
+      parameters:
+        dataSource: "#bean:{{dsBean}}"
+        onConsume: "{{?consumedQuery}}"
+        delay: "{{delay}}"
+      steps:
+        - marshal:
+            json:
+              library: Jackson
+        - to: "kamelet:sink"
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/KameletResources.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/KameletResources.java
index 8a437935..3c771080 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/KameletResources.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/KameletResources.java
@@ -64,11 +64,7 @@ public class KameletResources {
         if (infinispanService.isReady()) {
             Yaml yaml = new Yaml();
             return infinispanService.getProjectFiles(Project.Type.kamelets.name()).stream()
-                    .map(projectFile -> {
-                        Map<String, LinkedHashMap> obj = yaml.load(projectFile.getCode());
-                        LinkedHashMap<String, Object> metadata = obj.get("metadata");
-                        return metadata.get("name").toString();
-                    })
+                    .map(projectFile -> projectFile.getName().replace(".kamelet.yaml", ""))
                     .collect(Collectors.toList());
         } else {
             return List.of();
diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/route/useRouteDesignerHook.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/route/useRouteDesignerHook.tsx
index 4d814f1a..2a85f9d6 100644
--- a/karavan-web/karavan-app/src/main/webui/src/designer/route/useRouteDesignerHook.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/route/useRouteDesignerHook.tsx
@@ -77,15 +77,16 @@ export function useRouteDesignerHook () {
 
     const deleteElement = () =>  {
         EventBus.sendPosition("clean", new CamelElement(""), undefined, new DOMRect(), new DOMRect(), 0);
+        let i = integration;
         selectedUuids.forEach(uuidToDelete => {
-            const i = CamelDefinitionApiExt.deleteStepFromIntegration(integration, uuidToDelete);
-            setIntegration(i, false);
-            setShowSelector(false);
-            setShowDeleteConfirmation(false);
-            setDeleteMessage('');
-            setSelectedStep(undefined);
-            setSelectedUuids([]);
+             i = CamelDefinitionApiExt.deleteStepFromIntegration(i, uuidToDelete);
         });
+        setIntegration(i, false);
+        setShowSelector(false);
+        setShowDeleteConfirmation(false);
+        setDeleteMessage('');
+        setSelectedStep(undefined);
+        setSelectedUuids([]);
     }
 
     const selectElement = (element: CamelElement) =>  {
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/file/FileEditor.tsx b/karavan-web/karavan-app/src/main/webui/src/project/file/FileEditor.tsx
index f8f941c3..073b3bc3 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/file/FileEditor.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/project/file/FileEditor.tsx
@@ -84,10 +84,11 @@ export function FileEditor (props: Props) {
         )
     }
 
-    const isYaml = file !== undefined && file.name.endsWith("yaml");
-    const isIntegration = isYaml && file?.code && CamelDefinitionYaml.yamlIsIntegration(file.code);
+    const isCamelYaml = file !== undefined && file.name.endsWith(".camel.yaml");
+    const isKameletYaml = file !== undefined && file.name.endsWith(".kamelet.yaml");
+    const isIntegration = isCamelYaml && file?.code && CamelDefinitionYaml.yamlIsIntegration(file.code);
     const isProperties = file !== undefined && file.name.endsWith("properties");
-    const showDesigner = isYaml && isIntegration;
+    const showDesigner = isCamelYaml && isIntegration;
     const showEditor = !showDesigner && !isProperties;
     return (
         <>


[camel-karavan] 01/02: Fix #915

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 aa99df10e46b88ea63f6a3f969d2ed96584d8585
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Thu Sep 28 17:17:15 2023 -0400

    Fix #915
---
 .../src/designer/route/useRouteDesignerHook.tsx           | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/karavan-designer/src/designer/route/useRouteDesignerHook.tsx b/karavan-designer/src/designer/route/useRouteDesignerHook.tsx
index 4d814f1a..2a85f9d6 100644
--- a/karavan-designer/src/designer/route/useRouteDesignerHook.tsx
+++ b/karavan-designer/src/designer/route/useRouteDesignerHook.tsx
@@ -77,15 +77,16 @@ export function useRouteDesignerHook () {
 
     const deleteElement = () =>  {
         EventBus.sendPosition("clean", new CamelElement(""), undefined, new DOMRect(), new DOMRect(), 0);
+        let i = integration;
         selectedUuids.forEach(uuidToDelete => {
-            const i = CamelDefinitionApiExt.deleteStepFromIntegration(integration, uuidToDelete);
-            setIntegration(i, false);
-            setShowSelector(false);
-            setShowDeleteConfirmation(false);
-            setDeleteMessage('');
-            setSelectedStep(undefined);
-            setSelectedUuids([]);
+             i = CamelDefinitionApiExt.deleteStepFromIntegration(i, uuidToDelete);
         });
+        setIntegration(i, false);
+        setShowSelector(false);
+        setShowDeleteConfirmation(false);
+        setDeleteMessage('');
+        setSelectedStep(undefined);
+        setSelectedUuids([]);
     }
 
     const selectElement = (element: CamelElement) =>  {