268 lines
7.2 KiB
TypeScript
268 lines
7.2 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 { isNullOrUndefined } from '@swimlane/ngx-datatable';
|
|
import { DragulaService } from 'ng2-dragula';
|
|
import { pipe, Subject, Subscription } from 'rxjs';
|
|
import { debounceTime, delay, tap } from 'rxjs/operators';
|
|
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';
|
|
import { GENERAL_ANIMATIONS } from '../../animations/animations';
|
|
|
|
@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'],
|
|
animations:[GENERAL_ANIMATIONS]
|
|
})
|
|
|
|
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';
|
|
|
|
private initializer = new Subject<void>();
|
|
private scroller = new Subject<string>();
|
|
// private $selectedFieldsetId = new Subject<string>();
|
|
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 ;
|
|
}));
|
|
const initializerSub = this.initializer
|
|
.pipe(
|
|
debounceTime(100)
|
|
)
|
|
.subscribe(() =>{
|
|
this.initialize();
|
|
});
|
|
this.subs.add(initializerSub);
|
|
this.subs.add(
|
|
this.scroller
|
|
.pipe(debounceTime(700))
|
|
.subscribe(id => {
|
|
if(isNullOrUndefined(id)){
|
|
this._scrollOnTop();
|
|
return ;
|
|
}
|
|
this._scrollToElement(id);
|
|
})
|
|
);
|
|
|
|
// this.subs.add(
|
|
// this.$selectedFieldsetId
|
|
// .pipe(
|
|
// debounceTime(100)
|
|
// )
|
|
// .subscribe(id => this.selectedEntryId.emit(id))
|
|
// );
|
|
|
|
}
|
|
ngOnDestroy(){
|
|
// console.log('elemement destroyed -->');
|
|
|
|
this.subs.unsubscribe();
|
|
}
|
|
ngOnChanges(changes: SimpleChanges): void {
|
|
this.initializer.next();
|
|
}
|
|
|
|
|
|
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(id);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 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.scroller.next(null);
|
|
this._scrollOnTop(true);
|
|
}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);
|
|
this.scroller.next(this.tocentry.id);
|
|
}else{//scroll on top
|
|
// this._scrollOnTop();
|
|
this.scroller.next(null);
|
|
}
|
|
}
|
|
|
|
private _scrollToElement(id: string){
|
|
let el = this.myElement.nativeElement.querySelector("#"+this.idprefix+id);
|
|
if(el){
|
|
el.scrollIntoView({behavior: "smooth", block:'start'});
|
|
}
|
|
}
|
|
private _scrollOnTop(instant?: boolean){
|
|
const el = this.myElement.nativeElement.querySelector('#topofcontainer');
|
|
if(el){
|
|
if(instant){
|
|
el.scrollIntoView({ block:'end'});
|
|
}else{
|
|
el.scrollIntoView({behavior:'smooth', block:'end'});
|
|
}
|
|
}
|
|
}
|
|
ngOnInit() {
|
|
|
|
}
|
|
|
|
onRemoveFieldSet(fieldsetId: string){
|
|
this.removeFieldSet.emit(fieldsetId);
|
|
}
|
|
|
|
onCloneFieldSet(fieldset: FormGroup){
|
|
this.cloneFieldSet.emit(fieldset);
|
|
}
|
|
onAddFieldSet(){
|
|
// this.addNewFieldSet.emit(this.form);
|
|
try{
|
|
const length = (this.form.get('fieldSets') as FormArray).length;
|
|
if(length === 0){
|
|
this.addFieldSetAfter(-9999, 0);
|
|
return;
|
|
}
|
|
else{
|
|
const lastElement = (this.form.get('fieldSets') as FormArray).at(length -1);
|
|
this.addFieldSetAfter(lastElement.get('ordinal').value, length-1);
|
|
}
|
|
} catch {}
|
|
}
|
|
|
|
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();
|
|
|
|
// this.selectedFieldSetId = fieldSetId;
|
|
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;
|
|
}
|
|
}
|