argos/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-sect...

235 lines
6.6 KiB
TypeScript

import { OnDestroy } from '@angular/core';
import { Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
import { FormArray, FormGroup } from '@angular/forms';
import { Guid } from '@common/types/guid';
import { DragulaService } from 'ng2-dragula';
import { Subscription } from 'rxjs';
import { FieldEditorModel } from '../../../admin/field-editor-model';
import { FieldSetEditorModel } from '../../../admin/field-set-editor-model';
import { ToCEntry, ToCEntryType } from '../../../table-of-contents/table-of-contents-entry';
@Component({
selector: 'app-dataset-profile-editor-section-fieldset-component',
templateUrl: './dataset-profile-editor-section-fieldset.component.html',
styleUrls: ['./dataset-profile-editor-section-fieldset.component.scss']
})
export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnChanges, OnDestroy {
// @Input() form: FormGroup;
//@Input() dataModel: SectionEditorModel;
// @Input() indexPath: string;
@Input() viewOnly: boolean;
// @Input() numbering: string;
@Input() tocentry: ToCEntry;
@Output() selectedEntryId = new EventEmitter<string>();
@Output() dataNeedsRefresh = new EventEmitter<void> ();
@Output() removeFieldSet = new EventEmitter<string>();
@Output() addNewFieldSet = new EventEmitter<FormGroup>();
@Output() cloneFieldSet = new EventEmitter<FormGroup>();
// FIELDSET_PREFIX_ID="FIELDSET_PREFIX_ID";
// @Output() fieldsetAdded = new EventEmitter<String>(); //returns the id of the fieldset added
idprefix = "id";
readonly dragula_prefix = "dragulaid";
private subs = new Subscription();
private FIELDSETS = 'FIELDSETS';
constructor(
private dragulaService: DragulaService,
private myElement: ElementRef
)
{
if(this.dragulaService.find(this.FIELDSETS)){
this.dragulaService.destroy(this.FIELDSETS);
}
this.dragulaService.createGroup(this.FIELDSETS,{
moves:(el, container, handle)=>{
// if(this.viewOnly) return false; //uncomment if want to unable drag n drop in viewonly mode
if(el.id != (this.dragula_prefix+this.tocentry.id)) return false;
if(handle.className && handle.classList.contains('handle')) return true;
return false;
}
});
this.subs.add(this.dragulaService.drop(this.FIELDSETS).subscribe(obs=>{
(this.form.get('fieldSets') as FormArray).controls.forEach((e,i)=>{
e.get('ordinal').setValue(i);
});
// obs.
this.dataNeedsRefresh.emit();
return ;
}));
}
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);
}
form;
numbering;
private _selectedFieldSetId: string = null;
get selectedFieldSetId(){
return this._selectedFieldSetId;
}
set selectedFieldSetId(id: string){
if(id === this._selectedFieldSetId) return;
this._selectedFieldSetId = id;
this.selectedEntryId.emit(this._selectedFieldSetId);
}
private _findParentSection():FormGroup{
const parent = this.form.parent;
return parent;
}
private initialize(){
if(this.tocentry.type === ToCEntryType.Section){
this.form = this.tocentry.form;
this.numbering = this.tocentry.numbering;
this._selectedFieldSetId = null;
// this._scrollToElement(this.tocentry.id);
this._scrollOnTop();
}else if(this.tocentry.type === ToCEntryType.FieldSet){
this.form = this.tocentry.form.parent.parent;
const numberingArray = this.tocentry.numbering.split('.');
if(numberingArray.length){
numberingArray.splice(numberingArray.length-1);
this.numbering = numberingArray.join('.');
}else{
// console.warn('!not found numbering');
}
this.selectedFieldSetId = this.tocentry.id;
this._scrollToElement(this.selectedFieldSetId);
}else{//scroll on top
this._scrollOnTop();
}
}
private _scrollToElement(id: string){
let el = this.myElement.nativeElement.querySelector("#"+this.idprefix+id);
// let el = this.myElement.nativeElement.getElementbyId (this.selectedFieldSetId);
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", block:'start'});
}
}, 700);
}
}
private _scrollOnTop(){
setTimeout(() => {
const el = this.myElement.nativeElement.querySelector('#topofcontainer');
if(el){
el.scrollIntoView({behavior:'smooth', block:'end'})
}
},200);
}
ngOnInit() {
}
onRemoveFieldSet(fieldsetId: string){
this.removeFieldSet.emit(fieldsetId);
}
onCloneFieldSet(fieldset: FormGroup){
this.cloneFieldSet.emit(fieldset);
}
onAddFieldSet(){
this.addNewFieldSet.emit(this.form);
}
addFieldSetAfter(afterOrdinal: number, afterIndex: number):void{
const field: FieldEditorModel = new FieldEditorModel();
field.id = Guid.create().toString();
field.ordinal = 0;//first filed in the fields list
const fieldForm = field.buildForm();
//give fieldset id and ordinal
const fieldSet: FieldSetEditorModel = new FieldSetEditorModel();
const fieldSetId = Guid.create().toString();
fieldSet.id = fieldSetId;
fieldSet.ordinal = afterOrdinal < 0? 0 :afterOrdinal;
const parentArray = this.form.get('fieldSets') as FormArray;
parentArray.controls.forEach(fieldset=>{
const ordinalControl = fieldset.get('ordinal');
const ordinalValue = ordinalControl.value;
if(ordinalValue > afterOrdinal){
ordinalControl.setValue(ordinalValue +1);
}
});
const fieldsetForm = fieldSet.buildForm();
(fieldsetForm.get('fields') as FormArray).push(fieldForm);
const index = afterOrdinal < 0 ? 0: afterIndex +1;
parentArray.insert(index, fieldsetForm);
this.dataNeedsRefresh.emit();
setTimeout(() => {
this.selectedFieldSetId = fieldSetId;
}, 200);
}
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;
}
}