Dataset Profile Table of contents drag n drop fix. DIstinct ordinals that are on the same level.

This commit is contained in:
Kristian Ntavidi 2021-03-24 11:40:48 +02:00
parent b6236b7e0d
commit 8ba546fef4
5 changed files with 127 additions and 45 deletions

View File

@ -191,7 +191,8 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
} else { } else {
this.dataModel = new DatasetProfileEditorModel(); this.dataModel = new DatasetProfileEditorModel();
this.form = this.dataModel.buildForm(); this.form = this.dataModel.buildForm();
this.form.setValidators([this.customEditorValidators.atLeastOneElementListValidator('pages'), this.customEditorValidators.pagesHaveAtLeastOneSection('pages', 'sections')]) this.form.setValidators([this.customEditorValidators.atLeastOneElementListValidator('pages'), this.customEditorValidators.pagesHaveAtLeastOneSection('pages', 'sections')]);
if (this.dataModel.status === DatasetProfileEnum.FINALIZED) { if (this.dataModel.status === DatasetProfileEnum.FINALIZED) {
this.form.disable(); this.form.disable();
this.viewOnly = true; this.viewOnly = true;
@ -202,11 +203,24 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
setTimeout(() => { setTimeout(() => {
this.steps = this.stepper.steps; this.steps = this.stepper.steps;
}); });
this.refreshToCEntries(); this._initializeToCEntries();
} }
}); });
}
private _initializeToCEntries(){
const tocentries = this.refreshToCEntries();//tocentries are sorted based on their ordinal value
this._updateOrdinals(tocentries);
if(tocentries && tocentries.length){
this.selectedTocEntry = tocentries[0];
}
} }
prepareForm() { prepareForm() {
@ -229,11 +243,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
setTimeout(() => { setTimeout(() => {
this.steps = this.stepper.steps; this.steps = this.stepper.steps;
}); });
//SHOW THE FIRST PAGE this._initializeToCEntries();
const tocentries = this.refreshToCEntries();
if(tocentries && tocentries.length){
this.selectedTocEntry = tocentries[0];
}
} }
@ -558,18 +568,26 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
return this.toCEntries; return this.toCEntries;
} }
// private updateOrdinals(tocentries: ToCEntry[]){ /**
* Updates entries ordinal form value
* based on the index they have on the tocentry array.
* Tocentries that are on the same level have distinct ordinal value
*
* @param tocentries
*
*/
private _updateOrdinals(tocentries: ToCEntry[]){
// if(!tocentries || !tocentries.length) return; if(!tocentries || !tocentries.length) return;
// tocentries.forEach((e,idx)=>{ tocentries.forEach((e,idx)=>{
// const ordinalControl = e.form.get('ordinal'); const ordinalControl = e.form.get('ordinal');
// if(ordinalControl){ if(ordinalControl){
// ordinalControl.setValue(idx); ordinalControl.setValue(idx);
// ordinalControl.updateValueAndValidity(); ordinalControl.updateValueAndValidity();
// } }
// this.updateOrdinals(e.subEntries); this._updateOrdinals(e.subEntries);
// }); });
// } }
//sort tocentries based on their ordinality //sort tocentries based on their ordinality
private _sortToCentries(entries: ToCEntry[]){ private _sortToCentries(entries: ToCEntry[]){
@ -759,7 +777,17 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
sectionsArray = this.form.get('sections') as FormArray; sectionsArray = this.form.get('sections') as FormArray;
section.page = parent.id; section.page = parent.id;
section.ordinal = sectionsArray.length;
try{
const max = sectionsArray.controls.filter(control=>control.get('page').value === parent.id)
.map(control=>control.get('ordinal').value)
.reduce((a,b)=>Math.max(a,b));
section.ordinal = max + 1;
}catch{
section.ordinal = sectionsArray.length;
}
sectionsArray.push(section.buildForm()); sectionsArray.push(section.buildForm());
// this.form.updateValueAndValidity(); // this.form.updateValueAndValidity();
@ -768,13 +796,18 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
//adding page parent MAYBE NOT NEEDED //adding page parent MAYBE NOT NEEDED
section.page = parent.form.get('page').value; section.page = parent.form.get('page').value;
//MAYBE NOT NEEDED try{
section.ordinal = sectionsArray.length; const maxOrdinal = sectionsArray.controls.map(control=>control.get('ordinal').value).reduce((a,b)=>Math.max(a, b));
section.ordinal = maxOrdinal+1;
}catch{
section.ordinal = sectionsArray.length;
}
sectionsArray.push(section.buildForm()); sectionsArray.push(section.buildForm());
// (child.form.parent as FormArray).push(section.buildForm()); // (child.form.parent as FormArray).push(section.buildForm());
}else{ }else{
console.error('Section can only bee child of a page or another section'); console.error('Section can only be child of a page or another section');
} }
@ -806,7 +839,13 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
const fieldSet: FieldSetEditorModel = new FieldSetEditorModel(); const fieldSet: FieldSetEditorModel = new FieldSetEditorModel();
const fieldSetId = Guid.create().toString(); const fieldSetId = Guid.create().toString();
fieldSet.id = fieldSetId; fieldSet.id = fieldSetId;
fieldSet.ordinal = fieldSetsArray.length;
try{
const maxOrdinal = fieldSetsArray.controls.map(control=>control.get('ordinal').value).reduce((a,b)=>Math.max(a, b));
fieldSet.ordinal = maxOrdinal+1;
}catch{
fieldSet.ordinal = fieldSetsArray.length;
}
const fieldsetForm = fieldSet.buildForm(); const fieldsetForm = fieldSet.buildForm();

View File

@ -24,6 +24,7 @@
> --> > -->
<span class="table-label-element" [ngClass]="{'table-label-element-active': itemSelected?.id == parentLink?.id, 'text-danger': colorError()}" (click)="itemClicked(parentLink)" <span class="table-label-element" [ngClass]="{'table-label-element-active': itemSelected?.id == parentLink?.id, 'text-danger': colorError()}" (click)="itemClicked(parentLink)"
[ngStyle]="{'font-size' : (parentLink.type == tocEntryType.FieldSet? '.9rem':'1rem')}" [ngStyle]="{'font-size' : (parentLink.type == tocEntryType.FieldSet? '.9rem':'1rem')}"
[id]="'TABLE_ENTRY'+parentLink.id"
> >
<!-- {{parentLink?.numbering}} {{parentLink?.label? parentLink?.label : 'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.UNTITLED' | translate}} --> <!-- {{parentLink?.numbering}} {{parentLink?.label? parentLink?.label : 'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.UNTITLED' | translate}} -->
{{parentLink?.numbering}} {{parentLink?.form.get('title').value? parentLink?.form.get('title').value : 'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.UNTITLED' | translate}} {{parentLink?.numbering}} {{parentLink?.form.get('title').value? parentLink?.form.get('title').value : 'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.UNTITLED' | translate}}

View File

@ -1,7 +1,7 @@
<div class=""> <div class="">
<h3 id="guide-steps">{{'DMP-EDITOR.STEPPER.USER-GUIDE' | translate}}</h3> <h3 id="guide-steps">{{'DMP-EDITOR.STEPPER.USER-GUIDE' | translate}}</h3>
<div class="scroll-container" id="style-2"> <div class="scroll-container" id="tocentrytable">
<app-dataset-profile-table-of-contents-internal-section [links]="links" (itemClick)="itemClicked($event)" <app-dataset-profile-table-of-contents-internal-section [links]="links" (itemClick)="itemClicked($event)"
(newEntry)="addNewEntry($event)" (removeEntry)="deleteEntry($event)" (newEntry)="addNewEntry($event)" (removeEntry)="deleteEntry($event)"

View File

@ -113,20 +113,20 @@ span {
#style-2::-webkit-scrollbar-track #tocentrytable::-webkit-scrollbar-track
{ {
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
border-radius: 10px; border-radius: 10px;
background-color: #F5F5F5; background-color: #F5F5F5;
} }
#style-2::-webkit-scrollbar #tocentrytable::-webkit-scrollbar
{ {
width: 4px; width: 4px;
background-color: #F5F5F5; background-color: #F5F5F5;
} }
#style-2::-webkit-scrollbar-thumb #tocentrytable::-webkit-scrollbar-thumb
{ {
border-radius: 2px; border-radius: 2px;
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);

View File

@ -12,22 +12,22 @@ import { MatSnackBar, MatSnackBarConfig } from '@angular/material';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { ContentObserver } from '@angular/cdk/observers'; import { ContentObserver } from '@angular/cdk/observers';
export interface Link { // export interface Link {
/* id of the section*/ // /* id of the section*/
id: string; // id: string;
/* header type h3/h4 */ // /* header type h3/h4 */
type: string; // type: string;
/* If the anchor is in view of the page */ // /* If the anchor is in view of the page */
active: boolean; // active: boolean;
/* name of the anchor */ // /* name of the anchor */
name: string; // name: string;
/* top offset px of the anchor */ // /* top offset px of the anchor */
top: number; // top: number;
page: number; // page: number;
section: number; // section: number;
show: boolean; // show: boolean;
selected: boolean; // selected: boolean;
} // }
@Component({ @Component({
selector: 'dataset-profile-table-of-contents', selector: 'dataset-profile-table-of-contents',
@ -71,7 +71,7 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
DRAGULA_ITEM_ID_PREFIX="table_item_id_"; DRAGULA_ITEM_ID_PREFIX="table_item_id_";
ROOT_ID: string = "ROOT_ID";//no special meaning ROOT_ID: string = "ROOT_ID";//no special meaning
private _dragStartedAt; private _dragStartedAt;
private VALID_DROP_TIME = 500;//ms
constructor( constructor(
@Inject(DOCUMENT) private _document: Document, @Inject(DOCUMENT) private _document: Document,
@ -96,7 +96,7 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
if(this._dragStartedAt){ if(this._dragStartedAt){
const timeNow = new Date().getTime(); const timeNow = new Date().getTime();
if(timeNow - this._dragStartedAt> 600){ if(timeNow - this._dragStartedAt> this.VALID_DROP_TIME){
// console.log('timenow: ', timeNow); // console.log('timenow: ', timeNow);
// console.log('timestarted', this._dragStartedAt); // console.log('timestarted', this._dragStartedAt);
this._dragStartedAt = null; this._dragStartedAt = null;
@ -459,6 +459,12 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
console.log('drag fired'); console.log('drag fired');
this.isDragging = true; this.isDragging = true;
this.draggingItemId = (el.id as string).replace(this.DRAGULA_ITEM_ID_PREFIX, ''); this.draggingItemId = (el.id as string).replace(this.DRAGULA_ITEM_ID_PREFIX, '');
// setTimeout(() => {
// if(this.isDragging){
// this._scrollIntoDragginItem(this.draggingItemId);
// }
// }, this.VALID_DROP_TIME);
}); });
drake.on('over',(el, container, source)=>{ drake.on('over',(el, container, source)=>{
try { try {
@ -478,9 +484,45 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
} }
overcontainer: string = null; overcontainer: string = null;
private _scrollIntoDragginItem(id: string){
// const table = document.getElementById('tocentrytable');
// if(table){
// // const element = document.getElementById('TABLE_ENTRY'+id);
// console.log('Table found!');
// const element = document.getElementById('TABLE_ENTRY' + id);
// const elementFromTable = table.closest('#TABLE_ENTRY'+ id);
// if(elementFromTable){
// console.log('found from table:', elementFromTable);
// }
// if(element){
// console.log('Element found!');
// // element.classList.add('text-danger');
// // console.log(element);
// const tableRect = table.getBoundingClientRect();
// const elementRect = element.getBoundingClientRect();
// console.log('tablerect :',tableRect);
// console.log('elementRect :',elementRect);
// const dY = elementRect.top - tableRect.top;
// console.log('Distance from table is ', dY);
// // table.scroll({top:dY,behavior:'smooth'});
// console.log('found from document ', element);
// // element.scrollIntoView();
// }
// // element.scrollIntoView();
// }
}
private _findTocEntryById(id: string, tocentries: ToCEntry[]): ToCEntry{ private _findTocEntryById(id: string, tocentries: ToCEntry[]): ToCEntry{
if(!tocentries){ if(!tocentries){