inviton-powerduck 0.0.164 → 0.0.166

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/app/global-state.ts +28 -0
  2. package/app/powerduck-initializer.ts +10 -9
  3. package/app/powerduck-state.ts +3 -2
  4. package/common/ajax-xhr.ts +2 -1
  5. package/common/api-http.ts +6 -5
  6. package/common/base-component.tsx +2 -1
  7. package/common/dialog-utils.ts +2 -1
  8. package/common/external-barcode-scanner.ts +244 -242
  9. package/common/history-extended.ts +44 -6
  10. package/common/history-handler.ts +15 -15
  11. package/common/keyboard-open-tracker.ts +20 -6
  12. package/common/ladda-lite.ts +14 -1
  13. package/common/local-storage-shim.ts +66 -30
  14. package/common/resource-helper.ts +77 -71
  15. package/common/scroll-utils.ts +9 -4
  16. package/common/set-current-url.ts +8 -5
  17. package/common/utils/checkbox-utils.ts +6 -0
  18. package/common/utils/clipboard-provider.ts +37 -34
  19. package/common/utils/cookie.ts +9 -0
  20. package/common/utils/dropdown-utils.ts +5 -0
  21. package/common/utils/string-utils.ts +46 -40
  22. package/common/utils/upload-image-helper.ts +2 -1
  23. package/common/utils/utils.ts +34 -14
  24. package/components/app/navigation-guard.ts +5 -2
  25. package/components/app/root-dynamic-component-container.tsx +2 -1
  26. package/components/app/vue-plugin-jsxtransform.ts +3 -1
  27. package/components/chart-js/line-chart-flot.tsx +4 -3
  28. package/components/chart-js/line-chart.tsx +5 -0
  29. package/components/chart-js/pie-chart.tsx +4 -3
  30. package/components/collapse/index.tsx +9 -0
  31. package/components/container-with-breakpoints/ts/breakpoint-handler.ts +7 -6
  32. package/components/counter/index.tsx +2 -1
  33. package/components/counter/testall.tsx +12 -9
  34. package/components/datatable/datatable.tsx +2363 -2362
  35. package/components/dropdown/mobile/legacy_fdd.ts +10 -9
  36. package/components/dropdown/mobile/legacy_lvb.ts +3 -1
  37. package/components/file-downloader/index.tsx +6 -5
  38. package/components/google/maps.tsx +18 -8
  39. package/components/google/places-autocomplete.tsx +6 -1
  40. package/components/google/ts/google-maps-api.ts +3 -2
  41. package/components/image-crop/image-cropping-modal.tsx +11 -6
  42. package/components/image-crop/upload-and-crop.tsx +163 -162
  43. package/components/input/daterange-picker.tsx +9 -0
  44. package/components/input/datetime-picker.tsx +11 -2
  45. package/components/input/localized-url-input.tsx +2 -1
  46. package/components/input/ts/bootstrapInputSpinner.ts +7 -2
  47. package/components/input/ts/dateInputHelper.ts +8 -7
  48. package/components/memory-cache/index.ts +7 -5
  49. package/components/modal/modal-utils.ts +2 -1
  50. package/components/modal/modal.tsx +5 -4
  51. package/components/modal/ts/file-manager-dialog.ts +3 -2
  52. package/components/share/share-modal.tsx +13 -12
  53. package/components/share/share.tsx +13 -12
  54. package/components/swiper/swiper.tsx +19 -15
  55. package/package.json +1 -1
  56. package/common/cdn-webpack-shim.ts +0 -5
  57. package/components/input/plugins/daterangepicker/jquery.daterangepicker.min.js +0 -1910
@@ -5,10 +5,13 @@ import type { ColFilterModalShowResponse } from './filter-modal';
5
5
  import Mark from 'mark.js';
6
6
  import Sortable from 'sortablejs';
7
7
  import { Prop, toNative } from 'vue-facing-decorator';
8
+ import { globalState } from '../../app/global-state';
8
9
  import PowerduckState from '../../app/powerduck-state';
9
10
  import TsxComponent, { Component } from '../../app/vuetsx';
10
11
  import { DialogResult, DialogUtils } from '../../common/dialog-utils';
11
12
  import { DialogIcons } from '../../common/enums/dialog-icons';
13
+ import { sortBy } from '../../common/extensions/array-extensions';
14
+ import { capitalize, latinize } from '../../common/extensions/string-extensions';
12
15
  import { QueryStringUtils } from '../../common/query-string-utils';
13
16
  import CheckboxUtils from '../../common/utils/checkbox-utils';
14
17
  import DropdownUtils from '../../common/utils/dropdown-utils';
@@ -32,2468 +35,2466 @@ import ColFilterModal from './filter-modal';
32
35
  import loadingGif from './img/loading_16_16.gif';
33
36
  import ReorderProvider from './ts/reorder';
34
37
  import './css/datatable.css';
35
- import { sortBy } from '../../common/extensions/array-extensions';
36
- import { capitalize, latinize } from '../../common/extensions/string-extensions';
37
38
 
38
39
  interface DataTableArgs {
39
- id: string;
40
- apiClient: IWebApiClient;
41
- apiMethod: WebClientApiMethod;
42
- allowMassOperations?: boolean;
43
- allowExport?: boolean;
44
- autoFetch?: boolean;
45
- apiArgs?: any;
46
- exportConfig?: DataTableExportConfig;
47
- paginations?: number[];
48
- paginationLength?: number;
49
- autoFilter?: boolean;
50
- fullSizeTable?: boolean;
51
- insetTop?: boolean;
52
- fullSizeHasButtonBelow?: boolean;
53
- filterMode?: DataTableFilterMode;
54
- checkboxesVisible?: boolean;
55
- checkboxButtonsVisible?: boolean;
56
- topVisible?: boolean;
57
- bottomVisible?: boolean;
58
- cssClass?: string;
59
- columns: TableColumn[];
60
- buttons?: TableButton[];
61
- rowIndexMode?: RowIndexMode;
62
- fulltextPlaceholder?: string;
63
- skin?: DataTableSkin;
64
- preserveOrderBy?: boolean;
65
- preserveFilter?: boolean;
66
- sortableRows?: boolean;
67
- customAjaxCall?: (args: DataTablePostBackData) => Promise<DataTableLoadedRowset>;
68
- parseLoadedRowset?: (serverResp: any) => DataTableLoadedRowset;
69
- rowClicked?: (row: any) => void;
70
- rowCssClass?: (row: any) => string;
71
- rowCheckstateChanged?: (row: any, checked: boolean, selectedRows: any[]) => void;
72
- mobileBehavior?: DataTableMobileBehavior;
73
- mobileModeCustomRender?: (h, columns: TableColumn[], rows: any) => void;
74
- sortComplete?: (args: DataTableOnSortedArgs) => void;
75
- mobileModeRowIcon?: string;
76
- mobileModeShouldAutoCollapse?: boolean;
77
- massOperationOptions?: typeof DropdownButtonItem.prototype[];
78
- handleInitialFilter?: boolean;
79
- timezoneGmtOffset?: number;
80
- timezoneDstOffset?: number;
81
- timeFilterShiftTimezone?: boolean;
82
- hidePagination?: boolean;
40
+ id: string;
41
+ apiClient: IWebApiClient;
42
+ apiMethod: WebClientApiMethod;
43
+ allowMassOperations?: boolean;
44
+ allowExport?: boolean;
45
+ autoFetch?: boolean;
46
+ apiArgs?: any;
47
+ exportConfig?: DataTableExportConfig;
48
+ paginations?: number[];
49
+ paginationLength?: number;
50
+ autoFilter?: boolean;
51
+ fullSizeTable?: boolean;
52
+ insetTop?: boolean;
53
+ fullSizeHasButtonBelow?: boolean;
54
+ filterMode?: DataTableFilterMode;
55
+ checkboxesVisible?: boolean;
56
+ checkboxButtonsVisible?: boolean;
57
+ topVisible?: boolean;
58
+ bottomVisible?: boolean;
59
+ cssClass?: string;
60
+ columns: TableColumn[];
61
+ buttons?: TableButton[];
62
+ rowIndexMode?: RowIndexMode;
63
+ fulltextPlaceholder?: string;
64
+ skin?: DataTableSkin;
65
+ preserveOrderBy?: boolean;
66
+ preserveFilter?: boolean;
67
+ sortableRows?: boolean;
68
+ customAjaxCall?: (args: DataTablePostBackData) => Promise<DataTableLoadedRowset>;
69
+ parseLoadedRowset?: (serverResp: any) => DataTableLoadedRowset;
70
+ rowClicked?: (row: any) => void;
71
+ rowCssClass?: (row: any) => string;
72
+ rowCheckstateChanged?: (row: any, checked: boolean, selectedRows: any[]) => void;
73
+ mobileBehavior?: DataTableMobileBehavior;
74
+ mobileModeCustomRender?: (h, columns: TableColumn[], rows: any) => void;
75
+ sortComplete?: (args: DataTableOnSortedArgs) => void;
76
+ mobileModeRowIcon?: string;
77
+ mobileModeShouldAutoCollapse?: boolean;
78
+ massOperationOptions?: typeof DropdownButtonItem.prototype[];
79
+ handleInitialFilter?: boolean;
80
+ timezoneGmtOffset?: number;
81
+ timezoneDstOffset?: number;
82
+ timeFilterShiftTimezone?: boolean;
83
+ hidePagination?: boolean;
83
84
  }
84
85
 
85
86
  export interface DataTableExportConfig {
86
- attrName: string;
87
- limitName?: string;
88
- pageName?: string;
87
+ attrName: string;
88
+ limitName?: string;
89
+ pageName?: string;
89
90
  }
90
91
 
91
92
  export interface DataTablePostBackData {
92
- ShowHidden: boolean;
93
- PaginationPosition: number;
94
- PaginationLength: number;
95
- SessionId: number;
96
- Filter: DataTableFilterDefinition;
97
- Sort: DataTableSortDefinition;
93
+ ShowHidden: boolean;
94
+ PaginationPosition: number;
95
+ PaginationLength: number;
96
+ SessionId: number;
97
+ Filter: DataTableFilterDefinition;
98
+ Sort: DataTableSortDefinition;
98
99
  }
99
100
 
100
101
  interface DataTableFilterDefinition {
101
- FullText: string;
102
- FilterItems: DataTablePostBackFilterItem[];
102
+ FullText: string;
103
+ FilterItems: DataTablePostBackFilterItem[];
103
104
  }
104
105
 
105
106
  export interface DataTableOnSortedArgs {
106
- oldIndex: number;
107
- newIndex: number;
107
+ oldIndex: number;
108
+ newIndex: number;
108
109
  }
109
110
 
110
111
  export interface DataTablePostBackFilterItem {
111
- PropertyName: string;
112
- ContainsValue?: string;
113
- EqualsValue?: string;
114
- FilterType: DataTableFilterItemType;
115
- NumFrom?: number;
116
- NumTo?: number;
117
- DateFrom?: Temporal.PlainDateTime;
118
- DateTo?: Temporal.PlainDateTime;
119
- ValueArr?: string[];
120
- ValueArrStrategy?: MultiSelectExclusivity;
112
+ PropertyName: string;
113
+ ContainsValue?: string;
114
+ EqualsValue?: string;
115
+ FilterType: DataTableFilterItemType;
116
+ NumFrom?: number;
117
+ NumTo?: number;
118
+ DateFrom?: Temporal.PlainDateTime;
119
+ DateTo?: Temporal.PlainDateTime;
120
+ ValueArr?: string[];
121
+ ValueArrStrategy?: MultiSelectExclusivity;
121
122
  }
122
123
 
123
124
  interface DataTableSortDefinition {
124
- PropertyName: string;
125
- Direction: DataTableSortDirection;
125
+ PropertyName: string;
126
+ Direction: DataTableSortDirection;
126
127
  }
127
128
 
128
129
  export enum DataTableFilterMode {
129
- Serverside = 0,
130
- Clientside = 1,
130
+ Serverside = 0,
131
+ Clientside = 1,
131
132
  }
132
133
 
133
134
  export enum DataTableFilterItemType {
134
- None = 0,
135
- Text = 1,
136
- Dropdown = 2,
137
- DateRange = 3,
138
- NumericRange = 4,
135
+ None = 0,
136
+ Text = 1,
137
+ Dropdown = 2,
138
+ DateRange = 3,
139
+ NumericRange = 4,
139
140
  }
140
141
 
141
142
  export enum DataTableSkin {
142
- Default = 'default',
143
- Compact = 'compact',
143
+ Default = 'default',
144
+ Compact = 'compact',
144
145
  }
145
146
 
146
147
  export enum DataTableMobileBehavior {
147
- MobileLayout = 'mobile',
148
- Compact = 'compact',
149
- VerticalTransform = 'vertical', // Do not use, shitty
148
+ MobileLayout = 'mobile',
149
+ Compact = 'compact',
150
+ VerticalTransform = 'vertical', // Do not use, shitty
150
151
  }
151
152
 
152
153
  export enum RowIndexMode {
153
- Identifier = 0,
154
- Index = 1,
154
+ Identifier = 0,
155
+ Index = 1,
155
156
  }
156
157
 
157
158
  export interface DataTableLoadedRowset {
158
- totalCount: number;
159
- totalFilteredCount: number;
160
- rows: any[];
159
+ totalCount: number;
160
+ totalFilteredCount: number;
161
+ rows: any[];
161
162
  }
162
163
 
163
164
  interface StoredState {
164
- sortOrder: string[];
165
- filter: DataTablePostBackFilterItem[];
166
- hiddenColumns: string[];
167
- visibleColumns: string[];
168
- paginationLength: number;
169
- orderBy: SortDefinition;
170
- skin: DataTableSkin;
171
- mobileBehavior: DataTableMobileBehavior;
165
+ sortOrder: string[];
166
+ filter: DataTablePostBackFilterItem[];
167
+ hiddenColumns: string[];
168
+ visibleColumns: string[];
169
+ paginationLength: number;
170
+ orderBy: SortDefinition;
171
+ skin: DataTableSkin;
172
+ mobileBehavior: DataTableMobileBehavior;
172
173
  }
173
174
 
174
175
  class RowIdentifier {
175
- name: string = null;
176
- surname: string = null;
177
- dtColumns: TableColumn[] = null;
178
-
179
- constructor(name: string, surname: string) {
180
- this.name = name;
181
- this.surname = surname;
182
- }
183
-
184
- get fullName(): string {
185
- return (`${this.name || ''} ${this.surname || ''}`).trim();
186
- }
176
+ name: string = null;
177
+ surname: string = null;
178
+ dtColumns: TableColumn[] = null;
179
+
180
+ constructor(name: string, surname: string) {
181
+ this.name = name;
182
+ this.surname = surname;
183
+ }
184
+
185
+ get fullName(): string {
186
+ return (`${this.name || ''} ${this.surname || ''}`).trim();
187
+ }
187
188
  }
188
189
 
189
190
  export enum DataTableSortDirection {
190
- Ascending = 0,
191
- Descending = 1,
191
+ Ascending = 0,
192
+ Descending = 1,
192
193
  }
193
194
 
194
195
  interface SortDefinition {
195
- columnId: string;
196
- direction: DataTableSortDirection;
196
+ columnId: string;
197
+ direction: DataTableSortDirection;
197
198
  }
198
199
 
199
200
  const enum DataTableBreakpoint {
200
- Desktop = 'desktop',
201
- Mobile = 'mobile',
201
+ Desktop = 'desktop',
202
+ Mobile = 'mobile',
202
203
  }
203
204
 
204
205
  class StorageHelper {
205
- private static getStorageKey(id: string) {
206
- return `bldt-${window.location.pathname.split('/').join('_')}${id}`;
207
- }
208
-
209
- static getStoredState(id: string): StoredState {
210
- const retVal = localStorage.getItem(StorageHelper.getStorageKey(id));
211
- if (retVal != null) {
212
- try {
213
- return JSON.parse(retVal);
214
- } catch (e) { }
215
- }
216
-
217
- return {} as any;
218
- }
219
-
220
- static saveStoredState(id: string, state: StoredState): void {
221
- localStorage.setItem(StorageHelper.getStorageKey(id), JSON.stringify(state));
222
- }
223
-
224
- static storeSortOrder(id: string, sortOrder: string[]) {
225
- const state = StorageHelper.getStoredState(id);
226
- if (sortOrder != null) {
227
- state.sortOrder = sortOrder;
228
- } else if (state.sortOrder != null) {
229
- delete state.sortOrder;
230
- }
231
-
232
- StorageHelper.saveStoredState(id, state);
233
- }
234
-
235
- static storeOrderBy(id: string, orderBy: SortDefinition) {
236
- const state = StorageHelper.getStoredState(id);
237
- if (orderBy != null) {
238
- state.orderBy = orderBy;
239
- } else if (state.orderBy != null) {
240
- delete state.orderBy;
241
- }
242
-
243
- StorageHelper.saveStoredState(id, state);
244
- }
245
-
246
- static storeColVis(id: string, columns: TableColumn[]) {
247
- const state = StorageHelper.getStoredState(id);
248
- state.hiddenColumns = columns.filter(p => p.visible == false).map(p => p.id);
249
- state.visibleColumns = columns.filter(p => (p as any)._enforceVisible == true).map(p => p.id);
250
- StorageHelper.saveStoredState(id, state);
251
- }
252
-
253
- static storePaginationLength(id: string, paginationLength: number) {
254
- const state = StorageHelper.getStoredState(id);
255
- state.paginationLength = paginationLength;
256
- StorageHelper.saveStoredState(id, state);
257
- }
258
-
259
- static storeSkin(id: string, skin: DataTableSkin) {
260
- const state = StorageHelper.getStoredState(id);
261
- state.skin = skin;
262
- StorageHelper.saveStoredState(id, state);
263
- }
264
-
265
- static storeMobileBehavior(id: string, mobileBehavior: DataTableMobileBehavior) {
266
- const state = StorageHelper.getStoredState(id);
267
- state.mobileBehavior = mobileBehavior;
268
- StorageHelper.saveStoredState(id, state);
269
- }
270
-
271
- static storeFilter(id: string, filter: DataTablePostBackFilterItem) {
272
- const state = StorageHelper.getStoredState(id);
273
- if (filter != null) {
274
- if (state.filter == null || state.filter.length == 0) {
275
- state.filter = [filter];
276
- } else {
277
- if (state.filter.some(p => p.PropertyName.includes(filter.PropertyName))) {
278
- state.filter = state.filter.filter(p => p.PropertyName != filter.PropertyName);
279
- }
280
-
281
- state.filter.push(filter);
282
- }
283
- } else if (state.filter != null) {
284
- delete state.filter;
285
- }
286
-
287
- StorageHelper.saveStoredState(id, state);
288
- }
206
+ private static getStorageKey(id: string) {
207
+ return `bldt-${(globalState.location?.pathname || '').split('/').join('_')}${id}`;
208
+ }
209
+
210
+ static getStoredState(id: string): StoredState {
211
+ const retVal = localStorage.getItem(StorageHelper.getStorageKey(id));
212
+ if (retVal != null) {
213
+ try {
214
+ return JSON.parse(retVal);
215
+ } catch (e) { }
216
+ }
217
+
218
+ return {} as any;
219
+ }
220
+
221
+ static saveStoredState(id: string, state: StoredState): void {
222
+ localStorage.setItem(StorageHelper.getStorageKey(id), JSON.stringify(state));
223
+ }
224
+
225
+ static storeSortOrder(id: string, sortOrder: string[]) {
226
+ const state = StorageHelper.getStoredState(id);
227
+ if (sortOrder != null) {
228
+ state.sortOrder = sortOrder;
229
+ } else if (state.sortOrder != null) {
230
+ delete state.sortOrder;
231
+ }
232
+
233
+ StorageHelper.saveStoredState(id, state);
234
+ }
235
+
236
+ static storeOrderBy(id: string, orderBy: SortDefinition) {
237
+ const state = StorageHelper.getStoredState(id);
238
+ if (orderBy != null) {
239
+ state.orderBy = orderBy;
240
+ } else if (state.orderBy != null) {
241
+ delete state.orderBy;
242
+ }
243
+
244
+ StorageHelper.saveStoredState(id, state);
245
+ }
246
+
247
+ static storeColVis(id: string, columns: TableColumn[]) {
248
+ const state = StorageHelper.getStoredState(id);
249
+ state.hiddenColumns = columns.filter(p => p.visible == false).map(p => p.id);
250
+ state.visibleColumns = columns.filter(p => (p as any)._enforceVisible == true).map(p => p.id);
251
+ StorageHelper.saveStoredState(id, state);
252
+ }
253
+
254
+ static storePaginationLength(id: string, paginationLength: number) {
255
+ const state = StorageHelper.getStoredState(id);
256
+ state.paginationLength = paginationLength;
257
+ StorageHelper.saveStoredState(id, state);
258
+ }
259
+
260
+ static storeSkin(id: string, skin: DataTableSkin) {
261
+ const state = StorageHelper.getStoredState(id);
262
+ state.skin = skin;
263
+ StorageHelper.saveStoredState(id, state);
264
+ }
265
+
266
+ static storeMobileBehavior(id: string, mobileBehavior: DataTableMobileBehavior) {
267
+ const state = StorageHelper.getStoredState(id);
268
+ state.mobileBehavior = mobileBehavior;
269
+ StorageHelper.saveStoredState(id, state);
270
+ }
271
+
272
+ static storeFilter(id: string, filter: DataTablePostBackFilterItem) {
273
+ const state = StorageHelper.getStoredState(id);
274
+ if (filter != null) {
275
+ if (state.filter == null || state.filter.length == 0) {
276
+ state.filter = [filter];
277
+ } else {
278
+ if (state.filter.some(p => p.PropertyName.includes(filter.PropertyName))) {
279
+ state.filter = state.filter.filter(p => p.PropertyName != filter.PropertyName);
280
+ }
281
+
282
+ state.filter.push(filter);
283
+ }
284
+ } else if (state.filter != null) {
285
+ delete state.filter;
286
+ }
287
+
288
+ StorageHelper.saveStoredState(id, state);
289
+ }
289
290
  }
290
291
 
291
292
  export interface TableColumn {
292
- id: string;
293
- caption: string;
294
- cssClass?: string;
295
- visible?: boolean;
296
- sortable?: boolean;
297
- searchable?: boolean;
298
- filterType?: DataTableFilterItemType;
299
- filterItems?: DataTableFilterItemCollection;
300
- filterAllowExclusivity?: boolean;
301
- customFilterValue?: (row) => string;
302
- mobileOrder?: number;
303
- mobileRender?: (h, row) => void;
304
- mobileCaption?: boolean;
305
- mobileVisible?: boolean;
306
- mobileShouldRenderRow?: (row) => boolean;
307
- exportInclude?: boolean;
308
- exportValue?: (row) => any;
309
- customValue?: (row) => string;
310
- customRender?: (h, row) => void;
311
- clientsideFilter?: (row: any, filterDefinition: DataTablePostBackFilterItem) => boolean;
293
+ id: string;
294
+ caption: string;
295
+ cssClass?: string;
296
+ visible?: boolean;
297
+ sortable?: boolean;
298
+ searchable?: boolean;
299
+ filterType?: DataTableFilterItemType;
300
+ filterItems?: DataTableFilterItemCollection;
301
+ filterAllowExclusivity?: boolean;
302
+ customFilterValue?: (row) => string;
303
+ mobileOrder?: number;
304
+ mobileRender?: (h, row) => void;
305
+ mobileCaption?: boolean;
306
+ mobileVisible?: boolean;
307
+ mobileShouldRenderRow?: (row) => boolean;
308
+ exportInclude?: boolean;
309
+ exportValue?: (row) => any;
310
+ customValue?: (row) => string;
311
+ customRender?: (h, row) => void;
312
+ clientsideFilter?: (row: any, filterDefinition: DataTablePostBackFilterItem) => boolean;
312
313
  }
313
314
 
314
315
  export interface TableButton {
315
- title: string;
316
- icon: string;
317
- clicked: () => void;
318
- childItems?: TableButtonChildItem[];
319
- customRender?: (h, row) => void;
316
+ title: string;
317
+ icon: string;
318
+ clicked: () => void;
319
+ childItems?: TableButtonChildItem[];
320
+ customRender?: (h, row) => void;
320
321
  }
321
322
 
322
323
  export interface TableButtonChildItem extends TableButton {
323
- isSelectable?: boolean;
324
- isSelected?: boolean;
324
+ isSelectable?: boolean;
325
+ isSelected?: boolean;
325
326
  }
326
327
 
327
328
  export interface DataTableFilterItem {
328
- id: string;
329
- text: string;
329
+ id: string;
330
+ text: string;
330
331
  }
331
332
 
332
333
  export class DataTableFilterItemCollection extends Array<DataTableFilterItem> {
333
- allowExclusiveSearch: boolean = false;
334
-
335
- constructor(allowExclusive: boolean, items: DataTableFilterItem[]) {
336
- super();
337
- this.allowExclusiveSearch = allowExclusive;
338
- (items || []).forEach((item) => {
339
- this.push(item);
340
- });
341
- }
334
+ allowExclusiveSearch: boolean = false;
335
+
336
+ constructor(allowExclusive: boolean, items: DataTableFilterItem[]) {
337
+ super();
338
+ this.allowExclusiveSearch = allowExclusive;
339
+ (items || []).forEach((item) => {
340
+ this.push(item);
341
+ });
342
+ }
342
343
  }
343
344
 
344
345
  export class DataTableConfig {
345
- static filterMarking = true;
346
+ static filterMarking = true;
346
347
  }
347
348
 
348
349
  @Component
349
350
  class TableButtonComponent extends TsxComponent<TableButton> implements TableButton {
350
- @Prop() title!: string;
351
- @Prop() icon!: string;
352
- @Prop() cssClass!: string;
353
- @Prop() clicked: () => void;
354
- @Prop() customRender: (h, row) => void;
355
- @Prop() childItems!: TableButtonChildItem[];
356
- randomUUID: string = `ddl-${PortalUtils.randomString(10)}`;
357
-
358
- render(h) {
359
- if (isNullOrEmpty(this.childItems)) {
360
- return (
361
- <button class={`dt-button${this.cssClass != null ? ` ${this.cssClass}` : ''}`} title={this.title} onClick={this.clicked}>
362
- <span>
363
- <i class={this.icon}></i>
364
- </span>
365
- </button>
366
- );
367
- } else {
368
- return (
369
- <span class="nav-item dt-button dropdown">
370
- <span class="dropdown-toggle" id={this.randomUUID} data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
371
- <i class={this.icon}></i>
372
- </span>
373
- <div class="dropdown-menu dropdown-menu-right" aria-labelledby={this.randomUUID}>
374
- {this.childItems.map(childItem => (
375
- <a class={`dropdown-item${childItem.isSelectable == true ? ' dropdown-selectable-section' : ''}`} href="javascript:" onClick={() => childItem.clicked()}>
376
- <span>{childItem.title}</span>
377
- {childItem.isSelected && <i class="fas fa-check"></i>}
378
- </a>
379
- ))}
380
- </div>
381
- </span>
382
- );
383
- }
384
- }
351
+ @Prop() title!: string;
352
+ @Prop() icon!: string;
353
+ @Prop() cssClass!: string;
354
+ @Prop() clicked: () => void;
355
+ @Prop() customRender: (h, row) => void;
356
+ @Prop() childItems!: TableButtonChildItem[];
357
+ randomUUID: string = `ddl-${PortalUtils.randomString(10)}`;
358
+
359
+ render(h) {
360
+ if (isNullOrEmpty(this.childItems)) {
361
+ return (
362
+ <button class={`dt-button${this.cssClass != null ? ` ${this.cssClass}` : ''}`} title={this.title} onClick={this.clicked}>
363
+ <span>
364
+ <i class={this.icon}></i>
365
+ </span>
366
+ </button>
367
+ );
368
+ } else {
369
+ return (
370
+ <span class="nav-item dt-button dropdown">
371
+ <span class="dropdown-toggle" id={this.randomUUID} data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
372
+ <i class={this.icon}></i>
373
+ </span>
374
+ <div class="dropdown-menu dropdown-menu-right" aria-labelledby={this.randomUUID}>
375
+ {this.childItems.map(childItem => (
376
+ <a class={`dropdown-item${childItem.isSelectable == true ? ' dropdown-selectable-section' : ''}`} href="javascript:" onClick={() => childItem.clicked()}>
377
+ <span>{childItem.title}</span>
378
+ {childItem.isSelected && <i class="fas fa-check"></i>}
379
+ </a>
380
+ ))}
381
+ </div>
382
+ </span>
383
+ );
384
+ }
385
+ }
385
386
  }
386
387
 
387
388
  @Component
388
389
  class DataTableComponent extends TsxComponent<DataTableArgs> implements DataTableArgs {
389
- @Prop() id!: string;
390
- @Prop() apiClient!: IWebApiClient;
391
- @Prop() apiMethod!: WebClientApiMethod;
392
- @Prop() allowMassOperations!: boolean;
393
- @Prop() allowExport!: boolean;
394
- @Prop() apiArgs!: any;
395
- @Prop() exportConfig?: DataTableExportConfig;
396
- @Prop() paginations?: number[];
397
- @Prop() paginationLengthProp!: number;
398
- @Prop() cssClass!: string;
399
- @Prop() autoFilter!: boolean;
400
- @Prop() insetTop!: boolean;
401
- @Prop() topVisible!: boolean;
402
- @Prop() bottomVisible!: boolean;
403
- @Prop() skin!: DataTableSkin;
404
- @Prop() preserveOrderBy!: boolean;
405
- @Prop() preserveFilter!: boolean;
406
- @Prop() sortableRows!: boolean;
407
- @Prop() filterMode!: DataTableFilterMode;
408
- @Prop() fullSizeTable!: boolean;
409
- @Prop() fullSizeHasButtonBelow!: boolean;
410
- @Prop() mobileBehavior!: DataTableMobileBehavior;
411
- @Prop() mobileModeCustomRender!: (h, columns: TableColumn[], rows: any) => void;
412
- @Prop() mobileModeRowIcon!: string;
413
- @Prop() mobileModeShouldAutoCollapse!: boolean;
414
- @Prop() handleInitialFilter!: boolean;
415
- @Prop() massOperationOptions!: typeof DropdownButtonItem.prototype[];
416
- @Prop() checkboxesVisible!: boolean;
417
- @Prop() checkboxesTitle!: string;
418
- @Prop() checkboxButtonsVisible!: boolean;
419
- @Prop() rowIndexMode!: RowIndexMode;
420
- @Prop() fulltextPlaceholder!: string;
421
- @Prop() timezoneGmtOffset!: number;
422
- @Prop() timezoneDstOffset!: number;
423
- @Prop() timeFilterShiftTimezone!: boolean;
424
- @Prop() columns!: TableColumn[];
425
- @Prop() buttons!: TableButton[];
426
- @Prop() rowClicked: (row: any) => void;
427
- @Prop() rowCssClass: (row: any) => string;
428
- @Prop() rowCheckstateChanged: (row: any, checked: boolean, selectedRows: any[]) => void;
429
- @Prop() parseLoadedRowset?: (serverResp: any) => DataTableLoadedRowset;
430
- @Prop() customAjaxCall?: (args: DataTablePostBackData) => Promise<DataTableLoadedRowset>;
431
- @Prop() sortComplete?: (args: DataTableOnSortedArgs) => void;
432
- @Prop() autoFetch!: boolean;
433
- @Prop() hidePagination!: boolean;
434
- paginationLength: number = this.paginationLengthProp ?? 50;
435
- paginationPosition: number = 1;
436
- isLoading: boolean = false;
437
- initialized: boolean = false;
438
- initDataLoaded: boolean = false;
439
- currentMobileBehavior: DataTableMobileBehavior = null;
440
- currentSkin: DataTableSkin = null;
441
- currentAdvancedFilterState: any = {};
442
- fullTextQuery: string;
443
-
444
- rows: any[] = [];
445
- loadedRows: any[];
446
- tableFilterTimeout: any = null;
447
- filterArr: DataTablePostBackFilterItem[] = [];
448
- sessionId: number = null;
449
- totalCount: number = 0;
450
- totalFilteredCount: number = 0;
451
- colSortOrder: string[] = null;
452
- enforceHeaderRedraw: boolean = false;
453
- enforceBodyRedraw: boolean = false;
454
- checkboxesShown: boolean = false;
455
- sortDefinition: SortDefinition = null;
456
- activeBreakPoint: DataTableBreakpoint = null;
457
- markInstance: any = null;
458
-
459
- mounted(): void {
460
- this.checkboxesShown = this.checkboxesVisible == true;
461
- this.currentSkin = this.skin;
462
- this.currentMobileBehavior = this.mobileBehavior;
463
- this.performColumnRefresh();
464
- this.handleWindowResized();
465
- window.addEventListener(
466
- 'resize',
467
- this.handleWindowResized,
468
- true,
469
- );
470
-
471
- if (DataTableConfig.filterMarking) {
472
- this.markInstance = new Mark(this.$el);
473
- }
474
-
475
- if (this.handleInitialFilter) {
476
- this.parseInitialFilter();
477
- }
478
-
479
- if (this.fullSizeTable) {
480
- const htmlElem = $('html');
481
- htmlElem.addClass('has-dt-fullsize');
482
-
483
- if (PortalUtils.treatAsMobileDevice()) {
484
- htmlElem.addClass('has-dt-fullsize-mobile');
485
- }
486
-
487
- if (PortalUtils.isIOS()) {
488
- htmlElem.addClass('has-dt-fullsize-ios');
489
- }
490
- }
491
-
492
- if (this.sortableRows == true) {
493
- this.initRowSortable();
494
- }
495
-
496
- if (this.preserveFilter == true) {
497
- this.initRowFilters();
498
- }
499
-
500
- if (this.autoFetch != false) {
501
- setTimeout(async () => {
502
- this.loadInitialData();
503
- }, 300);
504
- } else {
505
- this.initialized = true;
506
- }
507
- }
508
-
509
- updated(): void {
510
- if (this.autoFetch != false) {
511
- this.loadInitialData();
512
- } else {
513
- this.initialized = true;
514
- }
515
- }
516
-
517
- beforeUnmount(): void {
518
- if (this.fullSizeTable) {
519
- this.removeFullsizeModeLayoutCssClass();
520
-
521
- $('html').removeClass('has-dt-fullsize').removeClass('has-dt-fullsize-mobile').removeClass('has-dt-fullsize-ios');
522
- }
523
-
524
- window.removeEventListener(
525
- 'resize',
526
- this.handleWindowResized,
527
- true,
528
- );
529
- }
530
-
531
- loadInitialData(): void {
532
- if (this.apiArgs == null) {
533
- return;
534
- }
535
-
536
- if (!this.initialized && !this.initDataLoaded) {
537
- this.initDataLoaded = true;
538
- const self = this;
539
- this.reloadDataPromise().then(() => {
540
- setTimeout(() => {
541
- this.initialized = true;
542
- }, 1);
543
- });
544
- }
545
- }
546
-
547
- parseInitialFilter(): void {
548
- const self = this;
549
- const filterBy = QueryStringUtils.getString('filterBy');
550
- const orderBy = QueryStringUtils.getString('orderBy');
551
- const getColumn = function (id: string) {
552
- let column = self.columns.filter(p => p.id == id)[0];
553
- if (column == null && id.toLowerCase() == 'name') {
554
- column = self.columns.filter(p => (p as any).customField != null && (p as any).customField.MappingType == 1)[0];
555
- }
556
-
557
- if (column == null && id.toLowerCase() == 'surname') {
558
- column = self.columns.filter(p => (p as any).customField != null && (p as any).customField.MappingType == 2)[0];
559
- }
560
-
561
- return column;
562
- };
563
-
564
- const getParamArr = function (val: string): Array<Array<string>> {
565
- let arrOfArr: Array<Array<string>>;
566
- try {
567
- arrOfArr = JSON.parse(val);
568
- } catch (e) { }
569
-
570
- if (arrOfArr == null) {
571
- return null;
572
- }
573
-
574
- if (arrOfArr.length && arrOfArr.splice) {
575
- if (PortalUtils.isString(arrOfArr[0])) {
576
- arrOfArr = [arrOfArr as any];
577
- }
578
-
579
- return arrOfArr;
580
- }
581
-
582
- return null;
583
- };
584
-
585
- if (!isNullOrEmpty(filterBy)) {
586
- const arrOfArr = getParamArr(filterBy);
587
-
588
- if (!isNullOrEmpty(arrOfArr)) {
589
- arrOfArr.forEach((pair) => {
590
- const column = getColumn(pair[0]);
591
- if (column != null) {
592
- if (column.filterType == null || column.filterType == DataTableFilterItemType.Text) {
593
- this.addFilterItem(column, {
594
- PropertyName: column.id,
595
- ContainsValue: pair[1],
596
- FilterType: DataTableFilterItemType.Text,
597
- });
598
- } else if (column.filterType == DataTableFilterItemType.Dropdown) {
599
- this.addFilterItem(column, {
600
- PropertyName: column.id,
601
- ValueArr: [pair[1]],
602
- ValueArrStrategy: MultiSelectExclusivity.Exclusive,
603
- FilterType: DataTableFilterItemType.Dropdown,
604
- });
605
- }
606
- }
607
- });
608
- }
609
- }
610
-
611
- if (!isNullOrEmpty(orderBy)) {
612
- const arrOfArr = getParamArr(orderBy);
613
-
614
- if (!isNullOrEmpty(arrOfArr)) {
615
- arrOfArr.forEach((pair) => {
616
- const column = getColumn(pair[0]);
617
- if (column != null) {
618
- this.sortDefinition = {
619
- columnId: column.id,
620
- direction: pair[1] == 'desc' ? DataTableSortDirection.Descending : DataTableSortDirection.Ascending,
621
- };
622
- }
623
- });
624
- }
625
- }
626
- }
627
-
628
- async ensureMassPaginationConsent(): Promise<DialogResult> {
629
- const selectedCount = this.getSelectedRows().length;
630
- const paginationLength = this.getPaginationLength();
631
- if (paginationLength < 0) {
632
- return DialogResult.Confirm;
633
- }
634
-
635
- if (this.totalCount < paginationLength) {
636
- return DialogResult.Confirm;
637
- }
638
-
639
- if (selectedCount < paginationLength - 7) {
640
- return DialogResult.Confirm;
641
- }
642
-
643
- const continueLabel = `${PowerduckState.getResourceValue('continue')}&nbsp;&nbsp;<i class="icon icon-arrow-right-circle"></i>`;
644
- const messageHtml = PowerduckState.getResourceValue('dtMassOperationWarningText').replace('{0}', selectedCount.toString()).replace('{1}', this.totalCount.toString());
645
- const dialogResult = await DialogUtils.showConfirmDialog(
646
- PowerduckState.getResourceValue('warning'),
647
- messageHtml,
648
- continueLabel,
649
- PowerduckState.getResourceValue('cancel'),
650
- DialogIcons.Warning,
651
- );
652
- return dialogResult;
653
- }
654
-
655
- performColumnRefresh(): void {
656
- const savedState = StorageHelper.getStoredState(this.id);
657
- this.colSortOrder = savedState.sortOrder;
658
- this.handleColumnsVisibility(savedState, this.columns);
659
- this.paginationLength = savedState.paginationLength;
660
-
661
- if (savedState.skin != null) {
662
- this.currentSkin = savedState.skin;
663
- }
664
-
665
- if (savedState.mobileBehavior != null) {
666
- this.currentMobileBehavior = savedState.mobileBehavior;
667
- }
668
-
669
- if (savedState.orderBy != null) {
670
- this.sortDefinition = savedState.orderBy;
671
- }
672
-
673
- if (savedState.filter != null) {
674
- this.filterArr = savedState.filter;
675
- }
676
- }
677
-
678
- initRowSortable(): void {
679
- const args = {
680
- animation: 150,
681
- handle: '.dt-col-index',
682
- onEnd: (evt) => {
683
- this.sortComplete(evt);
684
- },
685
- } as any;
686
-
687
- this.$nextTick(() => {
688
- this.$nextTick(() => {
689
- new Sortable(this.$el.querySelector('tbody'), args);
690
- });
691
- });
692
- }
693
-
694
- reorderColumns(sortOrder: string[], columns: TableColumn[]): void {
695
- if (sortOrder != null && sortOrder.length >= columns.length) {
696
- const sorted = [];
697
- let allFound = true;
698
-
699
- if (sortOrder.length == columns.length) {
700
- sortOrder.forEach((propName) => {
701
- const ci = columns.filter(p => p.id == propName)[0];
702
- if (ci != null) {
703
- sorted.push(ci);
704
- } else {
705
- allFound = false;
706
- }
707
- });
708
- }
709
-
710
- if (!allFound) {
711
- StorageHelper.storeSortOrder(this.id, null);
712
- sortOrder = null;
713
- } else {
714
- columns.splice(0, columns.length);
715
- sorted.forEach((sortedCol) => {
716
- columns.push(sortedCol);
717
- });
718
- }
719
- }
720
- }
721
-
722
- initRowFilters(): void {
723
- const savedState = StorageHelper.getStoredState(this.id);
724
-
725
- if (savedState.filter == null) {
726
- return;
727
- }
728
-
729
- for (const filterItem of savedState.filter) {
730
- if (filterItem.FilterType == DataTableFilterItemType.None) {
731
- continue;
732
- } else if (filterItem.FilterType == DataTableFilterItemType.Dropdown) {
733
- this.currentAdvancedFilterState[filterItem.PropertyName] = filterItem.ValueArr;
734
- } else if (filterItem.FilterType == DataTableFilterItemType.DateRange) {
735
- this.currentAdvancedFilterState[filterItem.PropertyName] = {
736
- startTime: filterItem.DateFrom,
737
- endTime: filterItem.DateTo,
738
- };
739
- } else if (filterItem.FilterType == DataTableFilterItemType.NumericRange) {
740
-
741
- } else if (filterItem.FilterType == DataTableFilterItemType.Text) {
742
- this.currentAdvancedFilterState[filterItem.PropertyName] = filterItem.ContainsValue;
743
- }
744
- }
745
- }
746
-
747
- handleWindowResized(): void {
748
- const width = window.innerWidth;
749
- const breakpointMode = width > 767 ? DataTableBreakpoint.Desktop : DataTableBreakpoint.Mobile;
750
-
751
- if (breakpointMode != this.activeBreakPoint) {
752
- this.activeBreakPoint = breakpointMode;
753
- this.handleMobileBreakpointChanged();
754
- }
755
- }
756
-
757
- handleMobileBreakpointChanged() {
758
- if (this.fullSizeTable && PortalUtils.treatAsMobileDevice()) {
759
- this.removeFullsizeModeLayoutCssClass();
760
- $('html').addClass(`dt-fullsize-beh-${this.getMobileBehavior()}`);
761
- $('html').addClass(`dt-fullsize-skin-${this.getSkin()}`);
762
- }
763
- }
764
-
765
- removeFullsizeModeLayoutCssClass() {
766
- if (this.fullSizeTable && PortalUtils.treatAsMobileDevice()) {
767
- $('html')
768
- .removeClass(`dt-fullsize-beh-${DataTableMobileBehavior.Compact}`)
769
- .removeClass(`dt-fullsize-beh-${DataTableMobileBehavior.MobileLayout}`)
770
- .removeClass(`dt-fullsize-beh-${DataTableMobileBehavior.VerticalTransform}`)
771
- .removeClass(`dt-fullsize-skin-${DataTableSkin.Default}`)
772
- .removeClass(`dt-fullsize-skin-${DataTableSkin.Compact}`);
773
- }
774
- }
775
-
776
- handleColumnsVisibility(savedState: StoredState, columns: TableColumn[]): void {
777
- if (savedState.hiddenColumns != null) {
778
- savedState.hiddenColumns.forEach((hc) => {
779
- const colItem = columns.filter(p => p.id == hc)[0];
780
- if (colItem != null) {
781
- colItem.visible = false;
782
-
783
- if ((colItem as any)._enforceVisible != null) {
784
- delete (colItem as any)._enforceVisible;
785
- }
786
- }
787
- });
788
- }
789
-
790
- if (savedState.visibleColumns != null) {
791
- savedState.visibleColumns.forEach((vc) => {
792
- const colItem = columns.filter(p => p.id == vc)[0];
793
- if (colItem != null) {
794
- colItem.visible = true;
795
- (colItem as any)._enforceVisible = true;
796
- }
797
- });
798
- }
799
- }
800
-
801
- getPaginationLength(): number {
802
- return this.paginationLength || 50;
803
- }
804
-
805
- getTableColumnHeaderCssClass(column: TableColumn, index: number): string {
806
- return `dt-header-${column.id.split(':').join('_').toLowerCase()} dt-header-i${index} ${column.cssClass || ''}${column.sortable == false ? ' dt-header-notsortable' : ''}`;
807
- }
808
-
809
- getTableColumnHeaderFilterCssClass(column: TableColumn, index: number): string {
810
- return `header-filter-cell dt-filter-${column.id.split(':').join('_').toLowerCase()} dt-filter-i${index} dt-filtertype-${this.getFilterTypeName(column.filterType)}`;
811
- }
812
-
813
- getTableItemCssClass(column: TableColumn, index: number): string {
814
- return `dt-col-${column.id.split(':').join('_').toLowerCase()} dt-col-i${index} ${column.cssClass || ''}`;
815
- }
816
-
817
- getFilterTypeName(filterType: DataTableFilterItemType): string {
818
- switch (filterType) {
819
- case DataTableFilterItemType.None:
820
- return 'none';
821
-
822
- case null:
823
- case undefined:
824
- case DataTableFilterItemType.Text:
825
- return 'text';
826
-
827
- case DataTableFilterItemType.Dropdown:
828
- return 'dropdown';
829
-
830
- case DataTableFilterItemType.DateRange:
831
- return 'daterange';
832
-
833
- case DataTableFilterItemType.NumericRange:
834
- return 'numericrange';
835
-
836
- default:
837
- }
838
- }
839
-
840
- getRowIdProp(row: any): string {
841
- if (row?.Id != null) {
842
- return 'Id';
843
- }
844
-
845
- return 'id';
846
- }
847
-
848
- getRowId(row: any): number {
849
- return row[this.getRowIdProp(row)];
850
- }
851
-
852
- getSelectedRows(): any[] {
853
- const self = this;
854
- const selectedRows = [];
855
-
856
- if (isNullOrEmpty(self.rows)) {
857
- return [];
858
- }
859
-
860
- const rowIdProp = this.getRowIdProp(self.rows[0]);
861
-
862
- $('.dt-selection-checkbox input:checked').each(function (this: any) {
863
- const rowId = Number($(this).closest('.dt-selection-checkbox').attr('data-id'));
864
- const existingRow = selectedRows.filter(p => p[rowIdProp] == rowId)[0];
865
-
866
- if (existingRow == null) {
867
- const selectedRow = self.rows.filter(p => p[rowIdProp] == rowId)[0];
868
- if (selectedRow != null) {
869
- selectedRows.push(selectedRow);
870
- }
871
- }
872
- });
873
-
874
- return selectedRows;
875
- }
876
-
877
- unmarkSelection(cb: () => void): void {
878
- if (DataTableConfig.filterMarking) {
879
- this.markInstance.unmark({
880
- done: () => {
881
- this.enforceBodyRedraw = true;
882
- this.$nextTick(() => {
883
- this.enforceBodyRedraw = false;
884
- this.$nextTick(() => {
885
- cb();
886
- });
887
- });
888
- },
889
- });
890
- } else {
891
- cb();
892
- }
893
- }
894
-
895
- markSelection(): void {
896
- const mySelf = this;
897
- const escapeRegExp = function (string) {
898
- return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
899
- };
900
-
901
- const getValueArr = function (filterItem: DataTablePostBackFilterItem): string[] {
902
- if (!isNullOrEmpty(filterItem.EqualsValue)) {
903
- return [filterItem.EqualsValue];
904
- } else if (!isNullOrEmpty(filterItem.ContainsValue)) {
905
- return [filterItem.ContainsValue];
906
- } else if (!isNullOrEmpty(filterItem.ValueArr)) {
907
- return [];
908
- // return filterItem.ValueArr;
909
- }
910
- };
911
-
912
- let regexBuilder = '';
913
- const markArr = [];
914
- if (this.filterArr != null) {
915
- this.filterArr.forEach((filterItem) => {
916
- if (regexBuilder.length > 0) {
917
- regexBuilder += '|';
918
- }
919
-
920
- const columnId = filterItem.PropertyName?.toLowerCase();
921
- const tds = Array.from($(mySelf.$el).find(`td.dt-col-${columnId}`));
922
- if (tds == null || tds.length == 0) {
923
- return;
924
- }
925
-
926
- (getValueArr(filterItem) || []).forEach((filterValue) => {
927
- markArr.push({
928
- value: escapeRegExp(filterValue),
929
- elements: tds,
930
- });
931
- });
932
- });
933
- }
934
-
935
- if (!isNullOrEmpty(this.fullTextQuery)) {
936
- const value = escapeRegExp(this.fullTextQuery);
937
- const tds = Array.from($(mySelf.$el).find(`td`));
938
- regexBuilder += value;
939
-
940
- markArr.push({
941
- value,
942
- elements: tds,
943
- });
944
- }
945
-
946
- if (DataTableConfig.filterMarking) {
947
- this.unmarkSelection(() => {
948
- for (const item of markArr) {
949
- this.markInstance.mark(item.value, {
950
- filter: (node) => {
951
- const parentTd = $(node).closest('td')[0];
952
- if (!parentTd) {
953
- return false;
954
- }
955
-
956
- const matchesColumn = item.elements?.some(el => parentTd?.isEqualNode(el));
957
- const matchesText = parentTd?.textContent?.toLowerCase().includes(item.value.toLowerCase());
958
- return matchesColumn && matchesText;
959
- },
960
- });
961
- }
962
- });
963
- }
964
- }
965
-
966
- addFilterItem(dtColumn: TableColumn, newFilter: DataTablePostBackFilterItem): void {
967
- const existingItem = this.filterArr.filter(p => p.PropertyName == dtColumn.id)[0];
968
- const hasValue
390
+ @Prop() id!: string;
391
+ @Prop() apiClient!: IWebApiClient;
392
+ @Prop() apiMethod!: WebClientApiMethod;
393
+ @Prop() allowMassOperations!: boolean;
394
+ @Prop() allowExport!: boolean;
395
+ @Prop() apiArgs!: any;
396
+ @Prop() exportConfig?: DataTableExportConfig;
397
+ @Prop() paginations?: number[];
398
+ @Prop() paginationLengthProp!: number;
399
+ @Prop() cssClass!: string;
400
+ @Prop() autoFilter!: boolean;
401
+ @Prop() insetTop!: boolean;
402
+ @Prop() topVisible!: boolean;
403
+ @Prop() bottomVisible!: boolean;
404
+ @Prop() skin!: DataTableSkin;
405
+ @Prop() preserveOrderBy!: boolean;
406
+ @Prop() preserveFilter!: boolean;
407
+ @Prop() sortableRows!: boolean;
408
+ @Prop() filterMode!: DataTableFilterMode;
409
+ @Prop() fullSizeTable!: boolean;
410
+ @Prop() fullSizeHasButtonBelow!: boolean;
411
+ @Prop() mobileBehavior!: DataTableMobileBehavior;
412
+ @Prop() mobileModeCustomRender!: (h, columns: TableColumn[], rows: any) => void;
413
+ @Prop() mobileModeRowIcon!: string;
414
+ @Prop() mobileModeShouldAutoCollapse!: boolean;
415
+ @Prop() handleInitialFilter!: boolean;
416
+ @Prop() massOperationOptions!: typeof DropdownButtonItem.prototype[];
417
+ @Prop() checkboxesVisible!: boolean;
418
+ @Prop() checkboxesTitle!: string;
419
+ @Prop() checkboxButtonsVisible!: boolean;
420
+ @Prop() rowIndexMode!: RowIndexMode;
421
+ @Prop() fulltextPlaceholder!: string;
422
+ @Prop() timezoneGmtOffset!: number;
423
+ @Prop() timezoneDstOffset!: number;
424
+ @Prop() timeFilterShiftTimezone!: boolean;
425
+ @Prop() columns!: TableColumn[];
426
+ @Prop() buttons!: TableButton[];
427
+ @Prop() rowClicked: (row: any) => void;
428
+ @Prop() rowCssClass: (row: any) => string;
429
+ @Prop() rowCheckstateChanged: (row: any, checked: boolean, selectedRows: any[]) => void;
430
+ @Prop() parseLoadedRowset?: (serverResp: any) => DataTableLoadedRowset;
431
+ @Prop() customAjaxCall?: (args: DataTablePostBackData) => Promise<DataTableLoadedRowset>;
432
+ @Prop() sortComplete?: (args: DataTableOnSortedArgs) => void;
433
+ @Prop() autoFetch!: boolean;
434
+ @Prop() hidePagination!: boolean;
435
+ paginationLength: number = this.paginationLengthProp ?? 50;
436
+ paginationPosition: number = 1;
437
+ isLoading: boolean = false;
438
+ initialized: boolean = false;
439
+ initDataLoaded: boolean = false;
440
+ currentMobileBehavior: DataTableMobileBehavior = null;
441
+ currentSkin: DataTableSkin = null;
442
+ currentAdvancedFilterState: any = {};
443
+ fullTextQuery: string;
444
+
445
+ rows: any[] = [];
446
+ loadedRows: any[];
447
+ tableFilterTimeout: any = null;
448
+ filterArr: DataTablePostBackFilterItem[] = [];
449
+ sessionId: number = null;
450
+ totalCount: number = 0;
451
+ totalFilteredCount: number = 0;
452
+ colSortOrder: string[] = null;
453
+ enforceHeaderRedraw: boolean = false;
454
+ enforceBodyRedraw: boolean = false;
455
+ checkboxesShown: boolean = false;
456
+ sortDefinition: SortDefinition = null;
457
+ activeBreakPoint: DataTableBreakpoint = null;
458
+ markInstance: any = null;
459
+
460
+ mounted(): void {
461
+ this.checkboxesShown = this.checkboxesVisible == true;
462
+ this.currentSkin = this.skin;
463
+ this.currentMobileBehavior = this.mobileBehavior;
464
+ this.performColumnRefresh();
465
+ this.handleWindowResized();
466
+ globalState.addEventListener(
467
+ 'resize',
468
+ this.handleWindowResized,
469
+ true,
470
+ );
471
+
472
+ if (DataTableConfig.filterMarking) {
473
+ this.markInstance = new Mark(this.$el);
474
+ }
475
+
476
+ if (this.handleInitialFilter) {
477
+ this.parseInitialFilter();
478
+ }
479
+
480
+ if (this.fullSizeTable) {
481
+ const htmlElem = $('html');
482
+ htmlElem.addClass('has-dt-fullsize');
483
+
484
+ if (PortalUtils.treatAsMobileDevice()) {
485
+ htmlElem.addClass('has-dt-fullsize-mobile');
486
+ }
487
+
488
+ if (PortalUtils.isIOS()) {
489
+ htmlElem.addClass('has-dt-fullsize-ios');
490
+ }
491
+ }
492
+
493
+ if (this.sortableRows == true) {
494
+ this.initRowSortable();
495
+ }
496
+
497
+ if (this.preserveFilter == true) {
498
+ this.initRowFilters();
499
+ }
500
+
501
+ if (this.autoFetch != false) {
502
+ setTimeout(async () => {
503
+ this.loadInitialData();
504
+ }, 300);
505
+ } else {
506
+ this.initialized = true;
507
+ }
508
+ }
509
+
510
+ updated(): void {
511
+ if (this.autoFetch != false) {
512
+ this.loadInitialData();
513
+ } else {
514
+ this.initialized = true;
515
+ }
516
+ }
517
+
518
+ beforeUnmount(): void {
519
+ if (this.fullSizeTable) {
520
+ this.removeFullsizeModeLayoutCssClass();
521
+
522
+ $('html').removeClass('has-dt-fullsize').removeClass('has-dt-fullsize-mobile').removeClass('has-dt-fullsize-ios');
523
+ }
524
+
525
+ globalState.removeEventListener(
526
+ 'resize',
527
+ this.handleWindowResized,
528
+ true,
529
+ );
530
+ }
531
+
532
+ loadInitialData(): void {
533
+ if (this.apiArgs == null) {
534
+ return;
535
+ }
536
+
537
+ if (!this.initialized && !this.initDataLoaded) {
538
+ this.initDataLoaded = true;
539
+ const self = this;
540
+ this.reloadDataPromise().then(() => {
541
+ setTimeout(() => {
542
+ this.initialized = true;
543
+ }, 1);
544
+ });
545
+ }
546
+ }
547
+
548
+ parseInitialFilter(): void {
549
+ const self = this;
550
+ const filterBy = QueryStringUtils.getString('filterBy');
551
+ const orderBy = QueryStringUtils.getString('orderBy');
552
+ const getColumn = function (id: string) {
553
+ let column = self.columns.filter(p => p.id == id)[0];
554
+ if (column == null && id.toLowerCase() == 'name') {
555
+ column = self.columns.filter(p => (p as any).customField != null && (p as any).customField.MappingType == 1)[0];
556
+ }
557
+
558
+ if (column == null && id.toLowerCase() == 'surname') {
559
+ column = self.columns.filter(p => (p as any).customField != null && (p as any).customField.MappingType == 2)[0];
560
+ }
561
+
562
+ return column;
563
+ };
564
+
565
+ const getParamArr = function (val: string): Array<Array<string>> {
566
+ let arrOfArr: Array<Array<string>>;
567
+ try {
568
+ arrOfArr = JSON.parse(val);
569
+ } catch (e) { }
570
+
571
+ if (arrOfArr == null) {
572
+ return null;
573
+ }
574
+
575
+ if (arrOfArr.length && arrOfArr.splice) {
576
+ if (PortalUtils.isString(arrOfArr[0])) {
577
+ arrOfArr = [arrOfArr as any];
578
+ }
579
+
580
+ return arrOfArr;
581
+ }
582
+
583
+ return null;
584
+ };
585
+
586
+ if (!isNullOrEmpty(filterBy)) {
587
+ const arrOfArr = getParamArr(filterBy);
588
+
589
+ if (!isNullOrEmpty(arrOfArr)) {
590
+ arrOfArr.forEach((pair) => {
591
+ const column = getColumn(pair[0]);
592
+ if (column != null) {
593
+ if (column.filterType == null || column.filterType == DataTableFilterItemType.Text) {
594
+ this.addFilterItem(column, {
595
+ PropertyName: column.id,
596
+ ContainsValue: pair[1],
597
+ FilterType: DataTableFilterItemType.Text,
598
+ });
599
+ } else if (column.filterType == DataTableFilterItemType.Dropdown) {
600
+ this.addFilterItem(column, {
601
+ PropertyName: column.id,
602
+ ValueArr: [pair[1]],
603
+ ValueArrStrategy: MultiSelectExclusivity.Exclusive,
604
+ FilterType: DataTableFilterItemType.Dropdown,
605
+ });
606
+ }
607
+ }
608
+ });
609
+ }
610
+ }
611
+
612
+ if (!isNullOrEmpty(orderBy)) {
613
+ const arrOfArr = getParamArr(orderBy);
614
+
615
+ if (!isNullOrEmpty(arrOfArr)) {
616
+ arrOfArr.forEach((pair) => {
617
+ const column = getColumn(pair[0]);
618
+ if (column != null) {
619
+ this.sortDefinition = {
620
+ columnId: column.id,
621
+ direction: pair[1] == 'desc' ? DataTableSortDirection.Descending : DataTableSortDirection.Ascending,
622
+ };
623
+ }
624
+ });
625
+ }
626
+ }
627
+ }
628
+
629
+ async ensureMassPaginationConsent(): Promise<DialogResult> {
630
+ const selectedCount = this.getSelectedRows().length;
631
+ const paginationLength = this.getPaginationLength();
632
+ if (paginationLength < 0) {
633
+ return DialogResult.Confirm;
634
+ }
635
+
636
+ if (this.totalCount < paginationLength) {
637
+ return DialogResult.Confirm;
638
+ }
639
+
640
+ if (selectedCount < paginationLength - 7) {
641
+ return DialogResult.Confirm;
642
+ }
643
+
644
+ const continueLabel = `${PowerduckState.getResourceValue('continue')}&nbsp;&nbsp;<i class="icon icon-arrow-right-circle"></i>`;
645
+ const messageHtml = PowerduckState.getResourceValue('dtMassOperationWarningText').replace('{0}', selectedCount.toString()).replace('{1}', this.totalCount.toString());
646
+ const dialogResult = await DialogUtils.showConfirmDialog(
647
+ PowerduckState.getResourceValue('warning'),
648
+ messageHtml,
649
+ continueLabel,
650
+ PowerduckState.getResourceValue('cancel'),
651
+ DialogIcons.Warning,
652
+ );
653
+ return dialogResult;
654
+ }
655
+
656
+ performColumnRefresh(): void {
657
+ const savedState = StorageHelper.getStoredState(this.id);
658
+ this.colSortOrder = savedState.sortOrder;
659
+ this.handleColumnsVisibility(savedState, this.columns);
660
+ this.paginationLength = savedState.paginationLength;
661
+
662
+ if (savedState.skin != null) {
663
+ this.currentSkin = savedState.skin;
664
+ }
665
+
666
+ if (savedState.mobileBehavior != null) {
667
+ this.currentMobileBehavior = savedState.mobileBehavior;
668
+ }
669
+
670
+ if (savedState.orderBy != null) {
671
+ this.sortDefinition = savedState.orderBy;
672
+ }
673
+
674
+ if (savedState.filter != null) {
675
+ this.filterArr = savedState.filter;
676
+ }
677
+ }
678
+
679
+ initRowSortable(): void {
680
+ const args = {
681
+ animation: 150,
682
+ handle: '.dt-col-index',
683
+ onEnd: (evt) => {
684
+ this.sortComplete(evt);
685
+ },
686
+ } as any;
687
+
688
+ this.$nextTick(() => {
689
+ this.$nextTick(() => {
690
+ new Sortable(this.$el.querySelector('tbody'), args);
691
+ });
692
+ });
693
+ }
694
+
695
+ reorderColumns(sortOrder: string[], columns: TableColumn[]): void {
696
+ if (sortOrder != null && sortOrder.length >= columns.length) {
697
+ const sorted = [];
698
+ let allFound = true;
699
+
700
+ if (sortOrder.length == columns.length) {
701
+ sortOrder.forEach((propName) => {
702
+ const ci = columns.filter(p => p.id == propName)[0];
703
+ if (ci != null) {
704
+ sorted.push(ci);
705
+ } else {
706
+ allFound = false;
707
+ }
708
+ });
709
+ }
710
+
711
+ if (!allFound) {
712
+ StorageHelper.storeSortOrder(this.id, null);
713
+ sortOrder = null;
714
+ } else {
715
+ columns.splice(0, columns.length);
716
+ sorted.forEach((sortedCol) => {
717
+ columns.push(sortedCol);
718
+ });
719
+ }
720
+ }
721
+ }
722
+
723
+ initRowFilters(): void {
724
+ const savedState = StorageHelper.getStoredState(this.id);
725
+
726
+ if (savedState.filter == null) {
727
+ return;
728
+ }
729
+
730
+ for (const filterItem of savedState.filter) {
731
+ if (filterItem.FilterType == DataTableFilterItemType.None) {
732
+ continue;
733
+ } else if (filterItem.FilterType == DataTableFilterItemType.Dropdown) {
734
+ this.currentAdvancedFilterState[filterItem.PropertyName] = filterItem.ValueArr;
735
+ } else if (filterItem.FilterType == DataTableFilterItemType.DateRange) {
736
+ this.currentAdvancedFilterState[filterItem.PropertyName] = {
737
+ startTime: filterItem.DateFrom,
738
+ endTime: filterItem.DateTo,
739
+ };
740
+ } else if (filterItem.FilterType == DataTableFilterItemType.NumericRange) {
741
+ // TODO: Implement
742
+ } else if (filterItem.FilterType == DataTableFilterItemType.Text) {
743
+ this.currentAdvancedFilterState[filterItem.PropertyName] = filterItem.ContainsValue;
744
+ }
745
+ }
746
+ }
747
+
748
+ handleWindowResized(): void {
749
+ const width = globalState.innerWidth;
750
+ const breakpointMode = width > 767 ? DataTableBreakpoint.Desktop : DataTableBreakpoint.Mobile;
751
+
752
+ if (breakpointMode != this.activeBreakPoint) {
753
+ this.activeBreakPoint = breakpointMode;
754
+ this.handleMobileBreakpointChanged();
755
+ }
756
+ }
757
+
758
+ handleMobileBreakpointChanged() {
759
+ if (this.fullSizeTable && PortalUtils.treatAsMobileDevice()) {
760
+ this.removeFullsizeModeLayoutCssClass();
761
+ $('html').addClass(`dt-fullsize-beh-${this.getMobileBehavior()}`);
762
+ $('html').addClass(`dt-fullsize-skin-${this.getSkin()}`);
763
+ }
764
+ }
765
+
766
+ removeFullsizeModeLayoutCssClass() {
767
+ if (this.fullSizeTable && PortalUtils.treatAsMobileDevice()) {
768
+ $('html')
769
+ .removeClass(`dt-fullsize-beh-${DataTableMobileBehavior.Compact}`)
770
+ .removeClass(`dt-fullsize-beh-${DataTableMobileBehavior.MobileLayout}`)
771
+ .removeClass(`dt-fullsize-beh-${DataTableMobileBehavior.VerticalTransform}`)
772
+ .removeClass(`dt-fullsize-skin-${DataTableSkin.Default}`)
773
+ .removeClass(`dt-fullsize-skin-${DataTableSkin.Compact}`);
774
+ }
775
+ }
776
+
777
+ handleColumnsVisibility(savedState: StoredState, columns: TableColumn[]): void {
778
+ if (savedState.hiddenColumns != null) {
779
+ savedState.hiddenColumns.forEach((hc) => {
780
+ const colItem = columns.filter(p => p.id == hc)[0];
781
+ if (colItem != null) {
782
+ colItem.visible = false;
783
+
784
+ if ((colItem as any)._enforceVisible != null) {
785
+ delete (colItem as any)._enforceVisible;
786
+ }
787
+ }
788
+ });
789
+ }
790
+
791
+ if (savedState.visibleColumns != null) {
792
+ savedState.visibleColumns.forEach((vc) => {
793
+ const colItem = columns.filter(p => p.id == vc)[0];
794
+ if (colItem != null) {
795
+ colItem.visible = true;
796
+ (colItem as any)._enforceVisible = true;
797
+ }
798
+ });
799
+ }
800
+ }
801
+
802
+ getPaginationLength(): number {
803
+ return this.paginationLength || 50;
804
+ }
805
+
806
+ getTableColumnHeaderCssClass(column: TableColumn, index: number): string {
807
+ return `dt-header-${column.id.split(':').join('_').toLowerCase()} dt-header-i${index} ${column.cssClass || ''}${column.sortable == false ? ' dt-header-notsortable' : ''}`;
808
+ }
809
+
810
+ getTableColumnHeaderFilterCssClass(column: TableColumn, index: number): string {
811
+ return `header-filter-cell dt-filter-${column.id.split(':').join('_').toLowerCase()} dt-filter-i${index} dt-filtertype-${this.getFilterTypeName(column.filterType)}`;
812
+ }
813
+
814
+ getTableItemCssClass(column: TableColumn, index: number): string {
815
+ return `dt-col-${column.id.split(':').join('_').toLowerCase()} dt-col-i${index} ${column.cssClass || ''}`;
816
+ }
817
+
818
+ getFilterTypeName(filterType: DataTableFilterItemType): string {
819
+ switch (filterType) {
820
+ case DataTableFilterItemType.None:
821
+ return 'none';
822
+
823
+ case null:
824
+ case undefined:
825
+ case DataTableFilterItemType.Text:
826
+ return 'text';
827
+
828
+ case DataTableFilterItemType.Dropdown:
829
+ return 'dropdown';
830
+
831
+ case DataTableFilterItemType.DateRange:
832
+ return 'daterange';
833
+
834
+ case DataTableFilterItemType.NumericRange:
835
+ return 'numericrange';
836
+
837
+ default:
838
+ }
839
+ }
840
+
841
+ getRowIdProp(row: any): string {
842
+ if (row?.Id != null) {
843
+ return 'Id';
844
+ }
845
+
846
+ return 'id';
847
+ }
848
+
849
+ getRowId(row: any): number {
850
+ return row[this.getRowIdProp(row)];
851
+ }
852
+
853
+ getSelectedRows(): any[] {
854
+ const self = this;
855
+ const selectedRows = [];
856
+
857
+ if (isNullOrEmpty(self.rows)) {
858
+ return [];
859
+ }
860
+
861
+ const rowIdProp = this.getRowIdProp(self.rows[0]);
862
+
863
+ $('.dt-selection-checkbox input:checked').each(function (this: any) {
864
+ const rowId = Number($(this).closest('.dt-selection-checkbox').attr('data-id'));
865
+ const existingRow = selectedRows.filter(p => p[rowIdProp] == rowId)[0];
866
+
867
+ if (existingRow == null) {
868
+ const selectedRow = self.rows.filter(p => p[rowIdProp] == rowId)[0];
869
+ if (selectedRow != null) {
870
+ selectedRows.push(selectedRow);
871
+ }
872
+ }
873
+ });
874
+
875
+ return selectedRows;
876
+ }
877
+
878
+ unmarkSelection(cb: () => void): void {
879
+ if (DataTableConfig.filterMarking) {
880
+ this.markInstance.unmark({
881
+ done: () => {
882
+ this.enforceBodyRedraw = true;
883
+ this.$nextTick(() => {
884
+ this.enforceBodyRedraw = false;
885
+ this.$nextTick(() => {
886
+ cb();
887
+ });
888
+ });
889
+ },
890
+ });
891
+ } else {
892
+ cb();
893
+ }
894
+ }
895
+
896
+ markSelection(): void {
897
+ const mySelf = this;
898
+ const escapeRegExp = function (string) {
899
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
900
+ };
901
+
902
+ const getValueArr = function (filterItem: DataTablePostBackFilterItem): string[] {
903
+ if (!isNullOrEmpty(filterItem.EqualsValue)) {
904
+ return [filterItem.EqualsValue];
905
+ } else if (!isNullOrEmpty(filterItem.ContainsValue)) {
906
+ return [filterItem.ContainsValue];
907
+ } else if (!isNullOrEmpty(filterItem.ValueArr)) {
908
+ return [];
909
+ // return filterItem.ValueArr;
910
+ }
911
+ };
912
+
913
+ let regexBuilder = '';
914
+ const markArr = [];
915
+ if (this.filterArr != null) {
916
+ this.filterArr.forEach((filterItem) => {
917
+ if (regexBuilder.length > 0) {
918
+ regexBuilder += '|';
919
+ }
920
+
921
+ const columnId = filterItem.PropertyName?.toLowerCase();
922
+ const tds = Array.from($(mySelf.$el).find(`td.dt-col-${columnId}`));
923
+ if (tds == null || tds.length == 0) {
924
+ return;
925
+ }
926
+
927
+ (getValueArr(filterItem) || []).forEach((filterValue) => {
928
+ markArr.push({
929
+ value: escapeRegExp(filterValue),
930
+ elements: tds,
931
+ });
932
+ });
933
+ });
934
+ }
935
+
936
+ if (!isNullOrEmpty(this.fullTextQuery)) {
937
+ const value = escapeRegExp(this.fullTextQuery);
938
+ const tds = Array.from($(mySelf.$el).find(`td`));
939
+ regexBuilder += value;
940
+
941
+ markArr.push({
942
+ value,
943
+ elements: tds,
944
+ });
945
+ }
946
+
947
+ if (DataTableConfig.filterMarking) {
948
+ this.unmarkSelection(() => {
949
+ for (const item of markArr) {
950
+ this.markInstance.mark(item.value, {
951
+ filter: (node) => {
952
+ const parentTd = $(node).closest('td')[0];
953
+ if (!parentTd) {
954
+ return false;
955
+ }
956
+
957
+ const matchesColumn = item.elements?.some(el => parentTd?.isEqualNode(el));
958
+ const matchesText = parentTd?.textContent?.toLowerCase().includes(item.value.toLowerCase());
959
+ return matchesColumn && matchesText;
960
+ },
961
+ });
962
+ }
963
+ });
964
+ }
965
+ }
966
+
967
+ addFilterItem(dtColumn: TableColumn, newFilter: DataTablePostBackFilterItem): void {
968
+ const existingItem = this.filterArr.filter(p => p.PropertyName == dtColumn.id)[0];
969
+ const hasValue
969
970
  = !isNullOrEmpty(newFilter.ContainsValue)
970
- || !isNullOrEmpty(newFilter.EqualsValue)
971
- || !isNullOrEmpty(newFilter.ValueArr)
972
- || newFilter.DateFrom != null
973
- || newFilter.DateTo != null
974
- || newFilter.NumFrom != null
975
- || newFilter.NumTo != null;
976
-
977
- if (existingItem == null && hasValue) {
978
- this.filterArr.push(newFilter);
979
- return;
980
- }
981
-
982
- this.filterArr.splice(this.filterArr.indexOf(existingItem), 1);
983
- if (existingItem != null && hasValue) {
984
- this.filterArr.push(newFilter);
985
- }
986
- }
987
-
988
- filterDataHaveChanged(dtColumn: TableColumn, filterItem: DataTablePostBackFilterItem): boolean {
989
- const currentData: DataTablePostBackFilterItem = this.filterArr.filter(p => p.PropertyName == dtColumn.id)[0] || ({} as any);
990
- return JSON.stringify(currentData) != JSON.stringify(filterItem);
991
- }
992
-
993
- handleClientsideFilter(markResults?: boolean): boolean {
994
- if (this.filterMode == DataTableFilterMode.Clientside) {
995
- this.unmarkSelection(() => {
996
- this.performClientsideFilter();
997
-
998
- if (markResults) {
999
- this.markSelection();
1000
- }
1001
- });
1002
-
1003
- return true;
1004
- }
1005
-
1006
- return false;
1007
- }
1008
-
1009
- performFullTextSearch(e): void {
1010
- if (this.tableFilterTimeout != null) {
1011
- clearTimeout(this.tableFilterTimeout);
1012
- }
1013
-
1014
- this.fullTextQuery = e.target.value;
1015
-
1016
- e = e || window.event;
1017
- let charCode: number = -1;
1018
- if (e.which) {
1019
- charCode = e.which;
1020
- } else if (e.keyCode) {
1021
- charCode = e.keyCode;
1022
- }
1023
-
1024
- if (charCode == 13) {
1025
- if (this.handleClientsideFilter(true)) {
1026
- return;
1027
- }
1028
-
1029
- this.reloadData();
1030
- } else {
1031
- this.tableFilterTimeout = setTimeout(() => {
1032
- if (this.handleClientsideFilter(true)) {
1033
- return;
1034
- }
1035
-
1036
- this.reloadData();
1037
- }, 750);
1038
- }
1039
- }
1040
-
1041
- performInputFilter(dtColumn: TableColumn, e): void {
1042
- if (this.tableFilterTimeout != null) {
1043
- clearTimeout(this.tableFilterTimeout);
1044
- }
1045
-
1046
- this.currentAdvancedFilterState[dtColumn.id] = e;
1047
-
1048
- const filterItem = {
1049
- PropertyName: dtColumn.id,
1050
- ContainsValue: (e || ''),
1051
- FilterType: DataTableFilterItemType.Text,
1052
- };
1053
-
1054
- this.addFilterItem(dtColumn, filterItem);
1055
-
1056
- if (this.preserveFilter == true) {
1057
- if (isNullOrEmpty(filterItem.ContainsValue)) {
1058
- StorageHelper.storeFilter(this.id, null);
1059
- } else {
1060
- StorageHelper.storeFilter(this.id, filterItem);
1061
- }
1062
- }
1063
-
1064
- if (this.handleClientsideFilter(true)) {
1065
- return;
1066
- }
1067
-
1068
- e = (e) || window.event;
1069
- let charCode: number = -1;
1070
- if (e.which) {
1071
- charCode = e.which;
1072
- } else if (e.keyCode) {
1073
- charCode = e.keyCode;
1074
- }
1075
-
1076
- if (charCode == 13) {
1077
- this.reloadData();
1078
- } else {
1079
- this.tableFilterTimeout = setTimeout(() => {
1080
- this.reloadData();
1081
- }, 750);
1082
- }
1083
- }
1084
-
1085
- performSelectionFilter(
1086
- dtColumn: TableColumn,
1087
- data: DataTableFilterItem[],
1088
- exclusivity: MultiSelectExclusivity,
1089
- ): void {
1090
- this.currentAdvancedFilterState[dtColumn.id] = data;
1091
-
1092
- const filterValue: DataTablePostBackFilterItem = {
1093
- PropertyName: dtColumn.id,
1094
- ValueArr: (data || []).map(p => p.id),
1095
- ValueArrStrategy: exclusivity == MultiSelectExclusivity.Exclusive ? MultiSelectExclusivity.Exclusive : MultiSelectExclusivity.Inclusive,
1096
- FilterType: DataTableFilterItemType.Dropdown,
1097
- };
1098
-
1099
- if (!this.filterDataHaveChanged(dtColumn, filterValue)) {
1100
- return;
1101
- }
1102
-
1103
- if (data == null || data.length == 0) {
1104
- this.addFilterItem(dtColumn, {} as any);
1105
- } else {
1106
- this.addFilterItem(dtColumn, filterValue);
1107
- }
1108
-
1109
- if (this.preserveFilter == true) {
1110
- if (data == null || data.length == 0) {
1111
- StorageHelper.storeFilter(this.id, null);
1112
- } else {
1113
- StorageHelper.storeFilter(this.id, filterValue);
1114
- }
1115
- }
1116
-
1117
- if (this.handleClientsideFilter(false)) {
1118
- return;
1119
- }
1120
-
1121
- // Immediate reload if changed, delay handled by the Dropdown component
1122
- this.reloadData();
1123
- }
1124
-
1125
- performDateRangeFilter(dtColumn: TableColumn, data: DaterangeChangedArgs): void {
1126
- this.currentAdvancedFilterState[dtColumn.id] = data;
1127
-
1128
- let startDate = data?.startTime;
1129
- let endDate = data?.endTime;
1130
- if (data == null || data.startTime == null || data.endTime == null) {
1131
- this.addFilterItem(dtColumn, {} as any);
1132
- }
1133
-
1134
- if (data != null && this.timeFilterShiftTimezone) {
1135
- let dstOffset = this.timezoneDstOffset;
1136
- let gmtOffset = this.timezoneGmtOffset;
1137
-
1138
- if (dstOffset == null && this.rows != null) {
1139
- dstOffset = (this.rows.filter(p => p.TimezoneDstOffset != null && p.TimezoneDstOffset != 0)[0] || {}).TimezoneDstOffset;
1140
- if (dstOffset == null) {
1141
- dstOffset = 0;
1142
- }
1143
- }
1144
-
1145
- if (gmtOffset == null && this.rows != null) {
1146
- gmtOffset = (this.rows.filter(p => p.TimezoneGmtOffset != null && p.TimezoneGmtOffset != 0)[0] || {}).TimezoneGmtOffset;
1147
- if (gmtOffset == null) {
1148
- gmtOffset = 0;
1149
- }
1150
- }
1151
-
1152
- startDate = TimezoneHelper.getUTCFromLocalDate(
1153
- startDate,
1154
- dstOffset,
1155
- gmtOffset,
1156
- );
1157
- endDate = TimezoneHelper.getUTCFromLocalDate(
1158
- endDate,
1159
- dstOffset,
1160
- gmtOffset,
1161
- );
1162
- }
1163
-
1164
- const filterValue: DataTablePostBackFilterItem = {
1165
- PropertyName: dtColumn.id,
1166
- DateFrom: startDate,
1167
- DateTo: endDate,
1168
- FilterType: DataTableFilterItemType.DateRange,
1169
- };
1170
-
1171
- if (!this.filterDataHaveChanged(dtColumn, filterValue)) {
1172
- return;
1173
- }
1174
-
1175
- if (data == null || data.startTime == null || data.endTime == null) {
1176
- this.addFilterItem(dtColumn, {} as any);
1177
- } else {
1178
- this.addFilterItem(dtColumn, filterValue);
1179
- }
1180
-
1181
- if (this.preserveFilter == true) {
1182
- if (data == null || data.startTime == null || data.endTime == null) {
1183
- StorageHelper.storeFilter(this.id, null);
1184
- } else {
1185
- StorageHelper.storeFilter(this.id, filterValue);
1186
- }
1187
- }
1188
-
1189
- if (this.handleClientsideFilter(false)) {
1190
- return;
1191
- }
1192
-
1193
- // Immediate reload if changed, delay handled by the Dropdown component
1194
- this.reloadData();
1195
- }
1196
-
1197
- performClientsideFilter(): void {
1198
- this.rows = this.getClientsideFilteredAndSortedRows(this.loadedRows);
1199
- }
1200
-
1201
- getClientsideFilteredAndSortedRows(rowArr: any[]): any[] {
1202
- let newRowArr = [...rowArr];
1203
- for (const filterData of this.filterArr) {
1204
- const column = this.columns.find(p => p.id == filterData.PropertyName);
1205
- const filterDef = column?.clientsideFilter;
1206
-
1207
- if (filterDef != null) {
1208
- if (!isNullOrEmpty(filterData.ContainsValue)) {
1209
- filterData.ContainsValue = this.normalizeStringForSearch(filterData.ContainsValue);
1210
- }
1211
-
1212
- newRowArr = newRowArr.filter((p) => {
1213
- return filterDef(p, filterData);
1214
- });
1215
-
1216
- continue;
1217
- }
1218
-
1219
- if (filterData.FilterType == DataTableFilterItemType.Text && !isNullOrEmpty(filterData.ContainsValue)) {
1220
- const containsVal = this.normalizeStringForSearch(filterData.ContainsValue);
1221
- newRowArr = newRowArr.filter((p) => {
1222
- let val: any;
1223
- if (column?.customFilterValue != null) {
1224
- val = column.customFilterValue(p);
1225
- } else if (column?.customValue != null) {
1226
- val = column.customValue(p);
1227
- } else {
1228
- val = p[filterData.PropertyName];
1229
- }
1230
-
1231
- if (val == null) {
1232
- return false;
1233
- }
1234
-
1235
- if (typeof val === 'string' || val instanceof String) {
1236
- return this.normalizeStringForSearch(val as any).includes(containsVal);
1237
- }
1238
-
1239
- return this.normalizeStringForSearch((p[filterData.PropertyName] || '').toString()).includes(containsVal);
1240
- });
1241
- } else if (filterData.FilterType == DataTableFilterItemType.Dropdown && !isNullOrEmpty(filterData.ValueArr)) {
1242
- newRowArr = newRowArr.filter((p) => {
1243
- let propVal: any;
1244
- if (column?.customFilterValue != null) {
1245
- propVal = column.customFilterValue(p);
1246
- } else if (column?.customValue != null) {
1247
- propVal = column.customValue(p);
1248
- } else {
1249
- propVal = p[filterData.PropertyName];
1250
- }
1251
-
1252
- if (propVal == null) {
1253
- return false;
1254
- }
1255
-
1256
- if (filterData.ValueArr.length == 1) {
1257
- return propVal == filterData.ValueArr[0];
1258
- } else if (filterData.ValueArrStrategy == MultiSelectExclusivity.Inclusive) {
1259
- return filterData.ValueArr.includes(propVal);
1260
- }
1261
-
1262
- return true;
1263
- });
1264
- } else if (filterData.FilterType == DataTableFilterItemType.DateRange) {
1265
- const fromMs = filterData.DateFrom?.toZonedDateTime('UTC')?.epochMilliseconds;
1266
- const toMs = filterData.DateTo?.toZonedDateTime('UTC')?.epochMilliseconds;
1267
-
1268
- newRowArr = newRowArr.filter((p) => {
1269
- let propVal: any;
1270
- if (column?.customFilterValue != null) {
1271
- propVal = column.customFilterValue(p);
1272
- } else if (column?.customValue != null) {
1273
- propVal = column.customValue(p);
1274
- } else {
1275
- propVal = p[filterData.PropertyName];
1276
- }
1277
-
1278
- if (propVal == null) {
1279
- return false;
1280
- }
1281
-
1282
- try {
1283
- if (typeof propVal == 'string') {
1284
- propVal = TemporalUtils.fromString(propVal);
1285
- }
1286
-
1287
- const timeMs = (propVal as Temporal.PlainDateTime)?.toZonedDateTime('UTC')?.epochMilliseconds;
1288
- return fromMs <= timeMs && toMs >= timeMs;
1289
- } catch (error) {
1290
- return false;
1291
- }
1292
- });
1293
- } else if (filterData.FilterType == DataTableFilterItemType.NumericRange) {
1294
- newRowArr = newRowArr.filter((p) => {
1295
- let propVal: any;
1296
- if (column?.customFilterValue != null) {
1297
- propVal = column.customFilterValue(p);
1298
- } else if (column?.customValue != null) {
1299
- propVal = column.customValue(p);
1300
- } else {
1301
- propVal = p[filterData.PropertyName];
1302
- }
1303
-
1304
- if (propVal == null) {
1305
- return false;
1306
- }
1307
-
1308
- return filterData.NumFrom <= propVal && filterData.NumTo >= propVal;
1309
- });
1310
- }
1311
- }
1312
-
1313
- if (!isNullOrEmpty(this.fullTextQuery)) {
1314
- const fulltextArr: any[] = [];
1315
- const normalizedQuery = this.normalizeStringForSearch(this.fullTextQuery);
1316
-
1317
- for (const row of newRowArr) {
1318
- for (const propName in row) {
1319
- const column = this.columns.find(p => p.id == propName);
1320
- let propVal: any;
1321
-
1322
- if (column?.customFilterValue != null) {
1323
- propVal = column.customFilterValue(row);
1324
- } else if (column?.customValue != null) {
1325
- propVal = column.customValue(row);
1326
- } else {
1327
- propVal = row[propName];
1328
- }
1329
-
1330
- if (propVal != null) {
1331
- if (this.normalizeStringForSearch(propVal.toString()).includes(normalizedQuery)) {
1332
- fulltextArr.push(row);
1333
- break;
1334
- }
1335
- }
1336
- }
1337
- }
1338
-
1339
- newRowArr = fulltextArr;
1340
- }
1341
-
1342
- if (this.sortDefinition != null) {
1343
- const colId = this.sortDefinition.columnId;
971
+ || !isNullOrEmpty(newFilter.EqualsValue)
972
+ || !isNullOrEmpty(newFilter.ValueArr)
973
+ || newFilter.DateFrom != null
974
+ || newFilter.DateTo != null
975
+ || newFilter.NumFrom != null
976
+ || newFilter.NumTo != null;
977
+
978
+ if (existingItem == null && hasValue) {
979
+ this.filterArr.push(newFilter);
980
+ return;
981
+ }
982
+
983
+ this.filterArr.splice(this.filterArr.indexOf(existingItem), 1);
984
+ if (existingItem != null && hasValue) {
985
+ this.filterArr.push(newFilter);
986
+ }
987
+ }
988
+
989
+ filterDataHaveChanged(dtColumn: TableColumn, filterItem: DataTablePostBackFilterItem): boolean {
990
+ const currentData: DataTablePostBackFilterItem = this.filterArr.filter(p => p.PropertyName == dtColumn.id)[0] || ({} as any);
991
+ return JSON.stringify(currentData) != JSON.stringify(filterItem);
992
+ }
993
+
994
+ handleClientsideFilter(markResults?: boolean): boolean {
995
+ if (this.filterMode == DataTableFilterMode.Clientside) {
996
+ this.unmarkSelection(() => {
997
+ this.performClientsideFilter();
998
+
999
+ if (markResults) {
1000
+ this.markSelection();
1001
+ }
1002
+ });
1003
+
1004
+ return true;
1005
+ }
1006
+
1007
+ return false;
1008
+ }
1009
+
1010
+ performFullTextSearch(e): void {
1011
+ if (this.tableFilterTimeout != null) {
1012
+ clearTimeout(this.tableFilterTimeout);
1013
+ }
1014
+
1015
+ this.fullTextQuery = e.target.value;
1016
+
1017
+ e = e || globalState.event;
1018
+ let charCode: number = -1;
1019
+ if (e.which) {
1020
+ charCode = e.which;
1021
+ } else if (e.keyCode) {
1022
+ charCode = e.keyCode;
1023
+ }
1024
+
1025
+ if (charCode == 13) {
1026
+ if (this.handleClientsideFilter(true)) {
1027
+ return;
1028
+ }
1029
+
1030
+ this.reloadData();
1031
+ } else {
1032
+ this.tableFilterTimeout = setTimeout(() => {
1033
+ if (this.handleClientsideFilter(true)) {
1034
+ return;
1035
+ }
1036
+
1037
+ this.reloadData();
1038
+ }, 750);
1039
+ }
1040
+ }
1041
+
1042
+ performInputFilter(dtColumn: TableColumn, e): void {
1043
+ if (this.tableFilterTimeout != null) {
1044
+ clearTimeout(this.tableFilterTimeout);
1045
+ }
1046
+
1047
+ this.currentAdvancedFilterState[dtColumn.id] = e;
1048
+
1049
+ const filterItem = {
1050
+ PropertyName: dtColumn.id,
1051
+ ContainsValue: (e || ''),
1052
+ FilterType: DataTableFilterItemType.Text,
1053
+ };
1054
+
1055
+ this.addFilterItem(dtColumn, filterItem);
1056
+
1057
+ if (this.preserveFilter == true) {
1058
+ if (isNullOrEmpty(filterItem.ContainsValue)) {
1059
+ StorageHelper.storeFilter(this.id, null);
1060
+ } else {
1061
+ StorageHelper.storeFilter(this.id, filterItem);
1062
+ }
1063
+ }
1064
+
1065
+ if (this.handleClientsideFilter(true)) {
1066
+ return;
1067
+ }
1068
+
1069
+ e = (e) || globalState.event;
1070
+ let charCode: number = -1;
1071
+ if (e.which) {
1072
+ charCode = e.which;
1073
+ } else if (e.keyCode) {
1074
+ charCode = e.keyCode;
1075
+ }
1076
+
1077
+ if (charCode == 13) {
1078
+ this.reloadData();
1079
+ } else {
1080
+ this.tableFilterTimeout = setTimeout(() => {
1081
+ this.reloadData();
1082
+ }, 750);
1083
+ }
1084
+ }
1085
+
1086
+ performSelectionFilter(
1087
+ dtColumn: TableColumn,
1088
+ data: DataTableFilterItem[],
1089
+ exclusivity: MultiSelectExclusivity,
1090
+ ): void {
1091
+ this.currentAdvancedFilterState[dtColumn.id] = data;
1092
+
1093
+ const filterValue: DataTablePostBackFilterItem = {
1094
+ PropertyName: dtColumn.id,
1095
+ ValueArr: (data || []).map(p => p.id),
1096
+ ValueArrStrategy: exclusivity == MultiSelectExclusivity.Exclusive ? MultiSelectExclusivity.Exclusive : MultiSelectExclusivity.Inclusive,
1097
+ FilterType: DataTableFilterItemType.Dropdown,
1098
+ };
1099
+
1100
+ if (!this.filterDataHaveChanged(dtColumn, filterValue)) {
1101
+ return;
1102
+ }
1103
+
1104
+ if (data == null || data.length == 0) {
1105
+ this.addFilterItem(dtColumn, {} as any);
1106
+ } else {
1107
+ this.addFilterItem(dtColumn, filterValue);
1108
+ }
1109
+
1110
+ if (this.preserveFilter == true) {
1111
+ if (data == null || data.length == 0) {
1112
+ StorageHelper.storeFilter(this.id, null);
1113
+ } else {
1114
+ StorageHelper.storeFilter(this.id, filterValue);
1115
+ }
1116
+ }
1117
+
1118
+ if (this.handleClientsideFilter(false)) {
1119
+ return;
1120
+ }
1121
+
1122
+ // Immediate reload if changed, delay handled by the Dropdown component
1123
+ this.reloadData();
1124
+ }
1125
+
1126
+ performDateRangeFilter(dtColumn: TableColumn, data: DaterangeChangedArgs): void {
1127
+ this.currentAdvancedFilterState[dtColumn.id] = data;
1128
+
1129
+ let startDate = data?.startTime;
1130
+ let endDate = data?.endTime;
1131
+ if (data == null || data.startTime == null || data.endTime == null) {
1132
+ this.addFilterItem(dtColumn, {} as any);
1133
+ }
1134
+
1135
+ if (data != null && this.timeFilterShiftTimezone) {
1136
+ let dstOffset = this.timezoneDstOffset;
1137
+ let gmtOffset = this.timezoneGmtOffset;
1138
+
1139
+ if (dstOffset == null && this.rows != null) {
1140
+ dstOffset = (this.rows.filter(p => p.TimezoneDstOffset != null && p.TimezoneDstOffset != 0)[0] || {}).TimezoneDstOffset;
1141
+ if (dstOffset == null) {
1142
+ dstOffset = 0;
1143
+ }
1144
+ }
1145
+
1146
+ if (gmtOffset == null && this.rows != null) {
1147
+ gmtOffset = (this.rows.filter(p => p.TimezoneGmtOffset != null && p.TimezoneGmtOffset != 0)[0] || {}).TimezoneGmtOffset;
1148
+ if (gmtOffset == null) {
1149
+ gmtOffset = 0;
1150
+ }
1151
+ }
1152
+
1153
+ startDate = TimezoneHelper.getUTCFromLocalDate(
1154
+ startDate,
1155
+ dstOffset,
1156
+ gmtOffset,
1157
+ );
1158
+ endDate = TimezoneHelper.getUTCFromLocalDate(
1159
+ endDate,
1160
+ dstOffset,
1161
+ gmtOffset,
1162
+ );
1163
+ }
1164
+
1165
+ const filterValue: DataTablePostBackFilterItem = {
1166
+ PropertyName: dtColumn.id,
1167
+ DateFrom: startDate,
1168
+ DateTo: endDate,
1169
+ FilterType: DataTableFilterItemType.DateRange,
1170
+ };
1171
+
1172
+ if (!this.filterDataHaveChanged(dtColumn, filterValue)) {
1173
+ return;
1174
+ }
1175
+
1176
+ if (data == null || data.startTime == null || data.endTime == null) {
1177
+ this.addFilterItem(dtColumn, {} as any);
1178
+ } else {
1179
+ this.addFilterItem(dtColumn, filterValue);
1180
+ }
1181
+
1182
+ if (this.preserveFilter == true) {
1183
+ if (data == null || data.startTime == null || data.endTime == null) {
1184
+ StorageHelper.storeFilter(this.id, null);
1185
+ } else {
1186
+ StorageHelper.storeFilter(this.id, filterValue);
1187
+ }
1188
+ }
1189
+
1190
+ if (this.handleClientsideFilter(false)) {
1191
+ return;
1192
+ }
1193
+
1194
+ // Immediate reload if changed, delay handled by the Dropdown component
1195
+ this.reloadData();
1196
+ }
1197
+
1198
+ performClientsideFilter(): void {
1199
+ this.rows = this.getClientsideFilteredAndSortedRows(this.loadedRows);
1200
+ }
1201
+
1202
+ getClientsideFilteredAndSortedRows(rowArr: any[]): any[] {
1203
+ let newRowArr = [...rowArr];
1204
+ for (const filterData of this.filterArr) {
1205
+ const column = this.columns.find(p => p.id == filterData.PropertyName);
1206
+ const filterDef = column?.clientsideFilter;
1207
+
1208
+ if (filterDef != null) {
1209
+ if (!isNullOrEmpty(filterData.ContainsValue)) {
1210
+ filterData.ContainsValue = this.normalizeStringForSearch(filterData.ContainsValue);
1211
+ }
1212
+
1213
+ newRowArr = newRowArr.filter((p) => {
1214
+ return filterDef(p, filterData);
1215
+ });
1216
+
1217
+ continue;
1218
+ }
1219
+
1220
+ if (filterData.FilterType == DataTableFilterItemType.Text && !isNullOrEmpty(filterData.ContainsValue)) {
1221
+ const containsVal = this.normalizeStringForSearch(filterData.ContainsValue);
1222
+ newRowArr = newRowArr.filter((p) => {
1223
+ let val: any;
1224
+ if (column?.customFilterValue != null) {
1225
+ val = column.customFilterValue(p);
1226
+ } else if (column?.customValue != null) {
1227
+ val = column.customValue(p);
1228
+ } else {
1229
+ val = p[filterData.PropertyName];
1230
+ }
1231
+
1232
+ if (val == null) {
1233
+ return false;
1234
+ }
1235
+
1236
+ if (typeof val === 'string' || val instanceof String) {
1237
+ return this.normalizeStringForSearch(val as any).includes(containsVal);
1238
+ }
1239
+
1240
+ return this.normalizeStringForSearch((p[filterData.PropertyName] || '').toString()).includes(containsVal);
1241
+ });
1242
+ } else if (filterData.FilterType == DataTableFilterItemType.Dropdown && !isNullOrEmpty(filterData.ValueArr)) {
1243
+ newRowArr = newRowArr.filter((p) => {
1244
+ let propVal: any;
1245
+ if (column?.customFilterValue != null) {
1246
+ propVal = column.customFilterValue(p);
1247
+ } else if (column?.customValue != null) {
1248
+ propVal = column.customValue(p);
1249
+ } else {
1250
+ propVal = p[filterData.PropertyName];
1251
+ }
1252
+
1253
+ if (propVal == null) {
1254
+ return false;
1255
+ }
1256
+
1257
+ if (filterData.ValueArr.length == 1) {
1258
+ return propVal == filterData.ValueArr[0];
1259
+ } else if (filterData.ValueArrStrategy == MultiSelectExclusivity.Inclusive) {
1260
+ return filterData.ValueArr.includes(propVal);
1261
+ }
1262
+
1263
+ return true;
1264
+ });
1265
+ } else if (filterData.FilterType == DataTableFilterItemType.DateRange) {
1266
+ const fromMs = filterData.DateFrom?.toZonedDateTime('UTC')?.epochMilliseconds;
1267
+ const toMs = filterData.DateTo?.toZonedDateTime('UTC')?.epochMilliseconds;
1268
+
1269
+ newRowArr = newRowArr.filter((p) => {
1270
+ let propVal: any;
1271
+ if (column?.customFilterValue != null) {
1272
+ propVal = column.customFilterValue(p);
1273
+ } else if (column?.customValue != null) {
1274
+ propVal = column.customValue(p);
1275
+ } else {
1276
+ propVal = p[filterData.PropertyName];
1277
+ }
1278
+
1279
+ if (propVal == null) {
1280
+ return false;
1281
+ }
1282
+
1283
+ try {
1284
+ if (typeof propVal == 'string') {
1285
+ propVal = TemporalUtils.fromString(propVal);
1286
+ }
1287
+
1288
+ const timeMs = (propVal as Temporal.PlainDateTime)?.toZonedDateTime('UTC')?.epochMilliseconds;
1289
+ return fromMs <= timeMs && toMs >= timeMs;
1290
+ } catch (error) {
1291
+ return false;
1292
+ }
1293
+ });
1294
+ } else if (filterData.FilterType == DataTableFilterItemType.NumericRange) {
1295
+ newRowArr = newRowArr.filter((p) => {
1296
+ let propVal: any;
1297
+ if (column?.customFilterValue != null) {
1298
+ propVal = column.customFilterValue(p);
1299
+ } else if (column?.customValue != null) {
1300
+ propVal = column.customValue(p);
1301
+ } else {
1302
+ propVal = p[filterData.PropertyName];
1303
+ }
1304
+
1305
+ if (propVal == null) {
1306
+ return false;
1307
+ }
1308
+
1309
+ return filterData.NumFrom <= propVal && filterData.NumTo >= propVal;
1310
+ });
1311
+ }
1312
+ }
1313
+
1314
+ if (!isNullOrEmpty(this.fullTextQuery)) {
1315
+ const fulltextArr: any[] = [];
1316
+ const normalizedQuery = this.normalizeStringForSearch(this.fullTextQuery);
1317
+
1318
+ for (const row of newRowArr) {
1319
+ for (const propName in row) {
1320
+ const column = this.columns.find(p => p.id == propName);
1321
+ let propVal: any;
1322
+
1323
+ if (column?.customFilterValue != null) {
1324
+ propVal = column.customFilterValue(row);
1325
+ } else if (column?.customValue != null) {
1326
+ propVal = column.customValue(row);
1327
+ } else {
1328
+ propVal = row[propName];
1329
+ }
1330
+
1331
+ if (propVal != null) {
1332
+ if (this.normalizeStringForSearch(propVal.toString()).includes(normalizedQuery)) {
1333
+ fulltextArr.push(row);
1334
+ break;
1335
+ }
1336
+ }
1337
+ }
1338
+ }
1339
+
1340
+ newRowArr = fulltextArr;
1341
+ }
1342
+
1343
+ if (this.sortDefinition != null) {
1344
+ const colId = this.sortDefinition.columnId;
1344
1345
  type SORT_TYPE_OPTS = 'string' | 'date' | 'unknown';
1345
1346
  let sortType: SORT_TYPE_OPTS = 'unknown';
1346
1347
 
1347
1348
  for (const row of newRowArr) {
1348
- const item = row[colId];
1349
- if (item == null) {
1350
- continue;
1351
- }
1352
-
1353
- if (typeof item === 'string' || item instanceof String) {
1354
- sortType = 'string';
1355
- } else if (item.getTime != null && item.getSeconds != null) {
1356
- sortType = 'date';
1357
- } else {
1358
- sortType = 'unknown';
1359
- }
1360
-
1361
- break;
1349
+ const item = row[colId];
1350
+ if (item == null) {
1351
+ continue;
1352
+ }
1353
+
1354
+ if (typeof item === 'string' || item instanceof String) {
1355
+ sortType = 'string';
1356
+ } else if (item.getTime != null && item.getSeconds != null) {
1357
+ sortType = 'date';
1358
+ } else {
1359
+ sortType = 'unknown';
1360
+ }
1361
+
1362
+ break;
1362
1363
  }
1363
1364
 
1364
1365
  if (sortType == 'string') {
1365
- const collator = new Intl.Collator(PowerduckState.getCurrentLanguage(), {
1366
- numeric: true,
1367
- sensitivity: 'base',
1368
- });
1369
- newRowArr = newRowArr.sort((a, b) => collator.compare(a[colId], b[colId]));
1366
+ const collator = new Intl.Collator(PowerduckState.getCurrentLanguage(), {
1367
+ numeric: true,
1368
+ sensitivity: 'base',
1369
+ });
1370
+ newRowArr = newRowArr.sort((a, b) => collator.compare(a[colId], b[colId]));
1370
1371
  } else if (sortType == 'date') {
1371
- newRowArr = newRowArr.sort((a, b) => {
1372
- return (b[colId]?.getTime() || 0) - (a[colId]?.getTime() || 0);
1373
- });
1372
+ newRowArr = newRowArr.sort((a, b) => {
1373
+ return (b[colId]?.getTime() || 0) - (a[colId]?.getTime() || 0);
1374
+ });
1374
1375
  } else {
1375
- try {
1376
- newRowArr = newRowArr[sortBy](this.sortDefinition.columnId);
1377
- } catch (error) { }
1376
+ try {
1377
+ newRowArr = newRowArr[sortBy](this.sortDefinition.columnId);
1378
+ } catch (error) { }
1378
1379
  }
1379
1380
 
1380
1381
  if (this.sortDefinition.direction == DataTableSortDirection.Descending) {
1381
- newRowArr = newRowArr.reverse();
1382
- }
1383
- }
1384
-
1385
- return newRowArr;
1386
- }
1387
-
1388
- normalizeStringForSearch(str: string): string {
1389
- return str.toLowerCase()[latinize]().trim();
1390
- }
1391
-
1392
- reloadData(): void {
1393
- this.reloadDataPromise().then((data) => {
1394
- this.handleClientsideFilter(false);
1395
- }).catch((err) => {
1396
-
1397
- });
1398
- }
1399
-
1400
- reloadDataPromise(paginationPosition?: number, paginationLength?: number): Promise<any> {
1401
- const mySelf = this;
1402
- this.isLoading = true;
1403
-
1404
- return new Promise((resolve, reject) => {
1405
- let loadPromise: Promise<any>;
1406
- if (mySelf.customAjaxCall == null) {
1407
- loadPromise = mySelf.apiClient[mySelf.apiMethod](mySelf.getAjaxArgs(paginationPosition, paginationLength));
1408
- } else {
1409
- loadPromise = mySelf.customAjaxCall(mySelf.getAjaxArgs(paginationPosition, paginationLength));
1410
- }
1411
-
1412
- loadPromise.then((data: any) => {
1413
- mySelf.unmarkSelection(() => {
1414
- mySelf.enforceBodyRedraw = true;
1415
- mySelf.$nextTick(() => {
1416
- mySelf.enforceBodyRedraw = false;
1417
- mySelf.isLoading = false;
1418
-
1419
- if (mySelf.parseLoadedRowset != null) {
1420
- const rowset = mySelf.parseLoadedRowset(data);
1421
- mySelf.totalCount = rowset.totalCount;
1422
- mySelf.totalFilteredCount = rowset.totalFilteredCount;
1423
- mySelf.rows = rowset.rows;
1424
- } else {
1425
- mySelf.totalCount = data.totalCount ?? data.TotalCount;
1426
- mySelf.totalFilteredCount = data.totalFilteredCount ?? data.TotalFilteredCount;
1427
- mySelf.rows = data.rows ?? data.Rows ?? data.data;
1428
- }
1429
-
1430
- mySelf.loadedRows = mySelf.rows;
1431
- mySelf.$forceUpdate();
1432
- mySelf.$nextTick(() => mySelf.markSelection());
1433
- resolve(data);
1434
- });
1435
- });
1436
- })
1437
- .catch((err) => {
1438
- mySelf.isLoading = false;
1439
- NotificationProvider.showErrorMessage(PowerduckState.getResourceValue('errorFetchingData'));
1440
- reject(err);
1441
- });
1442
- });
1443
- }
1444
-
1445
- getAjaxArgs(paginationPosition?: number, paginationLength?: number): DataTablePostBackData {
1446
- if (this.sessionId == null) {
1447
- this.sessionId = Math.floor(Math.random() * 2147483647) + 2147483647 * -1;
1448
- }
1449
-
1450
- const dataArgs = {} as any as DataTablePostBackData;
1451
- if (this.apiArgs != null) {
1452
- for (const key in this.apiArgs) {
1453
- const kv = this.apiArgs[key];
1454
- if (kv && {}.toString.call(kv) === '[object Function]') {
1455
- dataArgs[key] = kv.call(this);
1456
- } else {
1457
- dataArgs[key] = kv;
1458
- }
1459
- }
1460
- }
1461
-
1462
- dataArgs.SessionId = this.sessionId;
1463
- dataArgs.PaginationPosition = paginationPosition || this.paginationPosition;
1464
- dataArgs.PaginationLength = paginationLength || this.getPaginationLength();
1465
- dataArgs.Filter = {
1466
- FullText: this.fullTextQuery,
1467
- FilterItems: this.filterArr,
1468
- };
1469
-
1470
- if (this.sortDefinition != null) {
1471
- dataArgs.Sort = {
1472
- PropertyName: this.sortDefinition.columnId,
1473
- Direction: this.sortDefinition.direction,
1474
- };
1475
- }
1476
-
1477
- if (dataArgs.PaginationLength == -1) {
1478
- dataArgs.PaginationPosition = 1;
1479
- }
1480
-
1481
- return dataArgs;
1482
- }
1483
-
1484
- isMobileModeRenderType(): boolean {
1485
- return this.activeBreakPoint == 'mobile' && this.getMobileBehavior() == DataTableMobileBehavior.MobileLayout;
1486
- }
1487
-
1488
- forceHeaderRedraw(): void {
1489
- this.enforceHeaderRedraw = true;
1490
- this.$nextTick(() => (this.enforceHeaderRedraw = false));
1491
- }
1492
-
1493
- forceBodyRedraw(): void {
1494
- this.enforceBodyRedraw = true;
1495
- this.$nextTick(() => (this.enforceBodyRedraw = false));
1496
- }
1497
-
1498
- updateRows(rowArr: any[]): void {
1499
- this.rows = rowArr;
1500
- this.loadedRows = rowArr;
1501
- this.forceBodyRedraw();
1502
- }
1503
-
1504
- getTotalCount(): number {
1505
- return this.totalCount;
1506
- }
1507
-
1508
- setSkin(skin: DataTableSkin): void {
1509
- StorageHelper.storeSkin(this.id, skin);
1510
- this.currentSkin = skin;
1511
- this.handleMobileBreakpointChanged();
1512
- }
1513
-
1514
- setMobileBehavior(mobileBehavior: DataTableMobileBehavior): void {
1515
- StorageHelper.storeMobileBehavior(this.id, mobileBehavior);
1516
- this.currentMobileBehavior = mobileBehavior;
1517
- this.handleMobileBreakpointChanged();
1518
- }
1519
-
1520
- handleColumnsReordered(sortOrder: string[]): void {
1521
- sortOrder = sortOrder.filter(p => p != '_sysIndexCol');
1522
- StorageHelper.storeSortOrder(this.id, sortOrder);
1523
- this.colSortOrder = sortOrder;
1524
- this.reorderColumns(sortOrder, this.getVisibleColumns());
1525
- this.forceHeaderRedraw();
1526
- }
1527
-
1528
- async handleColumnHeaderClicked(dtColumn: TableColumn) {
1529
- if (dtColumn.sortable == false) {
1530
- return;
1531
- }
1532
-
1533
- const oldDef = this.sortDefinition;
1534
- let newDirection = DataTableSortDirection.Ascending;
1535
- if (this.sortDefinition != null && this.sortDefinition.columnId == dtColumn.id && this.sortDefinition.direction == DataTableSortDirection.Ascending) {
1536
- newDirection = DataTableSortDirection.Descending;
1537
- }
1538
-
1539
- this.sortDefinition = {
1540
- columnId: dtColumn.id,
1541
- direction: newDirection,
1542
- };
1543
-
1544
- if (this.preserveOrderBy == true) {
1545
- StorageHelper.storeOrderBy(this.id, this.sortDefinition);
1546
- }
1547
-
1548
- if (this.handleClientsideFilter(false)) {
1549
- return;
1550
- }
1551
-
1552
- try {
1553
- await this.reloadDataPromise();
1554
- } catch (e) {
1555
- this.sortDefinition = oldDef;
1556
- }
1557
- }
1558
-
1559
- handleColumnVisibilityChanged(columns: TableColumn[]): void {
1560
- StorageHelper.storeColVis(this.id, columns);
1561
- this.forceHeaderRedraw();
1562
- }
1563
-
1564
- handleColumnModalFilterChanged(e: ColFilterModalShowResponse): void {
1565
- if (e.changed) {
1566
- this.filterArr = e.filterArr;
1567
- this.reloadData();
1568
- }
1569
- }
1570
-
1571
- handleMobileRowClicked(e: any, row: any) {
1572
- if (this.checkboxesShown) {
1573
- let target = $(e.target);
1574
- if (!target.hasClass('dt-mobile-row-inner')) {
1575
- target = target.closest('.dt-mobile-row-inner');
1576
- }
1577
-
1578
- const input = target.find('.dt-selection-checkbox input')[0] as HTMLInputElement;
1579
- input.checked = !input.checked;
1580
- }
1581
-
1582
- if (this.rowClicked) {
1583
- this.rowClicked(row);
1584
- }
1585
- }
1586
-
1587
- handleRowCheckboxChanged(row: any, checked: boolean) {
1588
- if (this.rowCheckstateChanged != null) {
1589
- this.rowCheckstateChanged(
1590
- row,
1591
- checked,
1592
- this.getSelectedRows(),
1593
- );
1594
- }
1595
- }
1596
-
1597
- getLastPaginationIndex(): number {
1598
- let retVal = this.totalFilteredCount / this.getPaginationLength();
1599
- if (retVal % this.getPaginationLength() != 0) {
1600
- retVal = Math.floor(retVal) + 1;
1601
- }
1602
-
1603
- if (retVal == 0) {
1604
- retVal = 1;
1605
- }
1606
-
1607
- return retVal;
1608
- }
1609
-
1610
- async handlePaginationPositionChanged(newValue: number): Promise<any> {
1611
- if (this.paginationPosition == newValue || newValue < 1 || newValue > this.getLastPaginationIndex()) {
1612
- return;
1613
- }
1614
-
1615
- await this.reloadDataPromise(newValue);
1616
- this.paginationPosition = newValue;
1617
- }
1618
-
1619
- async handlePaginationLengthChanged(newValue: number) {
1620
- if (this.getPaginationLength() == newValue) {
1621
- return;
1622
- }
1623
-
1624
- await this.reloadDataPromise(null, newValue);
1625
- StorageHelper.storePaginationLength(this.id, newValue);
1626
- this.paginationLength = newValue;
1627
- }
1628
-
1629
- handleCheckAllChanged(checked: boolean): void {
1630
- $('.dt-col-indexcheckbox').each(function (this: HTMLElement) {
1631
- $(this).find('input').prop('checked', checked);
1632
- });
1633
-
1634
- this.handleRowCheckboxChanged(null, null);
1635
- }
1636
-
1637
- getNameAndSurnameIndex(name: string, surname: string): string {
1638
- let retVal: string;
1639
- if ((name != null && name.length > 0) || (surname != null && surname.length > 0)) {
1640
- name = name || '';
1641
- surname = surname || '';
1642
-
1643
- if (name.length > 0) {
1644
- if (surname.length > 0) {
1645
- retVal = name.substring(0, 1).toUpperCase() + surname.substring(0, 1).toUpperCase();
1646
- } else {
1647
- retVal = name;
1648
- }
1649
- } else {
1650
- retVal = surname;
1651
- }
1652
- }
1653
-
1654
- return retVal;
1655
- }
1656
-
1657
- getRowIdentifier(
1658
- columns: TableColumn[],
1659
- row: any,
1660
- includeColumns: boolean,
1661
- ): RowIdentifier {
1662
- let namingData: RowIdentifier;
1663
- if (row.CustomFields != null) {
1664
- const nameCf = (row.CustomFields.filter(p => p.MappingType == 1)[0] || {}) as any;
1665
- const surnameCf = (row.CustomFields.filter(p => p.MappingType == 2)[0] || {}) as any;
1666
- namingData = new RowIdentifier(nameCf.Value, surnameCf.Value);
1667
-
1668
- if (includeColumns && namingData.fullName.length > 1) {
1669
- namingData.dtColumns = [];
1670
-
1671
- const nameCol = columns.filter(p => p.id.includes(`cf:map:${1}`) || p.id.includes(`cf:id:${nameCf.Id}`))[0];
1672
- if (nameCol != null) {
1673
- namingData.dtColumns.push(nameCol);
1674
- }
1675
-
1676
- const surnameCol = columns.filter(p => p.id.includes(`cf:map:${2}`) || p.id.includes(`cf:id:${surnameCf.Id}`))[0];
1677
- if (surnameCol != null) {
1678
- namingData.dtColumns.push(surnameCol);
1679
- }
1382
+ newRowArr = newRowArr.reverse();
1680
1383
  }
1681
- }
1682
-
1683
- if (namingData == null || (namingData.fullName.length < 2 && row.Name != null)) {
1684
- namingData = new RowIdentifier(row.Name, row.Surname);
1685
-
1686
- if (includeColumns) {
1687
- namingData.dtColumns = [];
1688
-
1689
- const nameCol = columns.filter(p => p.id == 'Name')[0];
1690
- if (nameCol != null) {
1691
- namingData.dtColumns.push(nameCol);
1692
- }
1693
-
1694
- const surnameCol = columns.filter(p => p.id == 'Surname')[0];
1695
- if (surnameCol != null) {
1696
- namingData;
1697
- }
1698
- }
1699
- }
1700
-
1701
- if (namingData == null || (namingData.fullName.length < 2 && row.Email != null)) {
1702
- if (row.Email != null) {
1703
- namingData = new RowIdentifier(row.Email, '');
1704
-
1705
- if (includeColumns) {
1706
- const emailCol = columns.filter(p => p.id == 'Email')[0];
1707
- if (emailCol != null) {
1708
- namingData.dtColumns = [emailCol];
1709
- }
1710
- }
1711
- }
1712
- }
1713
-
1714
- if (namingData == null || (namingData.fullName.length < 2 && row.TicketName != null)) {
1715
- if (row.TicketName != null) {
1716
- namingData = new RowIdentifier(row.TicketName, '');
1717
-
1718
- if (includeColumns) {
1719
- const emailCol = columns.filter(p => p.id == 'TicketName')[0];
1720
- if (emailCol != null) {
1721
- namingData.dtColumns = [emailCol];
1722
- }
1723
- }
1724
- }
1725
- }
1726
-
1727
- return namingData;
1728
- }
1729
-
1730
- getHeaderColumnIndex(
1731
- columns: TableColumn[],
1732
- row,
1733
- i,
1734
- ): string {
1735
- if (this.rowIndexMode == RowIndexMode.Index) {
1736
- return i + 1;
1737
- } else {
1738
- var indexText: string;
1739
- const rowIdentifier = this.getRowIdentifier(
1740
- columns,
1741
- row,
1742
- false,
1743
- );
1744
- if (rowIdentifier != null) {
1745
- indexText = this.getNameAndSurnameIndex(rowIdentifier.name, rowIdentifier.surname);
1746
- }
1747
-
1748
- var indexText: string;
1749
- if (row.CustomFields != null) {
1750
- const nameCf = row.CustomFields.filter(p => p.MappingType == 1)[0];
1751
- const surnameCf = row.CustomFields.filter(p => p.MappingType == 2)[0];
1752
- indexText = this.getNameAndSurnameIndex(nameCf != null ? nameCf.Value : '', surnameCf != null ? surnameCf.Value : '');
1753
- }
1754
-
1755
- if (indexText != null && indexText.length > 1) {
1756
- if (indexText.length > 2) {
1757
- const splitArr = indexText.split(' ');
1758
- if (splitArr.length > 1) {
1759
- indexText = (splitArr[0].substring(0, 1) + splitArr[1].substring(0, 1)).toUpperCase();
1760
- } else {
1761
- indexText = indexText.substring(0, 2).toUpperCase();
1762
- }
1763
- }
1764
- } else {
1765
- indexText = (i + 1).toString();
1766
- }
1767
-
1768
- return indexText;
1769
- }
1770
- }
1771
-
1772
- showColVis(): void {
1773
- (this.$refs.colVisModal as typeof ColVisModal.prototype).show();
1774
- }
1775
-
1776
- showFilterModal(): void {
1777
- (this.$refs.colFilterModal as typeof ColFilterModal.prototype).show({
1778
- filterArr: this.filterArr,
1779
- });
1780
- }
1781
-
1782
- exportExcel(): void {
1783
- (this.$refs.tableExportModal as typeof TableExportModal.prototype).show({
1784
- apiClient: this.apiClient,
1785
- apiMethod: this.apiMethod,
1786
- apiArgs: this.getAjaxArgs(),
1787
- columns: this.columns,
1788
- rows: this.rows,
1789
- exportConfig: this.exportConfig,
1790
- paginationOffset: this.paginationPosition - 1,
1791
- paginationLength: this.getPaginationLength(),
1792
- totalFilteredCount: this.totalFilteredCount,
1793
- });
1794
- }
1795
-
1796
- toggleCheckboxes(visible?: boolean): void {
1797
- if (visible == null) {
1798
- visible = !this.checkboxesShown;
1799
- }
1800
-
1801
- this.checkboxesShown = visible;
1802
- }
1803
-
1804
- getSkin(): DataTableSkin {
1805
- return this.currentSkin || DataTableSkin.Default;
1806
- }
1807
-
1808
- getMobileBehavior(): DataTableMobileBehavior {
1809
- return this.currentMobileBehavior || DataTableMobileBehavior.MobileLayout;
1810
- }
1811
-
1812
- getVisibleColumns(): TableColumn[] {
1813
- const state = StorageHelper.getStoredState(this.id);
1814
- const colArr = this.columns.filter(p => p.visible != false);
1815
- this.reorderColumns(this.colSortOrder, colArr);
1816
- this.handleColumnsVisibility(state, colArr);
1817
- return colArr;
1818
-
1819
- // return this.columns.filter(p => p.visible != false);
1820
- }
1821
-
1822
- isDesiredCustomFieldColumn(
1823
- dtCol: TableColumn,
1824
- row: any,
1825
- mappingType: any,
1826
- ): boolean {
1827
- const nameCf = row.CustomFields.filter(p => p.MappingType == mappingType)[0];
1828
- if (nameCf != null && ((dtCol.id.includes(`id:${nameCf.Id}`)) || (dtCol.id.includes(`map:${nameCf.MappingType}`)))) {
1829
- return true;
1830
- }
1831
-
1832
- return false;
1833
- }
1834
-
1835
- getChangeEventDelay() {
1836
- if (this.filterMode == DataTableFilterMode.Clientside) {
1837
- return 0;
1838
- } else {
1839
- return 650;
1840
- }
1841
- }
1842
-
1843
- getTableColumnOrder(dtCol: TableColumn, row: any): number {
1844
- if (dtCol.mobileOrder != null) {
1845
- return dtCol.mobileOrder;
1846
- }
1847
-
1848
- if (dtCol.id.includes('cf:') && row.CustomFields != null) {
1849
- if (this.isDesiredCustomFieldColumn(
1850
- dtCol,
1851
- row,
1852
- 1,
1853
- )) {
1854
- return -10100;
1855
- }
1856
-
1857
- if (this.isDesiredCustomFieldColumn(
1858
- dtCol,
1859
- row,
1860
- 1,
1861
- )) {
1862
- return -10000;
1863
- }
1864
- }
1865
-
1866
- if (dtCol.id == 'Name') {
1867
- return -9000;
1868
- }
1869
-
1870
- if (dtCol.id == 'TicketName') {
1871
- return -8900;
1872
- }
1873
-
1874
- return null;
1875
- }
1876
-
1877
- getTableColumnOrderStyle(dtCol: TableColumn, row: any): string {
1878
- const retVal = this.getTableColumnOrder(dtCol, row);
1879
- if (retVal != null) {
1880
- return `order:${retVal}`;
1881
- }
1882
-
1883
- return null;
1884
- }
1885
-
1886
- getMassOperationItems(): typeof DropdownButtonItem.prototype[] {
1887
- return this.massOperationOptions || [];
1888
- }
1889
-
1890
- shouldRenderMobileRowColumn(row, dtColumn: TableColumn): boolean {
1891
- if (dtColumn.customRender == null) {
1892
- if (dtColumn.customValue != null) {
1893
- return dtColumn.customValue(row) != null;
1894
- }
1895
-
1896
- return row[dtColumn.id] != null;
1897
- }
1898
-
1899
- if (dtColumn.mobileShouldRenderRow) {
1900
- return dtColumn.mobileShouldRenderRow(row);
1901
- }
1902
-
1903
- return true;
1904
- }
1905
-
1906
- clearSelection() {
1907
- $(this.$el).find('.dt-col-index').find('input').prop('checked', false);
1908
- }
1909
-
1910
- getFilterValue(dtColumn: TableColumn): any {
1911
- if (this.filterArr == null) {
1912
- return null;
1913
- }
1914
-
1915
- const filterItem = this.filterArr.filter(p => p.PropertyName == dtColumn.id)[0];
1916
- if (filterItem == null) {
1917
- return null;
1918
- }
1919
-
1920
- if (filterItem.FilterType == DataTableFilterItemType.Text) {
1921
- return filterItem.ContainsValue;
1922
- } else if (filterItem.FilterType == DataTableFilterItemType.Dropdown) {
1923
- return filterItem.ValueArr;
1924
- } else if (filterItem.FilterType == DataTableFilterItemType.DateRange) {
1925
- return {
1926
- startTime: filterItem.DateFrom,
1927
- endTime: filterItem.DateTo,
1928
- };
1929
- } else if (filterItem.FilterType == DataTableFilterItemType.NumericRange) {
1930
-
1931
- } else {
1932
- return null;
1933
- }
1934
- }
1935
-
1936
- render(h) {
1937
- const columns = this.getVisibleColumns();
1938
- let paginationStart = (this.paginationPosition - 1) * this.getPaginationLength() + 1;
1939
- let paginationEnd = Math.min(paginationStart + this.getPaginationLength(), this.totalFilteredCount) - 1;
1940
- const settingsUUID = `ddl-${PortalUtils.randomString(10)}`;
1941
- const isMobile = PortalUtils.treatAsMobileDevice();
1942
- const hasMobLayout = this.getMobileBehavior() == DataTableMobileBehavior.MobileLayout;
1943
- const hasTableSkin = this.getSkin() == DataTableSkin.Default;
1944
-
1945
- if (this.paginationPosition == this.getLastPaginationIndex()) {
1946
- paginationEnd += 1;
1947
- }
1948
-
1949
- if (this.totalFilteredCount == 0) {
1950
- paginationStart = 0;
1951
- paginationEnd = 0;
1952
- }
1953
-
1954
- if (this.getPaginationLength() == -1) {
1955
- paginationEnd = this.totalFilteredCount;
1956
- }
1957
-
1958
- return (
1959
- <div
1960
- class={
1961
- `dt-root dt-mobile-mobile dt-device-${PortalUtils.treatAsMobileDevice() ? 'mobile' : 'desktop'
1962
- }${PortalUtils.isIOS() ? ' dt-ios' : ''
1963
- } dt-skin-${this.getSkin()
1964
- } dt-mobbehavior-${this.getMobileBehavior()
1965
- }${this.checkboxesShown ? ' dt-checkboxes-visible' : ''
1966
- } dt-breakpoint-${this.activeBreakPoint
1967
- }${this.fullSizeHasButtonBelow ? ' dt-fs-buttonsbelow' : ''
1968
- }${this.insetTop ? ' dt-inset-top' : ''
1969
- }${this.fullSizeTable == true ? ' dt-fullsize-table' : ''
1970
- } ${this.cssClass || ''}`
1971
- }
1972
- >
1973
- {this.topVisible != false && (
1974
- <div class="dt-top">
1975
- <div class="dt-top-buttonsrow">
1976
- <div class="dt-buttons">
1977
- <TableButtonComponent title={PowerduckState.getResourceValue('colVisLabel')} icon="fa fa-eye-slash" clicked={() => this.showColVis()} />
1978
-
1979
- {this.buttons
1980
- && this.buttons.map(btn => (
1981
- <TableButtonComponent title={btn.title} icon={btn.icon} childItems={btn.childItems} customRender={btn.customRender} clicked={() => btn.clicked()} />
1982
- ))}
1983
-
1984
- {this.allowExport != false && <TableButtonComponent title="Excel export" icon="far fa-file-excel" clicked={() => this.exportExcel()} />}
1985
-
1986
- {this.allowMassOperations != false && <TableButtonComponent title={this.checkboxesTitle || ''} icon="far fa-check-square" clicked={() => this.toggleCheckboxes()} />}
1987
-
1988
- {this.activeBreakPoint == DataTableBreakpoint.Mobile && this.getMobileBehavior() == DataTableMobileBehavior.MobileLayout && (
1989
- <TableButtonComponent title="Filter" icon="fas fa-filter" clicked={() => this.showFilterModal()} />
1990
- )}
1991
-
1992
- <span class="nav-item dt-button dropdown">
1993
- <span class="dropdown-toggle" id={settingsUUID} data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
1994
- <i class="fas fa-desktop"></i>
1995
- </span>
1996
- <div class="dropdown-menu dropdown-menu-right" aria-labelledby={settingsUUID}>
1997
- {isMobile && (
1998
- <a class="dropdown-item dropdown-selectable-section" href="javascript:" onClick={() => this.setMobileBehavior(DataTableMobileBehavior.MobileLayout)}>
1999
- <span>{PowerduckState.getResourceValue('dtLayoutMobile')}</span>
2000
- {hasMobLayout && <i class="fas fa-check"></i>}
2001
- </a>
2002
- )}
2003
-
2004
- {!isMobile && (
2005
- <a class="dropdown-item dropdown-selectable-section" href="javascript:" onClick={() => this.setSkin(DataTableSkin.Default)}>
2006
- <span>{PowerduckState.getResourceValue('dtLayoutTable')}</span>
2007
- {hasTableSkin && <i class="fas fa-check"></i>}
2008
- </a>
2009
- )}
2010
-
2011
- <a
2012
- class="dropdown-item dropdown-selectable-section"
2013
- href="javascript:"
2014
- onClick={() => (isMobile ? this.setMobileBehavior(DataTableMobileBehavior.Compact) : this.setSkin(DataTableSkin.Compact))}
2015
- >
2016
- <span>{isMobile ? PowerduckState.getResourceValue('dtLayoutTable') : PowerduckState.getResourceValue('dtLayoutCompact')}</span>
2017
- {((isMobile && !hasMobLayout) || (!isMobile && !hasTableSkin)) && <i class="fas fa-check"></i>}
2018
- </a>
2019
- </div>
2020
- </span>
2021
- </div>
2022
- </div>
2023
- {this.hidePagination != true
2024
- && (
2025
- <div class="dt-top-paginationrow">
2026
- {(!this.checkboxesShown || this.checkboxButtonsVisible == false) && (
2027
- <div class="dt-pagination-length">
2028
- <select onChange={e => this.handlePaginationLengthChanged(Number(e.target.value))}>
2029
- {(this.paginations || [
2030
- 10,
2031
- 25,
2032
- 50,
2033
- 100,
2034
- 250,
2035
- 500,
2036
- 1000,
2037
- -1,
2038
- ]).map(item => (
2039
- <option value={item} selected={this.getPaginationLength() == item}>
2040
- {item != -1 ? item.toString() : PowerduckState.getResourceValue('all')}
2041
- </option>
2042
- ))}
2043
- </select>
2044
-
2045
- <span>{PowerduckState.getResourceValue('recordsDtLabel')}</span>
2046
- </div>
2047
- )}
2048
-
2049
- {this.checkboxesShown && this.checkboxButtonsVisible != false && (
2050
- <div class="dt-pagination-length dt-massop-btn-wrap">
2051
- <DropdownButton text="Hromadne operacie" layout={ButtonLayout.Secondary}>
2052
- {this.getMassOperationItems().map(mi =>
2053
- (mi as any).isSeparator != true ? <DropdownButtonItem icon={mi.icon} text={mi.text} clicked={mi.clicked} /> : <div class="dropdown-divider" />)}
2054
-
2055
- <DropdownButtonItem icon="icon icon-close" text={PowerduckState.getResourceValue('cancel')} clicked={() => this.toggleCheckboxes(false)} />
2056
- </DropdownButton>
2057
- <Button text={PowerduckState.getResourceValue('cancel')} layout={ButtonLayout.Default} clicked={() => this.toggleCheckboxes(false)} cssClass="dt-massop-cancelbtn" />
2058
- </div>
2059
- )}
2060
-
2061
- <div class="dt-fulltext-search">
2062
- <input type="search" placeholder={`${PowerduckState.getResourceValue('search')[capitalize]()}...`} onKeyup={e => this.performFullTextSearch(e)} />
2063
- </div>
2064
- </div>
2065
- )}
2066
- </div>
2067
- )}
2068
-
2069
- {this.renderTableByMode(h, columns)}
2070
-
2071
- {this.bottomVisible != false && (
2072
- <div class="dt-bottom">
2073
- <div class="dt-summary-wrap">
2074
- {PowerduckState.getResourceValue('dtCountText').replace('{0}', paginationStart.toString()).replace('{1}', paginationEnd.toString()).replace('{2}', this.totalFilteredCount.toString())}
2075
- {this.totalFilteredCount != this.totalCount && (
2076
- <span class="dt-summary-totalcount">
1384
+ }
1385
+
1386
+ return newRowArr;
1387
+ }
1388
+
1389
+ normalizeStringForSearch(str: string): string {
1390
+ return str.toLowerCase()[latinize]().trim();
1391
+ }
1392
+
1393
+ reloadData(): void {
1394
+ this.reloadDataPromise().then((data) => {
1395
+ this.handleClientsideFilter(false);
1396
+ }).catch((err) => {
1397
+
1398
+ });
1399
+ }
1400
+
1401
+ reloadDataPromise(paginationPosition?: number, paginationLength?: number): Promise<any> {
1402
+ const mySelf = this;
1403
+ this.isLoading = true;
1404
+
1405
+ return new Promise((resolve, reject) => {
1406
+ let loadPromise: Promise<any>;
1407
+ if (mySelf.customAjaxCall == null) {
1408
+ loadPromise = mySelf.apiClient[mySelf.apiMethod](mySelf.getAjaxArgs(paginationPosition, paginationLength));
1409
+ } else {
1410
+ loadPromise = mySelf.customAjaxCall(mySelf.getAjaxArgs(paginationPosition, paginationLength));
1411
+ }
1412
+
1413
+ loadPromise.then((data: any) => {
1414
+ mySelf.unmarkSelection(() => {
1415
+ mySelf.enforceBodyRedraw = true;
1416
+ mySelf.$nextTick(() => {
1417
+ mySelf.enforceBodyRedraw = false;
1418
+ mySelf.isLoading = false;
1419
+
1420
+ if (mySelf.parseLoadedRowset != null) {
1421
+ const rowset = mySelf.parseLoadedRowset(data);
1422
+ mySelf.totalCount = rowset.totalCount;
1423
+ mySelf.totalFilteredCount = rowset.totalFilteredCount;
1424
+ mySelf.rows = rowset.rows;
1425
+ } else {
1426
+ mySelf.totalCount = data.totalCount ?? data.TotalCount;
1427
+ mySelf.totalFilteredCount = data.totalFilteredCount ?? data.TotalFilteredCount;
1428
+ mySelf.rows = data.rows ?? data.Rows ?? data.data;
1429
+ }
1430
+
1431
+ mySelf.loadedRows = mySelf.rows;
1432
+ mySelf.$forceUpdate();
1433
+ mySelf.$nextTick(() => mySelf.markSelection());
1434
+ resolve(data);
1435
+ });
1436
+ });
1437
+ })
1438
+ .catch((err) => {
1439
+ mySelf.isLoading = false;
1440
+ NotificationProvider.showErrorMessage(PowerduckState.getResourceValue('errorFetchingData'));
1441
+ reject(err);
1442
+ });
1443
+ });
1444
+ }
1445
+
1446
+ getAjaxArgs(paginationPosition?: number, paginationLength?: number): DataTablePostBackData {
1447
+ if (this.sessionId == null) {
1448
+ this.sessionId = Math.floor(Math.random() * 2147483647) + 2147483647 * -1;
1449
+ }
1450
+
1451
+ const dataArgs = {} as any as DataTablePostBackData;
1452
+ if (this.apiArgs != null) {
1453
+ for (const key in this.apiArgs) {
1454
+ const kv = this.apiArgs[key];
1455
+ if (kv && {}.toString.call(kv) === '[object Function]') {
1456
+ dataArgs[key] = kv.call(this);
1457
+ } else {
1458
+ dataArgs[key] = kv;
1459
+ }
1460
+ }
1461
+ }
1462
+
1463
+ dataArgs.SessionId = this.sessionId;
1464
+ dataArgs.PaginationPosition = paginationPosition || this.paginationPosition;
1465
+ dataArgs.PaginationLength = paginationLength || this.getPaginationLength();
1466
+ dataArgs.Filter = {
1467
+ FullText: this.fullTextQuery,
1468
+ FilterItems: this.filterArr,
1469
+ };
1470
+
1471
+ if (this.sortDefinition != null) {
1472
+ dataArgs.Sort = {
1473
+ PropertyName: this.sortDefinition.columnId,
1474
+ Direction: this.sortDefinition.direction,
1475
+ };
1476
+ }
1477
+
1478
+ if (dataArgs.PaginationLength == -1) {
1479
+ dataArgs.PaginationPosition = 1;
1480
+ }
1481
+
1482
+ return dataArgs;
1483
+ }
1484
+
1485
+ isMobileModeRenderType(): boolean {
1486
+ return this.activeBreakPoint == 'mobile' && this.getMobileBehavior() == DataTableMobileBehavior.MobileLayout;
1487
+ }
1488
+
1489
+ forceHeaderRedraw(): void {
1490
+ this.enforceHeaderRedraw = true;
1491
+ this.$nextTick(() => (this.enforceHeaderRedraw = false));
1492
+ }
1493
+
1494
+ forceBodyRedraw(): void {
1495
+ this.enforceBodyRedraw = true;
1496
+ this.$nextTick(() => (this.enforceBodyRedraw = false));
1497
+ }
1498
+
1499
+ updateRows(rowArr: any[]): void {
1500
+ this.rows = rowArr;
1501
+ this.loadedRows = rowArr;
1502
+ this.forceBodyRedraw();
1503
+ }
1504
+
1505
+ getTotalCount(): number {
1506
+ return this.totalCount;
1507
+ }
1508
+
1509
+ setSkin(skin: DataTableSkin): void {
1510
+ StorageHelper.storeSkin(this.id, skin);
1511
+ this.currentSkin = skin;
1512
+ this.handleMobileBreakpointChanged();
1513
+ }
1514
+
1515
+ setMobileBehavior(mobileBehavior: DataTableMobileBehavior): void {
1516
+ StorageHelper.storeMobileBehavior(this.id, mobileBehavior);
1517
+ this.currentMobileBehavior = mobileBehavior;
1518
+ this.handleMobileBreakpointChanged();
1519
+ }
1520
+
1521
+ handleColumnsReordered(sortOrder: string[]): void {
1522
+ sortOrder = sortOrder.filter(p => p != '_sysIndexCol');
1523
+ StorageHelper.storeSortOrder(this.id, sortOrder);
1524
+ this.colSortOrder = sortOrder;
1525
+ this.reorderColumns(sortOrder, this.getVisibleColumns());
1526
+ this.forceHeaderRedraw();
1527
+ }
1528
+
1529
+ async handleColumnHeaderClicked(dtColumn: TableColumn) {
1530
+ if (dtColumn.sortable == false) {
1531
+ return;
1532
+ }
1533
+
1534
+ const oldDef = this.sortDefinition;
1535
+ let newDirection = DataTableSortDirection.Ascending;
1536
+ if (this.sortDefinition != null && this.sortDefinition.columnId == dtColumn.id && this.sortDefinition.direction == DataTableSortDirection.Ascending) {
1537
+ newDirection = DataTableSortDirection.Descending;
1538
+ }
1539
+
1540
+ this.sortDefinition = {
1541
+ columnId: dtColumn.id,
1542
+ direction: newDirection,
1543
+ };
1544
+
1545
+ if (this.preserveOrderBy == true) {
1546
+ StorageHelper.storeOrderBy(this.id, this.sortDefinition);
1547
+ }
1548
+
1549
+ if (this.handleClientsideFilter(false)) {
1550
+ return;
1551
+ }
1552
+
1553
+ try {
1554
+ await this.reloadDataPromise();
1555
+ } catch (e) {
1556
+ this.sortDefinition = oldDef;
1557
+ }
1558
+ }
1559
+
1560
+ handleColumnVisibilityChanged(columns: TableColumn[]): void {
1561
+ StorageHelper.storeColVis(this.id, columns);
1562
+ this.forceHeaderRedraw();
1563
+ }
1564
+
1565
+ handleColumnModalFilterChanged(e: ColFilterModalShowResponse): void {
1566
+ if (e.changed) {
1567
+ this.filterArr = e.filterArr;
1568
+ this.reloadData();
1569
+ }
1570
+ }
1571
+
1572
+ handleMobileRowClicked(e: any, row: any) {
1573
+ if (this.checkboxesShown) {
1574
+ let target = $(e.target);
1575
+ if (!target.hasClass('dt-mobile-row-inner')) {
1576
+ target = target.closest('.dt-mobile-row-inner');
1577
+ }
1578
+
1579
+ const input = target.find('.dt-selection-checkbox input')[0] as HTMLInputElement;
1580
+ input.checked = !input.checked;
1581
+ }
1582
+
1583
+ if (this.rowClicked) {
1584
+ this.rowClicked(row);
1585
+ }
1586
+ }
1587
+
1588
+ handleRowCheckboxChanged(row: any, checked: boolean) {
1589
+ if (this.rowCheckstateChanged != null) {
1590
+ this.rowCheckstateChanged(
1591
+ row,
1592
+ checked,
1593
+ this.getSelectedRows(),
1594
+ );
1595
+ }
1596
+ }
1597
+
1598
+ getLastPaginationIndex(): number {
1599
+ let retVal = this.totalFilteredCount / this.getPaginationLength();
1600
+ if (retVal % this.getPaginationLength() != 0) {
1601
+ retVal = Math.floor(retVal) + 1;
1602
+ }
1603
+
1604
+ if (retVal == 0) {
1605
+ retVal = 1;
1606
+ }
1607
+
1608
+ return retVal;
1609
+ }
1610
+
1611
+ async handlePaginationPositionChanged(newValue: number): Promise<any> {
1612
+ if (this.paginationPosition == newValue || newValue < 1 || newValue > this.getLastPaginationIndex()) {
1613
+ return;
1614
+ }
1615
+
1616
+ await this.reloadDataPromise(newValue);
1617
+ this.paginationPosition = newValue;
1618
+ }
1619
+
1620
+ async handlePaginationLengthChanged(newValue: number) {
1621
+ if (this.getPaginationLength() == newValue) {
1622
+ return;
1623
+ }
1624
+
1625
+ await this.reloadDataPromise(null, newValue);
1626
+ StorageHelper.storePaginationLength(this.id, newValue);
1627
+ this.paginationLength = newValue;
1628
+ }
1629
+
1630
+ handleCheckAllChanged(checked: boolean): void {
1631
+ $('.dt-col-indexcheckbox').each(function (this: HTMLElement) {
1632
+ $(this).find('input').prop('checked', checked);
1633
+ });
1634
+
1635
+ this.handleRowCheckboxChanged(null, null);
1636
+ }
1637
+
1638
+ getNameAndSurnameIndex(name: string, surname: string): string {
1639
+ let retVal: string;
1640
+ if ((name != null && name.length > 0) || (surname != null && surname.length > 0)) {
1641
+ name = name || '';
1642
+ surname = surname || '';
1643
+
1644
+ if (name.length > 0) {
1645
+ if (surname.length > 0) {
1646
+ retVal = name.substring(0, 1).toUpperCase() + surname.substring(0, 1).toUpperCase();
1647
+ } else {
1648
+ retVal = name;
1649
+ }
1650
+ } else {
1651
+ retVal = surname;
1652
+ }
1653
+ }
1654
+
1655
+ return retVal;
1656
+ }
1657
+
1658
+ getRowIdentifier(
1659
+ columns: TableColumn[],
1660
+ row: any,
1661
+ includeColumns: boolean,
1662
+ ): RowIdentifier {
1663
+ let namingData: RowIdentifier;
1664
+ if (row.CustomFields != null) {
1665
+ const nameCf = (row.CustomFields.filter(p => p.MappingType == 1)[0] || {}) as any;
1666
+ const surnameCf = (row.CustomFields.filter(p => p.MappingType == 2)[0] || {}) as any;
1667
+ namingData = new RowIdentifier(nameCf.Value, surnameCf.Value);
1668
+
1669
+ if (includeColumns && namingData.fullName.length > 1) {
1670
+ namingData.dtColumns = [];
1671
+
1672
+ const nameCol = columns.filter(p => p.id.includes(`cf:map:${1}`) || p.id.includes(`cf:id:${nameCf.Id}`))[0];
1673
+ if (nameCol != null) {
1674
+ namingData.dtColumns.push(nameCol);
1675
+ }
1676
+
1677
+ const surnameCol = columns.filter(p => p.id.includes(`cf:map:${2}`) || p.id.includes(`cf:id:${surnameCf.Id}`))[0];
1678
+ if (surnameCol != null) {
1679
+ namingData.dtColumns.push(surnameCol);
1680
+ }
1681
+ }
1682
+ }
1683
+
1684
+ if (namingData == null || (namingData.fullName.length < 2 && row.Name != null)) {
1685
+ namingData = new RowIdentifier(row.Name, row.Surname);
1686
+
1687
+ if (includeColumns) {
1688
+ namingData.dtColumns = [];
1689
+
1690
+ const nameCol = columns.filter(p => p.id == 'Name')[0];
1691
+ if (nameCol != null) {
1692
+ namingData.dtColumns.push(nameCol);
1693
+ }
1694
+
1695
+ const surnameCol = columns.filter(p => p.id == 'Surname')[0];
1696
+ if (surnameCol != null) {
1697
+ namingData;
1698
+ }
1699
+ }
1700
+ }
1701
+
1702
+ if (namingData == null || (namingData.fullName.length < 2 && row.Email != null)) {
1703
+ if (row.Email != null) {
1704
+ namingData = new RowIdentifier(row.Email, '');
1705
+
1706
+ if (includeColumns) {
1707
+ const emailCol = columns.filter(p => p.id == 'Email')[0];
1708
+ if (emailCol != null) {
1709
+ namingData.dtColumns = [emailCol];
1710
+ }
1711
+ }
1712
+ }
1713
+ }
1714
+
1715
+ if (namingData == null || (namingData.fullName.length < 2 && row.TicketName != null)) {
1716
+ if (row.TicketName != null) {
1717
+ namingData = new RowIdentifier(row.TicketName, '');
1718
+
1719
+ if (includeColumns) {
1720
+ const emailCol = columns.filter(p => p.id == 'TicketName')[0];
1721
+ if (emailCol != null) {
1722
+ namingData.dtColumns = [emailCol];
1723
+ }
1724
+ }
1725
+ }
1726
+ }
1727
+
1728
+ return namingData;
1729
+ }
1730
+
1731
+ getHeaderColumnIndex(
1732
+ columns: TableColumn[],
1733
+ row,
1734
+ i,
1735
+ ): string {
1736
+ if (this.rowIndexMode == RowIndexMode.Index) {
1737
+ return i + 1;
1738
+ } else {
1739
+ var indexText: string;
1740
+ const rowIdentifier = this.getRowIdentifier(
1741
+ columns,
1742
+ row,
1743
+ false,
1744
+ );
1745
+ if (rowIdentifier != null) {
1746
+ indexText = this.getNameAndSurnameIndex(rowIdentifier.name, rowIdentifier.surname);
1747
+ }
1748
+
1749
+ var indexText: string;
1750
+ if (row.CustomFields != null) {
1751
+ const nameCf = row.CustomFields.filter(p => p.MappingType == 1)[0];
1752
+ const surnameCf = row.CustomFields.filter(p => p.MappingType == 2)[0];
1753
+ indexText = this.getNameAndSurnameIndex(nameCf != null ? nameCf.Value : '', surnameCf != null ? surnameCf.Value : '');
1754
+ }
1755
+
1756
+ if (indexText != null && indexText.length > 1) {
1757
+ if (indexText.length > 2) {
1758
+ const splitArr = indexText.split(' ');
1759
+ if (splitArr.length > 1) {
1760
+ indexText = (splitArr[0].substring(0, 1) + splitArr[1].substring(0, 1)).toUpperCase();
1761
+ } else {
1762
+ indexText = indexText.substring(0, 2).toUpperCase();
1763
+ }
1764
+ }
1765
+ } else {
1766
+ indexText = (i + 1).toString();
1767
+ }
1768
+
1769
+ return indexText;
1770
+ }
1771
+ }
1772
+
1773
+ showColVis(): void {
1774
+ (this.$refs.colVisModal as typeof ColVisModal.prototype).show();
1775
+ }
1776
+
1777
+ showFilterModal(): void {
1778
+ (this.$refs.colFilterModal as typeof ColFilterModal.prototype).show({
1779
+ filterArr: this.filterArr,
1780
+ });
1781
+ }
1782
+
1783
+ exportExcel(): void {
1784
+ (this.$refs.tableExportModal as typeof TableExportModal.prototype).show({
1785
+ apiClient: this.apiClient,
1786
+ apiMethod: this.apiMethod,
1787
+ apiArgs: this.getAjaxArgs(),
1788
+ columns: this.columns,
1789
+ rows: this.rows,
1790
+ exportConfig: this.exportConfig,
1791
+ paginationOffset: this.paginationPosition - 1,
1792
+ paginationLength: this.getPaginationLength(),
1793
+ totalFilteredCount: this.totalFilteredCount,
1794
+ });
1795
+ }
1796
+
1797
+ toggleCheckboxes(visible?: boolean): void {
1798
+ if (visible == null) {
1799
+ visible = !this.checkboxesShown;
1800
+ }
1801
+
1802
+ this.checkboxesShown = visible;
1803
+ }
1804
+
1805
+ getSkin(): DataTableSkin {
1806
+ return this.currentSkin || DataTableSkin.Default;
1807
+ }
1808
+
1809
+ getMobileBehavior(): DataTableMobileBehavior {
1810
+ return this.currentMobileBehavior || DataTableMobileBehavior.MobileLayout;
1811
+ }
1812
+
1813
+ getVisibleColumns(): TableColumn[] {
1814
+ const state = StorageHelper.getStoredState(this.id);
1815
+ const colArr = this.columns.filter(p => p.visible != false);
1816
+ this.reorderColumns(this.colSortOrder, colArr);
1817
+ this.handleColumnsVisibility(state, colArr);
1818
+ return colArr;
1819
+
1820
+ // return this.columns.filter(p => p.visible != false);
1821
+ }
1822
+
1823
+ isDesiredCustomFieldColumn(
1824
+ dtCol: TableColumn,
1825
+ row: any,
1826
+ mappingType: any,
1827
+ ): boolean {
1828
+ const nameCf = row.CustomFields.filter(p => p.MappingType == mappingType)[0];
1829
+ if (nameCf != null && ((dtCol.id.includes(`id:${nameCf.Id}`)) || (dtCol.id.includes(`map:${nameCf.MappingType}`)))) {
1830
+ return true;
1831
+ }
1832
+
1833
+ return false;
1834
+ }
1835
+
1836
+ getChangeEventDelay() {
1837
+ if (this.filterMode == DataTableFilterMode.Clientside) {
1838
+ return 0;
1839
+ } else {
1840
+ return 650;
1841
+ }
1842
+ }
1843
+
1844
+ getTableColumnOrder(dtCol: TableColumn, row: any): number {
1845
+ if (dtCol.mobileOrder != null) {
1846
+ return dtCol.mobileOrder;
1847
+ }
1848
+
1849
+ if (dtCol.id.includes('cf:') && row.CustomFields != null) {
1850
+ if (this.isDesiredCustomFieldColumn(
1851
+ dtCol,
1852
+ row,
1853
+ 1,
1854
+ )) {
1855
+ return -10100;
1856
+ }
1857
+
1858
+ if (this.isDesiredCustomFieldColumn(
1859
+ dtCol,
1860
+ row,
1861
+ 1,
1862
+ )) {
1863
+ return -10000;
1864
+ }
1865
+ }
1866
+
1867
+ if (dtCol.id == 'Name') {
1868
+ return -9000;
1869
+ }
1870
+
1871
+ if (dtCol.id == 'TicketName') {
1872
+ return -8900;
1873
+ }
1874
+
1875
+ return null;
1876
+ }
1877
+
1878
+ getTableColumnOrderStyle(dtCol: TableColumn, row: any): string {
1879
+ const retVal = this.getTableColumnOrder(dtCol, row);
1880
+ if (retVal != null) {
1881
+ return `order:${retVal}`;
1882
+ }
1883
+
1884
+ return null;
1885
+ }
1886
+
1887
+ getMassOperationItems(): typeof DropdownButtonItem.prototype[] {
1888
+ return this.massOperationOptions || [];
1889
+ }
1890
+
1891
+ shouldRenderMobileRowColumn(row, dtColumn: TableColumn): boolean {
1892
+ if (dtColumn.customRender == null) {
1893
+ if (dtColumn.customValue != null) {
1894
+ return dtColumn.customValue(row) != null;
1895
+ }
1896
+
1897
+ return row[dtColumn.id] != null;
1898
+ }
1899
+
1900
+ if (dtColumn.mobileShouldRenderRow) {
1901
+ return dtColumn.mobileShouldRenderRow(row);
1902
+ }
1903
+
1904
+ return true;
1905
+ }
1906
+
1907
+ clearSelection() {
1908
+ $(this.$el).find('.dt-col-index').find('input').prop('checked', false);
1909
+ }
1910
+
1911
+ getFilterValue(dtColumn: TableColumn): any {
1912
+ if (this.filterArr == null) {
1913
+ return null;
1914
+ }
1915
+
1916
+ const filterItem = this.filterArr.filter(p => p.PropertyName == dtColumn.id)[0];
1917
+ if (filterItem == null) {
1918
+ return null;
1919
+ }
1920
+
1921
+ if (filterItem.FilterType == DataTableFilterItemType.Text) {
1922
+ return filterItem.ContainsValue;
1923
+ } else if (filterItem.FilterType == DataTableFilterItemType.Dropdown) {
1924
+ return filterItem.ValueArr;
1925
+ } else if (filterItem.FilterType == DataTableFilterItemType.DateRange) {
1926
+ return {
1927
+ startTime: filterItem.DateFrom,
1928
+ endTime: filterItem.DateTo,
1929
+ };
1930
+ } else if (filterItem.FilterType == DataTableFilterItemType.NumericRange) {
1931
+
1932
+ } else {
1933
+ return null;
1934
+ }
1935
+ }
1936
+
1937
+ render(h) {
1938
+ const columns = this.getVisibleColumns();
1939
+ let paginationStart = (this.paginationPosition - 1) * this.getPaginationLength() + 1;
1940
+ let paginationEnd = Math.min(paginationStart + this.getPaginationLength(), this.totalFilteredCount) - 1;
1941
+ const settingsUUID = `ddl-${PortalUtils.randomString(10)}`;
1942
+ const isMobile = PortalUtils.treatAsMobileDevice();
1943
+ const hasMobLayout = this.getMobileBehavior() == DataTableMobileBehavior.MobileLayout;
1944
+ const hasTableSkin = this.getSkin() == DataTableSkin.Default;
1945
+
1946
+ if (this.paginationPosition == this.getLastPaginationIndex()) {
1947
+ paginationEnd += 1;
1948
+ }
1949
+
1950
+ if (this.totalFilteredCount == 0) {
1951
+ paginationStart = 0;
1952
+ paginationEnd = 0;
1953
+ }
1954
+
1955
+ if (this.getPaginationLength() == -1) {
1956
+ paginationEnd = this.totalFilteredCount;
1957
+ }
1958
+
1959
+ return (
1960
+ <div
1961
+ class={
1962
+ `dt-root dt-mobile-mobile dt-device-${PortalUtils.treatAsMobileDevice() ? 'mobile' : 'desktop'
1963
+ }${PortalUtils.isIOS() ? ' dt-ios' : ''
1964
+ } dt-skin-${this.getSkin()
1965
+ } dt-mobbehavior-${this.getMobileBehavior()
1966
+ }${this.checkboxesShown ? ' dt-checkboxes-visible' : ''
1967
+ } dt-breakpoint-${this.activeBreakPoint
1968
+ }${this.fullSizeHasButtonBelow ? ' dt-fs-buttonsbelow' : ''
1969
+ }${this.insetTop ? ' dt-inset-top' : ''
1970
+ }${this.fullSizeTable == true ? ' dt-fullsize-table' : ''
1971
+ } ${this.cssClass || ''}`
1972
+ }
1973
+ >
1974
+ {this.topVisible != false && (
1975
+ <div class="dt-top">
1976
+ <div class="dt-top-buttonsrow">
1977
+ <div class="dt-buttons">
1978
+ <TableButtonComponent title={PowerduckState.getResourceValue('colVisLabel')} icon="fa fa-eye-slash" clicked={() => this.showColVis()} />
1979
+
1980
+ {this.buttons
1981
+ && this.buttons.map(btn => (
1982
+ <TableButtonComponent title={btn.title} icon={btn.icon} childItems={btn.childItems} customRender={btn.customRender} clicked={() => btn.clicked()} />
1983
+ ))}
1984
+
1985
+ {this.allowExport != false && <TableButtonComponent title="Excel export" icon="far fa-file-excel" clicked={() => this.exportExcel()} />}
1986
+
1987
+ {this.allowMassOperations != false && <TableButtonComponent title={this.checkboxesTitle || ''} icon="far fa-check-square" clicked={() => this.toggleCheckboxes()} />}
1988
+
1989
+ {this.activeBreakPoint == DataTableBreakpoint.Mobile && this.getMobileBehavior() == DataTableMobileBehavior.MobileLayout && (
1990
+ <TableButtonComponent title="Filter" icon="fas fa-filter" clicked={() => this.showFilterModal()} />
1991
+ )}
1992
+
1993
+ <span class="nav-item dt-button dropdown">
1994
+ <span class="dropdown-toggle" id={settingsUUID} data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
1995
+ <i class="fas fa-desktop"></i>
1996
+ </span>
1997
+ <div class="dropdown-menu dropdown-menu-right" aria-labelledby={settingsUUID}>
1998
+ {isMobile && (
1999
+ <a class="dropdown-item dropdown-selectable-section" href="javascript:" onClick={() => this.setMobileBehavior(DataTableMobileBehavior.MobileLayout)}>
2000
+ <span>{PowerduckState.getResourceValue('dtLayoutMobile')}</span>
2001
+ {hasMobLayout && <i class="fas fa-check"></i>}
2002
+ </a>
2003
+ )}
2004
+
2005
+ {!isMobile && (
2006
+ <a class="dropdown-item dropdown-selectable-section" href="javascript:" onClick={() => this.setSkin(DataTableSkin.Default)}>
2007
+ <span>{PowerduckState.getResourceValue('dtLayoutTable')}</span>
2008
+ {hasTableSkin && <i class="fas fa-check"></i>}
2009
+ </a>
2010
+ )}
2011
+
2012
+ <a
2013
+ class="dropdown-item dropdown-selectable-section"
2014
+ href="javascript:"
2015
+ onClick={() => (isMobile ? this.setMobileBehavior(DataTableMobileBehavior.Compact) : this.setSkin(DataTableSkin.Compact))}
2016
+ >
2017
+ <span>{isMobile ? PowerduckState.getResourceValue('dtLayoutTable') : PowerduckState.getResourceValue('dtLayoutCompact')}</span>
2018
+ {((isMobile && !hasMobLayout) || (!isMobile && !hasTableSkin)) && <i class="fas fa-check"></i>}
2019
+ </a>
2020
+ </div>
2021
+ </span>
2022
+ </div>
2023
+ </div>
2024
+ {this.hidePagination != true
2025
+ && (
2026
+ <div class="dt-top-paginationrow">
2027
+ {(!this.checkboxesShown || this.checkboxButtonsVisible == false) && (
2028
+ <div class="dt-pagination-length">
2029
+ <select onChange={e => this.handlePaginationLengthChanged(Number(e.target.value))}>
2030
+ {(this.paginations || [
2031
+ 10,
2032
+ 25,
2033
+ 50,
2034
+ 100,
2035
+ 250,
2036
+ 500,
2037
+ 1000,
2038
+ -1,
2039
+ ]).map(item => (
2040
+ <option value={item} selected={this.getPaginationLength() == item}>
2041
+ {item != -1 ? item.toString() : PowerduckState.getResourceValue('all')}
2042
+ </option>
2043
+ ))}
2044
+ </select>
2045
+
2046
+ <span>{PowerduckState.getResourceValue('recordsDtLabel')}</span>
2047
+ </div>
2048
+ )}
2049
+
2050
+ {this.checkboxesShown && this.checkboxButtonsVisible != false && (
2051
+ <div class="dt-pagination-length dt-massop-btn-wrap">
2052
+ <DropdownButton text="Hromadne operacie" layout={ButtonLayout.Secondary}>
2053
+ {this.getMassOperationItems().map(mi =>
2054
+ (mi as any).isSeparator != true ? <DropdownButtonItem icon={mi.icon} text={mi.text} clicked={mi.clicked} /> : <div class="dropdown-divider" />)}
2055
+
2056
+ <DropdownButtonItem icon="icon icon-close" text={PowerduckState.getResourceValue('cancel')} clicked={() => this.toggleCheckboxes(false)} />
2057
+ </DropdownButton>
2058
+ <Button text={PowerduckState.getResourceValue('cancel')} layout={ButtonLayout.Default} clicked={() => this.toggleCheckboxes(false)} cssClass="dt-massop-cancelbtn" />
2059
+ </div>
2060
+ )}
2061
+
2062
+ <div class="dt-fulltext-search">
2063
+ <input type="search" placeholder={`${PowerduckState.getResourceValue('search')[capitalize]()}...`} onKeyup={e => this.performFullTextSearch(e)} />
2064
+ </div>
2065
+ </div>
2066
+ )}
2067
+ </div>
2068
+ )}
2069
+
2070
+ {this.renderTableByMode(h, columns)}
2071
+
2072
+ {this.bottomVisible != false && (
2073
+ <div class="dt-bottom">
2074
+ <div class="dt-summary-wrap">
2075
+ {PowerduckState.getResourceValue('dtCountText').replace('{0}', paginationStart.toString()).replace('{1}', paginationEnd.toString()).replace('{2}', this.totalFilteredCount.toString())}
2076
+ {this.totalFilteredCount != this.totalCount && (
2077
+ <span class="dt-summary-totalcount">
2077
2078
  &nbsp;
2078
- {PowerduckState.getResourceValue('dtCountFilteredOutOf').replace('{0}', this.totalCount.toString())}
2079
- </span>
2080
- )}
2081
- </div>
2082
-
2083
- <div class="dt-pagination">{this.renderPagination(h)}</div>
2084
- </div>
2085
- )}
2086
-
2087
- <ColVisModal ref="colVisModal" columns={this.columns} changed={e => this.handleColumnVisibilityChanged(e)} />
2088
- <ColFilterModal ref="colFilterModal" columns={this.columns} changed={e => this.handleColumnModalFilterChanged(e)} />
2089
- <TableExportModal ref="tableExportModal" />
2090
- </div>
2091
- );
2092
- }
2093
-
2094
- protected renderTableByMode(h, columns: TableColumn[]) {
2095
- if (this.activeBreakPoint == DataTableBreakpoint.Mobile) {
2096
- if (this.getMobileBehavior() == DataTableMobileBehavior.MobileLayout) {
2097
- return this.renderMobileMode(h, columns);
2098
- } else if (this.getMobileBehavior() == DataTableMobileBehavior.VerticalTransform) {
2099
- return this.renderVerticallyTransformedTable(h, columns);
2100
- }
2101
- }
2102
-
2103
- return this.renderStandardTable(h, columns);
2104
- }
2105
-
2106
- protected renderStandardTable(h, columns: TableColumn[]) {
2107
- return (
2108
- <div class="dt-table dt-table-mode">
2109
- <table>
2110
- <LoadingIndicator visible={!this.initialized} />
2111
-
2112
- {this.enforceHeaderRedraw == false && (
2113
- <thead>
2114
- <tr class="dt-header">
2115
- <th data-col-id="_sysIndexCol" class="dt-header-index">
2116
- {!this.isLoading && (
2117
- <span>
2118
- <span class="dt-header-indexlabel" style={this.checkboxesShown ? 'display:none' : ''}>
2119
- #
2120
- </span>
2121
- <span class="dt-header-indexcheckbox" style={this.checkboxesShown ? '' : 'display:none'}>
2122
- <CheckBox
2123
- skin={CheckBoxSkin.Material}
2124
- label={null}
2125
- wrap={false}
2126
- value={false}
2127
- changed={(e) => {
2128
- this.handleCheckAllChanged(e);
2129
- }}
2130
- />
2131
- </span>
2132
- </span>
2133
- )}
2134
-
2135
- {this.isLoading && <img src={loadingGif} />}
2136
- </th>
2137
-
2138
- {this.renderHeaderRow(h, columns)}
2139
- </tr>
2140
-
2141
- {this.autoFilter != false && (
2142
- <tr class="dt-header-filter">
2143
- <th class="dt-filter-index"></th>
2144
-
2145
- {columns.map((dtColumn, i) => (
2146
- <th class={this.getTableColumnHeaderFilterCssClass(dtColumn, i)}>{this.renderHeaderFilter(h, dtColumn)}</th>
2147
- ))}
2148
- </tr>
2149
- )}
2150
- </thead>
2151
- )}
2152
- <tbody>
2153
- {this.rowClicked == null
2154
- && this.enforceBodyRedraw == false
2155
- && (this.rows || []).map((row, i) => (
2156
- <tr class={`dt-item${this.rowCssClass == null ? '' : ` ${this.rowCssClass(row)}`}`}>
2157
- <td class={`dt-col-index${this.sortableRows == true ? ' dt-has-sortable-rows' : ''}`}>
2158
- <span class="dt-col-indexlabel" style={this.checkboxesShown ? 'display:none' : ''}>
2159
- {this.getHeaderColumnIndex(
2160
- columns,
2161
- row,
2162
- i,
2163
- )}
2164
- </span>
2165
- <span class="dt-col-indexcheckbox dt-selection-checkbox" data-id={this.getRowId(row)} style={this.checkboxesShown ? '' : 'display:none'}>
2166
- <CheckBox skin={CheckBoxSkin.Material} label={null} value={false} wrap={false} changed={e => this.handleRowCheckboxChanged(row, e)} />
2167
- </span>
2168
-
2169
- {this.sortableRows == true && <i class="fas fa-sort dt-sort-handle" />}
2170
- </td>
2171
-
2172
- {columns.map((dtColumn, j) => (
2173
- <td class={this.getTableItemCssClass(dtColumn, j)}>{dtColumn.customRender == null ? (dtColumn.customValue == null ? row[dtColumn.id] : dtColumn.customValue(row)) : dtColumn.customRender(h, row)}</td>
2174
- ))}
2175
- </tr>
2176
- ))}
2177
-
2178
- {this.rowClicked != null
2179
- && this.enforceBodyRedraw == false
2180
- && (this.rows || []).map((row, i) => (
2181
- <tr
2182
- class={`dt-item${this.rowCssClass == null ? '' : ` ${this.rowCssClass(row)}`}`}
2183
- onClick={() => {
2184
- this.rowClicked(row);
2185
- }}
2186
- >
2187
- <td class={`dt-col-index${this.sortableRows == true ? ' dt-has-sortable-rows' : ''}`}>
2188
- <span class="dt-col-indexlabel" style={this.checkboxesShown ? 'display:none' : ''}>
2189
- {this.getHeaderColumnIndex(
2190
- columns,
2191
- row,
2192
- i,
2193
- )}
2194
- </span>
2195
- <span class="dt-col-indexcheckbox dt-selection-checkbox" data-id={this.getRowId(row)} style={this.checkboxesShown ? '' : 'display:none'}>
2196
- <CheckBox skin={CheckBoxSkin.Material} label={null} value={false} wrap={false} changed={e => this.handleRowCheckboxChanged(row, e)} />
2197
- </span>
2198
-
2199
- {this.sortableRows == true && <i class="fas fa-sort dt-sort-handle" />}
2200
- </td>
2201
-
2202
- {columns.map((dtColumn, j) => (
2203
- <td class={this.getTableItemCssClass(dtColumn, j)}>{dtColumn.customRender == null ? (dtColumn.customValue == null ? row[dtColumn.id] : dtColumn.customValue(row)) : dtColumn.customRender(h, row)}</td>
2204
- ))}
2205
- </tr>
2206
- ))}
2207
-
2208
- {this.totalFilteredCount == 0 && (
2209
- <tr>
2210
- <td class="dt-no-results" colspan="99999">
2211
- <div class="dt-no-results-inner">
2212
- <div>{PowerduckState.getResourceValue('noResultsFound')}</div>
2213
- </div>
2214
- </td>
2215
- </tr>
2216
- )}
2217
- </tbody>
2218
- </table>
2219
- </div>
2220
- );
2221
- }
2222
-
2223
- protected renderHeaderRow(h, columns: TableColumn[]) {
2224
- return columns.map((dtColumn, i) => (
2225
- <th
2226
- data-col-id={dtColumn.id}
2227
- onMousedown={e =>
2228
- ReorderProvider.handleMouseDown(
2229
- e,
2230
- (sortOrder) => {
2231
- this.handleColumnsReordered(sortOrder);
2232
- },
2233
- () => {
2234
- this.handleColumnHeaderClicked(dtColumn);
2235
- },
2236
- )}
2237
- onTouchstart={e =>
2238
- ReorderProvider.handleMouseDown(
2239
- e,
2240
- (sortOrder) => {
2241
- this.handleColumnsReordered(sortOrder);
2242
- },
2243
- () => {
2244
- this.handleColumnHeaderClicked(dtColumn);
2245
- },
2246
- )}
2247
- class={this.getTableColumnHeaderCssClass(dtColumn, i)}
2248
- >
2249
- {dtColumn.caption}
2250
- {this.sortDefinition && this.sortDefinition.columnId == dtColumn.id && (
2251
- <span class="dt-sort">
2252
- <i class={`fas ${this.sortDefinition.direction == DataTableSortDirection.Ascending ? 'fa-sort-up' : 'fa-sort-down'} float-right`} aria-hidden="true"></i>
2253
- </span>
2254
- )}
2255
- </th>
2256
- ));
2257
- }
2258
-
2259
- protected renderHeaderFilter(h, dtColumn: TableColumn) {
2260
- const filterType = dtColumn.filterType;
2261
- const filterValue = this.getFilterValue(dtColumn);
2262
- const closeIcon = !isNullOrEmpty(filterValue) ? 'icon icon-close' : null;
2263
- const appendIconClicked = () => {
2264
- if (this.currentAdvancedFilterState[dtColumn.id] != null) {
2265
- this.currentAdvancedFilterState[dtColumn.id] = null;
2266
- }
2267
-
2268
- if (this.filterArr != null) {
2269
- this.filterArr = this.filterArr.filter(p => p.PropertyName != dtColumn.id);
2270
- }
2271
-
2272
- if (filterType == DataTableFilterItemType.Text || filterType == null) {
2273
- this.performInputFilter(dtColumn, null);
2274
- } else if (filterType == DataTableFilterItemType.DateRange) {
2275
- this.performDateRangeFilter(dtColumn, null);
2276
- } else if (filterType == DataTableFilterItemType.Dropdown) {
2277
- this.performSelectionFilter(
2278
- dtColumn,
2279
- [],
2280
- null,
2281
- );
2282
- } else if (filterType == DataTableFilterItemType.NumericRange) {
2283
-
2284
- }
2285
- };
2286
-
2287
- if (filterType == DataTableFilterItemType.None) {
2288
- return '';
2289
- } else if (filterType == DataTableFilterItemType.Text || filterType == null) {
2290
- return (<TextBox updateMode="input" cssClass="dt-filter-input" wrap={false} label={null} placeholder={`${PowerduckState.getResourceValue('search')[capitalize]()}...`} value={this.currentAdvancedFilterState[dtColumn.id]} changed={(e) => { this.performInputFilter(dtColumn, e); }} appendIcon={closeIcon} appendIconClicked={appendIconClicked} />);
2291
- } else if (filterType == DataTableFilterItemType.Dropdown) {
2292
- return (
2293
- <div class="dt-filter-dropdown">
2294
- <DropdownList
2295
- label={null}
2296
- containerCssClass="dt-filter-dropdown-container"
2297
- options={dtColumn.filterItems}
2298
- wrap={false}
2299
- disableSearch={!dtColumn.searchable}
2300
- dropdownAutoWidth={true}
2301
- multiselect={true}
2302
- multiselectMode={MultiselectMode.Checkboxes}
2303
- mobileShortMode={true}
2304
- allowExclusiveSearch={dtColumn.filterAllowExclusivity}
2305
- changedEventDelay={this.getChangeEventDelay()}
2306
- selected={this.currentAdvancedFilterState[dtColumn.id]}
2307
- changed={(changeArr, exclusivity) => {
2308
- this.performSelectionFilter(
2309
- dtColumn,
2310
- changeArr,
2311
- exclusivity,
2312
- );
2313
- }}
2314
- appendIcon={closeIcon}
2315
- appendIconClicked={appendIconClicked}
2316
- />
2317
- </div>
2318
- );
2319
- } else if (filterType == DataTableFilterItemType.DateRange) {
2320
- return (<DaterangePicker label={null} cssClass="dt-filter-input" wrap={false} placeholder={`${PowerduckState.getResourceValue('search')[capitalize]()}...`} value={this.currentAdvancedFilterState[dtColumn.id]} changed={(e) => { this.performDateRangeFilter(dtColumn, e); }} appendIcon={closeIcon} appendIconClicked={appendIconClicked} />);
2321
- }
2322
- }
2323
-
2324
- protected renderVerticallyTransformedTable(h, columns: TableColumn[]) {
2325
- return (this.rows || []).map((row, i) => (
2326
- <div class="dt-vert-row">
2327
- {columns.map((dtColumn, j) => (
2328
- <div class="dt-vert-item" style={this.getTableColumnOrderStyle(dtColumn, row)}>
2329
- <div class="dt-vert-caption">{dtColumn.caption}</div>
2330
- <div class="dt-vert-value">{dtColumn.customRender == null ? (dtColumn.customValue == null ? row[dtColumn.id] : dtColumn.customValue(row)) : dtColumn.customRender(h, row)}</div>
2331
- </div>
2332
- ))}
2333
- </div>
2334
- ));
2335
- }
2336
-
2337
- protected renderMobileMode(h, columns: TableColumn[]) {
2338
- if (this.mobileModeCustomRender != null) {
2339
- return this.mobileModeCustomRender(
2340
- h,
2341
- columns,
2342
- this.rows,
2343
- );
2344
- }
2345
-
2346
- return (
2347
- <div class="dt-mobile-rows">
2348
- {(this.isLoading || this.enforceBodyRedraw || this.enforceHeaderRedraw) && (
2349
- <div style="min-height:150px;">
2350
- <LoadingIndicator visible={true} />
2351
- </div>
2352
- )}
2353
-
2354
- {this.enforceHeaderRedraw == false
2355
- && this.enforceBodyRedraw == false
2356
- && (this.rows || []).map((row, i) => (
2357
- <div class={`dt-mobile-row${this.rowCssClass == null ? '' : ` ${this.rowCssClass(row)}`}`}>
2358
- {this.renderMobileModeRow(
2359
- h,
2360
- columns,
2361
- row,
2362
- i,
2363
- )}
2364
- </div>
2365
- ))}
2366
- </div>
2367
- );
2368
- }
2369
-
2370
- protected renderMobileModeRow(
2371
- h,
2372
- columns: TableColumn[],
2373
- row: any,
2374
- i: number,
2375
- ) {
2376
- const identifier = this.getRowIdentifier(
2377
- columns,
2378
- row,
2379
- true,
2380
- );
2381
- let colArr = this.getVisibleColumns().filter(p => p.mobileVisible != false);
2382
- const cssClass = `dt-mobile-row-inner${this.checkboxesShown ? ' dt-mobile-chbvisible' : ''}`;
2383
-
2384
- // Exclude identifier columns if they are already picked by the engine
2385
- if (identifier != null && identifier.dtColumns != null && identifier.dtColumns.length > 0) {
2386
- colArr = colArr.filter(p => !identifier.dtColumns.map(c => c.id).includes(p.id));
2387
- }
2388
-
2389
- return (
2390
- <div
2391
- class={cssClass}
2392
- onClick={(e) => {
2393
- this.handleMobileRowClicked(e, row);
2394
- }}
2395
- >
2396
- {this.checkboxesShown && (
2397
- <div class="dt-mobile-checkbox dt-selection-checkbox" data-id={this.getRowId(row)}>
2398
- <CheckBox skin={CheckBoxSkin.Material} label={null} wrap={false} value={null} changed={e => this.handleRowCheckboxChanged(row, e)} />
2399
- </div>
2400
- )}
2401
-
2402
- {identifier && <div class="dt-mobile-identifier">{identifier.fullName}</div>}
2403
-
2404
- {colArr.map((dtColumn, j) => (
2405
- <div class={`dt-mobile-item dt-mobile-${dtColumn.id.replaceAll(':', '_').toLowerCase()}`} style={this.getTableColumnOrderStyle(dtColumn, row)}>
2406
- {dtColumn.mobileRender == null && this.shouldRenderMobileRowColumn(row, dtColumn) && (
2407
- <div class="dt-mobile-item-inner">
2408
- {dtColumn.mobileCaption != false && <div class="dt-mobile-caption">{dtColumn.caption}</div>}
2409
-
2410
- <div class="dt-mobile-value">{dtColumn.customRender == null ? (dtColumn.customValue == null ? row[dtColumn.id] : dtColumn.customValue(row)) : dtColumn.customRender(h, row)}</div>
2411
- </div>
2412
- )}
2413
- {dtColumn.mobileRender && dtColumn.mobileRender(h, row)}
2414
- </div>
2415
- ))}
2416
-
2417
- <i class={`${this.mobileModeRowIcon || 'icon icon-arrow-right'} dt-mobile-row-icon`}></i>
2418
- </div>
2419
- );
2420
- }
2421
-
2422
- protected renderPagination(h) {
2423
- let paginationLength = 5;
2424
- let firstIndex = Math.max(this.paginationPosition - 2, 1);
2425
- let paginationEnd = firstIndex + paginationLength - 1;
2426
- let indexArr = [];
2427
-
2428
- if (this.getPaginationLength() > -1) {
2429
- if (paginationEnd > this.getLastPaginationIndex()) {
2430
- paginationEnd = this.getLastPaginationIndex();
2431
- firstIndex = paginationEnd - paginationLength + 1;
2432
- }
2433
-
2434
- if (firstIndex < 1) {
2435
- firstIndex = 1;
2436
- paginationLength = paginationEnd - firstIndex + 1;
2437
- }
2438
-
2439
- for (let i = firstIndex, len = paginationLength; i <= paginationEnd; i++) {
2440
- indexArr.push(i);
2441
- }
2442
- } else {
2443
- indexArr = [1];
2444
- this.paginationPosition = 1;
2445
- }
2446
-
2447
- return (
2448
- <ul class="pagination">
2449
- <li class="page-item">
2450
- <a class="page-link" href="javascript:" aria-label="Previous" onClick={e => this.handlePaginationPositionChanged(this.paginationPosition - 1)}>
2451
- <span aria-hidden="true">
2452
- <i class="fa fa-angle-double-left" aria-hidden="true"></i>
2453
- </span>
2454
- </a>
2455
- </li>
2456
-
2457
- {indexArr.map(pagIndex => (
2458
- <li class={`page-item${pagIndex == this.paginationPosition ? ' active' : ''}`} onClick={e => this.handlePaginationPositionChanged(pagIndex)}>
2459
- <a class="page-link" href="javascript:">
2460
- {pagIndex}
2461
- </a>
2462
- </li>
2463
- ))}
2464
-
2465
- <li class="page-item">
2466
- <a class="page-link" href="javascript:" aria-label="Next" onClick={e => this.handlePaginationPositionChanged(this.paginationPosition + 1)}>
2467
- <span aria-hidden="true">
2468
- <i class="fa fa-angle-double-right" aria-hidden="true"></i>
2469
- </span>
2470
- </a>
2471
- </li>
2472
- </ul>
2473
- );
2474
- }
2475
-
2476
- protected renderColumnValue(
2477
- h,
2478
- dtColumn: TableColumn,
2479
- row,
2480
- ) {
2481
- if (dtColumn.customRender == null) {
2482
- return (dtColumn.customValue == null ? row[dtColumn.id] : dtColumn.customValue(row));
2483
- } else {
2484
- return dtColumn.customRender(h, row);
2485
- }
2486
- }
2079
+ {PowerduckState.getResourceValue('dtCountFilteredOutOf').replace('{0}', this.totalCount.toString())}
2080
+ </span>
2081
+ )}
2082
+ </div>
2083
+
2084
+ <div class="dt-pagination">{this.renderPagination(h)}</div>
2085
+ </div>
2086
+ )}
2087
+
2088
+ <ColVisModal ref="colVisModal" columns={this.columns} changed={e => this.handleColumnVisibilityChanged(e)} />
2089
+ <ColFilterModal ref="colFilterModal" columns={this.columns} changed={e => this.handleColumnModalFilterChanged(e)} />
2090
+ <TableExportModal ref="tableExportModal" />
2091
+ </div>
2092
+ );
2093
+ }
2094
+
2095
+ protected renderTableByMode(h, columns: TableColumn[]) {
2096
+ if (this.activeBreakPoint == DataTableBreakpoint.Mobile) {
2097
+ if (this.getMobileBehavior() == DataTableMobileBehavior.MobileLayout) {
2098
+ return this.renderMobileMode(h, columns);
2099
+ } else if (this.getMobileBehavior() == DataTableMobileBehavior.VerticalTransform) {
2100
+ return this.renderVerticallyTransformedTable(h, columns);
2101
+ }
2102
+ }
2103
+
2104
+ return this.renderStandardTable(h, columns);
2105
+ }
2106
+
2107
+ protected renderStandardTable(h, columns: TableColumn[]) {
2108
+ return (
2109
+ <div class="dt-table dt-table-mode">
2110
+ <table>
2111
+ <LoadingIndicator visible={!this.initialized} />
2112
+
2113
+ {this.enforceHeaderRedraw == false && (
2114
+ <thead>
2115
+ <tr class="dt-header">
2116
+ <th data-col-id="_sysIndexCol" class="dt-header-index">
2117
+ {!this.isLoading && (
2118
+ <span>
2119
+ <span class="dt-header-indexlabel" style={this.checkboxesShown ? 'display:none' : ''}>
2120
+ #
2121
+ </span>
2122
+ <span class="dt-header-indexcheckbox" style={this.checkboxesShown ? '' : 'display:none'}>
2123
+ <CheckBox
2124
+ skin={CheckBoxSkin.Material}
2125
+ label={null}
2126
+ wrap={false}
2127
+ value={false}
2128
+ changed={(e) => {
2129
+ this.handleCheckAllChanged(e);
2130
+ }}
2131
+ />
2132
+ </span>
2133
+ </span>
2134
+ )}
2135
+
2136
+ {this.isLoading && <img src={loadingGif} />}
2137
+ </th>
2138
+
2139
+ {this.renderHeaderRow(h, columns)}
2140
+ </tr>
2141
+
2142
+ {this.autoFilter != false && (
2143
+ <tr class="dt-header-filter">
2144
+ <th class="dt-filter-index"></th>
2145
+
2146
+ {columns.map((dtColumn, i) => (
2147
+ <th class={this.getTableColumnHeaderFilterCssClass(dtColumn, i)}>{this.renderHeaderFilter(h, dtColumn)}</th>
2148
+ ))}
2149
+ </tr>
2150
+ )}
2151
+ </thead>
2152
+ )}
2153
+ <tbody>
2154
+ {this.rowClicked == null
2155
+ && this.enforceBodyRedraw == false
2156
+ && (this.rows || []).map((row, i) => (
2157
+ <tr class={`dt-item${this.rowCssClass == null ? '' : ` ${this.rowCssClass(row)}`}`}>
2158
+ <td class={`dt-col-index${this.sortableRows == true ? ' dt-has-sortable-rows' : ''}`}>
2159
+ <span class="dt-col-indexlabel" style={this.checkboxesShown ? 'display:none' : ''}>
2160
+ {this.getHeaderColumnIndex(
2161
+ columns,
2162
+ row,
2163
+ i,
2164
+ )}
2165
+ </span>
2166
+ <span class="dt-col-indexcheckbox dt-selection-checkbox" data-id={this.getRowId(row)} style={this.checkboxesShown ? '' : 'display:none'}>
2167
+ <CheckBox skin={CheckBoxSkin.Material} label={null} value={false} wrap={false} changed={e => this.handleRowCheckboxChanged(row, e)} />
2168
+ </span>
2169
+
2170
+ {this.sortableRows == true && <i class="fas fa-sort dt-sort-handle" />}
2171
+ </td>
2172
+
2173
+ {columns.map((dtColumn, j) => (
2174
+ <td class={this.getTableItemCssClass(dtColumn, j)}>{dtColumn.customRender == null ? (dtColumn.customValue == null ? row[dtColumn.id] : dtColumn.customValue(row)) : dtColumn.customRender(h, row)}</td>
2175
+ ))}
2176
+ </tr>
2177
+ ))}
2178
+
2179
+ {this.rowClicked != null
2180
+ && this.enforceBodyRedraw == false
2181
+ && (this.rows || []).map((row, i) => (
2182
+ <tr
2183
+ class={`dt-item${this.rowCssClass == null ? '' : ` ${this.rowCssClass(row)}`}`}
2184
+ onClick={() => {
2185
+ this.rowClicked(row);
2186
+ }}
2187
+ >
2188
+ <td class={`dt-col-index${this.sortableRows == true ? ' dt-has-sortable-rows' : ''}`}>
2189
+ <span class="dt-col-indexlabel" style={this.checkboxesShown ? 'display:none' : ''}>
2190
+ {this.getHeaderColumnIndex(
2191
+ columns,
2192
+ row,
2193
+ i,
2194
+ )}
2195
+ </span>
2196
+ <span class="dt-col-indexcheckbox dt-selection-checkbox" data-id={this.getRowId(row)} style={this.checkboxesShown ? '' : 'display:none'}>
2197
+ <CheckBox skin={CheckBoxSkin.Material} label={null} value={false} wrap={false} changed={e => this.handleRowCheckboxChanged(row, e)} />
2198
+ </span>
2199
+
2200
+ {this.sortableRows == true && <i class="fas fa-sort dt-sort-handle" />}
2201
+ </td>
2202
+
2203
+ {columns.map((dtColumn, j) => (
2204
+ <td class={this.getTableItemCssClass(dtColumn, j)}>{dtColumn.customRender == null ? (dtColumn.customValue == null ? row[dtColumn.id] : dtColumn.customValue(row)) : dtColumn.customRender(h, row)}</td>
2205
+ ))}
2206
+ </tr>
2207
+ ))}
2208
+
2209
+ {this.totalFilteredCount == 0 && (
2210
+ <tr>
2211
+ <td class="dt-no-results" colspan="99999">
2212
+ <div class="dt-no-results-inner">
2213
+ <div>{PowerduckState.getResourceValue('noResultsFound')}</div>
2214
+ </div>
2215
+ </td>
2216
+ </tr>
2217
+ )}
2218
+ </tbody>
2219
+ </table>
2220
+ </div>
2221
+ );
2222
+ }
2223
+
2224
+ protected renderHeaderRow(h, columns: TableColumn[]) {
2225
+ return columns.map((dtColumn, i) => (
2226
+ <th
2227
+ data-col-id={dtColumn.id}
2228
+ onMousedown={e =>
2229
+ ReorderProvider.handleMouseDown(
2230
+ e,
2231
+ (sortOrder) => {
2232
+ this.handleColumnsReordered(sortOrder);
2233
+ },
2234
+ () => {
2235
+ this.handleColumnHeaderClicked(dtColumn);
2236
+ },
2237
+ )}
2238
+ onTouchstart={e =>
2239
+ ReorderProvider.handleMouseDown(
2240
+ e,
2241
+ (sortOrder) => {
2242
+ this.handleColumnsReordered(sortOrder);
2243
+ },
2244
+ () => {
2245
+ this.handleColumnHeaderClicked(dtColumn);
2246
+ },
2247
+ )}
2248
+ class={this.getTableColumnHeaderCssClass(dtColumn, i)}
2249
+ >
2250
+ {dtColumn.caption}
2251
+ {this.sortDefinition && this.sortDefinition.columnId == dtColumn.id && (
2252
+ <span class="dt-sort">
2253
+ <i class={`fas ${this.sortDefinition.direction == DataTableSortDirection.Ascending ? 'fa-sort-up' : 'fa-sort-down'} float-right`} aria-hidden="true"></i>
2254
+ </span>
2255
+ )}
2256
+ </th>
2257
+ ));
2258
+ }
2259
+
2260
+ protected renderHeaderFilter(h, dtColumn: TableColumn) {
2261
+ const filterType = dtColumn.filterType;
2262
+ const filterValue = this.getFilterValue(dtColumn);
2263
+ const closeIcon = !isNullOrEmpty(filterValue) ? 'icon icon-close' : null;
2264
+ const appendIconClicked = () => {
2265
+ if (this.currentAdvancedFilterState[dtColumn.id] != null) {
2266
+ this.currentAdvancedFilterState[dtColumn.id] = null;
2267
+ }
2268
+
2269
+ if (this.filterArr != null) {
2270
+ this.filterArr = this.filterArr.filter(p => p.PropertyName != dtColumn.id);
2271
+ }
2272
+
2273
+ if (filterType == DataTableFilterItemType.Text || filterType == null) {
2274
+ this.performInputFilter(dtColumn, null);
2275
+ } else if (filterType == DataTableFilterItemType.DateRange) {
2276
+ this.performDateRangeFilter(dtColumn, null);
2277
+ } else if (filterType == DataTableFilterItemType.Dropdown) {
2278
+ this.performSelectionFilter(
2279
+ dtColumn,
2280
+ [],
2281
+ null,
2282
+ );
2283
+ } else if (filterType == DataTableFilterItemType.NumericRange) {
2284
+
2285
+ }
2286
+ };
2287
+
2288
+ if (filterType == DataTableFilterItemType.None) {
2289
+ return '';
2290
+ } else if (filterType == DataTableFilterItemType.Text || filterType == null) {
2291
+ return (<TextBox updateMode="input" cssClass="dt-filter-input" wrap={false} label={null} placeholder={`${PowerduckState.getResourceValue('search')[capitalize]()}...`} value={this.currentAdvancedFilterState[dtColumn.id]} changed={(e) => { this.performInputFilter(dtColumn, e); }} appendIcon={closeIcon} appendIconClicked={appendIconClicked} />);
2292
+ } else if (filterType == DataTableFilterItemType.Dropdown) {
2293
+ return (
2294
+ <div class="dt-filter-dropdown">
2295
+ <DropdownList
2296
+ label={null}
2297
+ containerCssClass="dt-filter-dropdown-container"
2298
+ options={dtColumn.filterItems}
2299
+ wrap={false}
2300
+ disableSearch={!dtColumn.searchable}
2301
+ dropdownAutoWidth={true}
2302
+ multiselect={true}
2303
+ multiselectMode={MultiselectMode.Checkboxes}
2304
+ mobileShortMode={true}
2305
+ allowExclusiveSearch={dtColumn.filterAllowExclusivity}
2306
+ changedEventDelay={this.getChangeEventDelay()}
2307
+ selected={this.currentAdvancedFilterState[dtColumn.id]}
2308
+ changed={(changeArr, exclusivity) => {
2309
+ this.performSelectionFilter(
2310
+ dtColumn,
2311
+ changeArr,
2312
+ exclusivity,
2313
+ );
2314
+ }}
2315
+ appendIcon={closeIcon}
2316
+ appendIconClicked={appendIconClicked}
2317
+ />
2318
+ </div>
2319
+ );
2320
+ } else if (filterType == DataTableFilterItemType.DateRange) {
2321
+ return (<DaterangePicker label={null} cssClass="dt-filter-input" wrap={false} placeholder={`${PowerduckState.getResourceValue('search')[capitalize]()}...`} value={this.currentAdvancedFilterState[dtColumn.id]} changed={(e) => { this.performDateRangeFilter(dtColumn, e); }} appendIcon={closeIcon} appendIconClicked={appendIconClicked} />);
2322
+ }
2323
+ }
2324
+
2325
+ protected renderVerticallyTransformedTable(h, columns: TableColumn[]) {
2326
+ return (this.rows || []).map((row, i) => (
2327
+ <div class="dt-vert-row">
2328
+ {columns.map((dtColumn, j) => (
2329
+ <div class="dt-vert-item" style={this.getTableColumnOrderStyle(dtColumn, row)}>
2330
+ <div class="dt-vert-caption">{dtColumn.caption}</div>
2331
+ <div class="dt-vert-value">{dtColumn.customRender == null ? (dtColumn.customValue == null ? row[dtColumn.id] : dtColumn.customValue(row)) : dtColumn.customRender(h, row)}</div>
2332
+ </div>
2333
+ ))}
2334
+ </div>
2335
+ ));
2336
+ }
2337
+
2338
+ protected renderMobileMode(h, columns: TableColumn[]) {
2339
+ if (this.mobileModeCustomRender != null) {
2340
+ return this.mobileModeCustomRender(
2341
+ h,
2342
+ columns,
2343
+ this.rows,
2344
+ );
2345
+ }
2346
+
2347
+ return (
2348
+ <div class="dt-mobile-rows">
2349
+ {(this.isLoading || this.enforceBodyRedraw || this.enforceHeaderRedraw) && (
2350
+ <div style="min-height:150px;">
2351
+ <LoadingIndicator visible={true} />
2352
+ </div>
2353
+ )}
2354
+
2355
+ {this.enforceHeaderRedraw == false
2356
+ && this.enforceBodyRedraw == false
2357
+ && (this.rows || []).map((row, i) => (
2358
+ <div class={`dt-mobile-row${this.rowCssClass == null ? '' : ` ${this.rowCssClass(row)}`}`}>
2359
+ {this.renderMobileModeRow(
2360
+ h,
2361
+ columns,
2362
+ row,
2363
+ i,
2364
+ )}
2365
+ </div>
2366
+ ))}
2367
+ </div>
2368
+ );
2369
+ }
2370
+
2371
+ protected renderMobileModeRow(
2372
+ h,
2373
+ columns: TableColumn[],
2374
+ row: any,
2375
+ i: number,
2376
+ ) {
2377
+ const identifier = this.getRowIdentifier(
2378
+ columns,
2379
+ row,
2380
+ true,
2381
+ );
2382
+ let colArr = this.getVisibleColumns().filter(p => p.mobileVisible != false);
2383
+ const cssClass = `dt-mobile-row-inner${this.checkboxesShown ? ' dt-mobile-chbvisible' : ''}`;
2384
+
2385
+ // Exclude identifier columns if they are already picked by the engine
2386
+ if (identifier != null && identifier.dtColumns != null && identifier.dtColumns.length > 0) {
2387
+ colArr = colArr.filter(p => !identifier.dtColumns.map(c => c.id).includes(p.id));
2388
+ }
2389
+
2390
+ return (
2391
+ <div
2392
+ class={cssClass}
2393
+ onClick={(e) => {
2394
+ this.handleMobileRowClicked(e, row);
2395
+ }}
2396
+ >
2397
+ {this.checkboxesShown && (
2398
+ <div class="dt-mobile-checkbox dt-selection-checkbox" data-id={this.getRowId(row)}>
2399
+ <CheckBox skin={CheckBoxSkin.Material} label={null} wrap={false} value={null} changed={e => this.handleRowCheckboxChanged(row, e)} />
2400
+ </div>
2401
+ )}
2402
+
2403
+ {identifier && <div class="dt-mobile-identifier">{identifier.fullName}</div>}
2404
+
2405
+ {colArr.map((dtColumn, j) => (
2406
+ <div class={`dt-mobile-item dt-mobile-${dtColumn.id.replaceAll(':', '_').toLowerCase()}`} style={this.getTableColumnOrderStyle(dtColumn, row)}>
2407
+ {dtColumn.mobileRender == null && this.shouldRenderMobileRowColumn(row, dtColumn) && (
2408
+ <div class="dt-mobile-item-inner">
2409
+ {dtColumn.mobileCaption != false && <div class="dt-mobile-caption">{dtColumn.caption}</div>}
2410
+
2411
+ <div class="dt-mobile-value">{dtColumn.customRender == null ? (dtColumn.customValue == null ? row[dtColumn.id] : dtColumn.customValue(row)) : dtColumn.customRender(h, row)}</div>
2412
+ </div>
2413
+ )}
2414
+ {dtColumn.mobileRender && dtColumn.mobileRender(h, row)}
2415
+ </div>
2416
+ ))}
2417
+
2418
+ <i class={`${this.mobileModeRowIcon || 'icon icon-arrow-right'} dt-mobile-row-icon`}></i>
2419
+ </div>
2420
+ );
2421
+ }
2422
+
2423
+ protected renderPagination(h) {
2424
+ let paginationLength = 5;
2425
+ let firstIndex = Math.max(this.paginationPosition - 2, 1);
2426
+ let paginationEnd = firstIndex + paginationLength - 1;
2427
+ let indexArr = [];
2428
+
2429
+ if (this.getPaginationLength() > -1) {
2430
+ if (paginationEnd > this.getLastPaginationIndex()) {
2431
+ paginationEnd = this.getLastPaginationIndex();
2432
+ firstIndex = paginationEnd - paginationLength + 1;
2433
+ }
2434
+
2435
+ if (firstIndex < 1) {
2436
+ firstIndex = 1;
2437
+ paginationLength = paginationEnd - firstIndex + 1;
2438
+ }
2439
+
2440
+ for (let i = firstIndex, len = paginationLength; i <= paginationEnd; i++) {
2441
+ indexArr.push(i);
2442
+ }
2443
+ } else {
2444
+ indexArr = [1];
2445
+ this.paginationPosition = 1;
2446
+ }
2447
+
2448
+ return (
2449
+ <ul class="pagination">
2450
+ <li class="page-item">
2451
+ <a class="page-link" href="javascript:" aria-label="Previous" onClick={e => this.handlePaginationPositionChanged(this.paginationPosition - 1)}>
2452
+ <span aria-hidden="true">
2453
+ <i class="fa fa-angle-double-left" aria-hidden="true"></i>
2454
+ </span>
2455
+ </a>
2456
+ </li>
2457
+
2458
+ {indexArr.map(pagIndex => (
2459
+ <li class={`page-item${pagIndex == this.paginationPosition ? ' active' : ''}`} onClick={e => this.handlePaginationPositionChanged(pagIndex)}>
2460
+ <a class="page-link" href="javascript:">
2461
+ {pagIndex}
2462
+ </a>
2463
+ </li>
2464
+ ))}
2465
+
2466
+ <li class="page-item">
2467
+ <a class="page-link" href="javascript:" aria-label="Next" onClick={e => this.handlePaginationPositionChanged(this.paginationPosition + 1)}>
2468
+ <span aria-hidden="true">
2469
+ <i class="fa fa-angle-double-right" aria-hidden="true"></i>
2470
+ </span>
2471
+ </a>
2472
+ </li>
2473
+ </ul>
2474
+ );
2475
+ }
2476
+
2477
+ protected renderColumnValue(
2478
+ h,
2479
+ dtColumn: TableColumn,
2480
+ row,
2481
+ ) {
2482
+ if (dtColumn.customRender == null) {
2483
+ return (dtColumn.customValue == null ? row[dtColumn.id] : dtColumn.customValue(row));
2484
+ } else {
2485
+ return dtColumn.customRender(h, row);
2486
+ }
2487
+ }
2487
2488
  }
2488
2489
 
2489
2490
  (function () {
2490
- CheckboxUtils.bindTableShiftClick();
2491
- DropdownUtils.bindDropdownOverflowHack(
2492
- '.dt-root.dt-breakpoint-desktop tbody .dropdown',
2493
- 'dataTableDropdown',
2494
- 'dt-dropdown-button-cloned',
2495
- false,
2496
- );
2491
+ CheckboxUtils.bindTableShiftClick();
2492
+ DropdownUtils.bindDropdownOverflowHack(
2493
+ '.dt-root.dt-breakpoint-desktop tbody .dropdown',
2494
+ 'dataTableDropdown',
2495
+ 'dt-dropdown-button-cloned',
2496
+ false,
2497
+ );
2497
2498
  })();
2498
2499
 
2499
2500
  const DataTable = toNative(DataTableComponent);