Dataset Profile Editor. Table of contents numbering drag and drop fix. Fix issues in dragging as well.

This commit is contained in:
Kristian Ntavidi 2021-03-23 12:39:04 +02:00
parent 427c04f631
commit 5e77f78a1c
5 changed files with 88 additions and 52 deletions

View File

@ -1,5 +1,5 @@
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { Inject } from '@angular/core';
import { ChangeDetectorRef, Inject, OnDestroy } from '@angular/core';
import { Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
import { FormArray, FormGroup } from '@angular/forms';
import { FieldEditorModel } from '@app/ui/admin/dataset-profile/admin/field-editor-model';
@ -18,7 +18,7 @@ import { ToCEntry, ToCEntryType } from '../../../table-of-contents/table-of-cont
styleUrls: ['./dataset-profile-editor-section-fieldset.component.scss']
})
export class DatasetProfileEditorSectionFieldSetComponent extends BaseComponent implements OnInit, OnChanges {
export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnChanges, OnDestroy {
// @Input() form: FormGroup;
//@Input() dataModel: SectionEditorModel;
// @Input() indexPath: string;
@ -41,7 +41,6 @@ export class DatasetProfileEditorSectionFieldSetComponent extends BaseComponent
private myElement: ElementRef
)
{
super();
if(this.dragulaService.find(this.FIELDSETS)){
this.dragulaService.destroy(this.FIELDSETS);
}
@ -70,10 +69,20 @@ export class DatasetProfileEditorSectionFieldSetComponent extends BaseComponent
}
ngOnDestroy(){
// console.log('elemement destroyed -->');
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);
}
@ -113,6 +122,8 @@ export class DatasetProfileEditorSectionFieldSetComponent extends BaseComponent
if(numberingArray.length){
numberingArray.splice(numberingArray.length-1);
this.numbering = numberingArray.join('.');
}else{
// console.warn('!not found numbering');
}
this.selectedFieldSetId = this.tocentry.id;
@ -128,12 +139,18 @@ export class DatasetProfileEditorSectionFieldSetComponent extends BaseComponent
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"});
}
}, 300);
}, 1100);
}else{
this._scrollOnTop();
}
@ -150,7 +167,9 @@ export class DatasetProfileEditorSectionFieldSetComponent extends BaseComponent
}
ngOnInit() {
this.initialize();
// console.log('<-- element created');
// this.initialize();
//TODO

View File

@ -198,7 +198,7 @@
(removeEntry)="onRemoveEntry($event)"
[itemSelected]="selectedTocEntry"
[viewOnly]="viewOnly"
(dataNeedsRefresh)="onDataNeedsRefresh()"
(dataNeedsRefresh)="onDataNeedsRefresh($event)"
[colorizeInvalid]="colorizeInvalid">
</dataset-profile-table-of-contents>

View File

@ -44,6 +44,8 @@ import { SideNavService } from '@app/core/services/sidenav/side-nav.sevice';
import { EditorCustomValidators, EditorCustomValidatorsEnum } from './custom-validators/editor-custom-validators';
import { CustomErrorValidator } from '@common/forms/validation/custom-validator';
import { STEPPER_ANIMATIONS } from './animations/animations';
const skipDisable: any[] = require('../../../../../assets/resources/skipDisable.json');
@Component({
@ -556,18 +558,18 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
return this.toCEntries;
}
private updateOrdinals(tocentries: ToCEntry[]){
// 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[]){
@ -708,7 +710,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
private _findTocEntryById(id: string, tocentries: ToCEntry[]): ToCEntry{
if(!tocentries){
if(!tocentries || !tocentries.length){
return null;
}
@ -1414,8 +1416,15 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
}
// previewForm:FormGroup;
onDataNeedsRefresh(){
this.refreshToCEntries();
onDataNeedsRefresh(params?){
const tocentries = this.refreshToCEntries();
if(params && params.draggedItemId){
if(params.draggedItemId){
this.displayItem(this._findTocEntryById(params.draggedItemId, tocentries));
}
}
}
cloneFieldSet(fieldset: FormGroup){

View File

@ -21,4 +21,9 @@ export enum ToCEntryType {
export interface Foo {
childType: ToCEntryType,
parent: ToCEntry
}
export interface TableUpdateInfo{
draggedItemId?: string;
data?:any;
}

View File

@ -5,11 +5,12 @@ import { interval, Subject, Subscription } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
import { type } from 'os';
import { SimpleChanges } from '@angular/core';
import { Foo, ToCEntry, ToCEntryType } from './table-of-contents-entry';
import { Foo, TableUpdateInfo, ToCEntry, ToCEntryType } from './table-of-contents-entry';
import { DragulaService } from 'ng2-dragula';
import { FormArray } from '@angular/forms';
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*/
@ -44,7 +45,7 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
@Output() createEntry = new EventEmitter<Foo>();//TODO
@Output() dataNeedsRefresh = new EventEmitter<void>();
@Output() dataNeedsRefresh = new EventEmitter<TableUpdateInfo>();
@Input() itemSelected: ToCEntry;
@Input() colorizeInvalid: boolean = false;
@ -96,8 +97,8 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
const timeNow = new Date().getTime();
if(timeNow - this._dragStartedAt> 600){
console.log('timenow: ', timeNow);
console.log('timestarted', this._dragStartedAt);
// console.log('timenow: ', timeNow);
// console.log('timestarted', this._dragStartedAt);
this._dragStartedAt = null;
}else{
@ -135,7 +136,7 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
switch(element.type){
case ToCEntryType.FieldSet:
case ToCEntryType.FieldSet:{
if(targetContainer.type != this.tocEntryType.Section){
// const message = 'Fieldset can only be child of Subsections';
const message = this.language.instant('DATASET-PROFILE-EDITOR.STEPS.FORM.TABLE-OF-CONTENTS.ERROR-MESSAGES.FIELDSET-MUST-HAVE-PARENT-SECTION');
@ -179,11 +180,12 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
sourceFieldsets.controls.forEach(control=>{
const ordinal = control.get('ordinal');
if(ordinal.value>= sourceOrdinal){
if((ordinal.value>= sourceOrdinal) && sourceOrdinal>0){
const updatedOrdinalVal = ordinal.value -1;
ordinal.setValue(updatedOrdinalVal);
}
});
sourceFieldsets.controls.sort(this._compareOrdinals);
}
let position:number = targetFieldsets.length;
@ -201,7 +203,7 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
});
if(siblingIndex>=0 && (position!=targetFieldsets.length)){
if(siblingIndex>=0){ //sibling found
targetFieldsets.controls.filter(control=> control.get('ordinal').value >= position).forEach(control=>{
const ordinal = control.get('ordinal');
@ -215,11 +217,12 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
fieldsetForm.get('ordinal').setValue(position);
targetFieldsets.insert(position,fieldsetForm);
this.dataNeedsRefresh.emit();
targetFieldsets.controls.sort(this._compareOrdinals);
this.dataNeedsRefresh.emit({draggedItemId: elementId});
break;
case ToCEntryType.Section:
}
case ToCEntryType.Section:{
if(targetContainer.type == ToCEntryType.Section){
if((targetContainer.form.get('fieldSets')as FormArray).length){
@ -256,7 +259,7 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
sourceSections.controls.filter(control=>control.get('ordinal').value >= elementSectionForm.get('ordinal').value).forEach(control=>{
const ordinal = control.get('ordinal');
const updatedOrdinalVal = ordinal.value -1;
const updatedOrdinalVal = ordinal.value? ordinal.value -1: 0;
ordinal.setValue(updatedOrdinalVal);
});
@ -274,14 +277,14 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
}
})
if(targetOrdinal!=targetSections.length){
// if(targetOrdinal!=targetSections.length){//mporei na einai idio
// section.get('ordinal').setValue(i+1);
targetSections.controls.filter(control=> control.get('ordinal').value>=targetOrdinal).forEach(control=>{
const ordinal = control.get('ordinal');
const updatedOrdinalVal = ordinal.value+1;
ordinal.setValue(updatedOrdinalVal);
});
}
// }
}else{
console.info('no siblings found');
@ -290,7 +293,7 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
targetSections.insert(targetOrdinal, elementSectionForm);
}else if(targetContainer.type === ToCEntryType.Page){
const pageId = targetContainer.form.get('id').value;
// const pageId = targetContainer.form.get('id').value;
const rootform = targetContainer.form.root;
const sectionForm = element.form;
@ -313,7 +316,7 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
//update parent sections ordinal
parentSections.controls.filter(section=>section.get('ordinal').value >= sectionForm.get('ordinal').value).forEach(section=>{
const ordinal = section.get('ordinal');
const updatedOrdinalVal = ordinal.value -1;
const updatedOrdinalVal = ordinal.value?ordinal.value -1: 0;
ordinal.setValue(updatedOrdinalVal);
})
@ -333,13 +336,13 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
const siblingId= sibling.id.replace(this.DRAGULA_ITEM_ID_PREFIX, '');
let indx = -1;
targetContainer.subEntries.forEach((e,i)=>{//TOOD TO CHECK IF ORDINAL AND INDEX IS THE SAME
targetContainer.subEntries.forEach((e,i)=>{
if(e.form.get('id').value === siblingId){
indx = i;
position = e.form.get('ordinal').value;
}
});
if(indx>=0 && position !=targetContainer.subEntries.length) {
if(indx>=0) {
// e.form.get('ordinal').setValue(i+1);
targetContainer.subEntries.filter(e=>e.form.get('ordinal').value >= position).forEach(e=>{
@ -368,9 +371,10 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
this.dataNeedsRefresh.emit();
this.dataNeedsRefresh.emit({draggedItemId: elementId});
break;
case ToCEntryType.Page:
}
case ToCEntryType.Page:{
if(targetId != this.ROOT_ID){
// const message = 'A page element can only be at top level';
const message = this.language.instant('DATASET-PROFILE-EDITOR.STEPS.FORM.TABLE-OF-CONTENTS.ERROR-MESSAGES.PAGE-ELEMENT-ONLY-TOP-LEVEL');
@ -407,9 +411,9 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
//ordinality
pages.controls.filter(page=> page.get('ordinal').value> pageForm.get('ordinal').value).forEach(page=>{
pages.controls.filter(page=> page.get('ordinal').value>= pageForm.get('ordinal').value).forEach(page=>{
const ordinal = page.get('ordinal');
const ordinalVal = ordinal.value - 1;
const ordinalVal = ordinal.value? ordinal.value - 1: 0;
ordinal.setValue(ordinalVal);
});
@ -437,9 +441,9 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
pages.insert(targetPosition, pageForm);
this.dataNeedsRefresh.emit();
this.dataNeedsRefresh.emit({draggedItemId:elementId});
break;
}
default:
console.error('Could not support moving objects for specific type of element');
@ -464,18 +468,9 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
}
});
drake.on('dragend',(el)=>{
const draggingItem = this.draggingItemId;
this.isDragging = false;
this.draggingItemId = null;
this.overcontainer = null;
const entry = this._findTocEntryById(draggingItem, this.links);
if(entry){
this.itemClicked(entry);
}
});
@ -554,6 +549,14 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
duration:2000
}
private _compareOrdinals(a, b){
const aValue = a.get('ordinal').value as number;
const bValue = b.get('ordinal').value as number;
// if(!aValue || !bValue) return 0;
return aValue - bValue;
}
}