@angular-generic-table/core 5.0.0-rc.16 → 5.0.0-rc.18
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.
- package/esm2020/lib/core.component.mjs +334 -39
- package/esm2020/lib/core.module.mjs +5 -1
- package/esm2020/lib/models/gt-pagination.mjs +1 -1
- package/esm2020/lib/models/table-config.interface.mjs +1 -1
- package/esm2020/lib/models/table-events.interface.mjs +1 -1
- package/esm2020/lib/models/table-info.interface.mjs +1 -1
- package/esm2020/lib/pagination/pagination.component.mjs +86 -27
- package/esm2020/lib/pipes/row-selection.pipe.mjs +17 -0
- package/esm2020/lib/utilities/utilities.mjs +36 -1
- package/esm2020/public-api.mjs +8 -1
- package/fesm2015/angular-generic-table-core.mjs +476 -67
- package/fesm2015/angular-generic-table-core.mjs.map +1 -1
- package/fesm2020/angular-generic-table-core.mjs +469 -63
- package/fesm2020/angular-generic-table-core.mjs.map +1 -1
- package/lib/core.component.d.ts +94 -18
- package/lib/core.module.d.ts +5 -4
- package/lib/models/gt-pagination.d.ts +8 -0
- package/lib/models/table-config.interface.d.ts +5 -1
- package/lib/models/table-events.interface.d.ts +11 -2
- package/lib/models/table-info.interface.d.ts +3 -1
- package/lib/pagination/pagination.component.d.ts +49 -11
- package/lib/pipes/row-selection.pipe.d.ts +8 -0
- package/lib/utilities/utilities.d.ts +21 -1
- package/package.json +1 -1
- package/public-api.d.ts +7 -0
- package/scss/index.scss +6 -3
|
@@ -1,8 +1,9 @@
|
|
|
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, BehaviorSubject, isObservable, of, combineLatest } from 'rxjs';
|
|
3
|
+
import { Subject, ReplaySubject, BehaviorSubject, isObservable, of, combineLatest, fromEvent } 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 {
|
|
6
|
+
import { distinctUntilChanged, tap, shareReplay, startWith, map, switchMap, withLatestFrom, filter, pluck, take, takeUntil } from 'rxjs/operators';
|
|
6
7
|
|
|
7
8
|
class CoreService {
|
|
8
9
|
constructor() { }
|
|
@@ -144,6 +145,7 @@ let calculate = (data, config) => {
|
|
|
144
145
|
};
|
|
145
146
|
};
|
|
146
147
|
/** sortOnMultipleKeys
|
|
148
|
+
* @description Sort data on multiple keys
|
|
147
149
|
* @param {GtSortOrder} keys - array with sort config objects to sort on, data will be sorted according to array order
|
|
148
150
|
* @returns sort function
|
|
149
151
|
*/
|
|
@@ -160,6 +162,40 @@ const sortOnMultipleKeys = (keys) => {
|
|
|
160
162
|
return 0;
|
|
161
163
|
};
|
|
162
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
|
+
};
|
|
163
199
|
|
|
164
200
|
class CapitalCasePipe {
|
|
165
201
|
transform(s) {
|
|
@@ -300,21 +336,84 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImpor
|
|
|
300
336
|
}]
|
|
301
337
|
}] });
|
|
302
338
|
|
|
339
|
+
class RowSelectionPipe {
|
|
340
|
+
transform(row, selection, comparator, className) {
|
|
341
|
+
return className && comparator(row, selection) ? className : '';
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
RowSelectionPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: RowSelectionPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
345
|
+
RowSelectionPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.1.1", ngImport: i0, type: RowSelectionPipe, isStandalone: true, name: "rowSelection" });
|
|
346
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: RowSelectionPipe, decorators: [{
|
|
347
|
+
type: Pipe,
|
|
348
|
+
args: [{
|
|
349
|
+
name: 'rowSelection',
|
|
350
|
+
standalone: true,
|
|
351
|
+
}]
|
|
352
|
+
}] });
|
|
353
|
+
|
|
303
354
|
class CoreComponent {
|
|
304
355
|
constructor() {
|
|
356
|
+
this.unsubscribe$ = new Subject();
|
|
357
|
+
this._navigationKeys = [
|
|
358
|
+
'ArrowDown',
|
|
359
|
+
'ArrowUp',
|
|
360
|
+
'ArrowLeft',
|
|
361
|
+
'ArrowRight',
|
|
362
|
+
'Home',
|
|
363
|
+
'End',
|
|
364
|
+
];
|
|
365
|
+
this._selectKeys = ['Enter', ' '];
|
|
366
|
+
this._customClasses = {
|
|
367
|
+
selectedRow: 'gt-selected',
|
|
368
|
+
activeRow: 'gt-active',
|
|
369
|
+
};
|
|
370
|
+
/** selection
|
|
371
|
+
* @description An object that contains the currently selected row(s) in the table. It's passed to the selection function to determine which rows should be selected.
|
|
372
|
+
* @type {any}
|
|
373
|
+
*/
|
|
374
|
+
this.selection = {};
|
|
375
|
+
/** generateRowId
|
|
376
|
+
* @description Whether or not to generate a unique id for each row in the table. Defaults to `true`.
|
|
377
|
+
* @type {boolean}
|
|
378
|
+
*/
|
|
379
|
+
this.generateRowId = true;
|
|
305
380
|
this.rowClick = new EventEmitter();
|
|
381
|
+
this.rowSelect = new EventEmitter();
|
|
306
382
|
this.sortOrderChange = new EventEmitter();
|
|
307
|
-
this.
|
|
308
|
-
this.
|
|
383
|
+
this._rowActive$ = new ReplaySubject(1);
|
|
384
|
+
this.rowActive = new EventEmitter();
|
|
309
385
|
this.columnSort = new EventEmitter();
|
|
310
|
-
|
|
386
|
+
/** page change event - emitted when current page/index changes for pagination */
|
|
387
|
+
this.pageChange = new EventEmitter();
|
|
388
|
+
this.rowActive$ = this._rowActive$.asObservable().pipe(distinctUntilChanged((p, q) => {
|
|
389
|
+
if (this.rowIdKey && p.row && q.row) {
|
|
390
|
+
return p.row[this.rowIdKey] === q.row[this.rowIdKey];
|
|
391
|
+
}
|
|
392
|
+
else if (this.generateRowId && p.row && q.row) {
|
|
393
|
+
return p.row._id === q.row._id;
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
return p.index === q.index;
|
|
397
|
+
}
|
|
398
|
+
}), tap((event) => (this.activeRowIndex = event.index)), tap((event) => this.rowActive.emit(event)), shareReplay(1));
|
|
399
|
+
this.activeRowIndex = null;
|
|
311
400
|
this._loading$ = new ReplaySubject(1);
|
|
312
401
|
this._sortOrder$ = new BehaviorSubject([]);
|
|
313
402
|
this._searchBy$ = new ReplaySubject(1);
|
|
314
403
|
this.searchBy$ = this._searchBy$.pipe(startWith(''), map((value) => (isObservable(value) ? value : of(value))), switchMap((obs) => obs), shareReplay(1));
|
|
404
|
+
this._pagingInfo$ = new BehaviorSubject({
|
|
405
|
+
pageCurrent: null,
|
|
406
|
+
pageNext: null,
|
|
407
|
+
pagePrevious: null,
|
|
408
|
+
pageSize: null,
|
|
409
|
+
numberOfRecords: null,
|
|
410
|
+
//recordsAfterFilter: null,
|
|
411
|
+
//recordsAfterSearch: null,
|
|
412
|
+
//recordsAll: null,
|
|
413
|
+
});
|
|
315
414
|
// tslint:disable-next-line:variable-name
|
|
316
415
|
this._tableConfig$ = new BehaviorSubject({});
|
|
317
|
-
this.tableConfig$ = this._tableConfig$.pipe(map((value) => (isObservable(value) ? value : of(value))), switchMap((obs) => obs), shareReplay(1));
|
|
416
|
+
this.tableConfig$ = this._tableConfig$.pipe(map((value) => (isObservable(value) ? value : of(value))), switchMap((obs) => obs), tap((config) => (this._tableConfig = config)), shareReplay(1));
|
|
318
417
|
this._data$ = new ReplaySubject(1);
|
|
319
418
|
this.data$ = this._data$.pipe(map((value) => (isObservable(value) ? value : of(value))), switchMap((obs) => combineLatest([obs])), withLatestFrom(this.tableConfig$), map(([[data], config]) => {
|
|
320
419
|
// if columns or rows contains config for mapTo...
|
|
@@ -336,15 +435,22 @@ class CoreComponent {
|
|
|
336
435
|
}
|
|
337
436
|
data = newData;
|
|
338
437
|
}
|
|
438
|
+
if (this.generateRowId && !this.rowIdKey && data.length > 0) {
|
|
439
|
+
const dataWithId = [];
|
|
440
|
+
for (let i = 0; i < data.length; i++) {
|
|
441
|
+
dataWithId[i] = { ...data[i], _id: i };
|
|
442
|
+
}
|
|
443
|
+
data = dataWithId;
|
|
444
|
+
}
|
|
339
445
|
return { data, config };
|
|
340
446
|
}), switchMap((obs) => combineLatest([of(obs), this.sortOrder$, this.searchBy$])), map(([table, sortBy, searchBy]) => {
|
|
341
447
|
// create a new array reference and sort new array (prevent mutating existing state)
|
|
342
448
|
table.data = [...table.data];
|
|
343
|
-
return !sortBy
|
|
344
|
-
? searchBy
|
|
449
|
+
return !sortBy?.length || table.config?.disableTableSort
|
|
450
|
+
? searchBy && !this.tableInfo?.lazyLoaded
|
|
345
451
|
? search(searchBy, false, table.data, table.config)
|
|
346
452
|
: table.data
|
|
347
|
-
: searchBy
|
|
453
|
+
: searchBy && !this.tableInfo?.lazyLoaded
|
|
348
454
|
? search(searchBy, false, table.data, table.config)?.sort(sortOnMultipleKeys(sortBy))
|
|
349
455
|
: table.data?.sort(sortOnMultipleKeys(sortBy));
|
|
350
456
|
}), shareReplay(1));
|
|
@@ -352,14 +458,30 @@ class CoreComponent {
|
|
|
352
458
|
this.table$ = combineLatest([
|
|
353
459
|
this.data$,
|
|
354
460
|
this.tableConfig$,
|
|
355
|
-
|
|
461
|
+
this._pagingInfo$,
|
|
462
|
+
]).pipe(map(([sorted, config, pagingInfo]) => {
|
|
463
|
+
if (pagingInfo.pageCurrent !== null &&
|
|
464
|
+
pagingInfo.numberOfRecords !== null &&
|
|
465
|
+
pagingInfo.pageSize !== null) {
|
|
466
|
+
return {
|
|
467
|
+
data: [sorted],
|
|
468
|
+
config,
|
|
469
|
+
info: {
|
|
470
|
+
lazyLoaded: true,
|
|
471
|
+
numberOfRecords: pagingInfo.numberOfRecords,
|
|
472
|
+
pageSize: pagingInfo.pageSize,
|
|
473
|
+
pageTotal: pagingInfo.pageTotal ??
|
|
474
|
+
Math.ceil(pagingInfo.numberOfRecords / pagingInfo.pageSize),
|
|
475
|
+
},
|
|
476
|
+
};
|
|
477
|
+
}
|
|
356
478
|
// if pagination is disabled...
|
|
357
479
|
if (!config.pagination || config.pagination.length === 0) {
|
|
358
480
|
// ...return unaltered array
|
|
359
481
|
return {
|
|
360
482
|
data: [sorted],
|
|
361
483
|
config,
|
|
362
|
-
info: {
|
|
484
|
+
info: { numberOfRecords: sorted.length, pageTotal: 1 },
|
|
363
485
|
};
|
|
364
486
|
}
|
|
365
487
|
// return record set
|
|
@@ -367,19 +489,25 @@ class CoreComponent {
|
|
|
367
489
|
data: chunk(sorted, +(config.pagination.length || 0)),
|
|
368
490
|
config,
|
|
369
491
|
info: {
|
|
370
|
-
|
|
492
|
+
numberOfRecords: sorted.length,
|
|
493
|
+
pageSize: +(config.pagination.length || 0),
|
|
371
494
|
pageTotal: Math.ceil(sorted.length / +(config.pagination.length || 0)),
|
|
372
495
|
},
|
|
373
496
|
};
|
|
374
|
-
}), shareReplay(1));
|
|
375
|
-
this.
|
|
376
|
-
this.
|
|
497
|
+
}), tap((meta) => this._tableInfo$.next(meta.info)), shareReplay(1));
|
|
498
|
+
this._tableInfo$ = new BehaviorSubject(undefined);
|
|
499
|
+
this._currentPaginationIndex$ = new BehaviorSubject(0);
|
|
500
|
+
this.currentPaginationIndex$ = combineLatest([
|
|
501
|
+
this._currentPaginationIndex$,
|
|
502
|
+
this.table$,
|
|
503
|
+
]).pipe(map(([page, table]) => {
|
|
377
504
|
// determine last page
|
|
378
505
|
const lastPage = Math.ceil(table.info.records /
|
|
379
|
-
(table.
|
|
380
|
-
|
|
506
|
+
(table.info.recordLength ??
|
|
507
|
+
(table.config?.pagination?.length || table.info.records))) - 1;
|
|
508
|
+
// determine min/max position
|
|
381
509
|
return +page < 0 ? 0 : +page > lastPage ? lastPage : +page;
|
|
382
|
-
}), shareReplay(1));
|
|
510
|
+
}), distinctUntilChanged(), tap((index) => this.pageChange.emit({ index })), shareReplay(1));
|
|
383
511
|
this.colspan$ = this.tableConfig$.pipe(switchMap((config) => config.columns
|
|
384
512
|
? of(Object.values(config.columns || config.rows || {}).filter((value) => value.hidden !== true).length)
|
|
385
513
|
: this.data$.pipe(map((data) => data.length + 1))), shareReplay(1));
|
|
@@ -396,6 +524,30 @@ class CoreComponent {
|
|
|
396
524
|
this.columnOrder = (a, b) => {
|
|
397
525
|
return (a.value.order || 0) - (b.value.order || 0);
|
|
398
526
|
};
|
|
527
|
+
this._unsubscribeFromKeyboardEvents$ = new Subject();
|
|
528
|
+
this._keyboardArrowEvent$ = fromEvent(document, 'keydown').pipe(filter((event) => [...this._navigationKeys, ...this._selectKeys].indexOf(event.key) > -1));
|
|
529
|
+
}
|
|
530
|
+
get navigationKeys() {
|
|
531
|
+
return this._navigationKeys;
|
|
532
|
+
}
|
|
533
|
+
/** navigationKeys
|
|
534
|
+
* @description An array of keyboard keys that will trigger navigation and active row, currently only supports arrow keys, home and end (omit key name from array to disable it)
|
|
535
|
+
* @type {string[]}
|
|
536
|
+
* @default ['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight', 'Home', 'End']
|
|
537
|
+
*/
|
|
538
|
+
set navigationKeys(value) {
|
|
539
|
+
this._navigationKeys = value;
|
|
540
|
+
}
|
|
541
|
+
get selectKeys() {
|
|
542
|
+
return this._selectKeys;
|
|
543
|
+
}
|
|
544
|
+
/** selectKeys
|
|
545
|
+
* @description An array of keyboard keys that will trigger row selection (omit key name from array to disable it)
|
|
546
|
+
* @type {string[]}
|
|
547
|
+
* @default ['Enter', ' ']
|
|
548
|
+
*/
|
|
549
|
+
set selectKeys(value) {
|
|
550
|
+
this._selectKeys = value;
|
|
399
551
|
}
|
|
400
552
|
get sortOrder$() {
|
|
401
553
|
return this._sortOrder$.asObservable();
|
|
@@ -403,8 +555,52 @@ class CoreComponent {
|
|
|
403
555
|
set loading(isLoading) {
|
|
404
556
|
this._loading$.next(isLoading);
|
|
405
557
|
}
|
|
406
|
-
set
|
|
407
|
-
this.
|
|
558
|
+
set paginationIndex(pageIndex) {
|
|
559
|
+
this._currentPaginationIndex$.next(pageIndex);
|
|
560
|
+
}
|
|
561
|
+
get paginationIndex() {
|
|
562
|
+
return this._currentPaginationIndex$.getValue();
|
|
563
|
+
}
|
|
564
|
+
set pagingInfo(value) {
|
|
565
|
+
if (value) {
|
|
566
|
+
this._pagingInfo$.next(value);
|
|
567
|
+
if (value.pageCurrent !== this._currentPaginationIndex$.getValue() + 1 &&
|
|
568
|
+
value.pageCurrent !== null) {
|
|
569
|
+
this.paginationIndex = value.pageCurrent - 1;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
/** customClasses
|
|
574
|
+
* @description An object that contains custom classes for various elements in the table.
|
|
575
|
+
* @type {object} - { selectedRow: string, activeRow: string } - default classes are 'gt-selected' and 'gt-active'
|
|
576
|
+
*/
|
|
577
|
+
set customClasses(classes) {
|
|
578
|
+
this._customClasses = { ...this._customClasses, ...classes };
|
|
579
|
+
}
|
|
580
|
+
get customClasses() {
|
|
581
|
+
return this._customClasses;
|
|
582
|
+
}
|
|
583
|
+
/** isRowSelectedFn
|
|
584
|
+
* @description Function to determine if row is selected or not.
|
|
585
|
+
* @type {fn} A function that receives a row object and optional state for current selection that can be used to determine if row should be marked as selected or not. */
|
|
586
|
+
set isRowSelectedFn(fn) {
|
|
587
|
+
this._isRowSelectedFn = fn;
|
|
588
|
+
}
|
|
589
|
+
get isRowSelectedFn() {
|
|
590
|
+
return this._isRowSelectedFn;
|
|
591
|
+
}
|
|
592
|
+
/** trackRowByFn
|
|
593
|
+
* @description A function that returns a unique identifier for each row in the table to optimize rendering when data is added or removed.
|
|
594
|
+
* @type fn - TrackByFunction to retrieve unique id based on index and/or row. Defaults to using `row[this.rowIdKey]`.
|
|
595
|
+
*/
|
|
596
|
+
set trackRowByFn(fn) {
|
|
597
|
+
this._trackRowByFn = fn;
|
|
598
|
+
}
|
|
599
|
+
get trackRowByFn() {
|
|
600
|
+
return this._trackRowByFn;
|
|
601
|
+
}
|
|
602
|
+
_trackRowByFn(index, row) {
|
|
603
|
+
return this.rowIdKey ? row[this.rowIdKey] : row?._id;
|
|
408
604
|
}
|
|
409
605
|
set search(string) {
|
|
410
606
|
this._searchBy$.next(string);
|
|
@@ -413,7 +609,9 @@ class CoreComponent {
|
|
|
413
609
|
this._tableConfig$.next(config);
|
|
414
610
|
}
|
|
415
611
|
set data(data) {
|
|
416
|
-
|
|
612
|
+
if (data) {
|
|
613
|
+
this._data$.next(data);
|
|
614
|
+
}
|
|
417
615
|
}
|
|
418
616
|
set sortOrder(sortConfig) {
|
|
419
617
|
if (JSON.stringify(sortConfig) !== JSON.stringify(this._sortOrder$.value)) {
|
|
@@ -424,31 +622,44 @@ class CoreComponent {
|
|
|
424
622
|
_rowClick(row, index, event) {
|
|
425
623
|
this.rowClick.emit({ row, index, event });
|
|
426
624
|
}
|
|
427
|
-
|
|
625
|
+
_rowActive(row, index, event) {
|
|
626
|
+
this.rowSelect.emit({ row, index, event });
|
|
627
|
+
}
|
|
628
|
+
activateRow(arg, event) {
|
|
428
629
|
if (typeof arg === 'number') {
|
|
429
|
-
this.
|
|
430
|
-
.pipe(map((data) => data[arg]), take(1))
|
|
431
|
-
.subscribe((row) => this.
|
|
630
|
+
this.table$
|
|
631
|
+
.pipe(pluck('data'), map((data) => data[this.paginationIndex][arg]), take(1), takeUntil(this.unsubscribe$))
|
|
632
|
+
.subscribe((row) => this._activateRow(row, arg, event));
|
|
432
633
|
}
|
|
433
634
|
else if (typeof arg === 'string') {
|
|
434
635
|
// TODO: implement hover by id
|
|
435
636
|
}
|
|
436
637
|
else {
|
|
437
|
-
this.
|
|
638
|
+
this._activateRow(null, null);
|
|
438
639
|
}
|
|
439
640
|
}
|
|
440
|
-
|
|
441
|
-
this.
|
|
641
|
+
_activateRow(row, index, event) {
|
|
642
|
+
this._rowActive$.next({ row, index, event });
|
|
442
643
|
}
|
|
443
644
|
get loading$() {
|
|
444
645
|
return this._loading$.pipe(startWith(false), map((value) => (isObservable(value) ? value : of(value))), switchMap((obs) => obs), shareReplay(1));
|
|
445
646
|
}
|
|
647
|
+
/** tableInfo$ - returns observable for table info
|
|
648
|
+
* @return Observable<TableInfo> */
|
|
649
|
+
get tableInfo$() {
|
|
650
|
+
return this._tableInfo$.asObservable().pipe(filter((info) => !!info), shareReplay(1));
|
|
651
|
+
}
|
|
652
|
+
/** tableInfo - returns the current table info
|
|
653
|
+
* @return TableInfo */
|
|
654
|
+
get tableInfo() {
|
|
655
|
+
return this._tableInfo$.getValue();
|
|
656
|
+
}
|
|
446
657
|
/** sortByKey - Sort by key in table row
|
|
447
658
|
* @param key - key to sort by
|
|
448
659
|
* @param { MouseEvent } [$event] - Mouse event triggering sort, if shift key is pressed sort key will be added to already present sort keys
|
|
449
660
|
*/
|
|
450
661
|
sortByKey(key, $event) {
|
|
451
|
-
const shiftKey = $event?.shiftKey;
|
|
662
|
+
const shiftKey = $event?.shiftKey === true;
|
|
452
663
|
const currentOrder = this._sortOrder$.value;
|
|
453
664
|
let sortOrder = 'asc';
|
|
454
665
|
let newOrder = [];
|
|
@@ -496,6 +707,7 @@ class CoreComponent {
|
|
|
496
707
|
key,
|
|
497
708
|
order: sortOrder,
|
|
498
709
|
currentSortOrder: newOrder,
|
|
710
|
+
addSortKey: shiftKey,
|
|
499
711
|
};
|
|
500
712
|
// if event is passed to sort function...
|
|
501
713
|
if ($event) {
|
|
@@ -504,17 +716,128 @@ class CoreComponent {
|
|
|
504
716
|
}
|
|
505
717
|
// emit sort event
|
|
506
718
|
this.columnSort.emit(sortEvent);
|
|
507
|
-
//
|
|
508
|
-
this.
|
|
719
|
+
// if table is not lazy loaded (sorting is then handled server-side)...
|
|
720
|
+
if (!this.tableInfo?.lazyLoaded) {
|
|
721
|
+
// ...update sort order
|
|
722
|
+
this.sortOrder = newOrder;
|
|
723
|
+
}
|
|
509
724
|
}
|
|
510
725
|
nestedValue(object, mapTo, missingValue = null) {
|
|
511
726
|
const levels = mapTo.split('.');
|
|
512
727
|
return levels.reduce((previousValue, currentValue, index) => previousValue[currentValue] ||
|
|
513
728
|
(index === levels.length - 1 ? missingValue : {}), object);
|
|
514
729
|
}
|
|
730
|
+
listenToKeyboardEvents() {
|
|
731
|
+
if (!this._tableConfig?.activateRowOnKeyboardNavigation) {
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
this._unsubscribeFromKeyboardEvents$.next(true);
|
|
735
|
+
this._keyboardArrowEvent$
|
|
736
|
+
.pipe(withLatestFrom(this.data$, this.currentPaginationIndex$, this.tableInfo$), takeUntil(this._unsubscribeFromKeyboardEvents$), takeUntil(this.unsubscribe$))
|
|
737
|
+
.subscribe(([event, rows, currentPage, tableInfo]) => {
|
|
738
|
+
const selectEvent = this._selectKeys.includes(event.key);
|
|
739
|
+
if (selectEvent && this.activeRowIndex !== null) {
|
|
740
|
+
const rowIndex = this.activeRowIndex + currentPage * (tableInfo?.pageSize ?? 0);
|
|
741
|
+
this._rowActive(rows[rowIndex], rowIndex, event);
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
const navigationEvent = this._navigationKeys.includes(event.key);
|
|
745
|
+
if (navigationEvent) {
|
|
746
|
+
this._handleNavigationEvent(event, rows, currentPage, tableInfo);
|
|
747
|
+
}
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
unsubscribeFromKeyboardEvents(tableRef) {
|
|
751
|
+
if (!this._tableConfig?.activateRowOnKeyboardNavigation) {
|
|
752
|
+
return;
|
|
753
|
+
}
|
|
754
|
+
// only unsubscribe if table is not focused
|
|
755
|
+
if (tableRef !== document.activeElement) {
|
|
756
|
+
if (this._tableConfig?.activateRowOnHover) {
|
|
757
|
+
// unset active row
|
|
758
|
+
this.activateRow(null);
|
|
759
|
+
}
|
|
760
|
+
this._unsubscribeFromKeyboardEvents$.next(true);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
_handleNavigationEvent(event, rows, currentPage, tableInfo) {
|
|
764
|
+
const hasPagination = (tableInfo?.pageTotal || 0) > 1 && tableInfo;
|
|
765
|
+
const lastRowIndex = rows.length - 1;
|
|
766
|
+
let newIndex = this.activeRowIndex;
|
|
767
|
+
let indexModifier = 0;
|
|
768
|
+
if (event.key === 'Home') {
|
|
769
|
+
this.paginationIndex = 0;
|
|
770
|
+
this.activateRow(0, event);
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
if (event.key === 'End') {
|
|
774
|
+
const indexOfLastRecord = hasPagination
|
|
775
|
+
? rows.length - (tableInfo.pageTotal - 1) * tableInfo.pageSize - 1
|
|
776
|
+
: lastRowIndex;
|
|
777
|
+
if (tableInfo?.pageTotal) {
|
|
778
|
+
this.paginationIndex = tableInfo.pageTotal - 1;
|
|
779
|
+
}
|
|
780
|
+
this.activateRow(indexOfLastRecord, event);
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
if (event.key === 'ArrowDown') {
|
|
784
|
+
indexModifier = 1;
|
|
785
|
+
}
|
|
786
|
+
else if (event.key === 'ArrowUp') {
|
|
787
|
+
indexModifier = -1;
|
|
788
|
+
}
|
|
789
|
+
if (newIndex === null) {
|
|
790
|
+
newIndex = 0;
|
|
791
|
+
}
|
|
792
|
+
else if (newIndex + indexModifier >= 0 &&
|
|
793
|
+
newIndex + indexModifier <= lastRowIndex) {
|
|
794
|
+
newIndex = newIndex + indexModifier;
|
|
795
|
+
}
|
|
796
|
+
if (hasPagination && tableInfo?.pageSize) {
|
|
797
|
+
const isNotLastPage = currentPage + 1 < tableInfo.pageTotal;
|
|
798
|
+
const recordsOnLastPage = rows.length - (tableInfo.pageTotal - 1) * tableInfo.pageSize - 1;
|
|
799
|
+
const maxIndex = isNotLastPage
|
|
800
|
+
? tableInfo?.pageSize - 1
|
|
801
|
+
: recordsOnLastPage;
|
|
802
|
+
if (event.key === 'ArrowLeft' && currentPage > 0) {
|
|
803
|
+
this.paginationIndex = currentPage - 1;
|
|
804
|
+
this.activateRow(newIndex, event);
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
else if (event.key === 'ArrowRight' && isNotLastPage) {
|
|
808
|
+
if (currentPage + 1 === tableInfo.pageTotal - 1 &&
|
|
809
|
+
newIndex > recordsOnLastPage) {
|
|
810
|
+
this.activateRow(recordsOnLastPage, event);
|
|
811
|
+
}
|
|
812
|
+
this.paginationIndex = currentPage + 1;
|
|
813
|
+
this.activateRow(newIndex, event);
|
|
814
|
+
return;
|
|
815
|
+
}
|
|
816
|
+
if (currentPage > 0 &&
|
|
817
|
+
indexModifier < 0 &&
|
|
818
|
+
newIndex + indexModifier <= lastRowIndex &&
|
|
819
|
+
(this.activeRowIndex || 0) + indexModifier < 0) {
|
|
820
|
+
// set last row of previous page as active
|
|
821
|
+
this.activateRow(tableInfo?.pageSize - 1, event);
|
|
822
|
+
this.paginationIndex = currentPage - 1;
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
const pageIndex = newIndex % tableInfo?.pageSize;
|
|
826
|
+
if (newIndex > maxIndex && currentPage + 1 < tableInfo.pageTotal) {
|
|
827
|
+
this.paginationIndex = currentPage + 1;
|
|
828
|
+
}
|
|
829
|
+
this.activateRow(pageIndex > maxIndex ? maxIndex : pageIndex, event);
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
this.activateRow(newIndex, event);
|
|
833
|
+
}
|
|
834
|
+
ngOnDestroy() {
|
|
835
|
+
this.unsubscribe$.next(true);
|
|
836
|
+
this.unsubscribe$.complete();
|
|
837
|
+
}
|
|
515
838
|
}
|
|
516
839
|
CoreComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: CoreComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
517
|
-
CoreComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.1", type: CoreComponent, isStandalone: true, selector: "angular-generic-table", inputs: { loading: "loading", page: "page", search: "search", config: "config", data: "data", sortOrder: "sortOrder" }, outputs: { rowClick: "rowClick", sortOrderChange: "sortOrderChange", rowHover: "rowHover", columnSort: "columnSort" }, 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![(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 });
|
|
840
|
+
CoreComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.1", type: CoreComponent, isStandalone: true, selector: "angular-generic-table", inputs: { navigationKeys: "navigationKeys", selectKeys: "selectKeys", loading: "loading", paginationIndex: "paginationIndex", pagingInfo: "pagingInfo", customClasses: "customClasses", isRowSelectedFn: "isRowSelectedFn", selection: "selection", rowIdKey: "rowIdKey", generateRowId: "generateRowId", trackRowByFn: "trackRowByFn", search: "search", config: "config", data: "data", sortOrder: "sortOrder" }, outputs: { rowClick: "rowClick", rowSelect: "rowSelect", sortOrderChange: "sortOrderChange", rowActive: "rowActive", 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 [tabindex]=\"(tableConfig$ | async)?.activateRowOnKeyboardNavigation ? 0 : -1\"\n #tableRef\n (focus)=\"listenToKeyboardEvents()\"\n (focusout)=\"unsubscribeFromKeyboardEvents(tableRef)\"\n (mouseenter)=\"listenToKeyboardEvents()\"\n (mouseleave)=\"unsubscribeFromKeyboardEvents(tableRef)\"\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 trackBy: trackRowByFn;\n let i = index\n \"\n [attr.id]=\"'tableRow_' + i\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseenter)=\"\n table?.config?.activateRowOnHover && _activateRow(row, i, $event)\n \"\n (mouseleave)=\"\n table?.config?.activateRowOnHover &&\n _activateRow(null, null, $event)\n \"\n [ngClass]=\"[\n !!isRowSelectedFn\n ? (row\n | rowSelection\n : selection\n : isRowSelectedFn\n : customClasses.selectedRow)\n : '',\n (rowActive$ | async)?.index === i ? customClasses.activeRow : ''\n ]\"\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 (mouseenter)=\"\n table?.config?.activateRowOnHover && _activateRow(row, i, $event)\n \"\n (mouseleave)=\"\n table?.config?.activateRowOnHover &&\n _activateRow(null, null, $event)\n \"\n [ngClass]=\"[\n !!isRowSelectedFn\n ? (row\n | rowSelection\n : selection\n : isRowSelectedFn\n : customClasses.selectedRow)\n : '',\n (rowActive$ | async)?.index === i ? customClasses.activeRow : ''\n ]\"\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: RowSelectionPipe, name: "rowSelection" }, { 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 });
|
|
518
841
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: CoreComponent, decorators: [{
|
|
519
842
|
type: Component,
|
|
520
843
|
args: [{ selector: 'angular-generic-table', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
@@ -522,6 +845,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImpor
|
|
|
522
845
|
KeyValuePipe,
|
|
523
846
|
SortClassPipe,
|
|
524
847
|
DashCasePipe,
|
|
848
|
+
RowSelectionPipe,
|
|
525
849
|
AsyncPipe,
|
|
526
850
|
NgTemplateOutlet,
|
|
527
851
|
SlicePipe,
|
|
@@ -530,10 +854,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImpor
|
|
|
530
854
|
NgClass,
|
|
531
855
|
NgIf,
|
|
532
856
|
NgForOf,
|
|
533
|
-
], 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![(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" }]
|
|
534
|
-
}], propDecorators: {
|
|
857
|
+
], 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 [tabindex]=\"(tableConfig$ | async)?.activateRowOnKeyboardNavigation ? 0 : -1\"\n #tableRef\n (focus)=\"listenToKeyboardEvents()\"\n (focusout)=\"unsubscribeFromKeyboardEvents(tableRef)\"\n (mouseenter)=\"listenToKeyboardEvents()\"\n (mouseleave)=\"unsubscribeFromKeyboardEvents(tableRef)\"\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 trackBy: trackRowByFn;\n let i = index\n \"\n [attr.id]=\"'tableRow_' + i\"\n (click)=\"table?.config?.rowClick && _rowClick(row, i, $event)\"\n (mouseenter)=\"\n table?.config?.activateRowOnHover && _activateRow(row, i, $event)\n \"\n (mouseleave)=\"\n table?.config?.activateRowOnHover &&\n _activateRow(null, null, $event)\n \"\n [ngClass]=\"[\n !!isRowSelectedFn\n ? (row\n | rowSelection\n : selection\n : isRowSelectedFn\n : customClasses.selectedRow)\n : '',\n (rowActive$ | async)?.index === i ? customClasses.activeRow : ''\n ]\"\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 (mouseenter)=\"\n table?.config?.activateRowOnHover && _activateRow(row, i, $event)\n \"\n (mouseleave)=\"\n table?.config?.activateRowOnHover &&\n _activateRow(null, null, $event)\n \"\n [ngClass]=\"[\n !!isRowSelectedFn\n ? (row\n | rowSelection\n : selection\n : isRowSelectedFn\n : customClasses.selectedRow)\n : '',\n (rowActive$ | async)?.index === i ? customClasses.activeRow : ''\n ]\"\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" }]
|
|
858
|
+
}], propDecorators: { navigationKeys: [{
|
|
859
|
+
type: Input
|
|
860
|
+
}], selectKeys: [{
|
|
861
|
+
type: Input
|
|
862
|
+
}], loading: [{
|
|
863
|
+
type: Input
|
|
864
|
+
}], paginationIndex: [{
|
|
865
|
+
type: Input
|
|
866
|
+
}], pagingInfo: [{
|
|
867
|
+
type: Input
|
|
868
|
+
}], customClasses: [{
|
|
535
869
|
type: Input
|
|
536
|
-
}],
|
|
870
|
+
}], isRowSelectedFn: [{
|
|
871
|
+
type: Input
|
|
872
|
+
}], selection: [{
|
|
873
|
+
type: Input
|
|
874
|
+
}], rowIdKey: [{
|
|
875
|
+
type: Input
|
|
876
|
+
}], generateRowId: [{
|
|
877
|
+
type: Input
|
|
878
|
+
}], trackRowByFn: [{
|
|
537
879
|
type: Input
|
|
538
880
|
}], search: [{
|
|
539
881
|
type: Input
|
|
@@ -545,13 +887,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImpor
|
|
|
545
887
|
type: Input
|
|
546
888
|
}], rowClick: [{
|
|
547
889
|
type: Output
|
|
890
|
+
}], rowSelect: [{
|
|
891
|
+
type: Output
|
|
548
892
|
}], sortOrderChange: [{
|
|
549
|
-
type: Output
|
|
550
|
-
|
|
551
|
-
}], rowHover: [{
|
|
893
|
+
type: Output
|
|
894
|
+
}], rowActive: [{
|
|
552
895
|
type: Output
|
|
553
896
|
}], columnSort: [{
|
|
554
897
|
type: Output
|
|
898
|
+
}], pageChange: [{
|
|
899
|
+
type: Output
|
|
555
900
|
}] } });
|
|
556
901
|
|
|
557
902
|
class GtDeltaComponent {
|
|
@@ -685,6 +1030,7 @@ GenericTableCoreModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0",
|
|
|
685
1030
|
SortClassPipe,
|
|
686
1031
|
DashCasePipe,
|
|
687
1032
|
HighlightPipe,
|
|
1033
|
+
RowSelectionPipe,
|
|
688
1034
|
CapitalCasePipe,
|
|
689
1035
|
CapitalCasePipe,
|
|
690
1036
|
DynamicPipe,
|
|
@@ -701,18 +1047,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImpor
|
|
|
701
1047
|
SortClassPipe,
|
|
702
1048
|
DashCasePipe,
|
|
703
1049
|
HighlightPipe,
|
|
1050
|
+
RowSelectionPipe,
|
|
704
1051
|
CapitalCasePipe,
|
|
705
1052
|
CapitalCasePipe,
|
|
706
1053
|
DynamicPipe,
|
|
707
1054
|
GtDeltaComponent,
|
|
708
1055
|
],
|
|
709
1056
|
exports: [CoreComponent, GtDeltaComponent],
|
|
1057
|
+
declarations: [],
|
|
710
1058
|
}]
|
|
711
1059
|
}] });
|
|
712
1060
|
|
|
713
1061
|
class PaginationComponent {
|
|
714
1062
|
constructor() {
|
|
715
|
-
this.
|
|
1063
|
+
this._table$ = new ReplaySubject(1);
|
|
716
1064
|
this._ariaLabels = {
|
|
717
1065
|
nav: 'Table pagination',
|
|
718
1066
|
button: 'Go to page ',
|
|
@@ -723,58 +1071,111 @@ class PaginationComponent {
|
|
|
723
1071
|
button: 'page-link',
|
|
724
1072
|
};
|
|
725
1073
|
this._paginationLength = 5;
|
|
726
|
-
|
|
1074
|
+
/** paginationListItems$ - observable for page numbers to show based on number of pages and current position */
|
|
1075
|
+
this.paginationListItems$ = this._table$.pipe(switchMap((core) => combineLatest([
|
|
1076
|
+
core?.table$.pipe(pluck('info')),
|
|
1077
|
+
core?.currentPaginationIndex$,
|
|
1078
|
+
])), map(([info, currentPage]) => this._generateList(info.pageTotal, currentPage)), shareReplay(1));
|
|
1079
|
+
}
|
|
1080
|
+
get pagingInfo() {
|
|
1081
|
+
return (this._pagingInfo || {
|
|
1082
|
+
pageNext: null,
|
|
1083
|
+
pageCurrent: null,
|
|
1084
|
+
pagePrevious: null,
|
|
1085
|
+
pageSize: null,
|
|
1086
|
+
numberOfRecords: null,
|
|
1087
|
+
pageTotal: null,
|
|
1088
|
+
});
|
|
1089
|
+
}
|
|
1090
|
+
/** pagingInfo
|
|
1091
|
+
* @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).
|
|
1092
|
+
* @type info - metadata for pagination component
|
|
1093
|
+
*/
|
|
1094
|
+
set pagingInfo(info) {
|
|
1095
|
+
this._pagingInfo = info;
|
|
727
1096
|
}
|
|
728
1097
|
get paginationLength() {
|
|
729
1098
|
return this._paginationLength;
|
|
730
1099
|
}
|
|
731
|
-
|
|
732
|
-
|
|
1100
|
+
/** paginationLength
|
|
1101
|
+
* @description number of buttons to show in pagination
|
|
1102
|
+
* @type length - number of buttons to show. Defaults to: `5`
|
|
1103
|
+
*/
|
|
1104
|
+
set paginationLength(length) {
|
|
1105
|
+
this._paginationLength = +length;
|
|
733
1106
|
}
|
|
734
1107
|
get classes() {
|
|
735
1108
|
return this._classes;
|
|
736
1109
|
}
|
|
737
|
-
|
|
738
|
-
|
|
1110
|
+
/** classes
|
|
1111
|
+
* @description classes that should be used within pagination component for different elements
|
|
1112
|
+
* @type classes - classes to be used. Defaults to: `{
|
|
1113
|
+
* ul: 'pagination',
|
|
1114
|
+
* li: 'page-item',
|
|
1115
|
+
* button: 'page-link',
|
|
1116
|
+
* }`
|
|
1117
|
+
*/
|
|
1118
|
+
set classes(classes) {
|
|
1119
|
+
this._classes = classes;
|
|
739
1120
|
}
|
|
740
1121
|
get ariaLabels() {
|
|
741
1122
|
return this._ariaLabels;
|
|
742
1123
|
}
|
|
743
|
-
|
|
744
|
-
|
|
1124
|
+
/** ariaLabels
|
|
1125
|
+
* @description aria labels that describe pagination component
|
|
1126
|
+
* @type labels - aria labels for pagination. Defaults to: `{
|
|
1127
|
+
* nav: 'Table pagination',
|
|
1128
|
+
* button: 'Go to page ',
|
|
1129
|
+
* }`
|
|
1130
|
+
*/
|
|
1131
|
+
set ariaLabels(labels) {
|
|
1132
|
+
this._ariaLabels = labels;
|
|
745
1133
|
}
|
|
746
1134
|
get table() {
|
|
747
1135
|
return this._table;
|
|
748
1136
|
}
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
1137
|
+
/** table
|
|
1138
|
+
* @description table component to which pagination is attached
|
|
1139
|
+
* @type tableRef - table component
|
|
1140
|
+
*/
|
|
1141
|
+
set table(tableRef) {
|
|
1142
|
+
this._table = tableRef;
|
|
1143
|
+
this._table$.next(tableRef);
|
|
752
1144
|
}
|
|
753
|
-
|
|
1145
|
+
/** generate list - generate an array with page numbers to show based on number of pages and current position
|
|
1146
|
+
* @param numberOfPages number of pages to show
|
|
1147
|
+
* @param currentPosition current position (page index) being shown in table
|
|
1148
|
+
* @returns Array<number> array of page numbers to show
|
|
1149
|
+
*/
|
|
1150
|
+
_generateList(numberOfPages, currentPosition) {
|
|
754
1151
|
const middle = Math.floor(this.paginationLength / 2);
|
|
755
|
-
const length =
|
|
1152
|
+
const length = numberOfPages < this.paginationLength
|
|
1153
|
+
? numberOfPages
|
|
1154
|
+
: this.paginationLength;
|
|
756
1155
|
return Array.from({ length }, (_, i) => {
|
|
757
1156
|
if (i === 0) {
|
|
758
1157
|
return 1;
|
|
759
1158
|
}
|
|
760
|
-
else if (
|
|
1159
|
+
else if (numberOfPages < this.paginationLength) {
|
|
761
1160
|
return i + 1;
|
|
762
1161
|
}
|
|
763
1162
|
else if (i + 1 === length) {
|
|
764
|
-
return
|
|
1163
|
+
return numberOfPages;
|
|
765
1164
|
}
|
|
766
|
-
else if (currentPosition > middle &&
|
|
1165
|
+
else if (currentPosition > middle &&
|
|
1166
|
+
currentPosition < numberOfPages - middle) {
|
|
767
1167
|
return i + currentPosition - (middle - 1);
|
|
768
1168
|
}
|
|
769
1169
|
else if (currentPosition > middle &&
|
|
770
|
-
currentPosition <
|
|
1170
|
+
currentPosition < numberOfPages - (middle - 1)) {
|
|
771
1171
|
return i + currentPosition - middle;
|
|
772
1172
|
}
|
|
773
1173
|
else if (currentPosition > middle &&
|
|
774
|
-
currentPosition ===
|
|
1174
|
+
currentPosition === numberOfPages - (middle - 1)) {
|
|
775
1175
|
return i + currentPosition - (middle + 1);
|
|
776
1176
|
}
|
|
777
|
-
else if (currentPosition > middle &&
|
|
1177
|
+
else if (currentPosition > middle &&
|
|
1178
|
+
currentPosition === numberOfPages - 1) {
|
|
778
1179
|
return i + currentPosition - (middle + 2);
|
|
779
1180
|
}
|
|
780
1181
|
else {
|
|
@@ -782,18 +1183,23 @@ class PaginationComponent {
|
|
|
782
1183
|
}
|
|
783
1184
|
});
|
|
784
1185
|
}
|
|
785
|
-
|
|
1186
|
+
/** go to page
|
|
1187
|
+
* @param index - page index to go to
|
|
1188
|
+
*/
|
|
1189
|
+
goToPage(index) {
|
|
786
1190
|
if (this.table) {
|
|
787
|
-
this.table.
|
|
1191
|
+
this.table.paginationIndex = index - 1;
|
|
788
1192
|
}
|
|
789
1193
|
}
|
|
790
1194
|
}
|
|
791
1195
|
PaginationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: PaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
792
|
-
PaginationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.1", 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:
|
|
1196
|
+
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 });
|
|
793
1197
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: PaginationComponent, decorators: [{
|
|
794
1198
|
type: Component,
|
|
795
|
-
args: [{ selector: 'angular-generic-table-pagination', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
796
|
-
}], propDecorators: {
|
|
1199
|
+
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" }]
|
|
1200
|
+
}], propDecorators: { pagingInfo: [{
|
|
1201
|
+
type: Input
|
|
1202
|
+
}], paginationLength: [{
|
|
797
1203
|
type: Input
|
|
798
1204
|
}], classes: [{
|
|
799
1205
|
type: Input
|
|
@@ -824,5 +1230,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImpor
|
|
|
824
1230
|
* Generated bundle index. Do not edit.
|
|
825
1231
|
*/
|
|
826
1232
|
|
|
827
|
-
export { CoreComponent, CoreService, GenericTableCoreModule, GenericTablePaginationModule, GtDeltaComponent, PaginationComponent };
|
|
1233
|
+
export { CapitalCasePipe, CoreComponent, CoreService, DashCasePipe, DynamicPipe, GenericTableCoreModule, GenericTablePaginationModule, GtDeltaComponent, HighlightPipe, PaginationComponent, SortClassPipe, calculate, capitalize, chunk, dashed, parseSortOrderParams, search, sortOnMultipleKeys, sortOrderConfigToParam, sortOrderToParams };
|
|
828
1234
|
//# sourceMappingURL=angular-generic-table-core.mjs.map
|