@ngrdt/table 0.0.66

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.
@@ -0,0 +1,1100 @@
1
+ import * as i0 from '@angular/core';
2
+ import { computed, untracked, input, Directive, ViewEncapsulation, ChangeDetectionStrategy, Component, inject, linkedSignal, booleanAttribute, signal, output, Injector, ChangeDetectorRef, Renderer2, afterRenderEffect, ElementRef, ViewChildren, ViewChild, effect, CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
3
+ import { RdtRouterService } from '@ngrdt/router';
4
+ import { signalStore, withState, withHooks, withComputed, withMethods, patchState } from '@ngrx/signals';
5
+ import { withEntities, setAllEntities } from '@ngrx/signals/entities';
6
+ import * as i1$1 from '@angular/common';
7
+ import { CommonModule } from '@angular/common';
8
+ import * as i1 from '@angular/forms';
9
+ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
10
+ import * as i3 from '@angular/cdk/table';
11
+ import { CdkTableModule } from '@angular/cdk/table';
12
+ import * as i4 from '@ngrdt/forms';
13
+ import { RdtCheckboxOutletDirective } from '@ngrdt/forms';
14
+ import * as i2 from '@ngrdt/icon';
15
+ import { RdtIconRegistryService, RdtIcon, RdtIconOutletDirective } from '@ngrdt/icon';
16
+ import { RdtDateUtils, RdtObjectUtils } from '@ngrdt/utils';
17
+ import { of, delay, combineLatest, map } from 'rxjs';
18
+ import { toObservable } from '@angular/core/rxjs-interop';
19
+ import { GovDesignSystemModule } from '@gov-design-system-ce/angular';
20
+
21
+ const RDT_TABLE_PAGE_SIZE_OPTIONS = [20, 50, 100];
22
+ const RDT_TABLE_DEFAULT_PAGE_SIZE = RDT_TABLE_PAGE_SIZE_OPTIONS[0];
23
+ const RDT_TABLE_DEFAULT_NOT_FOUND_HEADER = 'Nic nenalezeno';
24
+ const RDT_TABLE_DEFAULT_NOT_FOUND_MESSAGE = 'Nepodařilo se dohledat žádné výsledky, zkuste prosím hledaný výraz upravit.';
25
+ const RDT_TABLE_DEFAULT_ERROR_MESSAGE = 'Při načítání dat došlo k chybě.';
26
+ const RDT_TABLE_DEFAULT_ERROR_HEADER = 'Chyba';
27
+
28
+ function isRdtTableMessage(obj) {
29
+ return (obj && typeof obj.header === 'string' && typeof obj.message === 'string');
30
+ }
31
+
32
+ const rdtTableInitialState = {
33
+ ready: false,
34
+ pageIndex: 0,
35
+ pageSize: RDT_TABLE_DEFAULT_PAGE_SIZE,
36
+ pageSizeOptions: RDT_TABLE_PAGE_SIZE_OPTIONS,
37
+ totalCount: 0,
38
+ selectedIds: {},
39
+ loading: true,
40
+ totalCountKnown: true,
41
+ displayedColumns: [],
42
+ datasource: null,
43
+ headerFilters: [],
44
+ staticFilters: [],
45
+ extendedFilter: null,
46
+ sort: null,
47
+ selectId: (item) => ('id' in item ? item.id : JSON.stringify(item)),
48
+ _fetchWhenDatasourceSet: false,
49
+ fetchError: null,
50
+ _fetchSubscription: null,
51
+ };
52
+
53
+ function getRdtTableStore(initialState = rdtTableInitialState) {
54
+ return signalStore(withState(initialState), withEntities(), withHooks({
55
+ onDestroy(store) {
56
+ store._fetchSubscription?.()?.unsubscribe();
57
+ },
58
+ }), withComputed((state) => ({
59
+ allFilters: computed(() => [
60
+ ...state.headerFilters(),
61
+ ...state.staticFilters(),
62
+ state.extendedFilter(),
63
+ ]),
64
+ pageCount: computed(() => {
65
+ const totalCount = state.totalCount();
66
+ const pageSize = state.pageSize();
67
+ return totalCount ? Math.ceil(totalCount / pageSize) : 0;
68
+ }),
69
+ selectedItems: computed(() => {
70
+ const selection = state.selectedIds();
71
+ const selectId = state.selectId();
72
+ if (!selection || !Object.keys(selection).length) {
73
+ return [];
74
+ }
75
+ return state.entities().filter((item) => selection[selectId(item)]);
76
+ }),
77
+ selectedAll: computed(() => {
78
+ const selection = state.selectedIds();
79
+ const items = state.entities();
80
+ if (!selection || !Object.keys(selection).length) {
81
+ return false;
82
+ }
83
+ return (items.length > 0 && items.length === Object.keys(selection).length);
84
+ }),
85
+ requestParams: computed(() => ({
86
+ filters: [...state.headerFilters(), ...state.staticFilters()],
87
+ extendedFilter: state.extendedFilter() ?? null,
88
+ sort: state.sort?.() ?? null,
89
+ pageIndex: state.pageIndex(),
90
+ pageSize: state.pageSize(),
91
+ })),
92
+ firstRowIndex: computed(() => {
93
+ const pageIndex = state.pageIndex();
94
+ const pageSize = state.pageSize();
95
+ return pageIndex * pageSize;
96
+ }),
97
+ lastRowIndex: computed(() => {
98
+ const startIndex = state.pageIndex() * state.pageSize();
99
+ const pageSize = state.pageSize();
100
+ return Math.min(startIndex + pageSize, state.totalCount()) - 1;
101
+ }),
102
+ })), withMethods((store) => ({
103
+ fetch() {
104
+ const datasource = untracked(store.datasource);
105
+ if (!datasource) {
106
+ patchState(store, { _fetchWhenDatasourceSet: true });
107
+ return;
108
+ }
109
+ untracked(store._fetchSubscription)?.unsubscribe();
110
+ const requestParams = untracked(store.requestParams);
111
+ const observer = this._getFetchObserver(requestParams);
112
+ patchState(store, { loading: true });
113
+ const sub = datasource.getData(requestParams).subscribe(observer);
114
+ patchState(store, { _fetchSubscription: sub });
115
+ },
116
+ _getFetchObserver(requestParams) {
117
+ return {
118
+ next: (page) => this._onFetchSuccess(page, requestParams),
119
+ error: (error) => this._onFetchError(error),
120
+ complete: () => this._onFetchComplete(),
121
+ };
122
+ },
123
+ _onFetchSuccess(page, requestParams) {
124
+ const selectId = untracked(store.selectId);
125
+ patchState(store, {
126
+ totalCount: page.totalCount ??
127
+ Math.max(untracked(store.totalCount), page.pageIndex * requestParams.pageSize + page.data.length),
128
+ pageIndex: page.pageIndex,
129
+ totalCountKnown: page.totalCount !== null ||
130
+ page.data.length < requestParams.pageSize,
131
+ loading: false,
132
+ _fetchSubscription: null,
133
+ fetchError: null,
134
+ });
135
+ patchState(store, setAllEntities(page.data, { selectId: selectId }));
136
+ },
137
+ _onFetchError(error) {
138
+ const selectId = untracked(store.selectId);
139
+ patchState(store, {
140
+ loading: false,
141
+ fetchError: getRdtTableError(error),
142
+ totalCount: 0,
143
+ totalCountKnown: true,
144
+ pageIndex: 0,
145
+ _fetchSubscription: null,
146
+ });
147
+ patchState(store, setAllEntities([], { selectId: selectId }));
148
+ },
149
+ _onFetchComplete() {
150
+ patchState(store, {
151
+ _fetchSubscription: null,
152
+ loading: false,
153
+ });
154
+ },
155
+ setPagination(pageSize, pageIndex) {
156
+ patchState(store, { pageSize, pageIndex });
157
+ this.unselectAll();
158
+ },
159
+ setSort(sort) {
160
+ patchState(store, {
161
+ sort,
162
+ });
163
+ this.unselectAll();
164
+ },
165
+ setHeaderFilters(filters) {
166
+ patchState(store, {
167
+ headerFilters: filters,
168
+ });
169
+ this.resetTotalCountKnown();
170
+ this.unselectAll();
171
+ },
172
+ setStaticFilters(filters) {
173
+ patchState(store, {
174
+ staticFilters: filters,
175
+ });
176
+ this.unselectAll();
177
+ this.resetTotalCountKnown();
178
+ },
179
+ setExtendedFilter(filters) {
180
+ patchState(store, {
181
+ extendedFilter: filters,
182
+ });
183
+ this.unselectAll();
184
+ this.resetTotalCountKnown();
185
+ },
186
+ setReady() {
187
+ const _fetchWhenDatasourceSet = untracked(store._fetchWhenDatasourceSet);
188
+ if (untracked(store.datasource) && _fetchWhenDatasourceSet) {
189
+ patchState(store, { ready: true, _fetchWhenDatasourceSet: false });
190
+ this.fetch();
191
+ }
192
+ else {
193
+ patchState(store, { ready: true });
194
+ }
195
+ },
196
+ setDatasource(datasource) {
197
+ untracked(store._fetchSubscription)?.unsubscribe();
198
+ const _fetchWhenDatasourceSet = untracked(store._fetchWhenDatasourceSet);
199
+ patchState(store, {
200
+ datasource,
201
+ _fetchSubscription: null,
202
+ fetchError: null,
203
+ totalCountKnown: datasource.totalCountKnown,
204
+ });
205
+ if (untracked(store.ready) && _fetchWhenDatasourceSet) {
206
+ patchState(store, { _fetchWhenDatasourceSet: false });
207
+ this.fetch();
208
+ }
209
+ },
210
+ selectAll() {
211
+ const items = untracked(store.entities);
212
+ const selectedIds = {};
213
+ items.forEach((item) => {
214
+ selectedIds[untracked(store.selectId)(item)] = true;
215
+ });
216
+ patchState(store, { selectedIds });
217
+ },
218
+ unselectAll() {
219
+ patchState(store, {
220
+ selectedIds: {},
221
+ });
222
+ },
223
+ toggleSelectAll() {
224
+ if (untracked(store.selectedAll)) {
225
+ this.unselectAll();
226
+ }
227
+ else {
228
+ this.selectAll();
229
+ }
230
+ },
231
+ resetTotalCountKnown() {
232
+ patchState(store, {
233
+ totalCountKnown: untracked(store.datasource)?.totalCountKnown ?? true,
234
+ });
235
+ },
236
+ toggleSelectItem(item) {
237
+ const selectId = untracked(store.selectId);
238
+ const oldIds = untracked(store.selectedIds);
239
+ const id = selectId(item);
240
+ const selectedIds = { ...oldIds, [id]: !oldIds[id] };
241
+ patchState(store, { selectedIds });
242
+ },
243
+ toggleSelectSingleItem(item) {
244
+ const selectId = untracked(store.selectId);
245
+ const oldIds = untracked(store.selectedIds);
246
+ const id = selectId(item);
247
+ if (oldIds[id]) {
248
+ patchState(store, { selectedIds: {} });
249
+ }
250
+ else {
251
+ patchState(store, { selectedIds: { [id]: true } });
252
+ }
253
+ },
254
+ cancelFetch() {
255
+ untracked(store._fetchSubscription)?.unsubscribe();
256
+ patchState(store, {
257
+ _fetchSubscription: null,
258
+ loading: false,
259
+ fetchError: null,
260
+ });
261
+ },
262
+ isSelected(item) {
263
+ const selectId = untracked(store.selectId);
264
+ return !!untracked(store.selectedIds)[selectId(item)];
265
+ },
266
+ getSortDirection(column) {
267
+ const currentSort = store.sort();
268
+ if (currentSort?.key === column.sortKey) {
269
+ return currentSort.direction;
270
+ }
271
+ return null;
272
+ },
273
+ resetHeaderFilters() {
274
+ this.setHeaderFilters([]);
275
+ },
276
+ toggleSort(column) {
277
+ const currentSort = untracked(store.sort);
278
+ const sortKey = column.sortKey ?? column.key;
279
+ let direction = 'asc';
280
+ if (currentSort?.key === sortKey) {
281
+ switch (currentSort.direction) {
282
+ case 'asc':
283
+ direction = 'desc';
284
+ break;
285
+ case 'desc':
286
+ this.setSort(null);
287
+ this.fetch();
288
+ return;
289
+ }
290
+ }
291
+ else {
292
+ direction = 'asc';
293
+ }
294
+ const sort = {
295
+ key: column.key,
296
+ direction,
297
+ type: column.cellRendererParams?.dataType ?? 'string',
298
+ };
299
+ this.setSort(sort);
300
+ this.fetch();
301
+ },
302
+ setDisplayedColumns(displayedColumns) {
303
+ patchState(store, { displayedColumns });
304
+ },
305
+ })));
306
+ }
307
+ const RdtTableStore = getRdtTableStore();
308
+ function getRdtTableError(error) {
309
+ if (isRdtTableMessage(error)) {
310
+ return error;
311
+ }
312
+ if (typeof error === 'string') {
313
+ return { message: error, header: RDT_TABLE_DEFAULT_ERROR_HEADER };
314
+ }
315
+ if (error && typeof error === 'object' && 'message' in error) {
316
+ return { message: error.message, header: RDT_TABLE_DEFAULT_ERROR_HEADER };
317
+ }
318
+ return {
319
+ header: RDT_TABLE_DEFAULT_ERROR_HEADER,
320
+ message: RDT_TABLE_DEFAULT_ERROR_MESSAGE,
321
+ };
322
+ }
323
+
324
+ function selectIdTransform(value) {
325
+ if (typeof value === 'function') {
326
+ return value;
327
+ }
328
+ return (item) => item[value];
329
+ }
330
+
331
+ /* import humanizeString from 'humanize-string'; */
332
+ class RdtBaseColumnBuilder {
333
+ _key;
334
+ _header;
335
+ _sortable = false;
336
+ _sortKey;
337
+ _cellClass = '';
338
+ _cellStyle = '';
339
+ _headerStyle = '';
340
+ _headerClass = '';
341
+ _minWidth;
342
+ _maxWidth;
343
+ _interactive = () => false;
344
+ _sticky;
345
+ constructor(key) {
346
+ this._key = key;
347
+ }
348
+ withSticky(sticky = 'end') {
349
+ this._sticky = sticky;
350
+ return this;
351
+ }
352
+ withHeader(header) {
353
+ this._header = header;
354
+ return this;
355
+ }
356
+ withSortable(sortable = true) {
357
+ this._sortable = sortable;
358
+ return this;
359
+ }
360
+ withSortKey(sortKey) {
361
+ this._sortKey = sortKey;
362
+ return this;
363
+ }
364
+ withCellClass(cellClass) {
365
+ this._cellClass = cellClass;
366
+ return this;
367
+ }
368
+ withCellStyle(cellStyle) {
369
+ this._cellStyle = cellStyle;
370
+ return this;
371
+ }
372
+ withHeaderStyle(headerStyle) {
373
+ this._headerStyle = headerStyle;
374
+ return this;
375
+ }
376
+ withHeaderClass(headerClass) {
377
+ this._headerClass = headerClass;
378
+ return this;
379
+ }
380
+ withMinWidth(minWidth) {
381
+ this._minWidth = typeof minWidth === 'string' ? minWidth : `${minWidth}px`;
382
+ return this;
383
+ }
384
+ withMaxWidth(maxWidth) {
385
+ this._maxWidth = typeof maxWidth === 'string' ? maxWidth : `${maxWidth}px`;
386
+ return this;
387
+ }
388
+ withInteractive(interactive = true) {
389
+ this._interactive =
390
+ typeof interactive === 'function' ? interactive : () => interactive;
391
+ return this;
392
+ }
393
+ getCellClassFn() {
394
+ const cellClass = this._cellClass;
395
+ return typeof cellClass === 'function' ? cellClass : () => cellClass;
396
+ }
397
+ getCellStyleFn() {
398
+ const cellStyle = this._cellStyle;
399
+ return typeof cellStyle === 'function' ? cellStyle : () => cellStyle;
400
+ }
401
+ getSortKey() {
402
+ return this._sortKey ?? this._key;
403
+ }
404
+ getHeader() {
405
+ return this._header ?? this._key; /* ?? humanizeString(this._key); */
406
+ }
407
+ build() {
408
+ return {
409
+ key: this._key,
410
+ header: this.getHeader(),
411
+ sortable: this._sortable,
412
+ sortKey: this.getSortKey(),
413
+ cellClass: this.getCellClassFn(),
414
+ cellStyle: this.getCellStyleFn(),
415
+ headerStyle: this._headerStyle,
416
+ headerClass: this._headerClass,
417
+ cellRenderer: this.getCellRenderer(),
418
+ cellRendererParams: this.getCellRendererParams(),
419
+ interactive: this._interactive,
420
+ minWidth: this._minWidth,
421
+ maxWidth: this._maxWidth,
422
+ sticky: this._sticky,
423
+ };
424
+ }
425
+ }
426
+
427
+ class RdtBaseCellRendererComponent {
428
+ row = input.required();
429
+ index = input.required();
430
+ store = input.required();
431
+ cellRendererParams = input.required();
432
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtBaseCellRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
433
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.0", type: RdtBaseCellRendererComponent, isStandalone: true, selector: "rdt-base-cell-renderer", inputs: { row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null }, index: { classPropertyName: "index", publicName: "index", isSignal: true, isRequired: true, transformFunction: null }, store: { classPropertyName: "store", publicName: "store", isSignal: true, isRequired: true, transformFunction: null }, cellRendererParams: { classPropertyName: "cellRendererParams", publicName: "cellRendererParams", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
434
+ }
435
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtBaseCellRendererComponent, decorators: [{
436
+ type: Directive,
437
+ args: [{
438
+ selector: 'rdt-base-cell-renderer',
439
+ }]
440
+ }] });
441
+
442
+ class RdtStaticCellRendererComponent extends RdtBaseCellRendererComponent {
443
+ value = computed(() => this.cellRendererParams().valueFormatter(this.row()));
444
+ tooltip = computed(() => this.cellRendererParams().tooltipFormatter(this.row()));
445
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtStaticCellRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
446
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.0", type: RdtStaticCellRendererComponent, isStandalone: false, selector: "rdt-static-cell-renderer", host: { classAttribute: "cell-value-base" }, usesInheritance: true, ngImport: i0, template: "@let val = value();\n{{ val }}\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
447
+ }
448
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtStaticCellRendererComponent, decorators: [{
449
+ type: Component,
450
+ args: [{ selector: 'rdt-static-cell-renderer', host: {
451
+ class: 'cell-value-base',
452
+ }, standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "@let val = value();\n{{ val }}\n" }]
453
+ }] });
454
+
455
+ class RdtStaticColumnBuilder extends RdtBaseColumnBuilder {
456
+ _dataType = 'string';
457
+ _valueFormatter;
458
+ _tooltipFormatter;
459
+ _enumValues;
460
+ _tooltipEnabled = true;
461
+ constructor(key) {
462
+ super(key);
463
+ }
464
+ withDataType(dataType) {
465
+ this._dataType = dataType;
466
+ return this;
467
+ }
468
+ withValueFormatter(formatter) {
469
+ this._valueFormatter = formatter;
470
+ return this;
471
+ }
472
+ withTooltipFormatter(formatter) {
473
+ this._tooltipFormatter = formatter;
474
+ return this;
475
+ }
476
+ withTooltipEnabled(enabled) {
477
+ this._tooltipEnabled = enabled;
478
+ return this;
479
+ }
480
+ withEnumValues(enumValues) {
481
+ this._enumValues = enumValues;
482
+ return this;
483
+ }
484
+ getCellRenderer() {
485
+ return RdtStaticCellRendererComponent;
486
+ }
487
+ formatNumber(value) {
488
+ let numericValue;
489
+ if (typeof value === 'number') {
490
+ numericValue = value;
491
+ }
492
+ else if (value == null) {
493
+ return '';
494
+ }
495
+ else if (typeof value === 'string') {
496
+ numericValue = Number(value);
497
+ if (isNaN(numericValue)) {
498
+ return value;
499
+ }
500
+ }
501
+ else {
502
+ return '';
503
+ }
504
+ return numericValue.toFixed(2).replace(/\.0+$/, '');
505
+ }
506
+ formatDecimal(value) {
507
+ if (typeof value === 'number') {
508
+ return value.toFixed(2);
509
+ }
510
+ else if (typeof value === 'string') {
511
+ const num = parseFloat(value);
512
+ return isNaN(num) ? value : num.toFixed(2);
513
+ }
514
+ return '';
515
+ }
516
+ formatDate(value) {
517
+ return RdtDateUtils.formatDate(value);
518
+ }
519
+ formatDateTime(date) {
520
+ if (date === null || date === undefined || date === '') {
521
+ return '';
522
+ }
523
+ const d = date instanceof Date ? date : new Date(date);
524
+ if (RdtDateUtils.isValidDate(d)) {
525
+ const year = d.getFullYear();
526
+ const month = `${d.getMonth() + 1}`.padStart(2, '0');
527
+ const day = `${d.getDate()}`.padStart(2, '0');
528
+ const hour = `${d.getHours()}`.padStart(2, '0');
529
+ const minute = `${d.getMinutes()}`.padStart(2, '0');
530
+ return `${day}.${month}.${year} ${hour}:${minute}`;
531
+ }
532
+ else {
533
+ return '';
534
+ }
535
+ }
536
+ formatBoolean(value) {
537
+ switch (value) {
538
+ case true:
539
+ case 'true':
540
+ case 1:
541
+ case '1':
542
+ return 'Ano';
543
+ case false:
544
+ case 'false':
545
+ case 0:
546
+ case '0':
547
+ return 'Ne';
548
+ default:
549
+ return '';
550
+ }
551
+ }
552
+ formatEnum(value) {
553
+ if (!this._enumValues) {
554
+ throw new Error('Enum values are not set');
555
+ }
556
+ return this._enumValues[value] || value;
557
+ }
558
+ getValueFormatter() {
559
+ if (this._valueFormatter) {
560
+ return this._valueFormatter;
561
+ }
562
+ switch (this._dataType) {
563
+ case 'boolean':
564
+ return (row) => this.formatBoolean(this.pluck(row, this._key));
565
+ case 'date':
566
+ return (row) => this.formatDate(this.pluck(row, this._key));
567
+ case 'date-time':
568
+ return (row) => this.formatDateTime(this.pluck(row, this._key));
569
+ case 'decimal':
570
+ return (row) => this.formatDecimal(this.pluck(row, this._key));
571
+ case 'enum':
572
+ return (row) => this.formatEnum(this.pluck(row, this._key));
573
+ case 'number':
574
+ return (row) => this.formatNumber(this.pluck(row, this._key));
575
+ default:
576
+ return (row) => this.pluck(row, this._key);
577
+ }
578
+ }
579
+ pluck(row, key) {
580
+ if (key in row) {
581
+ return row[key];
582
+ }
583
+ else {
584
+ return RdtObjectUtils.pluck(row, key);
585
+ }
586
+ }
587
+ getTooltipFormatter() {
588
+ return this._tooltipFormatter ?? this.getValueFormatter();
589
+ }
590
+ getCellRendererParams() {
591
+ return {
592
+ dataType: this._dataType,
593
+ valueFormatter: this.getValueFormatter(),
594
+ tooltipEnabled: this._tooltipEnabled,
595
+ tooltipFormatter: this.getTooltipFormatter(),
596
+ };
597
+ }
598
+ }
599
+
600
+ class RdtTableDatasource {
601
+ totalCountKnown = true;
602
+ }
603
+
604
+ class RdtTablePaginatorComponent {
605
+ store = inject(RdtTableStore);
606
+ iconRegistry = inject(RdtIconRegistryService);
607
+ from = computed(() => this.store.totalCount() > 0 ? this.store.firstRowIndex() + 1 : 0);
608
+ to = computed(() => this.store.lastRowIndex() + 1);
609
+ total = computed(() => this.store.totalCount());
610
+ pageSize = computed(() => this.store.pageSize());
611
+ currentPageNumber = computed(() => this.store.pageIndex() + 1);
612
+ pageSizeOptions = computed(() => this.store.pageSizeOptions().map((opt) => ({ label: `${opt}`, value: opt })));
613
+ pageCount = computed(() => this.store.pageCount());
614
+ skipRightIcon = this.iconRegistry.getIcon(RdtIcon.SkipRight);
615
+ skipDoubleRightIcon = this.iconRegistry.getIcon(RdtIcon.SkipDoubleRight);
616
+ skipLeftIcon = this.iconRegistry.getIcon(RdtIcon.SkipLeft);
617
+ skipDoubleLeftIcon = this.iconRegistry.getIcon(RdtIcon.SkipDoubleLeft);
618
+ pageWindow = computed(() => {
619
+ const pageCount = this.pageCount();
620
+ const current = this.currentPageNumber();
621
+ const windowSize = 2;
622
+ const start = Math.max(1, current - windowSize);
623
+ const end = Math.min(pageCount, current + windowSize);
624
+ const pages = [];
625
+ for (let i = start; i <= end; i++) {
626
+ pages.push(i);
627
+ }
628
+ return pages;
629
+ });
630
+ onPageSizeChange(event) {
631
+ const value = event.target.value;
632
+ const pageSize = parseInt(value);
633
+ this.store.setPagination(pageSize ?? 10, 0);
634
+ this.store.fetch();
635
+ }
636
+ onPageChange(pageNumber) {
637
+ const pageIndex = pageNumber - 1;
638
+ this.store.setPagination(this.pageSize(), pageIndex);
639
+ this.store.fetch();
640
+ }
641
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtTablePaginatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
642
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: RdtTablePaginatorComponent, isStandalone: false, selector: "rdt-table-paginator", ngImport: i0, template: "@if (store.ready()) {\n<div\n class=\"flex flex-row-reverse flex-wrap-reverse justify-between items-center gap-2\"\n [class.invisible]=\"total() === 0\"\n>\n <div class=\"paginator\">\n <div class=\"paginator-info\">\n Zobrazeno <b>{{ from() }} - {{ to() }} z\u00E1znam\u016F z {{ total() }}</b>\n </div>\n <div class=\"paginator-controls\">\n <select\n class=\"action-btn\"\n [value]=\"pageSize()\"\n (change)=\"onPageSizeChange($event)\"\n >\n @for (option of pageSizeOptions(); track $index) {\n <option [value]=\"option.value\">{{ option.value }}</option>\n }\n </select>\n <button\n class=\"action-btn\"\n [disabled]=\"currentPageNumber() === 1\"\n (click)=\"onPageChange(1)\"\n >\n <ng-container\n rdtIconOutlet\n [inputs]=\"{ name: skipDoubleLeftIcon }\"\n ></ng-container>\n <!-- \u2039\u2039 -->\n </button>\n <button\n class=\"action-btn\"\n [disabled]=\"currentPageNumber() === 1\"\n (click)=\"onPageChange(currentPageNumber() - 1)\"\n >\n <ng-container\n rdtIconOutlet\n [inputs]=\"{ name: skipLeftIcon }\"\n ></ng-container>\n <!-- \u2039 -->\n </button>\n @for (page of pageWindow(); track $index) {\n <button\n class=\"action-btn\"\n [class.selected]=\"currentPageNumber() === page\"\n [disabled]=\"currentPageNumber() === page\"\n (click)=\"onPageChange(page)\"\n >\n {{ page }}\n </button>\n }\n <button\n class=\"action-btn\"\n [disabled]=\"currentPageNumber() === pageCount()\"\n (click)=\"onPageChange(currentPageNumber() + 1)\"\n >\n <ng-container\n rdtIconOutlet\n [inputs]=\"{ name: skipRightIcon }\"\n ></ng-container>\n <!-- \u203A -->\n </button>\n <button\n class=\"action-btn\"\n [disabled]=\"currentPageNumber() === pageCount()\"\n (click)=\"onPageChange(pageCount())\"\n >\n <ng-container\n rdtIconOutlet\n [inputs]=\"{ name: skipDoubleRightIcon }\"\n ></ng-container>\n <!-- \u203A\u203A -->\n </button>\n </div>\n </div>\n</div>\n}\n", styles: [".paginator{display:flex;flex-wrap:wrap;justify-content:space-between;margin:1rem 1rem 0}.paginator-controls{display:flex;gap:.3rem}.paginator-controls select{margin-right:10px}\n"], dependencies: [{ kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.RdtIconOutletDirective, selector: "[rdtIconOutlet]", exportAs: ["rdtIconOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
643
+ }
644
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtTablePaginatorComponent, decorators: [{
645
+ type: Component,
646
+ args: [{ selector: 'rdt-table-paginator', changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, encapsulation: ViewEncapsulation.None, template: "@if (store.ready()) {\n<div\n class=\"flex flex-row-reverse flex-wrap-reverse justify-between items-center gap-2\"\n [class.invisible]=\"total() === 0\"\n>\n <div class=\"paginator\">\n <div class=\"paginator-info\">\n Zobrazeno <b>{{ from() }} - {{ to() }} z\u00E1znam\u016F z {{ total() }}</b>\n </div>\n <div class=\"paginator-controls\">\n <select\n class=\"action-btn\"\n [value]=\"pageSize()\"\n (change)=\"onPageSizeChange($event)\"\n >\n @for (option of pageSizeOptions(); track $index) {\n <option [value]=\"option.value\">{{ option.value }}</option>\n }\n </select>\n <button\n class=\"action-btn\"\n [disabled]=\"currentPageNumber() === 1\"\n (click)=\"onPageChange(1)\"\n >\n <ng-container\n rdtIconOutlet\n [inputs]=\"{ name: skipDoubleLeftIcon }\"\n ></ng-container>\n <!-- \u2039\u2039 -->\n </button>\n <button\n class=\"action-btn\"\n [disabled]=\"currentPageNumber() === 1\"\n (click)=\"onPageChange(currentPageNumber() - 1)\"\n >\n <ng-container\n rdtIconOutlet\n [inputs]=\"{ name: skipLeftIcon }\"\n ></ng-container>\n <!-- \u2039 -->\n </button>\n @for (page of pageWindow(); track $index) {\n <button\n class=\"action-btn\"\n [class.selected]=\"currentPageNumber() === page\"\n [disabled]=\"currentPageNumber() === page\"\n (click)=\"onPageChange(page)\"\n >\n {{ page }}\n </button>\n }\n <button\n class=\"action-btn\"\n [disabled]=\"currentPageNumber() === pageCount()\"\n (click)=\"onPageChange(currentPageNumber() + 1)\"\n >\n <ng-container\n rdtIconOutlet\n [inputs]=\"{ name: skipRightIcon }\"\n ></ng-container>\n <!-- \u203A -->\n </button>\n <button\n class=\"action-btn\"\n [disabled]=\"currentPageNumber() === pageCount()\"\n (click)=\"onPageChange(pageCount())\"\n >\n <ng-container\n rdtIconOutlet\n [inputs]=\"{ name: skipDoubleRightIcon }\"\n ></ng-container>\n <!-- \u203A\u203A -->\n </button>\n </div>\n </div>\n</div>\n}\n", styles: [".paginator{display:flex;flex-wrap:wrap;justify-content:space-between;margin:1rem 1rem 0}.paginator-controls{display:flex;gap:.3rem}.paginator-controls select{margin-right:10px}\n"] }]
647
+ }] });
648
+
649
+ class RdtHeaderCellRendererComponent {
650
+ iconRegistry = inject(RdtIconRegistryService);
651
+ store = inject(RdtTableStore);
652
+ column = input.required();
653
+ sortDirection = computed(() => this.store.getSortDirection(this.column()));
654
+ sortAscIcon = this.iconRegistry.getIcon(RdtIcon.SortAsc);
655
+ sortDescIcon = this.iconRegistry.getIcon(RdtIcon.SortDesc);
656
+ sortEnabledIcon = this.iconRegistry.getIcon(RdtIcon.SortEnabled);
657
+ sort(event) {
658
+ if (this.column().sortable) {
659
+ event.stopPropagation();
660
+ this.store.toggleSort(this.column());
661
+ }
662
+ }
663
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtHeaderCellRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
664
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: RdtHeaderCellRendererComponent, isStandalone: false, selector: "rdt-header-cell-renderer", inputs: { column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class.sortable-header-cell": "column().sortable" } }, ngImport: i0, template: "@let col = column();\n<div class=\"space-between\">\n <div class=\"table-header\">\n <span\n (click)=\"sort($event)\"\n (keyup.enter)=\"sort($event)\"\n class=\"header-cell-text\"\n [attr.tabindex]=\"col.sortable ? 0 : -1\"\n [attr.role]=\"col.sortable ? 'button' : 'presentation'\"\n >\n {{ col.header }}\n </span>\n </div>\n @if (col.sortable) { @let direction = sortDirection(); @if (direction ===\n 'asc') {\n <button class=\"action-btn\" (click)=\"sort($event)\">\n <ng-container rdtIconOutlet [inputs]=\"{ name: sortAscIcon }\"></ng-container>\n </button>\n } @else if (direction === 'desc') {\n <button class=\"action-btn\" (click)=\"sort($event)\">\n <ng-container\n rdtIconOutlet\n [inputs]=\"{ name: sortDescIcon }\"\n ></ng-container>\n </button>\n } @else {\n <button class=\"action-btn\" (click)=\"sort($event)\">\n <ng-container\n rdtIconOutlet\n [inputs]=\"{ name: sortEnabledIcon }\"\n ></ng-container>\n </button>\n }}\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i2.RdtIconOutletDirective, selector: "[rdtIconOutlet]", exportAs: ["rdtIconOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
665
+ }
666
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtHeaderCellRendererComponent, decorators: [{
667
+ type: Component,
668
+ args: [{ selector: 'rdt-header-cell-renderer', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, host: {
669
+ '[class.sortable-header-cell]': 'column().sortable',
670
+ }, template: "@let col = column();\n<div class=\"space-between\">\n <div class=\"table-header\">\n <span\n (click)=\"sort($event)\"\n (keyup.enter)=\"sort($event)\"\n class=\"header-cell-text\"\n [attr.tabindex]=\"col.sortable ? 0 : -1\"\n [attr.role]=\"col.sortable ? 'button' : 'presentation'\"\n >\n {{ col.header }}\n </span>\n </div>\n @if (col.sortable) { @let direction = sortDirection(); @if (direction ===\n 'asc') {\n <button class=\"action-btn\" (click)=\"sort($event)\">\n <ng-container rdtIconOutlet [inputs]=\"{ name: sortAscIcon }\"></ng-container>\n </button>\n } @else if (direction === 'desc') {\n <button class=\"action-btn\" (click)=\"sort($event)\">\n <ng-container\n rdtIconOutlet\n [inputs]=\"{ name: sortDescIcon }\"\n ></ng-container>\n </button>\n } @else {\n <button class=\"action-btn\" (click)=\"sort($event)\">\n <ng-container\n rdtIconOutlet\n [inputs]=\"{ name: sortEnabledIcon }\"\n ></ng-container>\n </button>\n }}\n</div>\n" }]
671
+ }] });
672
+
673
+ class RdtTableComponent {
674
+ router = inject(RdtRouterService);
675
+ itemIdFn = input.required({ transform: (selectIdTransform) });
676
+ colDefsInput = input([], { alias: 'colDefs' });
677
+ colDefs = linkedSignal(() => this.colDefsInput());
678
+ size = input('md');
679
+ selectMode = input('none');
680
+ showPaginator = input(true, { transform: booleanAttribute });
681
+ showSelectAll = input(true, { transform: booleanAttribute });
682
+ autoSize = input(true, { transform: booleanAttribute });
683
+ displayedColumns = input(undefined);
684
+ notFoundConfig = input({
685
+ header: RDT_TABLE_DEFAULT_NOT_FOUND_HEADER,
686
+ message: RDT_TABLE_DEFAULT_NOT_FOUND_MESSAGE,
687
+ });
688
+ usesDoubleClickInput = input(false, {
689
+ transform: booleanAttribute,
690
+ alias: 'usesDoubleClick',
691
+ });
692
+ usesDoubleClick = linkedSignal(() => this.usesDoubleClickInput());
693
+ tableEl;
694
+ headerCells = [];
695
+ defaultColumnWidth = 200; //px
696
+ savedColumnWidths = signal(new Map());
697
+ hasInitializedWidths = signal(false);
698
+ explicitWidthsApplied = signal(new Set());
699
+ rowDoubleClick = output();
700
+ selectKey = 'RdtTableSelectColumnKey';
701
+ allColumnKeys = computed(() => {
702
+ return this.colDefs().map((col) => col.key);
703
+ });
704
+ realDisplayedColumns = computed(() => {
705
+ const columns = this.displayedColumns() ?? this.allColumnKeys();
706
+ if (this.selectMode() !== 'none') {
707
+ return [this.selectKey, ...columns];
708
+ }
709
+ else {
710
+ return columns;
711
+ }
712
+ });
713
+ clickDebounceTime = computed(() => this.usesDoubleClick() ? 250 : 0);
714
+ getColumnWidth(col) {
715
+ return col?.width;
716
+ }
717
+ getMinColumnWidth(col) {
718
+ return col?.minWidth;
719
+ }
720
+ getMaxColumnWidth(col) {
721
+ if (!this.autoSize()) {
722
+ return col.maxWidth;
723
+ }
724
+ return col?.maxWidth ?? `${this.defaultColumnWidth}px`;
725
+ }
726
+ injector = inject(Injector);
727
+ cd = inject(ChangeDetectorRef);
728
+ renderer = inject(Renderer2);
729
+ store = inject(RdtTableStore);
730
+ dataChangeEffect = afterRenderEffect({
731
+ earlyRead: () => {
732
+ const data = this.store.entities();
733
+ const loading = this.store.loading();
734
+ if (!loading && this.autoSize() && data.length > 0) {
735
+ const table = this.tableEl?.nativeElement;
736
+ if (!table)
737
+ return [];
738
+ return this.headerCells.map((cellRef, index) => {
739
+ const col = cellRef.nativeElement;
740
+ const colDefIndex = index - 1;
741
+ const colDef = this.colDefs()[colDefIndex];
742
+ const colWidth = col.getBoundingClientRect().width;
743
+ return {
744
+ col: col,
745
+ index,
746
+ colDef,
747
+ colWidth,
748
+ hasExplicitMinWidth: colDef?.minWidth !== undefined,
749
+ hasExplicitMaxWidth: colDef?.maxWidth !== undefined,
750
+ };
751
+ });
752
+ }
753
+ return [];
754
+ },
755
+ write: (measurementsSignal) => {
756
+ const measurements = measurementsSignal();
757
+ if (!measurements || measurements.length === 0)
758
+ return;
759
+ measurements.forEach(({ col, index, colDef, colWidth, hasExplicitMinWidth, hasExplicitMaxWidth, }) => {
760
+ if (hasExplicitMinWidth || hasExplicitMaxWidth) {
761
+ if (colDef) {
762
+ this.applyColumnWidths(col, index, colDef, hasExplicitMinWidth, hasExplicitMaxWidth);
763
+ }
764
+ }
765
+ else {
766
+ this.handleAutoSizing(col, index, colWidth);
767
+ }
768
+ });
769
+ this.hasInitializedWidths.set(true);
770
+ },
771
+ });
772
+ onCellDblClick(row, column) {
773
+ if (column.interactive(row)) {
774
+ return;
775
+ }
776
+ this.rowDoubleClick.emit(row);
777
+ }
778
+ onCellClick(row, column) {
779
+ if (column.interactive(row)) {
780
+ return;
781
+ }
782
+ this.onSelect(row);
783
+ }
784
+ onSelect(row) {
785
+ const mode = untracked(this.selectMode);
786
+ if (mode === 'multi') {
787
+ this.store.toggleSelectItem(row);
788
+ }
789
+ else if (mode === 'single') {
790
+ this.store.toggleSelectSingleItem(row);
791
+ }
792
+ }
793
+ selectAll() {
794
+ this.store.toggleSelectAll();
795
+ }
796
+ getCellCursor(row, column) {
797
+ if (column.interactive(row)) {
798
+ return 'default';
799
+ }
800
+ if (this.selectMode() !== 'none' || this.usesDoubleClick()) {
801
+ return 'pointer';
802
+ }
803
+ return 'default';
804
+ }
805
+ applyColumnWidths(col, index, colDef, hasExplicitMinWidth, hasExplicitMaxWidth) {
806
+ const { minWidth, maxWidth } = colDef;
807
+ if (!this.explicitWidthsApplied().has(index)) {
808
+ if (hasExplicitMinWidth) {
809
+ this.renderer.setStyle(col, 'minWidth', minWidth);
810
+ }
811
+ if (hasExplicitMaxWidth) {
812
+ this.renderer.setStyle(col, 'maxWidth', maxWidth);
813
+ }
814
+ this.renderer.setStyle(col, 'width', maxWidth ? maxWidth : minWidth);
815
+ this.explicitWidthsApplied.update((set) => new Set([...set, index]));
816
+ }
817
+ }
818
+ handleAutoSizing(col, index, colWidth) {
819
+ let finalWidth;
820
+ if (!this.hasInitializedWidths()) {
821
+ // first render
822
+ finalWidth =
823
+ colWidth < this.defaultColumnWidth ? colWidth : this.defaultColumnWidth;
824
+ this.savedColumnWidths.update((map) => new Map([...map, [index, finalWidth]]));
825
+ }
826
+ else {
827
+ // other renders
828
+ finalWidth =
829
+ this.savedColumnWidths().get(index) || this.defaultColumnWidth;
830
+ }
831
+ const widthPx = `${finalWidth}px`;
832
+ this.renderer.setStyle(col, 'width', widthPx);
833
+ this.renderer.setStyle(col, 'minWidth', widthPx);
834
+ this.renderer.setStyle(col, 'maxWidth', widthPx);
835
+ }
836
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
837
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: RdtTableComponent, isStandalone: false, selector: "rdt-table", inputs: { itemIdFn: { classPropertyName: "itemIdFn", publicName: "itemIdFn", isSignal: true, isRequired: true, transformFunction: null }, colDefsInput: { classPropertyName: "colDefsInput", publicName: "colDefs", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, selectMode: { classPropertyName: "selectMode", publicName: "selectMode", isSignal: true, isRequired: false, transformFunction: null }, showPaginator: { classPropertyName: "showPaginator", publicName: "showPaginator", isSignal: true, isRequired: false, transformFunction: null }, showSelectAll: { classPropertyName: "showSelectAll", publicName: "showSelectAll", isSignal: true, isRequired: false, transformFunction: null }, autoSize: { classPropertyName: "autoSize", publicName: "autoSize", isSignal: true, isRequired: false, transformFunction: null }, displayedColumns: { classPropertyName: "displayedColumns", publicName: "displayedColumns", isSignal: true, isRequired: false, transformFunction: null }, notFoundConfig: { classPropertyName: "notFoundConfig", publicName: "notFoundConfig", isSignal: true, isRequired: false, transformFunction: null }, usesDoubleClickInput: { classPropertyName: "usesDoubleClickInput", publicName: "usesDoubleClick", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowDoubleClick: "rowDoubleClick" }, providers: [RdtTableStore], viewQueries: [{ propertyName: "tableEl", first: true, predicate: ["tableEl"], descendants: true, read: ElementRef }, { propertyName: "headerCells", predicate: ["headerEl"], descendants: true, read: ElementRef }], exportAs: ["rdtTable"], ngImport: i0, template: "@let data = store.entities(); @let loading = store.loading() || !store.ready();\n<div [class]=\"'rdt-table--' + size()\" class=\"rdt-table-wrapper\">\n <table cdk-table [dataSource]=\"loading ? data : data\" slot=\"table\" #tableEl>\n @let colNames = realDisplayedColumns();\n <tr cdk-header-row *cdkHeaderRowDef=\"colNames\"></tr>\n <tr\n cdk-row\n *cdkRowDef=\"let row; columns: colNames\"\n [class.row-selected]=\"store.isSelected(row)\"\n ></tr>\n\n <ng-container [cdkColumnDef]=\"selectKey\" [sticky]=\"true\">\n @let mode = selectMode();\n <th\n cdk-header-cell\n *cdkHeaderCellDef\n class=\"rdt-select-column-header\"\n #headerEl\n >\n @if (showSelectAll() && mode === 'multi') {\n <ng-container\n rdtCheckboxOutlet\n [ngModel]=\"store.selectedAll()\"\n (checkedChange)=\"selectAll()\"\n ></ng-container>\n }\n </th>\n <td\n cdk-cell\n *cdkCellDef=\"let row; let i = index\"\n class=\"rdt-select-column-cell\"\n >\n <div class=\"rdt-select-column-cell-wrapper\">\n <ng-container\n rdtCheckboxOutlet\n [ngModel]=\"store.isSelected(row)\"\n (checkedChange)=\"onSelect(row)\"\n ></ng-container>\n </div>\n </td>\n </ng-container>\n\n @for (column of colDefs(); track column.key) {\n <ng-container\n [cdkColumnDef]=\"column.key\"\n [sticky]=\"column.sticky === 'start'\"\n [stickyEnd]=\"column.sticky === 'end'\"\n >\n <th\n cdk-header-cell\n *cdkHeaderCellDef\n [class]=\"column.headerClass\"\n [style]=\"column.headerStyle\"\n [style.min-width]=\"getMinColumnWidth(column)\"\n [style.max-width]=\"getMaxColumnWidth(column)\"\n [style.width]=\"getColumnWidth(column)\"\n #headerEl\n >\n <rdt-header-cell-renderer [column]=\"column\" />\n </th>\n\n <td\n cdk-cell\n *cdkCellDef=\"let row; let i = index\"\n [class]=\"column.cellClass(row)\"\n [style]=\"column.cellStyle(row)\"\n [style.min-width]=\"getMinColumnWidth(column)\"\n [style.max-width]=\"getMaxColumnWidth(column)\"\n [style.width]=\"getColumnWidth(column)\"\n (click.double)=\"onCellDblClick(row, column)\"\n (click.single)=\"onCellClick(row, column)\"\n [style.cursor]=\"getCellCursor(row, column)\"\n >\n <!-- [debounceTime]=\"clickDebounceTime()\" -->\n <ng-container\n *ngComponentOutlet=\"\n column.cellRenderer;\n injector: injector;\n inputs: {\n row: row,\n index: i,\n store: store,\n cellRendererParams: column.cellRendererParams,\n }\n \"\n >\n </ng-container>\n </td>\n </ng-container>\n }\n </table>\n <!-- @if (loading) {\n <div class=\"spinner-wrapper special-content\">\n <rdt-spinner />\n </div>\n } -->\n <!-- @else if (store.fetchError(); as error) {\n <div class=\"error-wrapper special-content\">\n <rdt-table-no-result type=\"error\" [config]=\"error\" />\n </div>\n } @else if (data.length === 0) {\n <rdt-table-no-result type=\"not-found\" [config]=\"notFoundConfig()\" />\n } -->\n</div>\n\n<!-- @if (showPaginator()) { -->\n<rdt-table-paginator />\n<!-- } -->\n", styles: [":root{--rdt-table-height-sm: 250px;--rdt-table-height-md: 350px;--rdt-table-height-lg: 500px;--rdt-table-cell-padding: .25em}table{width:100%}rdt-table .rdt-table--sm .special-content{height:calc(var(--rdt-table-height-sm) - var(--gov-text-xs-font-size) - 2 * var(--rdt-table-cell-padding))}rdt-table .rdt-table--md .special-content{height:calc(var(--rdt-table-height-md) - .75rem + 2 * var(--rdt-table-cell-padding))}rdt-table .rdt-table--lg .special-content{height:calc(var(--rdt-table-height-lg) - .75rem + 2 * var(--rdt-table-cell-padding))}rdt-table thead{z-index:9;position:sticky;top:0}rdt-table .action-btn{border:none;outline:none;border-radius:4px;background-color:#00000006;padding:4px 8px;font-weight:500}rdt-table .action-btn:hover{cursor:pointer;background-color:#00000013}rdt-table .action-btn.selected{background-color:#00000020;color:#000}rdt-table .space-between{display:flex;justify-content:space-between}rdt-table .spinner-wrapper{display:flex;justify-content:center;height:100%;align-items:center}rdt-table .no-records{height:100%}rdt-table .table-header{display:flex;align-items:center;gap:2px}rdt-table td.cdk-table-sticky{background:var(--gov-color-neutral-white)!important}rdt-table td,rdt-table th{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;overflow-wrap:anywhere}rdt-table td{padding:0!important}rdt-table .rdt-select-column-header,rdt-table .rdt-select-column-cell{width:calc(var(--gov-form-checkbox-core-xs-indicator-size, 1rem) + 2 * var(--rdt-table-cell-padding));padding:var(--rdt-table-cell-padding)!important}rdt-table .row-selected td{background-color:var(--gov-color-primary-100)!important}rdt-table .cell-value-base{display:block;width:100%;padding:.25rem .5rem;overflow:hidden;text-overflow:ellipsis}\n"], dependencies: [{ kind: "directive", type: i1$1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.CdkTable, selector: "cdk-table, table[cdk-table]", inputs: ["trackBy", "dataSource", "multiTemplateDataRows", "fixedLayout"], outputs: ["contentChanged"], exportAs: ["cdkTable"] }, { kind: "directive", type: i3.CdkRowDef, selector: "[cdkRowDef]", inputs: ["cdkRowDefColumns", "cdkRowDefWhen"] }, { kind: "directive", type: i3.CdkCellDef, selector: "[cdkCellDef]" }, { kind: "directive", type: i3.CdkHeaderCellDef, selector: "[cdkHeaderCellDef]" }, { kind: "directive", type: i3.CdkColumnDef, selector: "[cdkColumnDef]", inputs: ["cdkColumnDef", "sticky", "stickyEnd"] }, { kind: "directive", type: i3.CdkCell, selector: "cdk-cell, td[cdk-cell]" }, { kind: "component", type: i3.CdkRow, selector: "cdk-row, tr[cdk-row]" }, { kind: "directive", type: i3.CdkHeaderCell, selector: "cdk-header-cell, th[cdk-header-cell]" }, { kind: "component", type: i3.CdkHeaderRow, selector: "cdk-header-row, tr[cdk-header-row]" }, { kind: "directive", type: i3.CdkHeaderRowDef, selector: "[cdkHeaderRowDef]", inputs: ["cdkHeaderRowDef", "cdkHeaderRowDefSticky"] }, { kind: "directive", type: i4.RdtCheckboxOutletDirective, selector: "[rdtCheckboxOutlet]", outputs: ["checkedChange"], exportAs: ["rdtCheckboxOutlet"] }, { kind: "component", type: RdtTablePaginatorComponent, selector: "rdt-table-paginator" }, { kind: "component", type: RdtHeaderCellRendererComponent, selector: "rdt-header-cell-renderer", inputs: ["column"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
838
+ }
839
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtTableComponent, decorators: [{
840
+ type: Component,
841
+ args: [{ selector: 'rdt-table', changeDetection: ChangeDetectionStrategy.OnPush, providers: [RdtTableStore], standalone: false, encapsulation: ViewEncapsulation.None, exportAs: 'rdtTable', template: "@let data = store.entities(); @let loading = store.loading() || !store.ready();\n<div [class]=\"'rdt-table--' + size()\" class=\"rdt-table-wrapper\">\n <table cdk-table [dataSource]=\"loading ? data : data\" slot=\"table\" #tableEl>\n @let colNames = realDisplayedColumns();\n <tr cdk-header-row *cdkHeaderRowDef=\"colNames\"></tr>\n <tr\n cdk-row\n *cdkRowDef=\"let row; columns: colNames\"\n [class.row-selected]=\"store.isSelected(row)\"\n ></tr>\n\n <ng-container [cdkColumnDef]=\"selectKey\" [sticky]=\"true\">\n @let mode = selectMode();\n <th\n cdk-header-cell\n *cdkHeaderCellDef\n class=\"rdt-select-column-header\"\n #headerEl\n >\n @if (showSelectAll() && mode === 'multi') {\n <ng-container\n rdtCheckboxOutlet\n [ngModel]=\"store.selectedAll()\"\n (checkedChange)=\"selectAll()\"\n ></ng-container>\n }\n </th>\n <td\n cdk-cell\n *cdkCellDef=\"let row; let i = index\"\n class=\"rdt-select-column-cell\"\n >\n <div class=\"rdt-select-column-cell-wrapper\">\n <ng-container\n rdtCheckboxOutlet\n [ngModel]=\"store.isSelected(row)\"\n (checkedChange)=\"onSelect(row)\"\n ></ng-container>\n </div>\n </td>\n </ng-container>\n\n @for (column of colDefs(); track column.key) {\n <ng-container\n [cdkColumnDef]=\"column.key\"\n [sticky]=\"column.sticky === 'start'\"\n [stickyEnd]=\"column.sticky === 'end'\"\n >\n <th\n cdk-header-cell\n *cdkHeaderCellDef\n [class]=\"column.headerClass\"\n [style]=\"column.headerStyle\"\n [style.min-width]=\"getMinColumnWidth(column)\"\n [style.max-width]=\"getMaxColumnWidth(column)\"\n [style.width]=\"getColumnWidth(column)\"\n #headerEl\n >\n <rdt-header-cell-renderer [column]=\"column\" />\n </th>\n\n <td\n cdk-cell\n *cdkCellDef=\"let row; let i = index\"\n [class]=\"column.cellClass(row)\"\n [style]=\"column.cellStyle(row)\"\n [style.min-width]=\"getMinColumnWidth(column)\"\n [style.max-width]=\"getMaxColumnWidth(column)\"\n [style.width]=\"getColumnWidth(column)\"\n (click.double)=\"onCellDblClick(row, column)\"\n (click.single)=\"onCellClick(row, column)\"\n [style.cursor]=\"getCellCursor(row, column)\"\n >\n <!-- [debounceTime]=\"clickDebounceTime()\" -->\n <ng-container\n *ngComponentOutlet=\"\n column.cellRenderer;\n injector: injector;\n inputs: {\n row: row,\n index: i,\n store: store,\n cellRendererParams: column.cellRendererParams,\n }\n \"\n >\n </ng-container>\n </td>\n </ng-container>\n }\n </table>\n <!-- @if (loading) {\n <div class=\"spinner-wrapper special-content\">\n <rdt-spinner />\n </div>\n } -->\n <!-- @else if (store.fetchError(); as error) {\n <div class=\"error-wrapper special-content\">\n <rdt-table-no-result type=\"error\" [config]=\"error\" />\n </div>\n } @else if (data.length === 0) {\n <rdt-table-no-result type=\"not-found\" [config]=\"notFoundConfig()\" />\n } -->\n</div>\n\n<!-- @if (showPaginator()) { -->\n<rdt-table-paginator />\n<!-- } -->\n", styles: [":root{--rdt-table-height-sm: 250px;--rdt-table-height-md: 350px;--rdt-table-height-lg: 500px;--rdt-table-cell-padding: .25em}table{width:100%}rdt-table .rdt-table--sm .special-content{height:calc(var(--rdt-table-height-sm) - var(--gov-text-xs-font-size) - 2 * var(--rdt-table-cell-padding))}rdt-table .rdt-table--md .special-content{height:calc(var(--rdt-table-height-md) - .75rem + 2 * var(--rdt-table-cell-padding))}rdt-table .rdt-table--lg .special-content{height:calc(var(--rdt-table-height-lg) - .75rem + 2 * var(--rdt-table-cell-padding))}rdt-table thead{z-index:9;position:sticky;top:0}rdt-table .action-btn{border:none;outline:none;border-radius:4px;background-color:#00000006;padding:4px 8px;font-weight:500}rdt-table .action-btn:hover{cursor:pointer;background-color:#00000013}rdt-table .action-btn.selected{background-color:#00000020;color:#000}rdt-table .space-between{display:flex;justify-content:space-between}rdt-table .spinner-wrapper{display:flex;justify-content:center;height:100%;align-items:center}rdt-table .no-records{height:100%}rdt-table .table-header{display:flex;align-items:center;gap:2px}rdt-table td.cdk-table-sticky{background:var(--gov-color-neutral-white)!important}rdt-table td,rdt-table th{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;overflow-wrap:anywhere}rdt-table td{padding:0!important}rdt-table .rdt-select-column-header,rdt-table .rdt-select-column-cell{width:calc(var(--gov-form-checkbox-core-xs-indicator-size, 1rem) + 2 * var(--rdt-table-cell-padding));padding:var(--rdt-table-cell-padding)!important}rdt-table .row-selected td{background-color:var(--gov-color-primary-100)!important}rdt-table .cell-value-base{display:block;width:100%;padding:.25rem .5rem;overflow:hidden;text-overflow:ellipsis}\n"] }]
842
+ }], propDecorators: { tableEl: [{
843
+ type: ViewChild,
844
+ args: ['tableEl', { static: false, read: ElementRef }]
845
+ }], headerCells: [{
846
+ type: ViewChildren,
847
+ args: ['headerEl', { read: ElementRef }]
848
+ }] } });
849
+
850
+ class RdtTableNoStateDirective {
851
+ table = inject(RdtTableComponent, { self: true });
852
+ ngOnInit() {
853
+ this.table.store.setReady();
854
+ this.table.store.fetch();
855
+ }
856
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtTableNoStateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
857
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.0", type: RdtTableNoStateDirective, isStandalone: false, selector: "rdt-table:not([queryParamsState])", ngImport: i0 });
858
+ }
859
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtTableNoStateDirective, decorators: [{
860
+ type: Directive,
861
+ args: [{
862
+ selector: 'rdt-table:not([queryParamsState])',
863
+ standalone: false,
864
+ }]
865
+ }] });
866
+
867
+ class RdtTableOfflineDatasource extends RdtTableDatasource {
868
+ _data;
869
+ constructor(_data) {
870
+ super();
871
+ this._data = _data;
872
+ }
873
+ set data(value) {
874
+ this._data = value;
875
+ }
876
+ get data() {
877
+ return this._data;
878
+ }
879
+ // This method first filters data according to filters,
880
+ // Then sorts the filtered data and finally paginates it.
881
+ getData(params) {
882
+ // Apply filtering
883
+ let filteredData = this._data;
884
+ if (params.filters) {
885
+ filteredData = filteredData.filter((item) => params.filters.every((filter) => this.applyFilter(filter, item)));
886
+ }
887
+ // Apply sorting
888
+ if (params.sort) {
889
+ filteredData = filteredData.sort(this.getSortFn(params.sort));
890
+ }
891
+ // Apply pagination
892
+ const start = params.pageIndex * params.pageSize;
893
+ const end = start + params.pageSize;
894
+ const paginatedData = filteredData.slice(start, end);
895
+ return of({
896
+ data: paginatedData,
897
+ totalCount: filteredData.length,
898
+ pageIndex: params.pageIndex,
899
+ }).pipe(delay(300));
900
+ }
901
+ compare(aValue, bValue, type) {
902
+ if (aValue == null && bValue == null) {
903
+ return 0;
904
+ }
905
+ else if (aValue == null) {
906
+ return 1; // nulls are considered greater
907
+ }
908
+ else if (bValue == null) {
909
+ return -1; // nulls are considered less
910
+ }
911
+ switch (type) {
912
+ case 'string':
913
+ return aValue.localeCompare(bValue);
914
+ case 'number':
915
+ case 'decimal':
916
+ return aValue - bValue;
917
+ case 'boolean':
918
+ return Number(aValue) - Number(bValue);
919
+ case 'date':
920
+ return new Date(aValue).getTime() - new Date(bValue).getTime();
921
+ case 'enum':
922
+ return typeof aValue === 'string' && typeof bValue === 'string'
923
+ ? aValue.localeCompare(bValue)
924
+ : aValue - bValue;
925
+ default:
926
+ return 0;
927
+ }
928
+ }
929
+ getSortFn(sort) {
930
+ return (a, b) => {
931
+ const aValue = RdtObjectUtils.pluck(a, sort.key);
932
+ const bValue = RdtObjectUtils.pluck(b, sort.key);
933
+ return (this.compare(aValue, bValue, sort.type) *
934
+ (sort.direction === 'asc' ? 1 : -1));
935
+ };
936
+ }
937
+ // TODO: Implementovat jako na BE
938
+ applyFilter(filter, item) {
939
+ const value = RdtObjectUtils.pluck(item, filter.key);
940
+ if (value === undefined || value === null) {
941
+ return false;
942
+ }
943
+ switch (filter.type) {
944
+ case 'string':
945
+ return String(value).includes(filter.value);
946
+ case 'number':
947
+ return value === filter.value;
948
+ case 'boolean':
949
+ return value === filter.value;
950
+ case 'date':
951
+ return (new Date(value).toDateString() ===
952
+ new Date(filter.value).toDateString());
953
+ default:
954
+ return false;
955
+ }
956
+ }
957
+ }
958
+
959
+ class RdtTableOfflineDatasourceProviderDirective {
960
+ store = inject(RdtTableStore, { self: true });
961
+ data = input();
962
+ dataEffect = effect(() => {
963
+ const data = this.data();
964
+ if (data) {
965
+ this.store.setDatasource(new RdtTableOfflineDatasource(data));
966
+ }
967
+ });
968
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtTableOfflineDatasourceProviderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
969
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.0", type: RdtTableOfflineDatasourceProviderDirective, isStandalone: false, selector: "rdt-table[data]", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
970
+ }
971
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtTableOfflineDatasourceProviderDirective, decorators: [{
972
+ type: Directive,
973
+ args: [{
974
+ selector: 'rdt-table[data]',
975
+ standalone: false,
976
+ }]
977
+ }] });
978
+
979
+ class RdtTableStateDirective {
980
+ table = inject(RdtTableComponent, { self: true });
981
+ elementRef = inject(ElementRef);
982
+ subscription;
983
+ storeObservable;
984
+ constructor() {
985
+ const store = this.table.store;
986
+ this.storeObservable = combineLatest([
987
+ toObservable(store.sort),
988
+ toObservable(store.headerFilters),
989
+ toObservable(store.pageSize),
990
+ toObservable(store.pageIndex),
991
+ toObservable(store.displayedColumns),
992
+ ]).pipe(map(([sort, headerFilters, pageSize, pageIndex, displayedColumns]) => ({
993
+ sort: sort,
994
+ headerFilters: headerFilters,
995
+ pageSize,
996
+ page: pageIndex,
997
+ displayedColumns,
998
+ })));
999
+ }
1000
+ ngOnInit() {
1001
+ this.readState().subscribe((state) => {
1002
+ if (state) {
1003
+ this.table.store.setSort(state.sort);
1004
+ this.table.store.setHeaderFilters(state.headerFilters);
1005
+ this.table.store.setPagination(state.pageSize ?? 0, state.page ?? 0);
1006
+ this.table.store.setDisplayedColumns(state.displayedColumns ?? []);
1007
+ }
1008
+ });
1009
+ this.subscription = this.storeObservable.subscribe((state) => {
1010
+ this.writeState(state).subscribe();
1011
+ });
1012
+ }
1013
+ ngOnDestroy() {
1014
+ this.subscription?.unsubscribe();
1015
+ }
1016
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtTableStateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1017
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.0", type: RdtTableStateDirective, isStandalone: false, ngImport: i0 });
1018
+ }
1019
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtTableStateDirective, decorators: [{
1020
+ type: Directive,
1021
+ args: [{
1022
+ standalone: false,
1023
+ }]
1024
+ }], ctorParameters: () => [] });
1025
+
1026
+ class RdtTableModule {
1027
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtTableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1028
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.0", ngImport: i0, type: RdtTableModule, declarations: [RdtTableComponent,
1029
+ RdtTablePaginatorComponent,
1030
+ RdtHeaderCellRendererComponent,
1031
+ RdtTableOfflineDatasourceProviderDirective,
1032
+ RdtStaticCellRendererComponent,
1033
+ /* RdtTableActionBarComponent, */
1034
+ RdtTableNoStateDirective], imports: [CommonModule,
1035
+ FormsModule,
1036
+ ReactiveFormsModule,
1037
+ CdkTableModule,
1038
+ GovDesignSystemModule,
1039
+ RdtCheckboxOutletDirective,
1040
+ RdtIconOutletDirective], exports: [RdtTableComponent,
1041
+ RdtHeaderCellRendererComponent,
1042
+ RdtTablePaginatorComponent,
1043
+ RdtTableOfflineDatasourceProviderDirective,
1044
+ RdtStaticCellRendererComponent,
1045
+ RdtTableNoStateDirective] });
1046
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtTableModule, imports: [CommonModule,
1047
+ FormsModule,
1048
+ ReactiveFormsModule,
1049
+ CdkTableModule,
1050
+ GovDesignSystemModule] });
1051
+ }
1052
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: RdtTableModule, decorators: [{
1053
+ type: NgModule,
1054
+ args: [{
1055
+ declarations: [
1056
+ RdtTableComponent,
1057
+ RdtTablePaginatorComponent,
1058
+ RdtHeaderCellRendererComponent,
1059
+ RdtTableOfflineDatasourceProviderDirective,
1060
+ RdtStaticCellRendererComponent,
1061
+ /* RdtTableActionBarComponent, */
1062
+ RdtTableNoStateDirective,
1063
+ /* RdtTableNoResultComponent,
1064
+ RdtTableQueryParamsStateDirective, */
1065
+ ],
1066
+ exports: [
1067
+ RdtTableComponent,
1068
+ RdtHeaderCellRendererComponent,
1069
+ RdtTablePaginatorComponent,
1070
+ RdtTableOfflineDatasourceProviderDirective,
1071
+ RdtStaticCellRendererComponent,
1072
+ RdtTableNoStateDirective,
1073
+ ],
1074
+ imports: [
1075
+ CommonModule,
1076
+ FormsModule,
1077
+ ReactiveFormsModule,
1078
+ CdkTableModule,
1079
+ GovDesignSystemModule,
1080
+ RdtCheckboxOutletDirective,
1081
+ RdtIconOutletDirective,
1082
+ /* RdtMenuModule, */
1083
+ /*
1084
+ CsuSpinnerComponent,
1085
+ CsuButtonComponent,
1086
+ CsuCheckboxComponent,
1087
+ CsuClickDoubleDirective,
1088
+ CsuSelectComponent,
1089
+ CsuSelectOfflineProviderDirective, */
1090
+ ],
1091
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
1092
+ }]
1093
+ }] });
1094
+
1095
+ /**
1096
+ * Generated bundle index. Do not edit.
1097
+ */
1098
+
1099
+ export { RdtBaseCellRendererComponent, RdtBaseColumnBuilder, RdtHeaderCellRendererComponent, RdtStaticCellRendererComponent, RdtStaticColumnBuilder, RdtTableComponent, RdtTableDatasource, RdtTableModule, RdtTableNoStateDirective, RdtTableOfflineDatasourceProviderDirective, RdtTablePaginatorComponent, RdtTableStateDirective, RdtTableStore, isRdtTableMessage, rdtTableInitialState };
1100
+ //# sourceMappingURL=ngrdt-table.mjs.map