File

projects/commons/src/lib/elements/dialog/components/dialog.component.ts

import { Observable, Subject } from 'rxjs';
import { animate, keyframes, style, transition, trigger } from '@angular/animations';

import {
    Component, ComponentFactoryResolver, ElementRef, EventEmitter, HostListener, OnInit,
    TemplateRef, ViewChild, ViewContainerRef, ViewEncapsulation
} from '@angular/core';

import { IDialogConfig } from '../interfaces';

interface ComponentType<T> {
    new(...args: any[]): T;
}

@Component({
    selector: 'cmn-dialog',
    templateUrl: './dialog.component.html',
    encapsulation: ViewEncapsulation.None,
    animations: [
        trigger('modalState', [
            transition(
                'void => active',
                animate('200ms', keyframes([
                    style({ opacity: '0', top: '5%', offset: 0 }),
                    style({ opacity: '1', top: '0', offset: 1 })
                ]))
            ),
            transition(
                'active => inactive',
                animate('200ms', keyframes([
                    style({ opacity: '1', offset: 0 }),
                    style({ opacity: '0', top: '5%', offset: 1 })
                ]))
            )
        ])
    ]
})

export class DialogComponent<T> implements OnInit {
    @ViewChild('header') public readonly headerEl: ElementRef;
    @ViewChild('footer') public readonly footerEl: ElementRef;
    @ViewChild('okButton') public readonly okButtonEl: ElementRef;
    @ViewChild('cancelButton') public readonly cancelButtonEl: ElementRef;
    @ViewChild('backdropButton') public readonly backdropButtonEl: ElementRef;
    @ViewChild('componentSection', { read: ViewContainerRef }) public readonly componentSection: ViewContainerRef;


    public open = false;
    public componentInstance: T;
    public hasComponent = false;
    public config: IDialogConfig;
    public ready = new EventEmitter<boolean>();

    private fromOkButton = false;
    private afterClosed$: Subject<any> = new Subject();

    constructor(private readonly componentFactoryResolver: ComponentFactoryResolver) {}

    public ngOnInit() {
        this.open = true;
        this.ready.next(true);
    }

    @HostListener('document:keydown.escape')
    public keypress() {
        this.backdropHandler();
    }

    public backdropHandler() {
        if (this.config.hasBackdrop) {
            this.dismiss(false);
        }
    }

    public cancelHandler() {
        this.actionHandler('cancelHandler');
    }

    public okHandler() {
        this.actionHandler('okHandler', true);
    }

    public dismiss(fromOkButton: boolean) {
        this.open = false;

        this.fromOkButton = fromOkButton;
    }

    public animationDone(event: AnimationEvent) {
        if ((event as any).fromState === 'active' && (event as any).toState === 'inactive') {
            this.afterClosed$.next(this.fromOkButton);
            this.afterClosed$.complete();
        }
    }

    public afterClosed(): Observable<boolean> {
        return this.afterClosed$.asObservable();
    }

    public _setComponent(componentOrTemplateRef: ComponentType<T> | TemplateRef<T>) {
        if (componentOrTemplateRef instanceof TemplateRef) {
            this.componentSection.createEmbeddedView(componentOrTemplateRef);
        } else {
            const factory = this.componentFactoryResolver.resolveComponentFactory(componentOrTemplateRef);
            const componentRef = this.componentSection.createComponent(factory);

            this.componentInstance = componentRef.instance as T;
        }

        this.hasComponent = true;
    }

    private actionHandler(action: 'okHandler' | 'cancelHandler', isDismiss: boolean = false) {
        if (this.config[action]) {
            this.config[action]();
        } else {
            this.dismiss(isDismiss);
        }
    }
}

result-matching ""

    No results matching ""