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

zehnder pushed a commit to branch 3112-opc-ua-multi-node-selection-editor
in repository https://gitbox.apache.org/repos/asf/streampipes.git


The following commit(s) were added to 
refs/heads/3112-opc-ua-multi-node-selection-editor by this push:
     new b3beb3e6d0 feat(#3112): First version of text input works now
b3beb3e6d0 is described below

commit b3beb3e6d0088fd8fb2d1196b705382c183007e2
Author: Philipp Zehnder <[email protected]>
AuthorDate: Tue Aug 13 10:16:15 2024 +0200

    feat(#3112): First version of text input works now
---
 ...eNodeBuilder.ts => TreeNodeUserInputBuilder.ts} |  7 +-
 .../model/{TreeNode.ts => TreeNodeUserInput.ts}    |  3 +-
 .../tests/connect/{ => opcua}/opcAdapter.spec.ts   | 77 ++++++++++++++--------
 .../{ => opcua}/opcAdapterConfiguration.spec.ts    | 65 ++++++++++++------
 .../static-tree-input-text-editor.component.html   | 26 ++++++++
 .../static-tree-input-text-editor.component.ts     | 70 ++++++++++++++++++++
 6 files changed, 198 insertions(+), 50 deletions(-)

diff --git a/ui/cypress/support/builder/TreeNodeBuilder.ts 
b/ui/cypress/support/builder/TreeNodeUserInputBuilder.ts
similarity index 90%
rename from ui/cypress/support/builder/TreeNodeBuilder.ts
rename to ui/cypress/support/builder/TreeNodeUserInputBuilder.ts
index 0dd04ff1c7..fcec8db9ef 100644
--- a/ui/cypress/support/builder/TreeNodeBuilder.ts
+++ b/ui/cypress/support/builder/TreeNodeUserInputBuilder.ts
@@ -22,7 +22,7 @@ export class TreeNodeBuilder {
     private readonly node: TreeNode;
 
     constructor(name: string) {
-        this.node = { name, children: [] };
+        this.node = { name, children: [] , isTextConfig: false};
     }
 
     addChildren(...childrenBuilders: TreeNodeBuilder[]): TreeNodeBuilder {
@@ -32,6 +32,11 @@ export class TreeNodeBuilder {
         return this;
     }
 
+    isTextConfig(): TreeNodeBuilder {
+        this.node.isTextConfig = true;
+        return this
+    }
+
     static create(
         name: string,
         ...children: TreeNodeBuilder[]
diff --git a/ui/cypress/support/model/TreeNode.ts 
b/ui/cypress/support/model/TreeNodeUserInput.ts
similarity index 94%
rename from ui/cypress/support/model/TreeNode.ts
rename to ui/cypress/support/model/TreeNodeUserInput.ts
index 49c717c0d3..681a0a4629 100644
--- a/ui/cypress/support/model/TreeNode.ts
+++ b/ui/cypress/support/model/TreeNodeUserInput.ts
@@ -16,6 +16,7 @@
  *
  */
 export class TreeNode {
-    name: String;
+    name: string;
     children?: TreeNode[];
+    isTextConfig?: boolean = false;
 }
diff --git a/ui/cypress/tests/connect/opcAdapter.spec.ts 
b/ui/cypress/tests/connect/opcua/opcAdapter.spec.ts
similarity index 77%
rename from ui/cypress/tests/connect/opcAdapter.spec.ts
rename to ui/cypress/tests/connect/opcua/opcAdapter.spec.ts
index f7addefa16..1e3cd8c907 100644
--- a/ui/cypress/tests/connect/opcAdapter.spec.ts
+++ b/ui/cypress/tests/connect/opcua/opcAdapter.spec.ts
@@ -27,19 +27,63 @@ describe('Test OPC-UA Adapter Pull Mode', () => {
     });
 
     it('Test OPC-UA Adapter Pull Mode', () => {
-        const adapterInput = getAdapterBuilder(true);
+        const adapterInput = getAdapterBuilderWithTreeNodes(true);
 
         ConnectUtils.testAdapter(adapterInput);
     });
 
     it('Test OPC-UA Adapter Subscription Mode', () => {
-        const adapterInput = getAdapterBuilder(false);
+        const adapterInput = getAdapterBuilderWithTreeNodes(false);
+
+        ConnectUtils.testAdapter(adapterInput);
+    });
+
+    it('Test OPC-UA Adapter Text Editor Configuration', () => {
+        const adapterInput = getAdapterBuilderWithTextNodes(false);
 
         ConnectUtils.testAdapter(adapterInput);
     });
 });
 
-const getAdapterBuilder = (pullMode: boolean) => {
+const getAdapterBuilderWithTreeNodes = (pullMode: boolean) => {
+
+    const builder = getBaseAdapterConfigBuilder(pullMode);
+    builder.addTreeNode(
+        TreeNodeBuilder.create(
+            'Objects',
+            TreeNodeBuilder.create(
+                'OpcPlc',
+                TreeNodeBuilder.create(
+                    'Telemetry',
+                    TreeNodeBuilder.create('Basic').addChildren(
+                        TreeNodeBuilder.create('AlternatingBoolean'),
+                        TreeNodeBuilder.create('StepUp'),
+                        TreeNodeBuilder.create('RandomSignedInt32'),
+                        TreeNodeBuilder.create('RandomUnsignedInt32'),
+                    ),
+                ),
+            ),
+        ),
+    );
+
+
+    return builder.build();
+};
+
+const getAdapterBuilderWithTextNodes = (pullMode: boolean) => {
+    const builder = getBaseAdapterConfigBuilder(pullMode);
+    builder.addTreeNode(
+        TreeNodeBuilder.create('ns=3;s=StepUp')
+            .isTextConfig()
+    );
+
+    return builder.build();
+};
+
+
+
+
+const getBaseAdapterConfigBuilder = (pullMode: boolean) : AdapterBuilder => {
     const host: string = ParameterUtils.get('localhost', 'opcua');
 
     const builder = AdapterBuilder.create('OPC_UA').setName(
@@ -62,32 +106,7 @@ const getAdapterBuilder = (pullMode: boolean) => {
             'opc.tcp://' + host + ':50000',
         );
 
-    builder.addTreeNode(
-        TreeNodeBuilder.create(
-            'Objects',
-            TreeNodeBuilder.create(
-                'OpcPlc',
-                TreeNodeBuilder.create(
-                    'Telemetry',
-                    TreeNodeBuilder.create('Basic').addChildren(
-                        TreeNodeBuilder.create('AlternatingBoolean'),
-                        TreeNodeBuilder.create('StepUp'),
-                        TreeNodeBuilder.create('RandomSignedInt32'),
-                        TreeNodeBuilder.create('RandomUnsignedInt32'),
-                    ),
-                    // TreeNodeBuilder.create('Anomaly')
-                    //     .addChildren(
-                    //         TreeNodeBuilder.create('DipData'),
-                    //         TreeNodeBuilder.create('NegativeTrendData'),
-                    //         TreeNodeBuilder.create('PositiveTrendData'),
-                    //         TreeNodeBuilder.create('SpikeData'),
-                    //     ),
-                ),
-            ),
-        ),
-    );
-
     builder.setAutoAddTimestampPropery();
 
-    return builder.build();
+    return builder;
 };
diff --git a/ui/cypress/tests/connect/opcAdapterConfiguration.spec.ts 
b/ui/cypress/tests/connect/opcua/opcAdapterConfiguration.spec.ts
similarity index 76%
rename from ui/cypress/tests/connect/opcAdapterConfiguration.spec.ts
rename to ui/cypress/tests/connect/opcua/opcAdapterConfiguration.spec.ts
index 57b10bd41a..24173c88b5 100644
--- a/ui/cypress/tests/connect/opcAdapterConfiguration.spec.ts
+++ b/ui/cypress/tests/connect/opcua/opcAdapterConfiguration.spec.ts
@@ -23,13 +23,30 @@ import { TreeNodeBuilder } from 
'../../support/builder/TreeNodeBuilder';
 import { StaticPropertyUtils } from 
'../../support/utils/userInput/StaticPropertyUtils';
 import { TreeStaticPropertyUtils } from 
'../../support/utils/userInput/TreeStaticPropertyUtils';
 
-describe('Test OPC-UA Adapter Pull Mode', () => {
+describe('Test OPC-UA Adapter Configuration', () => {
     beforeEach('Setup Test', () => {
         cy.initStreamPipesTest();
     });
 
-    it('Test OPC-UA Adapter Pull Mode', () => {
-        const adapterConfiguration = getAdapterBuilder();
+    it('Test OPC-UA Tree Node Configuration', () => {
+        const adapterBuilder = getAdapterBuilder();
+        adapterBuilder.addTreeNode(
+            TreeNodeBuilder.create(
+                'Objects',
+                TreeNodeBuilder.create(
+                    'OpcPlc',
+                    TreeNodeBuilder.create(
+                        'Telemetry',
+                        TreeNodeBuilder.create('Basic').addChildren(
+                            TreeNodeBuilder.create('AlternatingBoolean'),
+                            TreeNodeBuilder.create('StepUp'),
+                        ),
+                    ),
+                ),
+            ),
+        );
+
+        const adapterConfiguration = adapterBuilder.build();
 
         // Set up initial configuration
         ConnectUtils.goToConnect();
@@ -62,6 +79,30 @@ describe('Test OPC-UA Adapter Pull Mode', () => {
         TreeStaticPropertyUtils.clickClearAndReloadButton();
         TreeStaticPropertyUtils.validateAmountOfSelectedNodes(0);
     });
+
+    it('Test OPC-UA Code Editor', () => {
+        const adapterConfiguration = getAdapterBuilder().build();
+
+        // Set up initial configuration
+        ConnectUtils.goToConnect();
+        ConnectUtils.goToNewAdapterPage();
+        ConnectUtils.selectAdapter(adapterConfiguration.adapterType);
+        StaticPropertyUtils.input(adapterConfiguration.adapterConfiguration);
+
+
+        TreeStaticPropertyUtils.treeEditor().should('be.visible');
+        TreeStaticPropertyUtils.textEditor().should('not.exist');
+
+        // Switch to text editor
+        TreeStaticPropertyUtils.switchToTextEditor();
+
+        // Validate that text editor is shown
+        TreeStaticPropertyUtils.treeEditor().should('not.exist');
+        TreeStaticPropertyUtils.textEditor().should('be.visible');
+
+        TreeStaticPropertyUtils.typeInTextEditor('ns=3;s=StepUp');
+
+    });
 });
 
 const getAdapterBuilder = () => {
@@ -78,22 +119,8 @@ const getAdapterBuilder = () => {
             'undefined-OPC_SERVER_URL-0',
             'opc.tcp://' + host + ':50000',
         )
-        .addTreeNode(
-            TreeNodeBuilder.create(
-                'Objects',
-                TreeNodeBuilder.create(
-                    'OpcPlc',
-                    TreeNodeBuilder.create(
-                        'Telemetry',
-                        TreeNodeBuilder.create('Basic').addChildren(
-                            TreeNodeBuilder.create('AlternatingBoolean'),
-                            TreeNodeBuilder.create('StepUp'),
-                        ),
-                    ),
-                ),
-            ),
-        )
+
         .setAutoAddTimestampPropery();
 
-    return builder.build();
+    return builder;
 };
diff --git 
a/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-tree-input-text-editor/static-tree-input-text-editor.component.html
 
b/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-tree-input-text-editor/static-tree-input-text-editor.component.html
new file mode 100644
index 0000000000..c1d07b3dad
--- /dev/null
+++ 
b/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-tree-input-text-editor/static-tree-input-text-editor.component.html
@@ -0,0 +1,26 @@
+<!--
+  ~ 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.
+  ~
+  -->
+
+<ngx-codemirror
+    style='width: 100%'
+    [(ngModel)]='textEditor'
+    (ngModelChange)='onTextEditorChange($event)'
+    [options]='editorOptions'
+    data-cy='static-tree-input-text-editor'
+>
+</ngx-codemirror>
diff --git 
a/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-tree-input-text-editor/static-tree-input-text-editor.component.ts
 
b/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-tree-input-text-editor/static-tree-input-text-editor.component.ts
new file mode 100644
index 0000000000..6042c9554d
--- /dev/null
+++ 
b/ui/src/app/core-ui/static-properties/static-runtime-resolvable-tree-input/static-tree-input-text-editor/static-tree-input-text-editor.component.ts
@@ -0,0 +1,70 @@
+/*
+ * 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 { Component, EventEmitter, Input, Output } from '@angular/core';
+import { Subject } from 'rxjs';
+import { debounceTime } from 'rxjs/operators';
+import { RuntimeResolvableTreeInputStaticProperty } from 
'@streampipes/platform-services';
+
+@Component({
+    selector: 'sp-static-tree-input-text-editor',
+    templateUrl: './static-tree-input-text-editor.component.html',
+})
+export class StaticTreeInputTextEditorComponent {
+
+    @Input()
+    staticProperty: RuntimeResolvableTreeInputStaticProperty;
+
+    @Output()
+    performValidationEmitter: EventEmitter<void> = new EventEmitter<void>();
+
+    editorOptions = {
+        mode: 'text/plain',
+        autoRefresh: true,
+        theme: 'dracula',
+        lineNumbers: true,
+        lineWrapping: true,
+        readOnly: false,
+        extraKeys: {
+            'Ctrl-Space': 'autocomplete',
+        },
+    };
+
+    textEditor: string = '';
+
+    private textChangeSubject: Subject<string> = new Subject<string>();
+
+    constructor() {
+        this.textChangeSubject.pipe(
+            debounceTime(500),
+        ).subscribe(value => {
+            this.onTextChange(value);
+        });
+    }
+
+    onTextEditorChange(value: string): void {
+        this.textChangeSubject.next(value);
+    }
+
+    onTextChange(value: string): void {
+        const lines = value.split('\n').filter(line => !line.startsWith('#'));
+        this.staticProperty.selectedNodesInternalNames = lines;
+        this.performValidationEmitter.emit();
+    }
+
+}

Reply via email to