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(); @Output() dataNeedsRefresh = new EventEmitter (); @Output() removeFieldSet = new EventEmitter(); @Output() addNewFieldSet = new EventEmitter(); @Output() cloneFieldSet = new EventEmitter(); // FIELDSET_PREFIX_ID="FIELDSET_PREFIX_ID"; // @Output() fieldsetAdded = new EventEmitter(); //returns the id of the fieldset added idprefix = "id"; readonly dragula_prefix = "dragulaid"; private subs = new Subscription(); private FIELDSETS = 'FIELDSETS'; private initializer = new Subject(); private scroller = new Subject(); // private $selectedFieldsetId = new Subject(); 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; } }