This is an automated email from the ASF dual-hosted git repository. zehnder pushed a commit to branch migrate-first-components-to-signals in repository https://gitbox.apache.org/repos/asf/streampipes.git
commit 17363bbf7aaa928a33cdebeb0de516e4a6ce538a Author: Philipp Zehnder <[email protected]> AuthorDate: Wed Mar 18 14:20:00 2026 +0100 refactor: migrate core-ui components to signals --- .../core-ui/error-hint/error-hint.component.html | 30 +++++++++------------ .../app/core-ui/error-hint/error-hint.component.ts | 22 +++++++-------- .../loading-indicator.component.html | 2 +- .../loading-indicator.component.ts | 7 +++-- .../pipeline-operation-status.component.html | 2 +- .../pipeline-operation-status.component.ts | 7 ++--- .../pipeline-started-status.component.html | 26 +++++++++--------- .../pipeline-started-status.component.ts | 31 +++++++--------------- .../status-indicator.component.html | 6 ++--- .../status-indicator/status-indicator.component.ts | 13 ++++----- 10 files changed, 62 insertions(+), 84 deletions(-) diff --git a/ui/src/app/core-ui/error-hint/error-hint.component.html b/ui/src/app/core-ui/error-hint/error-hint.component.html index b86579b5ef..1507d70ad6 100644 --- a/ui/src/app/core-ui/error-hint/error-hint.component.html +++ b/ui/src/app/core-ui/error-hint/error-hint.component.html @@ -16,51 +16,47 @@ ~ --> <div class="error-hint-position"> - @if (displayMessages) { + @if (displayMessages()) { <div class="pipeline-validation-summary {{ - errorMessages.length > 0 - ? 'pipeline-validation-summary-error' - : '' + hasErrorMessages() ? 'pipeline-validation-summary-error' : '' }}" (click)="toggleErrorMessagesDisplayed()" > <div fxLayout="row" fxLayoutAlign="center center"> <div fxLayout="row" fxLayoutAlign="start center"> - @if (errorMessages.length > 0) { + @if (hasErrorMessages()) { <i class="material-icons">notifications</i> } - @if (errorMessages.length === 0) { + @if (!hasErrorMessages()) { <i class="material-icons">done</i> } </div> <div> - @if (errorMessages.length === 0) { - <span>{{ validationString }} ok</span> + @if (!hasErrorMessages()) { + <span>{{ validationString() }} ok</span> } - @if (errorMessages.length > 0) { + @if (hasErrorMessages()) { <span - >{{ errorMessages.length }} - {{ - errorMessages.length > 1 ? 'hints' : 'hint' - }}</span + >{{ errorCount() }} + {{ errorCount() > 1 ? 'hints' : 'hint' }}</span > } </div> </div> </div> } - @if (errorMessages.length > 0 && errorMessagesDisplayed) { + @if (hasErrorMessages() && errorMessagesDisplayed()) { <div class="editor-error-notifications"> <h5 class="error-hint-color"> <b - >{{ errorMessages.length }} - {{ errorMessages.length === 1 ? 'error' : 'errors' }} + >{{ errorCount() }} + {{ errorCount() === 1 ? 'error' : 'errors' }} found.</b > </h5> <hr /> - @for (errorMessage of errorMessages; track errorMessage) { + @for (errorMessage of errorMessages(); track errorMessage) { <div> <b>{{ errorMessage.title }}</b> <div>{{ errorMessage.content }}</div> diff --git a/ui/src/app/core-ui/error-hint/error-hint.component.ts b/ui/src/app/core-ui/error-hint/error-hint.component.ts index 0994193416..7242135909 100644 --- a/ui/src/app/core-ui/error-hint/error-hint.component.ts +++ b/ui/src/app/core-ui/error-hint/error-hint.component.ts @@ -16,7 +16,7 @@ * */ -import { Component, Input, OnInit } from '@angular/core'; +import { Component, computed, input, signal } from '@angular/core'; import { UserErrorMessage } from '../../core-model/base/UserErrorMessage'; import { LayoutAlignDirective, @@ -29,20 +29,16 @@ import { styleUrls: ['./error-hint.component.scss'], imports: [LayoutDirective, LayoutAlignDirective], }) -export class ErrorHintComponent implements OnInit { - @Input() errorMessages: UserErrorMessage[]; - @Input() displayMessages = true; - @Input() validationString: string; +export class ErrorHintComponent { + readonly errorMessages = input<UserErrorMessage[]>([]); + readonly displayMessages = input(true); + readonly validationString = input(''); - errorMessagesDisplayed: boolean; - - constructor() {} - - ngOnInit(): void { - this.errorMessagesDisplayed = false; - } + readonly errorMessagesDisplayed = signal(false); + readonly errorCount = computed(() => this.errorMessages().length); + readonly hasErrorMessages = computed(() => this.errorCount() > 0); public toggleErrorMessagesDisplayed() { - this.errorMessagesDisplayed = !this.errorMessagesDisplayed; + this.errorMessagesDisplayed.update(displayed => !displayed); } } diff --git a/ui/src/app/core-ui/loading-indicator/loading-indicator.component.html b/ui/src/app/core-ui/loading-indicator/loading-indicator.component.html index 3982ccb2ac..3be5c4666f 100644 --- a/ui/src/app/core-ui/loading-indicator/loading-indicator.component.html +++ b/ui/src/app/core-ui/loading-indicator/loading-indicator.component.html @@ -18,5 +18,5 @@ <div fxLayout="column" fxFlex="100" fxLayoutAlign="center center"> <mat-spinner [diameter]="30" color="accent"></mat-spinner> - <div class="message-text">{{ message }}</div> + <div class="message-text">{{ message() }}</div> </div> diff --git a/ui/src/app/core-ui/loading-indicator/loading-indicator.component.ts b/ui/src/app/core-ui/loading-indicator/loading-indicator.component.ts index 5821e78d3c..b96cf1100d 100644 --- a/ui/src/app/core-ui/loading-indicator/loading-indicator.component.ts +++ b/ui/src/app/core-ui/loading-indicator/loading-indicator.component.ts @@ -16,7 +16,7 @@ * */ -import { Component, inject, Input } from '@angular/core'; +import { Component, inject, input } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { FlexDirective, @@ -37,8 +37,7 @@ import { MatProgressSpinner } from '@angular/material/progress-spinner'; ], }) export class LoadingIndicatorComponent { - translateService = inject(TranslateService); + private readonly translateService = inject(TranslateService); - @Input() - message = this.translateService.instant('Loading'); + readonly message = input(this.translateService.instant('Loading')); } diff --git a/ui/src/app/core-ui/pipeline/pipeline-operation-status/pipeline-operation-status.component.html b/ui/src/app/core-ui/pipeline/pipeline-operation-status/pipeline-operation-status.component.html index 3424af07c4..88dde64932 100644 --- a/ui/src/app/core-ui/pipeline/pipeline-operation-status/pipeline-operation-status.component.html +++ b/ui/src/app/core-ui/pipeline/pipeline-operation-status/pipeline-operation-status.component.html @@ -16,7 +16,7 @@ ~ --> -@for (msg of pipelineOperationStatus.elementStatus; track msg) { +@for (msg of pipelineOperationStatus()?.elementStatus ?? []; track msg) { <div fxFlex="100" fxLayout="column" class="status-outer mt-10"> <div fxFlex="100" fxLayout="column"> <div diff --git a/ui/src/app/core-ui/pipeline/pipeline-operation-status/pipeline-operation-status.component.ts b/ui/src/app/core-ui/pipeline/pipeline-operation-status/pipeline-operation-status.component.ts index 76489c92d6..cbfd29fe76 100644 --- a/ui/src/app/core-ui/pipeline/pipeline-operation-status/pipeline-operation-status.component.ts +++ b/ui/src/app/core-ui/pipeline/pipeline-operation-status/pipeline-operation-status.component.ts @@ -16,7 +16,7 @@ * */ -import { Component, Input } from '@angular/core'; +import { Component, input } from '@angular/core'; import { PipelineOperationStatus } from '@streampipes/platform-services'; import { FlexDirective, @@ -32,6 +32,7 @@ import { MatIcon } from '@angular/material/icon'; imports: [FlexDirective, LayoutDirective, LayoutAlignDirective, MatIcon], }) export class PipelineOperationStatusComponent { - @Input() - pipelineOperationStatus: PipelineOperationStatus; + readonly pipelineOperationStatus = input< + PipelineOperationStatus | undefined + >(undefined); } diff --git a/ui/src/app/core-ui/pipeline/pipeline-started-status/pipeline-started-status.component.html b/ui/src/app/core-ui/pipeline/pipeline-started-status/pipeline-started-status.component.html index 8f41f26993..a73fb1e48e 100644 --- a/ui/src/app/core-ui/pipeline/pipeline-started-status/pipeline-started-status.component.html +++ b/ui/src/app/core-ui/pipeline/pipeline-started-status/pipeline-started-status.component.html @@ -25,20 +25,20 @@ data-cy="sp-pipeline-started-dialog" > <div fxLayout="row"> - @if (pipelineOperationStatus.success) { + @if (pipelineOperationStatus()?.success) { <mat-icon data-cy="sp-pipeline-started-success" color="accent" >done</mat-icon > } - @if (!pipelineOperationStatus.success) { + @if (!pipelineOperationStatus()?.success) { <mat-icon style="color: red">error</mat-icon> } - <span> {{ pipelineOperationStatus.title }}.</span> + <span> {{ pipelineOperationStatus()?.title }}.</span> </div> @if ( - action === 1 && - !pipelineOperationStatus.success && - !forceStopDisabled + action() === 1 && + !pipelineOperationStatus()?.success && + !forceStopDisabled() ) { <span class="message-small">{{ 'You can perform a forced stop, which will stop and reset the pipeline status.' @@ -53,21 +53,21 @@ class="mat-basic" (click)="toggleStatusDetailsVisible()" > - @if (!statusDetailsVisible) { + @if (!statusDetailsVisible()) { <div> {{ 'Show Details' | translate }} </div> } - @if (statusDetailsVisible) { + @if (statusDetailsVisible()) { <div> {{ 'Hide Details' | translate }} </div> } </button> @if ( - action === 1 && - !pipelineOperationStatus.success && - !forceStopDisabled + action() === 1 && + !pipelineOperationStatus()?.success && + !forceStopDisabled() ) { <button mat-button @@ -81,11 +81,11 @@ } </div> - @if (statusDetailsVisible) { + @if (statusDetailsVisible()) { <div fxFlex="100" fxLayout="column" class="w-100"> <sp-pipeline-operation-status fxLayout="column" - [pipelineOperationStatus]="pipelineOperationStatus" + [pipelineOperationStatus]="pipelineOperationStatus()" > </sp-pipeline-operation-status> </div> diff --git a/ui/src/app/core-ui/pipeline/pipeline-started-status/pipeline-started-status.component.ts b/ui/src/app/core-ui/pipeline/pipeline-started-status/pipeline-started-status.component.ts index 6566904a9f..947e92d7b9 100644 --- a/ui/src/app/core-ui/pipeline/pipeline-started-status/pipeline-started-status.component.ts +++ b/ui/src/app/core-ui/pipeline/pipeline-started-status/pipeline-started-status.component.ts @@ -16,7 +16,7 @@ * */ -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Component, input, output, signal } from '@angular/core'; import { PipelineOperationStatus } from '@streampipes/platform-services'; import { PipelineAction } from '../../../pipelines/model/pipeline-model'; import { @@ -43,32 +43,21 @@ import { TranslatePipe } from '@ngx-translate/core'; TranslatePipe, ], }) -export class PipelineStartedStatusComponent implements OnInit { - @Input() - pipelineOperationStatus: PipelineOperationStatus; +export class PipelineStartedStatusComponent { + readonly pipelineOperationStatus = input< + PipelineOperationStatus | undefined + >(undefined); + readonly action = input<PipelineAction | undefined>(undefined); + readonly forceStopDisabled = input(false); - @Input() - action: PipelineAction; - - @Input() - forceStopDisabled = false; - - @Output() - forceStopPipelineEmitter = new EventEmitter(); - - statusDetailsVisible: boolean; - - constructor() {} - - ngOnInit(): void { - this.statusDetailsVisible = false; - } + readonly forceStopPipelineEmitter = output<void>(); + readonly statusDetailsVisible = signal(false); forceStopPipeline() { this.forceStopPipelineEmitter.emit(); } toggleStatusDetailsVisible() { - this.statusDetailsVisible = !this.statusDetailsVisible; + this.statusDetailsVisible.update(visible => !visible); } } diff --git a/ui/src/app/core-ui/status-indicator/status-indicator.component.html b/ui/src/app/core-ui/status-indicator/status-indicator.component.html index bbb27508b0..173b275c47 100644 --- a/ui/src/app/core-ui/status-indicator/status-indicator.component.html +++ b/ui/src/app/core-ui/status-indicator/status-indicator.component.html @@ -17,7 +17,7 @@ --> <div fxLayout="column" fxFlex="100" fxLayoutAlign="center center"> - <i class="material-icons status-icon">{{ icon }}</i> - <div class="status-text">{{ message }}</div> - <div class="status-subtext">{{ additionalDescription }}</div> + <i class="material-icons status-icon">{{ icon() }}</i> + <div class="status-text">{{ message() }}</div> + <div class="status-subtext">{{ additionalDescription() }}</div> </div> diff --git a/ui/src/app/core-ui/status-indicator/status-indicator.component.ts b/ui/src/app/core-ui/status-indicator/status-indicator.component.ts index 738494c2b8..acefc62920 100644 --- a/ui/src/app/core-ui/status-indicator/status-indicator.component.ts +++ b/ui/src/app/core-ui/status-indicator/status-indicator.component.ts @@ -16,7 +16,7 @@ * */ -import { Component, inject, Input } from '@angular/core'; +import { Component, inject, input } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { FlexDirective, @@ -31,14 +31,11 @@ import { imports: [LayoutDirective, FlexDirective, LayoutAlignDirective], }) export class StatusIndicatorComponent { - translateService = inject(TranslateService); + private readonly translateService = inject(TranslateService); - @Input() - message = this.translateService.instant('Loading'); + readonly message = input(this.translateService.instant('Loading')); - @Input() - additionalDescription = ''; + readonly additionalDescription = input(''); - @Input() - icon: string; + readonly icon = input<string | undefined>(undefined); }
