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 {
this.dataModel = new DatasetProfileEditorModel();
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) {
this.form.disable();
this.viewOnly = true;
@ -202,11 +203,24 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
setTimeout(() => {
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() {
@ -229,11 +243,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
setTimeout(() => {
this.steps = this.stepper.steps;
});
//SHOW THE FIRST PAGE
const tocentries = this.refreshToCEntries();
if(tocentries && tocentries.length){
this.selectedTocEntry = tocentries[0];
}
this._initializeToCEntries();
}
@ -558,18 +568,26 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
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;
// tocentries.forEach((e,idx)=>{
// const ordinalControl = e.form.get('ordinal');
// if(ordinalControl){
// ordinalControl.setValue(idx);
// ordinalControl.updateValueAndValidity();
// }
// this.updateOrdinals(e.subEntries);
// });
// }
if(!tocentries || !tocentries.length) return;
tocentries.forEach((e,idx)=>{
const ordinalControl = e.form.get('ordinal');
if(ordinalControl){
ordinalControl.setValue(idx);
ordinalControl.updateValueAndValidity();
}
this._updateOrdinals(e.subEntries);
});
}
//sort tocentries based on their ordinality
private _sortToCentries(entries: ToCEntry[]){
@ -759,7 +777,17 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
sectionsArray = this.form.get('sections') as FormArray;
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());
// this.form.updateValueAndValidity();
@ -768,13 +796,18 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
//adding page parent MAYBE NOT NEEDED
section.page = parent.form.get('page').value;
//MAYBE NOT NEEDED
section.ordinal = sectionsArray.length;
try{
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());
// (child.form.parent as FormArray).push(section.buildForm());
}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 fieldSetId = Guid.create().toString();
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();

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)"
[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?.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="">
<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)"
(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);
border-radius: 10px;
background-color: #F5F5F5;
}
#style-2::-webkit-scrollbar
#tocentrytable::-webkit-scrollbar
{
width: 4px;
background-color: #F5F5F5;
}
#style-2::-webkit-scrollbar-thumb
#tocentrytable::-webkit-scrollbar-thumb
{
border-radius: 2px;
-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 { ContentObserver } from '@angular/cdk/observers';
export interface Link {
/* id of the section*/
id: string;
/* header type h3/h4 */
type: string;
/* If the anchor is in view of the page */
active: boolean;
/* name of the anchor */
name: string;
/* top offset px of the anchor */
top: number;
page: number;
section: number;
show: boolean;
selected: boolean;
}
// export interface Link {
// /* id of the section*/
// id: string;
// /* header type h3/h4 */
// type: string;
// /* If the anchor is in view of the page */
// active: boolean;
// /* name of the anchor */
// name: string;
// /* top offset px of the anchor */
// top: number;
// page: number;
// section: number;
// show: boolean;
// selected: boolean;
// }
@Component({
selector: 'dataset-profile-table-of-contents',
@ -71,7 +71,7 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
DRAGULA_ITEM_ID_PREFIX="table_item_id_";
ROOT_ID: string = "ROOT_ID";//no special meaning
private _dragStartedAt;
private VALID_DROP_TIME = 500;//ms
constructor(
@Inject(DOCUMENT) private _document: Document,
@ -96,7 +96,7 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
if(this._dragStartedAt){
const timeNow = new Date().getTime();
if(timeNow - this._dragStartedAt> 600){
if(timeNow - this._dragStartedAt> this.VALID_DROP_TIME){
// console.log('timenow: ', timeNow);
// console.log('timestarted', this._dragStartedAt);
this._dragStartedAt = null;
@ -459,6 +459,12 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
console.log('drag fired');
this.isDragging = true;
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)=>{
try {
@ -478,9 +484,45 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
}
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{
if(!tocentries){