Skip to content

Commit

Permalink
NAS-133264 / 25.04 / Add more warnings about unsaved changes (#11268)
Browse files Browse the repository at this point in the history
* NAS-133264: Add more warnings about unsaved changes

* NAS-133264: PR Update
  • Loading branch information
AlexKarpov98 authored Jan 2, 2025
1 parent 5a6312a commit 446920f
Show file tree
Hide file tree
Showing 28 changed files with 88 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ describe('CloudCredentialsFormComponent', () => {
const slideInRef = {
close: jest.fn(),
getData: jest.fn(() => undefined),
requireConfirmationWhen: jest.fn(),
};

const createComponent = createComponentFactory({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ export class CloudCredentialsFormComponent implements OnInit {
private cloudCredentialService: CloudCredentialService,
public slideInRef: SlideInRef<CloudCredentialFormInput, CloudSyncCredential | null>,
) {
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,14 @@ export class SshConnectionFormComponent implements OnInit {
private dialogService: DialogService,
private snackbar: SnackbarService,
public slideInRef: SlideInRef<KeychainSshCredentials, KeychainCredential | null>,
) { }
) {
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();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

@if (selectedSlot()) {
<ix-widget-group-slot-form
#widgetGroupSlotForm
[slotConfig]="selectedSlot()"
(validityChange)="updateSlotValidation($event)"
(settingsChange)="updateSlotSettings($event)"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import {
ChangeDetectionStrategy, ChangeDetectorRef, Component, computed, signal,
ChangeDetectionStrategy, ChangeDetectorRef, Component, computed, forwardRef, Signal, signal,
viewChild,
} from '@angular/core';
import {
FormControl, ValidationErrors, Validators, ReactiveFormsModule,
} from '@angular/forms';
import { MatButton } from '@angular/material/button';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { TranslateModule } from '@ngx-translate/core';
import { tap } from 'rxjs';
import { of, tap } from 'rxjs';
import { FormActionsComponent } from 'app/modules/forms/ix-forms/components/form-actions/form-actions.component';
import { IxFieldsetComponent } from 'app/modules/forms/ix-forms/components/ix-fieldset/ix-fieldset.component';
import { IxIconGroupComponent } from 'app/modules/forms/ix-forms/components/ix-icon-group/ix-icon-group.component';
Expand Down Expand Up @@ -52,6 +53,9 @@ export class WidgetGroupFormComponent {
{ layout: WidgetGroupLayout.Full, slots: [{ type: null }] },
);

readonly widgetGroupSlotForm: Signal<WidgetGroupSlotFormComponent>
= viewChild(forwardRef(() => WidgetGroupSlotFormComponent));

selectedSlot = signal<WidgetGroupSlot<object>>({
slotPosition: 0,
slotSize: SlotSize.Full,
Expand All @@ -78,6 +82,9 @@ export class WidgetGroupFormComponent {
public slideInRef: SlideInRef<WidgetGroup | undefined, WidgetGroup | false>,
private cdr: ChangeDetectorRef,
) {
this.slideInRef.requireConfirmationWhen(() => {
return of(this.layoutControl.dirty || this.widgetGroupSlotForm()?.form?.dirty);
});
this.setupLayoutUpdates();
this.setInitialFormValues();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ export class RsyncTaskFormComponent implements OnInit {
private validatorsService: IxValidatorsService,
public slideInRef: SlideInRef<RsyncTask | undefined, RsyncTask | false>,
) {
this.slideInRef.requireConfirmationWhen(() => {
return of(this.form.dirty);
});
this.editingTask = this.slideInRef.getData();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ describe('ConsoleFormComponent', () => {
}),
mockProvider(SlideInRef, {
close: jest.fn(),
requireConfirmationWhen: jest.fn(),
getData: jest.fn(() => ({
consolemenu: true,
serialconsole: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ export class ConsoleFormComponent implements OnInit {
private store$: Store<AppState>,
public slideInRef: SlideInRef<ConsoleConfig, boolean>,
) {
this.slideInRef.requireConfirmationWhen(() => {
return of(this.form.dirty);
});
this.consoleConfig = this.slideInRef.getData();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -101,6 +101,9 @@ export class CronFormComponent implements OnInit {
private userService: UserService,
public slideInRef: SlideInRef<Cronjob | undefined, boolean>,
) {
this.slideInRef.requireConfirmationWhen(() => {
return of(this.form.dirty);
});
this.editingCron = this.slideInRef.getData();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ export class GlobalTwoFactorAuthFormComponent implements OnInit {
public slideInRef: SlideInRef<GlobalTwoFactorConfig, boolean>,
@Inject(WINDOW) private window: Window,
) {
this.slideInRef.requireConfirmationWhen(() => {
return of(this.form.dirty);
});
this.twoFactorConfig = this.slideInRef.getData();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
],
});
Expand Down Expand Up @@ -116,6 +120,7 @@ describe('InitShutdownFormComponent', () => {
providers: [
mockProvider(SlideInRef, {
close: jest.fn(),
requireConfirmationWhen: jest.fn(),
getData: jest.fn(() => ({
id: 13,
comment: 'Existing script',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ export class InitShutdownFormComponent implements OnInit {
private filesystemService: FilesystemService,
public slideInRef: SlideInRef<InitShutdownScript | undefined, boolean>,
) {
this.slideInRef.requireConfirmationWhen(() => {
return of(this.form.dirty);
});
this.editingScript = this.slideInRef.getData();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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([]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -65,6 +66,9 @@ export class ReplicationSettingsFormComponent implements OnInit {
private translate: TranslateService,
public slideInRef: SlideInRef<ReplicationConfig, boolean>,
) {
this.slideInRef.requireConfirmationWhen(() => {
return of(this.form.dirty);
});
this.replicationConfig = this.slideInRef.getData();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ describe('SedFormComponent', () => {
mockProvider(SlideInRef, {
close: jest.fn(),
getData: jest.fn(() => ({ sedPassword: '123', sedUser: SedUser.User })),
requireConfirmationWhen: jest.fn(),
}),
mockAuth(),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ export class SelfEncryptingDriveFormComponent implements OnInit {
private dialogService: DialogService,
public slideInRef: SlideInRef<SedConfig, boolean>,
) {
this.slideInRef.requireConfirmationWhen(() => {
return of(this.form.dirty);
});
this.sedConfig = this.slideInRef.getData();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ describe('StorageSettingsFormComponent', () => {
mockProvider(SlideInRef, {
close: jest.fn(),
getData: jest.fn(() => ({ swapSize: 5, systemDsPool: 'current-pool' })),
requireConfirmationWhen: jest.fn(),
}),
mockAuth(),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ export class StorageSettingsFormComponent implements OnInit {
private snackbar: SnackbarService,
public slideInRef: SlideInRef<StorageSettings, boolean>,
) {
this.slideInRef.requireConfirmationWhen(() => {
return of(this.form.dirty);
});
this.storageSettings = this.slideInRef.getData();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ describe('TunableFormComponent', () => {
mockProvider(SlideInRef, {
close: jest.fn(),
getData: jest.fn(() => undefined),
requireConfirmationWhen: jest.fn(),
}),
mockAuth(),
],
Expand Down Expand Up @@ -78,6 +79,7 @@ describe('TunableFormComponent', () => {
providers: [
mockProvider(SlideInRef, {
close: jest.fn(),
requireConfirmationWhen: jest.fn(),
getData: jest.fn(() => ({
id: 1,
comment: 'Existing variable',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -83,6 +83,9 @@ export class TunableFormComponent implements OnInit {
private translate: TranslateService,
public slideInRef: SlideInRef<Tunable | undefined, boolean>,
) {
this.slideInRef.requireConfirmationWhen(() => {
return of(this.form.dirty);
});
this.editingTunable = this.slideInRef.getData();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ describe('SyslogFormComponent', () => {
provideMockStore(),
mockProvider(SlideInRef, {
close: jest.fn(),
requireConfirmationWhen: jest.fn(),
getData: jest.fn(() => ({
fqdn_syslog: true,
sysloglevel: SyslogLevel.Error,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ export class SyslogFormComponent implements OnInit {
private formErrorHandler: FormErrorHandlerService,
public slideInRef: SlideInRef<SyslogConfig, boolean>,
) {
this.slideInRef.requireConfirmationWhen(() => {
return of(this.form.dirty);
});
this.syslogConfig = this.slideInRef.getData();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ describe('SystemSecurityFormComponent', () => {
mockProvider(SlideInRef, {
close: jest.fn(),
getData: jest.fn(() => fakeSystemSecurityConfig),
requireConfirmationWhen: jest.fn(),
}),
mockAuth(),
mockProvider(DialogService, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ describe('GlobalConfigFormComponent', () => {
}),
mockProvider(SlideInRef, {
close: jest.fn(),
requireConfirmationWhen: jest.fn(),
getData: jest.fn(() => ({
pool: 'poolio',
bridge: 'bridge1',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -72,6 +72,10 @@ export class GlobalConfigFormComponent {
private errorHandler: ErrorHandlerService,
public slideInRef: SlideInRef<VirtualizationGlobalConfig, boolean>,
) {
this.slideInRef.requireConfirmationWhen(() => {
return of(this.form.dirty);
});

const currentConfig = this.slideInRef.getData();

this.form.setValue({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ describe('InstanceEditFormComponent', () => {
}),
mockProvider(SlideInRef, {
getData: () => mockInstance,
requireConfirmationWhen: jest.fn(),
close: jest.fn(),
}),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -74,6 +75,10 @@ export class InstanceEditFormComponent {
protected formatter: IxFormatterService,
public slideInRef: SlideInRef<VirtualizationInstance, VirtualizationInstance | false>,
) {
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({
Expand Down

0 comments on commit 446920f

Please sign in to comment.