]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/eg2/src/app/share/grid/grid-filter-control.component.ts
fbc59186c2c6a1d5fa09b04ca7b73f354b00ce29
[working/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, 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';
11
12 @Component({
13   selector: 'eg-grid-filter-control',
14   templateUrl: './grid-filter-control.component.html'
15 })
16
17 export class GridFilterControlComponent implements OnInit {
18
19     @Input() context: GridContext;
20     @Input() col:     GridColumn;
21
22
23     @ViewChildren(ComboboxComponent)   filterComboboxes: QueryList<ComboboxComponent>;
24     @ViewChildren(DateSelectComponent) dateSelects: QueryList<DateSelectComponent>;
25     @ViewChildren(OrgSelectComponent)  orgSelects: QueryList<OrgSelectComponent>;
26     @ViewChildren(NgbDropdown)         dropdowns: QueryList<NgbDropdown>;
27
28     constructor(
29         private org: OrgService
30     ) {}
31
32     ngOnInit() { }
33
34     operatorChanged(col: GridColumn) {
35         if (col.filterOperator === 'null' || col.filterOperator === 'not null') {
36             col.filterInputDisabled = true;
37             col.filterValue = undefined;
38         } else {
39             col.filterInputDisabled = false;
40         }
41     }
42
43     applyOrgFilter(org: IdlObject, col: GridColumn) {
44         if (org == null) {
45             this.clearFilter(col);
46             return;
47         }
48         const ous: any[] = new Array();
49         if (col.filterIncludeOrgDescendants || col.filterIncludeOrgAncestors) {
50             if (col.filterIncludeOrgAncestors) {
51                 ous.push(...this.org.ancestors(org, true));
52             }
53             if (col.filterIncludeOrgDescendants) {
54                 ous.push(...this.org.descendants(org, true));
55             }
56         } else {
57             ous.push(org.id());
58         }
59         const filt: any = {};
60         filt[col.name] = {};
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();
66     }
67     applyLinkFilter($event, col: GridColumn) {
68         col.filterValue = $event.id;
69         this.applyFilter(col);
70     }
71
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('-');
76         return new Date(
77             Number(parts[0]), Number(parts[1]) - 1, Number(parts[2]));
78     }
79     applyDateFilter(dateStr: string, col: GridColumn, endDateStr: string) {
80         if (col.filterOperator === 'null' || col.filterOperator === 'not null') {
81             this.applyFilter(col);
82         } else {
83             if (dateStr == null) {
84                 this.clearFilter(col);
85                 return;
86             }
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 === '>') {
95                 date1 = date;
96                 date1.setHours(23);
97                 date1.setMinutes(59);
98                 date1.setSeconds(59);
99                 filt[op] = date1.toISOString();
100                 if (col.name === 'dob') { filt[op] = dateStr; } // special case
101                 filt2[col.name] = filt;
102                 filters.push(filt2);
103             } else if (col.filterOperator === '>=') {
104                 date1 = date;
105                 filt[op] = date1.toISOString();
106                 if (col.name === 'dob') { filt[op] = dateStr; } // special case
107                 filt2[col.name] = filt;
108                 filters.push(filt2);
109             } else if (col.filterOperator === '<') {
110                 date1 = date;
111                 filt[op] = date1.toISOString();
112                 if (col.name === 'dob') { filt[op] = dateStr; } // special case
113                 filt2[col.name] = filt;
114                 filters.push(filt2);
115             } else if (col.filterOperator === '<=') {
116                 date1 = date;
117                 date1.setHours(23);
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;
123                 filters.push(filt2);
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;
129                 filters.push(filt2);
130
131                 date2 = new Date(date.valueOf());
132                 date2.setHours(23);
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;
146
147                 date2 = new Date(date.valueOf());
148                 date2.setHours(23);
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;
156
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') {
162                 date1 = date;
163                 date2 = this.localDateFromYmd(endDateStr);
164
165                 let date1op = '>=';
166                 let date2op = '<=';
167                 if (date1 > date2) {
168                     // don't make user care about the order
169                     // they enter the dates in
170                     date1op = '<=';
171                     date2op = '>=';
172                 }
173                 filt[date1op] = date1.toISOString();
174                 if (col.name === 'dob') { filt['>='] = dateStr; } // special case
175                 filt2[col.name] = filt;
176                 filters.push(filt2);
177
178                 date2.setHours(23);
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);
187             }
188             this.context.dataSource.filters[col.name] = filters;
189             col.isFiltered = true;
190             this.context.reload();
191         }
192     }
193     clearDateFilter(col: GridColumn) {
194         delete this.context.dataSource.filters[col.name];
195         col.isFiltered = false;
196         this.context.reload();
197     }
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();
203         } else {
204             const val: string = col.filterValue;
205             const op = '=';
206             const filt: Object = {};
207             filt[op] = val;
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();
213         }
214     }
215     applyFilter(col: GridColumn) {
216         // fallback if the operator somehow was not set yet
217         if (col.filterOperator === undefined) { col.filterOperator = '='; }
218
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
222             // the filter
223             delete this.context.dataSource.filters[col.name];
224             col.isFiltered = false;
225         } else {
226             let op: string = col.filterOperator;
227             let val: string = col.filterValue;
228             const name: string = col.name;
229             if (col.filterOperator === 'null') {
230                 op  = '=';
231                 val = null;
232             } else if (col.filterOperator === 'not null') {
233                 op  = '!=';
234                 val = null;
235             } else if (col.filterOperator === 'like' || col.filterOperator === 'not like') {
236                 val = '%' + val + '%';
237             } else if (col.filterOperator === 'startswith') {
238                 op = 'like';
239                 val = val + '%';
240             } else if (col.filterOperator === 'endswith') {
241                 op = 'like';
242                 val = '%' + val;
243             }
244             const filt: any = {};
245             if (col.filterOperator === 'not like') {
246                 filt['-not'] = {};
247                 filt['-not'][col.name] = {};
248                 filt['-not'][col.name]['like'] = val;
249                 this.context.dataSource.filters[col.name] = [ filt ];
250                 col.isFiltered = true;
251             } else {
252                 filt[col.name] = {};
253                 filt[col.name][op] = val;
254                 this.context.dataSource.filters[col.name] = [ filt ];
255                 col.isFiltered = true;
256             }
257         }
258         this.context.reload();
259     }
260     clearFilter(col: GridColumn) {
261         // clear filter values...
262         col.removeFilter();
263         // ... and inform the data source
264         delete this.context.dataSource.filters[col.name];
265         col.isFiltered = false;
266         this.reset();
267         this.context.reload();
268     }
269
270     closeDropdown() {
271         this.dropdowns.forEach(drp => { drp.close(); });
272     }
273
274     reset() {
275         this.filterComboboxes.forEach(ctl => { ctl.applyEntryId(null); });
276         this.dateSelects.forEach(ctl => { ctl.reset(); });
277         this.orgSelects.forEach(ctl => { ctl.reset(); });
278     }
279 }
280