From d02dadc56af7990af8496636a430b0f15dc52e52 Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Mon, 26 Jun 2023 15:28:04 +0300 Subject: [PATCH] RED-3800: update dialog directive --- src/lib/dialog/index.ts | 2 ++ .../iqser-dialog-component.directive.ts | 31 +++++++++++++++++++ src/lib/utils/functions.ts | 4 +-- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/lib/dialog/index.ts b/src/lib/dialog/index.ts index 274a697..10e7d05 100644 --- a/src/lib/dialog/index.ts +++ b/src/lib/dialog/index.ts @@ -2,3 +2,5 @@ export * from './base-dialog.component'; export * from './confirmation-dialog.service'; export * from './confirmation-dialog/confirmation-dialog.component'; export * from './dialog.service'; +export * from './iqser-dialog-component.directive'; +export * from './iqser-dialog.service'; diff --git a/src/lib/dialog/iqser-dialog-component.directive.ts b/src/lib/dialog/iqser-dialog-component.directive.ts index 7f10939..93e8f62 100644 --- a/src/lib/dialog/iqser-dialog-component.directive.ts +++ b/src/lib/dialog/iqser-dialog-component.directive.ts @@ -1,6 +1,8 @@ import { Directive, HostListener, inject } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; +import { hasFormChanged, IqserEventTarget } from '../utils'; +import { FormGroup } from '@angular/forms'; const DATA_TYPE_SYMBOL = Symbol.for('DATA_TYPE'); const RETURN_TYPE_SYMBOL = Symbol.for('RETURN_TYPE'); @@ -8,6 +10,8 @@ const RETURN_TYPE_SYMBOL = Symbol.for('RETURN_TYPE'); export type DATA_TYPE = typeof DATA_TYPE_SYMBOL; export type RETURN_TYPE = typeof RETURN_TYPE_SYMBOL; +const TARGET_NODE = 'mat-dialog-container'; + @Directive() export abstract class IqserDialogComponent { readonly [DATA_TYPE_SYMBOL]!: DataType; @@ -16,6 +20,8 @@ export abstract class IqserDialogComponent readonly dialogRef = inject(MatDialogRef); readonly data = inject(MAT_DIALOG_DATA); readonly dialog = inject(MatDialog); + readonly form?: FormGroup; + initialFormValue: Record = {}; constructor() { this.dialogRef @@ -25,6 +31,18 @@ export abstract class IqserDialogComponent .subscribe(() => this.close()); } + get valid(): boolean { + return !this.form || this.form.valid; + } + + get changed(): boolean { + return !this.form || hasFormChanged(this.form, this.initialFormValue); + } + + get disabled(): boolean { + return !this.valid || !this.changed; + } + @HostListener('window:keydown.Escape', ['$event']) onEscape(): void { if (this.dialog.openDialogs.length === 1) { @@ -32,6 +50,19 @@ export abstract class IqserDialogComponent } } + @HostListener('window:keydown.Enter', ['$event']) + onEnter(event: KeyboardEvent): void { + event?.stopImmediatePropagation(); + const node = (event.target as IqserEventTarget).localName?.trim()?.toLowerCase(); + if (this.onEnterValidator(event) && node === TARGET_NODE) { + this.close(); + } + } + + onEnterValidator(event: KeyboardEvent) { + return this.valid && !this.disabled && this.changed; + } + close(dialogResult?: ReturnType) { this.dialogRef.close(dialogResult); } diff --git a/src/lib/utils/functions.ts b/src/lib/utils/functions.ts index 425c4ab..21c2afe 100644 --- a/src/lib/utils/functions.ts +++ b/src/lib/utils/functions.ts @@ -5,7 +5,7 @@ import dayjs, { type Dayjs } from 'dayjs'; import { inject } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -export function capitalize(value: string | String): string { +export function capitalize(value: string | string): string { if (!value) { return ''; } @@ -89,7 +89,7 @@ export function trackByFactory, PrimaryKey exte return (_index: number, item: T): Id => item.id; } -export function hasFormChanged(form: UntypedFormGroup, initialFormValue: Record): boolean { +export function hasFormChanged(form: UntypedFormGroup, initialFormValue: Record): boolean { if (!form || !initialFormValue) { return false; }