src/app/core/ui/dialog-view/dialog-view.component.ts

Description

Wrapper component for a modal/dialog view that takes parameters from the dialog data and passes these on to normal @Input properties.

This allows to develop functional feature components in a way to easily reuse them for display as a full page view or in a modal dialog. (also see RoutedViewComponent)

Extends

AbstractViewComponent

Example

Metadata

Relationships

Used by

No results matching.

Depends on

Index

Properties

Constructor

constructor()

Properties

component
Type : string
componentInjector
Type : Injector | undefined
Inherited from AbstractViewComponent
config
Type : any
viewContext
Type : ViewComponentContext
Inherited from AbstractViewComponent
import { CommonModule } from "@angular/common";
import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  DestroyRef,
  inject,
  Injector,
} from "@angular/core";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
import {
  MAT_DIALOG_DATA,
  MatDialogActions,
  MatDialogClose,
  MatDialogContent,
  MatDialogTitle,
} from "@angular/material/dialog";
import { Router } from "@angular/router";
import { DialogCloseComponent } from "../../common-components/dialog-close/dialog-close.component";
import { DynamicComponentPipe } from "../../config/dynamic-components/dynamic-component.pipe";
import { getEntityRuntimeDetailsRoutePath } from "../../entity/entity-config.service";
import { Entity } from "../../entity/model/entity";
import { AbstractViewComponent } from "../abstract-view/abstract-view.component";

/**
 * Wrapper component for a modal/dialog view
 * that takes parameters from the dialog data and passes these on to normal @Input properties.
 *
 * This allows to develop functional feature components in a way to easily reuse them for display
 * as a full page view or in a modal dialog.
 * (also see RoutedViewComponent)
 */
@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [
    CommonModule,
    DialogCloseComponent,
    MatDialogClose,
    DynamicComponentPipe,
    MatDialogTitle,
    MatDialogContent,
    MatDialogActions,
  ],
  templateUrl: "./dialog-view.component.html",
  styleUrls: ["./dialog-view.component.scss"],
})
export class DialogViewComponent<T = any> extends AbstractViewComponent {
  component: string;
  config: any;

  constructor() {
    const dialogData = inject<DialogViewData<T>>(MAT_DIALOG_DATA);
    const injector = inject(Injector);
    const router = inject(Router);
    const cdr = inject(ChangeDetectorRef);
    const destroyRef = inject(DestroyRef);

    super(injector, true);

    this.component = dialogData.component;

    let viewConfig = {};
    if (dialogData.entity) {
      const detailsRoute = getEntityRuntimeDetailsRoutePath(
        dialogData.entity.getConstructor(),
      );
      viewConfig =
        router.config.find((route) => route.path === detailsRoute)?.data
          ?.config ?? {};
    }

    this.config = {
      ...viewConfig,
      ...dialogData.config,
      ...(dialogData.entity ? { entity: dialogData.entity } : {}),
    };

    this.viewContext.changes$
      .pipe(takeUntilDestroyed(destroyRef))
      .subscribe(() => cdr.markForCheck());
  }

  declare componentInjector: Injector | undefined;
}

export interface DialogViewData<T = any> {
  component: string;
  config?: T;

  /**
   * (Optional) if an EntityDetails view, the full entity record to be displayed
   */
  entity?: Entity;
}
<div mat-dialog-title>
  <div class="margin-top-regular">
    <ng-container
      *ngTemplateOutlet="viewContext?.title?.template"
    ></ng-container>
  </div>
  <div style="width: 24px"><!-- spacer for dialog close button--></div>
  <app-dialog-close class="dialog-close" mat-dialog-close></app-dialog-close>
</div>

<div class="dialog-container" mat-dialog-content>
  <ng-container
    *ngComponentOutlet="
      component | dynamicComponent | async;
      inputs: config;
      injector: componentInjector
    "
  ></ng-container>
</div>

<mat-dialog-actions>
  <ng-container
    *ngTemplateOutlet="viewContext?.actions?.template"
  ></ng-container>
</mat-dialog-actions>

./dialog-view.component.scss

@use "variables/sizes";

.dialog-container {
  padding: sizes.$regular;
}

.dialog-close {
  position: absolute;
  top: -(sizes.$small);
  right: 0;
}

.mdc-dialog__title {
  margin-top: sizes.$small;
}
.mdc-dialog__title::before {
  display: none;
}

.mdc-dialog__content {
  /* allow "almost fullscreen" sized dialogs for complex views */
  max-height: initial;
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""