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 2021/11/02 22:38:13 UTC

[camel-karavan] branch main updated: Fixed #41 (#66)

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


The following commit(s) were added to refs/heads/main by this push:
     new 49a81f4  Fixed #41 (#66)
49a81f4 is described below

commit 49a81f44479b5d0b292df62ad77904935dfac655
Author: Marat Gubaidullin <ma...@gmail.com>
AuthorDate: Tue Nov 2 18:34:01 2021 -0400

    Fixed #41 (#66)
---
 karavan-designer/src/App.tsx                       |  7 +-
 karavan-designer/src/designer/api/CamelUi.tsx      |  2 +-
 karavan-designer/src/designer/api/CamelYaml.tsx    | 33 ++++++--
 karavan-designer/src/designer/model/CamelModel.tsx |  1 +
 karavan-designer/src/designer/ui/DslProperties.tsx | 11 +--
 .../src/designer/ui/KaravanDesigner.tsx            |  8 +-
 .../src/main/resources/camel-model.template        |  1 +
 karavan-vscode/package.json                        | 22 ++++--
 karavan-vscode/src/extension.ts                    | 90 ++++++++++++----------
 karavan-vscode/webview/App.tsx                     | 22 +++---
 10 files changed, 113 insertions(+), 84 deletions(-)

diff --git a/karavan-designer/src/App.tsx b/karavan-designer/src/App.tsx
index 261e556..818daff 100644
--- a/karavan-designer/src/App.tsx
+++ b/karavan-designer/src/App.tsx
@@ -90,15 +90,16 @@ class App extends React.Component<Props, State> {
 
     }
 
-    save(name: string, yaml: string) {
+    save(filename: string, yaml: string) {
+        console.log(filename);
         console.log(yaml);
     }
 
     public render() {
         return (
             <Page className="karavan">
-                <KaravanDesigner key={this.state.key} name={this.state.name} yaml={this.state.yaml}
-                                 onSave={(name, yaml) => this.save(name, yaml)}
+                <KaravanDesigner key={this.state.key} filename={this.state.name} yaml={this.state.yaml}
+                                 onSave={(filename, yaml) => this.save(filename, yaml)}
                                  borderColor="#fb8824"
                                  borderColorSelected="black"
                                  dark={document.body.className.includes('vscode-dark')}
diff --git a/karavan-designer/src/designer/api/CamelUi.tsx b/karavan-designer/src/designer/api/CamelUi.tsx
index 6ff11e1..e18a8fb 100644
--- a/karavan-designer/src/designer/api/CamelUi.tsx
+++ b/karavan-designer/src/designer/api/CamelUi.tsx
@@ -159,7 +159,7 @@ export class CamelUi {
         }
     };
 
-    static nameFomTitle = (title: string): string => {
+    static nameFromTitle = (title: string): string => {
         return title.replace(/[^a-z0-9+]+/gi, "-").toLowerCase();
     };
 
diff --git a/karavan-designer/src/designer/api/CamelYaml.tsx b/karavan-designer/src/designer/api/CamelYaml.tsx
index 1c4c172..088e41f 100644
--- a/karavan-designer/src/designer/api/CamelYaml.tsx
+++ b/karavan-designer/src/designer/api/CamelYaml.tsx
@@ -29,9 +29,16 @@ export class CamelYaml {
         const clone: any = Object.assign({}, integration);
         const flows = integration.spec.flows
         clone.spec.flows = flows.map((f: any) => CamelYaml.cleanupElement(f));
-        const i = JSON.parse(JSON.stringify(clone, null, 3)); // fix undefined in string attributes
-        const text = yaml.dump(i);
-        return text;
+        if (integration.crd) {
+            delete clone.crd 
+            const i = JSON.parse(JSON.stringify(clone, null, 3)); // fix undefined in string attributes
+            const text = yaml.dump(i);
+            return text;
+        } else {
+            const f = JSON.parse(JSON.stringify(clone.spec.flows, null, 3));
+            const text = yaml.dump(f);
+            return text;
+        }
     }
 
     static cleanupElement = (element: CamelElement): CamelElement => {
@@ -80,12 +87,22 @@ export class CamelYaml {
         return result
     }
 
-    static yamlToIntegration = (text: string): Integration => {
+    static yamlToIntegration = (filename: string, text: string): Integration => {
+        const i: Integration = Integration.createNew(filename);
         const fromYaml: any = yaml.load(text);
-        const int: Integration = new Integration({...fromYaml});
-        const flows = int.spec.flows.map(f => CamelApi.createFrom(f))
-        int.spec.flows = flows;
-        return int;
+        if (Array.isArray(fromYaml)) {
+            i.crd = false;
+            const flows: any[] = fromYaml;
+            const froms = flows.filter((e: any) => e.hasOwnProperty('from'));
+            if (froms.length > 0) {
+                froms.forEach((f: any) => i.spec.flows.push(CamelApi.createFrom(f)));
+            }
+        } else {
+            i.crd = true;
+            const int: Integration = new Integration({...fromYaml});
+            int.spec.flows.forEach((f: any) => i.spec.flows.push(CamelApi.createFrom(f)));
+        }
+        return i;
     }
 
     static cloneIntegration = (integration: Integration): Integration => {
diff --git a/karavan-designer/src/designer/model/CamelModel.tsx b/karavan-designer/src/designer/model/CamelModel.tsx
index 94c2567..4372750 100644
--- a/karavan-designer/src/designer/model/CamelModel.tsx
+++ b/karavan-designer/src/designer/model/CamelModel.tsx
@@ -25,6 +25,7 @@ export class Integration {
     kind: string = 'Integration';
     metadata: Metadata = new Metadata();
     spec: Spec = new Spec();
+    crd: boolean = true;
 
     public constructor(init?: Partial<Integration>) {
         Object.assign(this, init);
diff --git a/karavan-designer/src/designer/ui/DslProperties.tsx b/karavan-designer/src/designer/ui/DslProperties.tsx
index 142805a..9492c33 100644
--- a/karavan-designer/src/designer/ui/DslProperties.tsx
+++ b/karavan-designer/src/designer/ui/DslProperties.tsx
@@ -74,14 +74,6 @@ export class DslProperties extends React.Component<Props, State> {
         this.props.onChangeView.call(this, view);
     }
 
-    onIntegrationChange = (field: string, value: string) => {
-        let clone = new Integration({...this.state.integration});
-        if (field === 'title') {
-            clone.metadata.name = CamelUi.nameFomTitle(value);
-            this.props.onIntegrationUpdate?.call(this, clone);
-        }
-    };
-
     propertyChanged = (fieldId: string, value: string | number | boolean | any) => {
         if (this.state.step && this.state.element) {
             const clone = CamelYaml.cloneStep(this.state.step);
@@ -154,8 +146,7 @@ export class DslProperties extends React.Component<Props, State> {
                     <TextInput className="text-field" type="text" id="title" name="title" isReadOnly
                                value={
                                    CamelUi.titleFromName(this.state.integration.metadata.name)
-                               }
-                               onChange={e => this.onIntegrationChange('title', e)}/>
+                               }/>
                 </FormGroup>
                 <FormGroup label="Name" fieldId="name" isRequired>
                     <TextInput className="text-field" type="text" id="name" name="name" isReadOnly
diff --git a/karavan-designer/src/designer/ui/KaravanDesigner.tsx b/karavan-designer/src/designer/ui/KaravanDesigner.tsx
index bce1856..abf7d4e 100644
--- a/karavan-designer/src/designer/ui/KaravanDesigner.tsx
+++ b/karavan-designer/src/designer/ui/KaravanDesigner.tsx
@@ -34,8 +34,8 @@ import {CamelUi} from "../api/CamelUi";
 import {EventBus} from "../api/EventBus";
 
 interface Props {
-    onSave?: (name: string, yaml: string) => void
-    name: string
+    onSave?: (filename: string, yaml: string) => void
+    filename: string
     yaml: string
     borderColor: string
     borderColorSelected: string
@@ -56,8 +56,8 @@ export class KaravanDesigner extends React.Component<Props, State> {
 
     public state: State = {
         integration: this.props.yaml
-            ? CamelYaml.yamlToIntegration(this.props.yaml)
-            : Integration.createNew(CamelUi.nameFomTitle(this.props.name)),
+            ? CamelYaml.yamlToIntegration(this.props.filename, this.props.yaml)
+            : Integration.createNew(this.props.filename),
         showSelector: false,
         parentId: '',
         parentType: '',
diff --git a/karavan-generator/src/main/resources/camel-model.template b/karavan-generator/src/main/resources/camel-model.template
index d555760..aaf49f5 100644
--- a/karavan-generator/src/main/resources/camel-model.template
+++ b/karavan-generator/src/main/resources/camel-model.template
@@ -25,6 +25,7 @@ export class Integration {
     kind: string = 'Integration';
     metadata: Metadata = new Metadata();
     spec: Spec = new Spec();
+    crd: boolean = true;
 
     public constructor(init?: Partial<Integration>) {
         Object.assign(this, init);
diff --git a/karavan-vscode/package.json b/karavan-vscode/package.json
index e03193a..fe1495f 100644
--- a/karavan-vscode/package.json
+++ b/karavan-vscode/package.json
@@ -41,20 +41,24 @@
     "Integration"
   ],
   "activationEvents": [
-    "onCommand:karavan.create",
-    "onCommand:karavan.open",
+    "onCommand:karavan.create-crd",
+    "onCommand:karavan.open-yaml",
     "onCommand:karavan.jbang-run"
   ],
   "main": "./dist/extension.js",
   "contributes": {
     "commands": [
       {
-        "command": "karavan.create",
-        "title": "Karavan: Create Integration"
+        "command": "karavan.create-crd",
+        "title": "Karavan: Create CRD"
+      },
+      {
+        "command": "karavan.create-yaml",
+        "title": "Karavan: Create YAML"
       },
       {
         "command": "karavan.open",
-        "title": "Karavan: Open in Designer",
+        "title": "Karavan: Open",
         "icon": {
           "light": "./icons/icon.png",
           "dark": "./icons/icon.png"
@@ -62,14 +66,18 @@
       },
       {
         "command": "karavan.jbang-run",
-        "title": "Run with JBang",
+        "title": "Karavan: JBang Run",
         "icon": "./icons/run.png"
       }
     ],
     "menus": {
       "explorer/context": [
         {
-          "command": "karavan.create",
+          "command": "karavan.create-crd",
+           "when": "explorerResourceIsFolder && explorerResourceIsRoot"
+        },
+        {
+          "command": "karavan.create-yaml",
            "when": "explorerResourceIsFolder && explorerResourceIsRoot"
         },
         {
diff --git a/karavan-vscode/src/extension.ts b/karavan-vscode/src/extension.ts
index f7fe044..8d5df09 100644
--- a/karavan-vscode/src/extension.ts
+++ b/karavan-vscode/src/extension.ts
@@ -19,6 +19,8 @@ import * as fs from "fs";
 import * as path from "path";
 import { CamelYaml } from "../designer/api/CamelYaml";
 import { CamelUi } from "../designer/api/CamelUi";
+import * as jsyaml from 'js-yaml';
+import { Integration } from "../designer/model/CamelModel";
 
 const KARAVAN_LOADED = "karavan:loaded";
 const KARAVAN_PANELS: Map<any, string> = new Map<string, string>();
@@ -42,27 +44,11 @@ export function activate(context: vscode.ExtensionContext) {
                 .toString()
         );
 
-    // Create new Camel-K Integration command
-    const create = vscode.commands.registerCommand(
-        "karavan.create",
-        () => {
-            vscode.window
-                .showInputBox({
-                    title: "Create Integration",
-                    ignoreFocusOut: true,
-                    prompt: "Integration name",
-                    validateInput: (text: string): string | undefined => {
-                        if (!text || text.length === 0) {
-                            return 'Name should not be empty';
-                        } else {
-                            return undefined;
-                        }
-                    }
-                }).then(value => {
-                    if (value) openKaravanWebView(context, webviewContent, value, value + '.yaml', undefined);
-                });
-        }
-    );
+    // Create new Camel-K Integration CRD command
+    const createCrd = vscode.commands.registerCommand("karavan.create-crd", () => createIntegration(context, webviewContent, true));
+
+    // Create new Camel Integration YAML command
+    const createYaml = vscode.commands.registerCommand("karavan.create-yaml", () => createIntegration(context, webviewContent, false));
 
     // Open Camel-K integration in designer
     const open = vscode.commands.registerCommand(
@@ -70,12 +56,12 @@ export function activate(context: vscode.ExtensionContext) {
         (...args: any[]) => {
             if (args && args.length > 0) {
                 const yaml = fs.readFileSync(path.resolve(args[0].path)).toString('utf8');
-                const parce = isIntegration(yaml);
                 const filename = path.basename(args[0].path);
-                if (parce[0]) {
-                    openKaravanWebView(context, webviewContent, parce[1] || '', filename || '', yaml);
+                const integration = parceYaml(filename, yaml);
+                if (integration[0]) {
+                    openKaravanWebView(context, webviewContent, filename || '', integration[1]);
                 } else {
-                    vscode.window.showErrorMessage("File is not Camel-K Integration!")
+                    vscode.window.showErrorMessage("File is not Camel Integration!")
                 }
             }
         }
@@ -88,16 +74,14 @@ export function activate(context: vscode.ExtensionContext) {
             if (args && args.length > 0) {
                 if (args[0].path.startsWith('webview-panel/webview')) {
                     const filename = KARAVAN_PANELS.get(args[0].path);
-                    console.log(filename)
-                    if (filename){
+                    if (filename) {
                         runCamelJbang(filename);
                     }
                 } else {
                     const yaml = fs.readFileSync(path.resolve(args[0].path)).toString('utf8');
-                    const parce = isIntegration(yaml);
                     const filename = path.basename(args[0].path);
-                    console.log(filename)
-                    if (parce[0]) {
+                    const integration = parceYaml(filename, yaml);
+                    if (integration[0]) {
                         runCamelJbang(filename);
                     } else {
                         vscode.window.showErrorMessage("File is not Camel-K Integration!")
@@ -106,16 +90,17 @@ export function activate(context: vscode.ExtensionContext) {
             }
         }
     );
-    context.subscriptions.push(create);
+    context.subscriptions.push(createCrd);
+    context.subscriptions.push(createYaml);
     context.subscriptions.push(open);
     context.subscriptions.push(run);
 }
 
-function openKaravanWebView(context: vscode.ExtensionContext, webviewContent: string, name: string, filename: string, yaml?: string) {
+function openKaravanWebView(context: vscode.ExtensionContext, webviewContent: string, filename: string, yaml?: string) {
     // Karavan webview
     const panel = vscode.window.createWebviewPanel(
         "karavan",
-        CamelUi.nameFomTitle(filename),
+        filename,
         vscode.ViewColumn.One,
         {
             enableScripts: true,
@@ -139,24 +124,25 @@ function openKaravanWebView(context: vscode.ExtensionContext, webviewContent: st
     panel.webview.postMessage({ command: 'components', components: readComponents(context) });
 
     // Send integration
-    panel.webview.postMessage({ command: 'open', name: name, yaml: yaml });
+    panel.webview.postMessage({ command: 'open', filename: filename, yaml: yaml });
 
 
     // Handle messages from the webview
     panel.webview.onDidReceiveMessage(
         message => {
+            console.log(message);
             switch (message.command) {
                 case 'save':
                     if (vscode.workspace.workspaceFolders) {
                         const uriFolder: vscode.Uri = vscode.workspace.workspaceFolders[0].uri;
-                        const uriFile: vscode.Uri = vscode.Uri.file(path.join(uriFolder.path, message.name + '.yaml'));
+                        const uriFile: vscode.Uri = vscode.Uri.file(path.join(uriFolder.path, message.filename));
                         fs.writeFile(uriFile.path, message.yaml, err => {
                             if (err) vscode.window.showErrorMessage("Error: " + err?.message);
                         });
                     }
                     return;
                 case 'url-mapping':
-                    KARAVAN_PANELS.set('webview-panel/webview-' + message.pathId, CamelUi.nameFomTitle(message.name) + '.yaml');
+                    KARAVAN_PANELS.set('webview-panel/webview-' + message.pathId, CamelUi.nameFromTitle(message.filename));
             }
         },
         undefined,
@@ -165,6 +151,30 @@ function openKaravanWebView(context: vscode.ExtensionContext, webviewContent: st
     vscode.commands.executeCommand("setContext", KARAVAN_LOADED, true);
 }
 
+function createIntegration(context: vscode.ExtensionContext, webviewContent: string, crd: boolean) {
+    vscode.window
+        .showInputBox({
+            title: crd ? "Create Camel-K Integration CRD" : "Create Camel Integration YAML",
+            ignoreFocusOut: true,
+            prompt: "Integration name",
+            validateInput: (text: string): string | undefined => {
+                if (!text || text.length === 0) {
+                    return 'Name should not be empty';
+                } else {
+                    return undefined;
+                }
+            }
+        }).then(value => {
+            if (value) {
+                const name = CamelUi.nameFromTitle(value);
+                const i = Integration.createNew(name);
+                i.crd = crd;
+                const yaml = CamelYaml.integrationToYaml(i);
+                openKaravanWebView(context, webviewContent, name + '.yaml', yaml);
+            }
+        });
+}
+
 function readKamelets(context: vscode.ExtensionContext): string[] {
     const dir = path.join(context.extensionPath, 'kamelets');
     const yamls: string[] = fs.readdirSync(dir).filter(file => file.endsWith("yaml")).map(file => fs.readFileSync(dir + "/" + file, 'utf-8'));
@@ -177,17 +187,17 @@ function readComponents(context: vscode.ExtensionContext): string[] {
     return jsons;
 }
 
-function isIntegration(yaml: string): [boolean, string?] {
-    const i = CamelYaml.yamlToIntegration(yaml);
+function parceYaml(filename: string, yaml: string): [boolean, string?] {
+    const i = CamelYaml.yamlToIntegration(filename, yaml);
     if (i.kind === 'Integration' && i.metadata.name) {
-        return [true, i.metadata.name];
+        return [true, yaml];
     } else {
         return [false, undefined];
     }
 }
 
 function runCamelJbang(filename: string) {
-    const terminal = vscode.window.createTerminal(`Karavan: ` + filename);
+    const terminal = vscode.window.createTerminal('Karavan: ' + filename);
     terminal.show();
     terminal.sendText("CamelJBang run " + filename);
 }
diff --git a/karavan-vscode/webview/App.tsx b/karavan-vscode/webview/App.tsx
index 6ba0cf9..a7878f9 100644
--- a/karavan-vscode/webview/App.tsx
+++ b/karavan-vscode/webview/App.tsx
@@ -28,7 +28,7 @@ interface Props {
 }
 
 interface State {
-  name: string
+  filename: string
   yaml: string
   key: string
 }
@@ -36,7 +36,7 @@ interface State {
 class App extends React.Component<Props, State> {
 
   public state: State = {
-    name: '',
+    filename: '',
     yaml: '',
     key: ''
   };
@@ -53,24 +53,24 @@ class App extends React.Component<Props, State> {
           ComponentApi.saveComponents(message.components);
           break;  
         case 'open':
-          if (this.state.name === '' && this.state.key === ''){
-            this.setState({name: message.name, yaml: message.yaml, key: Math.random().toString()});
-            this.sendUrlMapping(message.name)
+          if (this.state.filename === '' && this.state.key === ''){
+            this.setState({filename: message.filename, yaml: message.yaml, key: Math.random().toString()});
+            this.sendUrlMapping(message.filename)
           }
           break;
       }
     });
   }
 
-  sendUrlMapping(name: string){
+  sendUrlMapping(filename: string){
     const url = new URL(window.location.href)
-    vscode.postMessage({ command: 'url-mapping', pathId: url.host, name: name })
+    vscode.postMessage({ command: 'url-mapping', pathId: url.host, filename: filename })
   }
 
-  save(name: string, yaml: string) {
+  save(filename: string, yaml: string) {
     vscode.postMessage({
       command: 'save',
-      name: name,
+      filename: filename,
       yaml: yaml
     })
   }
@@ -80,9 +80,9 @@ class App extends React.Component<Props, State> {
       <Page className="karavan">
          <KaravanDesigner 
           key={this.state.key} 
-          name={this.state.name} 
+          filename={this.state.filename} 
           yaml={this.state.yaml} 
-          onSave={(name, yaml) => this.save(name, yaml)}
+          onSave={(filename, yaml) => this.save(filename, yaml)}
           borderColor="#fca338"
           borderColorSelected="#fee3c3"
           dark={this.props.dark}