All files / modal/services modal.service.ts

100% Statements 20/20
100% Branches 20/20
100% Functions 4/4
100% Lines 18/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 852x   2x 2x       2x 18x           13x                               13x         13x             5x                             5x         5x     2x           18x   18x 3x 2x   1x       18x      
import { ModalContainerComponent } from '../components/modal-container.component';
import { LazyComponentLoader, ModalConfig, ModalRef } from '../models/modal.types';
import { Injectable, inject } from '@angular/core';
import { MatDialog, MatDialogConfig } from '@angular/material/dialog';
import { Observable } from 'rxjs';
 
@Injectable({ providedIn: 'root' })
export class ModalService {
    private readonly dialog = inject(MatDialog);
 
    open<TData = unknown, TResult = unknown>(
        loader: LazyComponentLoader<unknown>,
        config: ModalConfig<TData> = {}
    ): Observable<TResult | undefined> {
        const dialogConfig: MatDialogConfig = {
            data: {
                loader,
                data: config.data,
            },
            width: config.width ?? '500px',
            minWidth: config.minWidth,
            maxWidth: config.maxWidth ?? '90vw',
            minHeight: config.minHeight,
            maxHeight: config.maxHeight ?? '90vh',
            disableClose: config.disableClose ?? false,
            panelClass: this.buildPanelClasses(config.panelClass),
            autoFocus: 'first-tabbable',
            restoreFocus: true,
        };
 
        const dialogRef = this.dialog.open<ModalContainerComponent<TData, TResult>, unknown, TResult>(
            ModalContainerComponent,
            dialogConfig
        );
 
        return dialogRef.afterClosed();
    }
 
    openWithRef<TData = unknown, TResult = unknown>(
        loader: LazyComponentLoader<unknown>,
        config: ModalConfig<TData> = {}
    ): { closed: Observable<TResult | undefined>; ref: ModalRef<TResult> } {
        const dialogConfig: MatDialogConfig = {
            data: {
                loader,
                data: config.data,
            },
            width: config.width ?? '500px',
            minWidth: config.minWidth,
            maxWidth: config.maxWidth ?? '90vw',
            maxHeight: '90vh',
            disableClose: config.disableClose ?? false,
            panelClass: this.buildPanelClasses(config.panelClass),
            autoFocus: 'first-tabbable',
            restoreFocus: true,
        };
 
        const dialogRef = this.dialog.open<ModalContainerComponent<TData, TResult>, unknown, TResult>(
            ModalContainerComponent,
            dialogConfig
        );
 
        return {
            closed: dialogRef.afterClosed(),
            ref: {
                close: (result?: TResult) => dialogRef.close(result),
            },
        };
    }
 
    private buildPanelClasses(customClass?: string | string[]): string[] {
        const classes = ['ui-modal-panel'];
 
        if (customClass) {
            if (Array.isArray(customClass)) {
                classes.push(...customClass);
            } else {
                classes.push(customClass);
            }
        }
 
        return classes;
    }
}