This is an automated email from the ASF dual-hosted git repository.
riemer pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/streampipes.git
The following commit(s) were added to refs/heads/dev by this push:
new 75e4d76578 refactor: migrate core-ui components to signals (#4267)
75e4d76578 is described below
commit 75e4d765781f702ac82388898fbfdd6fe9450825
Author: Philipp Zehnder <[email protected]>
AuthorDate: Sat Mar 21 20:23:54 2026 +0100
refactor: migrate core-ui components to signals (#4267)
---
.../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);
}