File

src/app/shared/widgets/container/container.component.ts

import {
  AfterContentInit,
  AfterViewChecked,
  ChangeDetectorRef,
  Component,
  ComponentFactoryResolver,
  ComponentRef,
  EventEmitter,
  HostBinding,
  Input,
  NgModule,
  OnChanges,
  OnDestroy,
  OnInit,
  Optional,
  Output,
  SimpleChanges,
  ViewChild,
  ViewContainerRef,
} from "@angular/core";
import { NmWidgetMetadataRegistry } from "../widget.metadata.registry";
import { WidgetRegistry } from "../widget.registry";
import { AppService, WidgetData } from "../configuration/app.service";
import { WidgetConfig } from "../widget.configuration";
import { UtilService } from "../../components/util";
import { CommonModule } from "@angular/common";
import { CoreComponentsModule } from "../../components/core-components.module";
import { WidgetForPipe } from "./widget-for.pipe";
import { MatDrawer, MatSidenavModule } from "@angular/material/sidenav";
import { MatFormFieldModule } from "@angular/material/form-field";
import { MatOptionModule } from "@angular/material/core";
import { MatSelectModule } from "@angular/material/select";
import { AppContext } from "../../components/app-context";
import { Subject } from "rxjs";
import { NmDrawerContainerComponent } from "./drawer-container.component";
import { MatCardModule } from "@angular/material/card";
import { MatIconModule } from "@angular/material/icon";
import { MatButtonModule } from "@angular/material/button";

@Component({
  selector: "nm-container",
  templateUrl: "container.component.html",
  styleUrls: ["container.component.scss"],
  host: { "[id]": "id", "[attr.data-layout]": "layout" },
  // TODO: Check if following line is still valid
  // can't be activated, until PIMWEB-1219 is completed
  //changeDetection: ChangeDetectionStrategy.OnPush
})
export class NmContainerComponent
  implements OnInit, OnChanges, AfterContentInit, AfterViewChecked, OnDestroy {
  @ViewChild("target", { read: ViewContainerRef, static: true })
  viewContainerRef: ViewContainerRef;

  @HostBinding("class") hostClass = null;
  public elementClass = null;

  @Input()
  public configuration: WidgetConfig;

  @Input()
  private parent: string;

  @Input()
  public id: string;

  public layoutContainer: boolean;
  public layout: string;

  private cmpRef: ComponentRef<any>;
  private isViewInitialized: boolean = false;
  private widgetId: string;
  private widgetData: WidgetData;

  private componentChanged = false;

  public dockMode = new Subject();
  public sideMode: boolean = false;

  @ViewChild("drawer", { static: false }) public drawer: MatDrawer;

  @Output("component-initialized")
  public componentInitialized = new EventEmitter<string>();
  selectedMode: any;

  constructor(
    private appContext: AppContext,
    private _resolver: ComponentFactoryResolver,
    private changeDetectorRef: ChangeDetectorRef,
    @Optional() private widgetRegistry: WidgetRegistry,
    @Optional() private appService: AppService
  ) {}

  updateComponent() {
    if (!this.isViewInitialized) {
      return;
    }
    if (this.cmpRef) {
      if (this.appService && this.widgetId) {
        this.appService.destroyComponent(this.widgetId);
      }

      this.cmpRef.destroy();
      this.cmpRef = null;
    }

    if (!this.configuration) {
      return;
    }

    this.layout = this.getOrientation();
    this.layoutContainer = this.isLayoutContainer();

    this.hostClass = UtilService.buildCssClass(
      this.configuration.hostClass,
      this.configuration.hostClassModifiers
    );

    this.elementClass = UtilService.buildCssClass(
      this.configuration.elementClass,
      this.configuration.elementClassModifiers
    );

    if (this.layoutContainer) {
      //Still set that the component changed here so we will fire that the container is initialized later on
      this.componentChanged = true;
      return;
    }

    let { descriptor, widget } = this.createComponent();

    if (this.appService) {
      this.widgetData = this.appService.configure(
        this.id,
        widget,
        descriptor,
        this.configuration
      );

      this.widgetId = this.widgetData.widgetId;
    } else if (this.widgetRegistry) {
      this.widgetRegistry.configureWidget(
        this.parent,
        this.id,
        this.configuration,
        widget,
        descriptor
      );
    }

    this.componentChanged = true;
    this.changeDetectorRef.markForCheck();
  }

  private createComponent() {
    let component = this.configuration.component;
    let descriptor = NmWidgetMetadataRegistry.getWidgetDescriptor(component);

    if (!descriptor) {
      throw new Error('no descriptor found for widget "' + component + '"');
    }

    let componentFactory = this._resolver.resolveComponentFactory(
      descriptor.component
    );

    this.cmpRef = this.viewContainerRef.createComponent(componentFactory, 0);

    if (this.elementClass) {
      this.cmpRef.location.nativeElement.className = this.elementClass;
    }

    let widget = this.cmpRef.instance;

    return { descriptor, widget };
  }

  private isLayoutContainer(): boolean {
    if (!this.configuration) {
      return false;
    }
    return (
      this.configuration.component === "nm-horizontal-layout" ||
      this.configuration.component === "nm-vertical-layout" ||
      this.configuration.component === "nm-drawer-layout"
    );
  }

  ngOnInit() {}

  ngAfterViewChecked() {
    if (this.componentChanged) {
      this.componentChanged = false;

      if (this.widgetData) {
        this.widgetData.initializeChannels();
      }

      if (this.appService) {
        this.appService.componentInitialized(this.id);
      }
      this.componentInitialized.emit(this.id);
    }
  }

  ngOnChanges(changes: SimpleChanges) {
    this.updateComponent();
  }

  ngAfterContentInit() {
    this.isViewInitialized = true;
    this.updateComponent();
  }

  ngOnDestroy() {
    if (this.cmpRef) {
      this.cmpRef.destroy();
    }
  }

  private getOrientation(): string {
    if (this.configuration.component === "nm-horizontal-layout") {
      return "horizontal";
    }
    if (this.configuration.component === "nm-vertical-layout") {
      return "vertical";
    }
    if (this.configuration.component === "nm-drawer-layout") {
      return "drawer";
    }

    return "inherited";
  }

  onModeChange(value) {
    console.log("onModeChange", value);
    this.dockMode.next(value);
  }
}

@NgModule({
  imports: [
    CommonModule,
    CoreComponentsModule,
    MatSidenavModule,
    MatFormFieldModule,
    MatOptionModule,
    MatSelectModule,
    MatCardModule,
    MatIconModule,
    MatButtonModule,
  ],
  declarations: [
    NmContainerComponent,
    WidgetForPipe,
    NmDrawerContainerComponent,
  ],
  exports: [NmContainerComponent, WidgetForPipe, NmDrawerContainerComponent],
})
export class ContainerModule {}

results matching ""

    No results matching ""