mirror of
https://github.com/zitadel/zitadel.git
synced 2025-05-23 11:38:19 +00:00
feat(console): warning if backdrop click or escape key is pressed when new action form is dirty (#5989)
* fix: add action control esc and backdrop click * fix: set values for new action and update action * feat: add translations for supported languages * feat: add some comments * fix: add suggested changes by @peintnermax
This commit is contained in:
parent
e39d1b7d82
commit
33a8ab4ecf
@ -98,6 +98,7 @@ export class ActionTableComponent implements OnInit {
|
|||||||
const dialogRef = this.dialog.open(AddActionDialogComponent, {
|
const dialogRef = this.dialog.open(AddActionDialogComponent, {
|
||||||
data: {},
|
data: {},
|
||||||
width: '500px',
|
width: '500px',
|
||||||
|
disableClose: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe((req: CreateActionRequest) => {
|
dialogRef.afterClosed().subscribe((req: CreateActionRequest) => {
|
||||||
@ -120,6 +121,7 @@ export class ActionTableComponent implements OnInit {
|
|||||||
action: action,
|
action: action,
|
||||||
},
|
},
|
||||||
width: '500px',
|
width: '500px',
|
||||||
|
disableClose: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe((req: UpdateActionRequest) => {
|
dialogRef.afterClosed().subscribe((req: UpdateActionRequest) => {
|
||||||
|
@ -2,14 +2,15 @@
|
|||||||
<span *ngIf="id" class="action-dialog-title" mat-dialog-title>{{ 'FLOWS.DIALOG.UPDATE.TITLE' | translate }}</span>
|
<span *ngIf="id" class="action-dialog-title" mat-dialog-title>{{ 'FLOWS.DIALOG.UPDATE.TITLE' | translate }}</span>
|
||||||
|
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
|
<form [formGroup]="form">
|
||||||
<cnsl-form-field class="form-field">
|
<cnsl-form-field class="form-field">
|
||||||
<cnsl-label>{{ 'FLOWS.NAME' | translate }}</cnsl-label>
|
<cnsl-label>{{ 'FLOWS.NAME' | translate }}</cnsl-label>
|
||||||
<input cnslInput [(ngModel)]="name" />
|
<input cnslInput formControlName="name" />
|
||||||
</cnsl-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<ngx-codemirror
|
<ngx-codemirror
|
||||||
*ngIf="opened$ | async"
|
*ngIf="opened$ | async"
|
||||||
[(ngModel)]="script"
|
formControlName="script"
|
||||||
[options]="{
|
[options]="{
|
||||||
lineNumbers: true,
|
lineNumbers: true,
|
||||||
theme: 'material',
|
theme: 'material',
|
||||||
@ -19,10 +20,11 @@
|
|||||||
|
|
||||||
<cnsl-form-field class="form-field">
|
<cnsl-form-field class="form-field">
|
||||||
<cnsl-label>{{ 'FLOWS.TIMEOUTINSEC' | translate }}</cnsl-label>
|
<cnsl-label>{{ 'FLOWS.TIMEOUTINSEC' | translate }}</cnsl-label>
|
||||||
<input type="number" cnslInput [(ngModel)]="durationInSec" />
|
<input type="number" cnslInput formControlName="durationInSec" />
|
||||||
</cnsl-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<mat-checkbox [(ngModel)]="allowedToFail">{{ 'FLOWS.ALLOWEDTOFAIL' | translate }}</mat-checkbox>
|
<mat-checkbox formControlName="allowedToFail">{{ 'FLOWS.ALLOWEDTOFAIL' | translate }}</mat-checkbox>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div mat-dialog-actions class="action">
|
<div mat-dialog-actions class="action">
|
||||||
<button *ngIf="id" mat-stroked-button color="warn" (click)="deleteAndCloseDialog()">
|
<button *ngIf="id" mat-stroked-button color="warn" (click)="deleteAndCloseDialog()">
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import { Component, Inject } from '@angular/core';
|
import { Component, Inject, OnInit } from '@angular/core';
|
||||||
|
import { FormControl, FormGroup } from '@angular/forms';
|
||||||
import {
|
import {
|
||||||
MatLegacyDialog as MatDialog,
|
MatLegacyDialog as MatDialog,
|
||||||
MatLegacyDialogRef as MatDialogRef,
|
MatLegacyDialogRef as MatDialogRef,
|
||||||
MAT_LEGACY_DIALOG_DATA as MAT_DIALOG_DATA,
|
MAT_LEGACY_DIALOG_DATA as MAT_DIALOG_DATA,
|
||||||
} from '@angular/material/legacy-dialog';
|
} from '@angular/material/legacy-dialog';
|
||||||
|
|
||||||
import { Duration } from 'google-protobuf/google/protobuf/duration_pb';
|
import { Duration } from 'google-protobuf/google/protobuf/duration_pb';
|
||||||
import { mapTo } from 'rxjs';
|
import { mapTo } from 'rxjs';
|
||||||
import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
|
import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
|
||||||
@ -17,35 +19,76 @@ import { ToastService } from 'src/app/services/toast.service';
|
|||||||
templateUrl: './add-action-dialog.component.html',
|
templateUrl: './add-action-dialog.component.html',
|
||||||
styleUrls: ['./add-action-dialog.component.scss'],
|
styleUrls: ['./add-action-dialog.component.scss'],
|
||||||
})
|
})
|
||||||
export class AddActionDialogComponent {
|
export class AddActionDialogComponent implements OnInit {
|
||||||
public name: string = '';
|
|
||||||
public script: string = '';
|
|
||||||
public durationInSec: number = 10;
|
|
||||||
public allowedToFail: boolean = false;
|
|
||||||
|
|
||||||
public id: string = '';
|
public id: string = '';
|
||||||
|
|
||||||
public opened$ = this.dialogRef.afterOpened().pipe(mapTo(true));
|
public opened$ = this.dialogRef.afterOpened().pipe(mapTo(true));
|
||||||
|
public form: FormGroup = new FormGroup({
|
||||||
|
name: new FormControl<string>('', []),
|
||||||
|
script: new FormControl<string>('', []),
|
||||||
|
durationInSec: new FormControl<number>(10, []),
|
||||||
|
allowedToFail: new FormControl<boolean>(false, []),
|
||||||
|
});
|
||||||
constructor(
|
constructor(
|
||||||
private toast: ToastService,
|
private toast: ToastService,
|
||||||
private mgmtService: ManagementService,
|
private mgmtService: ManagementService,
|
||||||
private dialog: MatDialog,
|
private dialog: MatDialog,
|
||||||
|
private unsavedChangesDialog: MatDialog,
|
||||||
public dialogRef: MatDialogRef<AddActionDialogComponent>,
|
public dialogRef: MatDialogRef<AddActionDialogComponent>,
|
||||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
) {
|
) {
|
||||||
if (data && data.action) {
|
if (data && data.action) {
|
||||||
const action: Action.AsObject = data.action;
|
const action: Action.AsObject = data.action;
|
||||||
this.name = action.name;
|
this.form.setValue({
|
||||||
this.script = action.script;
|
name: action.name,
|
||||||
if (action.timeout?.seconds) {
|
script: action.script,
|
||||||
this.durationInSec = action.timeout?.seconds;
|
durationInSec: action.timeout?.seconds ?? 10,
|
||||||
}
|
allowedToFail: action.allowedToFail,
|
||||||
this.allowedToFail = action.allowedToFail;
|
});
|
||||||
this.id = action.id;
|
this.id = action.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
// prevent unsaved changes get lost if backdrop is clicked
|
||||||
|
this.dialogRef.backdropClick().subscribe(() => {
|
||||||
|
if (this.form.dirty) {
|
||||||
|
this.showUnsavedDialog();
|
||||||
|
} else {
|
||||||
|
this.dialogRef.close(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// prevent unsaved changes get lost if escape key is pressed
|
||||||
|
this.dialogRef.keydownEvents().subscribe((event) => {
|
||||||
|
if (event.key === 'Escape') {
|
||||||
|
if (this.form.dirty) {
|
||||||
|
this.showUnsavedDialog();
|
||||||
|
} else {
|
||||||
|
this.dialogRef.close(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private showUnsavedDialog(): void {
|
||||||
|
const unsavedChangesDialogRef = this.unsavedChangesDialog.open(WarnDialogComponent, {
|
||||||
|
data: {
|
||||||
|
confirmKey: 'ACTIONS.UNSAVED.DIALOG.DISCARD',
|
||||||
|
cancelKey: 'ACTIONS.UNSAVED.DIALOG.CANCEL',
|
||||||
|
titleKey: 'ACTIONS.UNSAVEDCHANGES',
|
||||||
|
descriptionKey: 'ACTIONS.UNSAVED.DIALOG.DESCRIPTION',
|
||||||
|
},
|
||||||
|
width: '400px',
|
||||||
|
});
|
||||||
|
|
||||||
|
unsavedChangesDialogRef.afterClosed().subscribe((resp) => {
|
||||||
|
if (resp) {
|
||||||
|
this.dialogRef.close(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public closeDialog(): void {
|
public closeDialog(): void {
|
||||||
this.dialogRef.close(false);
|
this.dialogRef.close(false);
|
||||||
}
|
}
|
||||||
@ -54,27 +97,27 @@ export class AddActionDialogComponent {
|
|||||||
if (this.id) {
|
if (this.id) {
|
||||||
const req = new UpdateActionRequest();
|
const req = new UpdateActionRequest();
|
||||||
req.setId(this.id);
|
req.setId(this.id);
|
||||||
req.setName(this.name);
|
req.setName(this.form.value.name);
|
||||||
req.setScript(this.script);
|
req.setScript(this.form.value.script);
|
||||||
|
|
||||||
const duration = new Duration();
|
const duration = new Duration();
|
||||||
duration.setNanos(0);
|
duration.setNanos(0);
|
||||||
duration.setSeconds(this.durationInSec);
|
duration.setSeconds(this.form.value.durationInSec);
|
||||||
|
|
||||||
req.setAllowedToFail(this.allowedToFail);
|
req.setAllowedToFail(this.form.value.allowedToFail);
|
||||||
|
|
||||||
req.setTimeout(duration);
|
req.setTimeout(duration);
|
||||||
this.dialogRef.close(req);
|
this.dialogRef.close(req);
|
||||||
} else {
|
} else {
|
||||||
const req = new CreateActionRequest();
|
const req = new CreateActionRequest();
|
||||||
req.setName(this.name);
|
req.setName(this.form.value.name);
|
||||||
req.setScript(this.script);
|
req.setScript(this.form.value.script);
|
||||||
|
|
||||||
const duration = new Duration();
|
const duration = new Duration();
|
||||||
duration.setNanos(0);
|
duration.setNanos(0);
|
||||||
duration.setSeconds(this.durationInSec);
|
duration.setSeconds(this.form.value.durationInSec);
|
||||||
|
|
||||||
req.setAllowedToFail(this.allowedToFail);
|
req.setAllowedToFail(this.form.value.allowedToFail);
|
||||||
|
|
||||||
req.setTimeout(duration);
|
req.setTimeout(duration);
|
||||||
this.dialogRef.close(req);
|
this.dialogRef.close(req);
|
||||||
|
@ -166,7 +166,14 @@
|
|||||||
"NEXT": "Weiter",
|
"NEXT": "Weiter",
|
||||||
"MORE": "mehr",
|
"MORE": "mehr",
|
||||||
"STEP": "Schritt",
|
"STEP": "Schritt",
|
||||||
"COMINGSOON": "Coming soon",
|
"UNSAVEDCHANGES": "Nicht gespeicherte Änderungen",
|
||||||
|
"UNSAVED": {
|
||||||
|
"DIALOG": {
|
||||||
|
"DESCRIPTION": "Möchten Sie diese neue Aktion wirklich verwerfen? Ihre Aktion geht verloren",
|
||||||
|
"CANCEL": "Abbrechen",
|
||||||
|
"DISCARD": "Verwerfen"
|
||||||
|
}
|
||||||
|
},
|
||||||
"TABLE": {
|
"TABLE": {
|
||||||
"SHOWUSER": "Zeige Benutzer {{value}}"
|
"SHOWUSER": "Zeige Benutzer {{value}}"
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,14 @@
|
|||||||
"MORE": "more",
|
"MORE": "more",
|
||||||
"STEP": "Step",
|
"STEP": "Step",
|
||||||
"SETUP": "Setup",
|
"SETUP": "Setup",
|
||||||
"COMINGSOON": "Coming soon",
|
"UNSAVEDCHANGES": "Unsaved changes",
|
||||||
|
"UNSAVED": {
|
||||||
|
"DIALOG": {
|
||||||
|
"DESCRIPTION": "Are you sure you want to discard this new action? Your action will be lost",
|
||||||
|
"CANCEL": "Cancel",
|
||||||
|
"DISCARD": "Discard"
|
||||||
|
}
|
||||||
|
},
|
||||||
"TABLE": {
|
"TABLE": {
|
||||||
"SHOWUSER": "Show user {{value}}"
|
"SHOWUSER": "Show user {{value}}"
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,14 @@
|
|||||||
"MORE": "más",
|
"MORE": "más",
|
||||||
"STEP": "Paso",
|
"STEP": "Paso",
|
||||||
"SETUP": "Configurar",
|
"SETUP": "Configurar",
|
||||||
"COMINGSOON": "Próximamente",
|
"UNSAVEDCHANGES": "Cambios no guardados",
|
||||||
|
"UNSAVED": {
|
||||||
|
"DIALOG": {
|
||||||
|
"DESCRIPTION": "¿Estás seguro de que quieres descartar esta nueva acción? Tu acción se perderá",
|
||||||
|
"CANCEL": "Cancelar",
|
||||||
|
"DISCARD": "Descartar"
|
||||||
|
}
|
||||||
|
},
|
||||||
"TABLE": {
|
"TABLE": {
|
||||||
"SHOWUSER": "Mostrar usuario {{value}}"
|
"SHOWUSER": "Mostrar usuario {{value}}"
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,14 @@
|
|||||||
"NEXT": "Suivant",
|
"NEXT": "Suivant",
|
||||||
"MORE": "plus",
|
"MORE": "plus",
|
||||||
"STEP": "Étape",
|
"STEP": "Étape",
|
||||||
"COMINGSOON": "Coming soon",
|
"UNSAVEDCHANGES": "Modifications non enregistrées",
|
||||||
|
"UNSAVED": {
|
||||||
|
"DIALOG": {
|
||||||
|
"DESCRIPTION": "Voulez-vous vraiment annuler cette nouvelle action ? Votre action sera perdue",
|
||||||
|
"CANCEL": "Annuler",
|
||||||
|
"DISCARD": "Jeter"
|
||||||
|
}
|
||||||
|
},
|
||||||
"TABLE": {
|
"TABLE": {
|
||||||
"SHOWUSER": "Afficher l'utilisateur{{value}}"
|
"SHOWUSER": "Afficher l'utilisateur{{value}}"
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,13 @@
|
|||||||
"NEXT": "Avanti",
|
"NEXT": "Avanti",
|
||||||
"MORE": "azioni",
|
"MORE": "azioni",
|
||||||
"STEP": "Passo",
|
"STEP": "Passo",
|
||||||
"COMINGSOON": "Coming soon",
|
"UNSAVED": {
|
||||||
|
"DIALOG": {
|
||||||
|
"DESCRIPTION": "Sei sicuro di voler eliminare questa nuova azione? La tua azione andrà persa",
|
||||||
|
"CANCEL": "Cancella",
|
||||||
|
"DISCARD": "Continua comunque"
|
||||||
|
}
|
||||||
|
},
|
||||||
"TABLE": {
|
"TABLE": {
|
||||||
"SHOWUSER": "Mostra utente {{value}}"
|
"SHOWUSER": "Mostra utente {{value}}"
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,14 @@
|
|||||||
"MORE": "さらに",
|
"MORE": "さらに",
|
||||||
"STEP": "ステップ",
|
"STEP": "ステップ",
|
||||||
"SETUP": "セットアップ",
|
"SETUP": "セットアップ",
|
||||||
"COMINGSOON": "近日公開",
|
"UNSAVEDCHANGES": "未保存の変更",
|
||||||
|
"UNSAVED": {
|
||||||
|
"DIALOG": {
|
||||||
|
"DESCRIPTION": "この新しいアクションを破棄してもよろしいですか?あなたのアクションは失われます",
|
||||||
|
"CANCEL": "キャンセル",
|
||||||
|
"DISCARD": "破棄"
|
||||||
|
}
|
||||||
|
},
|
||||||
"TABLE": {
|
"TABLE": {
|
||||||
"SHOWUSER": "ユーザー {{value}} を表示する"
|
"SHOWUSER": "ユーザー {{value}} を表示する"
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,14 @@
|
|||||||
"NEXT": "Następny",
|
"NEXT": "Następny",
|
||||||
"MORE": "więcej",
|
"MORE": "więcej",
|
||||||
"STEP": "Krok",
|
"STEP": "Krok",
|
||||||
"COMINGSOON": "Coming soon",
|
"UNSAVEDCHANGES": "Niezapisane zmiany",
|
||||||
|
"UNSAVED": {
|
||||||
|
"DIALOG": {
|
||||||
|
"DESCRIPTION": "Czy na pewno chcesz odrzucić to nowe działanie? Twoje działanie zostanie utracone",
|
||||||
|
"CANCEL": "Anuluj",
|
||||||
|
"DISCARD": "Wyrzucać"
|
||||||
|
}
|
||||||
|
},
|
||||||
"TABLE": {
|
"TABLE": {
|
||||||
"SHOWUSER": "Pokaż użytkownika {{value}}"
|
"SHOWUSER": "Pokaż użytkownika {{value}}"
|
||||||
}
|
}
|
||||||
|
@ -165,8 +165,15 @@
|
|||||||
"PREVIOUS": "上一页",
|
"PREVIOUS": "上一页",
|
||||||
"NEXT": "下一页",
|
"NEXT": "下一页",
|
||||||
"MORE": "更多",
|
"MORE": "更多",
|
||||||
"STEP": "Step",
|
"STEP": "步",
|
||||||
"COMINGSOON": "Coming soon",
|
"UNSAVEDCHANGES": "未保存的更改",
|
||||||
|
"UNSAVED": {
|
||||||
|
"DIALOG": {
|
||||||
|
"DESCRIPTION": "您确定要放弃此新操作吗?你的行动将会失败",
|
||||||
|
"CANCEL": "取消",
|
||||||
|
"DISCARD": "丢弃"
|
||||||
|
}
|
||||||
|
},
|
||||||
"TABLE": {
|
"TABLE": {
|
||||||
"SHOWUSER": "Show user {{value}}"
|
"SHOWUSER": "Show user {{value}}"
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user