2 <!-- drop-down toggle link -->
3 <ng-template #dropdownToggle let-col="col">
4 <span i18n>Filter</span>
5 <ng-container *ngIf="!col.isFiltered">
6 <span class="material-icons mat-icon-in-button">filter_list</span>
8 <ng-container *ngIf="col.isFiltered">
9 <span class="material-icons mat-icon-in-button">create</span>
13 <!-- apply/clear actions are the same for all filter types -->
14 <ng-template #actionsTemplate let-col="col">
16 <button class="btn btn-sm btn-outline-dark"
17 (click)="closeDropdown(); applyFilter(col)" i18n>Apply filter</button>
18 <span class="pl-2"></span>
19 <button class="btn btn-sm btn-outline-dark"
20 (click)="closeDropdown(); clearFilter(col)" i18n>Clear filter</button>
24 <!-- various number filters all use the same operators -->
25 <ng-template #numericOperators let-col="col">
26 <select id="eg-filter-op-select-{{col.name}}" class="form-control"
27 [(ngModel)]="col.filterOperator" (change)="operatorChanged(col)">
28 <option value="=" i18n>Is exactly</option>
29 <option value="!=" i18n>Is not</option>
30 <option value="not null" i18n>Exists</option>
31 <option value="null" i18n>Does not exist</option>
32 <option value="<" i18n>Is less than</option>
33 <option value=">" i18n>Is greater than</option>
34 <option value="<=" i18n>Is less than or equal to</option>
35 <option value=">=" i18n>Is greater than or equal to</option>
39 <div *ngIf="col.isFilterable" class="eg-grid-filter-control">
40 <div [ngSwitch]="col.datatype">
41 <div *ngSwitchCase="'link'">
42 <div class="input-group">
43 <div ngbDropdown class="d-inline-block p-1" autoClose="outside" placement="bottom-left"
44 [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
45 <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
46 <ng-container *ngTemplateOutlet="dropdownToggle; context:{col:col}"></ng-container>
48 <div ngbDropdownMenu class="eg-grid-filter-menu">
49 <div class="dropdown-item">
51 <eg-combobox [asyncSupportsEmptyTermClick]="col.asyncSupportsEmptyTermClick"
52 [idlClass]="col.idlFieldDef.class" (onChange)="applyLinkFilter($event, col)"
53 [disabled]="col.filterInputDisabled || context.dataSource.requestingData"
54 i18n-placeholder placeholder="Enter value to filter by"></eg-combobox>
56 <ng-container *ngTemplateOutlet="actionsTemplate; context:{col: col}"></ng-container>
62 <div *ngSwitchCase="'bool'">
63 <div class="input-group">
64 <div ngbDropdown class="d-inline-block p-1" autoClose="outside" placement="bottom-left"
65 [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
66 <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
67 <ng-container *ngTemplateOutlet="dropdownToggle; context:{col:col}"></ng-container>
69 <div ngbDropdownMenu class="eg-grid-filter-menu">
70 <div class="dropdown-item">
72 <select class="custom-select" [(ngModel)]="col.filterValue" (change)="applyBooleanFilter(col)"
73 [disabled]="col.filterInputDisabled || context.dataSource.requestingData">
74 <option value="" i18n>Any</option>
75 <option value="t" i18n>True</option>
76 <option value="f" i18n>False</option>
79 <ng-container *ngTemplateOutlet="actionsTemplate; context:{'col': col}"></ng-container>
85 <div *ngSwitchCase="'text'">
86 <div class="input-group">
87 <div ngbDropdown class="d-inline-block p-1" autoClose="outside" placement="bottom-left"
88 [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
89 <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
90 <ng-container *ngTemplateOutlet="dropdownToggle; context:{col:col}"></ng-container>
92 <div ngbDropdownMenu class="eg-grid-filter-menu">
93 <div class="dropdown-item">
95 <label for="eg-filter-op-select-{{col.name}}" i18n>Operator</label>
96 <select id="eg-filter-op-select-{{col.name}}" class="form-control"
97 [(ngModel)]="col.filterOperator" (change)="operatorChanged(col)">
98 <option value="=" i18n>Is exactly</option>
99 <option value="!=" i18n>Is not</option>
100 <option value="like" i18n>Contains</option>
101 <option value="not like" i18n>Does not contain</option>
102 <option value="startswith" i18n>Starts with</option>
103 <option value="endswith" i18n>Ends with</option>
104 <option value="not null" i18n>Exists</option>
105 <option value="null" i18n>Does not exist</option>
106 <option value="<" i18n>Is less than</option>
107 <option value=">" i18n>Is greater than</option>
108 <option value="<=" i18n>Is less than or equal to</option>
109 <option value=">=" i18n>Is greater than or equal to</option>
113 <input type="text" class="form-control"
114 [(ngModel)]="col.filterValue" (keyup.enter)="applyFilter(col); closeDropdown()"
115 [disabled]="col.filterInputDisabled || context.dataSource.requestingData"
116 i18n-placeholder placeholder="Enter value to filter by">
118 <ng-container *ngTemplateOutlet="actionsTemplate; context:{'col': col}"></ng-container>
124 <div *ngSwitchCase="'int'">
125 <div class="input-group">
126 <div ngbDropdown class="d-inline-block p-1" autoClose="outside" placement="bottom-left"
127 [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
128 <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
129 <ng-container *ngTemplateOutlet="dropdownToggle; context:{col:col}"></ng-container>
131 <div ngbDropdownMenu class="eg-grid-filter-menu">
132 <div class="dropdown-item">
134 <label for="eg-filter-op-select-{{col.name}}" i18n>Operator</label>
135 <ng-container *ngTemplateOutlet="numericOperators; context:{'col': col}"></ng-container>
138 <input type="number" min="0" step="1" class="form-control"
139 [(ngModel)]="col.filterValue" (keyup.enter)="applyFilter(col); closeDropdown()"
140 [disabled]="col.filterInputDisabled || context.dataSource.requestingData"/>
142 <ng-container *ngTemplateOutlet="actionsTemplate; context:{'col': col}"></ng-container>
148 <div *ngSwitchCase="'id'">
149 <div class="input-group">
150 <div ngbDropdown class="d-inline-block p-1" autoClose="outside" placement="bottom-left"
151 [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
152 <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
153 <ng-container *ngTemplateOutlet="dropdownToggle; context:{col:col}"></ng-container>
155 <div ngbDropdownMenu class="eg-grid-filter-menu">
156 <div class="dropdown-item">
158 <label for="eg-filter-op-select-{{col.name}}" i18n>Operator</label>
159 <ng-container *ngTemplateOutlet="numericOperators; context:{'col': col}"></ng-container>
162 <input type="number" min="0" step="1" class="form-control"
163 [(ngModel)]="col.filterValue" (keyup.enter)="applyFilter(col); closeDropdown()"
164 [disabled]="col.filterInputDisabled || context.dataSource.requestingData">
166 <ng-container *ngTemplateOutlet="actionsTemplate; context:{'col': col}"></ng-container>
172 <div *ngSwitchCase="'float'">
173 <div class="input-group">
174 <div ngbDropdown class="d-inline-block p-1" autoClose="outside" placement="bottom-left"
175 [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
176 <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
177 <ng-container *ngTemplateOutlet="dropdownToggle; context:{col:col}"></ng-container>
179 <div ngbDropdownMenu class="eg-grid-filter-menu">
180 <div class="dropdown-item">
182 <label for="eg-filter-op-select-{{col.name}}" i18n>Operator</label>
183 <ng-container *ngTemplateOutlet="numericOperators; context:{'col': col}"></ng-container>
186 <input type="number" class="form-control" [(ngModel)]="col.filterValue"
187 (keyup.enter)="applyFilter(col); closeDropdown()"
188 [disabled]="col.filterInputDisabled || context.dataSource.requestingData">
190 <ng-container *ngTemplateOutlet="actionsTemplate; context:{'col': col}"></ng-container>
196 <div *ngSwitchCase="'money'">
197 <div class="input-group">
198 <div ngbDropdown class="d-inline-block p-1" autoClose="outside" placement="bottom-left"
199 [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
200 <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
201 <ng-container *ngTemplateOutlet="dropdownToggle; context:{col:col}"></ng-container>
203 <div ngbDropdownMenu class="eg-grid-filter-menu">
204 <div class="dropdown-item">
206 <label for="eg-filter-op-select-{{col.name}}" i18n>Operator</label>
207 <ng-container *ngTemplateOutlet="numericOperators; context:{'col': col}"></ng-container>
210 <input type="number" step="0.01" class="form-control"
211 [(ngModel)]="col.filterValue" (keyup.enter)="applyFilter(col); closeDropdown()"
212 [disabled]="col.filterInputDisabled || context.dataSource.requestingData"/>
214 <ng-container *ngTemplateOutlet="actionsTemplate; context:{'col': col}"></ng-container>
220 <div *ngSwitchCase="'timestamp'">
221 <div class="input-group">
222 <!-- [autoClose]="false" because editing the date widgets, which open
223 their open popups, registers to the dropdown as clicking
224 outside the dropdown -->
225 <div ngbDropdown class="d-inline-block p-1" [autoClose]="false" placement="bottom-left"
226 [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
227 <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
228 <ng-container *ngTemplateOutlet="dropdownToggle; context:{col:col}"></ng-container>
230 <div ngbDropdownMenu class="eg-grid-filter-menu">
231 <div class="dropdown-item">
233 <label for="eg-filter-op-select-{{col.name}}" i18n>Operator</label>
234 <select id="eg-filter-op-select-{{col.name}}" class="form-control"
235 [(ngModel)]="col.filterOperator" (change)="operatorChanged(col)">
236 <option value="=" i18n>Is exactly</option>
237 <option value="!=" i18n>Is not</option>
238 <option value="not null" i18n>Exists</option>
239 <option value="null" i18n>Does not exist</option>
240 <option value="<" i18n>Is less than</option>
241 <option value=">" i18n>Is greater than</option>
242 <option value="<=" i18n>Is less than or equal to</option>
243 <option value=">=" i18n>Is greater than or equal to</option>
244 <option value="between" i18n>Between</option>
248 <eg-date-select [initialYmd]="col.filterValue"
249 (onChangeAsYmd)="applyDateFilter($event, col, dateendsel.currentAsYmd())" (onCleared)="clearDateFilter(col)"
250 [disabled]="col.filterInputDisabled || context.dataSource.requestingData" #datesel></eg-date-select>
251 <div [hidden]="col.filterOperator !== 'between'" class="form-inline form-group">
252 <label for="eg-filter-end-date-select-{{col.name}}" style="width: 3em;" i18n>and</label>
253 <eg-date-select [hidden]="col.filterOperator !== 'between'"
254 (onChangeAsYmd)="applyDateFilter(datesel.currentAsYmd(), col, $event)"
255 [disabled]="col.filterInputDisabled || context.dataSource.requestingData"
256 [required]="col.filterOperator == 'between'" #dateendsel></eg-date-select>
259 <ng-container *ngTemplateOutlet="actionsTemplate; context:{'col': col}"></ng-container>
265 <div *ngSwitchCase="'org_unit'">
266 <div class="input-group">
267 <div ngbDropdown class="d-inline-block p-1" autoClose="outside" placement="bottom-left"
268 [ngClass]="{'border rounded border-secondary eg-grid-col-is-filtered' : col.isFiltered}">
269 <a ngbDropdownToggle class="no-dropdown-caret text-dark" href="javascript:;">
270 <ng-container *ngTemplateOutlet="dropdownToggle; context:{col:col}"></ng-container>
272 <div ngbDropdownMenu class="eg-grid-filter-menu">
273 <div class="dropdown-item">
275 <label for="eg-filter-op-select-{{col.name}}" i18n>Operator</label>
276 <select id="eg-filter-op-select-{{col.name}}" class="form-control" [(ngModel)]="col.filterOperator" (change)="operatorChanged(col)">
277 <option value="=" i18n>Is (or includes)</option>
278 <option value="!=" i18n>Is not (or excludes)</option>
281 <div class="dropdown-item">
282 <div class="form-check">
283 <input type="checkbox"
284 [(ngModel)]="col.filterIncludeOrgAncestors"
285 class="form-check-input" id="include-ancestors">
286 <label class="form-check-label" for="include-ancestors" i18n>+ Ancestors</label>
288 <div class="form-check">
289 <input type="checkbox"
290 [(ngModel)]="col.filterIncludeOrgDescendants"
291 class="form-check-input" id="include-descendants">
292 <label class="form-check-label" for="include-descendants" i18n>+ Descendants</label>
296 <eg-org-select [applyOrgId]="col.filterValue" (onChange)="applyOrgFilter($event, col)"
297 [disabled]="col.filterInputDisabled || context.dataSource.requestingData"
298 i18n-placeholder placeholder="Enter library to filter by" #ousel></eg-org-select>
300 <ng-container *ngTemplateOutlet="actionsTemplate; context:{'col': col}"></ng-container>
306 <div *ngSwitchDefault>I don't know how to filter {{col.name}} - {{col.datatype}}</div>
309 <span *ngIf="col.datatype !== 'org_unit'" class="eg-grid-filter-operator"><ng-container i18n>Operator:</ng-container>
310 <span [ngSwitch]="col.filterOperator">
311 <span *ngSwitchCase="'='" i18n>Is exactly</span>
312 <span *ngSwitchCase="'!='" i18n>Is not</span>
313 <span *ngSwitchCase="'>'" i18n>Is greater than</span>
314 <span *ngSwitchCase="'>='" i18n>Is greater than or equal to</span>
315 <span *ngSwitchCase="'<'" i18n>Is less than</span>
316 <span *ngSwitchCase="'<='" i18n>Is less than or equal to</span>
317 <span *ngSwitchCase="'like'" i18n>Contains</span>
318 <span *ngSwitchCase="'not like'" i18n>Does not contain</span>
319 <span *ngSwitchCase="'startswith'" i18n>Starts with</span>
320 <span *ngSwitchCase="'endswith'" i18n>Ends with</span>
321 <span *ngSwitchCase="'null'" i18n>Does not exist</span>
322 <span *ngSwitchCase="'not null'" i18n>Exists</span>
323 <span *ngSwitchCase="'between'" i18n>Between</span>
326 <span *ngIf="col.datatype == 'org_unit'" class="eg-grid-filter-operator"><ng-container i18n>Operator:</ng-container>
327 <span [ngSwitch]="col.filterOperator">
328 <span *ngSwitchCase="'='" i18n>Is (or includes)</span>
329 <span *ngSwitchCase="'!='" i18n>Is not (or excludes)</span>