168 lines
5.0 KiB
TypeScript
168 lines
5.0 KiB
TypeScript
|
import { DOCUMENT } from '@angular/common';
|
||
|
import { Component, EventEmitter, Inject, OnInit, Output, Input } from '@angular/core';
|
||
|
import { BaseComponent } from '@common/base/base.component';
|
||
|
import { interval, Subject, Subscription } from 'rxjs';
|
||
|
import { distinctUntilChanged } from 'rxjs/operators';
|
||
|
import { type } from 'os';
|
||
|
import { SimpleChanges } from '@angular/core';
|
||
|
import { ToCEntry } from './table-of-contents-entry';
|
||
|
|
||
|
export interface Link {
|
||
|
/* id of the section*/
|
||
|
id: string;
|
||
|
/* header type h3/h4 */
|
||
|
type: string;
|
||
|
/* If the anchor is in view of the page */
|
||
|
active: boolean;
|
||
|
/* name of the anchor */
|
||
|
name: string;
|
||
|
/* top offset px of the anchor */
|
||
|
top: number;
|
||
|
page: number;
|
||
|
section: number;
|
||
|
show: boolean;
|
||
|
selected: boolean;
|
||
|
}
|
||
|
|
||
|
@Component({
|
||
|
selector: 'dataset-profile-table-of-contents',
|
||
|
styleUrls: ['./table-of-contents.scss'],
|
||
|
templateUrl: './table-of-contents.html'
|
||
|
})
|
||
|
export class DatasetProfileTableOfContents extends BaseComponent implements OnInit {
|
||
|
|
||
|
@Input() links: ToCEntry[];
|
||
|
container: string;
|
||
|
headerSelectors = '.toc-page-header, .toc-section-header, .toc-compositeField-header';
|
||
|
@Output() stepFound = new EventEmitter<LinkToScroll>();
|
||
|
@Output() currentLinks = new EventEmitter<Link[]>();
|
||
|
subscription: Subscription;
|
||
|
linksSubject: Subject<HTMLElement[]> = new Subject<HTMLElement[]>();
|
||
|
|
||
|
@Input() isActive: boolean;
|
||
|
show: boolean = false;
|
||
|
|
||
|
constructor(
|
||
|
@Inject(DOCUMENT) private _document: Document) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
|
||
|
ngOnInit(): void {
|
||
|
//emit value every 500ms
|
||
|
// const source = interval(500);
|
||
|
// this.subscription = source.subscribe(val => {
|
||
|
// const headers = Array.from(this._document.querySelectorAll(this.headerSelectors)) as HTMLElement[];
|
||
|
// this.linksSubject.next(headers);
|
||
|
// });
|
||
|
|
||
|
// if (!this.links || this.links.length === 0) {
|
||
|
// this.linksSubject.asObservable()
|
||
|
// .pipe(distinctUntilChanged((p: HTMLElement[], q: HTMLElement[]) => JSON.stringify(p) == JSON.stringify(q)))
|
||
|
// .subscribe(headers => {
|
||
|
// const links: Array<Link> = [];
|
||
|
|
||
|
// if (headers.length) {
|
||
|
// let page;
|
||
|
// let section;
|
||
|
// let show
|
||
|
// for (const header of headers) {
|
||
|
// let name;
|
||
|
// let id;
|
||
|
// if (header.classList.contains('toc-page-header')) { // deprecated after removing stepper
|
||
|
// name = header.innerText.trim().replace(/^link/, '');
|
||
|
// id = header.id;
|
||
|
// page = header.id.split('_')[1];
|
||
|
// section = undefined;
|
||
|
// show = true;
|
||
|
// } else if (header.classList.contains('toc-section-header')) {
|
||
|
// name = header.childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0].nodeValue.trim().replace(/^link/, '');
|
||
|
// id = header.id;
|
||
|
// page = header.id.split('.')[1];
|
||
|
// section = header.id;
|
||
|
// if (header.id.split('.')[4]) { show = false; }
|
||
|
// else { show = true; }
|
||
|
// } else if (header.classList.contains('toc-compositeField-header')) {
|
||
|
// name = (header.childNodes[0]).nodeValue.trim().replace(/^link/, '');
|
||
|
// id = header.id;
|
||
|
// // id = header.parentElement.parentElement.parentElement.id;
|
||
|
// show = false;
|
||
|
// }
|
||
|
// const { top } = header.getBoundingClientRect();
|
||
|
// links.push({
|
||
|
// name,
|
||
|
// id,
|
||
|
// type: header.tagName.toLowerCase(),
|
||
|
// top: top,
|
||
|
// active: false,
|
||
|
// page: page,
|
||
|
// section: section,
|
||
|
// show: show,
|
||
|
// selected: false
|
||
|
// });
|
||
|
// }
|
||
|
// }
|
||
|
// this.links = links;
|
||
|
// // Initialize selected for button next on dataset wizard component editor
|
||
|
// this.links.length > 0 ? this.links[0].selected = true : null;
|
||
|
// })
|
||
|
// }
|
||
|
|
||
|
}
|
||
|
|
||
|
ngOnChanges(changes: SimpleChanges) {
|
||
|
// if (!this.isActive && this.links && this.links.length > 0) {
|
||
|
// this.links.forEach(link => {
|
||
|
// link.selected = false;
|
||
|
// })
|
||
|
// this.links[0].selected = true;
|
||
|
// }
|
||
|
}
|
||
|
|
||
|
goToStep(link: Link) {
|
||
|
// this.stepFound.emit({
|
||
|
// page: link.page,
|
||
|
// section: link.section
|
||
|
// });
|
||
|
// this.currentLinks.emit(this.links);
|
||
|
|
||
|
// setTimeout(() => {
|
||
|
// const target = document.getElementById(link.id);
|
||
|
// target.scrollIntoView(true);
|
||
|
|
||
|
// var scrolledY = window.scrollY;
|
||
|
// if (scrolledY) {
|
||
|
// window.scroll(0, scrolledY - 70);
|
||
|
// }
|
||
|
// }, 500);
|
||
|
}
|
||
|
|
||
|
toggle(headerLink: Link) {
|
||
|
// const headerPage = +headerLink.name.split(" ", 1);
|
||
|
// let innerPage;
|
||
|
// for (const link of this.links) {
|
||
|
// link.selected = false;
|
||
|
// if (link.type === 'mat-expansion-panel') {
|
||
|
// innerPage = +link.name.split(".", 1)[0];
|
||
|
// if (isNaN(innerPage)) { innerPage = +link.name.split(" ", 1) }
|
||
|
// } else if (link.type === 'h5') {
|
||
|
// innerPage = +link.name.split(".", 1)[0];
|
||
|
// }
|
||
|
// if (headerPage === innerPage && (link.type !== 'mat-expansion-panel' || (link.type === 'mat-expansion-panel' && link.id.split(".")[4]))) {
|
||
|
// link.show = !link.show;
|
||
|
// }
|
||
|
// }
|
||
|
// headerLink.selected = true;
|
||
|
}
|
||
|
|
||
|
// getIndex(link: Link): number {
|
||
|
// return +link.id.split("_", 2)[1];
|
||
|
// }
|
||
|
|
||
|
}
|
||
|
|
||
|
export interface LinkToScroll {
|
||
|
page: number;
|
||
|
section: number;
|
||
|
}
|