import { CdkDragDrop, CdkDropList } from '@angular/cdk/drag-drop'; import { AfterViewInit, Component, EventEmitter, HostListener, Input, Output, ViewChild, ViewEncapsulation } from '@angular/core'; import { FormGroup } from '@angular/forms'; import { BaseApplication } from '@core/typings/application.typing'; import { BaseApplicationForLogic, FormDefinitionComponent, FormDefinitionForUi, FormioChangesWithCompKey } from '@features/configure-forms/form.typing'; import { FormBuilderActionEvent } from '@features/formio/form-builder/form-builder.typing'; import { FormBuilderService } from '@features/formio/form-builder/services/form-builder/form-builder.service'; import { LogicState } from '@features/logic-builder/logic-builder.typing'; import { ArrayHelpersService, SimpleStringMap, TypeToken } from '@yourcause/common'; @Component({ encapsulation: ViewEncapsulation.None, selector: 'gc-form-instance', templateUrl: './gc-form-instance.component.html', styleUrls: ['./gc-form-instance.component.scss'] }) export class GcFormInstanceComponent implements AfterViewInit { @Input() formId: number; @Input() readOnly: boolean; @Input() masked: boolean; @Input() tabFormGroup: FormGroup; @Input() hiddenCompKeys: string[]; @Input() showErrorSummary: boolean; @Input() translations: SimpleStringMap; @Input() formDefinition: FormDefinitionForUi; @Input() parentFields: Partial; @Input() validityState: LogicState; @Input() notAutoSave: boolean; @Input() uploadRequestStatusText: string; @Input() editable: boolean; @Input() isManagerEditingApplicantForm: boolean; @Input() isManagerForm: boolean; @Output() onValueChange = new EventEmitter(); @Output() hasErrorsChange = new EventEmitter(); @Output() componentDropped = new EventEmitter>(); @Output() componentActionClick = new EventEmitter(); @Output() dropListsChanged = new EventEmitter(); @ViewChild('instanceDropList') dropList: CdkDropList; trackBy = (_: number, comp: FormDefinitionComponent) => comp.key; dropLists: { list: CdkDropList; depth: number; }[] = []; $baseComponent = new TypeToken(); $dropLists = new TypeToken(); forceErrorSummaryUpdate: boolean; afterInit = false; shouldFlatten = false; @HostListener('window:resize') setShouldFlatten () { this.shouldFlatten = window.innerWidth <= 768; } constructor ( private arrayHelper: ArrayHelpersService, private formBuilderService: FormBuilderService ) { this.setShouldFlatten(); } ngAfterViewInit () { this.registerDropList(this.dropList, 0); } handleComponentDropped (drop: CdkDragDrop) { this.componentDropped.emit(drop); } registerDropList (list: CdkDropList, depth: number) { this.formBuilderService.patchDragDrop(list._dropListRef); this.dropLists.push({ list, depth }); this.reapplyDropListConnections(); } deregisterDropList (listToRemove: CdkDropList) { this.dropLists = this.dropLists.filter(({ list }) => { return list !== listToRemove; }); this.reapplyDropListConnections(); } private reapplyDropListConnections () { const fullList: string[] = []; const sortedLists = this.arrayHelper.sort(this.dropLists, 'depth', false); const dropLists = sortedLists .map(({ list }) => { fullList.push(list.id); list.element.nativeElement.id = list.id; list.connectedTo = fullList; return list; }); this.dropListsChanged.emit(dropLists); } valueChanged (details: FormioChangesWithCompKey) { this.onValueChange.emit(details); } validChanged () { this.forceErrorSummaryUpdate = true; setTimeout(() => { this.forceErrorSummaryUpdate = false; }); } onHasErrorsChange (hasErrors: boolean) { this.hasErrorsChange.emit(hasErrors); } }