All files / lib/context-header context-header.component.ts

94.11% Statements 128/136
92.85% Branches 13/14
75% Functions 6/8
94.11% Lines 128/136

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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 1371x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 6x 4x 4x 1x 1x 45x 45x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 3x 3x 3x 3x 3x 3x 1x 1x 1x 1x 1x     1x 1x 1x 1x 1x             1x 1x 1x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 1x 3x 3x 4x 4x 1x  
/*******************************************************************************
 * Copyright bei
 * Entwicklungs- und Pflegeverbund für das gemeinsame Fachverfahren gefa
 *
 *******************************************************************************/
import {
  Component,
  ElementRef,
  Input,
  NgZone,
  OnDestroy,
  TemplateRef,
  ViewChild,
} from '@angular/core';
 
import { observeElementSize } from '../utils/internal-utils';
import { BadgeItem, Callback, Item, LinkItem } from '../utils/util.types';
 
import { BadgeItemTemplateContext } from '../badge-list/badge-list.component';
 
/**
 * Context Header is a responsive, context-specific, horizontal user interface element that contains badges and links that lead to other websites or parts of the page.
 */
@Component({
  selector: 'gc-context-header',
  templateUrl: './context-header.component.html',
  styleUrls: ['./context-header.component.css'],
})
export class ContextHeaderComponent implements OnDestroy {
  /**
   * Label to show in the header.
   */
  @Input()
  public label = '';
 
  /**
   * Items that will be rendered as badges in the header.
   */
  @Input()
  public badges: readonly BadgeItem[] = [];
 
  /**
   * Icon template that will be used for the badges.
   */
  @Input()
  public iconProvider?: TemplateRef<BadgeItemTemplateContext>;
 
  /**
   * @ignore
   */
  @ViewChild('linksContainer')
  private linksContainerElement!: ElementRef<HTMLDivElement>;
 
  /**
   * Items that will be rendered as links in the header.
   */
  @Input()
  public set links(value: readonly LinkItem[]) {
    this._links = value;
    this._popItems = this._links.map(item => {
      return { key: item.key, label: item.label + ' öffnen' };
    });
  }
 
  public get links(): readonly LinkItem[] {
    return this._links;
  }
 
  /**
   * @ignore
   */
  public _mode: 'small' | 'medium' | 'default' = 'default';
 
  /** @ignore */
  public _popItems: readonly Item[] = [];
 
  /**
   * @ignore
   */
  private resizeObserver: Callback;
 
  /**
   * @ignore
   */
  private _links: readonly LinkItem[] = [];
 
  constructor(zone: NgZone, el: ElementRef<HTMLElement>) {
    this.resizeObserver = observeElementSize(
      el.nativeElement,
      zone,
      this.handleResize.bind(this),
    );
  }
 
  /**
   * @ignore
   */
  ngOnDestroy(): void {
    this.resizeObserver();
  }
 
  /**
   * @ignore
   */
  public _goToLink(item: Item): void {
    const link = this.links.find(i => i.key === item.key)?.link;

    if (link) {
      window.location.href = link;
    }
  }
 
  /** @ignore */
  private handleResize(entry: ResizeObserverEntry): void {
    // padding 64px
    // gap = 24px
    const elementWidth = entry.contentRect.width - 64 - 24;
 
    const mediumButtonExists = this.links.length > 0;
    // medium button is 148px
    if (elementWidth - (mediumButtonExists ? 148 : 0) < 400) {
      this._mode = 'small';
      return;
    }
 
    const linksContainerWidth =
      this.linksContainerElement.nativeElement.getBoundingClientRect().width;
    const spaceInHeader = elementWidth - linksContainerWidth;
 
    if (spaceInHeader < 720) {
      this._mode = 'medium';
    } else {
      this._mode = 'default';
    }
  }
}