Skip to content

Commit

Permalink
NAS-125917: Ask user when they try to close the form after making edits
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexKarpov98 committed Oct 10, 2024
1 parent 07149af commit 00066b7
Show file tree
Hide file tree
Showing 93 changed files with 263 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import {
Directive, Input, OnInit,
} from '@angular/core';
import { FormGroup } from '@angular/forms';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { TranslateService } from '@ngx-translate/core';
import { Observable, of } from 'rxjs';
import { filter, switchMap } from 'rxjs/operators';
import { DialogService } from 'app/modules/dialog/dialog.service';
import { IxSlideInRef } from 'app/modules/forms/ix-forms/components/ix-slide-in/ix-slide-in-ref';

@UntilDestroy()
@Directive({
selector: '[formChangeGuardForSlideIn]',
standalone: true,
})
export class FormChangeGuardForSlideInDirective<T> implements OnInit {
@Input() formGroup: FormGroup;

private formChanged = false;

constructor(
private translate: TranslateService,
private dialogService: DialogService,
private slideInRef: IxSlideInRef<T>,
) {}

ngOnInit(): void {
this.trackFormChanges();
this.overrideSlideInClose();
}

private trackFormChanges(): void {
this.formGroup.valueChanges
.pipe(
filter(() => !this.formGroup.pristine),
untilDestroyed(this),
)
.subscribe(() => {
this.formChanged = true;
});
}

private overrideSlideInClose(): void {
this.slideInRef.close = (response?: T) => this.closeWithConfirmation(response)
.pipe(untilDestroyed(this))
.subscribe();
}

private closeWithConfirmation(response?: T): Observable<boolean> {
if (!this.formChanged) {
this.emitClose(response);
return of(true);
}

return this.showConfirmDialog().pipe(
switchMap((shouldClose) => {
if (shouldClose) {
this.formChanged = false;
this.emitClose(response);
}
return of(shouldClose);
}),
);
}

private showConfirmDialog(): Observable<boolean> {
return this.dialogService.confirm({
title: this.translate.instant('Unsaved Changes'),
message: this.translate.instant('You have unsaved changes. Are you sure you want to close?'),
cancelText: this.translate.instant('No'),
buttonText: this.translate.instant('Yes'),
hideCheckbox: true,
});
}

private emitClose(response?: T): void {
this.slideInRef.slideInClosed$.next(response);
this.slideInRef.slideInClosed$.complete();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<ix-modal-header [requiredRoles]="requiredRoles" [title]="title" [loading]="isFormLoading"></ix-modal-header>

<form class="ix-form-container" [formGroup]="form" (submit)="onSubmit()">
<form class="ix-form-container" formChangeGuardForSlideIn [formGroup]="form" (submit)="onSubmit()">
<ix-fieldset [title]="'Identification' | translate">
<div class="columns">
<div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
debounceTime, filter, map, switchMap, take,
} from 'rxjs/operators';
import { allCommands } from 'app/constants/all-commands.constant';
import { FormChangeGuardForSlideInDirective } from 'app/directives/form-change-guard/form-change-guard-for-slide-in.directive';
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 @@ -88,6 +89,7 @@ const defaultHomePath = '/var/empty';
MatButton,
TestDirective,
TranslateModule,
FormChangeGuardForSlideInDirective,
],
})
export class UserFormComponent implements OnInit {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<mat-card>
<mat-card-content>
<form class="ix-form-container" [formGroup]="form" (submit)="onSubmit()">
<form class="ix-form-container" formChangeGuardForSlideIn [formGroup]="form" (submit)="onSubmit()">
<ix-fieldset [title]="'General Options' | translate">
<ix-input
formControlName="destination"
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 { TranslateService, TranslateModule } from '@ngx-translate/core';
import { Observable } from 'rxjs';
import { FormChangeGuardForSlideInDirective } from 'app/directives/form-change-guard/form-change-guard-for-slide-in.directive';
import { RequiresRolesDirective } from 'app/directives/requires-roles/requires-roles.directive';
import { Role } from 'app/enums/role.enum';
import { helptextStaticRoutes } from 'app/helptext/network/static-routes/static-routes';
Expand Down Expand Up @@ -41,6 +42,7 @@ import { WebSocketService } from 'app/services/ws.service';
MatButton,
TestDirective,
TranslateModule,
FormChangeGuardForSlideInDirective,
],
})
export class StaticRouteFormComponent implements OnInit {
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/af.json
Original file line number Diff line number Diff line change
Expand Up @@ -4574,6 +4574,7 @@
"Unlock with Key file": "",
"Unlocked": "",
"Unlocking Datasets": "",
"Unsaved Changes": "",
"Unselect All": "",
"Unset": "",
"Unset <i>Generate Encryption Key</i> to instead import a custom Hex key.": "",
Expand Down Expand Up @@ -4920,6 +4921,7 @@
"You can search both for local groups as well as groups from Active Directory. Press ENTER to separate entries.": "",
"You can search both for local users as well as users from Active Directory.Press ENTER to separate entries.": "",
"You have left the domain.": "",
"You have unsaved changes. Are you sure you want to close?": "",
"You may enter a specific IP address (e.g., 192.168.1.1) for individual access, or use an IP address with a subnet mask (e.g., 192.168.1.0/24) to define a range of addresses.": "",
"Your dashboard is currently empty!": "",
"ZFS": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -4574,6 +4574,7 @@
"Unlock with Key file": "",
"Unlocked": "",
"Unlocking Datasets": "",
"Unsaved Changes": "",
"Unselect All": "",
"Unset": "",
"Unset <i>Generate Encryption Key</i> to instead import a custom Hex key.": "",
Expand Down Expand Up @@ -4920,6 +4921,7 @@
"You can search both for local groups as well as groups from Active Directory. Press ENTER to separate entries.": "",
"You can search both for local users as well as users from Active Directory.Press ENTER to separate entries.": "",
"You have left the domain.": "",
"You have unsaved changes. Are you sure you want to close?": "",
"You may enter a specific IP address (e.g., 192.168.1.1) for individual access, or use an IP address with a subnet mask (e.g., 192.168.1.0/24) to define a range of addresses.": "",
"Your dashboard is currently empty!": "",
"ZFS": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/ast.json
Original file line number Diff line number Diff line change
Expand Up @@ -4574,6 +4574,7 @@
"Unlock with Key file": "",
"Unlocked": "",
"Unlocking Datasets": "",
"Unsaved Changes": "",
"Unselect All": "",
"Unset": "",
"Unset <i>Generate Encryption Key</i> to instead import a custom Hex key.": "",
Expand Down Expand Up @@ -4920,6 +4921,7 @@
"You can search both for local groups as well as groups from Active Directory. Press ENTER to separate entries.": "",
"You can search both for local users as well as users from Active Directory.Press ENTER to separate entries.": "",
"You have left the domain.": "",
"You have unsaved changes. Are you sure you want to close?": "",
"You may enter a specific IP address (e.g., 192.168.1.1) for individual access, or use an IP address with a subnet mask (e.g., 192.168.1.0/24) to define a range of addresses.": "",
"Your dashboard is currently empty!": "",
"ZFS": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/az.json
Original file line number Diff line number Diff line change
Expand Up @@ -4574,6 +4574,7 @@
"Unlock with Key file": "",
"Unlocked": "",
"Unlocking Datasets": "",
"Unsaved Changes": "",
"Unselect All": "",
"Unset": "",
"Unset <i>Generate Encryption Key</i> to instead import a custom Hex key.": "",
Expand Down Expand Up @@ -4920,6 +4921,7 @@
"You can search both for local groups as well as groups from Active Directory. Press ENTER to separate entries.": "",
"You can search both for local users as well as users from Active Directory.Press ENTER to separate entries.": "",
"You have left the domain.": "",
"You have unsaved changes. Are you sure you want to close?": "",
"You may enter a specific IP address (e.g., 192.168.1.1) for individual access, or use an IP address with a subnet mask (e.g., 192.168.1.0/24) to define a range of addresses.": "",
"Your dashboard is currently empty!": "",
"ZFS": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/be.json
Original file line number Diff line number Diff line change
Expand Up @@ -4574,6 +4574,7 @@
"Unlock with Key file": "",
"Unlocked": "",
"Unlocking Datasets": "",
"Unsaved Changes": "",
"Unselect All": "",
"Unset": "",
"Unset <i>Generate Encryption Key</i> to instead import a custom Hex key.": "",
Expand Down Expand Up @@ -4920,6 +4921,7 @@
"You can search both for local groups as well as groups from Active Directory. Press ENTER to separate entries.": "",
"You can search both for local users as well as users from Active Directory.Press ENTER to separate entries.": "",
"You have left the domain.": "",
"You have unsaved changes. Are you sure you want to close?": "",
"You may enter a specific IP address (e.g., 192.168.1.1) for individual access, or use an IP address with a subnet mask (e.g., 192.168.1.0/24) to define a range of addresses.": "",
"Your dashboard is currently empty!": "",
"ZFS": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/bg.json
Original file line number Diff line number Diff line change
Expand Up @@ -4574,6 +4574,7 @@
"Unlock with Key file": "",
"Unlocked": "",
"Unlocking Datasets": "",
"Unsaved Changes": "",
"Unselect All": "",
"Unset": "",
"Unset <i>Generate Encryption Key</i> to instead import a custom Hex key.": "",
Expand Down Expand Up @@ -4920,6 +4921,7 @@
"You can search both for local groups as well as groups from Active Directory. Press ENTER to separate entries.": "",
"You can search both for local users as well as users from Active Directory.Press ENTER to separate entries.": "",
"You have left the domain.": "",
"You have unsaved changes. Are you sure you want to close?": "",
"You may enter a specific IP address (e.g., 192.168.1.1) for individual access, or use an IP address with a subnet mask (e.g., 192.168.1.0/24) to define a range of addresses.": "",
"Your dashboard is currently empty!": "",
"ZFS": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/bn.json
Original file line number Diff line number Diff line change
Expand Up @@ -4574,6 +4574,7 @@
"Unlock with Key file": "",
"Unlocked": "",
"Unlocking Datasets": "",
"Unsaved Changes": "",
"Unselect All": "",
"Unset": "",
"Unset <i>Generate Encryption Key</i> to instead import a custom Hex key.": "",
Expand Down Expand Up @@ -4920,6 +4921,7 @@
"You can search both for local groups as well as groups from Active Directory. Press ENTER to separate entries.": "",
"You can search both for local users as well as users from Active Directory.Press ENTER to separate entries.": "",
"You have left the domain.": "",
"You have unsaved changes. Are you sure you want to close?": "",
"You may enter a specific IP address (e.g., 192.168.1.1) for individual access, or use an IP address with a subnet mask (e.g., 192.168.1.0/24) to define a range of addresses.": "",
"Your dashboard is currently empty!": "",
"ZFS": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/br.json
Original file line number Diff line number Diff line change
Expand Up @@ -4574,6 +4574,7 @@
"Unlock with Key file": "",
"Unlocked": "",
"Unlocking Datasets": "",
"Unsaved Changes": "",
"Unselect All": "",
"Unset": "",
"Unset <i>Generate Encryption Key</i> to instead import a custom Hex key.": "",
Expand Down Expand Up @@ -4920,6 +4921,7 @@
"You can search both for local groups as well as groups from Active Directory. Press ENTER to separate entries.": "",
"You can search both for local users as well as users from Active Directory.Press ENTER to separate entries.": "",
"You have left the domain.": "",
"You have unsaved changes. Are you sure you want to close?": "",
"You may enter a specific IP address (e.g., 192.168.1.1) for individual access, or use an IP address with a subnet mask (e.g., 192.168.1.0/24) to define a range of addresses.": "",
"Your dashboard is currently empty!": "",
"ZFS": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/bs.json
Original file line number Diff line number Diff line change
Expand Up @@ -4574,6 +4574,7 @@
"Unlock with Key file": "",
"Unlocked": "",
"Unlocking Datasets": "",
"Unsaved Changes": "",
"Unselect All": "",
"Unset": "",
"Unset <i>Generate Encryption Key</i> to instead import a custom Hex key.": "",
Expand Down Expand Up @@ -4920,6 +4921,7 @@
"You can search both for local groups as well as groups from Active Directory. Press ENTER to separate entries.": "",
"You can search both for local users as well as users from Active Directory.Press ENTER to separate entries.": "",
"You have left the domain.": "",
"You have unsaved changes. Are you sure you want to close?": "",
"You may enter a specific IP address (e.g., 192.168.1.1) for individual access, or use an IP address with a subnet mask (e.g., 192.168.1.0/24) to define a range of addresses.": "",
"Your dashboard is currently empty!": "",
"ZFS": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/ca.json
Original file line number Diff line number Diff line change
Expand Up @@ -4574,6 +4574,7 @@
"Unlock with Key file": "",
"Unlocked": "",
"Unlocking Datasets": "",
"Unsaved Changes": "",
"Unselect All": "",
"Unset": "",
"Unset <i>Generate Encryption Key</i> to instead import a custom Hex key.": "",
Expand Down Expand Up @@ -4920,6 +4921,7 @@
"You can search both for local groups as well as groups from Active Directory. Press ENTER to separate entries.": "",
"You can search both for local users as well as users from Active Directory.Press ENTER to separate entries.": "",
"You have left the domain.": "",
"You have unsaved changes. Are you sure you want to close?": "",
"You may enter a specific IP address (e.g., 192.168.1.1) for individual access, or use an IP address with a subnet mask (e.g., 192.168.1.0/24) to define a range of addresses.": "",
"Your dashboard is currently empty!": "",
"ZFS": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -3901,6 +3901,7 @@
"Unlock with Key file": "",
"Unlocked": "",
"Unlocking Datasets": "",
"Unsaved Changes": "",
"Unselect All": "",
"Unset": "",
"Unset <i>Generate Encryption Key</i> to instead import a custom Hex key.": "",
Expand Down Expand Up @@ -4043,6 +4044,7 @@
"Who this ACL entry applies to, shown as a user name. Requires adding the user <i>Domain</i>.": "",
"Xen: Extent block size 512b, TPC enabled, Xen compat mode enabled, SSD speed": "",
"You can also vote for new features <a target=\"_blank\" href=\"https://forums.truenas.com/feature-requests\">on our forum.</a>": "",
"You have unsaved changes. Are you sure you want to close?": "",
"ZFS Errors": "",
"iXsystems does not audit or otherwise validate the contents of third-party applications catalogs. It is incumbent on the user to verify that the new catalog is from a trusted source and that the third-party properly audits its chart contents. Failure to exercise due diligence may expose the user and their data to some or all of the following:<br/> <ul>\n <li>Malicious software</li>\n <li>Broken services on TrueNAS host</li>\n <li>Service disruption on TrueNAS host</li>\n <li>Broken filesystem permissions on Host or within application</li>\n <li>Unexpected deletion of user data</li>\n <li>Unsafe service configuration in application</li>\n <li>Degradation of TrueNAS host performance and stability</li>\n </ul>": "",
"{n, plural, one {# CPU} other {# CPUs}}": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/cy.json
Original file line number Diff line number Diff line change
Expand Up @@ -4574,6 +4574,7 @@
"Unlock with Key file": "",
"Unlocked": "",
"Unlocking Datasets": "",
"Unsaved Changes": "",
"Unselect All": "",
"Unset": "",
"Unset <i>Generate Encryption Key</i> to instead import a custom Hex key.": "",
Expand Down Expand Up @@ -4920,6 +4921,7 @@
"You can search both for local groups as well as groups from Active Directory. Press ENTER to separate entries.": "",
"You can search both for local users as well as users from Active Directory.Press ENTER to separate entries.": "",
"You have left the domain.": "",
"You have unsaved changes. Are you sure you want to close?": "",
"You may enter a specific IP address (e.g., 192.168.1.1) for individual access, or use an IP address with a subnet mask (e.g., 192.168.1.0/24) to define a range of addresses.": "",
"Your dashboard is currently empty!": "",
"ZFS": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/da.json
Original file line number Diff line number Diff line change
Expand Up @@ -4574,6 +4574,7 @@
"Unlock with Key file": "",
"Unlocked": "",
"Unlocking Datasets": "",
"Unsaved Changes": "",
"Unselect All": "",
"Unset": "",
"Unset <i>Generate Encryption Key</i> to instead import a custom Hex key.": "",
Expand Down Expand Up @@ -4920,6 +4921,7 @@
"You can search both for local groups as well as groups from Active Directory. Press ENTER to separate entries.": "",
"You can search both for local users as well as users from Active Directory.Press ENTER to separate entries.": "",
"You have left the domain.": "",
"You have unsaved changes. Are you sure you want to close?": "",
"You may enter a specific IP address (e.g., 192.168.1.1) for individual access, or use an IP address with a subnet mask (e.g., 192.168.1.0/24) to define a range of addresses.": "",
"Your dashboard is currently empty!": "",
"ZFS": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -3303,6 +3303,7 @@
"Unlock with Key file": "",
"Unlocked": "",
"Unlocking Datasets": "",
"Unsaved Changes": "",
"Unselect All": "",
"Unset": "",
"Unset <i>Generate Encryption Key</i> to instead import a custom Hex key.": "",
Expand Down Expand Up @@ -3566,6 +3567,7 @@
"You can join the <a href=\"https://www.truenas.com/newsletter/\" target=\"_blank\" class=\"external-link\">TrueNAS Newsletter</a> for monthly updates and latest developments.": "",
"You can search both for local groups as well as groups from Active Directory. Press ENTER to separate entries.": "",
"You can search both for local users as well as users from Active Directory.Press ENTER to separate entries.": "",
"You have unsaved changes. Are you sure you want to close?": "",
"You may enter a specific IP address (e.g., 192.168.1.1) for individual access, or use an IP address with a subnet mask (e.g., 192.168.1.0/24) to define a range of addresses.": "",
"Your dashboard is currently empty!": "",
"ZFS": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/dsb.json
Original file line number Diff line number Diff line change
Expand Up @@ -4574,6 +4574,7 @@
"Unlock with Key file": "",
"Unlocked": "",
"Unlocking Datasets": "",
"Unsaved Changes": "",
"Unselect All": "",
"Unset": "",
"Unset <i>Generate Encryption Key</i> to instead import a custom Hex key.": "",
Expand Down Expand Up @@ -4920,6 +4921,7 @@
"You can search both for local groups as well as groups from Active Directory. Press ENTER to separate entries.": "",
"You can search both for local users as well as users from Active Directory.Press ENTER to separate entries.": "",
"You have left the domain.": "",
"You have unsaved changes. Are you sure you want to close?": "",
"You may enter a specific IP address (e.g., 192.168.1.1) for individual access, or use an IP address with a subnet mask (e.g., 192.168.1.0/24) to define a range of addresses.": "",
"Your dashboard is currently empty!": "",
"ZFS": "",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/el.json
Original file line number Diff line number Diff line change
Expand Up @@ -4574,6 +4574,7 @@
"Unlock with Key file": "",
"Unlocked": "",
"Unlocking Datasets": "",
"Unsaved Changes": "",
"Unselect All": "",
"Unset": "",
"Unset <i>Generate Encryption Key</i> to instead import a custom Hex key.": "",
Expand Down Expand Up @@ -4920,6 +4921,7 @@
"You can search both for local groups as well as groups from Active Directory. Press ENTER to separate entries.": "",
"You can search both for local users as well as users from Active Directory.Press ENTER to separate entries.": "",
"You have left the domain.": "",
"You have unsaved changes. Are you sure you want to close?": "",
"You may enter a specific IP address (e.g., 192.168.1.1) for individual access, or use an IP address with a subnet mask (e.g., 192.168.1.0/24) to define a range of addresses.": "",
"Your dashboard is currently empty!": "",
"ZFS": "",
Expand Down
Loading

0 comments on commit 00066b7

Please sign in to comment.