Commit 4c22799f authored by Kristian Ntavidi's avatar Kristian Ntavidi
Browse files

Bug fixes on dataset templates editor Admin (partial)

* Make use of observables instead of setTimeouts
* Remove not nessecary calculations
parent 1d397d28
......@@ -76,46 +76,40 @@
</mat-form-field>
</div>
</div>
<div style="position: relative;" class="col-12">
<ng-container *ngIf="hasFocus">
<div class="row" *ngIf="showDescription">
<mat-form-field class="col p-0 underline-line-field" appearance="legacy">
<input matInput type="text" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.DESCRIPTION' | translate}}"
[formControl]="this.form.get('description')">
</mat-form-field>
</div>
<div class="row" *ngIf="showExtendedDescription">
<mat-form-field class="col p-0 underline-line-field" appearance="legacy">
<input matInput type="text" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.EXTENDED-DESCRIPTION' | translate}}"
[formControl]="this.form.get('extendedDescription')"/>
</mat-form-field>
</div>
<div class="row" *ngIf="showAdditionalInfo">
<mat-form-field class="col p-0 underline-line-field" appearance="legacy">
<input matInput type="text" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.ADDITIONAL-INFORMATION' | translate}}"
[formControl]="this.form.get('additionalInformation')"/>
</mat-form-field>
</div>
<div class="row">
<mat-form-field *ngIf="isMultiplicityEnabled" class="col pl-0 underline-line-field" appearance="legacy">
<input matInput placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.MULTIPLICITY-MIN' | translate}}"
type="number" [formControl]="form.get('multiplicity').get('min')" required>
<mat-error *ngIf="form.get('multiplicity').get('min').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
</mat-error>
</mat-form-field>
<mat-form-field *ngIf="isMultiplicityEnabled" class="col pr-0 underline-line-field" appearance="legacy">
<input matInput placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.MULTIPLICITY-MAX' | translate}}"
type="number" [formControl]="this.form.get('multiplicity').get('max')" required>
<mat-error *ngIf="form.get('multiplicity').get('max').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
</mat-error>
</mat-form-field>
</div>
</ng-container>
<div style="position: relative;" class="col-12" *ngIf="hasFocus">
<div class="row" *ngIf="showDescription">
<mat-form-field class="col p-0 underline-line-field" appearance="legacy">
<input matInput type="text" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.DESCRIPTION' | translate}}"
[formControl]="this.form.get('description')">
</mat-form-field>
</div>
<div class="row" *ngIf="showExtendedDescription">
<mat-form-field class="col p-0 underline-line-field" appearance="legacy">
<input matInput type="text" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.EXTENDED-DESCRIPTION' | translate}}"
[formControl]="this.form.get('extendedDescription')"/>
</mat-form-field>
</div>
<div class="row" *ngIf="showAdditionalInfo">
<mat-form-field class="col p-0 underline-line-field" appearance="legacy">
<input matInput type="text" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.ADDITIONAL-INFORMATION' | translate}}"
[formControl]="this.form.get('additionalInformation')"/>
</mat-form-field>
</div>
<div class="row">
<mat-form-field *ngIf="isMultiplicityEnabled" class="col pl-0 underline-line-field" appearance="legacy">
<input matInput placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.MULTIPLICITY-MIN' | translate}}"
type="number" [formControl]="form.get('multiplicity').get('min')" required>
<mat-error *ngIf="form.get('multiplicity').get('min').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
</mat-error>
</mat-form-field>
<mat-form-field *ngIf="isMultiplicityEnabled" class="col pr-0 underline-line-field" appearance="legacy">
<input matInput placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.MULTIPLICITY-MAX' | translate}}"
type="number" [formControl]="this.form.get('multiplicity').get('max')" required>
<mat-error *ngIf="form.get('multiplicity').get('max').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
</mat-error>
</mat-form-field>
</div>
</div>
......@@ -123,59 +117,56 @@
<div class="row">
<!-- FIELDS -->
<div class="col">
<div>
<ng-container *ngFor="let field of form.get('fields')['controls']; let i=index" >
<div class="row bg-white" style="position: relative;" (click)="setTargetField(field)"
>
<!-- field-container -->
<!-- [ngClass]="{'field-container-active': (field.get('id').value === targetField?.get('id').value) && hasFocus}" -->
<!-- <div class="field-id-container">
{{form.get('fields').get(''+i).get('id').value}} -->
<!-- <button mat-mini-fab class="field-id-container-icon" (click)="DeleteField(i)">
<mat-icon>delete</mat-icon>
</button> -->
<!-- </div> -->
<!-- *ngIf="!isComposite" -->
<app-dataset-profile-editor-field-component class="col-12"
[form]="form.get('fields').get(''+i)" [showOrdinal]="false"
[indexPath]="indexPath + 'f' + i" [viewOnly]="viewOnly"
[expandView]="hasFocus"
[canBeDeleted]="form.get('fields')['controls'].length !=1"
(delete)="deleteField(i)">
</app-dataset-profile-editor-field-component>
</div>
<hr *ngIf="hasFocus">
</ng-container>
<!--
<div *ngIf="isComposite" class="row">
<h4 class="col-12 titleStile">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.SUB-FIELDS-TITLE' | translate}}
</h4>
<div class="col-12">
<mat-expansion-panel *ngFor="let field of form.get('fields')['controls'] let i=index;" #panel class="field-container">
<div class="field-id-container">
random id
</div>
<mat-expansion-panel-header>
<mat-panel-title class="cardTitle">{{i + 1}}. {{getFieldTile(field, i)}}</mat-panel-title>
<div class="row">
<button mat-icon-button type="button" class="deleteBtn col-auto" (click)="DeleteField(i);" [disabled]="viewOnly">
<mat-icon>delete</mat-icon>
</button>
</div>
</mat-expansion-panel-header>
<div id="{{indexPath + 'f' + i}}" *ngIf="panel.expanded">
<app-dataset-profile-editor-field-component [form]="form.get('fields').get(''+i)" [indexPath]="indexPath + 'f' + i" [viewOnly]="viewOnly"></app-dataset-profile-editor-field-component>
<div class="col-12" *ngIf="hasFocus">
<ng-container *ngFor="let field of form.get('fields')['controls']; let i=index" >
<div class="row bg-white" style="position: relative;" (click)="setTargetField(field)"
>
<!-- field-container -->
<!-- [ngClass]="{'field-container-active': (field.get('id').value === targetField?.get('id').value) && hasFocus}" -->
<!-- <div class="field-id-container">
{{form.get('fields').get(''+i).get('id').value}} -->
<!-- <button mat-mini-fab class="field-id-container-icon" (click)="DeleteField(i)">
<mat-icon>delete</mat-icon>
</button> -->
<!-- </div> -->
<!-- *ngIf="!isComposite" -->
<app-dataset-profile-editor-field-component class="col-12"
[form]="form.get('fields').get(''+i)" [showOrdinal]="false"
[indexPath]="indexPath + 'f' + i" [viewOnly]="viewOnly"
[expandView]="hasFocus"
[canBeDeleted]="form.get('fields')['controls'].length !=1"
(delete)="deleteField(i)">
</app-dataset-profile-editor-field-component>
</div>
<hr>
</ng-container>
<!--
<div *ngIf="isComposite" class="row">
<h4 class="col-12 titleStile">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.SUB-FIELDS-TITLE' | translate}}
</h4>
<div class="col-12">
<mat-expansion-panel *ngFor="let field of form.get('fields')['controls'] let i=index;" #panel class="field-container">
<div class="field-id-container">
random id
</div>
<mat-expansion-panel-header>
<mat-panel-title class="cardTitle">{{i + 1}}. {{getFieldTile(field, i)}}</mat-panel-title>
<div class="row">
<button mat-icon-button type="button" class="deleteBtn col-auto" (click)="DeleteField(i);" [disabled]="viewOnly">
<mat-icon>delete</mat-icon>
</button>
</div>
</mat-expansion-panel>
</div>
<div class="col-12">
<button mat-button class="full-width" (click)="addNewField()" [disabled]="viewOnly">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.ACTIONS.ADD-CHILD-FIELD' | translate}}</button>
</div>
</div> -->
</div>
</mat-expansion-panel-header>
<div id="{{indexPath + 'f' + i}}" *ngIf="panel.expanded">
<app-dataset-profile-editor-field-component [form]="form.get('fields').get(''+i)" [indexPath]="indexPath + 'f' + i" [viewOnly]="viewOnly"></app-dataset-profile-editor-field-component>
</div>
</mat-expansion-panel>
</div>
<div class="col-12">
<button mat-button class="full-width" (click)="addNewField()" [disabled]="viewOnly">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.ACTIONS.ADD-CHILD-FIELD' | translate}}</button>
</div>
</div> -->
</div>
<!-- PREVIEW -->
......
......@@ -21,8 +21,9 @@ import { AutoCompleteFieldData, BooleanDecisionFieldData, CheckBoxFieldData, Cur
import { CompositeField } from '@app/core/model/dataset-profile-definition/composite-field';
import {Field as FieldDefinition} from '@app/core/model/dataset-profile-definition/field';
import { Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import { debounceTime, delay, map, takeUntil, tap } from 'rxjs/operators';
import { GENERAL_ANIMATIONS } from '../../animations/animations';
import { BaseComponent } from '@common/base/base.component';
@Component({
selector: 'app-dataset-profile-editor-composite-field-component',
......@@ -30,7 +31,7 @@ import { GENERAL_ANIMATIONS } from '../../animations/animations';
styleUrls: ['./dataset-profile-editor-composite-field.component.scss'],
animations:[GENERAL_ANIMATIONS]
})
export class DatasetProfileEditorCompositeFieldComponent implements OnInit, OnChanges {
export class DatasetProfileEditorCompositeFieldComponent extends BaseComponent implements OnInit, OnChanges {
@Input() form: FormGroup;
@Input() indexPath: string;
......@@ -61,7 +62,9 @@ export class DatasetProfileEditorCompositeFieldComponent implements OnInit, OnCh
private language: TranslateService,
public enumUtils: EnumUtils,
public datasetProfileService: DatasetProfileService
) { }
) {
super();
}
ngOnChanges(){
// this.setTargetField(null);
......@@ -112,16 +115,52 @@ export class DatasetProfileEditorCompositeFieldComponent implements OnInit, OnCh
this.showExtendedDescription = !!this.form.get('extendedDescription').value;
this.showAdditionalInfo = !!this.form.get('additionalInformation').value;
this.form.valueChanges.subscribe(changes=>{
this.form.valueChanges.pipe(takeUntil(this._destroyed)).subscribe(changes=>{
// this.previewForm = null;
this.previewDirty = true;
this.generatePreviewForm();
});
this.previewSubject$.pipe(debounceTime(600)).subscribe(model=>{
const updatedForm = model.buildForm();
this.reloadPreview(updatedForm)
})
this.previewSubject$
.pipe(debounceTime(600))
.pipe(
takeUntil(this._destroyed),
map(model => model.buildForm()),
map(updatedForm =>{
const previewContainer = document.getElementById('preview_container'+ this.form.get('id').value);
// let clientHeight = -1;
if(previewContainer){
// console.log(previewContainer);
const clientHeight = previewContainer.clientHeight;
// console.log(clientHeight);
if(clientHeight){
previewContainer.style.height = clientHeight.toString() + 'px';
// console.log('height:' ,previewContainer.style.height);
}
}
this.showPreview = false;
this.previewDirty = true;
this.previewForm = updatedForm;
return previewContainer;
}),
delay(100),
tap( previewContainer =>{
this.showPreview = true;
this.previewDirty = false;
}),
delay(100)
)
.subscribe(previewContainer=>{
if(previewContainer){
previewContainer.style.height = 'auto';
}
// const updatedForm = model.buildForm();
// this.reloadPreview(updatedForm)
});
this.generatePreviewForm();
......
......@@ -15,12 +15,10 @@
<li class="list-inline-item" *ngIf="!viewOnly && viewType && canBeDeleted" class="text-muted">
<mat-icon style="cursor: pointer; opacity: 0.7; transform:translateY(2px) translateX(10px) ;" (click)="onDelete()" [matTooltip]="'DATASET-PROFILE-EDITOR.ACTIONS.FIELD.DELETE-INPUT' | translate">delete</mat-icon>
</li>
</ul>
</div>
</div>
<div class="row">
<!-- <mat-form-field class="col">
<input matInput placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.ID' | translate}}" type="text" [formControl]="this.form.get('id')"
......@@ -173,9 +171,9 @@
</mat-form-field>
<!-- Combo Box -->
<mat-form-field *ngIf="showOrdinal" class="col">
<!-- <mat-form-field *ngIf="showOrdinal" class="col">
<input matInput type="number" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.ORDER' | translate}}" [formControl]="this.form.get('ordinal')" required>
</mat-form-field>
</mat-form-field> -->
<!-- Validation -->
<!-- <mat-form-field class="col" *ngIf="!(defaulValueRequired(form.get('viewStyle').get('renderStyle').value))">
......@@ -189,7 +187,7 @@
<mat-label>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.RDA-COMMON-STANDARDS' | translate}}</mat-label>
<mat-select [formControl]="this.form.get('rdaCommonStandard')">
<mat-option>--</mat-option>
<mat-option *ngFor="let property of datasetProfileService.getRDACommonStandards()" [value]="property">
<mat-option *ngFor="let property of rdaCommonStandards" [value]="property">
{{property}}
</mat-option>
</mat-select>
......@@ -246,7 +244,6 @@
<app-dataset-profile-editor-currency-field-component *ngSwitchCase="viewStyleEnum.Currency" class="col-12" [form]="form"></app-dataset-profile-editor-currency-field-component>
<app-dataset-profile-editor-validator-field-component *ngSwitchCase="viewStyleEnum.Validation" class="col-12" [form]="form"></app-dataset-profile-editor-validator-field-component>
</div>
</ng-container>
......
......@@ -41,6 +41,9 @@ export class DatasetProfileEditorFieldComponent extends BaseComponent implements
@Output() delete = new EventEmitter<void>();
rdaCommonStandards = this.datasetProfileService.getRDACommonStandards();
constructor(
public enumUtils: EnumUtils,
public datasetProfileService: DatasetProfileService,
......
......@@ -12,7 +12,7 @@ import { TranslateService } from '@ngx-translate/core';
styleUrls: ['./dataset-profile-editor-rule.component.scss']
})
export class DatasetProfileEditorRuleComponent implements OnInit{
export class DatasetProfileEditorRuleComponent implements OnInit {
@Input() form: FormArray;
......@@ -29,6 +29,9 @@ export class DatasetProfileEditorRuleComponent implements OnInit{
fieldSetOptions: OptionItem[];
fieldOptions: OptionItem[];
parentIds: string[] = [];
hiddenBy: string[] = [];
constructor(private language: TranslateService){
}
......@@ -70,6 +73,8 @@ export class DatasetProfileEditorRuleComponent implements OnInit{
this.fieldOptions.forEach(e=>this._buildHiddenBy(e));
this.fieldSetOptions.forEach(e=>this._buildHiddenBy(e));
this.parentIds = this.computeParentIds();
this.hiddenBy = this.computeHiddenBy();
}
......@@ -164,8 +169,15 @@ export class DatasetProfileEditorRuleComponent implements OnInit{
return result;
}
get parentIds(): string[]{
// get parentIds(): string[]{
// }
// get hiddenBy(): string[]{
// }
computeParentIds(): string[]{
if(!this.formControlForCheck.get('id')) return [];
const current = this.options.find(opt=> opt.id === this.formControlForCheck.get('id').value);
......@@ -175,7 +187,8 @@ export class DatasetProfileEditorRuleComponent implements OnInit{
}
return [];
}
get hiddenBy(): string[]{
computeHiddenBy(): string[]{
if(!this.formControlForCheck.get('id')) return [];
const current = this.options.find(opt=> opt.id === this.formControlForCheck.get('id').value);
......
<div id="topofcontainer"></div>
<div class="row" [id]="idprefix+form.get('id').value">
<div class="row" [id]="idprefix+form.get('id').value" *ngIf="form">
<div class="col-12" >
......@@ -69,7 +69,7 @@
<mat-card-content>
<mat-card-header *ngIf="(fieldset.get('id').value === selectedFieldSetId) && !viewOnly">
<mat-icon class="handle" style="display:inline-block; margin: 0px auto; cursor: grab;transform: rotate(90deg); opacity: 0.3;" cdkDragHandle>drag_indicator</mat-icon>
<mat-icon class="handle" style="display:inline-block; margin: 0px auto; cursor: grab;transform: rotate(90deg); opacity: 0.3;">drag_indicator</mat-icon>
</mat-card-header>
<app-dataset-profile-editor-composite-field-component [form]="fieldset"
[viewOnly]="viewOnly"
......@@ -81,7 +81,6 @@
</div>
<div class="col-2 col-xl-auto ml-4" *ngIf="selectedFieldSetId === fieldset.get('id').value &&(!viewOnly)">
<div class="row bg-white actions-list stick-list">
<nav *ngIf="!viewOnly">
<label class="action-list-label">{{'DATASET-PROFILE-EDITOR.STEPS.TOOLKIT.GENERAL-TOOLS' | translate}}</label>
......
......@@ -2,8 +2,10 @@
import { Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
import { FormArray, FormGroup } from '@angular/forms';
import { Guid } from '@common/types/guid';
import { isNullOrUndefined } from '@swimlane/ngx-datatable';
import { DragulaService } from 'ng2-dragula';
import { Subscription } from 'rxjs';
import { pipe, Subject, Subscription } from 'rxjs';
import { debounceTime, delay, tap } from 'rxjs/operators';
import { FieldEditorModel } from '../../../admin/field-editor-model';
import { FieldSetEditorModel } from '../../../admin/field-set-editor-model';
import { ToCEntry, ToCEntryType } from '../../../table-of-contents/table-of-contents-entry';
......@@ -36,6 +38,10 @@ export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnC
readonly dragula_prefix = "dragulaid";
private subs = new Subscription();
private FIELDSETS = 'FIELDSETS';
private initializer = new Subject<void>();
private scroller = new Subject<string>();
// private $selectedFieldsetId = new Subject<string>();
constructor(
private dragulaService: DragulaService,
private myElement: ElementRef
......@@ -66,6 +72,33 @@ export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnC
this.dataNeedsRefresh.emit();
return ;
}));
const initializerSub = this.initializer
.pipe(
debounceTime(200)
)
.subscribe(() =>{
this.initialize();
});
this.subs.add(initializerSub);
this.subs.add(
this.scroller
.pipe(debounceTime(700))
.subscribe(id => {
if(isNullOrUndefined(id)){
this._scrollOnTop();
return ;
}
this._scrollToElement(id);
})
);
// this.subs.add(
// this.$selectedFieldsetId
// .pipe(
// debounceTime(100)
// )
// .subscribe(id => this.selectedEntryId.emit(id))
// );
}
ngOnDestroy(){
......@@ -74,15 +107,7 @@ export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnC
this.subs.unsubscribe();
}
ngOnChanges(changes: SimpleChanges): void {
// console.log('---------element updated-------');
// console.log('numbering before:', this.numbering);
this.initialize();
// console.log('----post update----');
// console.log('numbering now', this.numbering, ' changes detected:', changes);
this.initializer.next();
}
......@@ -99,14 +124,18 @@ export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnC
if(id === this._selectedFieldSetId) return;
this._selectedFieldSetId = id;
this.selectedEntryId.emit(this._selectedFieldSetId);
this.selectedEntryId.emit(id);
}
private _findParentSection():FormGroup{
const parent = this.form.parent;
return parent;
}
// private _findParentSection():FormGroup{
// const parent = this.form.parent;
// return parent;
// }
private initialize(){
......@@ -115,8 +144,7 @@ export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnC
this.numbering = this.tocentry.numbering;
this._selectedFieldSetId = null;
// this._scrollToElement(this.tocentry.id);
this._scrollOnTop();
this.scroller.next(null);
}else if(this.tocentry.type === ToCEntryType.FieldSet){
this.form = this.tocentry.form.parent.parent;
const numberingArray = this.tocentry.numbering.split('.');
......@@ -126,45 +154,30 @@ export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnC
}else{
// console.warn('!not found numbering');
}
this.selectedFieldSetId = this.tocentry.id;
this._selectedFieldSetId = this.tocentry.id;
this._scrollToElement(this.selectedFieldSetId);
// this._scrollToElement(this.selectedFieldSetId);
this.scroller.next(this.tocentry.id);
}else{//scroll on top
this._scrollOnTop();
// this._scrollOnTop();
this.scroller.next(null);
}
}
private _scrollToElement(id: string){
let el = this.myElement.nativeElement.querySelector("#"+this.idprefix+id);
// let el = this.myElement.nativeElement.getElementbyId (this.selectedFieldSetId);
if(el){
/*
Give time to template to build itself (extending and collapsing).
In case we are dragging from one container to another, then the ui takes around 600ms to build
individual previews (dataset-profile-editor-field.component.ts);
*/
setTimeout(() => {
const el = this.myElement.nativeElement.querySelector("#"+this.idprefix+id);
if(el){
el.scrollIntoView({behavior: "smooth", block: