2017-03-29 14:13:40 -07:00
|
|
|
import { Component, ElementRef, HostListener, OnInit,
|
|
|
|
QueryList, ViewChild, ViewChildren } from '@angular/core';
|
|
|
|
import { MdSidenav } from '@angular/material/sidenav';
|
2017-03-13 18:08:23 -07:00
|
|
|
|
2017-03-29 14:13:40 -07:00
|
|
|
import { AutoScrollService } from 'app/shared/auto-scroll.service';
|
|
|
|
import { CurrentNode, NavigationService, NavigationViews, NavigationNode, VersionInfo } from 'app/navigation/navigation.service';
|
2017-03-01 14:30:25 +00:00
|
|
|
import { DocumentService, DocumentContents } from 'app/documents/document.service';
|
2017-03-13 09:20:09 +00:00
|
|
|
import { DocViewerComponent } from 'app/layout/doc-viewer/doc-viewer.component';
|
2017-03-29 14:13:40 -07:00
|
|
|
import { LocationService } from 'app/shared/location.service';
|
|
|
|
import { NavMenuComponent } from 'app/layout/nav-menu/nav-menu.component';
|
2017-03-12 15:20:55 +00:00
|
|
|
import { SearchResultsComponent } from 'app/search/search-results/search-results.component';
|
2017-03-30 09:55:03 +03:00
|
|
|
import { SwUpdateNotificationsService } from 'app/sw-updates/sw-update-notifications.service';
|
|
|
|
|
2017-03-29 14:13:40 -07:00
|
|
|
|
|
|
|
const sideNavView = 'SideNav';
|
2017-02-02 23:02:23 -08:00
|
|
|
|
2017-01-27 00:20:51 -08:00
|
|
|
@Component({
|
2017-02-02 12:10:47 -08:00
|
|
|
selector: 'aio-shell',
|
2017-03-06 15:08:34 +00:00
|
|
|
templateUrl: './app.component.html',
|
2017-01-27 00:20:51 -08:00
|
|
|
})
|
2017-03-01 14:30:25 +00:00
|
|
|
export class AppComponent implements OnInit {
|
2017-03-02 13:28:28 +00:00
|
|
|
|
2017-03-29 14:13:40 -07:00
|
|
|
currentNode: CurrentNode;
|
2017-04-01 09:58:19 +01:00
|
|
|
pageId: string;
|
2017-03-29 14:13:40 -07:00
|
|
|
currentDocument: DocumentContents;
|
|
|
|
footerNodes: NavigationNode[];
|
2017-03-01 14:30:25 +00:00
|
|
|
isSideBySide = false;
|
2017-03-29 14:13:40 -07:00
|
|
|
private isSideNavDoc = false;
|
|
|
|
private previousNavView: string;
|
|
|
|
private readonly sideBySideWidth = 600;
|
|
|
|
sideNavNodes: NavigationNode[];
|
|
|
|
topMenuNodes: NavigationNode[];
|
|
|
|
versionInfo: VersionInfo;
|
2017-03-01 14:30:25 +00:00
|
|
|
|
2017-03-29 14:13:40 -07:00
|
|
|
get homeImageUrl() {
|
|
|
|
return this.isSideBySide ?
|
2017-03-30 12:21:50 -07:00
|
|
|
'assets/images/logos/standard/logo-nav@2x.png' :
|
2017-03-29 14:13:40 -07:00
|
|
|
'assets/images/logos/standard/logo-nav-small.png';
|
|
|
|
}
|
|
|
|
get isOpened() { return this.isSideBySide && this.isSideNavDoc; }
|
|
|
|
get mode() { return this.isSideBySide ? 'side' : 'over'; }
|
|
|
|
|
|
|
|
// Need the doc-viewer element for scrolling the contents
|
|
|
|
@ViewChild(DocViewerComponent, { read: ElementRef })
|
|
|
|
docViewer: ElementRef;
|
2017-03-01 14:30:25 +00:00
|
|
|
|
2017-03-12 15:20:55 +00:00
|
|
|
@ViewChildren('searchBox, searchResults', { read: ElementRef })
|
|
|
|
searchElements: QueryList<ElementRef>;
|
|
|
|
|
|
|
|
@ViewChild(SearchResultsComponent)
|
|
|
|
searchResults: SearchResultsComponent;
|
2017-03-13 18:08:23 -07:00
|
|
|
|
2017-03-29 14:13:40 -07:00
|
|
|
@ViewChild(MdSidenav)
|
|
|
|
sidenav: MdSidenav;
|
2017-03-13 09:20:09 +00:00
|
|
|
|
2017-03-29 14:13:40 -07:00
|
|
|
constructor(
|
|
|
|
private autoScrollService: AutoScrollService,
|
|
|
|
private documentService: DocumentService,
|
|
|
|
private locationService: LocationService,
|
2017-03-30 09:55:03 +03:00
|
|
|
private navigationService: NavigationService,
|
|
|
|
private swUpdateNotifications: SwUpdateNotificationsService
|
2017-03-29 14:13:40 -07:00
|
|
|
) { }
|
2017-02-15 11:22:37 -08:00
|
|
|
|
2017-03-01 14:30:25 +00:00
|
|
|
ngOnInit() {
|
2017-03-29 14:13:40 -07:00
|
|
|
/* No need to unsubscribe because this root component never dies */
|
|
|
|
|
|
|
|
this.documentService.currentDocument.subscribe(doc => this.currentDocument = doc);
|
|
|
|
|
|
|
|
// scroll even if only the hash fragment changed
|
|
|
|
this.locationService.currentUrl.subscribe(url => this.autoScroll());
|
|
|
|
|
|
|
|
this.navigationService.currentNode.subscribe(currentNode => {
|
|
|
|
this.currentNode = currentNode;
|
2017-04-01 09:58:19 +01:00
|
|
|
this.pageId = this.currentNode.url.replace('/', '-') || 'home';
|
2017-03-29 14:13:40 -07:00
|
|
|
|
|
|
|
// Toggle the sidenav if the kind of view changed
|
|
|
|
if (this.previousNavView === currentNode.view) { return; }
|
|
|
|
this.previousNavView = currentNode.view;
|
|
|
|
this.isSideNavDoc = currentNode.view === sideNavView;
|
|
|
|
this.sideNavToggle(this.isSideNavDoc);
|
|
|
|
});
|
|
|
|
|
|
|
|
this.navigationService.navigationViews.subscribe(views => {
|
|
|
|
this.footerNodes = views.Footer || [];
|
|
|
|
this.sideNavNodes = views.SideNav || [];
|
|
|
|
this.topMenuNodes = views.TopBar || [];
|
|
|
|
});
|
|
|
|
|
|
|
|
this.navigationService.versionInfo.subscribe( vi => this.versionInfo = vi );
|
|
|
|
|
2017-03-30 09:55:03 +03:00
|
|
|
this.swUpdateNotifications.enable();
|
|
|
|
|
2017-03-01 14:30:25 +00:00
|
|
|
this.onResize(window.innerWidth);
|
2017-03-29 14:13:40 -07:00
|
|
|
}
|
2017-03-13 09:20:09 +00:00
|
|
|
|
2017-03-29 14:13:40 -07:00
|
|
|
// Scroll to the anchor in the hash fragment.
|
|
|
|
autoScroll() {
|
|
|
|
this.autoScrollService.scroll(this.docViewer.nativeElement.offsetParent);
|
2017-03-13 09:20:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onDocRendered(doc: DocumentContents) {
|
|
|
|
// This handler is needed because the subscription to the `currentUrl` in `ngOnInit`
|
|
|
|
// gets triggered too early before the doc-viewer has finished rendering the doc
|
2017-03-29 14:13:40 -07:00
|
|
|
this.autoScroll();
|
2017-03-01 14:30:25 +00:00
|
|
|
}
|
2017-02-15 11:22:37 -08:00
|
|
|
|
2017-03-12 14:07:49 +00:00
|
|
|
@HostListener('window:resize', ['$event.target.innerWidth'])
|
2017-03-01 14:30:25 +00:00
|
|
|
onResize(width) {
|
|
|
|
this.isSideBySide = width > this.sideBySideWidth;
|
|
|
|
}
|
2017-03-13 21:06:15 +00:00
|
|
|
|
|
|
|
@HostListener('click', ['$event.target', '$event.button', '$event.ctrlKey', '$event.metaKey'])
|
|
|
|
onClick(eventTarget: HTMLElement, button: number, ctrlKey: boolean, metaKey: boolean): boolean {
|
2017-03-12 15:20:55 +00:00
|
|
|
|
|
|
|
// Hide the search results if we clicked outside both the search box and the search results
|
|
|
|
if (this.searchResults) {
|
|
|
|
const hits = this.searchElements.filter(element => element.nativeElement.contains(eventTarget));
|
|
|
|
if (hits.length === 0) {
|
|
|
|
this.searchResults.hideResults();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Deal with anchor clicks
|
2017-03-29 14:13:40 -07:00
|
|
|
if (eventTarget instanceof HTMLImageElement) {
|
|
|
|
eventTarget = eventTarget.parentElement; // assume image wrapped in Anchor
|
|
|
|
}
|
2017-03-13 21:06:15 +00:00
|
|
|
if (eventTarget instanceof HTMLAnchorElement) {
|
|
|
|
return this.locationService.handleAnchorClick(eventTarget, button, ctrlKey, metaKey);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2017-03-29 14:13:40 -07:00
|
|
|
|
|
|
|
sideNavToggle(value?: boolean) {
|
|
|
|
this.sidenav.toggle(value);
|
|
|
|
}
|
2017-04-01 09:58:19 +01:00
|
|
|
|
2017-01-27 00:20:51 -08:00
|
|
|
}
|