2021-02-24 15:56:14 +01:00
|
|
|
import { CdkDrag, CdkDragDrop, CdkDropList, moveItemInArray } from '@angular/cdk/drag-drop';
|
2021-02-04 11:22:52 +01:00
|
|
|
import { DOCUMENT } from '@angular/common';
|
2021-02-24 15:56:14 +01:00
|
|
|
import { Component, EventEmitter, Inject, Input, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core';
|
2021-03-12 17:19:51 +01:00
|
|
|
import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms';
|
2021-02-04 11:22:52 +01:00
|
|
|
import { BaseComponent } from '@common/base/base.component';
|
2021-02-12 12:23:39 +01:00
|
|
|
import { Foo, ToCEntry, ToCEntryType } from '../table-of-contents-entry';
|
2021-02-04 11:22:52 +01:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'app-dataset-profile-table-of-contents-internal-section',
|
|
|
|
styleUrls: ['./table-of-contents-internal-section.scss'],
|
|
|
|
templateUrl: './table-of-contents-internal-section.html'
|
|
|
|
})
|
|
|
|
export class DatasetProfileTableOfContentsInternalSection extends BaseComponent implements OnInit {
|
|
|
|
|
|
|
|
@Input() links: ToCEntry[];
|
|
|
|
@Output() itemClick = new EventEmitter<ToCEntry>();
|
2021-02-12 12:23:39 +01:00
|
|
|
@Output() newEntry = new EventEmitter<ToCEntry>();
|
|
|
|
@Output() removeEntry = new EventEmitter<ToCEntry>();
|
|
|
|
|
|
|
|
@Output() createFooEntry = new EventEmitter<Foo>();
|
|
|
|
|
2021-02-19 15:35:14 +01:00
|
|
|
@Output() dataNeedsRefresh = new EventEmitter<void>();
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-02-12 12:23:39 +01:00
|
|
|
@Input() parentLink: ToCEntry;
|
|
|
|
@Input() itemSelected: ToCEntry;
|
2021-03-01 10:28:27 +01:00
|
|
|
@Input() DRAGULA_ITEM_ID_PREFIX;
|
|
|
|
@Input() overContainerId: string;
|
|
|
|
@Input() isDragging;
|
|
|
|
@Input() draggingItemId: string;
|
|
|
|
@Input() parentRootId: string;
|
2021-02-04 11:22:52 +01:00
|
|
|
|
2021-03-12 17:19:51 +01:00
|
|
|
@Input() colorizeInvalid:boolean = false;
|
|
|
|
|
2021-02-15 18:16:48 +01:00
|
|
|
@Input() viewOnly: boolean;
|
2021-02-24 15:56:14 +01:00
|
|
|
// @Input() dropListGroup: Set<string> = new Set<string>();
|
|
|
|
@Input() dropListGroup: string[];
|
|
|
|
|
|
|
|
@Input() dragHoveringOver: boolean = false;
|
|
|
|
@Input() depth: number = 0;
|
|
|
|
|
2021-03-03 11:10:11 +01:00
|
|
|
// @Input() dropListStruct: { id: string, depth: number}[] = [];
|
2021-02-15 18:16:48 +01:00
|
|
|
|
2021-02-04 11:22:52 +01:00
|
|
|
constructor(
|
|
|
|
@Inject(DOCUMENT) private _document: Document) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2021-02-12 12:23:39 +01:00
|
|
|
tocEntryType = ToCEntryType;
|
2021-02-04 11:22:52 +01:00
|
|
|
|
2021-03-03 11:10:11 +01:00
|
|
|
// showStructs(){
|
|
|
|
// console.log(this.dropListStruct.sort(this.compareFn));
|
|
|
|
// }
|
2021-02-24 15:56:14 +01:00
|
|
|
|
2021-03-03 11:10:11 +01:00
|
|
|
// get orderedListGroup(){
|
|
|
|
// return this.dropListStruct.sort(this.compareFn).map(element=> element.id);
|
|
|
|
// }
|
2021-02-24 15:56:14 +01:00
|
|
|
|
|
|
|
|
|
|
|
compareFn(a, b){
|
|
|
|
if(a.depth> b.depth) return -1;
|
|
|
|
if(a.depth< b.depth) return 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-02-04 11:22:52 +01:00
|
|
|
ngOnInit(): void {
|
2021-02-24 15:56:14 +01:00
|
|
|
// if(this.parentLink.id && this.dropListGroup){
|
|
|
|
// if(!this.dropListGroup.includes(this.parentLink.id)){
|
|
|
|
// this.dropListGroup.unshift(this.parentLink.id);//TODO
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
2021-03-03 11:10:11 +01:00
|
|
|
// this.dropListStruct.push({
|
|
|
|
// id: this.parentLink.id,
|
|
|
|
// depth: this.depth
|
|
|
|
// });
|
2021-02-04 11:22:52 +01:00
|
|
|
|
2021-02-24 15:56:14 +01:00
|
|
|
// if(this.links){
|
|
|
|
// this.links.forEach(link=>{
|
|
|
|
// this.dropListGroup.push(link.id);
|
|
|
|
// })
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// this.dropListGroup.add(this.parentLink.id)
|
2021-02-04 11:22:52 +01:00
|
|
|
}
|
|
|
|
|
2021-02-24 15:56:14 +01:00
|
|
|
showDroplists(){
|
|
|
|
console.log(this.dropListGroup);
|
|
|
|
}
|
|
|
|
|
|
|
|
hoveroverEnter(){
|
|
|
|
// console.log('user hovering drag over', this.parentLink.id, this.parentLink.label);
|
|
|
|
this.dragHoveringOver = true;
|
|
|
|
}
|
|
|
|
hoveroverLeft(){
|
|
|
|
this.dragHoveringOver = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
fellowContainers(){
|
|
|
|
return this.dropListGroup.filter(dl=> dl != this.parentLink.id);
|
|
|
|
}
|
2021-02-04 11:22:52 +01:00
|
|
|
ngOnChanges(changes: SimpleChanges) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-02-24 15:56:14 +01:00
|
|
|
// get grouListIds(){
|
|
|
|
// return Array.from(this.dropListGroup);
|
|
|
|
// }
|
2021-02-04 11:22:52 +01:00
|
|
|
itemClicked(item: ToCEntry) {
|
|
|
|
//leaf node
|
|
|
|
this.itemClick.emit(item);
|
|
|
|
}
|
|
|
|
|
2021-02-12 12:23:39 +01:00
|
|
|
deleteEntry(currentLink: ToCEntry){
|
|
|
|
this.removeEntry.emit(currentLink);
|
|
|
|
}
|
|
|
|
|
|
|
|
createNewEntry(foo: Foo){
|
|
|
|
this.createFooEntry.emit(foo);
|
|
|
|
}
|
2021-02-17 17:39:07 +01:00
|
|
|
|
|
|
|
tocEntryIsChildOf(testingChild: ToCEntry,parent: ToCEntry): boolean{
|
|
|
|
|
|
|
|
if(!testingChild || !parent) return false;
|
|
|
|
|
|
|
|
if(testingChild.id == parent.id){return true;}
|
|
|
|
|
|
|
|
if(parent.subEntries){
|
|
|
|
let childFound:boolean = false;
|
|
|
|
|
|
|
|
parent.subEntries.forEach(subEntry=>{
|
|
|
|
if(this.tocEntryIsChildOf(testingChild, subEntry)){
|
|
|
|
childFound = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
return childFound;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2021-02-19 15:35:14 +01:00
|
|
|
|
|
|
|
get selectedItemInLinks(){
|
|
|
|
if(!this.links || !this.itemSelected) return false;
|
|
|
|
|
|
|
|
const link = this.links.find(l=>l.id === this.itemSelected.id);
|
|
|
|
|
|
|
|
if(link) return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-02-24 15:56:14 +01:00
|
|
|
// appendAndGetDroplists(dropList: CdkDropList){
|
|
|
|
// this.dropListGroup.push(dropList);
|
|
|
|
// return this.dropListGroup;
|
|
|
|
// }
|
2021-02-19 15:35:14 +01:00
|
|
|
|
|
|
|
drop(event: CdkDragDrop<string[]>) {
|
2021-02-24 15:56:14 +01:00
|
|
|
// if(!this.links || !this.links.length) return;
|
|
|
|
|
|
|
|
if(event.container === event.previousContainer){
|
|
|
|
moveItemInArray(this.links, event.previousIndex, event.currentIndex);
|
|
|
|
|
|
|
|
let arrayToUpdate: FormArray = this.links[0].form.parent as FormArray;
|
|
|
|
// if(this.parentLink && this.parentLink.form){
|
|
|
|
// switch(this.parentLink.subEntriesType){
|
|
|
|
// case this.tocEntryType.Field:
|
|
|
|
// arrayToUpdate = (this.parentLink.form.get('fields') as FormArray);
|
|
|
|
// break;
|
|
|
|
// case this.tocEntryType.FieldSet:
|
|
|
|
// arrayToUpdate = (this.parentLink.form.get('fieldSets') as FormArray);
|
|
|
|
// break;
|
|
|
|
// case this.tocEntryType.Section:
|
|
|
|
// arrayToUpdate = (this.parentLink.form.get('sections') as FormArray);
|
|
|
|
// break
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
if(arrayToUpdate.controls){
|
|
|
|
moveItemInArray(arrayToUpdate.controls, event.previousIndex, event.currentIndex);
|
|
|
|
//update ordinality
|
|
|
|
arrayToUpdate.controls.forEach((element,idx ) => {
|
|
|
|
element.get('ordinal').setValue(idx);
|
|
|
|
element.updateValueAndValidity();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
this.dataNeedsRefresh.emit();
|
|
|
|
}else{
|
|
|
|
console.log('not same container');
|
2021-02-19 15:35:14 +01:00
|
|
|
}
|
|
|
|
|
2021-02-24 15:56:14 +01:00
|
|
|
console.log(event.container.id);
|
2021-02-19 15:35:14 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
onDataNeedsRefresh(){
|
|
|
|
this.dataNeedsRefresh.emit();
|
|
|
|
}
|
2021-03-01 10:28:27 +01:00
|
|
|
|
|
|
|
|
|
|
|
get hoveringOverParent(){
|
|
|
|
if(!this.overContainerId) return false;
|
|
|
|
const child = this._findTocEntryById(this.overContainerId, this.parentLink.subEntries);
|
|
|
|
if(!child) return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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-03-12 17:19:51 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
colorError():boolean{
|
|
|
|
|
|
|
|
if(!this.colorizeInvalid) return false;
|
|
|
|
|
|
|
|
const form = this.parentLink.form;
|
2021-03-22 14:47:45 +01:00
|
|
|
if((!form || form.valid || !form.touched) && this.parentLink.type !== this.tocEntryType.Page) return false;
|
2021-03-12 17:19:51 +01:00
|
|
|
|
|
|
|
const allFieldsAreTouched = this.allFieldsAreTouched(form);
|
|
|
|
|
|
|
|
//fieldset may have errros that are inside its controls and not in the fieldsetFormGroup
|
|
|
|
if(this.parentLink.type === this.tocEntryType.FieldSet && allFieldsAreTouched) return true;
|
|
|
|
|
|
|
|
if(form.errors && allFieldsAreTouched) return true;
|
|
|
|
|
2021-03-22 14:47:45 +01:00
|
|
|
//check if page has sections
|
|
|
|
if(this.parentLink.type === this.tocEntryType.Page && allFieldsAreTouched){
|
|
|
|
const rootForm = form.root;
|
|
|
|
if(rootForm){
|
|
|
|
const sections = rootForm.get('sections') as FormArray;
|
|
|
|
if(!sections.controls.find(section=>section.get('page').value === this.parentLink.id)){
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-03-12 17:19:51 +01:00
|
|
|
|
|
|
|
|
2021-03-22 14:47:45 +01:00
|
|
|
//checking first child form controls if have errors
|
2021-03-12 17:19:51 +01:00
|
|
|
let hasErrors = false;
|
|
|
|
if(allFieldsAreTouched){
|
|
|
|
if(form instanceof FormGroup){
|
|
|
|
const formGroup = form as FormGroup;
|
|
|
|
|
|
|
|
const controls = Object.keys(formGroup.controls);
|
|
|
|
|
|
|
|
controls.forEach(control=>{
|
|
|
|
if(formGroup.get(control).errors){
|
|
|
|
hasErrors = true;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return hasErrors;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
allFieldsAreTouched(aControl:AbstractControl){//auto na testaroume
|
|
|
|
|
|
|
|
if(!aControl|| aControl.untouched) return false;
|
|
|
|
|
|
|
|
if(aControl instanceof FormControl){
|
|
|
|
return aControl.touched;
|
|
|
|
}else if(aControl instanceof FormGroup){
|
|
|
|
const controlKeys = Object.keys((aControl as FormGroup).controls);
|
|
|
|
let areAllTouched = true;
|
|
|
|
controlKeys.forEach(key=>{
|
|
|
|
if(!this.allFieldsAreTouched(aControl.get(key))){
|
|
|
|
areAllTouched = false;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
// const areAllTouched = controlKeys.reduce((acc, key)=>acc && this._allFieldsAreTouched(aControl.get(key)), true);
|
|
|
|
return areAllTouched;
|
|
|
|
|
|
|
|
}else if(aControl instanceof FormArray){
|
|
|
|
const controls = (aControl as FormArray).controls;
|
|
|
|
// const areAllTouched = controls.reduce((acc, control)=>acc && this._allFieldsAreTouched(control), true);
|
|
|
|
let areAllTouched = true;
|
|
|
|
// controls.reduce((acc, control)=>acc && this._allFieldsAreTouched(control), true);
|
|
|
|
controls.forEach(control=>{
|
|
|
|
if(!this.allFieldsAreTouched(control)){
|
|
|
|
areAllTouched = false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return areAllTouched;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2021-02-04 11:22:52 +01:00
|
|
|
}
|