diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html
index 5251bb0f2..be7a809cf 100644
--- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html
+++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html
@@ -54,7 +54,7 @@
0. {{'DMP-EDITOR.STEPPER.MAIN-INFO' | translate}} (done)
@@ -89,14 +89,14 @@
-
+
-
+
diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.html b/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.html
index e3c7aad22..198ceb6b8 100644
--- a/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.html
+++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.html
@@ -16,22 +16,34 @@
-
+
-
-
- {{pageEntry.numbering}} - {{pageEntry.label}}
-
+
-
+
diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.ts
index f1b19ef16..eb1071433 100644
--- a/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.ts
+++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.ts
@@ -44,7 +44,7 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit
// this.formChanged.emit(val);
// });
// }
-
+
this.tocentries = this.getTocEntries();
}
diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents-internal/table-of-contents-internal.html b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents-internal/table-of-contents-internal.html
new file mode 100644
index 000000000..d6168cd64
--- /dev/null
+++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents-internal/table-of-contents-internal.html
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+ {{entry.numbering}}. {{entry.label}}
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents-internal/table-of-contents-internal.scss b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents-internal/table-of-contents-internal.scss
new file mode 100644
index 000000000..6a9aa908d
--- /dev/null
+++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents-internal/table-of-contents-internal.scss
@@ -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;
+}
\ No newline at end of file
diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents-internal/table-of-contents-internal.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents-internal/table-of-contents-internal.ts
new file mode 100644
index 000000000..63070df1f
--- /dev/null
+++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents-internal/table-of-contents-internal.ts
@@ -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();
+
+ 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 {};
+ }
+}
diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.html b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.html
index b91593ca0..629f03eed 100644
--- a/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.html
+++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.html
@@ -9,3 +9,30 @@
+
+
+
+
\ No newline at end of file
diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.module.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.module.ts
index b28ec7804..bf99a7809 100644
--- a/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.module.ts
+++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.module.ts
@@ -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 { }
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 b346518fa..9a0092598 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
@@ -68,3 +68,8 @@ span {
.docs-level-h5 {
margin-left: 24px;
}
+
+// .internal-table-outer{
+// padding-left: 1.1em;
+// width: 100%;
+// }
\ No newline at end of file
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 917a80f55..608d9c5b0 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
@@ -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 = new Subject();
@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 = [];
+ 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 = [];
- 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 {