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();
66 applyLinkFilter($event, col: GridColumn) {
68 col.filterValue = $event.id;
69 this.applyFilter(col);
72 // Value was cleared from the combobox
73 this.clearFilter(col);
77 // TODO: this was copied from date-select and
78 // really belongs in a date service
79 localDateFromYmd(ymd: string): Date {
80 const parts = ymd.split('-');
82 Number(parts[0]), Number(parts[1]) - 1, Number(parts[2]));
84 applyDateFilter(dateStr: string, col: GridColumn, endDateStr: string) {
85 if (col.filterOperator === 'null' || col.filterOperator === 'not null') {
86 this.applyFilter(col);
88 if (dateStr == null) {
89 this.clearFilter(col);
92 const date: Date = this.localDateFromYmd(dateStr);
93 let date1 = new Date();
94 let date2 = new Date();
95 const op: string = col.filterOperator;
96 const filt: Object = {};
97 const filt2: Object = {};
98 const filters = new Array();
99 if (col.filterOperator === '>') {
102 date1.setMinutes(59);
103 date1.setSeconds(59);
104 filt[op] = date1.toISOString();
105 if (col.name === 'dob') { filt[op] = dateStr; } // special case
106 filt2[col.name] = filt;
108 } else if (col.filterOperator === '>=') {
110 filt[op] = date1.toISOString();
111 if (col.name === 'dob') { filt[op] = dateStr; } // special case
112 filt2[col.name] = filt;
114 } else if (col.filterOperator === '<') {
116 filt[op] = date1.toISOString();
117 if (col.name === 'dob') { filt[op] = dateStr; } // special case
118 filt2[col.name] = filt;
120 } else if (col.filterOperator === '<=') {
123 date1.setMinutes(59);
124 date1.setSeconds(59);
125 filt[op] = date1.toISOString();
126 if (col.name === 'dob') { filt[op] = dateStr; } // special case
127 filt2[col.name] = filt;
129 } else if (col.filterOperator === '=') {
130 date1 = new Date(date.valueOf());
131 filt['>='] = date1.toISOString();
132 if (col.name === 'dob') { filt['>='] = dateStr; } // special case
133 filt2[col.name] = filt;
136 date2 = new Date(date.valueOf());
138 date2.setMinutes(59);
139 date2.setSeconds(59);
140 const filt_a: Object = {};
141 const filt2_a: Object = {};
142 filt_a['<='] = date2.toISOString();
143 if (col.name === 'dob') { filt_a['<='] = dateStr; } // special case
144 filt2_a[col.name] = filt_a;
145 filters.push(filt2_a);
146 } else if (col.filterOperator === '!=') {
147 date1 = new Date(date.valueOf());
148 filt['<'] = date1.toISOString();
149 if (col.name === 'dob') { filt['<'] = dateStr; } // special case
150 filt2[col.name] = filt;
152 date2 = new Date(date.valueOf());
154 date2.setMinutes(59);
155 date2.setSeconds(59);
156 const filt_a: Object = {};
157 const filt2_a: Object = {};
158 filt_a['>'] = date2.toISOString();
159 if (col.name === 'dob') { filt_a['>'] = dateStr; } // special case
160 filt2_a[col.name] = filt_a;
162 const date_filt: any = { '-or': [] };
163 date_filt['-or'].push(filt2);
164 date_filt['-or'].push(filt2_a);
165 filters.push(date_filt);
166 } else if (col.filterOperator === 'between') {
168 date2 = this.localDateFromYmd(endDateStr);
173 // don't make user care about the order
174 // they enter the dates in
178 filt[date1op] = date1.toISOString();
179 if (col.name === 'dob') { filt['>='] = dateStr; } // special case
180 filt2[col.name] = filt;
184 date2.setMinutes(59);
185 date2.setSeconds(59);
186 const filt_a: Object = {};
187 const filt2_a: Object = {};
188 filt_a[date2op] = date2.toISOString();
189 if (col.name === 'dob') { filt_a['<='] = endDateStr; } // special case
190 filt2_a[col.name] = filt_a;
191 filters.push(filt2_a);
193 this.context.dataSource.filters[col.name] = filters;
194 col.isFiltered = true;
195 this.context.reload();
198 clearDateFilter(col: GridColumn) {
199 delete this.context.dataSource.filters[col.name];
200 col.isFiltered = false;
201 this.context.reload();
203 applyBooleanFilter(col: GridColumn) {
204 if (!col.filterValue || col.filterValue === '') {
205 delete this.context.dataSource.filters[col.name];
206 col.isFiltered = false;
207 this.context.reload();
209 const val: string = col.filterValue;
211 const filt: Object = {};
213 const filt2: Object = {};
214 filt2[col.name] = filt;
215 this.context.dataSource.filters[col.name] = [ filt2 ];
216 col.isFiltered = true;
217 this.context.reload();
220 applyFilter(col: GridColumn) {
221 // fallback if the operator somehow was not set yet
222 if (col.filterOperator === undefined) { col.filterOperator = '='; }
224 if ( (col.filterOperator !== 'null') && (col.filterOperator !== 'not null') &&
225 (!col.filterValue || col.filterValue === '') &&
226 (col.filterValue !== '0') ) {
227 // if value is empty and we're _not_ checking for null/not null, clear
229 delete this.context.dataSource.filters[col.name];
230 col.isFiltered = false;
232 let op: string = col.filterOperator;
233 let val: string = col.filterValue;
234 if (col.filterOperator === 'null') {
237 } else if (col.filterOperator === 'not null') {
240 } else if (col.filterOperator === 'like' || col.filterOperator === 'not like') {
241 val = '%' + val + '%';
242 } else if (col.filterOperator === 'startswith') {
245 } else if (col.filterOperator === 'endswith') {
249 const filt: any = {};
250 if (col.filterOperator === 'not like') {
252 filt['-not'][col.name] = {};
253 filt['-not'][col.name]['like'] = val;
254 this.context.dataSource.filters[col.name] = [ filt ];
255 col.isFiltered = true;
258 filt[col.name][op] = val;
259 this.context.dataSource.filters[col.name] = [ filt ];
260 col.isFiltered = true;
263 this.context.reload();
265 clearFilter(col: GridColumn) {
266 // clear filter values...
268 // ... and inform the data source
269 delete this.context.dataSource.filters[col.name];
270 col.isFiltered = false;
272 this.context.reload();
276 this.dropdowns.forEach(drp => { drp.close(); });
280 this.filterComboboxes.forEach(ctl => { ctl.applyEntryId(null); });
281 this.dateSelects.forEach(ctl => { ctl.reset(); });
282 this.orgSelects.forEach(ctl => { ctl.reset(); });