All files / src/app/layout/modal modal.component.ts

19.64% Statements 11/56
0% Branches 0/11
5.88% Functions 1/17
25% Lines 8/32

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 7910x 10x 10x 10x   10x 10x 10x               10x                                                                                                                              
import { AfterContentInit, AfterViewInit, Component, ComponentRef, computed, Inject, Injector, OnChanges, OnDestroy, OnInit, SimpleChanges, viewChild, ViewChild, ViewContainerRef } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogContent, MatDialogRef } from '@angular/material/dialog';
import { CommonModule } from '@angular/common';
import { ComponentInputData, ComponentInputDomainData } from '@core/model/component-input-data.interface';
import { BaseChildComponent } from '@core/component/base-child.component';
import { MatButton, MatIconButton } from '@angular/material/button';
import { Subject, takeUntil } from 'rxjs';
import { MatIcon } from '@angular/material/icon';
 
@Component({
  selector: 'app-modal',
  imports: [CommonModule, MatIconButton, MatIcon, MatDialogContent],
  templateUrl: './modal.component.html',
  styleUrl: './modal.component.scss'
})
export class ModalComponent implements AfterViewInit, OnDestroy {
 
  // component loading target
  @ViewChild('component', { read: ViewContainerRef }) container!: ViewContainerRef;
 
  // helps prevent elements display before the component is added
  protected isLoaded = false;
 
  private destroy$: Subject<boolean> = new Subject<boolean>();
  
  constructor(public dialogRef: MatDialogRef<BaseChildComponent>, @Inject(MAT_DIALOG_DATA) public inputData: ComponentInputData, private viewContainerRef: ViewContainerRef) {
  }
  ngOnDestroy(): void {
    this.destroy$.next(true);
  }
 
  ngAfterContentInit(): void {
    this.isLoaded = true;
  }
 
  ngAfterViewInit(): void {
    this.isLoaded = false;
    this.loadComponent();
    this.isLoaded = true;
  }
  
  public succeeded(data: ComponentInputDomainData) :void {
    this.dialogRef.close();
    Iif(this.inputData.succeeded !== null) {
      this.inputData.succeeded(data);
    }
  }
 
  public failed(data: ComponentInputDomainData) :void {
    this.dialogRef.close();
    Iif(this.inputData.failed !== null) {
      this.inputData.failed(data);
    }
  }
 
  public close() :void {
    this.dialogRef.close();
  }
 
  private loadComponent() {
    try {
      this.viewContainerRef.clear(); // cleans up current view
      const componentRef: ComponentRef<BaseChildComponent> = this.container.createComponent(this.inputData.component!);
      
      // assign input
      Iif (this.inputData.data !== undefined) {
        componentRef.instance.data = this.inputData.data;
      }
 
      // handle what would normally be @Output
      componentRef.instance.succeeded.pipe(takeUntil(this.destroy$)).subscribe(this.succeeded.bind(this));
      componentRef.instance.failed.pipe(takeUntil(this.destroy$)).subscribe(this.failed.bind(this));
    }
    catch(e) {
      console.log(e);
    }
  }
}