From 446920fa9dd3b27b6256cdd1b2f0b876115127fd Mon Sep 17 00:00:00 2001 From: Alex Karpov Date: Fri, 3 Jan 2025 00:06:12 +0200 Subject: [PATCH] NAS-133264 / 25.04 / Add more warnings about unsaved changes (#11268) * NAS-133264: Add more warnings about unsaved changes * NAS-133264: PR Update --- .../cloud-credentials-form.component.spec.ts | 1 + .../cloud-credentials-form.component.ts | 4 ++++ .../ssh-connection-form.component.ts | 8 ++++++-- .../widget-group-form.component.html | 1 + .../widget-group-form/widget-group-form.component.ts | 11 +++++++++-- .../rsync-task-form/rsync-task-form.component.ts | 3 +++ .../console-form/console-form.component.spec.ts | 1 + .../console/console-form/console-form.component.ts | 3 +++ .../advanced/cron/cron-form/cron-form.component.ts | 5 ++++- .../global-two-factor-form.component.ts | 3 +++ .../init-shutdown-form.component.spec.ts | 7 ++++++- .../init-shutdown-form.component.ts | 3 +++ .../replication-settings-form.component.spec.ts | 6 +++++- .../replication-settings-form.component.ts | 4 ++++ .../self-encrypting-drive-form.component.spec.ts | 1 + .../self-encrypting-drive-form.component.ts | 3 +++ .../storage-settings-form.component.spec.ts | 1 + .../storage-settings-form.component.ts | 3 +++ .../tunable-form/tunable-form.component.spec.ts | 2 ++ .../sysctl/tunable-form/tunable-form.component.ts | 5 ++++- .../syslog/syslog-form/syslog-form.component.spec.ts | 1 + .../syslog/syslog-form/syslog-form.component.ts | 3 +++ .../system-security-form.component.spec.ts | 1 + .../system-security-form.component.ts | 4 ++++ .../global-config-form.component.spec.ts | 1 + .../global-config-form.component.ts | 6 +++++- .../instance-edit-form.component.spec.ts | 1 + .../instance-edit-form.component.ts | 5 +++++ 28 files changed, 88 insertions(+), 9 deletions(-) diff --git a/src/app/pages/credentials/backup-credentials/cloud-credentials-form/cloud-credentials-form.component.spec.ts b/src/app/pages/credentials/backup-credentials/cloud-credentials-form/cloud-credentials-form.component.spec.ts index c9cfd49d43d..a3af5efb1c8 100644 --- a/src/app/pages/credentials/backup-credentials/cloud-credentials-form/cloud-credentials-form.component.spec.ts +++ b/src/app/pages/credentials/backup-credentials/cloud-credentials-form/cloud-credentials-form.component.spec.ts @@ -96,6 +96,7 @@ describe('CloudCredentialsFormComponent', () => { const slideInRef = { close: jest.fn(), getData: jest.fn(() => undefined), + requireConfirmationWhen: jest.fn(), }; const createComponent = createComponentFactory({ diff --git a/src/app/pages/credentials/backup-credentials/cloud-credentials-form/cloud-credentials-form.component.ts b/src/app/pages/credentials/backup-credentials/cloud-credentials-form/cloud-credentials-form.component.ts index 565275f8184..28695d8a93a 100644 --- a/src/app/pages/credentials/backup-credentials/cloud-credentials-form/cloud-credentials-form.component.ts +++ b/src/app/pages/credentials/backup-credentials/cloud-credentials-form/cloud-credentials-form.component.ts @@ -101,6 +101,10 @@ export class CloudCredentialsFormComponent implements OnInit { private cloudCredentialService: CloudCredentialService, public slideInRef: SlideInRef, ) { + this.slideInRef.requireConfirmationWhen(() => { + return of(this.commonForm.dirty || this.providerForm.form.dirty); + }); + const data = this.slideInRef.getData(); this.existingCredential = data?.existingCredential; this.limitProviders = data?.providers; diff --git a/src/app/pages/credentials/backup-credentials/ssh-connection-form/ssh-connection-form.component.ts b/src/app/pages/credentials/backup-credentials/ssh-connection-form/ssh-connection-form.component.ts index 66021bd5afe..cdc9fbb5dca 100644 --- a/src/app/pages/credentials/backup-credentials/ssh-connection-form/ssh-connection-form.component.ts +++ b/src/app/pages/credentials/backup-credentials/ssh-connection-form/ssh-connection-form.component.ts @@ -174,10 +174,14 @@ export class SshConnectionFormComponent implements OnInit { private dialogService: DialogService, private snackbar: SnackbarService, public slideInRef: SlideInRef, - ) { } + ) { + this.slideInRef.requireConfirmationWhen(() => { + return of(this.form.dirty); + }); + this.existingConnection = this.slideInRef.getData(); + } ngOnInit(): void { - this.existingConnection = this.slideInRef.getData(); if (this.existingConnection) { this.setConnectionForEdit(); } diff --git a/src/app/pages/dashboard/components/widget-group-form/widget-group-form.component.html b/src/app/pages/dashboard/components/widget-group-form/widget-group-form.component.html index a4e8e39c3a5..103d5a0754b 100644 --- a/src/app/pages/dashboard/components/widget-group-form/widget-group-form.component.html +++ b/src/app/pages/dashboard/components/widget-group-form/widget-group-form.component.html @@ -24,6 +24,7 @@ @if (selectedSlot()) { + = viewChild(forwardRef(() => WidgetGroupSlotFormComponent)); + selectedSlot = signal>({ slotPosition: 0, slotSize: SlotSize.Full, @@ -78,6 +82,9 @@ export class WidgetGroupFormComponent { public slideInRef: SlideInRef, private cdr: ChangeDetectorRef, ) { + this.slideInRef.requireConfirmationWhen(() => { + return of(this.layoutControl.dirty || this.widgetGroupSlotForm()?.form?.dirty); + }); this.setupLayoutUpdates(); this.setInitialFormValues(); } diff --git a/src/app/pages/data-protection/rsync-task/rsync-task-form/rsync-task-form.component.ts b/src/app/pages/data-protection/rsync-task/rsync-task-form/rsync-task-form.component.ts index 4ea1988cd7f..bb159f78751 100644 --- a/src/app/pages/data-protection/rsync-task/rsync-task-form/rsync-task-form.component.ts +++ b/src/app/pages/data-protection/rsync-task/rsync-task-form/rsync-task-form.component.ts @@ -151,6 +151,9 @@ export class RsyncTaskFormComponent implements OnInit { private validatorsService: IxValidatorsService, public slideInRef: SlideInRef, ) { + this.slideInRef.requireConfirmationWhen(() => { + return of(this.form.dirty); + }); this.editingTask = this.slideInRef.getData(); } diff --git a/src/app/pages/system/advanced/console/console-form/console-form.component.spec.ts b/src/app/pages/system/advanced/console/console-form/console-form.component.spec.ts index 25e494a21f0..648292211a4 100644 --- a/src/app/pages/system/advanced/console/console-form/console-form.component.spec.ts +++ b/src/app/pages/system/advanced/console/console-form/console-form.component.spec.ts @@ -61,6 +61,7 @@ describe('ConsoleFormComponent', () => { }), mockProvider(SlideInRef, { close: jest.fn(), + requireConfirmationWhen: jest.fn(), getData: jest.fn(() => ({ consolemenu: true, serialconsole: true, diff --git a/src/app/pages/system/advanced/console/console-form/console-form.component.ts b/src/app/pages/system/advanced/console/console-form/console-form.component.ts index be14634f583..f189bbe1ebd 100644 --- a/src/app/pages/system/advanced/console/console-form/console-form.component.ts +++ b/src/app/pages/system/advanced/console/console-form/console-form.component.ts @@ -95,6 +95,9 @@ export class ConsoleFormComponent implements OnInit { private store$: Store, public slideInRef: SlideInRef, ) { + this.slideInRef.requireConfirmationWhen(() => { + return of(this.form.dirty); + }); this.consoleConfig = this.slideInRef.getData(); } diff --git a/src/app/pages/system/advanced/cron/cron-form/cron-form.component.ts b/src/app/pages/system/advanced/cron/cron-form/cron-form.component.ts index 64b7a5f1fd7..6cbf5a82660 100644 --- a/src/app/pages/system/advanced/cron/cron-form/cron-form.component.ts +++ b/src/app/pages/system/advanced/cron/cron-form/cron-form.component.ts @@ -6,7 +6,7 @@ import { MatButton } from '@angular/material/button'; import { MatCard, MatCardContent } from '@angular/material/card'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService, TranslateModule } from '@ngx-translate/core'; -import { Observable } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { RequiresRolesDirective } from 'app/directives/requires-roles/requires-roles.directive'; import { Role } from 'app/enums/role.enum'; import { helptextCron } from 'app/helptext/system/cron-form'; @@ -101,6 +101,9 @@ export class CronFormComponent implements OnInit { private userService: UserService, public slideInRef: SlideInRef, ) { + this.slideInRef.requireConfirmationWhen(() => { + return of(this.form.dirty); + }); this.editingCron = this.slideInRef.getData(); } diff --git a/src/app/pages/system/advanced/global-two-factor-auth/global-two-factor-form/global-two-factor-form.component.ts b/src/app/pages/system/advanced/global-two-factor-auth/global-two-factor-form/global-two-factor-form.component.ts index 263d640c34e..6d295d50c6a 100644 --- a/src/app/pages/system/advanced/global-two-factor-auth/global-two-factor-form/global-two-factor-form.component.ts +++ b/src/app/pages/system/advanced/global-two-factor-auth/global-two-factor-form/global-two-factor-form.component.ts @@ -76,6 +76,9 @@ export class GlobalTwoFactorAuthFormComponent implements OnInit { public slideInRef: SlideInRef, @Inject(WINDOW) private window: Window, ) { + this.slideInRef.requireConfirmationWhen(() => { + return of(this.form.dirty); + }); this.twoFactorConfig = this.slideInRef.getData(); } diff --git a/src/app/pages/system/advanced/init-shutdown/init-shutdown-form/init-shutdown-form.component.spec.ts b/src/app/pages/system/advanced/init-shutdown/init-shutdown-form/init-shutdown-form.component.spec.ts index 82a75b6a53f..dbc830cf0d5 100644 --- a/src/app/pages/system/advanced/init-shutdown/init-shutdown-form/init-shutdown-form.component.spec.ts +++ b/src/app/pages/system/advanced/init-shutdown/init-shutdown-form/init-shutdown-form.component.spec.ts @@ -47,7 +47,11 @@ describe('InitShutdownFormComponent', () => { }; }), }), - mockProvider(SlideInRef, { close: jest.fn(), getData: jest.fn(() => undefined) }), + mockProvider(SlideInRef, { + close: jest.fn(), + getData: jest.fn(() => undefined), + requireConfirmationWhen: jest.fn(), + }), mockAuth(), ], }); @@ -116,6 +120,7 @@ describe('InitShutdownFormComponent', () => { providers: [ mockProvider(SlideInRef, { close: jest.fn(), + requireConfirmationWhen: jest.fn(), getData: jest.fn(() => ({ id: 13, comment: 'Existing script', diff --git a/src/app/pages/system/advanced/init-shutdown/init-shutdown-form/init-shutdown-form.component.ts b/src/app/pages/system/advanced/init-shutdown/init-shutdown-form/init-shutdown-form.component.ts index 446d2724263..eb1e314c044 100644 --- a/src/app/pages/system/advanced/init-shutdown/init-shutdown-form/init-shutdown-form.component.ts +++ b/src/app/pages/system/advanced/init-shutdown/init-shutdown-form/init-shutdown-form.component.ts @@ -110,6 +110,9 @@ export class InitShutdownFormComponent implements OnInit { private filesystemService: FilesystemService, public slideInRef: SlideInRef, ) { + this.slideInRef.requireConfirmationWhen(() => { + return of(this.form.dirty); + }); this.editingScript = this.slideInRef.getData(); } diff --git a/src/app/pages/system/advanced/replication/replication-settings-form/replication-settings-form.component.spec.ts b/src/app/pages/system/advanced/replication/replication-settings-form/replication-settings-form.component.spec.ts index de9ede2415a..e8616f4917f 100644 --- a/src/app/pages/system/advanced/replication/replication-settings-form/replication-settings-form.component.spec.ts +++ b/src/app/pages/system/advanced/replication/replication-settings-form/replication-settings-form.component.spec.ts @@ -27,7 +27,11 @@ describe('ReplicationSettingsFormComponent', () => { mockApi([ mockCall('replication.config.update'), ]), - mockProvider(SlideInRef, { close: jest.fn(), getData: jest.fn(() => ({ max_parallel_replication_tasks: 1 })) }), + mockProvider(SlideInRef, { + close: jest.fn(), + getData: jest.fn(() => ({ max_parallel_replication_tasks: 1 })), + requireConfirmationWhen: jest.fn(), + }), mockProvider(SlideIn, { open: jest.fn(() => of({ response: true, error: null })), components$: of([]), diff --git a/src/app/pages/system/advanced/replication/replication-settings-form/replication-settings-form.component.ts b/src/app/pages/system/advanced/replication/replication-settings-form/replication-settings-form.component.ts index dfa8a076913..b6eca2f6cd1 100644 --- a/src/app/pages/system/advanced/replication/replication-settings-form/replication-settings-form.component.ts +++ b/src/app/pages/system/advanced/replication/replication-settings-form/replication-settings-form.component.ts @@ -6,6 +6,7 @@ import { MatButton } from '@angular/material/button'; import { MatCard, MatCardContent } from '@angular/material/card'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService, TranslateModule } from '@ngx-translate/core'; +import { of } from 'rxjs'; import { RequiresRolesDirective } from 'app/directives/requires-roles/requires-roles.directive'; import { Role } from 'app/enums/role.enum'; import { helptextSystemAdvanced } from 'app/helptext/system/advanced'; @@ -65,6 +66,9 @@ export class ReplicationSettingsFormComponent implements OnInit { private translate: TranslateService, public slideInRef: SlideInRef, ) { + this.slideInRef.requireConfirmationWhen(() => { + return of(this.form.dirty); + }); this.replicationConfig = this.slideInRef.getData(); } diff --git a/src/app/pages/system/advanced/self-encrypting-drive/self-encrypting-drive-form/self-encrypting-drive-form.component.spec.ts b/src/app/pages/system/advanced/self-encrypting-drive/self-encrypting-drive-form/self-encrypting-drive-form.component.spec.ts index 45bf9e68971..eb6ef7ddf92 100644 --- a/src/app/pages/system/advanced/self-encrypting-drive/self-encrypting-drive-form/self-encrypting-drive-form.component.spec.ts +++ b/src/app/pages/system/advanced/self-encrypting-drive/self-encrypting-drive-form/self-encrypting-drive-form.component.spec.ts @@ -34,6 +34,7 @@ describe('SedFormComponent', () => { mockProvider(SlideInRef, { close: jest.fn(), getData: jest.fn(() => ({ sedPassword: '123', sedUser: SedUser.User })), + requireConfirmationWhen: jest.fn(), }), mockAuth(), ], diff --git a/src/app/pages/system/advanced/self-encrypting-drive/self-encrypting-drive-form/self-encrypting-drive-form.component.ts b/src/app/pages/system/advanced/self-encrypting-drive/self-encrypting-drive-form/self-encrypting-drive-form.component.ts index a0d07976bba..7df2cb05a22 100644 --- a/src/app/pages/system/advanced/self-encrypting-drive/self-encrypting-drive-form/self-encrypting-drive-form.component.ts +++ b/src/app/pages/system/advanced/self-encrypting-drive/self-encrypting-drive-form/self-encrypting-drive-form.component.ts @@ -100,6 +100,9 @@ export class SelfEncryptingDriveFormComponent implements OnInit { private dialogService: DialogService, public slideInRef: SlideInRef, ) { + this.slideInRef.requireConfirmationWhen(() => { + return of(this.form.dirty); + }); this.sedConfig = this.slideInRef.getData(); } diff --git a/src/app/pages/system/advanced/storage/storage-settings-form/storage-settings-form.component.spec.ts b/src/app/pages/system/advanced/storage/storage-settings-form/storage-settings-form.component.spec.ts index f4b870552d8..c9fd2fd8638 100644 --- a/src/app/pages/system/advanced/storage/storage-settings-form/storage-settings-form.component.spec.ts +++ b/src/app/pages/system/advanced/storage/storage-settings-form/storage-settings-form.component.spec.ts @@ -64,6 +64,7 @@ describe('StorageSettingsFormComponent', () => { mockProvider(SlideInRef, { close: jest.fn(), getData: jest.fn(() => ({ swapSize: 5, systemDsPool: 'current-pool' })), + requireConfirmationWhen: jest.fn(), }), mockAuth(), ], diff --git a/src/app/pages/system/advanced/storage/storage-settings-form/storage-settings-form.component.ts b/src/app/pages/system/advanced/storage/storage-settings-form/storage-settings-form.component.ts index 12a22ddfd15..4180cd49e95 100644 --- a/src/app/pages/system/advanced/storage/storage-settings-form/storage-settings-form.component.ts +++ b/src/app/pages/system/advanced/storage/storage-settings-form/storage-settings-form.component.ts @@ -81,6 +81,9 @@ export class StorageSettingsFormComponent implements OnInit { private snackbar: SnackbarService, public slideInRef: SlideInRef, ) { + this.slideInRef.requireConfirmationWhen(() => { + return of(this.form.dirty); + }); this.storageSettings = this.slideInRef.getData(); } diff --git a/src/app/pages/system/advanced/sysctl/tunable-form/tunable-form.component.spec.ts b/src/app/pages/system/advanced/sysctl/tunable-form/tunable-form.component.spec.ts index ca1a091081e..c4dcad8a432 100644 --- a/src/app/pages/system/advanced/sysctl/tunable-form/tunable-form.component.spec.ts +++ b/src/app/pages/system/advanced/sysctl/tunable-form/tunable-form.component.spec.ts @@ -38,6 +38,7 @@ describe('TunableFormComponent', () => { mockProvider(SlideInRef, { close: jest.fn(), getData: jest.fn(() => undefined), + requireConfirmationWhen: jest.fn(), }), mockAuth(), ], @@ -78,6 +79,7 @@ describe('TunableFormComponent', () => { providers: [ mockProvider(SlideInRef, { close: jest.fn(), + requireConfirmationWhen: jest.fn(), getData: jest.fn(() => ({ id: 1, comment: 'Existing variable', diff --git a/src/app/pages/system/advanced/sysctl/tunable-form/tunable-form.component.ts b/src/app/pages/system/advanced/sysctl/tunable-form/tunable-form.component.ts index ca9689e6492..3b4aa0398d3 100644 --- a/src/app/pages/system/advanced/sysctl/tunable-form/tunable-form.component.ts +++ b/src/app/pages/system/advanced/sysctl/tunable-form/tunable-form.component.ts @@ -6,7 +6,7 @@ import { MatButton } from '@angular/material/button'; import { MatCard, MatCardContent } from '@angular/material/card'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService, TranslateModule } from '@ngx-translate/core'; -import { Observable } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { RequiresRolesDirective } from 'app/directives/requires-roles/requires-roles.directive'; import { Role } from 'app/enums/role.enum'; import { TunableType } from 'app/enums/tunable-type.enum'; @@ -83,6 +83,9 @@ export class TunableFormComponent implements OnInit { private translate: TranslateService, public slideInRef: SlideInRef, ) { + this.slideInRef.requireConfirmationWhen(() => { + return of(this.form.dirty); + }); this.editingTunable = this.slideInRef.getData(); } diff --git a/src/app/pages/system/advanced/syslog/syslog-form/syslog-form.component.spec.ts b/src/app/pages/system/advanced/syslog/syslog-form/syslog-form.component.spec.ts index 2c75206b4ab..f2ce62d7b1a 100644 --- a/src/app/pages/system/advanced/syslog/syslog-form/syslog-form.component.spec.ts +++ b/src/app/pages/system/advanced/syslog/syslog-form/syslog-form.component.spec.ts @@ -53,6 +53,7 @@ describe('SyslogFormComponent', () => { provideMockStore(), mockProvider(SlideInRef, { close: jest.fn(), + requireConfirmationWhen: jest.fn(), getData: jest.fn(() => ({ fqdn_syslog: true, sysloglevel: SyslogLevel.Error, diff --git a/src/app/pages/system/advanced/syslog/syslog-form/syslog-form.component.ts b/src/app/pages/system/advanced/syslog/syslog-form/syslog-form.component.ts index 88b74873f21..50c3a783d37 100644 --- a/src/app/pages/system/advanced/syslog/syslog-form/syslog-form.component.ts +++ b/src/app/pages/system/advanced/syslog/syslog-form/syslog-form.component.ts @@ -108,6 +108,9 @@ export class SyslogFormComponent implements OnInit { private formErrorHandler: FormErrorHandlerService, public slideInRef: SlideInRef, ) { + this.slideInRef.requireConfirmationWhen(() => { + return of(this.form.dirty); + }); this.syslogConfig = this.slideInRef.getData(); } diff --git a/src/app/pages/system/advanced/system-security/system-security-form/system-security-form.component.spec.ts b/src/app/pages/system/advanced/system-security/system-security-form/system-security-form.component.spec.ts index 1fa5def5565..e10a2693872 100644 --- a/src/app/pages/system/advanced/system-security/system-security-form/system-security-form.component.spec.ts +++ b/src/app/pages/system/advanced/system-security/system-security-form/system-security-form.component.spec.ts @@ -51,6 +51,7 @@ describe('SystemSecurityFormComponent', () => { mockProvider(SlideInRef, { close: jest.fn(), getData: jest.fn(() => fakeSystemSecurityConfig), + requireConfirmationWhen: jest.fn(), }), mockAuth(), mockProvider(DialogService, { diff --git a/src/app/pages/system/advanced/system-security/system-security-form/system-security-form.component.ts b/src/app/pages/system/advanced/system-security/system-security-form/system-security-form.component.ts index 0231ab882ba..c34542860b6 100644 --- a/src/app/pages/system/advanced/system-security/system-security-form/system-security-form.component.ts +++ b/src/app/pages/system/advanced/system-security/system-security-form/system-security-form.component.ts @@ -7,6 +7,7 @@ import { MatCard, MatCardContent } from '@angular/material/card'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { Store } from '@ngrx/store'; import { TranslateService, TranslateModule } from '@ngx-translate/core'; +import { of } from 'rxjs'; import { RequiresRolesDirective } from 'app/directives/requires-roles/requires-roles.directive'; import { Role } from 'app/enums/role.enum'; import { SystemSecurityConfig } from 'app/interfaces/system-security-config.interface'; @@ -62,6 +63,9 @@ export class SystemSecurityFormComponent implements OnInit { private api: ApiService, private errorHandler: ErrorHandlerService, ) { + this.slideInRef.requireConfirmationWhen(() => { + return of(this.form.dirty); + }); this.systemSecurityConfig = this.slideInRef.getData(); } diff --git a/src/app/pages/virtualization/components/all-instances/all-instances-header/global-config-form/global-config-form.component.spec.ts b/src/app/pages/virtualization/components/all-instances/all-instances-header/global-config-form/global-config-form.component.spec.ts index 39823ffc952..b65fedb8a19 100644 --- a/src/app/pages/virtualization/components/all-instances/all-instances-header/global-config-form/global-config-form.component.spec.ts +++ b/src/app/pages/virtualization/components/all-instances/all-instances-header/global-config-form/global-config-form.component.spec.ts @@ -40,6 +40,7 @@ describe('GlobalConfigFormComponent', () => { }), mockProvider(SlideInRef, { close: jest.fn(), + requireConfirmationWhen: jest.fn(), getData: jest.fn(() => ({ pool: 'poolio', bridge: 'bridge1', diff --git a/src/app/pages/virtualization/components/all-instances/all-instances-header/global-config-form/global-config-form.component.ts b/src/app/pages/virtualization/components/all-instances/all-instances-header/global-config-form/global-config-form.component.ts index e53d4ffb587..5d1860843c4 100644 --- a/src/app/pages/virtualization/components/all-instances/all-instances-header/global-config-form/global-config-form.component.ts +++ b/src/app/pages/virtualization/components/all-instances/all-instances-header/global-config-form/global-config-form.component.ts @@ -4,7 +4,7 @@ import { MatButton } from '@angular/material/button'; import { MatCard, MatCardContent } from '@angular/material/card'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; -import { finalize } from 'rxjs'; +import { finalize, of } from 'rxjs'; import { RequiresRolesDirective } from 'app/directives/requires-roles/requires-roles.directive'; import { Role } from 'app/enums/role.enum'; import { choicesToOptions } from 'app/helpers/operators/options.operators'; @@ -72,6 +72,10 @@ export class GlobalConfigFormComponent { private errorHandler: ErrorHandlerService, public slideInRef: SlideInRef, ) { + this.slideInRef.requireConfirmationWhen(() => { + return of(this.form.dirty); + }); + const currentConfig = this.slideInRef.getData(); this.form.setValue({ diff --git a/src/app/pages/virtualization/components/all-instances/instance-details/instance-general-info/instance-edit-form/instance-edit-form.component.spec.ts b/src/app/pages/virtualization/components/all-instances/instance-details/instance-general-info/instance-edit-form/instance-edit-form.component.spec.ts index 956814999b2..1c2cc69baad 100644 --- a/src/app/pages/virtualization/components/all-instances/instance-details/instance-general-info/instance-edit-form/instance-edit-form.component.spec.ts +++ b/src/app/pages/virtualization/components/all-instances/instance-details/instance-general-info/instance-edit-form/instance-edit-form.component.spec.ts @@ -61,6 +61,7 @@ describe('InstanceEditFormComponent', () => { }), mockProvider(SlideInRef, { getData: () => mockInstance, + requireConfirmationWhen: jest.fn(), close: jest.fn(), }), ], diff --git a/src/app/pages/virtualization/components/all-instances/instance-details/instance-general-info/instance-edit-form/instance-edit-form.component.ts b/src/app/pages/virtualization/components/all-instances/instance-details/instance-general-info/instance-edit-form/instance-edit-form.component.ts index c8ba6820e5f..bc5654a53cc 100644 --- a/src/app/pages/virtualization/components/all-instances/instance-details/instance-general-info/instance-edit-form/instance-edit-form.component.ts +++ b/src/app/pages/virtualization/components/all-instances/instance-details/instance-general-info/instance-edit-form/instance-edit-form.component.ts @@ -8,6 +8,7 @@ import { import { MatButton } from '@angular/material/button'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; +import { of } from 'rxjs'; import { Role } from 'app/enums/role.enum'; import { containersHelptext } from 'app/helptext/virtualization/containers'; import { @@ -74,6 +75,10 @@ export class InstanceEditFormComponent { protected formatter: IxFormatterService, public slideInRef: SlideInRef, ) { + this.slideInRef.requireConfirmationWhen(() => { + return of(this.form.dirty); + }); + this.editingInstance = this.slideInRef.getData(); this.title = this.translate.instant('Edit Instance: {name}', { name: this.editingInstance.name }); this.form.patchValue({