import { LocaleService } from '@farris/ui-locale'; import { BsModalService } from '@farris/ui-modal'; import { Injectable, Injector, ComponentFactoryResolver, ComponentRef } from '@angular/core'; import { Subject } from 'rxjs'; import { EnumEditorComponent } from './enum-editor.component'; import { cloneDeep } from 'lodash-es'; export enum EnumOutType { 'array', 'object' } @Injectable({ providedIn: 'root' }) export class EnumEditorService { enumEditorRef: ComponentRef = null; dlgRef = null; originalData = []; textField = 'name'; valueField = 'value'; outType = EnumOutType.array; dataChanged = new Subject(); constructor(private injector: Injector, private cfr: ComponentFactoryResolver, private modalService: BsModalService, private localeService: LocaleService) { } showDialog(enumData = [], options = {}) { enumData = this.toJSON(enumData); const enumEditorFactory = this.cfr.resolveComponentFactory(EnumEditorComponent); this.enumEditorRef = enumEditorFactory.create(this.injector); this.enumEditorRef.instance.data = enumData; this.originalData = cloneDeep(enumData); this.textField = options['textField'] || 'name'; this.valueField = options['valueField'] || 'value'; this.outType = options['outType'] || EnumOutType.array; options['showSortBtns'] = this.outType === EnumOutType.array; this.dlgRef = this.modalService.show(this.enumEditorRef, { width: 800, height: 500, title: this.localeService.getValue('enumEditor.title'), enableScroll: false, minHeight: 398, minWidth: 798, iconCls: 'f-icon f-icon-top_developmenttool', buttons: [ { text: this.localeService.getValue('enumEditor.cancelButton'), cls: 'btn btn-outline-secondary', handle: () => { this.cancel(); } }, { text: this.localeService.getValue('enumEditor.okButton'), cls: 'btn btn-primary', handle: () => { this.save(); } } ], initialState: options, dialogFooterStyles: { background: '#F4F6F9' }, buttonAlign: 'right', closed: (isCloseButtonClick: boolean) => { if (isCloseButtonClick) { this.cancel(); } } }); this.enumEditorRef.instance.height = this.dlgRef.dialog.instance.getContainerSize().height; this.dlgRef.dialog.instance.resized.subscribe(size => { this.enumEditorRef.instance.height = size.containerHeight; }); this.enumEditorRef.changeDetectorRef.detectChanges(); this.dlgRef.dialog.changeDetectorRef.reattach(); // this.openDialog.emit(); } cancel() { this._dataChanged(this.originalData); this.dlgRef.close(); } save() { const enumData = this.enumEditorRef.instance.data; this._dataChanged(enumData); this.dlgRef.close(); } private _dataChanged(enumData: any) { const str = this.toString(enumData); this.dataChanged.next(str); } toString(enumData: any) { if (enumData && enumData.length) { if (this.outType === EnumOutType.array) { return JSON.stringify(enumData); } else { const obj = enumData.reduce((r, c) => { r[c[this.valueField]] = c[this.textField]; return r; }, {}); return JSON.stringify(obj); } } return ''; } toJSON(val: any) { let enumData = []; if (val) { if (typeof val === 'string') { try { enumData = JSON.parse(val); if (this.outType === EnumOutType.object) { enumData = this.convertObject2Array(enumData); } } catch (e) { enumData = []; console.warn(e); } } else { if (Array.isArray(val)) { enumData = val; } else { enumData = this.convertObject2Array(val); } } } return enumData; } private convertObject2Array(obj: any) { const _enumData = []; Object.keys(obj).forEach(n => { _enumData.push({ [this.valueField]: n, [this.textField]: obj[n] }); }); return _enumData; } }