This is an automated email from the ASF dual-hosted git repository. zehnder pushed a commit to branch 4270-add-cancel-navigation-option-to-unsaved-changes-warning-for-chartsdashboards in repository https://gitbox.apache.org/repos/asf/streampipes.git
commit 7892d0d7e4823626b7d2bb50564c8a69beec7793 Author: Philipp Zehnder <[email protected]> AuthorDate: Fri Mar 20 15:38:01 2026 +0100 fix(#4270): add keep editing option to leave dialog --- ui/deployment/i18n/de.json | 1 + ui/deployment/i18n/en.json | 1 + ui/deployment/i18n/pl.json | 1 + .../confirm-dialog/confirm-dialog.component.html | 52 ++++++++++++++++------ .../confirm-dialog/confirm-dialog.component.scss | 4 ++ .../confirm-dialog/confirm-dialog.component.ts | 8 +++- .../components/chart-view/chart-view.component.ts | 25 +++++++---- .../components/panel/dashboard-panel.component.ts | 21 ++++++--- 8 files changed, 82 insertions(+), 31 deletions(-) diff --git a/ui/deployment/i18n/de.json b/ui/deployment/i18n/de.json index 4b2c860442..62b990cf10 100644 --- a/ui/deployment/i18n/de.json +++ b/ui/deployment/i18n/de.json @@ -847,6 +847,7 @@ "Save changes?": "Änderungen speichern?", "Update all changes to dashboard charts or discard current changes.": "Aktualisieren Sie alle Änderungen der Diagramme oder verwerfen Sie aktuelle Änderungen.", "Discard changes": "Änderungen verwerfen", + "Keep editing": "Weiter bearbeiten", "Off": "Aus", "Are you sure you want to delete this dashboard?": "Sind Sie sicher, dass Sie dieses Dashboard löschen möchten?", "This action cannot be undone!": "Diese Aktion kann nicht rückgängig gemacht werden!", diff --git a/ui/deployment/i18n/en.json b/ui/deployment/i18n/en.json index 9570d3407a..4d33544b20 100644 --- a/ui/deployment/i18n/en.json +++ b/ui/deployment/i18n/en.json @@ -847,6 +847,7 @@ "Save changes?": null, "Update all changes to dashboard charts or discard current changes.": null, "Discard changes": null, + "Keep editing": null, "Off": null, "Are you sure you want to delete this dashboard?": null, "This action cannot be undone!": null, diff --git a/ui/deployment/i18n/pl.json b/ui/deployment/i18n/pl.json index 5420260fbc..591f1fa683 100644 --- a/ui/deployment/i18n/pl.json +++ b/ui/deployment/i18n/pl.json @@ -847,6 +847,7 @@ "Save changes?": "Zapisać zmiany?", "Update all changes to dashboard charts or discard current changes.": "Zapisz wszystkie zmiany wykresów pulpitu lub odrzuć bieżące zmiany.", "Discard changes": "Odrzuć zmiany", + "Keep editing": "Kontynuuj edycję", "Off": "Wyłączone", "Are you sure you want to delete this dashboard?": "Czy na pewno chcesz usunąć ten pulpit?", "This action cannot be undone!": "Tego działania nie można cofnąć!", diff --git a/ui/projects/streampipes/shared-ui/src/lib/dialog/confirm-dialog/confirm-dialog.component.html b/ui/projects/streampipes/shared-ui/src/lib/dialog/confirm-dialog/confirm-dialog.component.html index 0a898a2cc8..96d592c0aa 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/dialog/confirm-dialog/confirm-dialog.component.html +++ b/ui/projects/streampipes/shared-ui/src/lib/dialog/confirm-dialog/confirm-dialog.component.html @@ -24,21 +24,47 @@ </div> </mat-dialog-content> <mat-dialog-actions> - <div fxFlex="100" fxLayoutAlign="end center" class="footer"> - @if (data.confirmAndCancel) { - <button mat-button (click)="onCancel()" data-cy="cancel-delete"> - {{ data.cancelTitle }} - </button> + <div + fxFlex="100" + fxLayout="row" + fxLayoutAlign="start center" + class="footer" + > + @if (data.neutralTitle) { + <div class="neutral-action-wrapper"> + <button + mat-button + (click)="onNeutral()" + data-cy="neutral-action" + > + {{ data.neutralTitle }} + </button> + </div> } - <button - mat-flat-button - color="accent" - (click)="onOk()" - cdkFocusInitial - data-cy="confirm-delete" + <div + fxLayout="row" + fxLayoutAlign="end center" + class="primary-actions" > - {{ data.okTitle }} - </button> + @if (data.confirmAndCancel) { + <button + mat-button + (click)="onCancel()" + data-cy="cancel-delete" + > + {{ data.cancelTitle }} + </button> + } + <button + mat-flat-button + color="accent" + (click)="onOk()" + cdkFocusInitial + data-cy="confirm-delete" + > + {{ data.okTitle }} + </button> + </div> </div> </mat-dialog-actions> </div> diff --git a/ui/projects/streampipes/shared-ui/src/lib/dialog/confirm-dialog/confirm-dialog.component.scss b/ui/projects/streampipes/shared-ui/src/lib/dialog/confirm-dialog/confirm-dialog.component.scss index 2f93cd02a0..eef4ad0780 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/dialog/confirm-dialog/confirm-dialog.component.scss +++ b/ui/projects/streampipes/shared-ui/src/lib/dialog/confirm-dialog/confirm-dialog.component.scss @@ -19,3 +19,7 @@ .footer { margin-top: 20px; } + +.neutral-action-wrapper { + margin-right: auto; +} diff --git a/ui/projects/streampipes/shared-ui/src/lib/dialog/confirm-dialog/confirm-dialog.component.ts b/ui/projects/streampipes/shared-ui/src/lib/dialog/confirm-dialog/confirm-dialog.component.ts index 9ee80e3e70..317c2fb343 100644 --- a/ui/projects/streampipes/shared-ui/src/lib/dialog/confirm-dialog/confirm-dialog.component.ts +++ b/ui/projects/streampipes/shared-ui/src/lib/dialog/confirm-dialog/confirm-dialog.component.ts @@ -50,10 +50,14 @@ export class ConfirmDialogComponent { ) {} onCancel(): void { - this.dialogRef.close(); + this.dialogRef.close(this.data.cancelResult); + } + + onNeutral(): void { + this.dialogRef.close(this.data.neutralResult); } onOk(): void { - this.dialogRef.close(true); + this.dialogRef.close(this.data.okResult ?? true); } } diff --git a/ui/src/app/chart/components/chart-view/chart-view.component.ts b/ui/src/app/chart/components/chart-view/chart-view.component.ts index 937d43fccf..9f0eee7aa4 100644 --- a/ui/src/app/chart/components/chart-view/chart-view.component.ts +++ b/ui/src/app/chart/components/chart-view/chart-view.component.ts @@ -57,7 +57,7 @@ import { ChartDetectChangesService } from '../../services/chart-detect-changes.s import { SupportsUnsavedChangeDialog } from '../../../chart-shared/models/dataview-dashboard.model'; import { Observable, of, Subscription } from 'rxjs'; import { MatDialog } from '@angular/material/dialog'; -import { catchError, map } from 'rxjs/operators'; +import { catchError, map, switchMap } from 'rxjs/operators'; import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { ResizeEchartsService } from '../../../chart-shared/services/resize-echarts.service'; import { AssetDialogComponent } from '../../dialog/asset-dialog.component'; @@ -428,27 +428,34 @@ export class ChartViewComponent subtitle: this.translateService.instant( 'Update all changes to chart or discard current changes.', ), + neutralTitle: this.translateService.instant('Keep editing'), + neutralResult: 'stay', cancelTitle: this.translateService.instant('Discard changes'), + cancelResult: false, okTitle: this.translateService.instant('Update'), + okResult: true, confirmAndCancel: true, }, }); return dialogRef.afterClosed().pipe( - map(shouldUpdate => { - if (shouldUpdate) { + switchMap(dialogResult => { + if (dialogResult === true) { this.dataView.timeSettings = this.timeSettings; - const observable = + return ( this.dataView.elementId !== undefined ? this.dataViewService.updateChart( this.dataView, ) - : this.dataViewService.saveChart(this.dataView); - observable.subscribe(() => { - return true; - }); + : this.dataViewService.saveChart(this.dataView) + ).pipe(map(() => true)); } - return true; + + if (dialogResult === false) { + return of(true); + } + + return of(false); }), ); } else { diff --git a/ui/src/app/dashboard/components/panel/dashboard-panel.component.ts b/ui/src/app/dashboard/components/panel/dashboard-panel.component.ts index 812959d7a3..a7f6e49ebf 100644 --- a/ui/src/app/dashboard/components/panel/dashboard-panel.component.ts +++ b/ui/src/app/dashboard/components/panel/dashboard-panel.component.ts @@ -325,24 +325,31 @@ export class DashboardPanelComponent subtitle: this.translateService.instant( 'Update all changes to dashboard charts or discard current changes.', ), + neutralTitle: this.translateService.instant('Keep editing'), + neutralResult: 'stay', cancelTitle: this.translateService.instant('Discard changes'), + cancelResult: false, okTitle: this.translateService.instant('Update'), + okResult: true, confirmAndCancel: true, }, }); return dialogRef.afterClosed().pipe( - map(shouldUpdate => { - if (shouldUpdate) { + switchMap(dialogResult => { + if (dialogResult === true) { this.dashboard.dashboardGeneralSettings.defaultViewMode = this.viewMode; - this.dashboardService + return this.dashboardService .updateDashboard(this.dashboard) - .subscribe(result => { - return true; - }); + .pipe(map(() => true)); } - return true; + + if (dialogResult === false) { + return of(true); + } + + return of(false); }), ); } else {
