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

riemer pushed a commit to branch fix-any-static-property
in repository https://gitbox.apache.org/repos/asf/streampipes.git

commit c192baa3fd8cd2cc04080c4350e6363fd9c5449e
Author: Dominik Riemer <[email protected]>
AuthorDate: Thu Sep 26 16:14:50 2024 +0200

    fix: Better handle runtime-resolved selections
---
 .../api/extractor/IParameterExtractor.java         |  2 +
 .../remote/ContainerProvidedOptionsHandler.java    |  3 +-
 .../apache/streampipes/sdk/StaticProperties.java   | 18 ++++++--
 .../sdk/extractor/AbstractParameterExtractor.java  | 11 +++++
 .../static-property.component.html                 |  1 +
 ...tic-runtime-resolvable-any-input.component.html | 54 ++++++++++++++--------
 ...tatic-runtime-resolvable-any-input.component.ts | 31 ++++++++++---
 7 files changed, 90 insertions(+), 30 deletions(-)

diff --git 
a/streampipes-extensions-api/src/main/java/org/apache/streampipes/extensions/api/extractor/IParameterExtractor.java
 
b/streampipes-extensions-api/src/main/java/org/apache/streampipes/extensions/api/extractor/IParameterExtractor.java
index 396f0f3961..6751372794 100644
--- 
a/streampipes-extensions-api/src/main/java/org/apache/streampipes/extensions/api/extractor/IParameterExtractor.java
+++ 
b/streampipes-extensions-api/src/main/java/org/apache/streampipes/extensions/api/extractor/IParameterExtractor.java
@@ -60,6 +60,8 @@ public interface IParameterExtractor {
 
   <V> List<V> selectedMultiValues(String internalName, Class<V> targetClass);
 
+  <V> List<V> selectedMultiValuesInternalNames(String internalName, Class<V> 
targetClass);
+
   <V> List<V> selectedTreeNodesInternalNames(String internalName,
                                              Class<V> targetClass);
 
diff --git 
a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/remote/ContainerProvidedOptionsHandler.java
 
b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/remote/ContainerProvidedOptionsHandler.java
index 16acbba678..eb212bb33e 100644
--- 
a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/remote/ContainerProvidedOptionsHandler.java
+++ 
b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/remote/ContainerProvidedOptionsHandler.java
@@ -30,6 +30,7 @@ import com.google.gson.JsonSyntaxException;
 import org.apache.http.client.fluent.Response;
 
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 
 public class ContainerProvidedOptionsHandler {
 
@@ -49,7 +50,7 @@ public class ContainerProvidedOptionsHandler {
   }
 
   private RuntimeOptionsResponse handleResponse(Response httpResp) throws 
JsonSyntaxException, IOException {
-    String resp = httpResp.returnContent().asString();
+    String resp = httpResp.returnContent().asString(StandardCharsets.UTF_8);
     return JacksonSerializer.getObjectMapper().readValue(resp, 
RuntimeOptionsResponse.class);
   }
 
diff --git 
a/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/StaticProperties.java
 
b/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/StaticProperties.java
index 2ad5f735e5..1793698efb 100644
--- 
a/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/StaticProperties.java
+++ 
b/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/StaticProperties.java
@@ -19,6 +19,7 @@
 package org.apache.streampipes.sdk;
 
 import org.apache.streampipes.model.schema.PropertyScope;
+import org.apache.streampipes.model.staticproperty.AnyStaticProperty;
 import org.apache.streampipes.model.staticproperty.CodeInputStaticProperty;
 import org.apache.streampipes.model.staticproperty.CollectionStaticProperty;
 import org.apache.streampipes.model.staticproperty.FileStaticProperty;
@@ -97,9 +98,9 @@ public class StaticProperties {
    * @return A configured FreeTextStaticProperty instance.
    */
   public static FreeTextStaticProperty stringFreeTextProperty(
-          Label label,
-          boolean isMultiLine,
-          boolean arePlaceholdersSupported) {
+      Label label,
+      boolean isMultiLine,
+      boolean arePlaceholdersSupported) {
     var property = stringFreeTextProperty(label);
     property.setMultiLine(isMultiLine);
     property.setPlaceholdersSupported(arePlaceholdersSupported);
@@ -233,6 +234,17 @@ public class StaticProperties {
     return osp;
   }
 
+  public static AnyStaticProperty multiValueSelection(Label label, 
List<Option> options) {
+    var osp = new AnyStaticProperty(
+        label.getInternalId(),
+        label.getLabel(),
+        label.getDescription()
+    );
+    osp.setOptions(options);
+
+    return osp;
+  }
+
   public static SecretStaticProperty secretValue(Label label) {
     return new SecretStaticProperty(label.getInternalId(),
         label.getLabel(), label.getDescription());
diff --git 
a/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/extractor/AbstractParameterExtractor.java
 
b/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/extractor/AbstractParameterExtractor.java
index b7230510f3..27a06e8e67 100644
--- 
a/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/extractor/AbstractParameterExtractor.java
+++ 
b/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/extractor/AbstractParameterExtractor.java
@@ -246,6 +246,17 @@ public abstract class AbstractParameterExtractor<T extends 
InvocableStreamPipesE
         .collect(Collectors.toList());
   }
 
+  @Override
+  public <V> List<V> selectedMultiValuesInternalNames(String internalName, 
Class<V> targetClass) {
+    return getStaticPropertyByName(internalName, AnyStaticProperty.class)
+        .getOptions()
+        .stream()
+        .filter(Option::isSelected)
+        .map(Option::getInternalName)
+        .map(o -> typeParser.parse(o, targetClass))
+        .collect(Collectors.toList());
+  }
+
   @Override
   /**
    * Extracts the user configuration from the tree static property.
diff --git 
a/ui/src/app/core-ui/static-properties/static-property.component.html 
b/ui/src/app/core-ui/static-properties/static-property.component.html
index e416735c84..3f43c9bd03 100644
--- a/ui/src/app/core-ui/static-properties/static-property.component.html
+++ b/ui/src/app/core-ui/static-properties/static-property.component.html
@@ -94,6 +94,7 @@
                 [parentForm]="parentForm"
                 [completedStaticProperty]="completedStaticProperty"
                 [adapterId]="adapterId"
+                (updateEmitter)="emitUpdate($event)"
             >
             </sp-app-static-runtime-resolvable-any-input>
 
diff --git 
a/ui/src/app/core-ui/static-properties/static-runtime-resolvable-any-input/static-runtime-resolvable-any-input.component.html
 
b/ui/src/app/core-ui/static-properties/static-runtime-resolvable-any-input/static-runtime-resolvable-any-input.component.html
index 4690c0f00c..ac1c4f7e54 100644
--- 
a/ui/src/app/core-ui/static-properties/static-runtime-resolvable-any-input/static-runtime-resolvable-any-input.component.html
+++ 
b/ui/src/app/core-ui/static-properties/static-runtime-resolvable-any-input/static-runtime-resolvable-any-input.component.html
@@ -17,48 +17,65 @@
   -->
 
 <div id="formWrapper" fxFlex="100" fxLayout="column">
-    <div>
+    <div fxLayout="row" class="mb-10">
+        <button
+            mat-button
+            mat-raised-button
+            color="accent"
+            class="small-button"
+            (click)="selectAll(true)"
+            [disabled]="!showOptions"
+        >
+            <span>Select all</span>
+        </button>
+        <button
+            mat-button
+            mat-raised-button
+            class="mat-basic small-button"
+            (click)="selectAll(false)"
+            [disabled]="!showOptions"
+        >
+            <span>Select none</span>
+        </button>
         <button
             mat-button
             mat-raised-button
             color="accent"
             class="small-button"
             (click)="loadOptionsFromRestApi()"
-            style="margin-right: 10px; margin-left: 10px"
             [disabled]="!showOptions"
         >
             <span>Reload</span>
         </button>
+        <mat-spinner
+            *ngIf="loading"
+            color="accent"
+            [mode]="'indeterminate'"
+            [diameter]="15"
+        ></mat-spinner>
     </div>
-    <div
-        *ngIf="!staticProperty.horizontalRendering"
-        fxLayout="column"
-        style="margin-top: 10px"
-    >
+    <div *ngIf="!staticProperty.horizontalRendering" fxLayout="column">
         <mat-checkbox
             style="padding-left: 10px"
             color="accent"
             *ngFor="let option of staticProperty.options"
             [(ngModel)]="option.selected"
+            (ngModelChange)="checkEmitUpdate()"
         >
             {{ option.name }}
         </mat-checkbox>
     </div>
-    <div fxLayout="column" *ngIf="!showOptions && !loading" class="mt-10">
+    <div fxLayout="column" *ngIf="!showOptions && !loading" class="mb-10">
         <span>(waiting for input)</span>
     </div>
-    <div fxLayout="column" *ngIf="loading">
-        <mat-spinner
-            color="accent"
-            [mode]="'indeterminate'"
-            [diameter]="20"
-        ></mat-spinner>
-    </div>
 
-    <div *ngIf="staticProperty.horizontalRendering">
+    <div *ngIf="staticProperty.horizontalRendering && showOptions">
         <mat-form-field style="width: 100%" color="accent">
-            <mat-label>{{ staticProperty.label }}</mat-label>
-            <mat-select multiple [(ngModel)]="option.selected">
+            <mat-select
+                multiple
+                [(ngModel)]="selectedOptions"
+                (selectionChange)="onSelectionChange()"
+            >
                 <mat-option
                     *ngFor="let option of staticProperty.options"
                     [value]="option"
@@ -66,7 +83,6 @@
                     {{ option.name }}
                 </mat-option>
             </mat-select>
-            <mat-hint>{{ staticProperty.description }}</mat-hint>
         </mat-form-field>
     </div>
 </div>
diff --git 
a/ui/src/app/core-ui/static-properties/static-runtime-resolvable-any-input/static-runtime-resolvable-any-input.component.ts
 
b/ui/src/app/core-ui/static-properties/static-runtime-resolvable-any-input/static-runtime-resolvable-any-input.component.ts
index 2fb2ea4da5..6d84538535 100644
--- 
a/ui/src/app/core-ui/static-properties/static-runtime-resolvable-any-input/static-runtime-resolvable-any-input.component.ts
+++ 
b/ui/src/app/core-ui/static-properties/static-runtime-resolvable-any-input/static-runtime-resolvable-any-input.component.ts
@@ -18,11 +18,13 @@
 
 import { Component, OnInit } from '@angular/core';
 import {
+    Option,
     RuntimeResolvableAnyStaticProperty,
     StaticPropertyUnion,
 } from '@streampipes/platform-services';
 import { RuntimeResolvableService } from 
'../static-runtime-resolvable-input/runtime-resolvable.service';
 import { BaseRuntimeResolvableSelectionInput } from 
'../static-runtime-resolvable-input/base-runtime-resolvable-selection-input';
+import { MatSelectChange } from '@angular/material/select';
 
 @Component({
     selector: 'sp-app-static-runtime-resolvable-any-input',
@@ -33,25 +35,40 @@ export class StaticRuntimeResolvableAnyInputComponent
     extends 
BaseRuntimeResolvableSelectionInput<RuntimeResolvableAnyStaticProperty>
     implements OnInit
 {
+    selectedOptions: Option[] = [];
+
     constructor(runtimeResolvableService: RuntimeResolvableService) {
         super(runtimeResolvableService);
     }
 
     ngOnInit() {
         super.onInit();
+        this.selectedOptions = this.staticProperty.options.filter(
+            o => o.selected,
+        );
+    }
+
+    selectAll(select: boolean): void {
+        this.staticProperty.options.forEach(o => (o.selected = select));
+        this.selectedOptions = select ? this.staticProperty.options : [];
+        this.emitUpdate(true);
+    }
+
+    onSelectionChange(): void {
+        this.staticProperty.options.forEach(option => {
+            option.selected = this.selectedOptions.includes(option);
+        });
     }
 
-    select(id) {
-        for (const option of this.staticProperty.options) {
-            option.selected = false;
-        }
-        this.staticProperty.options.find(
-            option => option.elementId === id,
-        ).selected = true;
+    checkEmitUpdate(): void {
+        this.emitUpdate(true);
     }
 
     afterOptionsLoaded(staticProperty: RuntimeResolvableAnyStaticProperty) {
         this.staticProperty.options = staticProperty.options;
+        this.selectedOptions = this.staticProperty.options.filter(
+            o => o.selected,
+        );
     }
 
     parse(

Reply via email to