added PendingChangesGuard for Configurations

This commit is contained in:
Valentin 2022-01-24 13:07:22 +02:00
parent 387f9a166c
commit 9f389d0e99
10 changed files with 75 additions and 52 deletions

View File

@ -2,13 +2,12 @@ import { CanDeactivate } from '@angular/router';
import { Injectable } from '@angular/core';
import { map, Observable } from 'rxjs';
import { ConfirmationDialogService } from '../../../../../libs/common-ui/src/lib/dialog/confirmation-dialog.service';
import { FormGroup } from '@angular/forms';
import { ConfirmOptions } from '../../../../../libs/common-ui/src';
export interface ComponentCanDeactivate {
changed: boolean;
isLeavingPage: boolean;
form: FormGroup;
valid?: boolean;
isLeavingPage?: boolean;
save: () => Promise<void>;
}
@ -20,7 +19,7 @@ export class PendingChangesGuard implements CanDeactivate<ComponentCanDeactivate
if (component.changed) {
component.isLeavingPage = true;
const dialogRef = this._dialogService.openDialog({ disableConfirm: component.form?.invalid });
const dialogRef = this._dialogService.openDialog({ disableConfirm: component.valid === false });
return dialogRef.afterClosed().pipe(
map(result => {
if (result === ConfirmOptions.CONFIRM) {

View File

@ -164,6 +164,7 @@ const routes: Routes = [
path: 'general-config',
component: GeneralConfigScreenComponent,
canActivate: [CompositeRouteGuard],
canDeactivate: [PendingChangesGuard],
data: {
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard],
requiredRoles: ['RED_ADMIN'],

View File

@ -27,5 +27,5 @@
</div>
</form>
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
<iqser-circle-button class="dialog-close" icon="iqser:close" (action)="close()"></iqser-circle-button>
</section>

View File

@ -1,23 +1,27 @@
import { Component, Inject } from '@angular/core';
import { Component, Inject, Injector } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { UserService } from '@services/user.service';
import { ISmtpConfiguration } from '@red/domain';
import { BaseDialogComponent } from '../../../../../../../../libs/common-ui/src';
@Component({
selector: 'redaction-smtp-auth-dialog',
templateUrl: './smtp-auth-dialog.component.html',
styleUrls: ['./smtp-auth-dialog.component.scss'],
})
export class SmtpAuthDialogComponent {
readonly form: FormGroup = this._getForm();
export class SmtpAuthDialogComponent extends BaseDialogComponent {
constructor(
private readonly _formBuilder: FormBuilder,
private readonly _userService: UserService,
public dialogRef: MatDialogRef<SmtpAuthDialogComponent>,
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<SmtpAuthDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: ISmtpConfiguration,
) {}
) {
super(_injector, _dialogRef);
this.form = this._getForm();
this.initialFormValue = this.form.getRawValue();
}
private _getForm(): FormGroup {
return this._formBuilder.group({
@ -27,6 +31,6 @@ export class SmtpAuthDialogComponent {
}
save() {
this.dialogRef.close(this.form.getRawValue());
this._dialogRef.close(this.form.getRawValue());
}
}

View File

@ -2,7 +2,7 @@
<div class="heading-l" translate="general-config-screen.general.title"></div>
<div translate="general-config-screen.general.subtitle"></div>
</div>
<form (submit)="saveGeneralConfig()" [formGroup]="form">
<form (submit)="save()" [formGroup]="form" *ngIf="form">
<div class="dialog-content">
<div class="dialog-content-left">
<div class="iqser-input-group">
@ -23,7 +23,7 @@
</div>
</div>
<div class="dialog-actions">
<button [disabled]="form.invalid || !generalConfigurationChanged" color="primary" mat-flat-button type="submit">
<button [disabled]="form?.invalid || !changed" color="primary" mat-flat-button type="submit">
{{ 'general-config-screen.actions.save' | translate }}
</button>
</div>

View File

@ -1,18 +1,18 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { AutoUnsubscribe, LoadingService } from '@iqser/common-ui';
import { LoadingService } from '@iqser/common-ui';
import { GeneralSettingsService } from '@services/general-settings.service';
import { IGeneralConfiguration } from '@red/domain';
import { ConfigService } from '@services/config.service';
import { FormBuilder, FormGroup } from '@angular/forms';
import { BaseFormComponent } from '../../../../../../../../../libs/common-ui/src/lib/form/base-form.component';
@Component({
selector: 'redaction-general-config-form',
templateUrl: './general-config-form.component.html',
styleUrls: ['./general-config-form.component.scss'],
})
export class GeneralConfigFormComponent extends AutoUnsubscribe implements OnInit, OnDestroy {
export class GeneralConfigFormComponent extends BaseFormComponent implements OnInit, OnDestroy {
private _initialConfiguration: IGeneralConfiguration;
readonly form: FormGroup = this._getForm();
constructor(
private readonly _loadingService: LoadingService,
@ -21,6 +21,7 @@ export class GeneralConfigFormComponent extends AutoUnsubscribe implements OnIni
private readonly _formBuilder: FormBuilder,
) {
super();
this.form = this._getForm();
}
private _getForm(): FormGroup {
@ -34,7 +35,7 @@ export class GeneralConfigFormComponent extends AutoUnsubscribe implements OnIni
await this._loadData();
}
async saveGeneralConfig() {
async save() {
this._loadingService.start();
const configFormValues = this.form.getRawValue();
@ -43,20 +44,8 @@ export class GeneralConfigFormComponent extends AutoUnsubscribe implements OnIni
this._initialConfiguration = await this._generalSettingsService.getGeneralConfigurations().toPromise();
this._configService.updateDisplayName(this._initialConfiguration.displayName);
this._loadingService.stop();
}
get generalConfigurationChanged(): boolean {
if (!this._initialConfiguration) {
return true;
}
for (const key of Object.keys(this.form.getRawValue())) {
if (this._initialConfiguration[key] !== this.form.get(key).value) {
return true;
}
}
return false;
await this._loadData();
}
private async _loadData() {
@ -64,6 +53,7 @@ export class GeneralConfigFormComponent extends AutoUnsubscribe implements OnIni
try {
this._initialConfiguration = await this._generalSettingsService.getGeneralConfigurations().toPromise();
this.form.patchValue(this._initialConfiguration, { emitEvent: false });
this.initialFormValue = this.form.getRawValue();
} catch (e) {}
this._loadingService.stop();

View File

@ -1,13 +1,52 @@
import { Component } from '@angular/core';
import { AfterViewInit, Component, ViewChild } from '@angular/core';
import { UserService } from '@services/user.service';
import { GeneralConfigFormComponent } from './general-config-form/general-config-form.component';
import { SmtpFormComponent } from './smtp-form/smtp-form.component';
import { BaseFormComponent } from '../../../../../../../../libs/common-ui/src/lib/form/base-form.component';
@Component({
selector: 'redaction-general-config-screen',
templateUrl: './general-config-screen.component.html',
styleUrls: ['./general-config-screen.component.scss'],
})
export class GeneralConfigScreenComponent {
export class GeneralConfigScreenComponent extends BaseFormComponent implements AfterViewInit {
readonly currentUser = this._userService.currentUser;
constructor(private readonly _userService: UserService) {}
@ViewChild(GeneralConfigFormComponent) generalConfigFormComponent: GeneralConfigFormComponent;
@ViewChild(SmtpFormComponent) smtpFormComponent: SmtpFormComponent;
children: BaseFormComponent[];
constructor(private readonly _userService: UserService) {
super();
}
ngAfterViewInit() {
this.children = [this.generalConfigFormComponent, this.smtpFormComponent];
}
get changed(): boolean {
for (const child of this.children) {
if (child.changed) {
return true;
}
}
return false;
}
get valid() {
for (const child of this.children) {
if (!child.valid) {
return false;
}
}
return true;
}
async save(): Promise<void> {
for (const child of this.children) {
if (child.changed) {
await child.save();
}
}
}
}

View File

@ -94,7 +94,7 @@
</div>
</div>
<div class="dialog-actions">
<button [disabled]="form.invalid || !smtpConfigurationChanged" color="primary" mat-flat-button type="submit">
<button [disabled]="form.invalid || !changed" color="primary" mat-flat-button type="submit">
{{ 'general-config-screen.actions.save' | translate }}
</button>

View File

@ -1,20 +1,20 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ISmtpConfiguration } from '@red/domain';
import { AutoUnsubscribe, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
import { IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
import { AdminDialogService } from '../../../services/admin-dialog.service';
import { SmtpConfigService } from '../../../services/smtp-config.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { BaseFormComponent } from '../../../../../../../../../libs/common-ui/src/lib/form/base-form.component';
@Component({
selector: 'redaction-smtp-form',
templateUrl: './smtp-form.component.html',
styleUrls: ['./smtp-form.component.scss'],
})
export class SmtpFormComponent extends AutoUnsubscribe implements OnInit, OnDestroy {
export class SmtpFormComponent extends BaseFormComponent implements OnInit, OnDestroy {
readonly iconButtonTypes = IconButtonTypes;
private _initialConfiguration: ISmtpConfiguration;
readonly form: FormGroup = this._getForm();
constructor(
private readonly _formBuilder: FormBuilder,
@ -24,6 +24,7 @@ export class SmtpFormComponent extends AutoUnsubscribe implements OnInit, OnDest
private readonly _toaster: Toaster,
) {
super();
this.form = this._getForm();
this.addSubscription = this.form.controls.auth.valueChanges.subscribe(auth => {
if (auth) {
this.openAuthConfigDialog();
@ -67,20 +68,8 @@ export class SmtpFormComponent extends AutoUnsubscribe implements OnInit, OnDest
await this._smtpConfigService.updateSMTPConfiguration(this.form.getRawValue()).toPromise();
this._initialConfiguration = this.form.getRawValue();
this._loadingService.stop();
}
get smtpConfigurationChanged(): boolean {
if (!this._initialConfiguration) {
return true;
}
for (const key of Object.keys(this.form.getRawValue())) {
if (this._initialConfiguration[key] !== this.form.get(key).value) {
return true;
}
}
return false;
this._loadData();
}
async testConnection() {
@ -101,6 +90,7 @@ export class SmtpFormComponent extends AutoUnsubscribe implements OnInit, OnDest
try {
this._initialConfiguration = await this._smtpConfigService.getCurrentSMTPConfiguration().toPromise();
this.form.patchValue(this._initialConfiguration, { emitEvent: false });
this.initialFormValue = this.form.getRawValue();
} catch (e) {}
this._loadingService.stop();

@ -1 +1 @@
Subproject commit 54d460682a995debb1bde96130e1b3689b0595de
Subproject commit 3d50996b2e1fc374cc4418d47ce7922ca9bb9aed