1 import {Component, Input, OnInit, QueryList, ViewChildren} from '@angular/core';
2 import {GridContext, GridColumn} from './grid';
3 import {IdlObject} from '@eg/core/idl.service';
4 import {ComboboxComponent} from '@eg/share/combobox/combobox.component';
5 import {DateSelectComponent} from '@eg/share/date-select/date-select.component';
6 import {OrgSelectComponent} from '@eg/share/org-select/org-select.component';
7 import {OrgService} from '@eg/core/org.service';
8 import {NgbDropdown} from '@ng-bootstrap/ng-bootstrap';
11 selector: 'eg-grid-filter-control',
12 templateUrl: './grid-filter-control.component.html'
15 export class GridFilterControlComponent implements OnInit {
17 @Input() context: GridContext;
18 @Input() col: GridColumn;
21 @ViewChildren(ComboboxComponent) filterComboboxes: QueryList<ComboboxComponent>;
22 @ViewChildren(DateSelectComponent) dateSelects: QueryList<DateSelectComponent>;
23 @ViewChildren(OrgSelectComponent) orgSelects: QueryList<OrgSelectComponent>;
24 @ViewChildren(NgbDropdown) dropdowns: QueryList<NgbDropdown>;
27 private org: OrgService
32 operatorChanged(col: GridColumn) {
33 if (col.filterOperator === 'null' || col.filterOperator === 'not null') {
34 col.filterInputDisabled = true;
35 col.filterValue = undefined;
37 col.filterInputDisabled = false;
41 applyOrgFilter(org: IdlObject, col: GridColumn) {
43 this.clearFilter(col);
46 const ous: any[] = new Array();
47 if (col.filterIncludeOrgDescendants || col.filterIncludeOrgAncestors) {
48 if (col.filterIncludeOrgAncestors) {
49 ous.push(...this.org.ancestors(org, true));
51 if (col.filterIncludeOrgDescendants) {
52 ous.push(...this.org.descendants(org, true));
59 const op: string = (col.filterOperator === '=' ? 'in' : 'not in');
60 filt[col.name][op] = ous;
61 this.context.dataSource.filters[col.name] = [ filt ];
62 col.isFiltered = true;
63 this.context.reload();
65 applyLinkFilter($event, col: GridColumn) {
66 col.filterValue = $event.id;
67 this.applyFilter(col);
70 // TODO: this was copied from date-select and
71 // really belongs in a date service
72 localDateFromYmd(ymd: string): Date {
73 const parts = ymd.split('-');
75 Number(parts[0]), Number(parts[1]) - 1, Number(parts[2]));
77 applyDateFilter(dateStr: string, col: GridColumn, endDateStr: string) {
78 if (col.filterOperator === 'null' || col.filterOperator === 'not null') {
79 this.applyFilter(col);
81 if (dateStr == null) {
82 this.clearFilter(col);
85 const date: Date = this.localDateFromYmd(dateStr);
86 let date1 = new Date();
87 let date2 = new Date();
88 const op: string = col.filterOperator;
89 const filt: Object = {};
90 const filt2: Object = {};
91 const filters = new Array();
92 if (col.filterOperator === '>') {
97 filt[op] = date1.toISOString();
98 if (col.name === 'dob') { filt[op] = dateStr; } // special case
99 filt2[col.name] = filt;
101 } else if (col.filterOperator === '>=') {
103 filt[op] = date1.toISOString();
104 if (col.name === 'dob') { filt[op] = dateStr; } // special case
105 filt2[col.name] = filt;
107 } else if (col.filterOperator === '<') {
109 filt[op] = date1.toISOString();
110 if (col.name === 'dob') { filt[op] = dateStr; } // special case
111 filt2[col.name] = filt;
113 } else if (col.filterOperator === '<=') {
116 date1.setMinutes(59);
117 date1.setSeconds(59);
118 filt[op] = date1.toISOString();
119 if (col.name === 'dob') { filt[op] = dateStr; } // special case
120 filt2[col.name] = filt;
122 } else if (col.filterOperator === '=') {
123 date1 = new Date(date.valueOf());
124 filt['>='] = date1.toISOString();
125 if (col.name === 'dob') { filt['>='] = dateStr; } // special case
126 filt2[col.name] = filt;
129 date2 = new Date(date.valueOf());
131 date2.setMinutes(59);
132 date2.setSeconds(59);
133 const filt_a: Object = {};
134 const filt2_a: Object = {};
135 filt_a['<='] = date2.toISOString();
136 if (col.name === 'dob') { filt_a['<='] = dateStr; } // special case
137 filt2_a[col.name] = filt_a;
138 filters.push(filt2_a);
139 } else if (col.filterOperator === '!=') {
140 date1 = new Date(date.valueOf());
141 filt['<'] = date1.toISOString();
142 if (col.name === 'dob') { filt['<'] = dateStr; } // special case
143 filt2[col.name] = filt;
145 date2 = new Date(date.valueOf());
147 date2.setMinutes(59);
148 date2.setSeconds(59);
149 const filt_a: Object = {};
150 const filt2_a: Object = {};
151 filt_a['>'] = date2.toISOString();
152 if (col.name === 'dob') { filt_a['>'] = dateStr; } // special case
153 filt2_a[col.name] = filt_a;
155 const date_filt: any = { '-or': [] };
156 date_filt['-or'].push(filt2);
157 date_filt['-or'].push(filt2_a);
158 filters.push(date_filt);
159 } else if (col.filterOperator === 'between') {
161 date2 = this.localDateFromYmd(endDateStr);
166 // don't make user care about the order
167 // they enter the dates in
171 filt[date1op] = date1.toISOString();
172 if (col.name === 'dob') { filt['>='] = dateStr; } // special case
173 filt2[col.name] = filt;
177 date2.setMinutes(59);
178 date2.setSeconds(59);
179 const filt_a: Object = {};
180 const filt2_a: Object = {};
181 filt_a[date2op] = date2.toISOString();
182 if (col.name === 'dob') { filt_a['<='] = endDateStr; } // special case
183 filt2_a[col.name] = filt_a;
184 filters.push(filt2_a);
186 this.context.dataSource.filters[col.name] = filters;
187 col.isFiltered = true;
188 this.context.reload();
191 clearDateFilter(col: GridColumn) {
192 delete this.context.dataSource.filters[col.name];
193 col.isFiltered = false;
194 this.context.reload();
196 applyBooleanFilter(col: GridColumn) {
197 if (!col.filterValue || col.filterValue === '') {
198 delete this.context.dataSource.filters[col.name];
199 col.isFiltered = false;
200 this.context.reload();
202 const val: string = col.filterValue;
204 const filt: Object = {};
206 const filt2: Object = {};
207 filt2[col.name] = filt;
208 this.context.dataSource.filters[col.name] = [ filt2 ];
209 col.isFiltered = true;
210 this.context.reload();
213 applyFilter(col: GridColumn) {
214 // fallback if the operator somehow was not set yet
215 if (col.filterOperator === undefined) { col.filterOperator = '='; }
217 if ( (col.filterOperator !== 'null') && (col.filterOperator !== 'not null') &&
218 (!col.filterValue || col.filterValue === '') &&
219 (col.filterValue !== '0') ) {
220 // if value is empty and we're _not_ checking for null/not null, clear
222 delete this.context.dataSource.filters[col.name];
223 col.isFiltered = false;
225 let op: string = col.filterOperator;
226 let val: string = col.filterValue;
227 if (col.filterOperator === 'null') {
230 } else if (col.filterOperator === 'not null') {
233 } else if (col.filterOperator === 'like' || col.filterOperator === 'not like') {
234 val = '%' + val + '%';
235 } else if (col.filterOperator === 'startswith') {
238 } else if (col.filterOperator === 'endswith') {
242 const filt: any = {};
243 if (col.filterOperator === 'not like') {
245 filt['-not'][col.name] = {};
246 filt['-not'][col.name]['like'] = val;
247 this.context.dataSource.filters[col.name] = [ filt ];
248 col.isFiltered = true;
251 filt[col.name][op] = val;
252 this.context.dataSource.filters[col.name] = [ filt ];
253 col.isFiltered = true;
256 this.context.reload();
258 clearFilter(col: GridColumn) {
259 // clear filter values...
261 // ... and inform the data source
262 delete this.context.dataSource.filters[col.name];
263 col.isFiltered = false;
265 this.context.reload();
269 this.dropdowns.forEach(drp => { drp.close(); });
273 this.filterComboboxes.forEach(ctl => { ctl.applyEntryId(null); });
274 this.dateSelects.forEach(ctl => { ctl.reset(); });
275 this.orgSelects.forEach(ctl => { ctl.reset(); });