/*
* © 2017 Stratio Big Data Inc., Sucursal en España.
*
* This software is licensed under the Apache License, Version 2.0.
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the terms of the License for more details.
*
* SPDX-License-Identifier: Apache-2.0.
*/
import {
AfterViewInit,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ElementRef,
EventEmitter,
HostListener,
Input,
Output,
ViewChild
} from '@angular/core';
import { Router } from '@angular/router';
import { StHeaderMenuOption, StHeaderSelection } from './st-header.model';
import { StWindowRefService } from '../utils/window-service';
/**
* @description {Component} [Header]
*
* The header component is a main component of an application.
* This component must be on top and scroll with page, when scroll is in a calculated position,
* the header shrinks and fix to top.
*
* @model
*
* [Header menu options] {./st-header.model.ts#StHeaderMenuOption}
* [Submenu options] {./st-header.model.ts#StHeaderSubMenuOption}
*
* @example
*
* {html}
*
* ```
*
* ```
*/
@Component({
selector: 'st-header',
templateUrl: './st-header.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class StHeaderComponent implements AfterViewInit {
/** @Input {StHeaderMenuOption[]} [menu] Array with menu option to show */
@Input() menu: StHeaderMenuOption[] = [];
/** @Input {boolean} [navigateByDefault] True if we want menu to manage navigation, false if navigation will be managed from the outside */
@Input() navigateByDefault: boolean = true;
/** @Output {StHeaderSelection} [selectMenu] Notify any menu option selection */
@Output() selectMenu: EventEmitter = new EventEmitter();
@ViewChild('headerDivElement', { static: false }) headerDivElement: ElementRef;
@ViewChild('headerFixPart', { static: false }) headerFixPart: ElementRef;
@ViewChild('userMenuContainerElement', { static: true }) userMenuContainer: ElementRef;
public showMenuNames: boolean = true;
private _headerSize: number = 0;
constructor(
private _router: Router,
private _windowServiceRef: StWindowRefService,
private _el: ElementRef,
private _cd: ChangeDetectorRef
) { }
public ngAfterViewInit(): void {
this._headerSize = this.headerFixPart.nativeElement.getBoundingClientRect().width + this.userMenuElementWidth + 20;
setTimeout(() => {
this.checkMenuLabelVisibility();
this._cd.markForCheck();
});
}
@HostListener('window:resize', [])
onResize(): void {
this.checkMenuLabelVisibility();
this._cd.markForCheck();
}
public get id(): string {
return this._el.nativeElement.id || 'st-header';
}
public onSelectMenu(selected: StHeaderSelection): void {
if (this.navigateByDefault) {
if (selected.external) {
this._windowServiceRef.nativeWindow.open(selected.link, selected.openInNewPage ? '_blank' : '_self');
} else {
this._router.navigate([selected.link]);
}
}
this.selectMenu.emit(selected);
}
public get menuContainerId(): string {
return `${this.id}-menu`;
}
public get userMenuElementWidth(): number {
const userMenuContainer: HTMLElement = this.userMenuContainer.nativeElement;
if (userMenuContainer.children && userMenuContainer.children.length > 0) {
return userMenuContainer.children[0].getBoundingClientRect().width;
} else {
return userMenuContainer.getBoundingClientRect().width;
}
}
private checkMenuLabelVisibility(): void {
const windowSize: number = this._windowServiceRef.nativeWindow.innerWidth;
const canShowMenuNames = this._headerSize <= windowSize;
if (this.showMenuNames !== canShowMenuNames) {
this.showMenuNames = canShowMenuNames;
this._cd.markForCheck();
}
}
}