2021-02-03 11:21:31 +01:00
|
|
|
import { DOCUMENT } from '@angular/common';
|
|
|
|
import { Component, EventEmitter, Inject, OnInit, Output, Input } from '@angular/core';
|
|
|
|
import { BaseComponent } from '@common/base/base.component';
|
|
|
|
import { interval, Subject, Subscription } from 'rxjs';
|
|
|
|
import { distinctUntilChanged } from 'rxjs/operators';
|
|
|
|
import { type } from 'os';
|
|
|
|
import { SimpleChanges } from '@angular/core';
|
2021-03-23 11:39:04 +01:00
|
|
|
import { Foo, TableUpdateInfo, ToCEntry, ToCEntryType } from './table-of-contents-entry';
|
2021-03-01 10:28:27 +01:00
|
|
|
import { DragulaService } from 'ng2-dragula';
|
|
|
|
import { FormArray } from '@angular/forms';
|
2021-03-03 11:10:11 +01:00
|
|
|
import { MatSnackBar, MatSnackBarConfig } from '@angular/material';
|
2021-03-22 14:47:45 +01:00
|
|
|
import { TranslateService } from '@ngx-translate/core';
|
2021-03-23 11:39:04 +01:00
|
|
|
import { ContentObserver } from '@angular/cdk/observers';
|
2021-02-03 11:21:31 +01:00
|
|
|
|
2021-03-24 10:40:48 +01:00
|
|
|
// 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;
|
|
|
|
// }
|
2021-02-03 11:21:31 +01:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'dataset-profile-table-of-contents',
|
|
|
|
styleUrls: ['./table-of-contents.scss'],
|
|
|
|
templateUrl: './table-of-contents.html'
|
|
|
|
})
|
|
|
|
export class DatasetProfileTableOfContents extends BaseComponent implements OnInit {
|
|
|
|
|
|
|
|
@Input() links: ToCEntry[];
|
2021-02-04 09:33:03 +01:00
|
|
|
|
2021-02-04 11:22:52 +01:00
|
|
|
@Output() itemClick = new EventEmitter<ToCEntry>();
|
2021-02-12 12:23:39 +01:00
|
|
|
@Output() newEntry = new EventEmitter<ToCEntry>();
|
|
|
|
@Output() removeEntry = new EventEmitter<ToCEntry>();
|
2021-02-04 09:33:03 +01:00
|
|
|
|
|
|
|
|
2021-03-22 14:47:45 +01:00
|
|
|
@Output() createEntry = new EventEmitter<Foo>();//TODO
|
2021-02-12 12:23:39 +01:00
|
|
|
|
2021-03-23 11:39:04 +01:00
|
|
|
@Output() dataNeedsRefresh = new EventEmitter<TableUpdateInfo>();
|
2021-02-12 12:23:39 +01:00
|
|
|
|
|
|
|
@Input() itemSelected: ToCEntry;
|
2021-03-12 17:19:51 +01:00
|
|
|
@Input() colorizeInvalid: boolean = false;
|
2021-03-04 13:38:46 +01:00
|
|
|
|
|
|
|
// @Input() set itemSelected(entry:ToCEntry){
|
|
|
|
// this._itemSelected = entry;
|
|
|
|
// };
|
|
|
|
// get itemSelected():ToCEntry{
|
|
|
|
// return this._itemSelected;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// private _itemSelected:ToCEntry;
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-02-15 18:16:48 +01:00
|
|
|
@Input() viewOnly: boolean;
|
2021-02-03 11:21:31 +01:00
|
|
|
show: boolean = false;
|
2021-03-01 10:28:27 +01:00
|
|
|
isDragging: boolean = false;
|
|
|
|
draggingItemId: string = null;
|
2021-02-03 11:21:31 +01:00
|
|
|
|
2021-02-12 12:23:39 +01:00
|
|
|
tocEntryType = ToCEntryType;
|
|
|
|
|
2021-03-01 10:28:27 +01:00
|
|
|
DRAGULA_ITEM_ID_PREFIX="table_item_id_";
|
|
|
|
ROOT_ID: string = "ROOT_ID";//no special meaning
|
2021-03-22 14:47:45 +01:00
|
|
|
private _dragStartedAt;
|
2021-03-24 10:40:48 +01:00
|
|
|
private VALID_DROP_TIME = 500;//ms
|
2021-03-22 14:47:45 +01:00
|
|
|
|
2021-02-03 11:21:31 +01:00
|
|
|
constructor(
|
2021-03-01 10:28:27 +01:00
|
|
|
@Inject(DOCUMENT) private _document: Document,
|
2021-03-03 11:10:11 +01:00
|
|
|
private dragulaService: DragulaService,
|
2021-03-22 14:47:45 +01:00
|
|
|
private snackbar: MatSnackBar,
|
|
|
|
private language: TranslateService
|
2021-03-01 10:28:27 +01:00
|
|
|
) {
|
2021-02-03 11:21:31 +01:00
|
|
|
super();
|
2021-03-01 10:28:27 +01:00
|
|
|
|
2021-03-04 13:38:46 +01:00
|
|
|
|
|
|
|
|
2021-03-01 10:28:27 +01:00
|
|
|
if(this.dragulaService.find('TABLEDRAG')){
|
|
|
|
this.dragulaService.destroy('TABLEDRAG');
|
|
|
|
}
|
|
|
|
|
2021-03-03 11:10:11 +01:00
|
|
|
const dragula = this.dragulaService.createGroup('TABLEDRAG', {});
|
2021-03-01 10:28:27 +01:00
|
|
|
|
|
|
|
const drake = dragula.drake;
|
|
|
|
|
|
|
|
drake.on('drop', (el, target, source,sibling)=>{
|
2021-03-22 14:47:45 +01:00
|
|
|
|
|
|
|
if(this._dragStartedAt){
|
|
|
|
const timeNow = new Date().getTime();
|
|
|
|
|
2021-03-24 10:40:48 +01:00
|
|
|
if(timeNow - this._dragStartedAt> this.VALID_DROP_TIME){
|
2021-03-23 11:39:04 +01:00
|
|
|
// console.log('timenow: ', timeNow);
|
|
|
|
// console.log('timestarted', this._dragStartedAt);
|
2021-03-22 14:47:45 +01:00
|
|
|
this._dragStartedAt = null;
|
|
|
|
|
|
|
|
}else{
|
|
|
|
this.dataNeedsRefresh.emit();// even though the data is not changed the TABLE DRAG may has changed
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
this.dataNeedsRefresh.emit();// even though the data is not changed the TABLE DRAG may has changed
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-03-01 10:28:27 +01:00
|
|
|
const elementId = (el.id as string).replace(this.DRAGULA_ITEM_ID_PREFIX,'');
|
|
|
|
const targetId = target.id as string;
|
|
|
|
const sourceId = source.id as string;
|
|
|
|
|
|
|
|
|
|
|
|
if(!(elementId && targetId && sourceId)){
|
|
|
|
console.error('Elements not have an id');
|
|
|
|
this.dataNeedsRefresh.emit();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const element:ToCEntry = this._findTocEntryById(elementId, this.links);
|
|
|
|
const targetContainer:ToCEntry = this._findTocEntryById(targetId , this.links);
|
|
|
|
const sourceContainer:ToCEntry = this._findTocEntryById(sourceId, this.links);
|
|
|
|
|
|
|
|
if(!(element && (targetContainer ||((element.type===ToCEntryType.Page) && (targetId === this.ROOT_ID))) && (sourceContainer||((element.type===ToCEntryType.Page) && (sourceId === this.ROOT_ID))))){
|
|
|
|
console.info('Could not find elements');
|
|
|
|
this.dataNeedsRefresh.emit();
|
|
|
|
drake.cancel(true);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch(element.type){
|
2021-03-23 11:39:04 +01:00
|
|
|
case ToCEntryType.FieldSet:{
|
2021-03-01 10:28:27 +01:00
|
|
|
if(targetContainer.type != this.tocEntryType.Section){
|
2021-03-22 14:47:45 +01:00
|
|
|
// 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');
|
2021-03-03 11:10:11 +01:00
|
|
|
console.error(message);
|
|
|
|
this.notifyUser(message)
|
2021-03-01 10:28:27 +01:00
|
|
|
this.dataNeedsRefresh.emit();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//check if target container has no sections
|
|
|
|
if((targetContainer.form.get('sections') as FormArray).length){
|
2021-03-22 14:47:45 +01:00
|
|
|
// const message = 'Cannot have inputs and sections on the same level';
|
|
|
|
const message = this.language.instant('DATASET-PROFILE-EDITOR.STEPS.FORM.TABLE-OF-CONTENTS.ERROR-MESSAGES.INPUT-SECTION-SAME-LEVEL');
|
2021-03-03 11:10:11 +01:00
|
|
|
this.notifyUser(message);
|
|
|
|
console.error(message);
|
2021-03-01 10:28:27 +01:00
|
|
|
this.dataNeedsRefresh.emit();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const fieldsetForm = element.form;
|
|
|
|
const targetFieldsets = targetContainer.form.get('fieldSets') as FormArray;
|
|
|
|
const sourceFieldsets = sourceContainer.form.get('fieldSets') as FormArray;
|
|
|
|
|
|
|
|
if(!targetFieldsets){
|
|
|
|
console.error('Not target fieldsets container found');
|
|
|
|
this.dataNeedsRefresh.emit();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let sourceOrdinal=-1;
|
|
|
|
let idx = -1;
|
|
|
|
sourceFieldsets.controls.forEach((elem,index)=>{
|
|
|
|
if(elem.get('id').value === elementId){
|
|
|
|
sourceOrdinal = elem.get('ordinal').value;
|
|
|
|
idx = index
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
if(sourceOrdinal>=0 && idx>=0){
|
|
|
|
sourceFieldsets.removeAt(idx);
|
|
|
|
|
|
|
|
sourceFieldsets.controls.forEach(control=>{
|
|
|
|
const ordinal = control.get('ordinal');
|
2021-03-23 11:39:04 +01:00
|
|
|
if((ordinal.value>= sourceOrdinal) && sourceOrdinal>0){
|
2021-03-01 10:28:27 +01:00
|
|
|
const updatedOrdinalVal = ordinal.value -1;
|
|
|
|
ordinal.setValue(updatedOrdinalVal);
|
|
|
|
}
|
|
|
|
});
|
2021-03-23 11:39:04 +01:00
|
|
|
sourceFieldsets.controls.sort(this._compareOrdinals);
|
2021-03-01 10:28:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
let position:number = targetFieldsets.length;
|
|
|
|
|
|
|
|
if(!sibling ||!sibling.id){
|
|
|
|
console.info('No sibling Id found');
|
|
|
|
}else{
|
|
|
|
const siblingId = (sibling.id as string).replace(this.DRAGULA_ITEM_ID_PREFIX,'');
|
|
|
|
let siblingIndex = -1;
|
|
|
|
targetFieldsets.controls.forEach((e,idx)=>{
|
|
|
|
if(e.get('id').value === siblingId){
|
|
|
|
siblingIndex = idx;
|
|
|
|
position = e.get('ordinal').value;
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
2021-03-23 11:39:04 +01:00
|
|
|
if(siblingIndex>=0){ //sibling found
|
2021-03-01 10:28:27 +01:00
|
|
|
|
|
|
|
targetFieldsets.controls.filter(control=> control.get('ordinal').value >= position).forEach(control=>{
|
|
|
|
const ordinal = control.get('ordinal');
|
|
|
|
const updatedOrdinalVal = ordinal.value +1;
|
|
|
|
ordinal.setValue(updatedOrdinalVal);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fieldsetForm.get('ordinal').setValue(position);
|
|
|
|
targetFieldsets.insert(position,fieldsetForm);
|
2021-03-23 11:39:04 +01:00
|
|
|
targetFieldsets.controls.sort(this._compareOrdinals);
|
|
|
|
this.dataNeedsRefresh.emit({draggedItemId: elementId});
|
2021-03-01 10:28:27 +01:00
|
|
|
|
|
|
|
break;
|
2021-03-23 11:39:04 +01:00
|
|
|
}
|
|
|
|
case ToCEntryType.Section:{
|
2021-03-01 10:28:27 +01:00
|
|
|
|
|
|
|
if(targetContainer.type == ToCEntryType.Section){
|
|
|
|
if((targetContainer.form.get('fieldSets')as FormArray).length){
|
2021-03-22 14:47:45 +01:00
|
|
|
// const message = 'Cannot have inputs and sections on the same level';
|
|
|
|
const message = this.language.instant('DATASET-PROFILE-EDITOR.STEPS.FORM.TABLE-OF-CONTENTS.ERROR-MESSAGES.INPUT-SECTION-SAME-LEVEL');;
|
2021-03-03 11:10:11 +01:00
|
|
|
this.notifyUser(message);
|
|
|
|
console.info(message);
|
2021-03-01 10:28:27 +01:00
|
|
|
this.dataNeedsRefresh.emit();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const targetSections = targetContainer.form.get('sections') as FormArray;
|
|
|
|
const elementSectionForm = element.form;
|
|
|
|
const sourceSections = elementSectionForm.parent as FormArray;
|
|
|
|
|
|
|
|
if(!(targetSections && sourceSections && elementSectionForm)){
|
|
|
|
console.info('Could not load sections');
|
|
|
|
this.dataNeedsRefresh.emit();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let idx = -1;
|
|
|
|
sourceSections.controls.forEach((section,i)=>{
|
|
|
|
if(section.get('id').value === elementId){
|
|
|
|
idx = i;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
if(!(idx>=0)){
|
|
|
|
console.info('Could not find element in Parent container');
|
|
|
|
this.dataNeedsRefresh.emit();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
sourceSections.controls.filter(control=>control.get('ordinal').value >= elementSectionForm.get('ordinal').value).forEach(control=>{
|
|
|
|
const ordinal = control.get('ordinal');
|
2021-03-23 11:39:04 +01:00
|
|
|
const updatedOrdinalVal = ordinal.value? ordinal.value -1: 0;
|
2021-03-01 10:28:27 +01:00
|
|
|
ordinal.setValue(updatedOrdinalVal);
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
sourceSections.removeAt(idx);
|
|
|
|
|
|
|
|
let targetOrdinal = targetSections.length;
|
|
|
|
|
|
|
|
if(sibling && sibling.id){
|
|
|
|
const siblingId = sibling.id.replace(this.DRAGULA_ITEM_ID_PREFIX,'');
|
|
|
|
|
|
|
|
targetSections.controls.forEach((section,i)=>{
|
|
|
|
if(section.get('id').value === siblingId){
|
|
|
|
targetOrdinal = section.get('ordinal').value;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2021-03-23 11:39:04 +01:00
|
|
|
// if(targetOrdinal!=targetSections.length){//mporei na einai idio
|
2021-03-01 10:28:27 +01:00
|
|
|
// 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);
|
|
|
|
});
|
2021-03-23 11:39:04 +01:00
|
|
|
// }
|
2021-03-01 10:28:27 +01:00
|
|
|
|
|
|
|
}else{
|
|
|
|
console.info('no siblings found');
|
|
|
|
}
|
|
|
|
elementSectionForm.get('ordinal').setValue(targetOrdinal);
|
|
|
|
targetSections.insert(targetOrdinal, elementSectionForm);
|
|
|
|
|
|
|
|
}else if(targetContainer.type === ToCEntryType.Page){
|
2021-03-23 11:39:04 +01:00
|
|
|
// const pageId = targetContainer.form.get('id').value;
|
2021-03-01 10:28:27 +01:00
|
|
|
|
|
|
|
const rootform = targetContainer.form.root;
|
|
|
|
const sectionForm = element.form;
|
|
|
|
const parentSections = sectionForm.parent as FormArray;
|
|
|
|
|
|
|
|
let parentIndex = -1;
|
|
|
|
parentSections.controls.forEach((section,i )=>{
|
|
|
|
if(section.get('id').value === elementId){
|
|
|
|
parentIndex = i
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if(parentIndex<0){
|
|
|
|
console.info('could not locate section in parents array');
|
|
|
|
this.dataNeedsRefresh.emit();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//update parent sections ordinal
|
|
|
|
parentSections.controls.filter(section=>section.get('ordinal').value >= sectionForm.get('ordinal').value).forEach(section=>{
|
|
|
|
const ordinal = section.get('ordinal');
|
2021-03-23 11:39:04 +01:00
|
|
|
const updatedOrdinalVal = ordinal.value?ordinal.value -1: 0;
|
2021-03-01 10:28:27 +01:00
|
|
|
ordinal.setValue(updatedOrdinalVal);
|
|
|
|
})
|
|
|
|
|
|
|
|
parentSections.removeAt(parentIndex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let position = 0;
|
|
|
|
if(targetContainer.subEntries){
|
|
|
|
position = targetContainer.subEntries.length;
|
|
|
|
}
|
|
|
|
//populate sections
|
|
|
|
const targetSectionsArray = rootform.get('sections') as FormArray;
|
|
|
|
|
|
|
|
|
|
|
|
if(sibling && sibling.id){
|
|
|
|
const siblingId= sibling.id.replace(this.DRAGULA_ITEM_ID_PREFIX, '');
|
|
|
|
let indx = -1;
|
|
|
|
|
2021-03-23 11:39:04 +01:00
|
|
|
targetContainer.subEntries.forEach((e,i)=>{
|
2021-03-01 10:28:27 +01:00
|
|
|
if(e.form.get('id').value === siblingId){
|
|
|
|
indx = i;
|
|
|
|
position = e.form.get('ordinal').value;
|
|
|
|
}
|
|
|
|
});
|
2021-03-23 11:39:04 +01:00
|
|
|
if(indx>=0) {
|
2021-03-01 10:28:27 +01:00
|
|
|
|
|
|
|
// e.form.get('ordinal').setValue(i+1);
|
|
|
|
targetContainer.subEntries.filter(e=>e.form.get('ordinal').value >= position).forEach(e=>{
|
|
|
|
const ordinal = e.form.get('ordinal');
|
|
|
|
const updatedOrdinalVal = ordinal.value +1;
|
|
|
|
ordinal.setValue(updatedOrdinalVal);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
}else{
|
|
|
|
console.info('No sibling found');
|
|
|
|
}
|
|
|
|
|
|
|
|
sectionForm.get('ordinal').setValue(position);
|
|
|
|
sectionForm.get('page').setValue(targetContainer.id);
|
|
|
|
targetSectionsArray.push(sectionForm);
|
|
|
|
|
|
|
|
}else{
|
2021-03-22 14:47:45 +01:00
|
|
|
// const message = 'Drag not support to specific container';
|
|
|
|
const message = this.language.instant('DATASET-PROFILE-EDITOR.STEPS.FORM.TABLE-OF-CONTENTS.ERROR-MESSAGES.DRAG-NOT-SUPPORTED');
|
2021-03-03 11:10:11 +01:00
|
|
|
this.notifyUser(message);
|
|
|
|
console.info(message);
|
2021-03-01 10:28:27 +01:00
|
|
|
this.dataNeedsRefresh.emit();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-03-23 11:39:04 +01:00
|
|
|
this.dataNeedsRefresh.emit({draggedItemId: elementId});
|
2021-03-01 10:28:27 +01:00
|
|
|
break;
|
2021-03-23 11:39:04 +01:00
|
|
|
}
|
|
|
|
case ToCEntryType.Page:{
|
2021-03-01 10:28:27 +01:00
|
|
|
if(targetId != this.ROOT_ID){
|
2021-03-22 14:47:45 +01:00
|
|
|
// 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');
|
2021-03-03 11:10:11 +01:00
|
|
|
this.notifyUser(message);
|
|
|
|
console.info(message);
|
2021-03-01 10:28:27 +01:00
|
|
|
this.dataNeedsRefresh.emit();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const rootForm = element.form.root;
|
|
|
|
if(!rootForm){
|
|
|
|
console.info('Could not find root!')
|
|
|
|
this.dataNeedsRefresh.emit();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const pages = rootForm.get('pages') as FormArray;
|
|
|
|
const pageForm = element.form;
|
|
|
|
|
|
|
|
let index = -1;
|
|
|
|
|
|
|
|
pages.controls.forEach((page,i)=>{
|
|
|
|
if(page.get('id').value === elementId){
|
|
|
|
index =i;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
if(index<0){
|
|
|
|
console.info('Could not locate page on pages');
|
|
|
|
this.dataNeedsRefresh.emit();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//ordinality
|
2021-03-23 11:39:04 +01:00
|
|
|
pages.controls.filter(page=> page.get('ordinal').value>= pageForm.get('ordinal').value).forEach(page=>{
|
2021-03-01 10:28:27 +01:00
|
|
|
const ordinal = page.get('ordinal');
|
2021-03-23 11:39:04 +01:00
|
|
|
const ordinalVal = ordinal.value? ordinal.value - 1: 0;
|
2021-03-01 10:28:27 +01:00
|
|
|
ordinal.setValue(ordinalVal);
|
|
|
|
});
|
|
|
|
|
|
|
|
pages.removeAt(index);
|
|
|
|
|
|
|
|
let targetPosition = pages.length;
|
|
|
|
|
|
|
|
if(sibling){
|
|
|
|
const siblingId = sibling.id.replace(this.DRAGULA_ITEM_ID_PREFIX, '');
|
|
|
|
|
|
|
|
pages.controls.forEach((page,i)=>{
|
|
|
|
if(page.get('id').value === siblingId){
|
|
|
|
targetPosition = page.get('ordinal').value;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
pageForm.get('ordinal').setValue(targetPosition);
|
|
|
|
|
|
|
|
//update ordinality
|
|
|
|
pages.controls.filter(page=> page.get('ordinal').value>= targetPosition).forEach(page=>{
|
|
|
|
const ordinal = page.get('ordinal');
|
|
|
|
const ordinalVal = ordinal.value +1;
|
|
|
|
ordinal.setValue(ordinalVal);
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
pages.insert(targetPosition, pageForm);
|
2021-03-23 11:39:04 +01:00
|
|
|
this.dataNeedsRefresh.emit({draggedItemId:elementId});
|
2021-03-01 10:28:27 +01:00
|
|
|
break;
|
2021-03-23 11:39:04 +01:00
|
|
|
}
|
2021-03-01 10:28:27 +01:00
|
|
|
default:
|
|
|
|
|
|
|
|
console.error('Could not support moving objects for specific type of element');
|
|
|
|
this.dataNeedsRefresh.emit();
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
drake.on('drag',(el,source)=>{
|
2021-03-22 14:47:45 +01:00
|
|
|
this._dragStartedAt = new Date().getTime();
|
2021-03-08 10:24:30 +01:00
|
|
|
console.log('drag fired');
|
2021-03-01 10:28:27 +01:00
|
|
|
this.isDragging = true;
|
|
|
|
this.draggingItemId = (el.id as string).replace(this.DRAGULA_ITEM_ID_PREFIX, '');
|
2021-03-24 10:40:48 +01:00
|
|
|
|
|
|
|
// setTimeout(() => {
|
|
|
|
// if(this.isDragging){
|
|
|
|
// this._scrollIntoDragginItem(this.draggingItemId);
|
|
|
|
// }
|
|
|
|
// }, this.VALID_DROP_TIME);
|
2021-03-01 10:28:27 +01:00
|
|
|
});
|
|
|
|
drake.on('over',(el, container, source)=>{
|
|
|
|
try {
|
|
|
|
this.overcontainer = container.id;
|
|
|
|
} catch (error) {
|
|
|
|
this.overcontainer = null;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
drake.on('dragend',(el)=>{
|
|
|
|
this.isDragging = false;
|
|
|
|
this.draggingItemId = null;
|
|
|
|
this.overcontainer = null;
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-02-03 11:21:31 +01:00
|
|
|
}
|
|
|
|
|
2021-03-24 10:40:48 +01:00
|
|
|
|
|
|
|
|
2021-03-01 10:28:27 +01:00
|
|
|
overcontainer: string = null;
|
|
|
|
|
2021-03-24 10:40:48 +01:00
|
|
|
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);
|
|
|
|
|
2021-03-01 10:28:27 +01:00
|
|
|
|
2021-03-24 10:40:48 +01:00
|
|
|
// 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();
|
|
|
|
// }
|
|
|
|
}
|
2021-03-01 10:28:27 +01:00
|
|
|
|
|
|
|
private _findTocEntryById(id: string, tocentries: ToCEntry[]): ToCEntry{
|
|
|
|
if(!tocentries){
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
let tocEntryFound = tocentries.find(entry=>entry.id === id);
|
|
|
|
|
|
|
|
if(tocEntryFound){
|
|
|
|
return tocEntryFound;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(let entry of tocentries){
|
|
|
|
const result = this._findTocEntryById(id, entry.subEntries);
|
|
|
|
if(result){
|
|
|
|
tocEntryFound = result;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return tocEntryFound? tocEntryFound: null;
|
|
|
|
}
|
2021-02-03 11:21:31 +01:00
|
|
|
|
|
|
|
ngOnInit(): void {
|
2021-03-22 14:47:45 +01:00
|
|
|
|
2021-02-03 11:21:31 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ngOnChanges(changes: SimpleChanges) {
|
2021-03-22 14:47:45 +01:00
|
|
|
|
2021-02-03 11:21:31 +01:00
|
|
|
}
|
|
|
|
|
2021-02-04 09:33:03 +01:00
|
|
|
|
|
|
|
itemClicked(item: ToCEntry){
|
|
|
|
//leaf node
|
2021-02-04 11:22:52 +01:00
|
|
|
this.itemClick.emit(item);
|
2021-02-04 09:33:03 +01:00
|
|
|
}
|
|
|
|
|
2021-02-04 11:22:52 +01:00
|
|
|
// propagateClickToParent(childIds:ToCEntry[], currentItem: ToCEntry){
|
|
|
|
// childIds.push(currentItem);
|
|
|
|
// this.itemClick.emit(childIds);
|
|
|
|
// }
|
2021-02-04 09:33:03 +01:00
|
|
|
|
|
|
|
|
2021-02-12 12:23:39 +01:00
|
|
|
addNewEntry(tce: ToCEntry){
|
|
|
|
this.newEntry.emit(tce);
|
|
|
|
}
|
|
|
|
deleteEntry(currentLink: ToCEntry){
|
|
|
|
this.removeEntry.emit(currentLink);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
createNewEntry(foo: Foo){
|
|
|
|
this.createEntry.emit(foo);
|
|
|
|
}
|
2021-02-19 15:35:14 +01:00
|
|
|
onDataNeedsRefresh(){
|
|
|
|
this.dataNeedsRefresh.emit();
|
|
|
|
}
|
2021-03-03 11:10:11 +01:00
|
|
|
|
|
|
|
notifyUser(message:string){
|
|
|
|
this.snackbar.open(message, null, this._snackBarConfig);
|
|
|
|
}
|
|
|
|
|
|
|
|
private _snackBarConfig: MatSnackBarConfig = {
|
|
|
|
duration:2000
|
|
|
|
}
|
|
|
|
|
2021-03-23 11:39:04 +01:00
|
|
|
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;
|
|
|
|
}
|
2021-03-03 11:10:11 +01:00
|
|
|
|
|
|
|
|
2021-02-03 11:21:31 +01:00
|
|
|
}
|