All files / si-map/components/si-map-popover si-map-popover.component.ts

84.61% Statements 22/26
86.36% Branches 19/22
100% Functions 4/4
81.81% Lines 18/22

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 85 86 87 88 89 90 91                                                            61x 23x 23x   23x     23x       23x             23x               7x   7x 1x   6x     7x                       1x     1x 1x         6x 6x 6x      
/**
 * Copyright (c) Siemens 2016 - 2026
 * SPDX-License-Identifier: MIT
 */
import {
  Component,
  ElementRef,
  signal,
  TemplateRef,
  Type,
  viewChild,
  ViewContainerRef
} from '@angular/core';
import Map from 'ol/Map';
 
import { MapPointMetaData } from '../../models/map-point.interface';
import { SiMapPopoverClusterTemplateDirective } from './si-map-popover-cluster-template.directive';
import { SiMapPopoverTemplateDirective } from './si-map-popover-template.directive';
export interface RenderOptions {
  component?: Type<any>;
  mapPoints: MapPointMetaData | MapPointMetaData[];
  map?: Map;
}
 
@Component({
  selector: 'si-map-popover',
  imports: [SiMapPopoverTemplateDirective, SiMapPopoverClusterTemplateDirective],
  templateUrl: './si-map-popover.component.html',
  styleUrl: './si-map-popover.component.scss'
})
export class SiMapPopoverComponent {
  private readonly elementRef = viewChild.required<ElementRef>('popover');
  protected readonly maxHeight = signal<number | null>(null);
 
  protected readonly contentContainer = viewChild.required<ElementRef, ViewContainerRef>(
    'contentContainer',
    {
      read: ViewContainerRef
    }
  );
 
  protected readonly defaultContent = viewChild.required<ElementRef, TemplateRef<any>>(
    'defaultContent',
    {
      read: TemplateRef
    }
  );
 
  protected readonly defaultCluster = viewChild.required<ElementRef, TemplateRef<any>>(
    'defaultCluster',
    {
      read: TemplateRef
    }
  );
 
  public render({ component, mapPoints, map }: RenderOptions): void {
    this.contentContainer().clear();
 
    if (component) {
      this.renderCustomComponent(component, mapPoints);
    } else {
      this.renderDefault(mapPoints);
    }
 
    Iif (map) {
      const mapHeight = map.getTargetElement().getBoundingClientRect().height;
      const contentY = this.elementRef().nativeElement.getBoundingClientRect().top;
      const maxheight = mapHeight - contentY - 20;
      this.maxHeight.set(maxheight);
    }
  }
 
  private renderCustomComponent(
    component: Type<any>,
    mapPoints: MapPointMetaData | MapPointMetaData[]
  ): void {
    const componentRef = this.contentContainer().createComponent(component);
 
    // Assign map point meta data to component instance input
    componentRef.setInput(Array.isArray(mapPoints) ? 'mapPoints' : 'mapPoint', mapPoints);
    componentRef.changeDetectorRef.detectChanges();
  }
 
  private renderDefault(mapPoints: MapPointMetaData | MapPointMetaData[]): void {
    // Create an embedded view with the default content template
    const context = Array.isArray(mapPoints) ? { mapPoints } : { mapPoint: mapPoints };
    const template = Array.isArray(mapPoints) ? this.defaultCluster() : this.defaultContent();
    this.contentContainer().createEmbeddedView(template, context).detectChanges();
  }
}