src/app/core/ui/dialog-view/dialog-view.component.ts
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)
| changeDetection | ChangeDetectionStrategy.OnPush |
| standalone | true |
| imports |
MatDialogClose
MatDialogTitle
MatDialogContent
MatDialogActions
|
| styleUrls | ./dialog-view.component.scss |
| templateUrl | ./dialog-view.component.html |
No results matching.
CommonModule
DialogCloseComponent
MatDialogClose
DynamicComponentPipe
MatDialogTitle
MatDialogContent
MatDialogActions
AbstractViewComponent
Properties |
constructor()
|
| 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;
}