UNPKG

ngx-ui-hero

Version:

Simple, fast and reliable utilities for Angular.

85 lines 17.8 kB
import { filter, uniqBy } from 'lodash-es'; import { Component, EventEmitter, Input, Output } from '@angular/core'; import { ColumnFilterModel, EqualsOperator } from '../../models/column-filter.model'; import { DataGridColumnModel } from '../../models/data-grid-column.model'; import * as _ from 'lodash'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "@angular/forms"; import * as i3 from "../../../ui/directives/debounce.directive"; import * as i4 from "../../../ui/directives/click-outside.directive"; export class ColumnFilterComponent { constructor() { this.onChange = new EventEmitter(); this.filterPlaceholder = 'Filter...'; this.emptyResultsMessage = 'No results found at this moment.'; this.search = ''; } ngOnInit() { this.initializeOptions(); } onSearch() { if (!this.search || this.search.length == 0) { this.clearFilters(); return; } this.filteredOptions = this.options.filter(x => x.toString().toUpperCase().indexOf(this.search.toUpperCase()) >= 0); } onClickOutside() { this.column.isFiltersOpenned = false; } select(item) { this.column.simpleFilter = new ColumnFilterModel(item, this.column, new EqualsOperator()); this.onChange.emit(this.column); this.clearFilters(); } removeSimpleFilter() { this.column.simpleFilter = null; this.onChange.emit(this.column); } initializeOptions() { if (!this.data || this.data.length == 0) return; this.options = this.data.map((row, index) => { if (this.column.render) return this.column.render(row, this.renderPropertyValue(this.column.data, row), index); return this.renderPropertyValue(this.column.data, row); }); this.options = uniqBy(this.options, x => x); this.options = filter(this.options, x => x != undefined && x != null); this.options = _.orderBy(this.options, x => x); this.clearFilters(); } renderPropertyValue(propertyPath, object) { let parts = propertyPath.split("."); let property = object || {}; for (let i = 0; i < parts.length; i++) { if (!property) { return null; } property = property[parts[i]]; } return property; } clearFilters() { this.search = ''; this.filteredOptions = Object.assign([], this.options); } } ColumnFilterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ColumnFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); ColumnFilterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ColumnFilterComponent, selector: "ui-column-filter", inputs: { data: "data", column: "column", filterPlaceholder: "filterPlaceholder", emptyResultsMessage: "emptyResultsMessage" }, outputs: { onChange: "onChange" }, ngImport: i0, template: "<div class=\"filters-container\" (clickOutside)=\"onClickOutside()\">\n <div class=\"search\">\n <div class=\"input-group\">\n <div class=\"input-group-prepend\">\n <span class=\"input-group-text\"><i class=\"fa fa-search\"></i></span>\n </div>\n <input type=\"text\" class=\"form-control form-control-sm\" [placeholder]=\"filterPlaceholder\" [(ngModel)]=\"search\" debounce (callback)=\"onSearch()\" />\n </div>\n </div>\n <div class=\"filters d-flex flex-wrap\" *ngIf=\"column.simpleFilter || column.customFilters?.length > 0\">\n <button class=\"btn btn-primary btn-sm text-truncate\" *ngIf=\"column.simpleFilter\" (click)=\"removeSimpleFilter()\">\n <i class=\"fa fa-times\"></i>\n <span class=\"ml-1\" [innerHtml]=\"column.simpleFilter.filter\"></span>\n </button>\n </div>\n <div class=\"options\">\n <div class=\"option text-truncate\" *ngFor=\"let item of filteredOptions\" [title]=\"item\" (click)=\"select(item)\" [innerHtml]=\"item\"></div>\n <p class=\"mb-0 p-3\" *ngIf=\"!filteredOptions || filteredOptions.length == 0\">{{emptyResultsMessage}}</p>\n </div>\n</div>", styles: [".filters-container{margin:-8px -12px}.filters-container .search{background-color:#f9f9f9;padding:10px;border-radius:.3rem .3rem 0 0;border-bottom:1px solid #CCC}.filters-container .options{background-color:#fff;max-height:200px;overflow-y:auto;overflow-x:hidden;border-radius:0 0 .3rem .3rem}.filters-container .options .option{cursor:pointer;padding:7px 10px;font-size:14px;max-width:300px}.filters-container .options .option:hover{background-color:#f9f9f9}.filters-container .filters{background-color:#d4e9ff;padding:10px;border-bottom:1px solid #aed5ff}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.DebounceDirective, selector: "[debounce]", inputs: ["delay"], outputs: ["callback", "arrowsCallback"] }, { kind: "directive", type: i4.ClickOutsideDirective, selector: "[clickOutside]", inputs: ["clickOutsideEnabled", "attachOutsideOnClick", "delayClickOutsideInit", "emitOnBlur", "exclude", "excludeBeforeClick", "clickOutsideEvents"], outputs: ["clickOutside"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ColumnFilterComponent, decorators: [{ type: Component, args: [{ selector: 'ui-column-filter', template: "<div class=\"filters-container\" (clickOutside)=\"onClickOutside()\">\n <div class=\"search\">\n <div class=\"input-group\">\n <div class=\"input-group-prepend\">\n <span class=\"input-group-text\"><i class=\"fa fa-search\"></i></span>\n </div>\n <input type=\"text\" class=\"form-control form-control-sm\" [placeholder]=\"filterPlaceholder\" [(ngModel)]=\"search\" debounce (callback)=\"onSearch()\" />\n </div>\n </div>\n <div class=\"filters d-flex flex-wrap\" *ngIf=\"column.simpleFilter || column.customFilters?.length > 0\">\n <button class=\"btn btn-primary btn-sm text-truncate\" *ngIf=\"column.simpleFilter\" (click)=\"removeSimpleFilter()\">\n <i class=\"fa fa-times\"></i>\n <span class=\"ml-1\" [innerHtml]=\"column.simpleFilter.filter\"></span>\n </button>\n </div>\n <div class=\"options\">\n <div class=\"option text-truncate\" *ngFor=\"let item of filteredOptions\" [title]=\"item\" (click)=\"select(item)\" [innerHtml]=\"item\"></div>\n <p class=\"mb-0 p-3\" *ngIf=\"!filteredOptions || filteredOptions.length == 0\">{{emptyResultsMessage}}</p>\n </div>\n</div>", styles: [".filters-container{margin:-8px -12px}.filters-container .search{background-color:#f9f9f9;padding:10px;border-radius:.3rem .3rem 0 0;border-bottom:1px solid #CCC}.filters-container .options{background-color:#fff;max-height:200px;overflow-y:auto;overflow-x:hidden;border-radius:0 0 .3rem .3rem}.filters-container .options .option{cursor:pointer;padding:7px 10px;font-size:14px;max-width:300px}.filters-container .options .option:hover{background-color:#f9f9f9}.filters-container .filters{background-color:#d4e9ff;padding:10px;border-bottom:1px solid #aed5ff}\n"] }] }], ctorParameters: function () { return []; }, propDecorators: { onChange: [{ type: Output }], data: [{ type: Input }], column: [{ type: Input }], filterPlaceholder: [{ type: Input }], emptyResultsMessage: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sdW1uLWZpbHRlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdWktaGVyby9zcmMvbGliL2RhdGEtZ3JpZC9jb21wb25lbnRzL2NvbHVtbi1maWx0ZXIvY29sdW1uLWZpbHRlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdWktaGVyby9zcmMvbGliL2RhdGEtZ3JpZC9jb21wb25lbnRzL2NvbHVtbi1maWx0ZXIvY29sdW1uLWZpbHRlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUUzQyxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRS9FLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxjQUFjLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNyRixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUUxRSxPQUFPLEtBQUssQ0FBQyxNQUFNLFFBQVEsQ0FBQzs7Ozs7O0FBTzVCLE1BQU0sT0FBTyxxQkFBcUI7SUFXaEM7UUFWVSxhQUFRLEdBQUcsSUFBSSxZQUFZLEVBQXVCLENBQUM7UUFHcEQsc0JBQWlCLEdBQVcsV0FBVyxDQUFDO1FBQ3hDLHdCQUFtQixHQUFZLGtDQUFrQyxDQUFDO1FBRTNFLFdBQU0sR0FBRyxFQUFFLENBQUM7SUFJSSxDQUFDO0lBRWpCLFFBQVE7UUFDTixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRTtZQUMzQyxJQUFJ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QztJQUNsQixDQUFDO0lBQ08sWUFBWTtRQUNsQixJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztRQUVqQixJQUFJLENBQUMsZUFBZSxHQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUUxRCxDQUFDOzttSEExRVUscUJBQXFCO3VHQUFyQixxQkFBcUIsMk5DZGxDLG9wQ0FtQk07NEZETE8scUJBQXFCO2tCQUxqQyxTQUFTOytCQUNFLGtCQUFrQjswRUFLbEIsUUFBUTtzQkFBakIsTUFBTTtnQkFDRSxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFDRyxtQkFBbUI7c0JBQTNCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBmaWx0ZXIsIHVuaXFCeSB9IGZyb20gJ2xvZGFzaC1lcyc7XG5cbmltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25Jbml0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgQ29sdW1uRmlsdGVyTW9kZWwsIEVxdWFsc09wZXJhdG9yIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2NvbHVtbi1maWx0ZXIubW9kZWwnO1xuaW1wb3J0IHsgRGF0YUdyaWRDb2x1bW5Nb2RlbCB9IGZyb20gJy4uLy4uL21vZGVscy9kYXRhLWdyaWQtY29sdW1uLm1vZGVsJztcblxuaW1wb3J0ICogYXMgXyBmcm9tICdsb2Rhc2gnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd1aS1jb2x1bW4tZmlsdGVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NvbHVtbi1maWx0ZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9jb2x1bW4tZmlsdGVyLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgQ29sdW1uRmlsdGVyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQE91dHB1dCgpIG9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxEYXRhR3JpZENvbHVtbk1vZGVsPigpO1xuICBASW5wdXQoKSBkYXRhOiBBcnJheTxhbnk+O1xuICBASW5wdXQoKSBjb2x1bW46IERhdGFHcmlkQ29sdW1uTW9kZWw7XG4gIEBJbnB1dCgpIGZpbHRlclBsYWNlaG9sZGVyOiBzdHJpbmcgPSAnRmlsdGVyLi4uJztcbiAgQElucHV0KCkgZW1wdHlSZXN1bHRzTWVzc2FnZT86IHN0cmluZyA9ICdObyByZXN1bHRzIGZvdW5kIGF0IHRoaXMgbW9tZW50Lic7XG5cbiAgc2VhcmNoID0gJyc7XG4gIG9wdGlvbnM6IEFycmF5PGFueT47XG4gIGZpbHRlcmVkT3B0aW9uczogQXJyYXk8YW55PjtcblxuICBjb25zdHJ1Y3RvcigpIHsgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuaW5pdGlhbGl6ZU9wdGlvbnMoKTtcbiAgfVxuXG4gIG9uU2VhcmNoKCkge1xuICAgIGlmICghdGhpcy5zZWFyY2ggfHwgdGhpcy5zZWFyY2gubGVuZ3RoID09IDApIHtcbiAgICAgIHRoaXMuY2xlYXJGaWx0ZXJzKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgXG4gICAgdGhpcy5maWx0ZXJlZE9wdGlvbnMgPSB0aGlzLm9wdGlvbnMuZmlsdGVyKHggPT4geC50b1N0cmluZygpLnRvVXBwZXJDYXNlKCkuaW5kZXhPZih0aGlzLnNlYXJjaC50b1VwcGVyQ2FzZSgpKSA+PSAwKTtcbiAgfVxuICBvbkNsaWNrT3V0c2lkZSgpIHtcbiAgICB0aGlzLmNvbHVtbi5pc0ZpbHRlcnNPcGVubmVkID0gZmFsc2U7XG4gIH1cblxuICBzZWxlY3QoaXRlbTogYW55KSB7XG4gICAgdGhpcy5jb2x1bW4uc2ltcGxlRmlsdGVyID0gbmV3IENvbHVtbkZpbHRlck1vZGVsKGl0ZW0sIHRoaXMuY29sdW1uLCBuZXcgRXF1YWxzT3BlcmF0b3IoKSk7XG4gICAgdGhpcy5vbkNoYW5nZS5lbWl0KHRoaXMuY29sdW1uKTtcbiAgICB0aGlzLmNsZWFyRmlsdGVycygpO1xuICB9XG4gIHJlbW92ZVNpbXBsZUZpbHRlcigpIHtcbiAgICB0aGlzLmNvbHVtbi5zaW1wbGVGaWx0ZXIgPSBudWxsO1xuICAgIHRoaXMub25DaGFuZ2UuZW1pdCh0aGlzLmNvbHVtbik7XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemVPcHRpb25zKCkge1xuICAgIGlmICghdGhpcy5kYXRhIHx8IHRoaXMuZGF0YS5sZW5ndGggPT0gMCkgcmV0dXJuO1xuXG4gICAgdGhpcy5vcHRpb25zID0gdGhpcy5kYXRhLm1hcCgocm93OiBhbnksIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgIGlmICh0aGlzLmNvbHVtbi5yZW5kZXIpXG4gICAgICAgIHJldHVybiB0aGlzLmNvbHVtbi5yZW5kZXIocm93LCB0aGlzLnJlbmRlclByb3BlcnR5VmFsdWUodGhpcy5jb2x1bW4uZGF0YSwgcm93KSwgaW5kZXgpO1xuICAgICAgXG4gICAgICByZXR1cm4gdGhpcy5yZW5kZXJQcm9wZXJ0eVZhbHVlKHRoaXMuY29sdW1uLmRhdGEsIHJvdyk7XG4gICAgfSk7XG5cbiAgICB0aGlzLm9wdGlvbnMgPSB1bmlxQnkodGhpcy5vcHRpb25zLCB4ID0+IHgpO1xuICAgIHRoaXMub3B0aW9ucyA9IGZpbHRlcih0aGlzLm9wdGlvbnMsIHggPT4geCAhPSB1bmRlZmluZWQgJiYgeCAhPSBudWxsKTtcbiAgICB0aGlzLm9wdGlvbnMgPSBfLm9yZGVyQnkodGhpcy5vcHRpb25zLCB4ID0+IHgpIDtcbiAgICB0aGlzLmNsZWFyRmlsdGVycygpO1xuICB9XG4gIHByaXZhdGUgcmVuZGVyUHJvcGVydHlWYWx1ZShwcm9wZXJ0eVBhdGg6IHN0cmluZywgb2JqZWN0OiBhbnkpOiBhbnkge1xuICAgIGxldCBwYXJ0czogc3RyaW5nW10gPSBwcm9wZXJ0eVBhdGguc3BsaXQoIFwiLlwiICk7XG4gICAgbGV0IHByb3BlcnR5OiBhbnkgPSBvYmplY3QgfHwge307XG4gIFxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKCFwcm9wZXJ0eSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBwcm9wZXJ0eSA9IHByb3BlcnR5W3BhcnRzW2ldXTtcbiAgICB9XG5cbiAgICByZXR1cm4gcHJvcGVydHk7XG4gIH1cbiAgcHJpdmF0ZSBjbGVhckZpbHRlcnMoKSB7XG4gICAgdGhpcy5zZWFyY2ggPSAnJztcbiAgICBcbiAgICB0aGlzLmZpbHRlcmVkT3B0aW9ucyA9ICBPYmplY3QuYXNzaWduKFtdLCB0aGlzLm9wdGlvbnMpO1xuICAgIFxuICB9XG5cbn1cbiIsIjxkaXYgY2xhc3M9XCJmaWx0ZXJzLWNvbnRhaW5lclwiIChjbGlja091dHNpZGUpPVwib25DbGlja091dHNpZGUoKVwiPlxuICAgIDxkaXYgY2xhc3M9XCJzZWFyY2hcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXAtcHJlcGVuZFwiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaW5wdXQtZ3JvdXAtdGV4dFwiPjxpIGNsYXNzPVwiZmEgZmEtc2VhcmNoXCI+PC9pPjwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0tY29udHJvbC1zbVwiIFtwbGFjZWhvbGRlcl09XCJmaWx0ZXJQbGFjZWhvbGRlclwiIFsobmdNb2RlbCldPVwic2VhcmNoXCIgZGVib3VuY2UgKGNhbGxiYWNrKT1cIm9uU2VhcmNoKClcIiAvPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImZpbHRlcnMgZC1mbGV4IGZsZXgtd3JhcFwiICpuZ0lmPVwiY29sdW1uLnNpbXBsZUZpbHRlciB8fCBjb2x1bW4uY3VzdG9tRmlsdGVycz8ubGVuZ3RoID4gMFwiPlxuICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBidG4tc20gdGV4dC10cnVuY2F0ZVwiICpuZ0lmPVwiY29sdW1uLnNpbXBsZUZpbHRlclwiIChjbGljayk9XCJyZW1vdmVTaW1wbGVGaWx0ZXIoKVwiPlxuICAgICAgICA8aSBjbGFzcz1cImZhIGZhLXRpbWVzXCI+PC9pPlxuICAgICAgICA8c3BhbiBjbGFzcz1cIm1sLTFcIiBbaW5uZXJIdG1sXT1cImNvbHVtbi5zaW1wbGVGaWx0ZXIuZmlsdGVyXCI+PC9zcGFuPlxuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cIm9wdGlvbnNcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJvcHRpb24gdGV4dC10cnVuY2F0ZVwiICpuZ0Zvcj1cImxldCBpdGVtIG9mIGZpbHRlcmVkT3B0aW9uc1wiIFt0aXRsZV09XCJpdGVtXCIgKGNsaWNrKT1cInNlbGVjdChpdGVtKVwiIFtpbm5lckh0bWxdPVwiaXRlbVwiPjwvZGl2PlxuICAgICAgPHAgY2xhc3M9XCJtYi0wIHAtM1wiICpuZ0lmPVwiIWZpbHRlcmVkT3B0aW9ucyB8fCBmaWx0ZXJlZE9wdGlvbnMubGVuZ3RoID09IDBcIj57e2VtcHR5UmVzdWx0c01lc3NhZ2V9fTwvcD5cbiAgICA8L2Rpdj5cbjwvZGl2PiJdfQ==