import { Component, OnInit, Input, OnDestroy, Inject, ChangeDetectorRef, HostBinding } from '@angular/core';
import { Subscription } from 'rxjs';
import { ConstantsService } from 'src/app/shared/constants/constants.service';
import { LabelService } from 'src/app/core/services/label-service/label-service.service';
import { UtilService } from 'src/app/core/services/util-service/util.service';
import { DOCUMENT } from '@angular/common';
import { ResizeContentService } from 'src/app/core/services/resize-service/resize-content.service';
import { IdGeneratorService } from 'src/app/core/services/id-generator.service';
interface ShortCutsData {
mobileMenuOpen: boolean;
jumpToSectionLabel: string;
shortcuts: Shortcut[];
}
interface Shortcut {
title: string;
target: string;
selected: boolean;
}
@Component({
selector: 'div[shortcuts-main]',
templateUrl: './shortcuts-main.component.html',
styleUrls: ['./shortcuts-main.component.scss']
})
export class ShortcutsMainComponent implements OnInit, OnDestroy {
data: ShortCutsData;
private readonly labelKey = 'shortcutsJumpToSection';
private subscriptions: Subscription[] = [];
desktopView: boolean;
previousWidth: number;
private componentId = this.idGenerator.getId();
@Input() entity;
@HostBinding('class') get class() { return 'bg-off-white'; }
constructor(
private label: LabelService,
private util: UtilService,
private constants: ConstantsService,
private changeDetector: ChangeDetectorRef,
private resizer: ResizeContentService,
private idGenerator: IdGeneratorService,
@Inject(DOCUMENT) private document) { }
ngOnInit() {
this.setup();
}
setup() {
if (this.entity) {
this.data = this.parseJson(this.entity);
this.setLabel(this.data);
const width = (window.innerWidth || this.document.documentElement.clientWidth);
this.desktopView = this.inDesktopView(width);
this.previousWidth = (window.innerWidth || this.document.documentElement.clientWidth);
this.resizer.registerCallback(this.componentId, () => this.actOnResize());
}
}
ngOnChanges() {
this.data = this.parseJson(this.entity);
this.setLabel(this.data);
}
actOnResize(): void {
const currentWidth = window.innerWidth || this.document.documentElement.clientWidth;
this.desktopView = this.inDesktopView(currentWidth);
const inMobile = currentWidth <= this.constants.BOOTSTRAP_BREAKPOINTS.MD;
const previousWasTablet = this.previousWidth > this.constants.BOOTSTRAP_BREAKPOINTS.MD;
// Close if it is not in the mobile view or the broswer is transitioning from non-mobile to mobile
if ((!inMobile) || (previousWasTablet && inMobile)) {
this.data.mobileMenuOpen = false;
}
this.previousWidth = currentWidth;
this.changeDetector.detectChanges();
}
ngOnDestroy(): void {
this.resizer.destroyCallback(this.componentId);
}
// called from the template
toggleMobileMenu(): void {
this.data.mobileMenuOpen = !this.data.mobileMenuOpen;
}
// called from the template
scroll(target, index): void {
// Target is the tcm id from tridion, appending component prefix to match what is set by dxa-entity
target = `${this.constants.COMPONENT_ID_PREFIX}-${target}`;
const scrollTarget = document.getElementById(target);
if (scrollTarget) {
this.setSelectedShortcut(index);
scrollTarget.scrollIntoView({behavior: 'smooth'});
if (!this.desktopView) {
this.toggleMobileMenu();
}
}
}
// set the shortcut that was clicked to selected, all others to false
private setSelectedShortcut(index): void {
this.data.shortcuts.forEach( shortcut => shortcut.selected = false);
this.data.shortcuts[index].selected = true;
}
private setLabel(data: ShortCutsData): void {
this.subscriptions.push(this.label.getValue(this.labelKey).subscribe(label => data.jumpToSectionLabel = label));
}
private parseJson(entity): ShortCutsData {
const shortcuts: Shortcut[] = (this.util.extract(entity, 'ShortcutLink') || []).map(e => this.parseShortcut(e));
const parsed: ShortCutsData = {
mobileMenuOpen: false,
jumpToSectionLabel: '',
shortcuts: shortcuts
};
return parsed;
}
private parseShortcut(jsonShortcut): Shortcut {
const title = this.util.extract(jsonShortcut, 'Title');
const target = this.util.extract(jsonShortcut, 'LinkedComponentId');
const parsed = {
title: title,
target: target,
selected: false
};
return parsed;
}
inDesktopView(width: number): boolean {
return width > this.constants.BOOTSTRAP_BREAKPOINTS.MD;
}
}