-
Contents
-
+
+
Contents
+
-
- {{link.name}}
-
-
+
+
+ {{link.name}}
+
+
+
diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.scss b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.scss
index be241f387..b3c4e796e 100644
--- a/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.scss
+++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.scss
@@ -1,58 +1,50 @@
-:host {
- font-size: 13px;
- // Width is container width minus content width
- width: 19%;
- height: fit-content;
- position: -webkit-sticky;
- position: sticky;
- // display: inline-flex;
- align-self: flex-start;
- top: 0;
- padding-left: 25px;
- box-sizing: border-box;
-}
-
.docs-toc-container {
- width: 100%;
- padding: 5px 0 10px 10px;
- cursor: pointer;
- border-left: solid 4px #0c7489;
+ width: 100%;
+ padding: 5px 0 10px 10px;
+ cursor: pointer;
+ border-left: solid 4px #0c7489;
- .docs-link {
- color: rgba(0, 0, 0, 0.54);
- // color: mat-color($app-blue-theme-foreground, secondary-text);
- transition: color 100ms;
+ .scroll-container {
+ overflow-y: auto;
+ // calc(100vh - 250px)
+ height: calc(100vh - 250px);
+ }
- &:hover,
- &.docs-active {
- color: #0c7489;
- // color: mat-color($primary, if($is-dark-theme, 200, default));
- }
- }
+ .docs-link {
+ color: rgba(0, 0, 0, 0.54);
+ // color: mat-color($app-blue-theme-foreground, secondary-text);
+ transition: color 100ms;
+
+ &:hover,
+ &.docs-active {
+ color: #0c7489;
+ // color: mat-color($primary, if($is-dark-theme, 200, default));
+ }
+ }
}
.docs-toc-heading {
- margin: 0;
- padding: 0;
- font-size: 13px;
- font-weight: bold;
+ margin: 0;
+ padding: 0;
+ font-size: 13px;
+ font-weight: bold;
}
span {
- line-height: 16px;
- margin: 8px 0 0;
- position: relative;
- text-decoration: none;
- display: block;
- text-overflow: ellipsis !important;
- overflow: hidden;
- color: rgba(0, 0, 0, 0.54);
+ line-height: 16px;
+ margin: 8px 0 0;
+ position: relative;
+ text-decoration: none;
+ display: block;
+ text-overflow: ellipsis !important;
+ overflow: hidden;
+ color: rgba(0, 0, 0, 0.54);
}
.docs-level-mat-expansion-panel {
- margin-left: 12px;
+ margin-left: 12px;
}
.docs-level-h5 {
- margin-left: 24px;
+ margin-left: 24px;
}
diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.ts
index 682fffcb1..4c399bee2 100644
--- a/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.ts
+++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.ts
@@ -1,29 +1,22 @@
import { DOCUMENT } from '@angular/common';
-import { AfterViewInit, Component, ElementRef, EventEmitter, Inject, Input, OnDestroy, OnInit, Output } from '@angular/core';
-import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
-import { fromEvent, Subject } from 'rxjs';
-import { debounceTime, takeUntil } from 'rxjs/operators';
-import { link } from 'fs';
-
+import { Component, ElementRef, EventEmitter, Inject, OnInit, Output } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { interval, Subject, Subscription } from 'rxjs';
+import { distinctUntilChanged } from 'rxjs/operators';
+import { BaseComponent } from '../../../../core/common/base/base.component';
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;
}
@@ -32,171 +25,73 @@ interface Link {
styleUrls: ['./table-of-contents.scss'],
templateUrl: './table-of-contents.html'
})
-export class TableOfContents implements OnInit, AfterViewInit, OnDestroy {
-
- @Input() links: Link[] = [];
- @Input() container: string;
- @Input() headerSelectors = '.toc-page-header, .toc-section-header, .toc-copositeField-header';
+export class TableOfContents extends BaseComponent implements OnInit {
+ links: Link[] = [];
+ container: string;
+ headerSelectors = '.toc-page-header, .toc-section-header, .toc-copositeField-header';
@Output() stepFound = new EventEmitter
();
+ subscription: Subscription;
+ linksSubject: Subject = new Subject();
- _rootUrl = this._router.url.split('#')[0];
- private _scrollContainer: any;
- private _destroyed = new Subject();
- private _urlFragment = '';
- private selectedLinkId: string;
-
- constructor(private _router: Router,
- private _route: ActivatedRoute,
- private _element: ElementRef,
+ constructor(
@Inject(DOCUMENT) private _document: Document) {
-
- this._router.events.pipe(takeUntil(this._destroyed)).subscribe((event) => {
- if (event instanceof NavigationEnd) {
- const rootUrl = _router.url.split('#')[0];
- if (rootUrl !== this._rootUrl) {
- this.links = this.createLinks();
- this._rootUrl = rootUrl;
- }
- }
- });
-
- this._route.fragment.pipe(takeUntil(this._destroyed)).subscribe(fragment => {
- this._urlFragment = fragment;
-
- const target = document.getElementById(this._urlFragment);
- if (target) {
- target.scrollIntoView();
- }
- });
+ super();
}
+
ngOnInit(): void {
- // On init, the sidenav content element doesn't yet exist, so it's not possible
- // to subscribe to its scroll event until next tick (when it does exist).
- Promise.resolve().then(() => {
- this._scrollContainer = this.container ?
- this._document.querySelectorAll(this.container)[0] : window;
-
- if (this._scrollContainer) {
- fromEvent(this._scrollContainer, 'scroll').pipe(
- takeUntil(this._destroyed),
- debounceTime(10))
- .subscribe(() => this.onScroll());
- }
+ //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);
});
- }
- ngAfterViewInit() {
- this.updateScrollPosition();
- }
+ this.linksSubject.asObservable()
+ .pipe(distinctUntilChanged((p: HTMLElement[], q: HTMLElement[]) => JSON.stringify(p) == JSON.stringify(q)))
+ .subscribe(headers => {
+ const links: Array = [];
- ngOnDestroy(): void {
- this._destroyed.next();
- }
-
- updateScrollPosition(): void {
- this.links = this.createLinks();
-
- const target = document.getElementById(this._urlFragment);
- if (target) {
- target.scrollIntoView();
- }
- }
-
- /** Gets the scroll offset of the scroll container */
- private getScrollOffset(): number | void {
- const { top } = this._element.nativeElement.getBoundingClientRect();
- if (typeof this._scrollContainer.scrollTop !== 'undefined') {
- return this._scrollContainer.scrollTop + top;
- } else if (typeof this._scrollContainer.pageYOffset !== 'undefined') {
- return this._scrollContainer.pageYOffset + top;
- }
- }
-
- private createLinks(): Link[] {
- const links: Array = [];
- const headers =
- Array.from(this._document.querySelectorAll(this.headerSelectors)) as HTMLElement[];
-
- if (headers.length) {
- for (const header of headers) {
- // const step = 0;
- // remove the 'link' icon name from the inner text
- const name = header.innerText.trim().replace(/^link/, '');
- const { top } = header.getBoundingClientRect();
- // links.push({
- // name,
- // // step,
- // type: header.tagName.toLowerCase(),
- // top: top,
- // id: header.id,
- // active: false,
- // section: section
- // });
- }
- }
-
- return links;
- }
-
- private onScroll(): void {
- // for (let i = 0; i < this.links.length; i++) {
- // this.links[i].active = this.isLinkActive(this.links[i], this.links[i + 1]);
- // }
- }
-
- // private isLinkActive(currentLink: any, nextLink: any): boolean {
- // A link is considered active if the page is scrolled passed the anchor without also
- // being scrolled passed the next link
- // const scrollOffset = this.getScrollOffset();
- // return scrollOffset >= currentLink.top && !(nextLink && nextLink.top < scrollOffset);
- // }
-
- getLinks() {
- const links: Array = [];
- const headers =
- Array.from(this._document.querySelectorAll(this.headerSelectors)) as HTMLElement[];
-
- if (headers.length) {
- let page;
- let section;
- for (const header of headers) {
- let name;
- let id;
- if (header.classList.contains('toc-page-header')) {
- name = header.innerText.trim().replace(/^link/, '');
- id = header.id;
- page = header.id.split('_')[1];
- section = undefined;
- } 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;
- } else if (header.classList.contains('toc-copositeField-header')) {
- name = (header.childNodes[0]).nodeValue.trim().replace(/^link/, '');
- id = header.id;
- // id = header.parentElement.parentElement.parentElement.id;
+ if (headers.length) {
+ let page;
+ let section;
+ for (const header of headers) {
+ let name;
+ let id;
+ if (header.classList.contains('toc-page-header')) {
+ name = header.innerText.trim().replace(/^link/, '');
+ id = header.id;
+ page = header.id.split('_')[1];
+ section = undefined;
+ } 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;
+ } else if (header.classList.contains('toc-copositeField-header')) {
+ name = (header.childNodes[0]).nodeValue.trim().replace(/^link/, '');
+ id = header.id;
+ // id = header.parentElement.parentElement.parentElement.id;
+ }
+ const { top } = header.getBoundingClientRect();
+ links.push({
+ name,
+ id,
+ type: header.tagName.toLowerCase(),
+ top: top,
+ active: false,
+ page: page,
+ section: section
+ });
+ }
}
- const { top } = header.getBoundingClientRect();
- links.push({
- name,
- id,
- type: header.tagName.toLowerCase(),
- top: top,
- active: this.selectedLinkId == id ? true : false,
- page: page,
- section: section
- });
- }
- }
- this.links = links;
- return links;
+ this.links = links;
+ })
}
goToStep(link: Link) {
- this.selectedLinkId = link.id;
+ // this.selectedLinkId = link.id;
this.stepFound.emit({
page: link.page,
section: link.section
@@ -210,7 +105,7 @@ export class TableOfContents implements OnInit, AfterViewInit, OnDestroy {
if (scrolledY) {
window.scroll(0, scrolledY - 70);
}
- }, 200);
+ }, 500);
}
}