This is an automated email from the ASF dual-hosted git repository. riemer pushed a commit to branch fix-optional-static-properties in repository https://gitbox.apache.org/repos/asf/streampipes.git
commit 6ad0da1800ad61fca3a52e6ede04aea94412ecc2 Author: Dominik Riemer <[email protected]> AuthorDate: Sun Mar 1 21:57:12 2026 +0100 fix: Properly handle optional static properties --- .../base/abstract-validated-static-property.ts | 1 + .../static-color-picker.component.ts | 35 +++++++++++++++++----- .../static-file-input.component.ts | 4 ++- .../static-free-input.component.ts | 7 +++-- .../static-mapping-unary.component.ts | 32 +++++++++++++++++--- .../static-property-util.service.ts | 1 + .../static-property.component.html | 1 + .../static-runtime-resolvable-group.component.html | 15 ---------- .../static-secret-input.component.html | 2 +- .../static-secret-input.component.ts | 31 ++++++++++++++----- .../static-slide-toggle.component.ts | 4 +-- 11 files changed, 92 insertions(+), 41 deletions(-) diff --git a/ui/src/app/core-ui/static-properties/base/abstract-validated-static-property.ts b/ui/src/app/core-ui/static-properties/base/abstract-validated-static-property.ts index d26d033746..898ab74350 100644 --- a/ui/src/app/core-ui/static-properties/base/abstract-validated-static-property.ts +++ b/ui/src/app/core-ui/static-properties/base/abstract-validated-static-property.ts @@ -38,6 +38,7 @@ export abstract class AbstractValidatedStaticPropertyRenderer< } enableValidators() { + this.fieldValid = this.parentForm.controls[this.fieldName].valid; this.parentForm.controls[this.fieldName].valueChanges.subscribe( value => { this.onValueChange(value); diff --git a/ui/src/app/core-ui/static-properties/static-color-picker/static-color-picker.component.ts b/ui/src/app/core-ui/static-properties/static-color-picker/static-color-picker.component.ts index c21ca8bcba..3b46e52881 100644 --- a/ui/src/app/core-ui/static-properties/static-color-picker/static-color-picker.component.ts +++ b/ui/src/app/core-ui/static-properties/static-color-picker/static-color-picker.component.ts @@ -18,7 +18,12 @@ import { Component, OnInit } from '@angular/core'; import { StaticPropertyUtilService } from '../static-property-util.service'; -import { FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; +import { + FormsModule, + ReactiveFormsModule, + ValidatorFn, + Validators, +} from '@angular/forms'; import { ColorPickerStaticProperty } from '@streampipes/platform-services'; import { AbstractValidatedStaticPropertyRenderer } from '../base/abstract-validated-static-property'; import { FlexDirective, LayoutDirective } from '@ngbracket/ngx-layout/flex'; @@ -59,23 +64,37 @@ export class StaticColorPickerComponent ngOnInit() { this.addValidator( this.staticProperty.selectedColor, - Validators.required, + this.collectValidators(), ); this.enableValidators(); + this.checkCompleted(); + } + + private collectValidators(): ValidatorFn[] { + const validators: ValidatorFn[] = []; + if (!this.staticProperty.optional) { + validators.push(Validators.required); + } + + return validators; } checkCompleted() { this.applyCompletedConfiguration( - this.staticPropertyUtil.asColorPickerStaticProperty( - this.staticProperty, - ).selectedColor && - this.staticPropertyUtil.asColorPickerStaticProperty( + this.staticProperty.optional || + (this.staticPropertyUtil.asColorPickerStaticProperty( this.staticProperty, - ).selectedColor !== '', + ).selectedColor && + this.staticPropertyUtil.asColorPickerStaticProperty( + this.staticProperty, + ).selectedColor !== ''), ); } onStatusChange(status: any) {} - onValueChange(value: any) {} + onValueChange(value: any) { + this.staticProperty.selectedColor = value; + this.checkCompleted(); + } } diff --git a/ui/src/app/core-ui/static-properties/static-file-input/static-file-input.component.ts b/ui/src/app/core-ui/static-properties/static-file-input/static-file-input.component.ts index 90c60615ad..86f8754f69 100644 --- a/ui/src/app/core-ui/static-properties/static-file-input/static-file-input.component.ts +++ b/ui/src/app/core-ui/static-properties/static-file-input/static-file-input.component.ts @@ -126,7 +126,9 @@ export class StaticFileInputComponent collectValidators() { const validators: ValidatorFn[] = []; - validators.push(Validators.required); + if (!this.staticProperty.optional) { + validators.push(Validators.required); + } return validators; } diff --git a/ui/src/app/core-ui/static-properties/static-free-input/static-free-input.component.ts b/ui/src/app/core-ui/static-properties/static-free-input/static-free-input.component.ts index 5748c6b942..97d02656fb 100644 --- a/ui/src/app/core-ui/static-properties/static-free-input/static-free-input.component.ts +++ b/ui/src/app/core-ui/static-properties/static-free-input/static-free-input.component.ts @@ -128,9 +128,10 @@ export class StaticFreeInputComponent emitUpdate() { const valid = - this.staticProperty.value !== undefined && - this.staticProperty.value !== '' && - this.staticProperty.value !== null; + this.staticProperty.optional || + (this.staticProperty.value !== undefined && + this.staticProperty.value !== '' && + this.staticProperty.value !== null); this.applyCompletedConfiguration(valid); } diff --git a/ui/src/app/core-ui/static-properties/static-mapping-unary/static-mapping-unary.component.ts b/ui/src/app/core-ui/static-properties/static-mapping-unary/static-mapping-unary.component.ts index 5b7e8fe923..8e325377a1 100644 --- a/ui/src/app/core-ui/static-properties/static-mapping-unary/static-mapping-unary.component.ts +++ b/ui/src/app/core-ui/static-properties/static-mapping-unary/static-mapping-unary.component.ts @@ -17,7 +17,12 @@ */ import { Component, OnInit } from '@angular/core'; -import { FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; +import { + FormsModule, + ReactiveFormsModule, + ValidatorFn, + Validators, +} from '@angular/forms'; import { StaticMappingComponent } from '../static-mapping/static-mapping'; import { MappingPropertyUnary } from '@streampipes/platform-services'; import { FlexDirective, LayoutDirective } from '@ngbracket/ngx-layout/flex'; @@ -50,22 +55,41 @@ export class StaticMappingUnaryComponent ngOnInit() { this.extractPossibleSelections(); - if (!this.staticProperty.selectedProperty) { + if ( + !this.staticProperty.selectedProperty && + !this.staticProperty.optional + ) { this.staticProperty.selectedProperty = this.availableProperties[0].propertySelector; this.applyCompletedConfiguration(true); } this.addValidator( this.staticProperty.selectedProperty, - Validators.required, + this.collectValidators(), ); this.enableValidators(); + this.applyCompletedConfiguration( + this.staticProperty.optional || + !!this.staticProperty.selectedProperty, + ); + } + + private collectValidators(): ValidatorFn[] { + const validators: ValidatorFn[] = []; + if (!this.staticProperty.optional) { + validators.push(Validators.required); + } + + return validators; } onStatusChange(status: any) {} onValueChange(value: any) { this.staticProperty.selectedProperty = value; - this.applyCompletedConfiguration(true); + this.applyCompletedConfiguration( + this.staticProperty.optional || + !!this.staticProperty.selectedProperty, + ); } } diff --git a/ui/src/app/core-ui/static-properties/static-property-util.service.ts b/ui/src/app/core-ui/static-properties/static-property-util.service.ts index f1e6989f87..314d20d915 100644 --- a/ui/src/app/core-ui/static-properties/static-property-util.service.ts +++ b/ui/src/app/core-ui/static-properties/static-property-util.service.ts @@ -191,6 +191,7 @@ export class StaticPropertyUtilService { dst.label = src.label; dst.description = src.description; dst.internalName = src.internalName; + dst.optional = src.optional; return dst; } 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 b071831fd9..0ebed3e66b 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 @@ -241,6 +241,7 @@ [eventSchemas]="eventSchemas" [parentForm]="parentForm" [fieldName]="fieldName" + [pipelineElement]="pipelineElement" [staticProperties]="staticProperties" [renderStaticProperty]="groupStaticPropertyTpl" [staticProperty]="staticProperty" diff --git a/ui/src/app/core-ui/static-properties/static-runtime-resolvable-group/static-runtime-resolvable-group.component.html b/ui/src/app/core-ui/static-properties/static-runtime-resolvable-group/static-runtime-resolvable-group.component.html index 11069a4bb1..aeb36061e0 100644 --- a/ui/src/app/core-ui/static-properties/static-runtime-resolvable-group/static-runtime-resolvable-group.component.html +++ b/ui/src/app/core-ui/static-properties/static-runtime-resolvable-group/static-runtime-resolvable-group.component.html @@ -47,21 +47,6 @@ [ngTemplateOutlet]="renderStaticProperty" [ngTemplateOutletContext]="ctxFor(property, i)" /> - <!-- <sp-app-static-property--> - <!-- [adapterId]="adapterId"--> - <!-- [parentForm]="parentForm"--> - <!-- [staticProperties]="staticProperties"--> - <!-- [fieldName]="--> - <!-- fieldName + '-' + property.internalName + '-' + i--> - <!-- "--> - <!-- [showBorder]="false"--> - <!-- [eventSchemas]="eventSchemas"--> - <!-- [staticProperty]="property"--> - <!-- [displayRecommended]="displayRecommended"--> - <!-- (updateEmitter)="handleConfigurationUpdate($event)"--> - <!-- class="test fullWidth"--> - <!-- >--> - <!-- </sp-app-static-property>--> } </div> </div> diff --git a/ui/src/app/core-ui/static-properties/static-secret-input/static-secret-input.component.html b/ui/src/app/core-ui/static-properties/static-secret-input/static-secret-input.component.html index 1e7a0430d0..03a3fc3c50 100644 --- a/ui/src/app/core-ui/static-properties/static-secret-input/static-secret-input.component.html +++ b/ui/src/app/core-ui/static-properties/static-secret-input/static-secret-input.component.html @@ -25,7 +25,7 @@ formControlName="{{ fieldName }}" matInput [placeholder]="staticProperty.label" - required + [required]="!staticProperty.optional" [attr.data-cy]="fieldName" (blur)="emitUpdate()" /> diff --git a/ui/src/app/core-ui/static-properties/static-secret-input/static-secret-input.component.ts b/ui/src/app/core-ui/static-properties/static-secret-input/static-secret-input.component.ts index bc9251ff62..68d442ba98 100644 --- a/ui/src/app/core-ui/static-properties/static-secret-input/static-secret-input.component.ts +++ b/ui/src/app/core-ui/static-properties/static-secret-input/static-secret-input.component.ts @@ -17,7 +17,12 @@ */ import { Component, OnInit } from '@angular/core'; -import { FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; +import { + FormsModule, + ReactiveFormsModule, + ValidatorFn, + Validators, +} from '@angular/forms'; import { StaticPropertyUtilService } from '../static-property-util.service'; import { SecretStaticProperty } from '@streampipes/platform-services'; import { AbstractValidatedStaticPropertyRenderer } from '../base/abstract-validated-static-property'; @@ -48,18 +53,29 @@ export class StaticSecretInputComponent } ngOnInit() { - this.addValidator(this.staticProperty.value, Validators.required); + this.addValidator(this.staticProperty.value, this.collectValidators()); this.enableValidators(); + this.emitUpdate(); + } + + private collectValidators(): ValidatorFn[] { + const validators: ValidatorFn[] = []; + if (!this.staticProperty.optional) { + validators.push(Validators.required); + } + + return validators; } emitUpdate() { this.applyCompletedConfiguration( - this.staticPropertyUtil.asFreeTextStaticProperty( - this.staticProperty, - ).value && - this.staticPropertyUtil.asFreeTextStaticProperty( + this.staticProperty.optional || + (this.staticPropertyUtil.asFreeTextStaticProperty( this.staticProperty, - ).value !== '', + ).value && + this.staticPropertyUtil.asFreeTextStaticProperty( + this.staticProperty, + ).value !== ''), ); } @@ -68,5 +84,6 @@ export class StaticSecretInputComponent onValueChange(value: any) { this.staticProperty.value = value; this.staticProperty.encrypted = false; + this.emitUpdate(); } } diff --git a/ui/src/app/core-ui/static-properties/static-slide-toggle/static-slide-toggle.component.ts b/ui/src/app/core-ui/static-properties/static-slide-toggle/static-slide-toggle.component.ts index a52e5294bb..dfc2220921 100644 --- a/ui/src/app/core-ui/static-properties/static-slide-toggle/static-slide-toggle.component.ts +++ b/ui/src/app/core-ui/static-properties/static-slide-toggle/static-slide-toggle.component.ts @@ -19,7 +19,7 @@ import { Component, OnInit } from '@angular/core'; import { SlideToggleStaticProperty } from '@streampipes/platform-services'; import { AbstractValidatedStaticPropertyRenderer } from '../base/abstract-validated-static-property'; -import { FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { FlexDirective, LayoutDirective } from '@ngbracket/ngx-layout/flex'; import { MatSlideToggle } from '@angular/material/slide-toggle'; @@ -39,7 +39,7 @@ export class StaticSlideToggleComponent implements OnInit { ngOnInit(): void { - this.addValidator(this.staticProperty.selected, Validators.required); + this.addValidator(this.staticProperty.selected, []); this.enableValidators(); this.emitUpdate(); }
