1 import {Component, Input, OnInit, QueryList, ViewChildren} from '@angular/core';
2 import {GridContext, GridColumn, GridRowSelector,
3 GridColumnSet, GridDataSource} from './grid';
4 import {IdlObject} from '@eg/core/idl.service';
5 import {ComboboxComponent,
6 ComboboxEntry} from '@eg/share/combobox/combobox.component';
7 import {DateSelectComponent} from '@eg/share/date-select/date-select.component';
8 import {OrgSelectComponent} from '@eg/share/org-select/org-select.component';
9 import {OrgService} from '@eg/core/org.service';
10 import {NgbDropdown} from '@ng-bootstrap/ng-bootstrap';
13 selector: 'eg-grid-filter-control',
14 templateUrl: './grid-filter-control.component.html'
17 export class GridFilterControlComponent implements OnInit {
19 @Input() context: GridContext;
20 @Input() col: GridColumn;
23 @ViewChildren(ComboboxComponent) filterComboboxes: QueryList<ComboboxComponent>;
24 @ViewChildren(DateSelectComponent) dateSelects: QueryList<DateSelectComponent>;
25 @ViewChildren(OrgSelectComponent) orgSelects: QueryList<OrgSelectComponent>;
26 @ViewChildren(NgbDropdown) dropdowns: QueryList<NgbDropdown>;
29 private org: OrgService
34 operatorChanged(col: GridColumn) {
35 if (col.filterOperator === 'null' || col.filterOperator === 'not null') {
36 col.filterInputDisabled = true;
37 col.filterValue = undefined;
39 col.filterInputDisabled = false;
43 applyOrgFilter(org: IdlObject, col: GridColumn) {
45 this.clearFilter(col);
48 const ous: any[] = new Array();
49 if (col.filterIncludeOrgDescendants || col.filterIncludeOrgAncestors) {
50 if (col.filterIncludeOrgAncestors) {
51 ous.push(...this.org.ancestors(org, true));
53 if (col.filterIncludeOrgDescendants) {
54 ous.push(...this.org.descendants(org, true));
61 const op: string = (col.filterOperator === '=' ? 'in' : 'not in');
62 filt[col.name][op] = ous;
63 this.context.dataSource.filters[col.name] = [ filt ];
64 col.isFiltered = true;
65 this.context.reload();
67 applyLinkFilter($event, col: GridColumn) {
68 col.filterValue = $event.id;
69 this.applyFilter(col);
72 // TODO: this was copied from date-select and
73 // really belongs in a date service
74 localDateFromYmd(ymd: string): Date {
75 const parts = ymd.split('-');
77 Number(parts[0]), Number(parts[1]) - 1, Number(parts[2]));
79 applyDateFilter(dateStr: string, col: GridColumn, endDateStr: string) {
80 if (col.filterOperator === 'null' || col.filterOperator === 'not null') {
81 this.applyFilter(col);
83 if (dateStr == null) {
84 this.clearFilter(col);
87 const date: Date = this.localDateFromYmd(dateStr);
88 let date1 = new Date();
89 let date2 = new Date();
90 const op: string = col.filterOperator;
91 const filt: Object = {};
92 const filt2: Object = {};
93 const filters = new Array();
94 if (col.filterOperator === '>') {
99 filt[op] = date1.toISOString();
100 if (col.name === 'dob') { filt[op] = dateStr; } // special case
101 filt2[col.name] = filt;
103 } else if (col.filterOperator === '>=') {
105 filt[op] = date1.toISOString();
106 if (col.name === 'dob') { filt[op] = dateStr; } // special case
107 filt2[col.name] = filt;
109 } else if (col.filterOperator === '<') {
111 filt[op] = date1.toISOString();
112 if (col.name === 'dob') { filt[op] = dateStr; } // special case
113 filt2[col.name] = filt;
115 } else if (col.filterOperator === '<=') {
118 date1.setMinutes(59);
119 date1.setSeconds(59);
120 filt[op] = date1.toISOString();
121 if (col.name === 'dob') { filt[op] = dateStr; } // special case
122 filt2[col.name] = filt;
124 } else if (col.filterOperator === '=') {
125 date1 = new Date(date.valueOf());
126 filt['>='] = date1.toISOString();
127 if (col.name === 'dob') { filt['>='] = dateStr; } // special case
128 filt2[col.name] = filt;
131 date2 = new Date(date.valueOf());
133 date2.setMinutes(59);
134 date2.setSeconds(59);
135 const filt_a: Object = {};
136 const filt2_a: Object = {};
137 filt_a['<='] = date2.toISOString();
138 if (col.name === 'dob') { filt_a['<='] = dateStr; } // special case
139 filt2_a[col.name] = filt_a;
140 filters.push(filt2_a);
141 } else if (col.filterOperator === '!=') {
142 date1 = new Date(date.valueOf());
143 filt['<'] = date1.toISOString();
144 if (col.name === 'dob') { filt['<'] = dateStr; } // special case
145 filt2[col.name] = filt;
147 date2 = new Date(date.valueOf());
149 date2.setMinutes(59);
150 date2.setSeconds(59);
151 const filt_a: Object = {};
152 const filt2_a: Object = {};
153 filt_a['>'] = date2.toISOString();
154 if (col.name === 'dob') { filt_a['>'] = dateStr; } // special case
155 filt2_a[col.name] = filt_a;
157 const date_filt: any = { '-or': [] };
158 date_filt['-or'].push(filt2);
159 date_filt['-or'].push(filt2_a);
160 filters.push(date_filt);
161 } else if (col.filterOperator === 'between') {
163 date2 = this.localDateFromYmd(endDateStr);
168 // don't make user care about the order
169 // they enter the dates in
173 filt[date1op] = date1.toISOString();
174 if (col.name === 'dob') { filt['>='] = dateStr; } // special case
175 filt2[col.name] = filt;
179 date2.setMinutes(59);
180 date2.setSeconds(59);
181 const filt_a: Object = {};
182 const filt2_a: Object = {};
183 filt_a[date2op] = date2.toISOString();
184 if (col.name === 'dob') { filt_a['<='] = endDateStr; } // special case
185 filt2_a[col.name] = filt_a;
186 filters.push(filt2_a);
188 this.context.dataSource.filters[col.name] = filters;
189 col.isFiltered = true;
190 this.context.reload();
193 clearDateFilter(col: GridColumn) {
194 delete this.context.dataSource.filters[col.name];
195 col.isFiltered = false;
196 this.context.reload();
198 applyBooleanFilter(col: GridColumn) {
199 if (!col.filterValue || col.filterValue === '') {
200 delete this.context.dataSource.filters[col.name];
201 col.isFiltered = false;
202 this.context.reload();
204 const val: string = col.filterValue;
206 const filt: Object = {};
208 const filt2: Object = {};
209 filt2[col.name] = filt;
210 this.context.dataSource.filters[col.name] = [ filt2 ];
211 col.isFiltered = true;
212 this.context.reload();
215 applyFilter(col: GridColumn) {
216 // fallback if the operator somehow was not set yet
217 if (col.filterOperator === undefined) { col.filterOperator = '='; }
219 if ( (col.filterOperator !== 'null') && (col.filterOperator !== 'not null') &&
220 (!col.filterValue || col.filterValue === '') ) {
221 // if value is empty and we're _not_ checking for null/not null, clear
223 delete this.context.dataSource.filters[col.name];
224 col.isFiltered = false;
226 let op: string = col.filterOperator;
227 let val: string = col.filterValue;
228 const name: string = col.name;
229 if (col.filterOperator === 'null') {
232 } else if (col.filterOperator === 'not null') {
235 } else if (col.filterOperator === 'like' || col.filterOperator === 'not like') {
236 val = '%' + val + '%';
237 } else if (col.filterOperator === 'startswith') {
240 } else if (col.filterOperator === 'endswith') {
244 const filt: any = {};
245 if (col.filterOperator === 'not like') {
247 filt['-not'][col.name] = {};
248 filt['-not'][col.name]['like'] = val;
249 this.context.dataSource.filters[col.name] = [ filt ];
250 col.isFiltered = true;
253 filt[col.name][op] = val;
254 this.context.dataSource.filters[col.name] = [ filt ];
255 col.isFiltered = true;
258 this.context.reload();
260 clearFilter(col: GridColumn) {
261 // clear filter values...
263 // ... and inform the data source
264 delete this.context.dataSource.filters[col.name];
265 col.isFiltered = false;
267 this.context.reload();
271 this.dropdowns.forEach(drp => { drp.close(); });
275 this.filterComboboxes.forEach(ctl => { ctl.applyEntryId(null); });
276 this.dateSelects.forEach(ctl => { ctl.reset(); });
277 this.orgSelects.forEach(ctl => { ctl.reset(); });