UNPKG

ngx-eagle

Version:

UI component infrastructure and Design components for mobile and desktop Angular web applications.

94 lines (78 loc) 2.63 kB
import { ComponentRef, TemplateRef } from '@angular/core'; import { from, merge, Observable, of, Subject } from 'rxjs'; import { defaultIfEmpty, filter, first } from 'rxjs/operators'; import { DialogConfig, GlobalDialogConfig, JustProps } from './types'; import { DragOffset } from './draggable.directive'; type GuardFN<R> = ( result?: R ) => Observable<boolean> | Promise<boolean> | boolean; export abstract class DialogRef< Data = any, Result = any, Ref extends ComponentRef<any> | TemplateRef<any> = | ComponentRef<any> | TemplateRef<any> > { ref!: Ref | null; data!: Data; id!: string; backdropClick$!: Observable<MouseEvent>; afterClosed$!: Observable<Result>; abstract close(result?: Result): void; abstract beforeClose(guard: GuardFN<Result>): void; abstract resetDrag(offset?: DragOffset): void; abstract updateConfig(config: Partial<DialogConfig>): void; } type InternalDialogRefProps = Partial< Omit<JustProps<InternalDialogRef>, 'id' | 'data'> & Pick<InternalDialogRef, 'onClose' | 'onReset'> >; export class InternalDialogRef extends DialogRef { config!: DialogConfig & GlobalDialogConfig; override backdropClick$!: Subject<MouseEvent>; beforeCloseGuards: GuardFN<unknown>[] = []; onClose!: (result?: unknown) => void | null; onReset!: (offset?: DragOffset) => void; constructor(props: InternalDialogRefProps = {}) { super(); this.mutate(props); } close(result?: unknown): void { this.canClose(result) .pipe(filter<boolean>(Boolean)) .subscribe({ next: () => this.onClose(result) }); } beforeClose(guard: GuardFN<unknown>) { this.beforeCloseGuards.push(guard); } resetDrag(offset?: DragOffset) { this.onReset(offset); } canClose(result: unknown): Observable<boolean> { const guards$ = this.beforeCloseGuards .map((guard) => guard(result)) .filter((value) => value !== undefined && value !== true) .map((value) => { return typeof value === 'boolean' ? of(value) : from(value).pipe(filter((canClose) => !canClose)); }); return merge(...guards$).pipe(defaultIfEmpty(true), first()); } mutate(props: InternalDialogRefProps) { Object.assign(this, props); this.data = this.config.data; this.id = this.config.id; } updateConfig(config: Partial<DialogConfig & GlobalDialogConfig>) { this.mutate({ config: { ...this.config, ...config, }, }); } asDialogRef(): DialogRef { return this; } }