Show the same numbering in wizard and editor. Sorting by ordinal in wizard description

This commit is contained in:
Kristian Ntavidi 2021-03-09 10:04:50 +02:00
parent 51228df7d5
commit 2924db4409
11 changed files with 284 additions and 13 deletions

View File

@ -89,6 +89,14 @@
</div> </div>
<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 class="main-content"> <!-- <div class="main-content">
<div class="container-fluid"> <div class="container-fluid">

View File

@ -938,4 +938,11 @@ export class DatasetWizardComponent extends BaseComponent implements OnInit, IBr
getLinks(currentLinks: Link[]) { getLinks(currentLinks: Link[]) {
this.links = currentLinks; this.links = currentLinks;
} }
printForm(){
console.log(this.formGroup);
}
printFormValue(){
console.log(this.formGroup.value);
}
} }

View File

@ -4,7 +4,7 @@
<div *ngIf="form.get('fields').length === 1 && this.visibilityRulesService.checkElementVisibility(form.get('fields')['controls'][0].get('id').value)" class="col-12"> <div *ngIf="form.get('fields').length === 1 && this.visibilityRulesService.checkElementVisibility(form.get('fields')['controls'][0].get('id').value)" class="col-12">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<app-form-composite-title class="row" [form]="form" [isChild]="isChild"></app-form-composite-title> <app-form-composite-title [tocentry]="tocentry" class="row" [form]="form" [isChild]="isChild"></app-form-composite-title>
</div> </div>
<div class="col-12"> <div class="col-12">
<div class="row"> <div class="row">
@ -27,7 +27,7 @@
<div *ngIf="form.get('fields').length > 1" class="col-12"> <div *ngIf="form.get('fields').length > 1" class="col-12">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<app-form-composite-title class="row" [form]="form" [isChild]="isChild"></app-form-composite-title> <app-form-composite-title [tocentry]="tocentry" class="row" [form]="form" [isChild]="isChild"></app-form-composite-title>
</div> </div>
<div class="col align-self-center"> <div class="col align-self-center">
<div *ngFor="let fieldFormGroup of form.get('fields')['controls']; let i = index;" class="col-12 compositeField"> <div *ngFor="let fieldFormGroup of form.get('fields')['controls']; let i = index;" class="col-12 compositeField">

View File

@ -1,6 +1,7 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { FormArray, FormGroup, AbstractControl } from '@angular/forms'; import { FormArray, FormGroup, AbstractControl } from '@angular/forms';
import { DatasetDescriptionCompositeFieldEditorModel, DatasetDescriptionFieldEditorModel } from '../../dataset-description-form.model'; import { DatasetDescriptionCompositeFieldEditorModel, DatasetDescriptionFieldEditorModel } from '../../dataset-description-form.model';
import { ToCEntry } from '../../dataset-description.component';
import { VisibilityRulesService } from '../../visibility-rules/visibility-rules.service'; import { VisibilityRulesService } from '../../visibility-rules/visibility-rules.service';
@Component({ @Component({
@ -14,6 +15,7 @@ export class FormCompositeFieldComponent {
@Input() form: FormGroup; @Input() form: FormGroup;
@Input() isChild: Boolean = false; @Input() isChild: Boolean = false;
@Input() showDelete: Boolean = false; @Input() showDelete: Boolean = false;
@Input() tocentry: ToCEntry;
constructor( constructor(
public visibilityRulesService: VisibilityRulesService, public visibilityRulesService: VisibilityRulesService,
@ -22,6 +24,10 @@ export class FormCompositeFieldComponent {
} }
ngOnInit() { ngOnInit() {
if(this.tocentry){
this.form = this.tocentry.form as FormGroup;
}
} }
// addMultipleField(fieldIndex: number) { // addMultipleField(fieldIndex: number) {

View File

@ -1,7 +1,7 @@
<div class="col-12"> <div class="col-12">
<div class="row"> <div class="row">
<h5 *ngIf="form.get('title').value && !isChild" class="col-auto compositeField toc-compositeField-header" [id]="this.form.get('id').value"> <h5 *ngIf="form.get('title').value && !isChild" class="col-auto compositeField toc-compositeField-header" [id]="this.form.get('id').value">
{{form.get('numbering').value}} {{tocentry? tocentry.numbering :form.get('numbering').value}}
{{form.get('title').value}} {{form.get('title').value}}
<!-- <a *ngIf="this.markForConsiderationService.exists(compositeField)" (click)="markForConsideration()" style="cursor: pointer"> <!-- <a *ngIf="this.markForConsiderationService.exists(compositeField)" (click)="markForConsideration()" style="cursor: pointer">
Mark For Consideration Mark For Consideration

View File

@ -1,5 +1,6 @@
import { Component, OnInit, Input } from '@angular/core'; import { Component, OnInit, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { FormGroup } from '@angular/forms';
import { ToCEntry } from '../../dataset-description.component';
@Component({ @Component({
selector: 'app-form-composite-title', selector: 'app-form-composite-title',
@ -10,10 +11,14 @@ export class FormCompositeTitleComponent implements OnInit {
@Input() form: FormGroup; @Input() form: FormGroup;
@Input() isChild: Boolean = false; @Input() isChild: Boolean = false;
@Input() tocentry:ToCEntry;
constructor() { } constructor() { }
ngOnInit() { ngOnInit() {
if(this.tocentry){
this.form = this.tocentry.form as FormGroup;
}
} }
} }

View File

@ -3,12 +3,13 @@
<mat-expansion-panel class="row expansion-panel toc-section-header" [id]="pathName" [(expanded)]="panelExpanded"> <mat-expansion-panel class="row expansion-panel toc-section-header" [id]="pathName" [(expanded)]="panelExpanded">
<mat-expansion-panel-header> <mat-expansion-panel-header>
<mat-panel-title> <mat-panel-title>
<h6 class='panel-title'>{{form.get('numbering').value}}. {{form.get('title').value}}</h6> <h6 class='panel-title'>{{tocentry? tocentry.numbering :form.get('numbering').value}}. {{form.get('title').value}}</h6>
</mat-panel-title> </mat-panel-title>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<mat-panel-description class="col-12"> <mat-panel-description class="col-12">
<h6 class='panel-desc' *ngIf="form.get('description').value">{{form.get('description').value}}</h6> <h6 class='panel-desc' *ngIf="form.get('description').value">{{form.get('description').value}}</h6>
</mat-panel-description> </mat-panel-description>
<ng-container *ngIf="!tocentry else tocentryCase">
<div *ngFor="let compositeFieldFormGroup of form.get('compositeFields')['controls']; let i = index;" class="col-12"> <div *ngFor="let compositeFieldFormGroup of form.get('compositeFields')['controls']; let i = index;" class="col-12">
<!-- <div *ngIf="isElementVisible(compositeField)" class="row"> --> <!-- <div *ngIf="isElementVisible(compositeField)" class="row"> -->
<!-- *ngIf="this.visibilityRulesService.checkElementVisibility(compositeFieldFormGroup.get('id').value)" --> <!-- *ngIf="this.visibilityRulesService.checkElementVisibility(compositeFieldFormGroup.get('id').value)" -->
@ -54,6 +55,79 @@
[datasetProfileId]="datasetProfileId"></app-form-section> [datasetProfileId]="datasetProfileId"></app-form-section>
</div> </div>
</div> </div>
</ng-container>
</mat-expansion-panel> </mat-expansion-panel>
</mat-accordion> </mat-accordion>
</div> </div>
<!-- WORKING WITH TOCENTRIES -->
<ng-template #tocentryCase>
<ng-container [ngSwitch]="tocentry.subEntriesType">
<ng-container *ngSwitchCase="tocentriesType.FieldSet">
<!-- FIELDSET CASE -->
<div *ngFor="let fieldsetEntry of tocentry.subEntries; let i = index;" class="col-12">
<!-- <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)">
<div class="col-12">
<div class="row">
<app-form-composite-field [tocentry]="fieldsetEntry" class="align-self-center col" [form]="fieldsetEntry.form" [datasetProfileId]="datasetProfileId"
[isChild]="false" [showDelete]="(fieldsetEntry.form.get('multiplicityItems').length) > 0"></app-form-composite-field>
</div>
</div>
<div *ngIf="fieldsetEntry.form" class="col-12">
<div class="row">
<div class="col-12" *ngFor="let multipleCompositeFieldFormGroup of fieldsetEntry.form.get('multiplicityItems')['controls']; let j = index">
<div class="row">
<app-form-composite-field class=" align-self-center col" [form]="multipleCompositeFieldFormGroup" [datasetProfileId]="datasetProfileId"
[isChild]="true" [showDelete]="true"></app-form-composite-field>
</div>
</div>
<div *ngIf="(fieldsetEntry.form.get('multiplicity').value.max - 1) > (fieldsetEntry.form.get('multiplicityItems').length)"
class="col-12 addOneFieldButton">
<button mat-icon-button color="primary" (click)="addMultipleField(i)" [disabled]="fieldsetEntry.form.disabled" matTooltip="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.MULTIPLICITY-ADD-ONE-FIELD' | translate}}">
<mat-icon>add_circle</mat-icon>
</button>
</div>
<mat-form-field *ngIf="fieldsetEntry.form.get('hasCommentField').value" class="col-12 mb-2" [formGroup]="fieldsetEntry.form">
<input matInput formControlName="commentFieldValue" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.COMMENT-PLACEHOLDER' | translate}}">
<mat-hint>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.COMMENT-HINT' | translate}}</mat-hint>
</mat-form-field>
<!-- <div class="col"></div>
<button class="col-auto" mat-icon-button type="button" (click)="next(compositeField)">
<mat-icon>expand_more</mat-icon>
</button> -->
</div>
</div>
</div>
</div>
</ng-container>
<ng-container *ngSwitchCase="tocentriesType.Section">
<!-- SECTION CASE -->
<div *ngIf="form.get('sections')" class="col-12"><!-- MAYBEE NOT NEEDED-->
<div *ngFor="let sectionEntry of tocentry.subEntries; let j = index;" class="row">
<app-form-section class="col-12" [tocentry]="sectionEntry" [form]="sectionEntry.form" [path]="path+'.'+(j+1)" [pathName]="pathName+'.sections.'+j" [linkToScroll]="subsectionLinkToScroll"
[datasetProfileId]="datasetProfileId"></app-form-section>
</div>
</div>
</ng-container>
</ng-container>
</ng-template>

View File

@ -5,6 +5,8 @@ import { VisibilityRulesService } from '../../visibility-rules/visibility-rules.
import { DatasetDescriptionSectionEditorModel, DatasetDescriptionCompositeFieldEditorModel } from '../../dataset-description-form.model'; import { DatasetDescriptionSectionEditorModel, DatasetDescriptionCompositeFieldEditorModel } from '../../dataset-description-form.model';
import { FormCompositeFieldComponent } from '../form-composite-field/form-composite-field.component'; import { FormCompositeFieldComponent } from '../form-composite-field/form-composite-field.component';
import { LinkToScroll } from '../../tableOfContentsMaterial/table-of-contents'; import { LinkToScroll } from '../../tableOfContentsMaterial/table-of-contents';
import { ToCEntry, ToCEntryType } from '../../dataset-description.component';
@Component({ @Component({
selector: 'app-form-section', selector: 'app-form-section',
@ -16,6 +18,7 @@ export class FormSectionComponent implements OnInit, OnChanges {
//@Input() section: DatasetDescriptionSectionEditorModel; //@Input() section: DatasetDescriptionSectionEditorModel;
@Input() datasetProfileId: String; @Input() datasetProfileId: String;
@Input() form: FormGroup; @Input() form: FormGroup;
@Input() tocentry: ToCEntry;
@Input() pathName: string; @Input() pathName: string;
@Input() path: string; @Input() path: string;
@Input() linkToScroll: LinkToScroll; @Input() linkToScroll: LinkToScroll;
@ -24,6 +27,8 @@ export class FormSectionComponent implements OnInit, OnChanges {
// sub = true; // sub = true;
subsectionLinkToScroll: LinkToScroll; subsectionLinkToScroll: LinkToScroll;
tocentriesType = ToCEntryType;
constructor( constructor(
public visibilityRulesService: VisibilityRulesService, public visibilityRulesService: VisibilityRulesService,
private formFocusService: FormFocusService private formFocusService: FormFocusService
@ -33,6 +38,10 @@ export class FormSectionComponent implements OnInit, OnChanges {
// if (this.section) { // if (this.section) {
// this.form = this.visibilityRulesService.getFormGroup(this.section.id); // this.form = this.visibilityRulesService.getFormGroup(this.section.id);
// } // }
if(this.tocentry){//maybe not needed as well
this.form = this.tocentry.form as FormGroup;
}
} }
ngOnChanges(changes: SimpleChanges) { ngOnChanges(changes: SimpleChanges) {

View File

@ -64,6 +64,7 @@ export class DatasetDescriptionPageEditorModel extends BaseFormModel {
}); });
formGroup.addControl('sections', this.formBuilder.array(sectionsFormArray)); formGroup.addControl('sections', this.formBuilder.array(sectionsFormArray));
formGroup.addControl('title', new FormControl({ value: this.title, disabled: true })); formGroup.addControl('title', new FormControl({ value: this.title, disabled: true }));
formGroup.addControl('ordinal', new FormControl({value:this.ordinal, disabled:true}));
return formGroup; return formGroup;
} }
} }
@ -115,6 +116,7 @@ export class DatasetDescriptionSectionEditorModel extends BaseFormModel {
formGroup.addControl('numbering', new FormControl({ value: this.numbering, disabled: true })); formGroup.addControl('numbering', new FormControl({ value: this.numbering, disabled: true }));
formGroup.addControl('title', new FormControl({ value: this.title, disabled: true })); formGroup.addControl('title', new FormControl({ value: this.title, disabled: true }));
formGroup.addControl('id', new FormControl({ value: this.title, disabled: false })); formGroup.addControl('id', new FormControl({ value: this.title, disabled: false }));
formGroup.addControl('ordinal', new FormControl({ value: this.ordinal, disabled: true }));
return formGroup; return formGroup;
} }
} }

View File

@ -5,6 +5,7 @@
<div class="row"> <div class="row">
<div class="dynamic-form-editor p-0 col-md-12"> <div class="dynamic-form-editor p-0 col-md-12">
<div id="form-container"> <div id="form-container">
<ng-container *ngIf="!tocentries else toctemplate">
<div *ngFor="let pageFormGroup of form.get('pages')['controls']; let z = index;"> <div *ngFor="let pageFormGroup of form.get('pages')['controls']; let z = index;">
<div *ngFor="let sectionFormGroup of pageFormGroup.get('sections')['controls']; let i = index;"> <div *ngFor="let sectionFormGroup of pageFormGroup.get('sections')['controls']; let i = index;">
<div class="row"> <div class="row">
@ -14,6 +15,25 @@
</div> </div>
</div> </div>
</div> </div>
</ng-container>
<ng-template #toctemplate>
<!--FIRST LEVEL ALWAYS PAGE-->
<div *ngFor="let pageEntry of tocentries; let z = index;">
<h4 >
{{pageEntry.numbering}} - {{pageEntry.label}}
</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>
</div>
</ng-template>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,7 +1,8 @@
import { AfterViewInit, Component, Input, OnChanges, OnInit, SimpleChanges, ViewChild, Output, EventEmitter } from '@angular/core'; import { AfterViewInit, Component, Input, OnChanges, OnInit, SimpleChanges, ViewChild, Output, EventEmitter } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { AbstractControl, AbstractControlOptions, FormArray, FormGroup } from '@angular/forms';
import { MatHorizontalStepper } from '@angular/material/stepper'; import { MatHorizontalStepper } from '@angular/material/stepper';
import { Rule } from '@app/core/model/dataset-profile-definition/rule'; import { Rule } from '@app/core/model/dataset-profile-definition/rule';
import { DatasetProfileTableOfContentsInternalSection } from '@app/ui/admin/dataset-profile/table-of-contents/table-of-contents-internal-section/table-of-contents-internal-section';
import { LinkToScroll } from '@app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents'; import { LinkToScroll } from '@app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents';
import { VisibilityRulesService } from '@app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service'; import { VisibilityRulesService } from '@app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service';
import { BaseComponent } from '@common/base/base.component'; import { BaseComponent } from '@common/base/base.component';
@ -16,16 +17,22 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit
// @ViewChild('stepper', { static: false }) stepper: MatHorizontalStepper; // @ViewChild('stepper', { static: false }) stepper: MatHorizontalStepper;
@Input() path: string; @Input() path: string;
@Input() form: FormGroup;
@Input() visibilityRules: Rule[] = []; @Input() visibilityRules: Rule[] = [];
@Input() datasetProfileId: String; @Input() datasetProfileId: String;
@Input() linkToScroll: LinkToScroll; @Input() linkToScroll: LinkToScroll;
@Output() formChanged: EventEmitter<any> = new EventEmitter(); @Output() formChanged: EventEmitter<any> = new EventEmitter();
tocentries: ToCEntry[];
@Input() form: FormGroup;
private _form: FormGroup;
constructor( constructor(
private visibilityRulesService: VisibilityRulesService, private visibilityRulesService: VisibilityRulesService,
) { ) {
super(); super();
} }
ngOnInit() { ngOnInit() {
@ -37,6 +44,8 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit
// this.formChanged.emit(val); // this.formChanged.emit(val);
// }); // });
// } // }
this.tocentries = this.getTocEntries();
} }
ngOnChanges(changes: SimpleChanges) { ngOnChanges(changes: SimpleChanges) {
@ -54,4 +63,135 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit
ngAfterViewInit() { ngAfterViewInit() {
} }
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 &&sections.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 &&sections.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(): ToCEntry[] {
if (this.form == null) { return []; }
const result: ToCEntry[] = [];
//build parent pages
(this.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;
}
}
export interface ToCEntry {
id: string;
label: string;
subEntriesType: ToCEntryType;
subEntries: ToCEntry[];
type: ToCEntryType;
form: AbstractControl;
numbering: string;
ordinal: number;
}
export enum ToCEntryType {
Page = 0,
Section = 1,
FieldSet = 2,
Field = 3
} }