Dataset description and table-of-contents works with tocentries.
This commit is contained in:
parent
720fa60f9b
commit
ae378899e2
|
@ -54,7 +54,7 @@
|
|||
<div (click)="changeStep(0)" *ngIf="datasetInfoValid()" class="main-info" [ngClass]="{'active': this.step === 0}">0. {{'DMP-EDITOR.STEPPER.MAIN-INFO' | translate}} (<mat-icon class="done-icon">done</mat-icon>)</div>
|
||||
<div class="row toc-pane-container" #boundary (click)="changeStep(1)">
|
||||
<div #spacer></div>
|
||||
<table-of-contents class="toc-pane-container" [links]="links" [boundary]="boundary" [spacer]="spacer" [isActive]="step !== 0" stickyThing (stepFound)="onStepFound($event)" (currentLinks)="getLinks($event)"></table-of-contents>
|
||||
<table-of-contents [hasFocus]="step === 1" [formGroup]="formGroup" *ngIf="formGroup && formGroup.get('datasetProfileDefinition')" [links]="links" [boundary]="boundary" [spacer]="spacer" [isActive]="step !== 0" stickyThing (stepFound)="onStepFound($event)" (currentLinks)="getLinks($event)" [visibilityRules]="formGroup.get('datasetProfileDefinition').get('rules').value"></table-of-contents>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -89,14 +89,14 @@
|
|||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<!-- <div class="row">
|
||||
<div class="col-12">
|
||||
<button (click)="printForm()">Print form</button>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button (click)="printFormValue()">Print form value</button>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- <div class="main-content">
|
||||
<div class="container-fluid">
|
||||
|
|
|
@ -277,6 +277,7 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - 246px);
|
||||
max-width: 366px;
|
||||
}
|
||||
|
||||
.stepper-options {
|
||||
|
@ -316,6 +317,8 @@
|
|||
|
||||
.stepper-list {
|
||||
.toc-pane-container {
|
||||
padding-left: 0.2rem;
|
||||
overflow-x: hidden;
|
||||
span {
|
||||
text-align: left;
|
||||
font-weight: 400;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { FormArray, FormControl, FormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
@ -45,6 +45,7 @@ import { SaveType } from '@app/core/common/enum/save-type';
|
|||
import { DatasetWizardModel } from '@app/core/model/dataset/dataset-wizard';
|
||||
import { MatomoService } from '@app/core/services/matomo/matomo-service';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { ToCEntry, ToCEntryType } from '@app/ui/misc/dataset-description-form/dataset-description.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dataset-wizard-component',
|
||||
|
@ -886,18 +887,28 @@ export class DatasetWizardComponent extends BaseComponent implements OnInit, IBr
|
|||
}
|
||||
|
||||
public changeStep(index: number, dataset?: FormControl) {
|
||||
if(this.step != index){ //view is changing
|
||||
this.resetScroll();
|
||||
}
|
||||
this.step = index;
|
||||
this.resetScroll();
|
||||
}
|
||||
|
||||
public nextStep() {
|
||||
this.step = this.step < this.maxStep ? this.step + 1 : this.step;
|
||||
this.resetScroll();
|
||||
if(this.step < this.maxStep){//view is changing
|
||||
this.step +=1;
|
||||
this.resetScroll();
|
||||
}
|
||||
// this.step = this.step < this.maxStep ? this.step + 1 : this.step;
|
||||
}
|
||||
|
||||
public previousStep() {
|
||||
this.step = this.step !== 0 ? this.step - 1 : this.step;
|
||||
this.resetScroll();
|
||||
if(this.step !== 0){
|
||||
|
||||
this.resetScroll();
|
||||
this.step =-1;
|
||||
}
|
||||
|
||||
// this.step = this.step !== 0 ? this.step - 1 : this.step;
|
||||
}
|
||||
|
||||
private resetScroll() {
|
||||
|
@ -945,4 +956,133 @@ export class DatasetWizardComponent extends BaseComponent implements OnInit, IBr
|
|||
printFormValue(){
|
||||
console.log(this.formGroup.value);
|
||||
}
|
||||
|
||||
// tocentries;
|
||||
// this.tocentries = this.getTocEntries(this.formGroup.get('datasetProfileDefinition')); //TODO
|
||||
|
||||
|
||||
|
||||
// get tocentries(){
|
||||
// const form = this.formGroup.get('datasetProfileDefinition')
|
||||
// if(!form) return null;
|
||||
|
||||
// return this.getTocEntries(this.formGroup.get('datasetProfileDefinition'));
|
||||
// }
|
||||
|
||||
|
||||
// private _buildRecursively(form: FormGroup,whatAmI:ToCEntryType):ToCEntry{
|
||||
// if(!form) return null;
|
||||
|
||||
// switch(whatAmI){
|
||||
// case ToCEntryType.Section:
|
||||
// const sections = form.get('sections') as FormArray;
|
||||
// const fieldsets = form.get('compositeFields') as FormArray;
|
||||
|
||||
|
||||
// const tempResult:ToCEntry[] = [];
|
||||
|
||||
// if(sections &§ions.length){
|
||||
// sections.controls.forEach(section=>{
|
||||
// tempResult.push(this._buildRecursively(section as FormGroup, ToCEntryType.Section));
|
||||
// });
|
||||
|
||||
// }else if(fieldsets && fieldsets.length){
|
||||
// fieldsets.controls.forEach(fieldset=>{
|
||||
// tempResult.push(this._buildRecursively(fieldset as FormGroup, ToCEntryType.FieldSet));
|
||||
// });
|
||||
// }
|
||||
// return {
|
||||
// form: form,
|
||||
// id: form.get('id').value,
|
||||
// label: form.get('title').value,
|
||||
// numbering: '',
|
||||
// subEntries:tempResult,
|
||||
// subEntriesType: sections &§ions.length? ToCEntryType.Section: ToCEntryType.FieldSet,
|
||||
// type: ToCEntryType.Section,
|
||||
// ordinal: form.get('ordinal').value
|
||||
// }
|
||||
// case ToCEntryType.FieldSet:
|
||||
// return {
|
||||
// form: form,
|
||||
// label:form.get('title').value,
|
||||
// id: form.get('id').value,
|
||||
// numbering:'s',
|
||||
// subEntries:[],
|
||||
// subEntriesType: ToCEntryType.Field,
|
||||
// type: ToCEntryType.FieldSet,
|
||||
// ordinal: form.get('ordinal').value
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// private _sortByOrdinal(tocentries: ToCEntry[]){
|
||||
|
||||
// if(!tocentries || !tocentries.length) return;
|
||||
|
||||
// tocentries.sort(this._customCompare);
|
||||
// tocentries.forEach(entry=>{
|
||||
// this._sortByOrdinal(entry.subEntries);
|
||||
// });
|
||||
// }
|
||||
|
||||
// private _customCompare(a,b){
|
||||
// return a.ordinal - b.ordinal;
|
||||
// }
|
||||
|
||||
// private _calculateNumbering(tocentries: ToCEntry[], depth:number[] = []){
|
||||
// if(!tocentries || !tocentries.length){
|
||||
// return;
|
||||
// }
|
||||
|
||||
// let prefixNumbering = depth.length? depth.join('.'): '';
|
||||
|
||||
// if(depth.length) prefixNumbering = prefixNumbering+".";
|
||||
// tocentries.forEach((entry,i)=>{
|
||||
// entry.numbering = prefixNumbering + (i+1);
|
||||
// this._calculateNumbering(entry.subEntries, [...depth, i+1])
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
// getTocEntries(form): ToCEntry[] {
|
||||
// if (form == null) { return []; }
|
||||
// const result: ToCEntry[] = [];
|
||||
|
||||
// //build parent pages
|
||||
// (form.get('pages') as FormArray).controls.forEach((pageElement, i) => {
|
||||
// result.push({
|
||||
// id: i+'id',
|
||||
// label: pageElement.get('title').value,
|
||||
// type: ToCEntryType.Page,
|
||||
// form: pageElement,
|
||||
// numbering: (i + 1).toString(),
|
||||
// subEntriesType: ToCEntryType.Section,
|
||||
// subEntries:[],
|
||||
// ordinal: pageElement.get('ordinal').value
|
||||
// } as ToCEntry)
|
||||
// });
|
||||
|
||||
|
||||
|
||||
// result.forEach((entry,i)=>{
|
||||
|
||||
// const sections = entry.form.get('sections') as FormArray;
|
||||
|
||||
// sections.controls.forEach(section=>{
|
||||
// const tempResults = this._buildRecursively(section as FormGroup,ToCEntryType.Section);
|
||||
// entry.subEntries.push(tempResults);
|
||||
// });
|
||||
|
||||
// });
|
||||
|
||||
// this._sortByOrdinal(result);
|
||||
// //calculate numbering
|
||||
// this._calculateNumbering(result);
|
||||
// return result;
|
||||
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
<ng-container *ngSwitchCase="tocentriesType.FieldSet">
|
||||
|
||||
<!-- FIELDSET CASE -->
|
||||
<div *ngFor="let fieldsetEntry of tocentry.subEntries; let i = index;" class="col-12">
|
||||
<div *ngFor="let fieldsetEntry of tocentry.subEntries; let i = index;" class="col-12" [id]="fieldsetEntry.id">
|
||||
<!-- <div *ngIf="isElementVisible(compositeField)" class="row"> -->
|
||||
<!-- *ngIf="this.visibilityRulesService.checkElementVisibility(compositeFieldFormGroup.get('id').value)" -->
|
||||
<div class="row" *ngIf="this.visibilityRulesService.checkElementVisibility(fieldsetEntry.form.get('id').value) && this.visibilityRulesService.scanIfChildsOfCompositeFieldHasVisibleItems(fieldsetEntry.form)">
|
||||
|
|
|
@ -16,22 +16,34 @@
|
|||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<!-- TOCENTRIES -->
|
||||
<ng-template #toctemplate>
|
||||
<!--FIRST LEVEL ALWAYS PAGE-->
|
||||
<div *ngFor="let pageEntry of tocentries; let z = index;">
|
||||
<h4 >
|
||||
{{pageEntry.numbering}} - {{pageEntry.label}}
|
||||
</h4>
|
||||
<mat-accordion [multi]="true">
|
||||
|
||||
<div *ngFor="let sectionEntry of pageEntry.subEntries; let i = index;">
|
||||
<div class="row">
|
||||
<app-form-section class="col-12" [tocentry]="sectionEntry" [path]="z+1"
|
||||
[pathName]="'pages.'+z+'.sections.'+i" [datasetProfileId]="datasetProfileId"
|
||||
[linkToScroll]="linkToScroll"></app-form-section>
|
||||
</div>
|
||||
<div *ngFor="let pageEntry of tocentries; let z = index;">
|
||||
<mat-expansion-panel [expanded]="true">
|
||||
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
<h4 class="panel-title toc-page-header">
|
||||
{{pageEntry.numbering}}. {{pageEntry.label |uppercase}}
|
||||
</h4>
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<!--
|
||||
<h4 class="toc-page-header">
|
||||
</h4> -->
|
||||
<div *ngFor="let sectionEntry of pageEntry.subEntries; let i = index;">
|
||||
<div class="row">
|
||||
<app-form-section class="col-12" [tocentry]="sectionEntry" [path]="z+1"
|
||||
[pathName]="'pages.'+z+'.sections.'+i" [datasetProfileId]="datasetProfileId"
|
||||
[linkToScroll]="linkToScroll"></app-form-section>
|
||||
</div>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
</div>
|
||||
</div>
|
||||
</mat-accordion>
|
||||
</ng-template>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -44,7 +44,7 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit
|
|||
// this.formChanged.emit(val);
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
this.tocentries = this.getTocEntries();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<div *ngFor="let entry of tocentries; index as idx">
|
||||
<!-- check if is visible -->
|
||||
<ng-container *ngIf="visibilityRulesService.checkElementVisibility(entry.id)">
|
||||
|
||||
<!-- Is fieldset and has no visible inputs -->
|
||||
<ng-container *ngIf="!(entry.type === tocEntryTypeEnum.FieldSet && !visibilityRulesService.scanIfChildsOfCompositeFieldHasVisibleItems(entry.form))">
|
||||
|
||||
<span class="table-entry"
|
||||
(click)="toggleExpand(idx);navigateToFieldSet(entry, $event); onEntrySelected(entry)"
|
||||
[ngStyle]="calculateStyle(entry)"
|
||||
[ngClass]="calculateClass(entry)"
|
||||
>
|
||||
{{entry.numbering}}. {{entry.label}}
|
||||
<!-- <ng-container *ngIf="entry.subEntries && entry.subEntries.length && !expandChildren[idx]">
|
||||
<small>
|
||||
({{entry.subEntries.length}})
|
||||
</small>
|
||||
|
||||
</ng-container> -->
|
||||
</span>
|
||||
<!-- <div class="table-entry-container">
|
||||
</div> -->
|
||||
<div class="internal-table">
|
||||
<table-of-contents-internal
|
||||
[tocentries]="entry.subEntries"
|
||||
*ngIf="entry.subEntries && entry.subEntries.length && expandChildren[idx]"
|
||||
(entrySelected)="onEntrySelected($event)"
|
||||
[selected]="selected">
|
||||
|
||||
</table-of-contents-internal>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
|
||||
|
||||
</ng-container>
|
||||
|
||||
</div>
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
.internal-table{
|
||||
margin-left: 1.2em;
|
||||
// width: inherit;
|
||||
}
|
||||
// .table-entry-container{
|
||||
// // overflow: hidden;
|
||||
// // width: inherit;
|
||||
// }
|
||||
.table-entry{
|
||||
cursor: pointer;
|
||||
// display: block;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
// overflow: hidden;
|
||||
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
transition: color 100ms;
|
||||
}
|
||||
|
||||
.table-entry:hover{
|
||||
background-color: #ececec;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.selected {
|
||||
color: #212121 !important;
|
||||
font-weight: 700 !important;
|
||||
opacity: 1 !important;
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
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, ToCEntryType } from '../../dataset-description.component';
|
||||
import { VisibilityRulesService } from '../../visibility-rules/visibility-rules.service';
|
||||
import { Rule } from '@app/core/model/dataset-profile-definition/rule';
|
||||
|
||||
@Component({
|
||||
selector: 'table-of-contents-internal',
|
||||
styleUrls: ['./table-of-contents-internal.scss'],
|
||||
templateUrl: './table-of-contents-internal.html'
|
||||
})
|
||||
export class TableOfContentsInternal implements OnInit {
|
||||
|
||||
@Input() tocentries: ToCEntry[] = null;
|
||||
@Input() selected: ToCEntry = null;
|
||||
// @Input() visibilityRules:Rule[] = [];
|
||||
@Output() entrySelected = new EventEmitter<ToCEntry>();
|
||||
|
||||
expandChildren:boolean[];
|
||||
tocEntryTypeEnum = ToCEntryType;
|
||||
|
||||
|
||||
constructor(public visibilityRulesService: VisibilityRulesService){
|
||||
|
||||
|
||||
}
|
||||
ngOnInit(): void {
|
||||
// console.log('component created');
|
||||
if(this.tocentries){
|
||||
this.expandChildren = this.tocentries.map(()=>false);
|
||||
}
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
// if (!this.isActive && this.links && this.links.length > 0) {
|
||||
// this.links.forEach(link => {
|
||||
// link.selected = false;
|
||||
// })
|
||||
// this.links[0].selected = true;
|
||||
// }
|
||||
}
|
||||
|
||||
toggleExpand(index){
|
||||
this.expandChildren[index] = !this.expandChildren[index];
|
||||
// console.log(this.expandChildren);
|
||||
}
|
||||
|
||||
navigateToFieldSet(entry:ToCEntry, event){
|
||||
if(entry.type === ToCEntryType.FieldSet){
|
||||
|
||||
const fieldSetId = entry.id;
|
||||
const element = document.getElementById(fieldSetId);
|
||||
if(element){
|
||||
element.scrollIntoView({behavior:'smooth'});
|
||||
// event.stopPropagation();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onEntrySelected(entry:ToCEntry){
|
||||
this.entrySelected.emit(entry);
|
||||
}
|
||||
|
||||
|
||||
calculateStyle(entry: ToCEntry){
|
||||
const style = {};
|
||||
style['font-size'] = entry.type ===this.tocEntryTypeEnum.FieldSet? '.9em': '1em';
|
||||
return style;
|
||||
}
|
||||
|
||||
calculateClass(entry:ToCEntry){
|
||||
|
||||
if(this.selected && entry.id === this.selected.id){
|
||||
return{'selected': true};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
|
@ -9,3 +9,30 @@
|
|||
<!-- </nav> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<ng-container *ngIf="tocentries">
|
||||
|
||||
<div class="internal-table-outer col-12">
|
||||
<table-of-contents-internal [tocentries]="tocentries"
|
||||
(entrySelected)="onToCentrySelected($event)"
|
||||
[selected]="tocentrySelected"
|
||||
|
||||
>
|
||||
|
||||
</table-of-contents-internal>
|
||||
</div>
|
||||
</ng-container> -->
|
||||
|
||||
<div *ngIf="tocentries" class="docs-toc-container">
|
||||
|
||||
<div class="scroll-container col-12">
|
||||
<table-of-contents-internal [tocentries]="tocentries"
|
||||
(entrySelected)="onToCentrySelected($event)"
|
||||
[selected]="tocentrySelected"
|
||||
|
||||
>
|
||||
|
||||
</table-of-contents-internal>
|
||||
</div>
|
||||
</div>
|
|
@ -2,11 +2,14 @@ import {CommonModule} from '@angular/common';
|
|||
import {NgModule} from '@angular/core';
|
||||
import {TableOfContents} from './table-of-contents';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import { TableOfContentsInternal } from './table-of-contents-internal/table-of-contents-internal';
|
||||
import { VisibilityRulesService } from '../visibility-rules/visibility-rules.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, RouterModule],
|
||||
declarations: [TableOfContents],
|
||||
declarations: [TableOfContents, TableOfContentsInternal],
|
||||
exports: [TableOfContents],
|
||||
entryComponents: [TableOfContents],
|
||||
providers:[VisibilityRulesService]
|
||||
})
|
||||
export class TableOfContentsModule { }
|
||||
|
|
|
@ -68,3 +68,8 @@ span {
|
|||
.docs-level-h5 {
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
// .internal-table-outer{
|
||||
// padding-left: 1.1em;
|
||||
// width: 100%;
|
||||
// }
|
|
@ -5,6 +5,10 @@ import { interval, Subject, Subscription } from 'rxjs';
|
|||
import { distinctUntilChanged } from 'rxjs/operators';
|
||||
import { type } from 'os';
|
||||
import { SimpleChanges } from '@angular/core';
|
||||
import { ToCEntry, ToCEntryType } from '../dataset-description.component';
|
||||
import { FormArray, FormGroup } from '@angular/forms';
|
||||
import { VisibilityRulesService } from '../visibility-rules/visibility-rules.service';
|
||||
import { Rule } from '@app/core/model/dataset-profile-definition/rule';
|
||||
|
||||
export interface Link {
|
||||
/* id of the section*/
|
||||
|
@ -39,72 +43,99 @@ export class TableOfContents extends BaseComponent implements OnInit {
|
|||
linksSubject: Subject<HTMLElement[]> = new Subject<HTMLElement[]>();
|
||||
|
||||
@Input() isActive: boolean;
|
||||
|
||||
tocentries: ToCEntry[] = null;
|
||||
// visibilityRules:Rule[] = [];
|
||||
@Input() visibilityRules:Rule[] = [];
|
||||
|
||||
private _tocentrySelected:ToCEntry = null;
|
||||
get tocentrySelected(){
|
||||
|
||||
return this.hasFocus?this._tocentrySelected: null;
|
||||
}
|
||||
set tocentrySelected(value){
|
||||
this._tocentrySelected = value;
|
||||
}
|
||||
|
||||
@Input() formGroup: FormGroup;
|
||||
@Input() hasFocus: boolean = false;
|
||||
show: boolean = false;
|
||||
|
||||
constructor(
|
||||
@Inject(DOCUMENT) private _document: Document) {
|
||||
@Inject(DOCUMENT) private _document: Document,
|
||||
public visibilityRulesService: VisibilityRulesService
|
||||
) {
|
||||
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.formGroup){
|
||||
this.tocentries = this.getTocEntries(this.formGroup.get('datasetProfileDefinition'));
|
||||
const fg = this.formGroup.get('datasetProfileDefinition');
|
||||
this.visibilityRulesService.buildVisibilityRules(this.visibilityRules, fg);
|
||||
|
||||
}else{
|
||||
|
||||
//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 (!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;
|
||||
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
|
||||
});
|
||||
}
|
||||
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;
|
||||
})
|
||||
this.links = links;
|
||||
// Initialize selected for button next on dataset wizard component editor
|
||||
this.links.length > 0 ? this.links[0].selected = true : null;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -158,6 +189,125 @@ export class TableOfContents extends BaseComponent implements OnInit {
|
|||
// return +link.id.split("_", 2)[1];
|
||||
// }
|
||||
|
||||
|
||||
private _buildRecursively(form: FormGroup,whatAmI:ToCEntryType):ToCEntry{
|
||||
if(!form) return null;
|
||||
|
||||
switch(whatAmI){
|
||||
case ToCEntryType.Section:
|
||||
const sections = form.get('sections') as FormArray;
|
||||
const fieldsets = form.get('compositeFields') as FormArray;
|
||||
|
||||
|
||||
const tempResult:ToCEntry[] = [];
|
||||
|
||||
if(sections &§ions.length){
|
||||
sections.controls.forEach(section=>{
|
||||
tempResult.push(this._buildRecursively(section as FormGroup, ToCEntryType.Section));
|
||||
});
|
||||
|
||||
}else if(fieldsets && fieldsets.length){
|
||||
fieldsets.controls.forEach(fieldset=>{
|
||||
tempResult.push(this._buildRecursively(fieldset as FormGroup, ToCEntryType.FieldSet));
|
||||
});
|
||||
}
|
||||
return {
|
||||
form: form,
|
||||
id: form.get('id').value,
|
||||
label: form.get('title').value,
|
||||
numbering: '',
|
||||
subEntries:tempResult,
|
||||
subEntriesType: sections &§ions.length? ToCEntryType.Section: ToCEntryType.FieldSet,
|
||||
type: ToCEntryType.Section,
|
||||
ordinal: form.get('ordinal').value
|
||||
}
|
||||
case ToCEntryType.FieldSet:
|
||||
return {
|
||||
form: form,
|
||||
label:form.get('title').value,
|
||||
id: form.get('id').value,
|
||||
numbering:'s',
|
||||
subEntries:[],
|
||||
subEntriesType: ToCEntryType.Field,
|
||||
type: ToCEntryType.FieldSet,
|
||||
ordinal: form.get('ordinal').value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _sortByOrdinal(tocentries: ToCEntry[]){
|
||||
|
||||
if(!tocentries || !tocentries.length) return;
|
||||
|
||||
tocentries.sort(this._customCompare);
|
||||
tocentries.forEach(entry=>{
|
||||
this._sortByOrdinal(entry.subEntries);
|
||||
});
|
||||
}
|
||||
|
||||
private _customCompare(a,b){
|
||||
return a.ordinal - b.ordinal;
|
||||
}
|
||||
|
||||
private _calculateNumbering(tocentries: ToCEntry[], depth:number[] = []){
|
||||
if(!tocentries || !tocentries.length){
|
||||
return;
|
||||
}
|
||||
|
||||
let prefixNumbering = depth.length? depth.join('.'): '';
|
||||
|
||||
if(depth.length) prefixNumbering = prefixNumbering+".";
|
||||
tocentries.forEach((entry,i)=>{
|
||||
entry.numbering = prefixNumbering + (i+1);
|
||||
this._calculateNumbering(entry.subEntries, [...depth, i+1])
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
getTocEntries(form): ToCEntry[] {
|
||||
if (form == null) { return []; }
|
||||
const result: ToCEntry[] = [];
|
||||
|
||||
//build parent pages
|
||||
(form.get('pages') as FormArray).controls.forEach((pageElement, i) => {
|
||||
result.push({
|
||||
id: i+'id',
|
||||
label: pageElement.get('title').value,
|
||||
type: ToCEntryType.Page,
|
||||
form: pageElement,
|
||||
numbering: (i + 1).toString(),
|
||||
subEntriesType: ToCEntryType.Section,
|
||||
subEntries:[],
|
||||
ordinal: pageElement.get('ordinal').value
|
||||
} as ToCEntry)
|
||||
});
|
||||
|
||||
|
||||
|
||||
result.forEach((entry,i)=>{
|
||||
|
||||
const sections = entry.form.get('sections') as FormArray;
|
||||
|
||||
sections.controls.forEach(section=>{
|
||||
const tempResults = this._buildRecursively(section as FormGroup,ToCEntryType.Section);
|
||||
entry.subEntries.push(tempResults);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
this._sortByOrdinal(result);
|
||||
//calculate numbering
|
||||
this._calculateNumbering(result);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
onToCentrySelected(entry: ToCEntry){
|
||||
this.tocentrySelected = entry;
|
||||
// console.log('entry selected', entry);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
export interface LinkToScroll {
|
||||
|
|
Loading…
Reference in New Issue