RED-3800 add dialog components
This commit is contained in:
parent
2fe65233bc
commit
88babfd1f6
44
src/lib/dialog/iqser-dialog-component.directive.ts
Normal file
44
src/lib/dialog/iqser-dialog-component.directive.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { Directive, HostListener, inject } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
const DATA_TYPE_SYMBOL = Symbol.for('DATA_TYPE');
|
||||
const RETURN_TYPE_SYMBOL = Symbol.for('RETURN_TYPE');
|
||||
|
||||
export type DATA_TYPE = typeof DATA_TYPE_SYMBOL;
|
||||
export type RETURN_TYPE = typeof RETURN_TYPE_SYMBOL;
|
||||
|
||||
@Directive()
|
||||
export abstract class IqserDialogComponent<ComponentType, DataType, ReturnType> {
|
||||
readonly [DATA_TYPE_SYMBOL]!: DataType;
|
||||
readonly [RETURN_TYPE_SYMBOL]!: ReturnType;
|
||||
|
||||
readonly dialogRef = inject(MatDialogRef<ComponentType, ReturnType>);
|
||||
readonly data = inject<DataType>(MAT_DIALOG_DATA);
|
||||
readonly dialog = inject(MatDialog);
|
||||
|
||||
constructor() {
|
||||
this.dialogRef
|
||||
.backdropClick()
|
||||
.pipe(takeUntilDestroyed())
|
||||
// eslint-disable-next-line rxjs/no-ignored-subscription
|
||||
.subscribe(() => this.close());
|
||||
}
|
||||
|
||||
@HostListener('window:keydown.Escape', ['$event'])
|
||||
onEscape(): void {
|
||||
if (this.dialog.openDialogs.length === 1) {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
close(dialogResult?: ReturnType) {
|
||||
this.dialogRef.close(dialogResult);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is for testing only
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
class DialogComponentImpl extends IqserDialogComponent<DialogComponentImpl, unknown, unknown> {}
|
||||
44
src/lib/dialog/iqser-dialog.service.ts
Normal file
44
src/lib/dialog/iqser-dialog.service.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { MatDialog, MatDialogConfig, MatDialogRef } from '@angular/material/dialog';
|
||||
import { ComponentType } from '@angular/cdk/portal';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { DATA_TYPE, IqserDialogComponent, RETURN_TYPE } from './iqser-dialog-component.directive';
|
||||
import { defaultDialogConfig, largeDialogConfig } from './dialog.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class IqserDialog {
|
||||
protected readonly _dialog = inject(MatDialog);
|
||||
|
||||
open<
|
||||
Component extends IqserDialogComponent<Component, unknown, unknown>,
|
||||
Data extends Component[DATA_TYPE],
|
||||
Return extends Component[RETURN_TYPE],
|
||||
>(dialog: ComponentType<Component>, config?: MatDialogConfig<Data>) {
|
||||
const ref = this._dialog.open<Component, Data, Return>(dialog, config);
|
||||
return {
|
||||
...ref,
|
||||
result() {
|
||||
console.log('result');
|
||||
return firstValueFrom(ref.afterClosed());
|
||||
},
|
||||
} as MatDialogRef<Component, Return> & { result(): Promise<Return> };
|
||||
}
|
||||
|
||||
openLarge<
|
||||
Component extends IqserDialogComponent<Component, unknown, unknown>,
|
||||
Data extends Component[DATA_TYPE],
|
||||
Return extends Component[RETURN_TYPE],
|
||||
>(dialog: ComponentType<Component>, config?: MatDialogConfig<Data>) {
|
||||
return this.open<Component, Data, Return>(dialog, { ...largeDialogConfig, ...config });
|
||||
}
|
||||
|
||||
openDefault<
|
||||
Component extends IqserDialogComponent<Component, unknown, unknown>,
|
||||
Data extends Component[DATA_TYPE],
|
||||
Return extends Component[RETURN_TYPE],
|
||||
>(dialog: ComponentType<Component>, config?: MatDialogConfig<Data>) {
|
||||
return this.open<Component, Data, Return>(dialog, { ...defaultDialogConfig, ...config });
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user