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(
