]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/share/grid/grid-filter-control.component.ts
8ed77f7c7d1a95ef0aa0f776b096855ce9df93eb
[Evergreen.git] / Open-ILS / src / eg2 / src / app / share / grid / grid-filter-control.component.ts
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';
9
10 @Component({
11   selector: 'eg-grid-filter-control',
12   templateUrl: './grid-filter-control.component.html'
13 })
14
15 export class GridFilterControlComponent implements OnInit {
16
17     @Input() context: GridContext;
18     @Input() col:     GridColumn;
19
20
21     @ViewChildren(ComboboxComponent)   filterComboboxes: QueryList<ComboboxComponent>;
22     @ViewChildren(DateSelectComponent) dateSelects: QueryList<DateSelectComponent>;
23     @ViewChildren(OrgSelectComponent)  orgSelects: QueryList<OrgSelectComponent>;
24     @ViewChildren(NgbDropdown)         dropdowns: QueryList<NgbDropdown>;
25
26     constructor(
27         private org: OrgService
28     ) {}
29
30     ngOnInit() { }
31
32     operatorChanged(col: GridColumn) {
33         if (col.filterOperator === 'null' || col.filterOperator === 'not null') {
34             col.filterInputDisabled = true;
35             col.filterValue = undefined;
36         } else {
37             col.filterInputDisabled = false;
38         }
39     }
40
41     applyOrgFilter(org: IdlObject, col: GridColumn) {
42         if (org == null) {
43             this.clearFilter(col);
44             return;
45         }
46         const ous: any[] = new Array();
47         if (col.filterIncludeOrgDescendants || col.filterIncludeOrgAncestors) {
48             if (col.filterIncludeOrgAncestors) {
49                 ous.push(...this.org.ancestors(org, true));
50             }
51             if (col.filterIncludeOrgDescendants) {
52                 ous.push(...this.org.descendants(org, true));
53             }
54         } else {
55             ous.push(org.id());
56         }
57         const filt: any = {};
58         filt[col.name] = {};
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();
64     }
65
66     applyLinkFilter($event, col: GridColumn) {
67         if ($event) {
68             col.filterValue = $event.id;
69             this.applyFilter(col);
70
71         } else {
72             // Value was cleared from the combobox
73             this.clearFilter(col);
74         }
75     }
76
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('-');
81         return new Date(
82             Number(parts[0]), Number(parts[1]) - 1, Number(parts[2]));
83     }
84     applyDateFilter(dateStr: string, col: GridColumn, endDateStr: string) {
85         if (col.filterOperator === 'null' || col.filterOperator === 'not null') {
86             this.applyFilter(col);
87         } else {
88             if (dateStr == null) {
89                 this.clearFilter(col);
90                 return;
91             }
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 === '>') {
100                 date1 = date;
101                 date1.setHours(23);
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;
107                 filters.push(filt2);
108             } else if (col.filterOperator === '>=') {
109                 date1 = date;
110                 filt[op] = date1.toISOString();
111                 if (col.name === 'dob') { filt[op] = dateStr; } // special case
112                 filt2[col.name] = filt;
113                 filters.push(filt2);
114             } else if (col.filterOperator === '<') {
115                 date1 = date;
116                 filt[op] = date1.toISOString();
117                 if (col.name === 'dob') { filt[op] = dateStr; } // special case
118                 filt2[col.name] = filt;
119                 filters.push(filt2);
120             } else if (col.filterOperator === '<=') {
121                 date1 = date;
122                 date1.setHours(23);
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;
128                 filters.push(filt2);
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;
134                 filters.push(filt2);
135
136                 date2 = new Date(date.valueOf());
137                 date2.setHours(23);
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;
151
152                 date2 = new Date(date.valueOf());
153                 date2.setHours(23);
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;
161
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') {
167                 date1 = date;
168                 date2 = this.localDateFromYmd(endDateStr);
169
170                 let date1op = '>=';
171                 let date2op = '<=';
172                 if (date1 > date2) {
173                     // don't make user care about the order
174                     // they enter the dates in
175                     date1op = '<=';
176                     date2op = '>=';
177                 }
178                 filt[date1op] = date1.toISOString();
179                 if (col.name === 'dob') { filt['>='] = dateStr; } // special case
180                 filt2[col.name] = filt;
181                 filters.push(filt2);
182
183                 date2.setHours(23);
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);
192             }
193             this.context.dataSource.filters[col.name] = filters;
194             col.isFiltered = true;
195             this.context.reload();
196         }
197     }
198     clearDateFilter(col: GridColumn) {
199         delete this.context.dataSource.filters[col.name];
200         col.isFiltered = false;
201         this.context.reload();
202     }
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();
208         } else {
209             const val: string = col.filterValue;
210             const op = '=';
211             const filt: Object = {};
212             filt[op] = val;
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();
218         }
219     }
220     applyFilter(col: GridColumn) {
221         // fallback if the operator somehow was not set yet
222         if (col.filterOperator === undefined) { col.filterOperator = '='; }
223
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
228             // the filter
229             delete this.context.dataSource.filters[col.name];
230             col.isFiltered = false;
231         } else {
232             let op: string = col.filterOperator;
233             let val: string = col.filterValue;
234             if (col.filterOperator === 'null') {
235                 op  = '=';
236                 val = null;
237             } else if (col.filterOperator === 'not null') {
238                 op  = '!=';
239                 val = null;
240             } else if (col.filterOperator === 'like' || col.filterOperator === 'not like') {
241                 val = '%' + val + '%';
242             } else if (col.filterOperator === 'startswith') {
243                 op = 'like';
244                 val = val + '%';
245             } else if (col.filterOperator === 'endswith') {
246                 op = 'like';
247                 val = '%' + val;
248             }
249             const filt: any = {};
250             if (col.filterOperator === 'not like') {
251                 filt['-not'] = {};
252                 filt['-not'][col.name] = {};
253                 filt['-not'][col.name]['like'] = val;
254                 this.context.dataSource.filters[col.name] = [ filt ];
255                 col.isFiltered = true;
256             } else {
257                 filt[col.name] = {};
258                 filt[col.name][op] = val;
259                 this.context.dataSource.filters[col.name] = [ filt ];
260                 col.isFiltered = true;
261             }
262         }
263         this.context.reload();
264     }
265     clearFilter(col: GridColumn) {
266         // clear filter values...
267         col.removeFilter();
268         // ... and inform the data source
269         delete this.context.dataSource.filters[col.name];
270         col.isFiltered = false;
271         this.reset();
272         this.context.reload();
273     }
274
275     closeDropdown() {
276         this.dropdowns.forEach(drp => { drp.close(); });
277     }
278
279     reset() {
280         this.filterComboboxes.forEach(ctl => { ctl.applyEntryId(null); });
281         this.dateSelects.forEach(ctl => { ctl.reset(); });
282         this.orgSelects.forEach(ctl => { ctl.reset(); });
283     }
284 }
285