import { LocaleService } from '@farris/ui-locale'; /* * @Author: 疯狂秀才(Lucas Huang) * @Date: 2018-12-04 10:43:42 * @LastEditors: 疯狂秀才(Lucas Huang) * @LastEditTime: 2019-10-17 17:34:39 * @Company: Inspur * @Version: v0.0.1 */ import { Component, Input, EventEmitter, Output, Injector, ElementRef, ComponentFactoryResolver, TemplateRef, ViewChild, ComponentRef, forwardRef, OnInit, HostListener, HostBinding, ChangeDetectorRef } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { cloneDeep } from 'lodash-es'; import { BsModalRef, BsModalService } from '@farris/ui-modal'; import { LookupComponent } from '@farris/ui-lookup'; import { FilterCondition, Compare } from '@farris/ui-common/types'; import { FilterService } from './services/filter.service'; import { FilterEditorComponent } from './components/filter-editor.component'; import { CommonUtils } from '@farris/ui-common'; export const FILTER_LOOKUPGRID_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => FilterComponent), multi: true }; export interface FILTER_FIELD_EDITOR { type: 'select' | 'combo-tree' | 'lookup'; options?: any; } @Component({ selector: 'filter,filter-textbox', templateUrl: 'filter.component.html', providers: [ FILTER_LOOKUPGRID_VALUE_ACCESSOR, FilterService ], styles: [ ` .lookup-clear { cursor: pointer; background: #fff!important;} .lookup-clear:hover { background: #e9ecef!important;} ` ] }) export class FilterComponent extends LookupComponent implements OnInit { @HostBinding('class') hostCls = 'f-cmp-inputgroup'; text = ''; conditions: FilterCondition[] = []; originalData: FilterCondition[] = []; /** 字段数据 */ @Input() columns: {label: string, value: string}[] = []; @Input() showCode = false; @Input() showSql = false; @Input() enableExpress = false; @Input() fieldEditor: FILTER_FIELD_EDITOR = { type: 'select', options: {}}; @Input() enableClear = true; @Input() returnType: 'object' | 'string' = 'object'; @Output() openDialog = new EventEmitter(); @Output() showExpress = new EventEmitter(); @ViewChild('defaultButtonRef') btnRef: TemplateRef; @ViewChild('txtbox') textbox: ElementRef; showClearButton = false; cd: ChangeDetectorRef = null; dlgRef: BsModalRef; filterEditorRef: ComponentRef; localeService: LocaleService; commonUtils: CommonUtils = null; constructor( injector: Injector, private cfr: ComponentFactoryResolver, private modalService: BsModalService, public el: ElementRef, private filterService: FilterService) { super(injector, el); this.filterService.conditionsChanged.subscribe(conditionList => { this.conditions = conditionList; }); this.localeService = this.injector.get(LocaleService); this.cd = this.injector.get(ChangeDetectorRef); this.commonUtils = this.injector.get(CommonUtils, null) || new CommonUtils(); } ngOnInit() { } @HostListener('mouseover', ['$event']) onmouseover(event: any) { this.showClearButton = true; } @HostListener('mouseleave', ['$event']) onmouseleave(event: any) { this.showClearButton = false; } showDialog() { if (!this.disabled) { if (this.fieldEditor && this.fieldEditor.type === 'combo-tree') { this.fieldEditor.options = this.fieldEditor.options || {}; if (this.fieldEditor.options.autoWidth === undefined) { this.fieldEditor.options.autoWidth = true; } if (!this.fieldEditor.options.columns) { this.fieldEditor.options.columns = [ { field: 'label', title: 'label', width: 100 } ]; } if (!this.fieldEditor.options.textField) { this.fieldEditor.options.textField = 'label'; } if (!this.fieldEditor.options.idField) { this.fieldEditor.options.idField = 'value'; } } const filterEditorFactory = this.cfr.resolveComponentFactory(FilterEditorComponent); this.filterEditorRef = filterEditorFactory.create(this.injector); this.filterEditorRef.instance.columns = this.columns; this.filterEditorRef.instance.conditions = this.conditions; this.originalData = cloneDeep(this.conditions); this.dlgRef = this.modalService.show(this.filterEditorRef, { width: 800, height: 500, title: this.localeService.getValue('filterEditor.title'), enableScroll: false, minHeight: 398, minWidth: 798, iconCls: 'k-icon k-i-filter', buttons: this.btnRef, dialogFooterStyles: { background: '#F4F6F9' }, buttonAlign: 'right', initialState: { showCode: this.showCode, showSql: this.showSql, enableExpress: this.enableExpress, fieldEditor: this.fieldEditor }, closed: (isCloseButtonClick: boolean) => { if (isCloseButtonClick) { this.cancel(); } } }); this.filterEditorRef.instance.height = this.dlgRef.dialog.instance.getContainerSize().height; this.filterEditorRef.instance.showExpress.subscribe(($event) => { this.showExpress.emit($event); }); this.dlgRef.dialog.instance.resized.subscribe( size => { this.filterEditorRef.instance.height = size.containerHeight; }); this.filterEditorRef.changeDetectorRef.detectChanges(); this.dlgRef.dialog.changeDetectorRef.reattach(); this.openDialog.emit(); } } writeValue(val: any) { if (val) { if (typeof val === 'string') { val = JSON.parse(val); } this.conditions = val || []; this.text = this.commonUtils.buildSqlWhere(this.conditions); } } save() { if (this.conditions.length) { this.conditions = this.conditions.filter(c => c.filterField); // 转换in 操作符的value 值 this.conditions = this.conditions.map(con => { const cp = parseInt('' + con.compare, 10); if (cp === Compare.In || cp === Compare.NotIn) { con.value = con.value.replace(/,/g, '\r\n'); } return con; }); this.text = this.commonUtils.buildSqlWhere(this.conditions); } else { this.text = ''; } if (this.cd) { this.cd.detectChanges(); } this.closeDialog(); } cancel() { this.conditions = this.originalData; this.closeDialog(); } closeDialog() { this.updateModel(); this.filterEditorRef = null; this.dlgRef.close(); } clear() { this.text = ''; this.conditions = []; this.updateModel(); } private updateModel() { let v: any = this.conditions; if (this.returnType === 'string') { v = JSON.stringify(this.conditions); } this.onModelChange(v); this.onModelTouched(v); } }