The navigation.json is now passed through the dgeni pipeline. The source file has been moved to `aio/content/navigation.json` but the generated file will now appear where the original source file was found, `aio/src/content/navigation.json`. Everything inside `aio/src/content` is now generated and ignored by git. The `processNavigationMap` processor in this commit adds the current version information to the navigation.json file and verifies the relative urls in the file map to real documents. The navigationService exposes the versionInfo as an observable, which the AppComponent renders at the top of the sidenav.
94 lines
3.9 KiB
TypeScript
94 lines
3.9 KiB
TypeScript
import { Component, ElementRef, HostListener, OnInit, QueryList, ViewChild, ViewChildren } from '@angular/core';
|
|
import { Observable } from 'rxjs/Observable';
|
|
|
|
import { GaService } from 'app/shared/ga.service';
|
|
import { LocationService } from 'app/shared/location.service';
|
|
import { DocumentService, DocumentContents } from 'app/documents/document.service';
|
|
import { DocViewerComponent } from 'app/layout/doc-viewer/doc-viewer.component';
|
|
import { NavigationService, NavigationViews, NavigationNode, VersionInfo } from 'app/navigation/navigation.service';
|
|
import { SearchService } from 'app/search/search.service';
|
|
import { SearchResultsComponent } from 'app/search/search-results/search-results.component';
|
|
import { AutoScrollService } from 'app/shared/auto-scroll.service';
|
|
|
|
@Component({
|
|
selector: 'aio-shell',
|
|
templateUrl: './app.component.html',
|
|
})
|
|
export class AppComponent implements OnInit {
|
|
readonly sideBySideWidth = 600;
|
|
readonly homeImageUrl = 'assets/images/logos/standard/logo-nav.png';
|
|
|
|
isHamburgerVisible = true; // always ... for now
|
|
isSideBySide = false;
|
|
|
|
currentDocument: Observable<DocumentContents>;
|
|
navigationViews: Observable<NavigationViews>;
|
|
selectedNodes: Observable<NavigationNode[]>;
|
|
versionInfo: Observable<VersionInfo>;
|
|
|
|
@ViewChildren('searchBox, searchResults', { read: ElementRef })
|
|
searchElements: QueryList<ElementRef>;
|
|
|
|
@ViewChild(SearchResultsComponent)
|
|
searchResults: SearchResultsComponent;
|
|
|
|
// We need the doc-viewer element for scrolling the contents
|
|
@ViewChild(DocViewerComponent, { read: ElementRef })
|
|
docViewer: ElementRef;
|
|
|
|
constructor(documentService: DocumentService,
|
|
gaService: GaService,
|
|
navigationService: NavigationService,
|
|
private autoScroll: AutoScrollService,
|
|
private locationService: LocationService,
|
|
private searchService: SearchService) {
|
|
this.currentDocument = documentService.currentDocument;
|
|
locationService.currentUrl.subscribe(url => gaService.locationChanged(url));
|
|
this.navigationViews = navigationService.navigationViews;
|
|
this.selectedNodes = navigationService.selectedNodes;
|
|
this.versionInfo = navigationService.versionInfo;
|
|
}
|
|
|
|
ngOnInit() {
|
|
this.searchService.initWorker('app/search/search-worker.js');
|
|
this.searchService.loadIndex();
|
|
|
|
this.onResize(window.innerWidth);
|
|
|
|
// The url changed, so scroll to the anchor in the hash fragment.
|
|
// This subscription is needed when navigating between anchors within a document
|
|
// and the document itself has not changed
|
|
this.locationService.currentUrl.subscribe(url => this.autoScroll.scroll(this.docViewer.nativeElement.offsetParent));
|
|
}
|
|
|
|
onDocRendered(doc: DocumentContents) {
|
|
// A new document has been rendered, so scroll to the anchor in the hash fragment.
|
|
// 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
|
|
this.autoScroll.scroll(this.docViewer.nativeElement.offsetParent);
|
|
}
|
|
|
|
@HostListener('window:resize', ['$event.target.innerWidth'])
|
|
onResize(width) {
|
|
this.isSideBySide = width > this.sideBySideWidth;
|
|
}
|
|
|
|
@HostListener('click', ['$event.target', '$event.button', '$event.ctrlKey', '$event.metaKey'])
|
|
onClick(eventTarget: HTMLElement, button: number, ctrlKey: boolean, metaKey: boolean): boolean {
|
|
|
|
// 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
|
|
if (eventTarget instanceof HTMLAnchorElement) {
|
|
return this.locationService.handleAnchorClick(eventTarget, button, ctrlKey, metaKey);
|
|
}
|
|
return true;
|
|
}
|
|
}
|