Page MenuHomec4science

navigation-service.service.ts
No OneTemporary

File Metadata

Created
Fri, Mar 29, 03:12

navigation-service.service.ts

import {EventEmitter, Injectable, OnDestroy} from '@angular/core';
import {
TlnManuscript, NavigationEntity, TlnPage, TlnEntity, TlnQueryParams, NavTreeIndex, NavTree,
SubTreeSelectionDef, SubTreeDef, NavTreeDef
} from '../models/models';
import {NietzscheSourceSeviceService} from "./nietzsche-source-sevice.service";
import {Subscription} from "rxjs/index";
import {ActivatedRoute, Params, Router, ChildActivationEnd} from '@angular/router';
import {QueryService} from "./query.service";
import {DomSanitizer} from '@angular/platform-browser';
import {NavigationDefinition} from '../../assets/content_definitions';
@Injectable()
export class NavigationServiceService {
navDefinitions = new NavigationDefinition();
queryParams: TlnQueryParams;
// Listening to the queries entered actively (so also if page is refreshed or a url loaded)
queryParamSubscription: Subscription;
viewTabSubscription: Subscription;
activeViewTab = '';
navTreeIndex: NavTreeDef[];
// the different manuscript navigation trees: Manuscripte archivalischer Ordnung, konzeptioneller Ordnung, ...
// Only set onInit once per default, once from url from reload or on change triggred by navlist component for routing accordingly
subTreeDefs: SubTreeDef[]; // the manuscriptNavTrees available for selection
selectedSubTree: SubTreeDef; // Definition of the active tree
manuscriptNavTrees: NavTree[]; // the trees inteslf with data;
// The active === actually displayed tree data; can equal either this.activeManuscriptNavTreeDat or this.activePageNavTreeData
activeTreeData: Array<NavigationEntity>;
activeTreeDataChange = new EventEmitter<NavigationEntity[]>(); // if the active tree data changes
// The actual selected things
selectedManuscriptChange = new EventEmitter<TlnManuscript>();
selectedPageChange = new EventEmitter<TlnPage>();
resourceOfInterest: string; // simple iri for Databrowser and rdf stuff to come
resourceOfInterestChange = new EventEmitter<string>();
// TODO: Change to new ManTreeModel with this.manuscriptNavTrees[selectedSubTree.id].entries
activeManuscriptNavTreeData: Array<NavigationEntity> = [];// ==> will be set to this.manuscriptNavTrees[selectedSubTree.id].entries
activeManuscriptNavTreeChange = new EventEmitter<Array<NavigationEntity>>(); // internally used
activePageNavTreeData: Array<NavigationEntity> = [];
activePageNavTreeChange = new EventEmitter<Array<NavigationEntity>>(); // internally used
selectedManuscript: TlnManuscript;
selectedPage: TlnPage;
constructor(private nietzscheSourceService: NietzscheSourceSeviceService,
private router: Router,
private sanitizer: DomSanitizer,
private activatedRoute: ActivatedRoute,
private queryService: QueryService ) {
this.queryParams = new TlnQueryParams('', '', '', '', '', false, 0, 0);
// Listening to the queries entered actively (so also if page is refreshed or a url loaded)
this.queryParamSubscription = this.activatedRoute.queryParams.subscribe( (queryparams: Params ) => {
// set new query params
this.queryParams = new TlnQueryParams(queryparams.man,
queryparams.page,
queryparams.row,
queryparams.word,
queryparams.viewMode,
queryparams.navBarOpenState,
queryparams.navTreeIndex,
queryparams.manuscriptGroup);
// console.log('this.queryParams', this.queryParams);
}
);
// also listening to changes in viewtab and impose navTreeChange
this.viewTabSubscription = this.router.events.subscribe(event => {
if (event instanceof ChildActivationEnd) {
const regex = new RegExp('\\W'); // for splitting at every non alphanumeric char
const newTab = this.router.url.split(regex)[2];
if (newTab && this.activeViewTab !== newTab) {
this.changeNavTreeOnViewChange(newTab);
}
}
});
// The overall tabIndex in navigation list
this.navTreeIndex = this.navDefinitions.navigationTreeDefs;
this.subTreeDefs = this.navDefinitions.navigationTreeDefs[0].subTrees;
this.selectedSubTree = this.subTreeDefs[0]; // default on construct class
this.manuscriptNavTrees = []; // TODO: make it generic for each tree, do not use this.manuscriptNavTrees
this.createSubNavTrees(0);
}
/**
* createSubNavTrees
* Creates the data array containing all subTrees,
* param: mainTreeId:number : the index of the main tree
*/
createSubNavTrees(mainTreeId: number) {
this.navDefinitions.navigationTreeDefs[mainTreeId].subTrees.forEach(subTree => {
const tree = new NavTree(subTree.id, subTree.label, [], subTree.description );
// TODO: make it generic for each tree, do not use this.manuscriptNavTrees
this.manuscriptNavTrees.push(tree); } );
}
/**
* setActiveTreeData
* Set the active tree data and emits it back to navigation list component,
* param: idx:number : the index of the tree data to be displayed.
*/
setActiveTreeData(idx: number) {
switch (idx) {
case 0: // Manuscript
this.activeTreeData = this.activeManuscriptNavTreeData;
break;
case 1: // Page
this.activeTreeData = this.activePageNavTreeData;
break;
}
this.activeTreeDataChange.emit(this.activeTreeData);
}
/**
* updateRoute
* routes to the active url with the updated query params of this class.
*/
updateRoute(itsme?) {
const activeUrl = this.router.url.split('?')[0]; // seems workaroundish, but actually safe & secure; no other suitable solution at hand
//console.log('updating route through', itsme, ' to ', this.queryParams);
this.router.navigate([activeUrl], { queryParams: this.queryParams });
}
/**
* changeActiveTreeIndex
* Simply changing the active tree index for the navBar in
* param: idx:number : the index of the tree which should be displayed.
*/
changeActiveTreeIndex(idx: number) {
// setting all to false first
for (let i = 0; i < this.navTreeIndex.length; i++) {
this.navTreeIndex[i].isActive = false; }
this.navTreeIndex[idx].isActive = true;
this.setQueryParamOnServiceLevel('navTreeIndex', idx.toString() );
// also routing according to the chosen thing
this.updateRoute('changeActiveTreeIndex()');
}
/**
* changeNavTreeOnViewChange: Changes the active Navigation tree
* e.g. if a user changes to page view, the navigation bar should also switch to pages. If Manuscript view is clicked, the navigation bar
* should show manuscript items
* param: oldView: The view before view changes
* param: chengedView: The newly active view
*
*/
changeNavTreeOnViewChange(changedView) {
let treeIndex;
if ( changedView === 'manuscript' ) {
treeIndex = 0; } else { treeIndex = 1; }
this.changeActiveTreeIndex(treeIndex);
this.setActiveTreeData(treeIndex);
this.activeViewTab = changedView;
}
/**
* createNavTreesOnInit creates the first trees if no query params are available in the url:
* It ceates the manuscripNavTree and the activePageNavTreeData of the first manuscript per default.
*
*/
createNavTreesOnInit() {
// selecting the first of the manuscript trees as the selected one
this.setSelectedManuscriptTree(0);
// Get all manuscript data for each manuscript tree
this.navDefinitions.navigationTreeDefs[0].subTrees.forEach(treeDef => {
this.getTreeData(treeDef);
});
// create the activePageNavTreeData with the first item of the first activeManuscriptNavTreeData AFTER the
// first TlnManuscript is in the activeManuscriptNavTreeData
this.activeManuscriptNavTreeChange.subscribe(tree => {
this.getPagesToNavTree(tree[0].tlnEntity.id);
this.activeTreeData = tree;
this.setActiveTreeData(0);
this.changeActiveTreeIndex(0);
});
if (!this.selectedManuscript) { // if no manuscript is selected the first entry will be set as selected manuscript;
this.activeManuscriptNavTreeChange.subscribe(manTree => this.setSelectedManuscript(manTree[0].tlnEntity)); }
}
createManuscriptNavTreeFromRdf() {
// TODO: implement this further for switch to RDF data only
this.queryService.getQueryfromFilename('getConvolutes.rq').subscribe(qString => {
this.queryService.getData(qString, 'SELECT').subscribe(data => {
console.log('convolute data: ', data);
});
});
}
getTreeData(treeDef: SubTreeDef) {
if ( treeDef.id === 0 || treeDef.id === 2 ) {
this.getManuscriptsFromNietzscheSource(treeDef.id, treeDef.apiDef.posFilterIds);
}
}
/**
* getManuscriptsFromNietzscheSource
* Gets the convolutes/manuscripts from nietzscheSource and pushes
*/
getManuscriptsFromNietzscheSource(treeIdx, posFilter?: string[] ) {
this.nietzscheSourceService.getConvolutes().subscribe( res => {
const manuscripts = res.result.children;
manuscripts.forEach(( man, index ) => {
if ( posFilter ) { // if a posFilter is passed only push the manuscripts defined in posfilter
if (posFilter.indexOf(man.id ) > -1) { this.pushToManuscriptNavTree(treeIdx, man, index); }
} else { this.pushToManuscriptNavTree(treeIdx, man, index); } // if no filter defined we push everything
// if everything is pushed to the activeManuscriptNavTreeData we emit the new tree to the navigation-list-component
if (index + 1 === manuscripts.length) {
// and if it is also the selected Manuscript tree coming from queryParams, we set the active tree and emit it
if ( this.manuscriptNavTrees[treeIdx].id === this.selectedSubTree.id) {
this.activeManuscriptNavTreeData = this.manuscriptNavTrees[treeIdx].entries;
this.activeManuscriptNavTreeChange.emit(this.activeManuscriptNavTreeData);
}
}
});
}
);
}
pushToManuscriptNavTree(treeIdx, man, index) {
const entity = new TlnEntity(man.id, man.api_retrieve_content, 'man', index, man.id);
const manEntity = new NavigationEntity(index, entity, '');
this.manuscriptNavTrees[treeIdx].entries.push(manEntity);
}
/**
* createManuscriptNavTreeFromUrl
* Gets the convolutes/manuscripts from nietzscheSource and pushes them as NavigationEntitiy objects to the activeManuscriptNavTreeData array
* param: params: the query parameters
*/
createManuscriptNavTreeFromUrl(params) {
this.subTreeDefs.forEach(treeDef => {
this.getTreeData(treeDef);
});
this.activeManuscriptNavTreeChange.subscribe(tree => {
tree.forEach(navEntity => {
if (navEntity.tlnEntity.id === params.man) { // set the manuscript entry as selected if its id equals the query param 'man'
this.setSelectedManuscript(navEntity.tlnEntity);
// TODO: Refactor and test: DELETE the if, becasue it is set always to params.navTreeIndex!!!
// setting the active tree to the activeManuscriptNavTreeData
if (params.navTreeIndex === '0') {
this.setActiveTreeData(Number(params.navTreeIndex));
}
}
});
});
}
/**
* getPagesToNavTree
* Gets the pages from a given manuscript to the activePageNavTreeData. Sets the selectedPage to the passed pageId. If no pageId is passed,
* the selectedPage will be set to the first page of the given manuscript.
* param: manId: the manuscript id for ehich the pages are loaded
* param: pageId: the page id which should be set as the selected page
*/
getPagesToNavTree(manId: string, pageId?: string) {
this.activePageNavTreeData = [];
this.nietzscheSourceService.getPages(manId).subscribe( res => {
const pages = res.result.children;
let intIndex = 0; // internal index
pages.forEach((p, index) => {
// only if the last id part of the id can be converted to a number, it is a single page for which we have use.
// (we only transcribe single pages for now
if (isNaN( p.id.split(',').pop() ) === false) {
const entity = new TlnEntity(p.id, p.api_retrieve_content, 'page', intIndex, p.id );
const pageEntity = new NavigationEntity(intIndex, entity, '');
this.activePageNavTreeData.push(pageEntity);
if (!pageId && intIndex === 0) { // if there is no page param passed set the first entry as selected page
this.setSelectedPage(this.activePageNavTreeData[0]);
}
intIndex += 1;
if (pageId && p.id === pageId ) { // if the p.id matches the pageId we set that page as selectedPage
this.setSelectedPage(pageEntity);
}
} // else {console.log('skipped double page', p.id); }
// if last page has been loaded to activePageNavTreeData we emit to navlist for display and add the additional data from other sources
if (index + 1 === pages.length) {
this.activePageNavTreeChange.emit(this.activePageNavTreeData);
this.addDataToPageTree();
}
});
});
}
/**
* createNavTreesFromUrlParams
* Loads the navigation view & trees accoring to the given query parameters.
* param: params: the query parameters
*/
createNavTreesFromUrlParams(params) {
// change active
this.changeActiveTreeIndex(Number(params.navTreeIndex));
this.setSelectedManuscriptTree(params.manuscriptGroup);
this.createManuscriptNavTreeFromUrl(params);
this.createPageNavTreeFromUrl(params);
}
// simply setting the active manuscript tree, not emitting hence the navlist component has set it and already setit itself
// emitting only the new tree data
setSelectedManuscriptTree(id: number) {
this.selectedSubTree = this.navDefinitions.navigationTreeDefs[0].subTrees[id];
this.activeManuscriptNavTreeData = this.manuscriptNavTrees[id].entries;
this.setQueryParamOnServiceLevel('manuscriptGroup', id.toString());
this.updateRoute('setSelectedManuscriptTree()');
// Todo: only if treedata is manuscript
this.setActiveTreeData(0);
}
setSelectedManuscript(man: TlnEntity) {
this.setQueryParamOnServiceLevel('man', man.id);
this.updateRoute();
// TODO: REMOVE the following if not needed anymore!!!
this.selectedManuscript = new TlnManuscript(man);
this.selectedManuscriptChange.emit(this.selectedManuscript);
}
setSelectedPage(pageData: NavigationEntity ) {
this.setQueryParamOnServiceLevel('page', pageData.tlnEntity.id);
this.updateRoute();
// TODO: REMOVE the following if not needed anymore!!!
this.selectedPage = new TlnPage(pageData.tlnEntity, pageData.tlnEntity.label, pageData.img, pageData.svg);
this.selectedPageChange.emit(this.selectedPage);
}
// sets the first page as selected if no selectedPage
setSelectedPageIfNone() {
if (!this.selectedPage) {
this.activePageNavTreeChange.subscribe(pageTree => this.setSelectedPage(pageTree[0]));
this.activePageNavTreeChange.unsubscribe();
}
}
turnPage(modifier: number) {
const newPageIndex = this.selectedPage.entity.navIndex + modifier;
if ( newPageIndex >= 0 && newPageIndex <= this.activePageNavTreeData.length) {
this.setSelectedPage(this.activePageNavTreeData[newPageIndex]);
}
}
/**
* createPageNavTreeFromUrl: Loads all navigation navigation trees according to the given queryParams passed
* param: params: the query parameters
*
*/
createPageNavTreeFromUrl(params) {
this.getPagesToNavTree(params.man, params.page);
// if the active tree === '1' we have to set activePageNavTreeData as active tree
if (params.navTreeIndex === '1' ) {
// update active tree data each time the activePageNavTreeData changes
this.activePageNavTreeChange.subscribe(tree => this.setActiveTreeData(Number(params.navTreeIndex)));
}
}
switchTreeIfPageView(activeTab: string) {
if ( activeTab === 'page') {
// console.log('switching tree hence acivetab ===', activeTab);
this.setActiveTreeData(1);
this.changeActiveTreeIndex(1);
this.setSelectedPageIfNone();
}
}
onSelectedItem(item: NavigationEntity) {
// if (this.activatedRoute.snapshot.queryParamMap.get('navTreeIndex') === '0') { };
//const activeTab = this.activatedRoute.snapshot['_urlSegment'].children.primary.segments[1].path;
switch (item.tlnEntity.type) {
case 'man': {
// set the new url with the chose man parameter
this.getPagesToNavTree(item.tlnEntity.id);
// If the active tab is the page view we switch automatically to page tree in navigation
// this.switchTreeIfPageView(activeTab);
this.setSelectedManuscript(item.tlnEntity);
break;
}
case 'page': {
this.setSelectedPage(item);
this.selectedPageChange.emit(this.selectedPage);
this.setQueryParamOnServiceLevel('page', this.selectedPage.entity.id );
break;
}
default: {
console.log('unknown item.tlnEntity.type: ', item.tlnEntity.type);
}
}
}
setResourceOfInterest(res: string) {
this.resourceOfInterest = res;
this.resourceOfInterestChange.emit(res);
}
// adds all file data such as thumbnails as well as imageUrls or svgUrls to the activePageNavTreeData
addDataToPageTree() {
for (let i = 0; i < this.activePageNavTreeData.length; i++) {
this.addFileDataToPageTree(this.activePageNavTreeData[i].tlnEntity.iri, i);
}
}
addFileDataToPageTree(pageIri, index) {
this.nietzscheSourceService.getPageData(pageIri).subscribe(data => {
this.getFileToEntity(data.result.metadata.download_version.thumb, index, 'thumb'); // get thumbnail
this.activePageNavTreeData[index].img = data.result.metadata.download_version.medium; // setting the image url
// console.log(data.result.metadata);
this.setSvgUrl(data.result.metadata.siglum, index); // setting the svg url
});
}
private setSvgUrl(pageName: string, index) {
const baseUrl = 'http://130.60.24.65:8081/exist/rest/db/ProjectData/Nietzsche/svg/';
const pNamepre = pageName.split('-').join('_'); // exchanging '-' with underscore
const pName = pNamepre.split(',')[0];
const pNumber = pNamepre.split(',')[1];
const pageZerofilled = ('000' + pNumber).slice(-3);
this.activePageNavTreeData[index].svg = baseUrl + pName + '_page' + pageZerofilled + '_web.svg';
}
/**
* getFileToEntity: Gets a file from a url and adds it to the desired property of a navigation entity
* param: url: the query parameters
* param: index: the index of the navTree entity to update
* param: prop: The property which will be set, e.g. 'thumb' for navEntity.thumb
*/
getFileToEntity(url: string, index: number, prop: string) {
this.nietzscheSourceService.getFileFromUrl(url).subscribe(file => {
const reader = new FileReader();
reader.addEventListener('load', () => {
if ( this.activePageNavTreeData[index] ) {
this.activePageNavTreeData[index][prop] = reader.result;
}
}, false);
if (file) { reader.readAsDataURL(file); }
this.activePageNavTreeChange.emit(this.activePageNavTreeData);
});
}
getFullImage(pageIri: string) {
this.nietzscheSourceService.getPageData(pageIri).subscribe(data => {
this.nietzscheSourceService.getFileFromUrl(data.result.metadata.download_version.medium).subscribe(img => {
const reader = new FileReader();
reader.addEventListener('load', () => {
if ( this.selectedPage ) {
this.selectedPage.image = reader.result;
}
}, false);
if (img) { reader.readAsDataURL(img); }
this.selectedPageChange.emit(this.selectedPage);
});
});
}
// sets queryParams: to the queryParam object
setQueryParamOnServiceLevel(type: string, value: string) {
this.queryParams[type] = value;
// this.queryParamsChange.emit(this.queryParams);
}
ngOnDestroy() {
// unsubscribe to subscriptions if component change so there is no memory leak
this.queryParamSubscription.unsubscribe();
}
}

Event Timeline