@angular-generic-table/core 5.0.0-rc.15 → 5.0.0-rc.17

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 (38) hide show
  1. package/esm2020/lib/core.component.mjs +167 -57
  2. package/esm2020/lib/core.module.mjs +4 -4
  3. package/esm2020/lib/core.service.mjs +3 -3
  4. package/esm2020/lib/gt-delta/gt-delta.component.mjs +13 -13
  5. package/esm2020/lib/models/gt-pagination.mjs +1 -1
  6. package/esm2020/lib/models/table-config.interface.mjs +1 -1
  7. package/esm2020/lib/models/table-events.interface.mjs +1 -1
  8. package/esm2020/lib/models/table-info.interface.mjs +1 -1
  9. package/esm2020/lib/models/table-sort.interface.mjs +1 -1
  10. package/esm2020/lib/pagination/pagination.component.mjs +88 -29
  11. package/esm2020/lib/pagination/pagination.module.mjs +4 -4
  12. package/esm2020/lib/pipes/capital-case.pipe.mjs +3 -3
  13. package/esm2020/lib/pipes/dash-case.pipe.mjs +3 -3
  14. package/esm2020/lib/pipes/dynamic.pipe.mjs +3 -3
  15. package/esm2020/lib/pipes/highlight.pipe.mjs +3 -3
  16. package/esm2020/lib/pipes/sort-class.pipe.mjs +29 -12
  17. package/esm2020/lib/utilities/utilities.mjs +58 -1
  18. package/esm2020/public-api.mjs +8 -1
  19. package/fesm2015/angular-generic-table-core.mjs +371 -137
  20. package/fesm2015/angular-generic-table-core.mjs.map +1 -1
  21. package/fesm2020/angular-generic-table-core.mjs +372 -134
  22. package/fesm2020/angular-generic-table-core.mjs.map +1 -1
  23. package/lib/core.component.d.ts +31 -11
  24. package/lib/gt-delta/gt-delta.component.d.ts +1 -1
  25. package/lib/models/gt-pagination.d.ts +8 -0
  26. package/lib/models/table-column.interface.d.ts +1 -1
  27. package/lib/models/table-config.interface.d.ts +6 -2
  28. package/lib/models/table-events.interface.d.ts +11 -0
  29. package/lib/models/table-info.interface.d.ts +3 -1
  30. package/lib/models/table-sort.interface.d.ts +6 -4
  31. package/lib/pagination/pagination.component.d.ts +49 -11
  32. package/lib/pipes/sort-class.pipe.d.ts +2 -5
  33. package/lib/utilities/utilities.d.ts +26 -0
  34. package/package.json +3 -3
  35. package/public-api.d.ts +7 -0
  36. package/scss/index.scss +26 -4
  37. package/esm2020/lib/enums/order.enum.mjs +0 -6
  38. package/lib/enums/order.enum.d.ts +0 -4
@@ -1,27 +1,22 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Injectable, Pipe, Injector, EventEmitter, Component, ChangeDetectionStrategy, Input, Output, NgModule } from '@angular/core';
3
- import { ReplaySubject, Subject, isObservable, of, combineLatest, EMPTY, BehaviorSubject } from 'rxjs';
3
+ import { ReplaySubject, BehaviorSubject, isObservable, of, combineLatest } from 'rxjs';
4
+ import * as i1 from '@angular/common';
4
5
  import { KeyValuePipe, AsyncPipe, NgTemplateOutlet, SlicePipe, NgClass, NgIf, NgForOf, PercentPipe, CommonModule } from '@angular/common';
5
- import { debounceTime, distinctUntilChanged, tap, shareReplay, startWith, map, switchMap, withLatestFrom, take, pluck } from 'rxjs/operators';
6
+ import { debounceTime, distinctUntilChanged, tap, shareReplay, startWith, map, switchMap, withLatestFrom, take, filter, pluck } from 'rxjs/operators';
6
7
 
7
8
  class CoreService {
8
9
  constructor() { }
9
10
  }
10
- CoreService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: CoreService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
11
- CoreService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: CoreService, providedIn: 'root' });
12
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: CoreService, decorators: [{
11
+ CoreService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: CoreService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
12
+ CoreService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: CoreService, providedIn: 'root' });
13
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: CoreService, decorators: [{
13
14
  type: Injectable,
14
15
  args: [{
15
16
  providedIn: 'root',
16
17
  }]
17
18
  }], ctorParameters: function () { return []; } });
18
19
 
19
- var Order;
20
- (function (Order) {
21
- Order["ASC"] = "asc";
22
- Order["DESC"] = "desc";
23
- })(Order || (Order = {}));
24
-
25
20
  let dashed;
26
21
  dashed = (s) => s.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase());
27
22
  let capitalize;
@@ -131,6 +126,11 @@ let calculate = (data, config) => {
131
126
  Object.entries(COLUMN_CALCULATIONS).forEach(([column, calculations]) => {
132
127
  if (calculations.indexOf('avg') !== -1) {
133
128
  CALCULATED[column].avg = CALCULATED[column]?.sum / data.length;
129
+ // if sum is not part of calculations config...
130
+ if (calculations.indexOf('sum') === -1 && CALCULATED[column].sum) {
131
+ // ...remove it
132
+ delete CALCULATED[column].sum;
133
+ }
134
134
  }
135
135
  if (calculations.indexOf('count') !== -1) {
136
136
  CALCULATED[column].count = data.length;
@@ -144,15 +144,67 @@ let calculate = (data, config) => {
144
144
  calculatedColumnsCount: Object.keys(CALCULATED).length || 0,
145
145
  };
146
146
  };
147
+ /** sortOnMultipleKeys
148
+ * @description Sort data on multiple keys
149
+ * @param {GtSortOrder} keys - array with sort config objects to sort on, data will be sorted according to array order
150
+ * @returns sort function
151
+ */
152
+ const sortOnMultipleKeys = (keys) => {
153
+ const order = keys.map((key) => (key.order === 'desc' ? -1 : 1));
154
+ return (a, b) => {
155
+ for (let i = 0; i < keys.length; i++) {
156
+ const o = keys[i].key;
157
+ if (a[o] > b[o])
158
+ return order[i];
159
+ if (a[o] < b[o])
160
+ return -order[i];
161
+ }
162
+ return 0;
163
+ };
164
+ };
165
+ /** parseSortOrderParams
166
+ * @description Convert sort order query param to array with sort config objects
167
+ * @param sortParams - Query param string where each sort config object is separated by comma and order is indicated by + (ascending) or - (descending), e.g. _'name,-age'_
168
+ * @returns GtSortOrder - Array with sort config objects
169
+ */
170
+ const parseSortOrderParams = (sortParams) => {
171
+ const sortParamsArray = sortParams.split(',');
172
+ return sortParamsArray.map((sortParam) => {
173
+ const [key, order] = sortParam.split(':');
174
+ return {
175
+ key: key.replace(/^[+-]/, ''),
176
+ order: order === 'desc' ? 'desc' : 'asc',
177
+ };
178
+ });
179
+ };
180
+ /** sortOrderConfigToParam
181
+ * @description Convert sort config object to string that can be used as query param when sorting is implemented server side
182
+ * @param sortConfig - Sort config object
183
+ * @returns string - Query param string where order is indicated by + (ascending) or - (descending), e.g. _'-name'_
184
+ */
185
+ const sortOrderConfigToParam = (sortConfig) => {
186
+ const order = sortConfig.order === 'desc' ? '-' : '+';
187
+ return `${order}${sortConfig.key}`;
188
+ };
189
+ /** sortOrderToParams
190
+ * @description Convert sort order array to string that can be used as query param when sorting is implemented server side
191
+ * @param sortOrder - Array with sort config objects
192
+ * @returns string - Query param string where each sort config object is separated by comma and order is indicated by + (ascending) or - (descending), e.g. _'name,-age'_
193
+ */
194
+ const sortOrderToParams = (sortOrder) => {
195
+ return sortOrder
196
+ .map((sortConfig) => sortOrderConfigToParam(sortConfig))
197
+ .join(',');
198
+ };
147
199
 
148
200
  class CapitalCasePipe {
149
201
  transform(s) {
150
202
  return capitalize(s);
151
203
  }
152
204
  }
153
- CapitalCasePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: CapitalCasePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
154
- CapitalCasePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.2.8", ngImport: i0, type: CapitalCasePipe, isStandalone: true, name: "capitalCase" });
155
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: CapitalCasePipe, decorators: [{
205
+ CapitalCasePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: CapitalCasePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
206
+ CapitalCasePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.1.1", ngImport: i0, type: CapitalCasePipe, isStandalone: true, name: "capitalCase" });
207
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: CapitalCasePipe, decorators: [{
156
208
  type: Pipe,
157
209
  args: [{
158
210
  name: 'capitalCase',
@@ -161,19 +213,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImpor
161
213
  }] });
162
214
 
163
215
  class SortClassPipe {
164
- transform(selection, property, aria = false) {
165
- return selection?.sortBy === property
166
- ? !aria
167
- ? 'gt-sort-' + selection.sortByOrder
168
- : selection.sortByOrder + 'ending'
169
- : !aria
170
- ? ''
171
- : null;
216
+ transform(sortOrder, key, context = 'class') {
217
+ const sortIndex = sortOrder
218
+ ? sortOrder.findIndex((s) => s.key === key)
219
+ : -1;
220
+ if (context === 'aria') {
221
+ if (sortIndex === -1 || !sortOrder) {
222
+ return null;
223
+ }
224
+ else {
225
+ return `${sortOrder[sortIndex].order}ending`;
226
+ }
227
+ }
228
+ else if (context === 'class') {
229
+ if (sortIndex === -1 || !sortOrder) {
230
+ return '';
231
+ }
232
+ else {
233
+ return `gt-sort-${sortOrder[sortIndex].order}`;
234
+ }
235
+ }
236
+ else {
237
+ return (sortOrder && sortOrder?.length === 1) || sortIndex < 0
238
+ ? null
239
+ : sortIndex + 1 + '';
240
+ }
172
241
  }
173
242
  }
174
- SortClassPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: SortClassPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
175
- SortClassPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.2.8", ngImport: i0, type: SortClassPipe, isStandalone: true, name: "sortClass" });
176
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: SortClassPipe, decorators: [{
243
+ SortClassPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: SortClassPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
244
+ SortClassPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.1.1", ngImport: i0, type: SortClassPipe, isStandalone: true, name: "sortClass" });
245
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: SortClassPipe, decorators: [{
177
246
  type: Pipe,
178
247
  args: [{
179
248
  name: 'sortClass',
@@ -186,9 +255,9 @@ class DashCasePipe {
186
255
  return dashed(s);
187
256
  }
188
257
  }
189
- DashCasePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: DashCasePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
190
- DashCasePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.2.8", ngImport: i0, type: DashCasePipe, isStandalone: true, name: "dashCase" });
191
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: DashCasePipe, decorators: [{
258
+ DashCasePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: DashCasePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
259
+ DashCasePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.1.1", ngImport: i0, type: DashCasePipe, isStandalone: true, name: "dashCase" });
260
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: DashCasePipe, decorators: [{
192
261
  type: Pipe,
193
262
  args: [{
194
263
  name: 'dashCase',
@@ -210,9 +279,9 @@ class DynamicPipe {
210
279
  return pipe.transform(value, ...(pipeArgs || []));
211
280
  }
212
281
  }
213
- DynamicPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: DynamicPipe, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Pipe });
214
- DynamicPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.2.8", ngImport: i0, type: DynamicPipe, isStandalone: true, name: "dynamicPipe" });
215
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: DynamicPipe, decorators: [{
282
+ DynamicPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: DynamicPipe, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Pipe });
283
+ DynamicPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.1.1", ngImport: i0, type: DynamicPipe, isStandalone: true, name: "dynamicPipe" });
284
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: DynamicPipe, decorators: [{
216
285
  type: Pipe,
217
286
  args: [{
218
287
  name: 'dynamicPipe',
@@ -257,9 +326,9 @@ class HighlightPipe {
257
326
  return highlightedText;
258
327
  }
259
328
  }
260
- HighlightPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: HighlightPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
261
- HighlightPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.2.8", ngImport: i0, type: HighlightPipe, isStandalone: true, name: "highlight" });
262
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: HighlightPipe, decorators: [{
329
+ HighlightPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: HighlightPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
330
+ HighlightPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.1.1", ngImport: i0, type: HighlightPipe, isStandalone: true, name: "highlight" });
331
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: HighlightPipe, decorators: [{
263
332
  type: Pipe,
264
333
  args: [{
265
334
  name: 'highlight',
@@ -270,16 +339,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImpor
270
339
  class CoreComponent {
271
340
  constructor() {
272
341
  this.rowClick = new EventEmitter();
342
+ this.sortOrderChange = new EventEmitter();
273
343
  this._rowHover$ = new ReplaySubject(1);
274
344
  this.rowHover = new EventEmitter();
345
+ this.columnSort = new EventEmitter();
346
+ /** page change event - emitted when current page/index changes for pagination */
347
+ this.pageChange = new EventEmitter();
275
348
  this.rowHover$ = this._rowHover$.asObservable().pipe(debounceTime(50), distinctUntilChanged((p, q) => p.index === q.index), tap((event) => this.rowHover.emit(event)), shareReplay(1));
276
349
  this._loading$ = new ReplaySubject(1);
277
- this.sortBy$ = new Subject();
278
- // tslint:disable-next-line:variable-name
350
+ this._sortOrder$ = new BehaviorSubject([]);
279
351
  this._searchBy$ = new ReplaySubject(1);
280
352
  this.searchBy$ = this._searchBy$.pipe(startWith(''), map((value) => (isObservable(value) ? value : of(value))), switchMap((obs) => obs), shareReplay(1));
353
+ this._pagingInfo$ = new BehaviorSubject({
354
+ pageCurrent: null,
355
+ pageNext: null,
356
+ pagePrevious: null,
357
+ pageSize: null,
358
+ numberOfRecords: null,
359
+ //recordsAfterFilter: null,
360
+ //recordsAfterSearch: null,
361
+ //recordsAll: null,
362
+ });
281
363
  // tslint:disable-next-line:variable-name
282
- this._tableConfig$ = new ReplaySubject(1);
364
+ this._tableConfig$ = new BehaviorSubject({});
283
365
  this.tableConfig$ = this._tableConfig$.pipe(map((value) => (isObservable(value) ? value : of(value))), switchMap((obs) => obs), shareReplay(1));
284
366
  this._data$ = new ReplaySubject(1);
285
367
  this.data$ = this._data$.pipe(map((value) => (isObservable(value) ? value : of(value))), switchMap((obs) => combineLatest([obs])), withLatestFrom(this.tableConfig$), map(([[data], config]) => {
@@ -303,45 +385,45 @@ class CoreComponent {
303
385
  data = newData;
304
386
  }
305
387
  return { data, config };
306
- }), switchMap((obs) => combineLatest([
307
- of(obs),
308
- this.sortBy$.pipe(startWith(EMPTY)),
309
- this.searchBy$,
310
- ])), map(([table, sortBy, searchBy]) => {
388
+ }), switchMap((obs) => combineLatest([of(obs), this.sortOrder$, this.searchBy$])), map(([table, sortBy, searchBy]) => {
311
389
  // create a new array reference and sort new array (prevent mutating existing state)
312
390
  table.data = [...table.data];
313
- return !sortBy
314
- ? searchBy
391
+ return !sortBy?.length || table.config?.disableTableSort
392
+ ? searchBy && !this.tableInfo?.lazyLoaded
315
393
  ? search(searchBy, false, table.data, table.config)
316
394
  : table.data
317
- : (searchBy
318
- ? search(searchBy, false, table.data, table.config)
319
- : table.data)?.sort((a, b) => {
320
- // TODO: improve logic
321
- const typed = sortBy;
322
- return a[typed.sortBy] > b[typed.sortBy]
323
- ? typed.sortByOrder === Order.ASC
324
- ? 1
325
- : -1
326
- : b[typed.sortBy] > a[typed.sortBy]
327
- ? typed.sortByOrder === Order.ASC
328
- ? -1
329
- : 1
330
- : 0;
331
- });
395
+ : searchBy && !this.tableInfo?.lazyLoaded
396
+ ? search(searchBy, false, table.data, table.config)?.sort(sortOnMultipleKeys(sortBy))
397
+ : table.data?.sort(sortOnMultipleKeys(sortBy));
332
398
  }), shareReplay(1));
333
399
  this.calculations$ = combineLatest([this.data$, this.tableConfig$]).pipe(map(([data, config]) => calculate(data, config)), shareReplay(1));
334
400
  this.table$ = combineLatest([
335
401
  this.data$,
336
402
  this.tableConfig$,
337
- ]).pipe(map(([sorted, config]) => {
403
+ this._pagingInfo$,
404
+ ]).pipe(map(([sorted, config, pagingInfo]) => {
405
+ if (pagingInfo.pageCurrent !== null &&
406
+ pagingInfo.numberOfRecords !== null &&
407
+ pagingInfo.pageSize !== null) {
408
+ return {
409
+ data: [sorted],
410
+ config,
411
+ info: {
412
+ lazyLoaded: true,
413
+ numberOfRecords: pagingInfo.numberOfRecords,
414
+ pageSize: pagingInfo.pageSize,
415
+ pageTotal: pagingInfo.pageTotal ??
416
+ Math.ceil(pagingInfo.numberOfRecords / pagingInfo.pageSize),
417
+ },
418
+ };
419
+ }
338
420
  // if pagination is disabled...
339
421
  if (!config.pagination || config.pagination.length === 0) {
340
422
  // ...return unaltered array
341
423
  return {
342
424
  data: [sorted],
343
425
  config,
344
- info: { records: sorted.length, pageTotal: 1 },
426
+ info: { numberOfRecords: sorted.length, pageTotal: 1 },
345
427
  };
346
428
  }
347
429
  // return record set
@@ -349,19 +431,24 @@ class CoreComponent {
349
431
  data: chunk(sorted, +(config.pagination.length || 0)),
350
432
  config,
351
433
  info: {
352
- records: sorted.length,
434
+ numberOfRecords: sorted.length,
353
435
  pageTotal: Math.ceil(sorted.length / +(config.pagination.length || 0)),
354
436
  },
355
437
  };
356
- }), shareReplay(1));
357
- this._currentPage$ = new BehaviorSubject(0);
358
- this.currentPage$ = combineLatest([this._currentPage$, this.table$]).pipe(map(([page, table]) => {
438
+ }), tap((meta) => this._tableInfo$.next(meta.info)), shareReplay(1));
439
+ this._tableInfo$ = new BehaviorSubject(undefined);
440
+ this._currentPaginationIndex$ = new BehaviorSubject(0);
441
+ this.currentPaginationIndex$ = combineLatest([
442
+ this._currentPaginationIndex$,
443
+ this.table$,
444
+ ]).pipe(map(([page, table]) => {
359
445
  // determine last page
360
446
  const lastPage = Math.ceil(table.info.records /
361
- (table.config?.pagination?.length || table.info.records)) - 1;
362
- // determine max/min position
447
+ (table.info.recordLength ??
448
+ (table.config?.pagination?.length || table.info.records))) - 1;
449
+ // determine min/max position
363
450
  return +page < 0 ? 0 : +page > lastPage ? lastPage : +page;
364
- }), shareReplay(1));
451
+ }), distinctUntilChanged(), tap((index) => this.pageChange.emit({ index })), shareReplay(1));
365
452
  this.colspan$ = this.tableConfig$.pipe(switchMap((config) => config.columns
366
453
  ? of(Object.values(config.columns || config.rows || {}).filter((value) => value.hidden !== true).length)
367
454
  : this.data$.pipe(map((data) => data.length + 1))), shareReplay(1));
@@ -379,11 +466,23 @@ class CoreComponent {
379
466
  return (a.value.order || 0) - (b.value.order || 0);
380
467
  };
381
468
  }
469
+ get sortOrder$() {
470
+ return this._sortOrder$.asObservable();
471
+ }
382
472
  set loading(isLoading) {
383
473
  this._loading$.next(isLoading);
384
474
  }
385
- set page(page) {
386
- this._currentPage$.next(page);
475
+ set paginationIndex(pageIndex) {
476
+ this._currentPaginationIndex$.next(pageIndex);
477
+ }
478
+ set pagingInfo(value) {
479
+ if (value) {
480
+ this._pagingInfo$.next(value);
481
+ if (value.pageCurrent !== this._currentPaginationIndex$.getValue() + 1 &&
482
+ value.pageCurrent !== null) {
483
+ this.paginationIndex = value.pageCurrent - 1;
484
+ }
485
+ }
387
486
  }
388
487
  set search(string) {
389
488
  this._searchBy$.next(string);
@@ -394,6 +493,12 @@ class CoreComponent {
394
493
  set data(data) {
395
494
  this._data$.next(data);
396
495
  }
496
+ set sortOrder(sortConfig) {
497
+ if (JSON.stringify(sortConfig) !== JSON.stringify(this._sortOrder$.value)) {
498
+ this.sortOrderChange.emit(sortConfig);
499
+ this._sortOrder$.next(sortConfig);
500
+ }
501
+ }
397
502
  _rowClick(row, index, event) {
398
503
  this.rowClick.emit({ row, index, event });
399
504
  }
@@ -416,18 +521,83 @@ class CoreComponent {
416
521
  get loading$() {
417
522
  return this._loading$.pipe(startWith(false), map((value) => (isObservable(value) ? value : of(value))), switchMap((obs) => obs), shareReplay(1));
418
523
  }
419
- sort(property) {
420
- const newSortOrder = this._sortBy?.sortBy !== property ||
421
- this._sortBy?.sortByOrder === Order.DESC ||
422
- !this._sortBy.sortByOrder
423
- ? Order.ASC
424
- : Order.DESC;
425
- const newSortBy = {
426
- sortBy: property,
427
- sortByOrder: newSortOrder,
524
+ /** tableInfo$ - returns observable for table info
525
+ * @return Observable<TableInfo> */
526
+ get tableInfo$() {
527
+ return this._tableInfo$.asObservable().pipe(filter((info) => !!info), shareReplay(1));
528
+ }
529
+ /** tableInfo - returns the current table info
530
+ * @return TableInfo */
531
+ get tableInfo() {
532
+ return this._tableInfo$.getValue();
533
+ }
534
+ /** sortByKey - Sort by key in table row
535
+ * @param key - key to sort by
536
+ * @param { MouseEvent } [$event] - Mouse event triggering sort, if shift key is pressed sort key will be added to already present sort keys
537
+ */
538
+ sortByKey(key, $event) {
539
+ const shiftKey = $event?.shiftKey === true;
540
+ const currentOrder = this._sortOrder$.value;
541
+ let sortOrder = 'asc';
542
+ let newOrder = [];
543
+ // if shift key is pressed while sorting...
544
+ if (shiftKey) {
545
+ // ...check if key is already sorted
546
+ const existingSortPosition = currentOrder.findIndex((value) => value.key === key);
547
+ if (existingSortPosition === -1) {
548
+ // ...if key is not sorted, add it to the end of the sort order
549
+ newOrder = [...currentOrder, { key, order: 'asc' }];
550
+ }
551
+ else {
552
+ // ...if key is already sorted, toggle sort order
553
+ sortOrder = currentOrder[existingSortPosition].order;
554
+ const newSortOrder = sortOrder === 'asc' ? 'desc' : 'asc';
555
+ newOrder = [...currentOrder];
556
+ newOrder[existingSortPosition] = {
557
+ ...newOrder[existingSortPosition],
558
+ order: newSortOrder,
559
+ };
560
+ }
561
+ }
562
+ else {
563
+ // ...else if shift key is not pressed...
564
+ if (currentOrder.length > 0) {
565
+ // ...check if key is already sorted
566
+ const existingSortPosition = currentOrder.findIndex((value) => value.key === key);
567
+ // ...if key is already sorted, toggle sort order
568
+ if (existingSortPosition === -1) {
569
+ newOrder = [{ key, order: 'asc' }];
570
+ }
571
+ else {
572
+ sortOrder = currentOrder[existingSortPosition].order;
573
+ const newSortOrder = sortOrder === 'asc' ? 'desc' : 'asc';
574
+ newOrder = [{ key, order: newSortOrder }];
575
+ }
576
+ }
577
+ else {
578
+ // ...if key is not sorted set sort order for key to ascending
579
+ newOrder = [{ key, order: sortOrder }];
580
+ }
581
+ }
582
+ // create sort event
583
+ const sortEvent = {
584
+ key,
585
+ order: sortOrder,
586
+ currentSortOrder: newOrder,
587
+ addSortKey: shiftKey,
428
588
  };
429
- this.sortBy$.next(newSortBy);
430
- this._sortBy = newSortBy;
589
+ // if event is passed to sort function...
590
+ if ($event) {
591
+ // ...emit it as well
592
+ sortEvent.event = $event;
593
+ }
594
+ // emit sort event
595
+ this.columnSort.emit(sortEvent);
596
+ // if table is not lazy loaded (sorting is then handled server-side)...
597
+ if (!this.tableInfo?.lazyLoaded) {
598
+ // ...update sort order
599
+ this.sortOrder = newOrder;
600
+ }
431
601
  }
432
602
  nestedValue(object, mapTo, missingValue = null) {
433
603
  const levels = mapTo.split('.');
@@ -435,9 +605,9 @@ class CoreComponent {
435
605
  (index === levels.length - 1 ? missingValue : {}), object);
436
606
  }
437
607
  }
438
- CoreComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: CoreComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
439
- CoreComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.8", type: CoreComponent, isStandalone: true, selector: "angular-generic-table", inputs: { loading: "loading", page: "page", search: "search", config: "config", data: "data" }, outputs: { rowClick: "rowClick", rowHover: "rowHover" }, ngImport: i0, template: "<table\n [ngClass]=\"(tableConfig$ | async)?.class || 'table'\"\n [class.table-mobile]=\"(tableConfig$ | async)?.mobileLayout\"\n [class.table-horizontal]=\"(tableConfig$ | async)?.rows\"\n [class.table-loading]=\"loading$ | async\"\n [class.gt-sticky-row-header]=\"\n (tableConfig$ | async)?.stickyHeaders?.row && (tableConfig$ | async)?.rows\n \"\n [class.gt-sticky-column-header]=\"\n (tableConfig$ | async)?.stickyHeaders?.column\n \"\n [attr.aria-busy]=\"(loading$ | async) === true ? true : null\"\n>\n <thead>\n <tr\n *ngIf=\"{\n config: (tableConfig$ | async)!,\n isLoading: loading$ | async\n } as table\"\n >\n <ng-container\n *ngFor=\"let column of table.config?.columns | keyvalue: columnOrder\"\n >\n <th\n *ngIf=\"!column.value?.hidden\"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [class.disabled]=\"table.isLoading\"\n [attr.aria-sort]=\"sortBy$ | async | sortClass: column.key:true\"\n [class.gt-sortable]=\"true\"\n scope=\"col\"\n >\n <button\n *ngIf=\"column.value?.sortable\"\n class=\"gt-sort\"\n (click)=\"\n table.isLoading || !column.value.sortable || sort(column.key)\n \"\n >\n <span *ngIf=\"column.value?.header !== false\">{{\n column.value.header || column.key | capitalCase\n }}</span>\n </button>\n <span\n *ngIf=\"!column.value?.sortable && column.value?.header !== false\"\n >{{ column.value.header || column.key | capitalCase }}</span\n >\n </th>\n </ng-container>\n <ng-container\n *ngIf=\"\n ((table?.config?.rows | keyvalue: columnOrder) || [])[0] as headerRow\n \"\n >\n <th\n class=\"row-header\"\n [attr.aria-sort]=\"sortBy$ | async | sortClass: headerRow.key:true\"\n ngClass=\"{{ headerRow.value.sortable ? 'sort ' : '' }} {{\n sortBy$ | async | sortClass: headerRow.key\n }} {{ (headerRow.key | dashCase) + '-column' }}\"\n (click)=\"\n table.isLoading || !headerRow.value.sortable || sort(headerRow.key)\n \"\n scope=\"col\"\n >\n <ng-container *ngIf=\"headerRow?.value?.header !== false\">{{\n headerRow?.value?.header || headerRow.key | capitalCase\n }}</ng-container>\n </th>\n <th\n *ngFor=\"let column of ((table$ | async)?.data || [])[0]\"\n ngClass=\"{{ headerRow.value.class }}\"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.rows || {})[headerRow.key].templateRef\n ? templateRef\n : (table.config.rows || {})[headerRow.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: column,\n column: headerRow,\n transform: (table.config.rows || {})[headerRow.key].transform,\n templateRef: (table.config.rows || {})[headerRow.key].templateRef,\n index: 0\n }\"\n >\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody *ngIf=\"loading$ | async; else tableContent\">\n <tr>\n <td class=\"p-0\" [colSpan]=\"colspan$ | async\">\n <ng-content select=\".table-loading\"></ng-content>\n </td>\n </tr>\n </tbody>\n <tfoot *ngIf=\"(table$ | async)! as table\">\n <ng-container *ngIf=\"table.data.length > 0 && !(loading$ | async)\">\n <ng-container *ngIf=\"(calculations$ | async)! as calculations\">\n <tr\n *ngFor=\"let calculation of calculations.calculations; let i = index\"\n >\n <ng-container\n *ngIf=\"{\n showHeader: (colspan$ | async) !== (footerColspan$ | async)\n } as footerRow\"\n >\n <th\n *ngIf=\"footerRow.showHeader\"\n [colSpan]=\"\n ((colspan$ | async) || 0) - ((footerColspan$ | async) || 0)\n \"\n scope=\"row\"\n >\n <ng-container\n *ngIf=\"table.config?.footer?.headers?.[calculation] as showHeader\"\n >{{showHeader === true ? (calculation | capitalCase): table.config.footer?.headers?.[calculation]}}\n </ng-container>\n </th>\n <ng-container\n *ngFor=\"\n let column of table.config?.columns | keyvalue: columnOrder\n \"\n >\n <td\n *ngIf=\"\n !column.value?.hidden && calculations.calculated[column.key]\n \"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [attr.data-header]=\"\n !footerRow.showHeader && table.config.footer?.headers?.[calculation]\n ? table.config.footer?.headers?.[calculation] === true ? (calculation | capitalCase) : table.config.footer?.headers?.[calculation]\n : null\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.columns || {})[column.key].transform\n ? transformFooter\n : rawFooter\n \"\n [ngTemplateOutletContext]=\"{\n value: calculations.calculated[column.key][calculation],\n transform: (table.config.columns || {})[column.key]\n .transform\n }\"\n ></ng-container>\n </td>\n </ng-container>\n </ng-container>\n </tr>\n </ng-container>\n </ng-container>\n </tfoot>\n</table>\n<ng-template #tableContent>\n <ng-container *ngIf=\"(table$ | async)! as table\">\n <tbody *ngIf=\"(table!.data![0] || table!.data!).length > 0; else noData\">\n <ng-container *ngIf=\"table.config.columns\">\n <tr\n *ngFor=\"\n let row of table!.data![(currentPage$ | async) || 0];\n let i = index\n \"\n [attr.id]=\"'tableRow_' + i\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseover)=\"table?.config?.rowHover && _hoverRow(row, i, $event)\"\n (mouseout)=\"table?.config?.rowHover && _hoverRow(null, null, $event)\"\n [class.gt-hover]=\"(rowHover$ | async)?.index === i\"\n >\n <ng-container\n *ngFor=\"let column of table.config?.columns | keyvalue: columnOrder\"\n >\n <td\n *ngIf=\"!column.value?.hidden\"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [attr.data-label]=\"\n table.config.mobileLayout && column.value.mobileHeader\n ? column.value.mobileHeader !== true\n ? column.value.mobileHeader\n : (column.value.header || column.key | capitalCase)\n : null\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (searchBy$ | async) &&\n !(table.config.columns || {})[column.key].templateRef\n ? highlighted\n : (table.config.columns || {})[column.key].templateRef\n ? templateRef\n : (table.config.columns || {})[column.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: row,\n column: column,\n search: (searchBy$ | async),\n transform: (table.config.columns || {})[column.key].transform,\n templateRef: (table.config.columns || {})[column.key]\n .templateRef,\n index: i,\n data: table.data[(currentPage$ | async) || 0]\n }\"\n ></ng-container>\n </td>\n </ng-container>\n </tr>\n </ng-container>\n <ng-container *ngIf=\"table.config.rows\">\n <ng-container\n *ngFor=\"\n let row of table?.config?.rows | keyvalue: columnOrder | slice: 1;\n let i = index\n \"\n >\n <tr\n *ngIf=\"!row.value?.hidden\"\n [attr.id]=\"'tableRow_' + i\"\n ngClass=\"{{ (row.key | dashCase) + '-row' }}\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseover)=\"table?.config?.rowHover && _hoverRow(row, i, $event)\"\n (mouseout)=\"\n table?.config?.rowHover && _hoverRow(null, null, $event)\n \"\n [class.gt-hover]=\"(rowHover$ | async)?.index === i\"\n >\n <th class=\"row-header\" scope=\"row\">\n {{ row.value.header || row.key | capitalCase }}\n </th>\n <td\n *ngFor=\"let column of (table?.data || [])[0]; let y = index\"\n ngClass=\"{{ row.value.class }}\"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.rows || {})[row.key].templateRef\n ? templateRef\n : (table.config.rows || {})[row.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: column,\n column: row,\n transform: (table.config.rows || {})[row.key].transform,\n templateRef: (table.config.rows || {})[row.key].templateRef,\n index: table.config.rows ? y : i,\n data: table.data[(currentPage$ | async) || 0]\n }\"\n >\n </ng-container>\n </td>\n </tr>\n </ng-container>\n </ng-container>\n </tbody>\n </ng-container>\n</ng-template>\n<ng-template #noData>\n <tbody>\n <tr>\n <td class=\"p-0\" [colSpan]=\"colspan$ | async\">\n <ng-content select=\".table-no-data\"></ng-content>\n </td>\n </tr>\n </tbody>\n</ng-template>\n<ng-template\n #highlighted\n let-row=\"row\"\n let-column=\"column\"\n let-search=\"search\"\n let-transform=\"transform\"\n>\n <div\n *ngIf=\"!transform\"\n [innerHTML]=\"row[column.key] | highlight: search\"\n ></div>\n <div\n *ngIf=\"transform\"\n [innerHTML]=\"\n row[column.key]\n | dynamicPipe: transform.pipe:transform?.args\n | highlight: search\n \"\n ></div>\n</ng-template>\n<ng-template #rawData let-row=\"row\" let-column=\"column\">\n {{ row[column.key] }}\n</ng-template>\n<ng-template\n #transformData\n let-row=\"row\"\n let-column=\"column\"\n let-transform=\"transform\"\n let-data=\"data\"\n>\n {{ row[column.key] | dynamicPipe: transform.pipe:transform?.args }}\n</ng-template>\n<ng-template #transformFooter let-value=\"value\" let-transform=\"transform\">\n {{\n (value | dynamicPipe: transform.pipe:transform?.args) ||\n (tableConfig$ | async)?.footer?.emptyContent\n }}\n</ng-template>\n<ng-template #rawFooter let-value=\"value\">\n {{ value || (tableConfig$ | async)?.footer?.emptyContent }}\n</ng-template>\n<ng-template\n #templateRef\n let-row=\"row\"\n let-column=\"column\"\n let-index=\"index\"\n let-templateRef=\"templateRef\"\n let-data=\"data\"\n>\n <ng-container\n [ngTemplateOutlet]=\"templateRef\"\n [ngTemplateOutletContext]=\"{\n row: row,\n col: column,\n index: index,\n data: data\n }\"\n ></ng-container>\n</ng-template>\n", dependencies: [{ kind: "pipe", type: CapitalCasePipe, name: "capitalCase" }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: SortClassPipe, name: "sortClass" }, { kind: "pipe", type: DashCasePipe, name: "dashCase" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: SlicePipe, name: "slice" }, { kind: "pipe", type: DynamicPipe, name: "dynamicPipe" }, { kind: "pipe", type: HighlightPipe, name: "highlight" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
440
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: CoreComponent, decorators: [{
608
+ CoreComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: CoreComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
609
+ CoreComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.1", type: CoreComponent, isStandalone: true, selector: "angular-generic-table", inputs: { loading: "loading", paginationIndex: "paginationIndex", pagingInfo: "pagingInfo", search: "search", config: "config", data: "data", sortOrder: "sortOrder" }, outputs: { rowClick: "rowClick", sortOrderChange: "sortOrderChange", rowHover: "rowHover", columnSort: "columnSort", pageChange: "pageChange" }, ngImport: i0, template: "<table\n [ngClass]=\"(tableConfig$ | async)?.class || 'table'\"\n [class.table-mobile]=\"(tableConfig$ | async)?.mobileLayout\"\n [class.table-horizontal]=\"(tableConfig$ | async)?.rows\"\n [class.table-loading]=\"loading$ | async\"\n [class.gt-sticky-row-header]=\"\n (tableConfig$ | async)?.stickyHeaders?.row && (tableConfig$ | async)?.rows\n \"\n [class.gt-sticky-column-header]=\"\n (tableConfig$ | async)?.stickyHeaders?.column\n \"\n [attr.aria-busy]=\"(loading$ | async) === true ? true : null\"\n>\n <thead>\n <tr\n *ngIf=\"{\n config: (tableConfig$ | async)!,\n isLoading: loading$ | async\n } as table\"\n >\n <ng-container\n *ngFor=\"let column of table.config?.columns | keyvalue: columnOrder\"\n >\n <th\n *ngIf=\"!column.value?.hidden\"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [class.disabled]=\"table.isLoading\"\n [attr.aria-sort]=\"sortOrder$ | async | sortClass: column.key:'aria'\"\n [class.gt-sortable]=\"true\"\n scope=\"col\"\n >\n <button\n *ngIf=\"column.value?.sortable\"\n [attr.data-sort-order]=\"\n sortOrder$ | async | sortClass: column.key:'order'\n \"\n class=\"gt-sort\"\n (click)=\"\n table.isLoading ||\n !column.value.sortable ||\n sortByKey(column.key, $event)\n \"\n >\n <span *ngIf=\"column.value?.header !== false\">{{\n column.value.header || column.key | capitalCase\n }}</span>\n </button>\n <span\n *ngIf=\"!column.value?.sortable && column.value?.header !== false\"\n >{{ column.value.header || column.key | capitalCase }}</span\n >\n </th>\n </ng-container>\n <ng-container\n *ngIf=\"\n ((table?.config?.rows | keyvalue: columnOrder) || [])[0] as headerRow\n \"\n >\n <th\n class=\"row-header\"\n [attr.aria-sort]=\"\n sortOrder$ | async | sortClass: headerRow.key:'aria'\n \"\n ngClass=\"{{ headerRow.value.sortable ? 'sort ' : '' }} {{\n sortOrder$ | async | sortClass: headerRow.key\n }} {{ (headerRow.key | dashCase) + '-column' }}\"\n (click)=\"\n table.isLoading ||\n !headerRow.value.sortable ||\n sortByKey(headerRow.key, $event)\n \"\n scope=\"col\"\n >\n <ng-container *ngIf=\"headerRow?.value?.header !== false\">{{\n headerRow?.value?.header || headerRow.key | capitalCase\n }}</ng-container>\n </th>\n <th\n *ngFor=\"let column of ((table$ | async)?.data || [])[0]\"\n ngClass=\"{{ headerRow.value.class }}\"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.rows || {})[headerRow.key].templateRef\n ? templateRef\n : (table.config.rows || {})[headerRow.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: column,\n column: headerRow,\n transform: (table.config.rows || {})[headerRow.key].transform,\n templateRef: (table.config.rows || {})[headerRow.key].templateRef,\n index: 0\n }\"\n >\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody *ngIf=\"loading$ | async; else tableContent\">\n <tr>\n <td class=\"p-0\" [colSpan]=\"colspan$ | async\">\n <ng-content select=\".table-loading\"></ng-content>\n </td>\n </tr>\n </tbody>\n <tfoot *ngIf=\"(table$ | async)! as table\">\n <ng-container *ngIf=\"table.data.length > 0 && !(loading$ | async)\">\n <ng-container *ngIf=\"(calculations$ | async)! as calculations\">\n <tr\n *ngFor=\"let calculation of calculations.calculations; let i = index\"\n >\n <ng-container\n *ngIf=\"{\n showHeader: (colspan$ | async) !== (footerColspan$ | async)\n } as footerRow\"\n >\n <th\n *ngIf=\"footerRow.showHeader\"\n [colSpan]=\"\n ((colspan$ | async) || 0) - ((footerColspan$ | async) || 0)\n \"\n scope=\"row\"\n >\n <ng-container\n *ngIf=\"table.config?.footer?.headers?.[calculation] as showHeader\"\n >{{showHeader === true ? (calculation | capitalCase): table.config.footer?.headers?.[calculation]}}\n </ng-container>\n </th>\n <ng-container\n *ngFor=\"\n let column of table.config?.columns | keyvalue: columnOrder\n \"\n >\n <td\n *ngIf=\"\n !column.value?.hidden && calculations.calculated[column.key]\n \"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [attr.data-header]=\"\n !footerRow.showHeader && table.config.footer?.headers?.[calculation]\n ? table.config.footer?.headers?.[calculation] === true ? (calculation | capitalCase) : table.config.footer?.headers?.[calculation]\n : null\n \"\n [attr.data-label]=\"\n table.config.mobileLayout && column.value.mobileHeader\n ? column.value.mobileHeader !== true\n ? column.value.mobileHeader\n : (column.value.header || column.key | capitalCase)\n : null\n \"\n [class.gt-no-content]=\"\n !calculations.calculated[column.key][calculation]\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.columns || {})[column.key].templateRef\n ? templateRef\n : (table.config.columns || {})[column.key].transform\n ? transformFooter\n : rawFooter\n \"\n [ngTemplateOutletContext]=\"{\n value: calculations.calculated[column.key][calculation],\n row: calculations.calculated[column.key],\n column: calculation,\n templateRef: (table.config.columns || {})[column.key]\n .templateRef,\n transform: (table.config.columns || {})[column.key]\n .transform\n }\"\n ></ng-container>\n </td>\n </ng-container>\n </ng-container>\n </tr>\n </ng-container>\n </ng-container>\n </tfoot>\n</table>\n<ng-template #tableContent>\n <ng-container *ngIf=\"(table$ | async)! as table\">\n <tbody *ngIf=\"(table!.data![0] || table!.data!).length > 0; else noData\">\n <ng-container *ngIf=\"table.config.columns\">\n <tr\n *ngFor=\"\n let row of table!.data![\n table.info.lazyLoaded ? 0 : (currentPaginationIndex$ | async) || 0\n ];\n let i = index\n \"\n [attr.id]=\"'tableRow_' + i\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseover)=\"table?.config?.rowHover && _hoverRow(row, i, $event)\"\n (mouseout)=\"table?.config?.rowHover && _hoverRow(null, null, $event)\"\n [class.gt-hover]=\"(rowHover$ | async)?.index === i\"\n >\n <ng-container\n *ngFor=\"let column of table.config?.columns | keyvalue: columnOrder\"\n >\n <td\n *ngIf=\"!column.value?.hidden\"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [attr.data-label]=\"\n table.config.mobileLayout && column.value.mobileHeader\n ? column.value.mobileHeader !== true\n ? column.value.mobileHeader\n : (column.value.header || column.key | capitalCase)\n : null\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (searchBy$ | async) &&\n !(table.config.columns || {})[column.key].templateRef\n ? highlighted\n : (table.config.columns || {})[column.key].templateRef\n ? templateRef\n : (table.config.columns || {})[column.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: row,\n column: column,\n search: (searchBy$ | async),\n transform: (table.config.columns || {})[column.key].transform,\n templateRef: (table.config.columns || {})[column.key]\n .templateRef,\n index: i,\n data: table.data[\n table.info.lazyLoaded\n ? 0\n : (currentPaginationIndex$ | async) || 0\n ]\n }\"\n ></ng-container>\n </td>\n </ng-container>\n </tr>\n </ng-container>\n <ng-container *ngIf=\"table.config.rows\">\n <ng-container\n *ngFor=\"\n let row of table?.config?.rows | keyvalue: columnOrder | slice: 1;\n let i = index\n \"\n >\n <tr\n *ngIf=\"!row.value?.hidden\"\n [attr.id]=\"'tableRow_' + i\"\n ngClass=\"{{ (row.key | dashCase) + '-row' }}\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseover)=\"table?.config?.rowHover && _hoverRow(row, i, $event)\"\n (mouseout)=\"\n table?.config?.rowHover && _hoverRow(null, null, $event)\n \"\n [class.gt-hover]=\"(rowHover$ | async)?.index === i\"\n >\n <th class=\"row-header\" scope=\"row\">\n {{ row.value.header || row.key | capitalCase }}\n </th>\n <td\n *ngFor=\"let column of (table?.data || [])[0]; let y = index\"\n ngClass=\"{{ row.value.class }}\"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.rows || {})[row.key].templateRef\n ? templateRef\n : (table.config.rows || {})[row.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: column,\n column: row,\n transform: (table.config.rows || {})[row.key].transform,\n templateRef: (table.config.rows || {})[row.key].templateRef,\n index: table.config.rows ? y : i,\n data: table.data[\n table.info.lazyLoaded\n ? 0\n : (currentPaginationIndex$ | async) || 0\n ]\n }\"\n >\n </ng-container>\n </td>\n </tr>\n </ng-container>\n </ng-container>\n </tbody>\n </ng-container>\n</ng-template>\n<ng-template #noData>\n <tbody>\n <tr>\n <td class=\"p-0\" [colSpan]=\"colspan$ | async\">\n <ng-content select=\".table-no-data\"></ng-content>\n </td>\n </tr>\n </tbody>\n</ng-template>\n<ng-template\n #highlighted\n let-row=\"row\"\n let-column=\"column\"\n let-search=\"search\"\n let-transform=\"transform\"\n>\n <div\n *ngIf=\"!transform\"\n [innerHTML]=\"row[column.key] | highlight: search\"\n ></div>\n <div\n *ngIf=\"transform\"\n [innerHTML]=\"\n row[column.key]\n | dynamicPipe: transform.pipe:transform?.args\n | highlight: search\n \"\n ></div>\n</ng-template>\n<ng-template #rawData let-row=\"row\" let-column=\"column\">\n {{ row[column.key] }}\n</ng-template>\n<ng-template\n #transformData\n let-row=\"row\"\n let-column=\"column\"\n let-transform=\"transform\"\n let-data=\"data\"\n>\n {{ row[column.key] | dynamicPipe: transform.pipe:transform?.args }}\n</ng-template>\n<ng-template #transformFooter let-value=\"value\" let-transform=\"transform\">\n {{\n (value | dynamicPipe: transform.pipe:transform?.args) ||\n (tableConfig$ | async)?.footer?.emptyContent\n }}\n</ng-template>\n<ng-template #rawFooter let-value=\"value\">\n {{ value || (tableConfig$ | async)?.footer?.emptyContent }}\n</ng-template>\n<ng-template\n #templateRef\n let-row=\"row\"\n let-column=\"column\"\n let-index=\"index\"\n let-templateRef=\"templateRef\"\n let-data=\"data\"\n>\n <ng-container\n [ngTemplateOutlet]=\"templateRef\"\n [ngTemplateOutletContext]=\"{\n row: row,\n col: column,\n index: index,\n data: data\n }\"\n ></ng-container>\n</ng-template>\n", dependencies: [{ kind: "pipe", type: CapitalCasePipe, name: "capitalCase" }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: SortClassPipe, name: "sortClass" }, { kind: "pipe", type: DashCasePipe, name: "dashCase" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: SlicePipe, name: "slice" }, { kind: "pipe", type: DynamicPipe, name: "dynamicPipe" }, { kind: "pipe", type: HighlightPipe, name: "highlight" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
610
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: CoreComponent, decorators: [{
441
611
  type: Component,
442
612
  args: [{ selector: 'angular-generic-table', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
443
613
  CapitalCasePipe,
@@ -452,10 +622,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImpor
452
622
  NgClass,
453
623
  NgIf,
454
624
  NgForOf,
455
- ], template: "<table\n [ngClass]=\"(tableConfig$ | async)?.class || 'table'\"\n [class.table-mobile]=\"(tableConfig$ | async)?.mobileLayout\"\n [class.table-horizontal]=\"(tableConfig$ | async)?.rows\"\n [class.table-loading]=\"loading$ | async\"\n [class.gt-sticky-row-header]=\"\n (tableConfig$ | async)?.stickyHeaders?.row && (tableConfig$ | async)?.rows\n \"\n [class.gt-sticky-column-header]=\"\n (tableConfig$ | async)?.stickyHeaders?.column\n \"\n [attr.aria-busy]=\"(loading$ | async) === true ? true : null\"\n>\n <thead>\n <tr\n *ngIf=\"{\n config: (tableConfig$ | async)!,\n isLoading: loading$ | async\n } as table\"\n >\n <ng-container\n *ngFor=\"let column of table.config?.columns | keyvalue: columnOrder\"\n >\n <th\n *ngIf=\"!column.value?.hidden\"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [class.disabled]=\"table.isLoading\"\n [attr.aria-sort]=\"sortBy$ | async | sortClass: column.key:true\"\n [class.gt-sortable]=\"true\"\n scope=\"col\"\n >\n <button\n *ngIf=\"column.value?.sortable\"\n class=\"gt-sort\"\n (click)=\"\n table.isLoading || !column.value.sortable || sort(column.key)\n \"\n >\n <span *ngIf=\"column.value?.header !== false\">{{\n column.value.header || column.key | capitalCase\n }}</span>\n </button>\n <span\n *ngIf=\"!column.value?.sortable && column.value?.header !== false\"\n >{{ column.value.header || column.key | capitalCase }}</span\n >\n </th>\n </ng-container>\n <ng-container\n *ngIf=\"\n ((table?.config?.rows | keyvalue: columnOrder) || [])[0] as headerRow\n \"\n >\n <th\n class=\"row-header\"\n [attr.aria-sort]=\"sortBy$ | async | sortClass: headerRow.key:true\"\n ngClass=\"{{ headerRow.value.sortable ? 'sort ' : '' }} {{\n sortBy$ | async | sortClass: headerRow.key\n }} {{ (headerRow.key | dashCase) + '-column' }}\"\n (click)=\"\n table.isLoading || !headerRow.value.sortable || sort(headerRow.key)\n \"\n scope=\"col\"\n >\n <ng-container *ngIf=\"headerRow?.value?.header !== false\">{{\n headerRow?.value?.header || headerRow.key | capitalCase\n }}</ng-container>\n </th>\n <th\n *ngFor=\"let column of ((table$ | async)?.data || [])[0]\"\n ngClass=\"{{ headerRow.value.class }}\"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.rows || {})[headerRow.key].templateRef\n ? templateRef\n : (table.config.rows || {})[headerRow.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: column,\n column: headerRow,\n transform: (table.config.rows || {})[headerRow.key].transform,\n templateRef: (table.config.rows || {})[headerRow.key].templateRef,\n index: 0\n }\"\n >\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody *ngIf=\"loading$ | async; else tableContent\">\n <tr>\n <td class=\"p-0\" [colSpan]=\"colspan$ | async\">\n <ng-content select=\".table-loading\"></ng-content>\n </td>\n </tr>\n </tbody>\n <tfoot *ngIf=\"(table$ | async)! as table\">\n <ng-container *ngIf=\"table.data.length > 0 && !(loading$ | async)\">\n <ng-container *ngIf=\"(calculations$ | async)! as calculations\">\n <tr\n *ngFor=\"let calculation of calculations.calculations; let i = index\"\n >\n <ng-container\n *ngIf=\"{\n showHeader: (colspan$ | async) !== (footerColspan$ | async)\n } as footerRow\"\n >\n <th\n *ngIf=\"footerRow.showHeader\"\n [colSpan]=\"\n ((colspan$ | async) || 0) - ((footerColspan$ | async) || 0)\n \"\n scope=\"row\"\n >\n <ng-container\n *ngIf=\"table.config?.footer?.headers?.[calculation] as showHeader\"\n >{{showHeader === true ? (calculation | capitalCase): table.config.footer?.headers?.[calculation]}}\n </ng-container>\n </th>\n <ng-container\n *ngFor=\"\n let column of table.config?.columns | keyvalue: columnOrder\n \"\n >\n <td\n *ngIf=\"\n !column.value?.hidden && calculations.calculated[column.key]\n \"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [attr.data-header]=\"\n !footerRow.showHeader && table.config.footer?.headers?.[calculation]\n ? table.config.footer?.headers?.[calculation] === true ? (calculation | capitalCase) : table.config.footer?.headers?.[calculation]\n : null\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.columns || {})[column.key].transform\n ? transformFooter\n : rawFooter\n \"\n [ngTemplateOutletContext]=\"{\n value: calculations.calculated[column.key][calculation],\n transform: (table.config.columns || {})[column.key]\n .transform\n }\"\n ></ng-container>\n </td>\n </ng-container>\n </ng-container>\n </tr>\n </ng-container>\n </ng-container>\n </tfoot>\n</table>\n<ng-template #tableContent>\n <ng-container *ngIf=\"(table$ | async)! as table\">\n <tbody *ngIf=\"(table!.data![0] || table!.data!).length > 0; else noData\">\n <ng-container *ngIf=\"table.config.columns\">\n <tr\n *ngFor=\"\n let row of table!.data![(currentPage$ | async) || 0];\n let i = index\n \"\n [attr.id]=\"'tableRow_' + i\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseover)=\"table?.config?.rowHover && _hoverRow(row, i, $event)\"\n (mouseout)=\"table?.config?.rowHover && _hoverRow(null, null, $event)\"\n [class.gt-hover]=\"(rowHover$ | async)?.index === i\"\n >\n <ng-container\n *ngFor=\"let column of table.config?.columns | keyvalue: columnOrder\"\n >\n <td\n *ngIf=\"!column.value?.hidden\"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [attr.data-label]=\"\n table.config.mobileLayout && column.value.mobileHeader\n ? column.value.mobileHeader !== true\n ? column.value.mobileHeader\n : (column.value.header || column.key | capitalCase)\n : null\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (searchBy$ | async) &&\n !(table.config.columns || {})[column.key].templateRef\n ? highlighted\n : (table.config.columns || {})[column.key].templateRef\n ? templateRef\n : (table.config.columns || {})[column.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: row,\n column: column,\n search: (searchBy$ | async),\n transform: (table.config.columns || {})[column.key].transform,\n templateRef: (table.config.columns || {})[column.key]\n .templateRef,\n index: i,\n data: table.data[(currentPage$ | async) || 0]\n }\"\n ></ng-container>\n </td>\n </ng-container>\n </tr>\n </ng-container>\n <ng-container *ngIf=\"table.config.rows\">\n <ng-container\n *ngFor=\"\n let row of table?.config?.rows | keyvalue: columnOrder | slice: 1;\n let i = index\n \"\n >\n <tr\n *ngIf=\"!row.value?.hidden\"\n [attr.id]=\"'tableRow_' + i\"\n ngClass=\"{{ (row.key | dashCase) + '-row' }}\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseover)=\"table?.config?.rowHover && _hoverRow(row, i, $event)\"\n (mouseout)=\"\n table?.config?.rowHover && _hoverRow(null, null, $event)\n \"\n [class.gt-hover]=\"(rowHover$ | async)?.index === i\"\n >\n <th class=\"row-header\" scope=\"row\">\n {{ row.value.header || row.key | capitalCase }}\n </th>\n <td\n *ngFor=\"let column of (table?.data || [])[0]; let y = index\"\n ngClass=\"{{ row.value.class }}\"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.rows || {})[row.key].templateRef\n ? templateRef\n : (table.config.rows || {})[row.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: column,\n column: row,\n transform: (table.config.rows || {})[row.key].transform,\n templateRef: (table.config.rows || {})[row.key].templateRef,\n index: table.config.rows ? y : i,\n data: table.data[(currentPage$ | async) || 0]\n }\"\n >\n </ng-container>\n </td>\n </tr>\n </ng-container>\n </ng-container>\n </tbody>\n </ng-container>\n</ng-template>\n<ng-template #noData>\n <tbody>\n <tr>\n <td class=\"p-0\" [colSpan]=\"colspan$ | async\">\n <ng-content select=\".table-no-data\"></ng-content>\n </td>\n </tr>\n </tbody>\n</ng-template>\n<ng-template\n #highlighted\n let-row=\"row\"\n let-column=\"column\"\n let-search=\"search\"\n let-transform=\"transform\"\n>\n <div\n *ngIf=\"!transform\"\n [innerHTML]=\"row[column.key] | highlight: search\"\n ></div>\n <div\n *ngIf=\"transform\"\n [innerHTML]=\"\n row[column.key]\n | dynamicPipe: transform.pipe:transform?.args\n | highlight: search\n \"\n ></div>\n</ng-template>\n<ng-template #rawData let-row=\"row\" let-column=\"column\">\n {{ row[column.key] }}\n</ng-template>\n<ng-template\n #transformData\n let-row=\"row\"\n let-column=\"column\"\n let-transform=\"transform\"\n let-data=\"data\"\n>\n {{ row[column.key] | dynamicPipe: transform.pipe:transform?.args }}\n</ng-template>\n<ng-template #transformFooter let-value=\"value\" let-transform=\"transform\">\n {{\n (value | dynamicPipe: transform.pipe:transform?.args) ||\n (tableConfig$ | async)?.footer?.emptyContent\n }}\n</ng-template>\n<ng-template #rawFooter let-value=\"value\">\n {{ value || (tableConfig$ | async)?.footer?.emptyContent }}\n</ng-template>\n<ng-template\n #templateRef\n let-row=\"row\"\n let-column=\"column\"\n let-index=\"index\"\n let-templateRef=\"templateRef\"\n let-data=\"data\"\n>\n <ng-container\n [ngTemplateOutlet]=\"templateRef\"\n [ngTemplateOutletContext]=\"{\n row: row,\n col: column,\n index: index,\n data: data\n }\"\n ></ng-container>\n</ng-template>\n" }]
625
+ ], template: "<table\n [ngClass]=\"(tableConfig$ | async)?.class || 'table'\"\n [class.table-mobile]=\"(tableConfig$ | async)?.mobileLayout\"\n [class.table-horizontal]=\"(tableConfig$ | async)?.rows\"\n [class.table-loading]=\"loading$ | async\"\n [class.gt-sticky-row-header]=\"\n (tableConfig$ | async)?.stickyHeaders?.row && (tableConfig$ | async)?.rows\n \"\n [class.gt-sticky-column-header]=\"\n (tableConfig$ | async)?.stickyHeaders?.column\n \"\n [attr.aria-busy]=\"(loading$ | async) === true ? true : null\"\n>\n <thead>\n <tr\n *ngIf=\"{\n config: (tableConfig$ | async)!,\n isLoading: loading$ | async\n } as table\"\n >\n <ng-container\n *ngFor=\"let column of table.config?.columns | keyvalue: columnOrder\"\n >\n <th\n *ngIf=\"!column.value?.hidden\"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [class.disabled]=\"table.isLoading\"\n [attr.aria-sort]=\"sortOrder$ | async | sortClass: column.key:'aria'\"\n [class.gt-sortable]=\"true\"\n scope=\"col\"\n >\n <button\n *ngIf=\"column.value?.sortable\"\n [attr.data-sort-order]=\"\n sortOrder$ | async | sortClass: column.key:'order'\n \"\n class=\"gt-sort\"\n (click)=\"\n table.isLoading ||\n !column.value.sortable ||\n sortByKey(column.key, $event)\n \"\n >\n <span *ngIf=\"column.value?.header !== false\">{{\n column.value.header || column.key | capitalCase\n }}</span>\n </button>\n <span\n *ngIf=\"!column.value?.sortable && column.value?.header !== false\"\n >{{ column.value.header || column.key | capitalCase }}</span\n >\n </th>\n </ng-container>\n <ng-container\n *ngIf=\"\n ((table?.config?.rows | keyvalue: columnOrder) || [])[0] as headerRow\n \"\n >\n <th\n class=\"row-header\"\n [attr.aria-sort]=\"\n sortOrder$ | async | sortClass: headerRow.key:'aria'\n \"\n ngClass=\"{{ headerRow.value.sortable ? 'sort ' : '' }} {{\n sortOrder$ | async | sortClass: headerRow.key\n }} {{ (headerRow.key | dashCase) + '-column' }}\"\n (click)=\"\n table.isLoading ||\n !headerRow.value.sortable ||\n sortByKey(headerRow.key, $event)\n \"\n scope=\"col\"\n >\n <ng-container *ngIf=\"headerRow?.value?.header !== false\">{{\n headerRow?.value?.header || headerRow.key | capitalCase\n }}</ng-container>\n </th>\n <th\n *ngFor=\"let column of ((table$ | async)?.data || [])[0]\"\n ngClass=\"{{ headerRow.value.class }}\"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.rows || {})[headerRow.key].templateRef\n ? templateRef\n : (table.config.rows || {})[headerRow.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: column,\n column: headerRow,\n transform: (table.config.rows || {})[headerRow.key].transform,\n templateRef: (table.config.rows || {})[headerRow.key].templateRef,\n index: 0\n }\"\n >\n </ng-container>\n </th>\n </ng-container>\n </tr>\n </thead>\n <tbody *ngIf=\"loading$ | async; else tableContent\">\n <tr>\n <td class=\"p-0\" [colSpan]=\"colspan$ | async\">\n <ng-content select=\".table-loading\"></ng-content>\n </td>\n </tr>\n </tbody>\n <tfoot *ngIf=\"(table$ | async)! as table\">\n <ng-container *ngIf=\"table.data.length > 0 && !(loading$ | async)\">\n <ng-container *ngIf=\"(calculations$ | async)! as calculations\">\n <tr\n *ngFor=\"let calculation of calculations.calculations; let i = index\"\n >\n <ng-container\n *ngIf=\"{\n showHeader: (colspan$ | async) !== (footerColspan$ | async)\n } as footerRow\"\n >\n <th\n *ngIf=\"footerRow.showHeader\"\n [colSpan]=\"\n ((colspan$ | async) || 0) - ((footerColspan$ | async) || 0)\n \"\n scope=\"row\"\n >\n <ng-container\n *ngIf=\"table.config?.footer?.headers?.[calculation] as showHeader\"\n >{{showHeader === true ? (calculation | capitalCase): table.config.footer?.headers?.[calculation]}}\n </ng-container>\n </th>\n <ng-container\n *ngFor=\"\n let column of table.config?.columns | keyvalue: columnOrder\n \"\n >\n <td\n *ngIf=\"\n !column.value?.hidden && calculations.calculated[column.key]\n \"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [attr.data-header]=\"\n !footerRow.showHeader && table.config.footer?.headers?.[calculation]\n ? table.config.footer?.headers?.[calculation] === true ? (calculation | capitalCase) : table.config.footer?.headers?.[calculation]\n : null\n \"\n [attr.data-label]=\"\n table.config.mobileLayout && column.value.mobileHeader\n ? column.value.mobileHeader !== true\n ? column.value.mobileHeader\n : (column.value.header || column.key | capitalCase)\n : null\n \"\n [class.gt-no-content]=\"\n !calculations.calculated[column.key][calculation]\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.columns || {})[column.key].templateRef\n ? templateRef\n : (table.config.columns || {})[column.key].transform\n ? transformFooter\n : rawFooter\n \"\n [ngTemplateOutletContext]=\"{\n value: calculations.calculated[column.key][calculation],\n row: calculations.calculated[column.key],\n column: calculation,\n templateRef: (table.config.columns || {})[column.key]\n .templateRef,\n transform: (table.config.columns || {})[column.key]\n .transform\n }\"\n ></ng-container>\n </td>\n </ng-container>\n </ng-container>\n </tr>\n </ng-container>\n </ng-container>\n </tfoot>\n</table>\n<ng-template #tableContent>\n <ng-container *ngIf=\"(table$ | async)! as table\">\n <tbody *ngIf=\"(table!.data![0] || table!.data!).length > 0; else noData\">\n <ng-container *ngIf=\"table.config.columns\">\n <tr\n *ngFor=\"\n let row of table!.data![\n table.info.lazyLoaded ? 0 : (currentPaginationIndex$ | async) || 0\n ];\n let i = index\n \"\n [attr.id]=\"'tableRow_' + i\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseover)=\"table?.config?.rowHover && _hoverRow(row, i, $event)\"\n (mouseout)=\"table?.config?.rowHover && _hoverRow(null, null, $event)\"\n [class.gt-hover]=\"(rowHover$ | async)?.index === i\"\n >\n <ng-container\n *ngFor=\"let column of table.config?.columns | keyvalue: columnOrder\"\n >\n <td\n *ngIf=\"!column.value?.hidden\"\n ngClass=\"{{ (column.key | dashCase) + '-column' }} {{\n column.value.class\n }}\"\n [attr.data-label]=\"\n table.config.mobileLayout && column.value.mobileHeader\n ? column.value.mobileHeader !== true\n ? column.value.mobileHeader\n : (column.value.header || column.key | capitalCase)\n : null\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (searchBy$ | async) &&\n !(table.config.columns || {})[column.key].templateRef\n ? highlighted\n : (table.config.columns || {})[column.key].templateRef\n ? templateRef\n : (table.config.columns || {})[column.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: row,\n column: column,\n search: (searchBy$ | async),\n transform: (table.config.columns || {})[column.key].transform,\n templateRef: (table.config.columns || {})[column.key]\n .templateRef,\n index: i,\n data: table.data[\n table.info.lazyLoaded\n ? 0\n : (currentPaginationIndex$ | async) || 0\n ]\n }\"\n ></ng-container>\n </td>\n </ng-container>\n </tr>\n </ng-container>\n <ng-container *ngIf=\"table.config.rows\">\n <ng-container\n *ngFor=\"\n let row of table?.config?.rows | keyvalue: columnOrder | slice: 1;\n let i = index\n \"\n >\n <tr\n *ngIf=\"!row.value?.hidden\"\n [attr.id]=\"'tableRow_' + i\"\n ngClass=\"{{ (row.key | dashCase) + '-row' }}\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseover)=\"table?.config?.rowHover && _hoverRow(row, i, $event)\"\n (mouseout)=\"\n table?.config?.rowHover && _hoverRow(null, null, $event)\n \"\n [class.gt-hover]=\"(rowHover$ | async)?.index === i\"\n >\n <th class=\"row-header\" scope=\"row\">\n {{ row.value.header || row.key | capitalCase }}\n </th>\n <td\n *ngFor=\"let column of (table?.data || [])[0]; let y = index\"\n ngClass=\"{{ row.value.class }}\"\n >\n <ng-container\n [ngTemplateOutlet]=\"\n (table.config.rows || {})[row.key].templateRef\n ? templateRef\n : (table.config.rows || {})[row.key].transform\n ? transformData\n : rawData\n \"\n [ngTemplateOutletContext]=\"{\n row: column,\n column: row,\n transform: (table.config.rows || {})[row.key].transform,\n templateRef: (table.config.rows || {})[row.key].templateRef,\n index: table.config.rows ? y : i,\n data: table.data[\n table.info.lazyLoaded\n ? 0\n : (currentPaginationIndex$ | async) || 0\n ]\n }\"\n >\n </ng-container>\n </td>\n </tr>\n </ng-container>\n </ng-container>\n </tbody>\n </ng-container>\n</ng-template>\n<ng-template #noData>\n <tbody>\n <tr>\n <td class=\"p-0\" [colSpan]=\"colspan$ | async\">\n <ng-content select=\".table-no-data\"></ng-content>\n </td>\n </tr>\n </tbody>\n</ng-template>\n<ng-template\n #highlighted\n let-row=\"row\"\n let-column=\"column\"\n let-search=\"search\"\n let-transform=\"transform\"\n>\n <div\n *ngIf=\"!transform\"\n [innerHTML]=\"row[column.key] | highlight: search\"\n ></div>\n <div\n *ngIf=\"transform\"\n [innerHTML]=\"\n row[column.key]\n | dynamicPipe: transform.pipe:transform?.args\n | highlight: search\n \"\n ></div>\n</ng-template>\n<ng-template #rawData let-row=\"row\" let-column=\"column\">\n {{ row[column.key] }}\n</ng-template>\n<ng-template\n #transformData\n let-row=\"row\"\n let-column=\"column\"\n let-transform=\"transform\"\n let-data=\"data\"\n>\n {{ row[column.key] | dynamicPipe: transform.pipe:transform?.args }}\n</ng-template>\n<ng-template #transformFooter let-value=\"value\" let-transform=\"transform\">\n {{\n (value | dynamicPipe: transform.pipe:transform?.args) ||\n (tableConfig$ | async)?.footer?.emptyContent\n }}\n</ng-template>\n<ng-template #rawFooter let-value=\"value\">\n {{ value || (tableConfig$ | async)?.footer?.emptyContent }}\n</ng-template>\n<ng-template\n #templateRef\n let-row=\"row\"\n let-column=\"column\"\n let-index=\"index\"\n let-templateRef=\"templateRef\"\n let-data=\"data\"\n>\n <ng-container\n [ngTemplateOutlet]=\"templateRef\"\n [ngTemplateOutletContext]=\"{\n row: row,\n col: column,\n index: index,\n data: data\n }\"\n ></ng-container>\n</ng-template>\n" }]
456
626
  }], propDecorators: { loading: [{
457
627
  type: Input
458
- }], page: [{
628
+ }], paginationIndex: [{
629
+ type: Input
630
+ }], pagingInfo: [{
459
631
  type: Input
460
632
  }], search: [{
461
633
  type: Input
@@ -463,13 +635,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImpor
463
635
  type: Input
464
636
  }], data: [{
465
637
  type: Input
638
+ }], sortOrder: [{
639
+ type: Input
466
640
  }], rowClick: [{
467
641
  type: Output
642
+ }], sortOrderChange: [{
643
+ type: Output
468
644
  }], rowHover: [{
469
645
  type: Output
646
+ }], columnSort: [{
647
+ type: Output
648
+ }], pageChange: [{
649
+ type: Output
470
650
  }] } });
471
651
 
472
652
  class GtDeltaComponent {
653
+ get value() {
654
+ return this._value;
655
+ }
656
+ set value(value) {
657
+ this._value = value;
658
+ }
659
+ get deltaTemplate() {
660
+ return this._deltaTemplate;
661
+ }
473
662
  constructor() {
474
663
  this.Math = Math;
475
664
  this.Number = Number;
@@ -484,15 +673,6 @@ class GtDeltaComponent {
484
673
  this.notApplicableValue = null;
485
674
  this.initialValue = null;
486
675
  }
487
- get value() {
488
- return this._value;
489
- }
490
- set value(value) {
491
- this._value = value;
492
- }
493
- get deltaTemplate() {
494
- return this._deltaTemplate;
495
- }
496
676
  set deltaTemplate(deltaTemplate) {
497
677
  this._deltaTemplate = deltaTemplate;
498
678
  }
@@ -529,8 +709,8 @@ class GtDeltaComponent {
529
709
  };
530
710
  }
531
711
  }
532
- GtDeltaComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: GtDeltaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
533
- GtDeltaComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.8", type: GtDeltaComponent, isStandalone: true, selector: "gt-delta", inputs: { deltaTemplate: "deltaTemplate", data: "data", index: "index", baseIndex: "baseIndex", classes: "classes", key: "key", notApplicableValue: "notApplicableValue", initialValue: "initialValue" }, usesOnChanges: true, ngImport: i0, template: `<span
712
+ GtDeltaComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: GtDeltaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
713
+ GtDeltaComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.1", type: GtDeltaComponent, isStandalone: true, selector: "gt-delta", inputs: { deltaTemplate: "deltaTemplate", data: "data", index: "index", baseIndex: "baseIndex", classes: "classes", key: "key", notApplicableValue: "notApplicableValue", initialValue: "initialValue" }, usesOnChanges: true, ngImport: i0, template: `<span
534
714
  *ngIf="value as delta"
535
715
  [class]="[
536
716
  classes.span,
@@ -551,7 +731,7 @@ GtDeltaComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", versi
551
731
  delta.relative | percent: '1.0-2'
552
732
  }}</span>
553
733
  </ng-template>`, isInline: true, styles: [":host{display:inline-block}\n"], dependencies: [{ kind: "pipe", type: PercentPipe, name: "percent" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
554
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: GtDeltaComponent, decorators: [{
734
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: GtDeltaComponent, decorators: [{
555
735
  type: Component,
556
736
  args: [{ selector: 'gt-delta', template: `<span
557
737
  *ngIf="value as delta"
@@ -594,8 +774,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImpor
594
774
 
595
775
  class GenericTableCoreModule {
596
776
  }
597
- GenericTableCoreModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: GenericTableCoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
598
- GenericTableCoreModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.8", ngImport: i0, type: GenericTableCoreModule, imports: [CommonModule,
777
+ GenericTableCoreModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: GenericTableCoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
778
+ GenericTableCoreModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.1.1", ngImport: i0, type: GenericTableCoreModule, imports: [CommonModule,
599
779
  CoreComponent,
600
780
  SortClassPipe,
601
781
  DashCasePipe,
@@ -604,10 +784,10 @@ GenericTableCoreModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0",
604
784
  CapitalCasePipe,
605
785
  DynamicPipe,
606
786
  GtDeltaComponent], exports: [CoreComponent, GtDeltaComponent] });
607
- GenericTableCoreModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: GenericTableCoreModule, imports: [CommonModule,
787
+ GenericTableCoreModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: GenericTableCoreModule, imports: [CommonModule,
608
788
  CoreComponent,
609
789
  GtDeltaComponent] });
610
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: GenericTableCoreModule, decorators: [{
790
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: GenericTableCoreModule, decorators: [{
611
791
  type: NgModule,
612
792
  args: [{
613
793
  imports: [
@@ -627,7 +807,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImpor
627
807
 
628
808
  class PaginationComponent {
629
809
  constructor() {
630
- this.table$ = new ReplaySubject(1);
810
+ this._table$ = new ReplaySubject(1);
631
811
  this._ariaLabels = {
632
812
  nav: 'Table pagination',
633
813
  button: 'Go to page ',
@@ -638,58 +818,111 @@ class PaginationComponent {
638
818
  button: 'page-link',
639
819
  };
640
820
  this._paginationLength = 5;
641
- this.pagination$ = this.table$.pipe(switchMap((core) => combineLatest([core?.table$.pipe(pluck('info')), core?.currentPage$])), map(([info, currentPage]) => this.generateList(info.pageTotal, currentPage)));
821
+ /** paginationListItems$ - observable for page numbers to show based on number of pages and current position */
822
+ this.paginationListItems$ = this._table$.pipe(switchMap((core) => combineLatest([
823
+ core?.table$.pipe(pluck('info')),
824
+ core?.currentPaginationIndex$,
825
+ ])), map(([info, currentPage]) => this._generateList(info.pageTotal, currentPage)), shareReplay(1));
826
+ }
827
+ get pagingInfo() {
828
+ return (this._pagingInfo || {
829
+ pageNext: null,
830
+ pageCurrent: null,
831
+ pagePrevious: null,
832
+ pageSize: null,
833
+ numberOfRecords: null,
834
+ pageTotal: null,
835
+ });
836
+ }
837
+ /** pagingInfo
838
+ * @description when provided, pagination component will use this information to render pagination instead of data from table. Use this option when pagination is handled by backend (server side).
839
+ * @type info - metadata for pagination component
840
+ */
841
+ set pagingInfo(info) {
842
+ this._pagingInfo = info;
642
843
  }
643
844
  get paginationLength() {
644
845
  return this._paginationLength;
645
846
  }
646
- set paginationLength(value) {
647
- this._paginationLength = +value;
847
+ /** paginationLength
848
+ * @description number of buttons to show in pagination
849
+ * @type length - number of buttons to show. Defaults to: `5`
850
+ */
851
+ set paginationLength(length) {
852
+ this._paginationLength = +length;
648
853
  }
649
854
  get classes() {
650
855
  return this._classes;
651
856
  }
652
- set classes(value) {
653
- this._classes = value;
857
+ /** classes
858
+ * @description classes that should be used within pagination component for different elements
859
+ * @type classes - classes to be used. Defaults to: `{
860
+ * ul: 'pagination',
861
+ * li: 'page-item',
862
+ * button: 'page-link',
863
+ * }`
864
+ */
865
+ set classes(classes) {
866
+ this._classes = classes;
654
867
  }
655
868
  get ariaLabels() {
656
869
  return this._ariaLabels;
657
870
  }
658
- set ariaLabels(value) {
659
- this._ariaLabels = value;
871
+ /** ariaLabels
872
+ * @description aria labels that describe pagination component
873
+ * @type labels - aria labels for pagination. Defaults to: `{
874
+ * nav: 'Table pagination',
875
+ * button: 'Go to page ',
876
+ * }`
877
+ */
878
+ set ariaLabels(labels) {
879
+ this._ariaLabels = labels;
660
880
  }
661
881
  get table() {
662
882
  return this._table;
663
883
  }
664
- set table(value) {
665
- this._table = value;
666
- this.table$.next(value);
667
- }
668
- generateList(pages, currentPosition) {
884
+ /** table
885
+ * @description table component to which pagination is attached
886
+ * @type tableRef - table component
887
+ */
888
+ set table(tableRef) {
889
+ this._table = tableRef;
890
+ this._table$.next(tableRef);
891
+ }
892
+ /** generate list - generate an array with page numbers to show based on number of pages and current position
893
+ * @param numberOfPages number of pages to show
894
+ * @param currentPosition current position (page index) being shown in table
895
+ * @returns Array<number> array of page numbers to show
896
+ */
897
+ _generateList(numberOfPages, currentPosition) {
669
898
  const middle = Math.floor(this.paginationLength / 2);
670
- const length = pages < this.paginationLength ? pages : this.paginationLength;
899
+ const length = numberOfPages < this.paginationLength
900
+ ? numberOfPages
901
+ : this.paginationLength;
671
902
  return Array.from({ length }, (_, i) => {
672
903
  if (i === 0) {
673
904
  return 1;
674
905
  }
675
- else if (pages < this.paginationLength) {
906
+ else if (numberOfPages < this.paginationLength) {
676
907
  return i + 1;
677
908
  }
678
909
  else if (i + 1 === length) {
679
- return pages;
910
+ return numberOfPages;
680
911
  }
681
- else if (currentPosition > middle && currentPosition < pages - middle) {
912
+ else if (currentPosition > middle &&
913
+ currentPosition < numberOfPages - middle) {
682
914
  return i + currentPosition - (middle - 1);
683
915
  }
684
916
  else if (currentPosition > middle &&
685
- currentPosition < pages - (middle - 1)) {
917
+ currentPosition < numberOfPages - (middle - 1)) {
686
918
  return i + currentPosition - middle;
687
919
  }
688
920
  else if (currentPosition > middle &&
689
- currentPosition === pages - (middle - 1)) {
921
+ currentPosition === numberOfPages - (middle - 1)) {
690
922
  return i + currentPosition - (middle + 1);
691
923
  }
692
- else if (currentPosition > middle && currentPosition === pages - 1) {
924
+ else if (currentPosition > middle &&
925
+ currentPosition === numberOfPages - 1) {
693
926
  return i + currentPosition - (middle + 2);
694
927
  }
695
928
  else {
@@ -697,18 +930,23 @@ class PaginationComponent {
697
930
  }
698
931
  });
699
932
  }
700
- goto(page) {
933
+ /** go to page
934
+ * @param index - page index to go to
935
+ */
936
+ goToPage(index) {
701
937
  if (this.table) {
702
- this.table.page = page - 1;
938
+ this.table.paginationIndex = index - 1;
703
939
  }
704
940
  }
705
941
  }
706
- PaginationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: PaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
707
- PaginationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.8", type: PaginationComponent, isStandalone: true, selector: "angular-generic-table-pagination", inputs: { paginationLength: "paginationLength", classes: "classes", ariaLabels: "ariaLabels", table: "table" }, ngImport: i0, template: "<ng-container\n *ngIf=\"{\n links: pagination$ | async,\n currentPosition: table?.currentPage$ | async\n } as pagination\"\n>\n <nav\n *ngIf=\"pagination.links && pagination.links.length > 1\"\n role=\"navigation\"\n [attr.aria-label]=\"ariaLabels.nav\"\n class=\"gt-pagination\"\n [class]=\"classes.nav\"\n >\n <ul [class]=\"classes.ul\">\n <ng-container\n *ngFor=\"\n let position of pagination!.links;\n let i = index;\n let last = last\n \"\n >\n <li\n [class]=\"classes.li\"\n [class.active]=\"position === (pagination!.currentPosition || 0) + 1\"\n >\n <button\n [class]=\"classes.button\"\n [attr.aria-label]=\"ariaLabels.button + position\"\n (click)=\"goto(position)\"\n >\n {{ position }}\n </button>\n </li>\n <li\n [class]=\"classes.li\"\n class=\"gt-ellipsis\"\n *ngIf=\"position + 1 !== pagination!.links![i + 1] && !last\"\n >\n <button [class]=\"classes.button\" disabled tabindex=\"-1\"></button>\n </li>\n </ng-container>\n </ul>\n </nav>\n</ng-container>\n", dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
708
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: PaginationComponent, decorators: [{
942
+ PaginationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: PaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
943
+ PaginationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.1", type: PaginationComponent, isStandalone: true, selector: "angular-generic-table-pagination", inputs: { pagingInfo: "pagingInfo", paginationLength: "paginationLength", classes: "classes", ariaLabels: "ariaLabels", table: "table" }, ngImport: i0, template: "<ng-container\n *ngIf=\"{\n links: paginationListItems$ | async,\n currentPosition: table?.currentPaginationIndex$ | async\n } as pagination\"\n>\n <nav\n *ngIf=\"pagination.links && pagination.links.length > 1\"\n role=\"navigation\"\n [attr.aria-label]=\"ariaLabels.nav\"\n class=\"gt-pagination\"\n [class]=\"classes.nav\"\n >\n <ul [class]=\"classes.ul\">\n <ng-container\n *ngFor=\"\n let position of pagination!.links;\n let i = index;\n let last = last\n \"\n >\n <li\n [class]=\"classes.li\"\n [class.active]=\"position === (pagination!.currentPosition || 0) + 1\"\n >\n <button\n [class]=\"classes.button\"\n [attr.aria-label]=\"ariaLabels.button + position\"\n (click)=\"goToPage(position)\"\n >\n {{ position }}\n </button>\n </li>\n <li\n [class]=\"classes.li\"\n class=\"gt-ellipsis\"\n *ngIf=\"position + 1 !== pagination!.links![i + 1] && !last\"\n >\n <button [class]=\"classes.button\" disabled tabindex=\"-1\"></button>\n </li>\n </ng-container>\n </ul>\n </nav>\n</ng-container>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
944
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: PaginationComponent, decorators: [{
709
945
  type: Component,
710
- args: [{ selector: 'angular-generic-table-pagination', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [AsyncPipe, NgIf, NgForOf], template: "<ng-container\n *ngIf=\"{\n links: pagination$ | async,\n currentPosition: table?.currentPage$ | async\n } as pagination\"\n>\n <nav\n *ngIf=\"pagination.links && pagination.links.length > 1\"\n role=\"navigation\"\n [attr.aria-label]=\"ariaLabels.nav\"\n class=\"gt-pagination\"\n [class]=\"classes.nav\"\n >\n <ul [class]=\"classes.ul\">\n <ng-container\n *ngFor=\"\n let position of pagination!.links;\n let i = index;\n let last = last\n \"\n >\n <li\n [class]=\"classes.li\"\n [class.active]=\"position === (pagination!.currentPosition || 0) + 1\"\n >\n <button\n [class]=\"classes.button\"\n [attr.aria-label]=\"ariaLabels.button + position\"\n (click)=\"goto(position)\"\n >\n {{ position }}\n </button>\n </li>\n <li\n [class]=\"classes.li\"\n class=\"gt-ellipsis\"\n *ngIf=\"position + 1 !== pagination!.links![i + 1] && !last\"\n >\n <button [class]=\"classes.button\" disabled tabindex=\"-1\"></button>\n </li>\n </ng-container>\n </ul>\n </nav>\n</ng-container>\n" }]
711
- }], propDecorators: { paginationLength: [{
946
+ args: [{ selector: 'angular-generic-table-pagination', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule], template: "<ng-container\n *ngIf=\"{\n links: paginationListItems$ | async,\n currentPosition: table?.currentPaginationIndex$ | async\n } as pagination\"\n>\n <nav\n *ngIf=\"pagination.links && pagination.links.length > 1\"\n role=\"navigation\"\n [attr.aria-label]=\"ariaLabels.nav\"\n class=\"gt-pagination\"\n [class]=\"classes.nav\"\n >\n <ul [class]=\"classes.ul\">\n <ng-container\n *ngFor=\"\n let position of pagination!.links;\n let i = index;\n let last = last\n \"\n >\n <li\n [class]=\"classes.li\"\n [class.active]=\"position === (pagination!.currentPosition || 0) + 1\"\n >\n <button\n [class]=\"classes.button\"\n [attr.aria-label]=\"ariaLabels.button + position\"\n (click)=\"goToPage(position)\"\n >\n {{ position }}\n </button>\n </li>\n <li\n [class]=\"classes.li\"\n class=\"gt-ellipsis\"\n *ngIf=\"position + 1 !== pagination!.links![i + 1] && !last\"\n >\n <button [class]=\"classes.button\" disabled tabindex=\"-1\"></button>\n </li>\n </ng-container>\n </ul>\n </nav>\n</ng-container>\n" }]
947
+ }], propDecorators: { pagingInfo: [{
948
+ type: Input
949
+ }], paginationLength: [{
712
950
  type: Input
713
951
  }], classes: [{
714
952
  type: Input
@@ -720,10 +958,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImpor
720
958
 
721
959
  class GenericTablePaginationModule {
722
960
  }
723
- GenericTablePaginationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: GenericTablePaginationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
724
- GenericTablePaginationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.8", ngImport: i0, type: GenericTablePaginationModule, imports: [CommonModule, PaginationComponent], exports: [PaginationComponent] });
725
- GenericTablePaginationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: GenericTablePaginationModule, imports: [CommonModule, PaginationComponent] });
726
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: GenericTablePaginationModule, decorators: [{
961
+ GenericTablePaginationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: GenericTablePaginationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
962
+ GenericTablePaginationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.1.1", ngImport: i0, type: GenericTablePaginationModule, imports: [CommonModule, PaginationComponent], exports: [PaginationComponent] });
963
+ GenericTablePaginationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: GenericTablePaginationModule, imports: [CommonModule, PaginationComponent] });
964
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: GenericTablePaginationModule, decorators: [{
727
965
  type: NgModule,
728
966
  args: [{
729
967
  imports: [CommonModule, PaginationComponent],
@@ -739,5 +977,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImpor
739
977
  * Generated bundle index. Do not edit.
740
978
  */
741
979
 
742
- export { CoreComponent, CoreService, GenericTableCoreModule, GenericTablePaginationModule, GtDeltaComponent, PaginationComponent };
980
+ export { CapitalCasePipe, CoreComponent, CoreService, DashCasePipe, DynamicPipe, GenericTableCoreModule, GenericTablePaginationModule, GtDeltaComponent, HighlightPipe, PaginationComponent, SortClassPipe, calculate, capitalize, chunk, dashed, parseSortOrderParams, search, sortOnMultipleKeys, sortOrderConfigToParam, sortOrderToParams };
743
981
  //# sourceMappingURL=angular-generic-table-core.mjs.map