diff --git a/src/app/content-view-tab-component/content-view-tab-component.component.ts b/src/app/content-view-tab-component/content-view-tab-component.component.ts index 2270988..fe3438d 100644 --- a/src/app/content-view-tab-component/content-view-tab-component.component.ts +++ b/src/app/content-view-tab-component/content-view-tab-component.component.ts @@ -1,79 +1,80 @@ import {Component, OnDestroy, OnInit} from '@angular/core'; import {ActivatedRoute, Params, Router} from '@angular/router'; import {Subscription} from "rxjs/index"; import {TlnManuscript, TlnPage, TlnWord, TlnEntity, TlnQueryParams} from '../models/models'; import {NavigationServiceService} from "../services/navigation-service.service"; @Component({ selector: 'app-content-view-tab-component', templateUrl: './content-view-tab-component.component.html', styleUrls: ['./content-view-tab-component.component.scss'] }) export class ContentViewTabComponentComponent implements OnInit, OnDestroy { // navigation tabs for the content view (manuscript view, page view, rhizome view) navTabLinks: any[]; // navbar on th left for navigating navBarOpenState: boolean; navBarOpenMode = 'push'; // side || over || push queryParams: TlnQueryParams; queryParamSubscription: Subscription; constructor(private router: Router, private activatedRoute: ActivatedRoute, private naviService: NavigationServiceService) { // The links/tabs for routing the correct view-component this.navTabLinks = [ { label: 'Manuskriptansicht', link: 'manuscript', index: 0 }, { label: 'Seitenansicht', link: 'page', index: 1 }, { label: 'Rhizome-Ansicht', link: 'rhizome', index: 2 }, ]; } ngOnInit(): void { // If url pasted or page refreshed --> resetting the chosen things according to the query params of the url; this.queryParamSubscription = this.activatedRoute.queryParams.subscribe( (queryparams: Params ) => { this.queryParams = new TlnQueryParams(queryparams.man, queryparams.page, queryparams.row, queryparams.word, queryparams.viewMode, queryparams.navBarOpenState, - queryparams.navTreeIndex ); + queryparams.navTreeIndex, + queryparams.manuscriptGroup); } ); // Create Navigation trees for the navBar from queryParams if (this.activatedRoute.snapshot.queryParamMap.get('man')) { this.naviService.createNavTreesFromUrlParams(this.activatedRoute.snapshot.queryParams); } else { this.naviService.createNavTreesOnInit(); } // Set the NavBarOpenstate to true if it is true in the url query param onInit. if (this.activatedRoute.snapshot.queryParamMap.get('navBarOpenState') === 'true') { this.navBarOpenState = true; } } toggleNavDrawer() { // set it locally this.navBarOpenState = !this.navBarOpenState; // set the route as well const openStateString = this.navBarOpenState === null ? 'false' : (this.navBarOpenState ? 'true' : 'false'); this.naviService.setQueryParam('navBarOpenState', openStateString); this.naviService.updateRoute(); } ngOnDestroy() { // unsubscribe if component destroyed so there is no memory leak this.queryParamSubscription.unsubscribe(); } } diff --git a/src/app/models/models.ts b/src/app/models/models.ts index 3ef47a8..1395194 100644 --- a/src/app/models/models.ts +++ b/src/app/models/models.ts @@ -1,166 +1,220 @@ // class for Everything: extended by NavigationEntity, Manuscript, Page, Word with all common properties import {SafeUrl, ɵDomSanitizerImpl} from '@angular/platform-browser'; export class TlnEntity { id: string; // Short id, iri in most cases iri: string; // iri type: string; // rdfs:type navIndex: number; label?: string; constructor(id: string, iri: string, type: string, navIndex: number, label?: string) { this.id = id; this.iri = iri; this.type = type; this.navIndex = navIndex; this.label = label; } } export class TlnQueryParams { man: string; page: string; row: string; word: string; viewMode: string; navBarOpenState: boolean; navTreeIndex: number; - constructor(man: string, page: string, row: string, word: string, viewMode: string, navBarOpenState: boolean, navTreeIndex: number ) { + manuscriptGroup: number; + + constructor(man: string, page: string, row: string, word: string, viewMode: string, navBarOpenState: boolean, navTreeIndex: number, manuscriptGoup ) { this.man = man; this.page = page; this.row = row; this.word = word; this.viewMode = viewMode; this.navBarOpenState = navBarOpenState; this.navTreeIndex = navTreeIndex; + this.manuscriptGroup = this.manuscriptGroup; } } // The navigation entries in each tree for each viewtab (TlnManuscript, TlnPage, PositionalEntity) used by navigation // TODO: add several idxes? Or choosing another order will reload all, hence there is only one idx // export class NavigationEntity { idx: number; tlnEntity: TlnEntity; thumb?: SafeUrl; // url of image (Thumbnail) img?: SafeUrl; // full image url svg?: SafeUrl; // svg url constructor(idx: number, tlnEntity: TlnEntity, thumb?: string, img?, svg?: SafeUrl ) { this.idx = idx; this.tlnEntity = tlnEntity; this.thumb = thumb; this.img = img; this.svg = svg; } } // subclass for TlnManuscript, TlnPage, Word with all common properties export class TlnPhysicalEntity { entity: TlnEntity; description?: string; image?: SafeUrl; // url of image (Thumbnail); svg?: SafeUrl; constructor(entity: TlnEntity, description?: string, image?: SafeUrl, svg?: SafeUrl) { this.entity = entity; this.description = description; this.image = image; this.svg = svg; } } // the manuscript class export class TlnManuscript extends TlnPhysicalEntity { manuscriptSpec?: string; constructor(entity: TlnEntity, description?: string, image?: SafeUrl, svg?: Svg, manuscriptSpec?: string ) { super( entity, description, image, svg); this.manuscriptSpec = manuscriptSpec; } } // the TlnPage class export class TlnPage extends TlnPhysicalEntity { pageSpec?: string; constructor(entity: TlnEntity, description?: string, image?: SafeUrl, svg?: SafeUrl, pageSpec?: string ) { super( entity, description, image, svg); this.pageSpec = pageSpec; } } export class TlnRow extends TlnPhysicalEntity { rowSpec?: PositionalEntity; constructor(entity: TlnEntity, description?: string, image?: SafeUrl, svg?: Svg, rowSpec?: PositionalEntity ) { super( entity, description, image, svg); this.rowSpec = rowSpec; } } // the TlnWord class export class TlnWord extends TlnPhysicalEntity { wordSpec?: PositionalEntity; constructor(entity: TlnEntity, description?: string, image?: SafeUrl, svg?: SafeUrl, wordSpec?: PositionalEntity ) { super( entity, description, image, svg); this.wordSpec = wordSpec; } } export class Annotation { id: string; text: string; styles: Array; } export class Svg { id: string; svgUrl: string; svg?: SafeUrl; constructor(id, svgUrl, svg?) { this.id = id; this.svgUrl = svgUrl; this.svg = svg; } } // Only relevant if we create an svg ourselves? export interface PositionalEntity { // used for word rectangles as well as for line numbering id: string; text: string; left: number; top: number; width: number; height: number; row?: number; iri?: string; // TODO, change this. will be the id later when change data source to rdf ... } -export class NavTree { +export class NavTreeIndex { idx: number; isActive: boolean; label: string; treeClass: string; constructor( idx: number, isActive: boolean, label: string, treeClass: string ) { this.idx = idx; this.isActive = isActive; this.label = label; this.treeClass = treeClass; } } export class RVPageView { // Object for "double page" view recto: SafeUrl; verso: SafeUrl; constructor(recto: SafeUrl, verso: SafeUrl) { this.recto = recto; this.verso = verso; } } +export class NavTree { // a manuscript nav tree + id: number; + label: string; + entries: Array; + description?: string; + + constructor(id, label, entries, description? ) { + this.id = id; + this.label = label; + this.entries = entries; + this.description = description; + } +} + +export class ManuscriptSelectionDef { + id: number; + label: string; + description: string; + + constructor( id: number, label: string, description: string) { + this.id = id; + this.description = description; + this.label = label; + } +} + +export class ManuscriptDef extends ManuscriptSelectionDef { + apiDef: ApiDef; + + constructor( id: number, label: string, description: string, apiDef: ApiDef) { + super( id, label, description ); + this.id = id; + this.description = description; + this.label = label; + this.apiDef = apiDef; + } +} + +export class ApiDef { + id: number; + description: string; + baseApi?: string; + query?: string; + + constructor(id: number, description: string, baseApi?: string, query?: string) { + this.id = id; + this.description = description; + this.baseApi = baseApi; + this.query = query; + } +} diff --git a/src/app/navigation-list-component/navigation-list-component.component.html b/src/app/navigation-list-component/navigation-list-component.component.html index b520a7e..9b93c49 100644 --- a/src/app/navigation-list-component/navigation-list-component.component.html +++ b/src/app/navigation-list-component/navigation-list-component.component.html @@ -1,31 +1,40 @@ Navigation - +
+ + Manuskriptauswahl + + {{manSel.label}} + + +
+
{{selectedManuscriptGroup | json}}
+

Manuskript {{selectedManId}}

diff --git a/src/app/navigation-list-component/navigation-list-component.component.scss b/src/app/navigation-list-component/navigation-list-component.component.scss index 7764ebe..f38b50a 100644 --- a/src/app/navigation-list-component/navigation-list-component.component.scss +++ b/src/app/navigation-list-component/navigation-list-component.component.scss @@ -1,27 +1,37 @@ .fixed-nav-header { position: sticky; } +.man-selection{ + .mat-form-field { + width: 100% !important; + } + .mat-select-value { + max-width: 100%; + width: 100%; + } +} + .navlist-container { height: 70vh; overflow: auto; overflow-x: hidden; } .mat-divider { padding: 2px; } .active-item { background-color: #dadada !important; } .mat-nav-list .mat-list-item { // flex: none; min-height: 72px; height: 100%; /* default is 72px */ } .thumbnail { max-width: 120px; } diff --git a/src/app/navigation-list-component/navigation-list-component.component.ts b/src/app/navigation-list-component/navigation-list-component.component.ts index a7fc05e..408994d 100644 --- a/src/app/navigation-list-component/navigation-list-component.component.ts +++ b/src/app/navigation-list-component/navigation-list-component.component.ts @@ -1,105 +1,115 @@ import {AfterViewInit, Component, ElementRef, Input, OnChanges, OnInit, QueryList, ViewChild, ViewChildren} from '@angular/core'; import {NavigationServiceService} from '../services/navigation-service.service'; -import {NavigationEntity, NavTree, TlnEntity, TlnManuscript, TlnPage, TlnQueryParams, TlnWord} from '../models/models'; +import { + ManuscriptSelectionDef, NavigationEntity, NavTree, NavTreeIndex, TlnEntity, TlnManuscript, TlnPage, TlnQueryParams, + TlnWord +} from '../models/models'; import {Subscription} from 'rxjs/index'; @Component({ selector: 'app-navigation-list-component', templateUrl: './navigation-list-component.component.html', styleUrls: ['./navigation-list-component.component.scss'] }) /** * NavigationListComponent * Does sinply consume data coming from parent component and naviservice. triggers click event to service. */ export class NavigationListComponentComponent implements OnInit { @ViewChildren('tabFocus') focussedElements: QueryList; navTreeData: Array; // the data displayed in the navigation bar navTreeDataSub: Subscription; // detecting/reloding if the tree data changes navTreeSubscription: Subscription; // subscribing if the displayed tree changes. - navTrees = []; // The navTrees available for the nav bar for switchich between navtrees + navTreeIndex = []; // The navTreeIndex available for the nav bar for switchich between navtrees + manuscriptSelections: Array; + selectedManuscriptGroup: number; // Subscribtions selectedManuscriptSub: Subscription; selectedPageSub: Subscription; // selectedWordSub: Subscription; selectedManId = ''; // for highlighting a chosen nav item. Will be set by click in the template as well as by subscription of nav service selectedPageId = ''; // for highlighting a chosen nav item - lastSelectedItem = ''; // for scrolling into view constructor( private naviService: NavigationServiceService ) { // if the displayed navTree changes through navigation. this.navTreeSubscription = this.naviService.navTreeIndexChange.subscribe(trees => { - this.navTrees = trees; + this.navTreeIndex = trees; } ); } ngOnInit() { + this.manuscriptSelections = this.naviService.getManuscriptSelections(); + this.navTreeDataSub = this.naviService.activeTreeDataChange.subscribe(treeData => { this.navTreeData = treeData; this.setFocusOnActiveTab(); this.tryToScroll(); } ); // Listening to changes and set the selected things accordingly. this.selectedManuscriptSub = this.naviService.selectedManuscriptChange.subscribe(m => { this.selectedManId = m.entity.id; }); this.selectedPageSub = this.naviService.selectedPageChange.subscribe(p => { this.selectedPageId = p.entity.id; }); } tryToScroll() { // TODO: Tooo slow: tree is not yet active, so wrong ID is passed // scroll into view of the selected item within the active tree - if (this.navTrees[this.navTrees.findIndex((tree) => tree.isActive)].idx === 0 ) { + if (this.navTreeIndex[this.navTreeIndex.findIndex((tree) => tree.isActive)].idx === 0 ) { this.scrollOnToSelectedItem(this.selectedManId); } else {this.scrollOnToSelectedItem(this.selectedPageId); } } setFocusOnActiveTab() { const activeTab = (element => element.isActive === true); - const activeTabIndex = this.navTrees.findIndex(activeTab); + const activeTabIndex = this.navTreeIndex.findIndex(activeTab); if ( this.focussedElements ) { this.focussedElements.forEach((elem, index) => { if ( index === activeTabIndex ) { elem.nativeElement.focus(); } }); } } onSelectNavItem(item: NavigationEntity) { this.naviService.onSelectedItem(item); this.scrollOnToSelectedItem(item.tlnEntity.id); } // For scrolling to the selected item (manuscript, page) into view scrollOnToSelectedItem(itemId: string) { - console.log('try to scroll to', itemId); + // console.log('try to scroll to', itemId); const itemToScrollTo = document.getElementById(itemId); if ( itemToScrollTo ) { itemToScrollTo.scrollIntoView({ behavior: 'smooth' }); } } // switches tabs in navtab ov navigation bar - changeToTree(idx) { + changeMainNavTree(idx) { // set treedata to new tab index this.naviService.setActiveTreeData(idx); // change also the tab itself. this.naviService.changeActiveTreeIndex(idx); this.setFocusOnActiveTab(); } + changeManuscriptNavTree(id: number) { + console.log('new treeId = ', id); + } + isItemSelected(itemId) { let isSelected = false; if (this.selectedManId === itemId || this.selectedPageId === itemId) { isSelected = true; } return isSelected; } } diff --git a/src/app/page-view-component/page-view-component.component.ts b/src/app/page-view-component/page-view-component.component.ts index 8fb8e73..b12dc38 100644 --- a/src/app/page-view-component/page-view-component.component.ts +++ b/src/app/page-view-component/page-view-component.component.ts @@ -1,117 +1,118 @@ import {Component, OnInit} from '@angular/core'; import {PositionalEntity, Svg, TlnEntity, NavigationEntity, TlnPage, TlnWord, RVPageView, TlnQueryParams} from '../models/models'; import {SvgService} from "../services/svg.service"; import {PageViewService} from "../services/field-interaction.service"; import {Subscription} from "rxjs/index"; import {ActivatedRoute, Params, Router} from "@angular/router"; import {NavigationServiceService} from "../services/navigation-service.service"; import {DomSanitizer, SafeUrl} from '@angular/platform-browser'; @Component({ selector: 'app-page-view-component', templateUrl: './page-view-component.component.html', styleUrls: ['./page-view-component.component.scss'] }) export class PageViewComponentComponent implements OnInit { activePage: TlnPage; activePageChange: Subscription; // images selectedImage: SafeUrl; // the image selected in gallery, menue or so // svg selectedSvg: SafeUrl; // the svg to show selectedSvgRV: RVPageView; // "double page" view for recto and verso // settings for user to choose paging: string; alignment: string; fixSidebar: boolean; highlight: boolean; queryParamSubscription: Subscription; queryParams: TlnQueryParams; wordSubscription: Subscription; wordQueryParam: string; // NavBar/Infobox selectedWord: TlnWord; openState: boolean; defaultOpenState = false; constructor(private svgService: SvgService, private pageViewService: PageViewService, private router: Router, private activatedRoute: ActivatedRoute, private naviService: NavigationServiceService, private sanitizer: DomSanitizer ) { } ngOnInit() { // If url pasted or page refreshed --> resetting the chosen things according to the query params of the url; this.queryParamSubscription = this.activatedRoute.queryParams.subscribe( (queryparams: Params ) => { this.queryParams = new TlnQueryParams(queryparams.man, queryparams.page, queryparams.row, queryparams.word, queryparams.viewMode, queryparams.navBarOpenState, - queryparams.navTreeIndex ); + queryparams.navTreeIndex, + queryparams.manuscriptGroup); } ); this.activePageChange = this.naviService.selectedPageChange.subscribe( page => { this.activePage = page; this.selectedSvg = this.sanitizer.bypassSecurityTrustResourceUrl(page.svg); } ); this.openState = this.defaultOpenState; // default settings oninit this.paging = 'double'; this.alignment = 'horizontal'; this.fixSidebar = false; this.highlight = true; this.wordSubscription = this.pageViewService.wordChange$.subscribe( word => { if (this.selectedWord) { if (this.selectedWord.wordSpec === word) { this.toggleDetailsDrawer(); } else { this.selectedWord.wordSpec = word; this.selectedWord.entity = new TlnEntity(word.id, word.iri, 'TlnWord', 0, word.text); const wordNav = new NavigationEntity(0, this.selectedWord.entity); this.naviService.onSelectedItem(wordNav); this.naviService.setResourceOfInterest(word.id); if (!this.openState) { this.toggleDetailsDrawer(); } } } else { const e = new TlnEntity(word.id, word.iri, 'TlnWord', 0, word.id); this.selectedWord = new TlnWord(e, word.text, this.selectedImage, this.selectedSvg, word); } }); } private turnPage(direction: number) { this.naviService.turnPage(direction); // change chosen page } toggleDetailsDrawer() { this.openState = !this.openState; } toggleHighlight() { this.highlight = !this.highlight; } toggleSidebarFixation() { this.fixSidebar = !this.fixSidebar; } setViewMode(view) { this.naviService.setQueryParam('viewMode', view); this.naviService.updateRoute(); } } diff --git a/src/app/services/navigation-service.service.ts b/src/app/services/navigation-service.service.ts index 32cdabf..c6f954d 100644 --- a/src/app/services/navigation-service.service.ts +++ b/src/app/services/navigation-service.service.ts @@ -1,412 +1,494 @@ import {EventEmitter, Injectable, OnDestroy} from '@angular/core'; -import { TlnManuscript, NavigationEntity, TlnPage, TlnEntity, TlnQueryParams, NavTree } from '../models/models'; +import { + TlnManuscript, NavigationEntity, TlnPage, TlnEntity, TlnQueryParams, NavTreeIndex, NavTree, + ManuscriptSelectionDef, ManuscriptDef +} 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'; @Injectable({ providedIn: 'root' }) export class NavigationServiceService implements OnDestroy { - selectedManuscript: TlnManuscript; - selectedPage: TlnPage; - queryParams: TlnQueryParams; // Listening to the queries entered actively (so also if page is refreshed or a url loaded) queryParamSubscription: Subscription; + viewTabSubscription: Subscription; activeViewTab = ''; + navTreeIndex: Array; + navTreeIndexChange = new EventEmitter(); // Weather only the index changes + + // the different manuscript navigation trees: Manuscripte archivalischer Ordnung, konzeptioneller Ordnung, ... + manuscriptSelections: ManuscriptDef[]; // the index of different manuscriptNavTrees available for selection + manuscriptNavTrees: NavTree[]; // the trees inteslf with data; + manuscriptNavTreesChange: EventEmitter; + + activeTreeData: Array; + activeTreeDataChange = new EventEmitter(); // if the active tree data changes + + // The actual selected things + selectedManuscriptChange = new EventEmitter(); + selectedPageChange = new EventEmitter(); + + resourceOfInterest: string; // simple iri for Databrowser and rdf stuff to come + resourceOfInterestChange = new EventEmitter(); + + // TODO: Change to new ManTreeModel + selectedManuscriptNavTree: Array = []; + manuscriptNavTreeChange = new EventEmitter>(); // internally used + selectedPageNavTree: Array = []; + pageNavTreeChange = new EventEmitter>(); // 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); + 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.navTreeIndex, + queryparams.manuscriptGroup); } ); // 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 (this.activeViewTab !== newTab) { this.changeNavTreeOnViewChange(newTab); } } }); + // The overall tabIndex in navigation list this.navTreeIndex = [ { idx: 0, isActive: true, label: 'Manuskripte', treeClass: 'Tln:Manuscript' }, { idx: 1, isActive: false, label: 'Seiten', treeClass: 'TlnPage' }/*, { idx: 2, isActive: false, label: 'Worte', treeClass: 'TlnWord' }*/ ]; - } - resourceOfInterest: string; // simple iri for Databrowser and rdf stuff to come - resourceOfInterestChange = new EventEmitter(); - selectedManuscriptChange = new EventEmitter(); - selectedPageChange = new EventEmitter(); + this.manuscriptSelections = [ + { + id: 0, + apiDef: { + id: 0, + description: 'all manuscripts in archival order', + baseApi: '', + query: 'rdf_archival_order.ttl' + }, + label: 'Manuskripte in archivalischer Ordnung', + description: 'Manuskripte in archivalischer Ordnung' + }, + { + id: 1, + apiDef: { + id: 1, + description: 'all manuscripts for which we have a conceptional order', + baseApi: '', + query: 'rdf_conceptional_order.ttl' + }, + label: 'Manuskripte in konzeptioneller Ordnung', + description: 'Manuskripte in konzeptioneller Ordnung' + }, + { + id: 2, + apiDef: { + id: 2, + description: 'all manuscripts from nietzscheSource', + baseApi: '', + query: '' + }, + label: 'Noch unaufbereitete Manuskripte', + description: 'Noch unaufbereitete Manuskrtipte' + } + ]; - activeTreeData: Array; - activeTreeDataChange = new EventEmitter>(); // if the active tree data changes - navTreeIndex: Array; - navTreeIndexChange = new EventEmitter>(); // Weather only the index changes + this.manuscriptNavTrees = [ + { + id: 0, + label: 'Manuskripte in archivalischer Ordnung', + entries: [], // NavTree[] from RDF data + description: 'Manuskripte in archivalischer Ordnung' + }, + { + id: 1, + label: 'Manuskripte in konzeptioneller Ordnung', + entries: [], // NavTree[] from RDF + description: 'Manuskripte in konzeptioneller Ordnung' + }, + { + id: 2, + label: 'noch unaufbereitete Manuskrtipte', + entries: [], // NavTree[] from NietzscheSource without our data + description: 'Noch unaufbereitete Manuskrtipte' + } + ]; + } - manuscriptNavTree: Array = []; - manuscriptNavTreeChange = new EventEmitter>(); // internally used - pageNavTree: Array = []; - pageNavTreeChange = new EventEmitter>(); // internally used + + getManuscriptSelections() { + const manGroups: ManuscriptSelectionDef[] = []; + for (const manDef of this.manuscriptSelections) { + const man = new ManuscriptSelectionDef(manDef.id, manDef.label, manDef.description ); + manGroups.push(man); + } + return manGroups; } /** * 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.manuscriptNavTree; + this.activeTreeData = this.selectedManuscriptNavTree; break; case 1: // Page - this.activeTreeData = this.pageNavTree; + this.activeTreeData = this.selectedPageNavTree; break; } this.activeTreeDataChange.emit(this.activeTreeData); } /** * updateRoute * routes to the active url with the updated query params of this class. */ updateRoute() { const activeUrl = this.router.url.split('?')[0]; // seems workaroundish, but actually safe & secure; no other suitable solution at hand 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.navTreeIndexChange.emit(this.navTreeIndex); this.setQueryParam('navTreeIndex', idx.toString() ); // also routing according to the chosen thing this.updateRoute(); } /** * 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 pageNavTree of the first manuscript per default. + * It ceates the manuscripNavTree and the selectedPageNavTree of the first manuscript per default. * */ createNavTreesOnInit() { - this.getManuscriptsToNavTree(); - // create the pageNavTree with the first item of manuscriptNavTree AFTER the first TlnManuscript is in the manuscriptNavTree + this.getManuscriptsFromNietzscheSourceToNavTree(); + // create the selectedPageNavTree with the first item of selectedManuscriptNavTree AFTER the first TlnManuscript is in the selectedManuscriptNavTree this.manuscriptNavTreeChange.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.manuscriptNavTreeChange.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); }); }); } /** - * getManuscriptsToNavTree - * Gets the convolutes/manuscripts from nietzscheSource and pushes them as NavigationEntitiy objects to the manuscriptNavTree array + * getManuscriptsFromNietzscheSourceToNavTree + * Gets the convolutes/manuscripts from nietzscheSource and pushes them as NavigationEntitiy objects to the selectedManuscriptNavTree array */ - getManuscriptsToNavTree() { + getManuscriptsFromNietzscheSourceToNavTree() { this.nietzscheSourceService.getConvolutes().subscribe( res => { const manuscripts = res.result.children; manuscripts.forEach(( man, index ) => { const entity = new TlnEntity(man.id, man.api_retrieve_content, 'man', index, man.id); const manEntity = new NavigationEntity(index, entity, ''); - this.manuscriptNavTree.push(manEntity); - // if everything is pushed to the manuscriptNavTree we emit the new tree to the navigation-list-component + this.selectedManuscriptNavTree.push(manEntity); + // if everything is pushed to the selectedManuscriptNavTree we emit the new tree to the navigation-list-component if (index + 1 === manuscripts.length) { - this.manuscriptNavTreeChange.emit(this.manuscriptNavTree); + this.manuscriptNavTreeChange.emit(this.selectedManuscriptNavTree); } }); } ); } /** * createManuscriptNavTreeFromUrl - * Gets the convolutes/manuscripts from nietzscheSource and pushes them as NavigationEntitiy objects to the manuscriptNavTree array + * Gets the convolutes/manuscripts from nietzscheSource and pushes them as NavigationEntitiy objects to the selectedManuscriptNavTree array * param: params: the query parameters */ createManuscriptNavTreeFromUrl(params) { - this.getManuscriptsToNavTree(); + this.getManuscriptsFromNietzscheSourceToNavTree(); this.manuscriptNavTreeChange.subscribe(tree => { tree.forEach(navEntity => { if (navEntity.tlnEntity.id === params.man) { this.setSelectedManuscript(navEntity.tlnEntity); - // setting the active tree to the manuscriptNavTree + // setting the active tree to the selectedManuscriptNavTree if (params.navTreeIndex === '0') { this.setActiveTreeData(Number(params.navTreeIndex)); } } }); }); } /** * getPagesToNavTree - * Gets the pages from a given manuscript to the pageNavTree. Sets the selectedPage to the passed pageId. If no pageId is passed, + * Gets the pages from a given manuscript to the selectedPageNavTree. 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.pageNavTree = []; + this.selectedPageNavTree = []; 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.pageNavTree.push(pageEntity); + this.selectedPageNavTree.push(pageEntity); if (!pageId && intIndex === 0) { // if there is no page param passed set the first entry as selected page - this.setSelectedPage(this.pageNavTree[0]); + this.setSelectedPage(this.selectedPageNavTree[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 pageNavTree we emit to navlist for display and add the additional data from other sources + // if last page has been loaded to selectedPageNavTree we emit to navlist for display and add the additional data from other sources if (index + 1 === pages.length) { - this.pageNavTreeChange.emit(this.pageNavTree); + this.pageNavTreeChange.emit(this.selectedPageNavTree); 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.createManuscriptNavTreeFromUrl(params); this.createPageNavTreeFromUrl(params); } setSelectedManuscript(man: TlnEntity) { this.selectedManuscript = new TlnManuscript(man); this.selectedManuscriptChange.emit(this.selectedManuscript); } setSelectedPage(pageData: NavigationEntity ) { 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.pageNavTreeChange.subscribe(pageTree => this.setSelectedPage(pageTree[0])); this.pageNavTreeChange.unsubscribe(); } } turnPage(modifier: number) { const newPageIndex = this.selectedPage.entity.navIndex + modifier; - this.setSelectedPage(this.pageNavTree[newPageIndex]); + this.setSelectedPage(this.selectedPageNavTree[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 pageNavTree as active tree + // if the active tree === '1' we have to set selectedPageNavTree as active tree if (params.navTreeIndex === '1' ) { - // update active tree data each time the pageNavTree changes + // update active tree data each time the selectedPageNavTree changes this.pageNavTreeChange.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) { console.log('clicked item: ', item); 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); this.setQueryParam('man', this.selectedManuscript.entity.id ); // also routing according to the chosen thing break; } case 'page': { this.setSelectedPage(item); this.selectedPageChange.emit(this.selectedPage); this.setQueryParam('page', this.selectedPage.entity.id ); // also routing according to the chosen thing break; } default: { console.log('unknown item.tlnEntity.type: ', item.tlnEntity.type); } } this.updateRoute(); } 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 pageNavTree + // adds all file data such as thumbnails as well as imageUrls or svgUrls to the selectedPageNavTree addDataToPageTree() { - for (let i = 0; i < this.pageNavTree.length; i++) { - this.addFileDataToPageTree(this.pageNavTree[i].tlnEntity.iri, i); + for (let i = 0; i < this.selectedPageNavTree.length; i++) { + this.addFileDataToPageTree(this.selectedPageNavTree[i].tlnEntity.iri, i); } } addFileDataToPageTree(pageIri, index) { this.nietzscheSourceService.getFileUrl(pageIri).subscribe(data => { this.getFileToEntity(data.result.metadata.download_version.thumb, index, 'thumb'); // get thumbnail - this.pageNavTree[index].img = data.result.metadata.download_version.medium; // setting the image url + this.selectedPageNavTree[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.pageNavTree[index].svg = baseUrl + pName + '_page' + pageZerofilled + '_web.svg'; + this.selectedPageNavTree[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.pageNavTree[index] ) { - this.pageNavTree[index][prop] = reader.result; + if ( this.selectedPageNavTree[index] ) { + this.selectedPageNavTree[index][prop] = reader.result; } }, false); if (file) { reader.readAsDataURL(file); } - this.pageNavTreeChange.emit(this.pageNavTree); + this.pageNavTreeChange.emit(this.selectedPageNavTree); }); } getFullImage(pageIri: string) { this.nietzscheSourceService.getFileUrl(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 setQueryParam(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(); } }