ng-dynamic-datatable 0.0.10 → 0.0.12
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.
|
@@ -1,7 +1,306 @@
|
|
|
1
1
|
import * as i1 from '@angular/common';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { EventEmitter,
|
|
4
|
+
import { EventEmitter, Output, Input, Component } from '@angular/core';
|
|
5
|
+
|
|
6
|
+
const VALID_TRIGGERS = {
|
|
7
|
+
hover: 'hover',
|
|
8
|
+
click: 'click'
|
|
9
|
+
};
|
|
10
|
+
const VALID_POSITIONS = {
|
|
11
|
+
top: 'top',
|
|
12
|
+
bottom: 'bottom',
|
|
13
|
+
left: 'left',
|
|
14
|
+
right: 'right'
|
|
15
|
+
};
|
|
16
|
+
class TooltipManager {
|
|
17
|
+
registry = new WeakMap();
|
|
18
|
+
root;
|
|
19
|
+
documentRef;
|
|
20
|
+
activeTarget = null;
|
|
21
|
+
activeTooltipEl = null;
|
|
22
|
+
offset = 10;
|
|
23
|
+
viewportPadding = 8;
|
|
24
|
+
onMouseOverBound = (event) => this.onMouseOver(event);
|
|
25
|
+
onMouseOutBound = (event) => this.onMouseOut(event);
|
|
26
|
+
onFocusInBound = (event) => this.onFocusIn(event);
|
|
27
|
+
onFocusOutBound = (event) => this.onFocusOut(event);
|
|
28
|
+
onClickBound = (event) => this.onClick(event);
|
|
29
|
+
onDocumentClickBound = (event) => this.onDocumentClick(event);
|
|
30
|
+
onDocumentKeydownBound = (event) => this.onDocumentKeydown(event);
|
|
31
|
+
onWindowResizeBound = () => this.reposition();
|
|
32
|
+
onWindowScrollBound = () => this.reposition();
|
|
33
|
+
constructor(root, documentRef = document) {
|
|
34
|
+
this.root = root;
|
|
35
|
+
this.documentRef = documentRef;
|
|
36
|
+
}
|
|
37
|
+
init() {
|
|
38
|
+
this.root.addEventListener('mouseover', this.onMouseOverBound);
|
|
39
|
+
this.root.addEventListener('mouseout', this.onMouseOutBound);
|
|
40
|
+
this.root.addEventListener('focusin', this.onFocusInBound);
|
|
41
|
+
this.root.addEventListener('focusout', this.onFocusOutBound);
|
|
42
|
+
this.root.addEventListener('click', this.onClickBound);
|
|
43
|
+
this.documentRef.addEventListener('click', this.onDocumentClickBound, true);
|
|
44
|
+
this.documentRef.addEventListener('keydown', this.onDocumentKeydownBound);
|
|
45
|
+
window.addEventListener('resize', this.onWindowResizeBound);
|
|
46
|
+
window.addEventListener('scroll', this.onWindowScrollBound, true);
|
|
47
|
+
}
|
|
48
|
+
destroy() {
|
|
49
|
+
this.hide(true);
|
|
50
|
+
this.root.removeEventListener('mouseover', this.onMouseOverBound);
|
|
51
|
+
this.root.removeEventListener('mouseout', this.onMouseOutBound);
|
|
52
|
+
this.root.removeEventListener('focusin', this.onFocusInBound);
|
|
53
|
+
this.root.removeEventListener('focusout', this.onFocusOutBound);
|
|
54
|
+
this.root.removeEventListener('click', this.onClickBound);
|
|
55
|
+
this.documentRef.removeEventListener('click', this.onDocumentClickBound, true);
|
|
56
|
+
this.documentRef.removeEventListener('keydown', this.onDocumentKeydownBound);
|
|
57
|
+
window.removeEventListener('resize', this.onWindowResizeBound);
|
|
58
|
+
window.removeEventListener('scroll', this.onWindowScrollBound, true);
|
|
59
|
+
}
|
|
60
|
+
register(element, config) {
|
|
61
|
+
this.registry.set(element, { config });
|
|
62
|
+
}
|
|
63
|
+
onMouseOver(event) {
|
|
64
|
+
const target = this.getTooltipTarget(event.target);
|
|
65
|
+
if (!target) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (this.getTrigger(target) !== 'hover') {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
this.show(target);
|
|
72
|
+
}
|
|
73
|
+
onMouseOut(event) {
|
|
74
|
+
const target = this.getTooltipTarget(event.target);
|
|
75
|
+
if (!target || this.getTrigger(target) !== 'hover') {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const next = event.relatedTarget;
|
|
79
|
+
if (next && (target.contains(next) || (this.activeTooltipEl?.contains(next) ?? false))) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
this.hide();
|
|
83
|
+
}
|
|
84
|
+
onFocusIn(event) {
|
|
85
|
+
const target = this.getTooltipTarget(event.target);
|
|
86
|
+
if (!target) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
this.show(target);
|
|
90
|
+
}
|
|
91
|
+
onFocusOut(event) {
|
|
92
|
+
const target = this.getTooltipTarget(event.target);
|
|
93
|
+
if (!target) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const next = event.relatedTarget;
|
|
97
|
+
if (next && (target.contains(next) || (this.activeTooltipEl?.contains(next) ?? false))) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
this.hide();
|
|
101
|
+
}
|
|
102
|
+
onClick(event) {
|
|
103
|
+
const target = this.getTooltipTarget(event.target);
|
|
104
|
+
if (!target) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (this.getTrigger(target) !== 'click') {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
event.preventDefault();
|
|
111
|
+
event.stopPropagation();
|
|
112
|
+
if (this.activeTarget === target && this.activeTooltipEl) {
|
|
113
|
+
this.hide();
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
this.show(target);
|
|
117
|
+
}
|
|
118
|
+
onDocumentClick(event) {
|
|
119
|
+
if (!this.activeTarget || !this.activeTooltipEl) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (this.getTrigger(this.activeTarget) !== 'click') {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const node = event.target;
|
|
126
|
+
const insideTarget = !!(node && this.activeTarget.contains(node));
|
|
127
|
+
const insideTooltip = !!(node && this.activeTooltipEl.contains(node));
|
|
128
|
+
if (!insideTarget && !insideTooltip) {
|
|
129
|
+
this.hide();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
onDocumentKeydown(event) {
|
|
133
|
+
if (event.key === 'Escape') {
|
|
134
|
+
this.hide();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
getTooltipTarget(input) {
|
|
138
|
+
if (!(input instanceof Element)) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
const target = input.closest('[data-tooltip]');
|
|
142
|
+
if (!target) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
if (!this.root.contains(target)) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
return target;
|
|
149
|
+
}
|
|
150
|
+
getEntry(target) {
|
|
151
|
+
return this.registry.get(target);
|
|
152
|
+
}
|
|
153
|
+
getTrigger(target) {
|
|
154
|
+
const value = this.getEntry(target)?.config.trigger ?? target.dataset['tooltipTrigger'] ?? 'hover';
|
|
155
|
+
const normalized = String(value).toLowerCase();
|
|
156
|
+
return VALID_TRIGGERS[normalized] ?? 'hover';
|
|
157
|
+
}
|
|
158
|
+
getPosition(target) {
|
|
159
|
+
const value = this.getEntry(target)?.config.position ?? target.dataset['tooltipPosition'] ?? 'bottom';
|
|
160
|
+
const normalized = String(value).toLowerCase();
|
|
161
|
+
return VALID_POSITIONS[normalized] ?? 'bottom';
|
|
162
|
+
}
|
|
163
|
+
getContent(target) {
|
|
164
|
+
const entry = this.getEntry(target);
|
|
165
|
+
const html = entry?.config.html ?? target.dataset['tooltipHtml'] ?? '';
|
|
166
|
+
const text = entry?.config.content ?? target.dataset['tooltip'] ?? '';
|
|
167
|
+
const icon = entry?.config.icon ?? target.dataset['tooltipIcon'] ?? '';
|
|
168
|
+
const allowHtmlAttr = target.dataset['tooltipAllowHtml'];
|
|
169
|
+
const allowHtml = entry?.config.allowHtml ?? (allowHtmlAttr === 'true');
|
|
170
|
+
const noArrowAttr = target.dataset['tooltipNoArrow'];
|
|
171
|
+
const noArrow = entry?.config.noArrow ?? (noArrowAttr === 'true');
|
|
172
|
+
const offsetRaw = entry?.config.offset ?? target.dataset['tooltipOffset'];
|
|
173
|
+
const offset = Number.isFinite(Number(offsetRaw)) ? Number(offsetRaw) : this.offset;
|
|
174
|
+
return { icon, text, html, allowHtml, noArrow, offset };
|
|
175
|
+
}
|
|
176
|
+
show(target) {
|
|
177
|
+
const payload = this.getContent(target);
|
|
178
|
+
const content = payload.allowHtml && payload.html ? payload.html : payload.text;
|
|
179
|
+
if (!content) {
|
|
180
|
+
this.hide();
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
this.hide(true);
|
|
184
|
+
const tooltip = this.documentRef.createElement('div');
|
|
185
|
+
tooltip.className = 'ndt-tooltip';
|
|
186
|
+
tooltip.setAttribute('role', 'tooltip');
|
|
187
|
+
tooltip.setAttribute('data-placement', this.getPosition(target));
|
|
188
|
+
if (payload.noArrow) {
|
|
189
|
+
tooltip.setAttribute('data-no-arrow', 'true');
|
|
190
|
+
}
|
|
191
|
+
const contentWrap = this.documentRef.createElement('div');
|
|
192
|
+
contentWrap.className = 'ndt-tooltip__content';
|
|
193
|
+
if (payload.icon) {
|
|
194
|
+
const iconEl = this.documentRef.createElement('span');
|
|
195
|
+
iconEl.className = `ndt-tooltip__icon ${payload.icon}`;
|
|
196
|
+
iconEl.setAttribute('aria-hidden', 'true');
|
|
197
|
+
contentWrap.appendChild(iconEl);
|
|
198
|
+
}
|
|
199
|
+
const textEl = this.documentRef.createElement('span');
|
|
200
|
+
textEl.className = 'ndt-tooltip__text';
|
|
201
|
+
if (payload.allowHtml && payload.html) {
|
|
202
|
+
textEl.innerHTML = payload.html;
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
textEl.textContent = payload.text;
|
|
206
|
+
}
|
|
207
|
+
contentWrap.appendChild(textEl);
|
|
208
|
+
tooltip.appendChild(contentWrap);
|
|
209
|
+
this.documentRef.body.appendChild(tooltip);
|
|
210
|
+
this.activeTarget = target;
|
|
211
|
+
this.activeTooltipEl = tooltip;
|
|
212
|
+
this.positionTooltip(target, tooltip, this.getPosition(target), payload.offset);
|
|
213
|
+
requestAnimationFrame(() => {
|
|
214
|
+
if (this.activeTooltipEl === tooltip) {
|
|
215
|
+
tooltip.classList.add('ndt-tooltip--show');
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
hide(immediate = false) {
|
|
220
|
+
if (!this.activeTooltipEl) {
|
|
221
|
+
this.activeTarget = null;
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
const tooltip = this.activeTooltipEl;
|
|
225
|
+
this.activeTooltipEl = null;
|
|
226
|
+
this.activeTarget = null;
|
|
227
|
+
if (immediate) {
|
|
228
|
+
if (tooltip.parentNode) {
|
|
229
|
+
tooltip.parentNode.removeChild(tooltip);
|
|
230
|
+
}
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
tooltip.classList.remove('ndt-tooltip--show');
|
|
234
|
+
window.setTimeout(() => {
|
|
235
|
+
if (tooltip.parentNode) {
|
|
236
|
+
tooltip.parentNode.removeChild(tooltip);
|
|
237
|
+
}
|
|
238
|
+
}, 180);
|
|
239
|
+
}
|
|
240
|
+
reposition() {
|
|
241
|
+
if (!this.activeTarget || !this.activeTooltipEl) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
const payload = this.getContent(this.activeTarget);
|
|
245
|
+
this.positionTooltip(this.activeTarget, this.activeTooltipEl, this.getPosition(this.activeTarget), payload.offset);
|
|
246
|
+
}
|
|
247
|
+
positionTooltip(target, tooltip, preferred, offset) {
|
|
248
|
+
const rect = target.getBoundingClientRect();
|
|
249
|
+
const tipRect = tooltip.getBoundingClientRect();
|
|
250
|
+
const vw = window.innerWidth;
|
|
251
|
+
const vh = window.innerHeight;
|
|
252
|
+
const placement = this.pickPlacement(preferred, rect, tipRect, vw, vh, offset);
|
|
253
|
+
const coords = this.computeCoords(placement, rect, tipRect, offset);
|
|
254
|
+
const minX = this.viewportPadding;
|
|
255
|
+
const maxX = vw - tipRect.width - this.viewportPadding;
|
|
256
|
+
const minY = this.viewportPadding;
|
|
257
|
+
const maxY = vh - tipRect.height - this.viewportPadding;
|
|
258
|
+
const left = Math.min(Math.max(coords.left, minX), Math.max(minX, maxX));
|
|
259
|
+
const top = Math.min(Math.max(coords.top, minY), Math.max(minY, maxY));
|
|
260
|
+
tooltip.style.left = `${Math.round(left)}px`;
|
|
261
|
+
tooltip.style.top = `${Math.round(top)}px`;
|
|
262
|
+
tooltip.setAttribute('data-placement', placement);
|
|
263
|
+
}
|
|
264
|
+
pickPlacement(preferred, rect, tipRect, vw, vh, offset) {
|
|
265
|
+
const fits = {
|
|
266
|
+
top: rect.top - offset - tipRect.height >= this.viewportPadding,
|
|
267
|
+
bottom: rect.bottom + offset + tipRect.height <= vh - this.viewportPadding,
|
|
268
|
+
left: rect.left - offset - tipRect.width >= this.viewportPadding,
|
|
269
|
+
right: rect.right + offset + tipRect.width <= vw - this.viewportPadding
|
|
270
|
+
};
|
|
271
|
+
const order = [preferred, 'bottom', 'top', 'right', 'left'];
|
|
272
|
+
for (const candidate of order) {
|
|
273
|
+
if (fits[candidate]) {
|
|
274
|
+
return candidate;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return preferred;
|
|
278
|
+
}
|
|
279
|
+
computeCoords(placement, rect, tipRect, offset) {
|
|
280
|
+
switch (placement) {
|
|
281
|
+
case 'top':
|
|
282
|
+
return {
|
|
283
|
+
top: rect.top - tipRect.height - offset,
|
|
284
|
+
left: rect.left + (rect.width - tipRect.width) / 2
|
|
285
|
+
};
|
|
286
|
+
case 'bottom':
|
|
287
|
+
return {
|
|
288
|
+
top: rect.bottom + offset,
|
|
289
|
+
left: rect.left + (rect.width - tipRect.width) / 2
|
|
290
|
+
};
|
|
291
|
+
case 'left':
|
|
292
|
+
return {
|
|
293
|
+
top: rect.top + (rect.height - tipRect.height) / 2,
|
|
294
|
+
left: rect.left - tipRect.width - offset
|
|
295
|
+
};
|
|
296
|
+
default:
|
|
297
|
+
return {
|
|
298
|
+
top: rect.top + (rect.height - tipRect.height) / 2,
|
|
299
|
+
left: rect.right + offset
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
5
304
|
|
|
6
305
|
const DEFAULT_CONFIG = {
|
|
7
306
|
title: 'Dynamic DataTable',
|
|
@@ -22,6 +321,7 @@ const DEFAULT_CONFIG = {
|
|
|
22
321
|
}
|
|
23
322
|
};
|
|
24
323
|
class DynamicDatatableComponent {
|
|
324
|
+
hostRef;
|
|
25
325
|
config = {};
|
|
26
326
|
columns = [];
|
|
27
327
|
data = [];
|
|
@@ -49,10 +349,22 @@ class DynamicDatatableComponent {
|
|
|
49
349
|
totalPages = 1;
|
|
50
350
|
sortState = { key: null, direction: 'asc' };
|
|
51
351
|
selectedRows = new Set();
|
|
52
|
-
openActionMenuRowId = null;
|
|
53
|
-
openActionAnchorEl = null;
|
|
54
|
-
actionMenuStyle = {};
|
|
55
352
|
isExportMenuOpen = false;
|
|
353
|
+
tooltipManager = null;
|
|
354
|
+
constructor(hostRef) {
|
|
355
|
+
this.hostRef = hostRef;
|
|
356
|
+
}
|
|
357
|
+
ngAfterViewInit() {
|
|
358
|
+
if (typeof document === 'undefined') {
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
this.tooltipManager = new TooltipManager(this.hostRef.nativeElement, document);
|
|
362
|
+
this.tooltipManager.init();
|
|
363
|
+
}
|
|
364
|
+
ngOnDestroy() {
|
|
365
|
+
this.tooltipManager?.destroy();
|
|
366
|
+
this.tooltipManager = null;
|
|
367
|
+
}
|
|
56
368
|
ngOnChanges(_changes) {
|
|
57
369
|
this.refresh();
|
|
58
370
|
}
|
|
@@ -86,7 +398,6 @@ class DynamicDatatableComponent {
|
|
|
86
398
|
onSearchInput(event) {
|
|
87
399
|
const input = event.target;
|
|
88
400
|
this.searchTerm = (input.value || '').trim().toLowerCase();
|
|
89
|
-
this.closeActionMenu();
|
|
90
401
|
this.currentPage = 1;
|
|
91
402
|
this.applyFiltersSortAndPagination();
|
|
92
403
|
}
|
|
@@ -94,7 +405,6 @@ class DynamicDatatableComponent {
|
|
|
94
405
|
const select = event.target;
|
|
95
406
|
const value = Number(select.value);
|
|
96
407
|
this.rowsPerPage = Number.isFinite(value) && value > 0 ? value : this.getInitialRowsPerPage();
|
|
97
|
-
this.closeActionMenu();
|
|
98
408
|
this.currentPage = 1;
|
|
99
409
|
this.applyFiltersSortAndPagination();
|
|
100
410
|
}
|
|
@@ -109,7 +419,6 @@ class DynamicDatatableComponent {
|
|
|
109
419
|
else {
|
|
110
420
|
this.sortState = { key, direction: 'asc' };
|
|
111
421
|
}
|
|
112
|
-
this.closeActionMenu();
|
|
113
422
|
this.currentPage = 1;
|
|
114
423
|
this.sortChange.emit({ ...this.sortState });
|
|
115
424
|
this.applyFiltersSortAndPagination();
|
|
@@ -131,7 +440,6 @@ class DynamicDatatableComponent {
|
|
|
131
440
|
if (bounded === this.currentPage) {
|
|
132
441
|
return;
|
|
133
442
|
}
|
|
134
|
-
this.closeActionMenu();
|
|
135
443
|
this.currentPage = bounded;
|
|
136
444
|
this.pageChange.emit(this.currentPage);
|
|
137
445
|
this.updatePagedRowsOnly();
|
|
@@ -170,36 +478,10 @@ class DynamicDatatableComponent {
|
|
|
170
478
|
}
|
|
171
479
|
return this.pagedRows.every((row) => this.selectedRows.has(row.id));
|
|
172
480
|
}
|
|
173
|
-
toggleActionMenu(rowId, event) {
|
|
174
|
-
event.stopPropagation();
|
|
175
|
-
const currentTarget = event.currentTarget;
|
|
176
|
-
const target = event.target;
|
|
177
|
-
const anchor = currentTarget ?? target?.closest('.ndt-actions-btn') ?? null;
|
|
178
|
-
if (!anchor) {
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
if (this.openActionMenuRowId === rowId) {
|
|
182
|
-
this.closeActionMenu();
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
this.openActionMenuRowId = rowId;
|
|
186
|
-
this.openActionAnchorEl = anchor;
|
|
187
|
-
this.updateActionMenuPosition();
|
|
188
|
-
// Recalculate once the menu is rendered so dimensions are accurate.
|
|
189
|
-
setTimeout(() => this.updateActionMenuPosition(), 0);
|
|
190
|
-
}
|
|
191
|
-
closeActionMenu() {
|
|
192
|
-
this.openActionMenuRowId = null;
|
|
193
|
-
this.openActionAnchorEl = null;
|
|
194
|
-
this.actionMenuStyle = {};
|
|
195
|
-
}
|
|
196
481
|
toggleExportMenu(event) {
|
|
197
482
|
event.stopPropagation();
|
|
198
483
|
this.isExportMenuOpen = !this.isExportMenuOpen;
|
|
199
484
|
}
|
|
200
|
-
isActionMenuOpen(rowId) {
|
|
201
|
-
return this.openActionMenuRowId === rowId;
|
|
202
|
-
}
|
|
203
485
|
onActionItemClick(actionIndex, row, event) {
|
|
204
486
|
event.preventDefault();
|
|
205
487
|
event.stopPropagation();
|
|
@@ -212,7 +494,6 @@ class DynamicDatatableComponent {
|
|
|
212
494
|
}
|
|
213
495
|
const rowIndex = this.filteredRows.findIndex((item) => item.id === row.id);
|
|
214
496
|
this.actionSelected.emit({ action, row: row.data, rowIndex });
|
|
215
|
-
this.closeActionMenu();
|
|
216
497
|
}
|
|
217
498
|
exportCSV() {
|
|
218
499
|
this.isExportMenuOpen = false;
|
|
@@ -260,6 +541,25 @@ class DynamicDatatableComponent {
|
|
|
260
541
|
}
|
|
261
542
|
return 'auto';
|
|
262
543
|
}
|
|
544
|
+
getColumnTooltip(column) {
|
|
545
|
+
const label = String(column.label || 'Column');
|
|
546
|
+
if (this.isFeatureOn('sorting') && column.sortable) {
|
|
547
|
+
const key = String(column.key);
|
|
548
|
+
if (this.sortState.key === key) {
|
|
549
|
+
const direction = this.sortState.direction === 'asc' ? 'ascending' : 'descending';
|
|
550
|
+
return `${label} (sorted ${direction})`;
|
|
551
|
+
}
|
|
552
|
+
return `${label} (click to sort)`;
|
|
553
|
+
}
|
|
554
|
+
return label;
|
|
555
|
+
}
|
|
556
|
+
getCellTooltip(row, column) {
|
|
557
|
+
const value = this.getCellTextValue(row, column).trim();
|
|
558
|
+
if (!value) {
|
|
559
|
+
return String(column.label || 'Cell');
|
|
560
|
+
}
|
|
561
|
+
return value;
|
|
562
|
+
}
|
|
263
563
|
getColumnCount() {
|
|
264
564
|
let count = this.mergedColumns.length;
|
|
265
565
|
if (this.isFeatureOn('checkboxSelection')) {
|
|
@@ -358,83 +658,10 @@ class DynamicDatatableComponent {
|
|
|
358
658
|
updatePagedRowsOnly() {
|
|
359
659
|
if (!this.isFeatureOn('pagination')) {
|
|
360
660
|
this.pagedRows = [...this.filteredRows];
|
|
361
|
-
this.validateOpenActionMenuRow();
|
|
362
661
|
return;
|
|
363
662
|
}
|
|
364
663
|
const start = (this.currentPage - 1) * this.rowsPerPage;
|
|
365
664
|
this.pagedRows = this.filteredRows.slice(start, start + this.rowsPerPage);
|
|
366
|
-
this.validateOpenActionMenuRow();
|
|
367
|
-
}
|
|
368
|
-
onWindowResize() {
|
|
369
|
-
this.updateActionMenuPosition();
|
|
370
|
-
}
|
|
371
|
-
onWindowScroll() {
|
|
372
|
-
this.updateActionMenuPosition();
|
|
373
|
-
}
|
|
374
|
-
validateOpenActionMenuRow() {
|
|
375
|
-
if (!this.openActionMenuRowId) {
|
|
376
|
-
return;
|
|
377
|
-
}
|
|
378
|
-
const existsOnPage = this.pagedRows.some((row) => row.id === this.openActionMenuRowId);
|
|
379
|
-
if (!existsOnPage) {
|
|
380
|
-
this.closeActionMenu();
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
updateActionMenuPosition() {
|
|
384
|
-
if (!this.openActionMenuRowId || !this.openActionAnchorEl || typeof document === 'undefined') {
|
|
385
|
-
return;
|
|
386
|
-
}
|
|
387
|
-
const menus = Array.from(document.querySelectorAll('.ndt-action-menu'));
|
|
388
|
-
const menu = menus.find((item) => item.getAttribute('data-row-id') === this.openActionMenuRowId) ?? null;
|
|
389
|
-
const rect = this.openActionAnchorEl.getBoundingClientRect();
|
|
390
|
-
const viewportWidth = window.innerWidth;
|
|
391
|
-
const viewportHeight = window.innerHeight;
|
|
392
|
-
const menuWidth = menu?.offsetWidth ?? 160;
|
|
393
|
-
const menuHeight = menu?.offsetHeight ?? this.getEstimatedActionMenuHeight();
|
|
394
|
-
const offset = 6;
|
|
395
|
-
const edgePadding = 8;
|
|
396
|
-
const spaceBelow = viewportHeight - rect.bottom - edgePadding;
|
|
397
|
-
const spaceAbove = rect.top - edgePadding;
|
|
398
|
-
const spaceRight = viewportWidth - rect.left - edgePadding;
|
|
399
|
-
const spaceLeft = rect.right - edgePadding;
|
|
400
|
-
let top;
|
|
401
|
-
if (spaceBelow >= menuHeight) {
|
|
402
|
-
top = rect.bottom + offset;
|
|
403
|
-
}
|
|
404
|
-
else if (spaceAbove >= menuHeight) {
|
|
405
|
-
top = rect.top - menuHeight - offset;
|
|
406
|
-
}
|
|
407
|
-
else if (spaceBelow >= spaceAbove) {
|
|
408
|
-
top = viewportHeight - menuHeight - edgePadding;
|
|
409
|
-
}
|
|
410
|
-
else {
|
|
411
|
-
top = edgePadding;
|
|
412
|
-
}
|
|
413
|
-
let left;
|
|
414
|
-
if (spaceRight >= menuWidth) {
|
|
415
|
-
left = rect.left;
|
|
416
|
-
}
|
|
417
|
-
else if (spaceLeft >= menuWidth) {
|
|
418
|
-
left = rect.right - menuWidth;
|
|
419
|
-
}
|
|
420
|
-
else {
|
|
421
|
-
left = Math.max(edgePadding, Math.min(rect.left, viewportWidth - menuWidth - edgePadding));
|
|
422
|
-
}
|
|
423
|
-
const maxHeight = Math.max(140, viewportHeight - edgePadding * 2);
|
|
424
|
-
this.actionMenuStyle = {
|
|
425
|
-
position: 'fixed',
|
|
426
|
-
top: `${Math.round(top)}px`,
|
|
427
|
-
left: `${Math.round(left)}px`,
|
|
428
|
-
zIndex: '1080',
|
|
429
|
-
maxHeight: `${Math.round(maxHeight)}px`,
|
|
430
|
-
overflowY: 'auto'
|
|
431
|
-
};
|
|
432
|
-
}
|
|
433
|
-
getEstimatedActionMenuHeight() {
|
|
434
|
-
const count = this.mergedConfig.actions?.length ?? 0;
|
|
435
|
-
const itemHeight = 34;
|
|
436
|
-
const verticalPadding = 12;
|
|
437
|
-
return Math.max(48, count * itemHeight + verticalPadding);
|
|
438
665
|
}
|
|
439
666
|
getCellTextValue(row, column) {
|
|
440
667
|
const key = String(column.key);
|
|
@@ -541,16 +768,15 @@ class DynamicDatatableComponent {
|
|
|
541
768
|
this.selectionChange.emit(this.getSelectedRows());
|
|
542
769
|
}
|
|
543
770
|
closeMenus() {
|
|
544
|
-
this.closeActionMenu();
|
|
545
771
|
this.isExportMenuOpen = false;
|
|
546
772
|
}
|
|
547
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DynamicDatatableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
548
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", type: DynamicDatatableComponent, isStandalone: true, selector: "lib-dynamic-datatable", inputs: { config: "config", columns: "columns", data: "data" }, outputs: { actionSelected: "actionSelected", selectionChange: "selectionChange", sortChange: "sortChange", pageChange: "pageChange", exportTriggered: "exportTriggered" }, host: { listeners: { "window:resize": "onWindowResize()", "window:scroll": "onWindowScroll()" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"ndt-card\" (click)=\"closeMenus()\">\r\n <div class=\"ndt-header\">\r\n <h3 class=\"ndt-title\">{{ mergedConfig.title }}</h3>\r\n </div>\r\n\r\n <div class=\"ndt-toolbar\">\r\n <div class=\"ndt-left-tools\">\r\n <ng-container *ngIf=\"isFeatureOn('export')\">\r\n <div class=\"ndt-dropdown\" (click)=\"$event.stopPropagation()\">\r\n <button class=\"ndt-btn ndt-export-btn\" type=\"button\" (click)=\"toggleExportMenu($event)\">\r\n <i class=\"bi bi-download\"></i>\r\n <span>Export</span>\r\n <i class=\"bi bi-chevron-down ndt-chevron\"></i>\r\n </button>\r\n\r\n <ul class=\"ndt-dropdown-menu\" *ngIf=\"isExportMenuOpen\">\r\n <li *ngIf=\"isExportFormatEnabled('csv')\">\r\n <button type=\"button\" class=\"ndt-dropdown-item\" (click)=\"exportCSV()\">\r\n <i class=\"bi bi-filetype-csv\"></i>\r\n <span>CSV</span>\r\n </button>\r\n </li>\r\n <li *ngIf=\"isExportFormatEnabled('excel')\">\r\n <button type=\"button\" class=\"ndt-dropdown-item\" (click)=\"exportExcel()\">\r\n <i class=\"bi bi-file-earmark-spreadsheet\"></i>\r\n <span>Excel (.xls)</span>\r\n </button>\r\n </li>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n\r\n <label class=\"ndt-inline-label\" *ngIf=\"isFeatureOn('rowsPerPage') && isFeatureOn('pagination')\">\r\n Rows per page:\r\n <select [value]=\"rowsPerPage\" (change)=\"onRowsPerPageChange($event)\">\r\n <option *ngFor=\"let option of mergedConfig.rowsPerPageOptions || []\" [value]=\"option\">{{ option }}</option>\r\n </select>\r\n </label>\r\n </div>\r\n\r\n <div class=\"ndt-right-tools\" *ngIf=\"isFeatureOn('searching')\">\r\n <input\r\n type=\"search\"\r\n placeholder=\"Search records\"\r\n [value]=\"searchTerm\"\r\n (input)=\"onSearchInput($event)\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"ndt-table-wrap\">\r\n <table class=\"ndt-table\">\r\n <colgroup>\r\n <col *ngIf=\"isFeatureOn('checkboxSelection')\" style=\"width: 44px\" />\r\n <col *ngFor=\"let column of mergedColumns\" [style.width]=\"toColumnWidth(column.width)\" />\r\n <col *ngIf=\"isFeatureOn('actions')\" style=\"width: 78px\" />\r\n </colgroup>\r\n\r\n <thead>\r\n <tr>\r\n <th *ngIf=\"isFeatureOn('checkboxSelection')\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"isCurrentPageFullySelected()\"\r\n (change)=\"toggleSelectAllCurrentPage($event)\"\r\n />\r\n </th>\r\n <th\r\n *ngFor=\"let column of mergedColumns\"\r\n [class.ndt-sortable]=\"isFeatureOn('sorting') && !!column.sortable\"\r\n (click)=\"toggleSort(column)\"\r\n >\r\n <span class=\"ndt-th-content\">\r\n <span class=\"ndt-th-label\">{{ column.label }}</span>\r\n <i\r\n *ngIf=\"isFeatureOn('sorting') && column.sortable\"\r\n [ngClass]=\"[\r\n 'ndt-sort-indicator',\r\n getSortIconClass(column.key.toString()),\r\n isSortColumn(column.key.toString()) ? 'active' : ''\r\n ]\"\r\n ></i>\r\n </span>\r\n </th>\r\n <th *ngIf=\"isFeatureOn('actions')\">Actions</th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n <tr *ngIf=\"!pagedRows.length\">\r\n <td [attr.colspan]=\"getColumnCount()\" class=\"ndt-empty\">No records found.</td>\r\n </tr>\r\n\r\n <tr *ngFor=\"let row of pagedRows\" [class.ndt-selected]=\"isRowSelected(row.id)\">\r\n <td *ngIf=\"isFeatureOn('checkboxSelection')\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"isRowSelected(row.id)\"\r\n (change)=\"toggleRowSelection(row, $event)\"\r\n />\r\n </td>\r\n\r\n <td *ngFor=\"let column of mergedColumns\" [innerHTML]=\"getRenderedCell(row.data, column)\"></td>\r\n\r\n <td *ngIf=\"isFeatureOn('actions')\" class=\"ndt-actions-cell\">\r\n <div class=\"ndt-dropdown\" (click)=\"$event.stopPropagation()\">\r\n <button\r\n type=\"button\"\r\n class=\"ndt-actions-btn\"\r\n (click)=\"toggleActionMenu(row.id, $event)\"\r\n [attr.aria-expanded]=\"isActionMenuOpen(row.id)\"\r\n >\r\n <span class=\"ndt-dots\">...</span>\r\n </button>\r\n\r\n <ul\r\n class=\"ndt-dropdown-menu ndt-action-menu\"\r\n *ngIf=\"isActionMenuOpen(row.id)\"\r\n [ngStyle]=\"actionMenuStyle\"\r\n [attr.data-row-id]=\"row.id\"\r\n >\r\n <li *ngFor=\"let action of mergedConfig.actions || []; let i = index\">\r\n <button\r\n type=\"button\"\r\n class=\"ndt-dropdown-item\"\r\n [class.ndt-danger]=\"!!action.danger\"\r\n (click)=\"onActionItemClick(i, row, $event)\"\r\n >\r\n <i *ngIf=\"action.icon\" [class]=\"action.icon\"></i>\r\n <span>{{ action.label }}</span>\r\n </button>\r\n </li>\r\n </ul>\r\n </div>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div class=\"ndt-footer\">\r\n <div>\r\n {{ selectedRows.size }} selected\r\n </div>\r\n\r\n <div>\r\n Showing {{ getStartEntry() }} to {{ getEndEntry() }} of {{ filteredRows.length }} entries\r\n </div>\r\n\r\n <ul class=\"ndt-pagination\" *ngIf=\"isFeatureOn('pagination') && totalPages > 1\">\r\n <li [class.disabled]=\"currentPage <= 1\">\r\n <button type=\"button\" class=\"ndt-page-link\" (click)=\"goToPage(currentPage - 1)\" [disabled]=\"currentPage <= 1\">Prev</button>\r\n </li>\r\n <li *ngFor=\"let page of getPaginationPages()\" [class.active]=\"page === currentPage\">\r\n <button type=\"button\" class=\"ndt-page-link\" (click)=\"goToPage(page)\">{{ page }}</button>\r\n </li>\r\n <li [class.disabled]=\"currentPage >= totalPages\">\r\n <button type=\"button\" class=\"ndt-page-link\" (click)=\"goToPage(currentPage + 1)\" [disabled]=\"currentPage >= totalPages\">Next</button>\r\n </li>\r\n </ul>\r\n </div>\r\n</div>\r\n", styles: [":host{display:block;--ndt-primary: #4f46e5;--ndt-primary-dark: #4338ca;--ndt-primary-soft: #eef2ff;--ndt-border: #dbe4ff;--ndt-text: #1f2a44;--ndt-muted: #6d7895}.ndt-card{border:1px solid var(--ndt-border);border-radius:20px;padding:10px;background:#ffffffe6;backdrop-filter:blur(3px);box-shadow:0 20px 45px #2d489124;overflow:hidden;color:var(--ndt-text);font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif}.ndt-header,.ndt-toolbar,.ndt-footer{padding:1.05rem 1.35rem}.ndt-header{background:linear-gradient(180deg,#fff,#fafcff);border-bottom:1px solid #eaf0ff}.ndt-title{margin:0;font-size:1.2rem;color:#1b2550}.ndt-toolbar{display:flex;justify-content:space-between;gap:.75rem;flex-wrap:wrap;align-items:center}.ndt-left-tools,.ndt-right-tools{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap}.ndt-btn,.ndt-toolbar select,.ndt-toolbar input{border:1px solid #d5def8;background:#fff;color:#445381;border-radius:10px;padding:.36rem .62rem;font-size:.85rem}.ndt-btn:hover{border-color:var(--ndt-primary);background:#4f46e512;color:var(--ndt-primary)}.ndt-toolbar input{min-width:260px}.ndt-toolbar input:focus,.ndt-toolbar select:focus{outline:none;border-color:#4f46e58c;box-shadow:0 0 0 .2rem #4f46e51f}.ndt-inline-label{display:inline-flex;align-items:center;gap:.4rem;color:var(--ndt-muted);font-size:.85rem}.ndt-table-wrap{margin:0 1.35rem;overflow-x:auto;overflow-y:visible;border:1px solid #e5ecff;border-radius:14px;background:#fff}.ndt-table{width:100%;min-width:920px;border-collapse:collapse;table-layout:fixed}.ndt-table th,.ndt-table td{padding:.8rem .72rem;text-align:left;border-bottom:1px solid #edf2ff;vertical-align:middle}.ndt-table th{color:#4a577f;font-size:.85rem;text-transform:uppercase;letter-spacing:.03em;background:#f7faff;border-bottom:1px solid #e6edff}.ndt-th-content{display:flex;align-items:center;justify-content:space-between;gap:.4rem}.ndt-th-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ndt-sortable{cursor:pointer}.ndt-sort-indicator{font-size:.82rem;color:#8a98c2;min-width:16px;text-align:center}.ndt-sort-indicator.active{color:var(--ndt-primary)}.ndt-table tbody tr:hover{background:#f5f8ff}.ndt-selected{background:#ebf1ff}.ndt-actions-cell{text-align:center;position:relative}.ndt-dropdown{position:relative;display:inline-block}.ndt-export-btn{display:inline-flex;align-items:center;gap:.42rem}.ndt-chevron{font-size:.72rem;margin-left:.12rem}.ndt-actions-btn{border:1px solid #d2dcfb;background:#f7f9ff;color:#33446e;border-radius:10px;width:34px;height:30px;padding:0;cursor:pointer}.ndt-actions-btn:hover{border-color:var(--ndt-primary);color:var(--ndt-primary);background:#eef3ff}.ndt-dots{font-size:1rem;line-height:1}.ndt-dropdown-menu{position:absolute;left:0;top:calc(100% + .35rem);list-style:none;margin:0;padding:.35rem 0;min-width:120px;border:1px solid #dbe4ff;border-radius:12px;background:#fff;box-shadow:0 12px 24px #2d489124;z-index:20}.ndt-action-menu{min-width:140px;max-height:calc(100vh - 16px);overflow-y:auto;z-index:1080}.ndt-dropdown-item{width:100%;border:0;background:#fff;color:#33446e;display:flex;align-items:center;gap:.45rem;text-align:left;padding:.42rem .72rem;font-size:.84rem;cursor:pointer}.ndt-dropdown-item i{font-size:.9rem;width:14px}.ndt-dropdown-item:hover{background:#f5f8ff;color:var(--ndt-primary)}.ndt-dropdown-item.ndt-danger{color:#dc3545}.ndt-dropdown-item.ndt-danger:hover{background:#fff1f3}.ndt-empty{text-align:center;color:var(--ndt-muted)}.ndt-footer{display:flex;align-items:center;justify-content:space-between;gap:.75rem;flex-wrap:wrap;color:#52628a;font-size:.88rem}.ndt-pagination{display:flex;list-style:none;margin:0;padding:0;align-items:center;gap:.35rem}.ndt-pagination li{display:inline-flex}.ndt-page-link{border:1px solid #d5def8;background:#fff;color:var(--ndt-primary);border-radius:8px;min-width:34px;height:30px;padding:0 .6rem;font-size:.82rem;display:inline-flex;align-items:center;justify-content:center}.ndt-page-link:hover{border-color:var(--ndt-primary);background:#4f46e512}.ndt-pagination li.active .ndt-page-link{background:var(--ndt-primary);border-color:var(--ndt-primary);color:#fff}.ndt-pagination li.disabled .ndt-page-link{opacity:.55;cursor:not-allowed}@media(max-width:900px){.ndt-toolbar,.ndt-footer{flex-direction:column;align-items:flex-start}.ndt-toolbar input{min-width:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
|
|
773
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DynamicDatatableComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
774
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", type: DynamicDatatableComponent, isStandalone: true, selector: "lib-dynamic-datatable", inputs: { config: "config", columns: "columns", data: "data" }, outputs: { actionSelected: "actionSelected", selectionChange: "selectionChange", sortChange: "sortChange", pageChange: "pageChange", exportTriggered: "exportTriggered" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"ndt-card\" (click)=\"closeMenus()\">\r\n <div class=\"ndt-header\">\r\n <h3 class=\"ndt-title\" [attr.data-tooltip]=\"mergedConfig.title\">{{ mergedConfig.title }}</h3>\r\n </div>\r\n\r\n <div class=\"ndt-toolbar\">\r\n <div class=\"ndt-left-tools\">\r\n <ng-container *ngIf=\"isFeatureOn('export')\">\r\n <div class=\"ndt-dropdown\" (click)=\"$event.stopPropagation()\">\r\n <button class=\"ndt-btn ndt-export-btn\" type=\"button\" data-tooltip=\"Export data\" data-tooltip-position=\"bottom\" (click)=\"toggleExportMenu($event)\">\r\n <i class=\"bi bi-download\"></i>\r\n <span>Export</span>\r\n <i class=\"bi bi-chevron-down ndt-chevron\"></i>\r\n </button>\r\n\r\n <ul class=\"ndt-dropdown-menu\" *ngIf=\"isExportMenuOpen\">\r\n <li *ngIf=\"isExportFormatEnabled('csv')\">\r\n <button type=\"button\" class=\"ndt-dropdown-item\" data-tooltip=\"Download CSV\" data-tooltip-position=\"right\" (click)=\"exportCSV()\">\r\n <i class=\"bi bi-filetype-csv\"></i>\r\n <span>CSV</span>\r\n </button>\r\n </li>\r\n <li *ngIf=\"isExportFormatEnabled('excel')\">\r\n <button type=\"button\" class=\"ndt-dropdown-item\" data-tooltip=\"Download Excel\" data-tooltip-position=\"right\" (click)=\"exportExcel()\">\r\n <i class=\"bi bi-file-earmark-spreadsheet\"></i>\r\n <span>Excel (.xls)</span>\r\n </button>\r\n </li>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n\r\n <label class=\"ndt-inline-label\" *ngIf=\"isFeatureOn('rowsPerPage') && isFeatureOn('pagination')\">\r\n Rows per page:\r\n <select data-tooltip=\"Rows per page\" [value]=\"rowsPerPage\" (change)=\"onRowsPerPageChange($event)\">\r\n <option *ngFor=\"let option of mergedConfig.rowsPerPageOptions || []\" [value]=\"option\" [attr.data-tooltip]=\"'Show ' + option + ' rows per page'\">{{ option }}</option>\r\n </select>\r\n </label>\r\n </div>\r\n\r\n <div class=\"ndt-right-tools\" *ngIf=\"isFeatureOn('searching')\">\r\n <input\r\n type=\"search\"\r\n placeholder=\"Search records\"\r\n data-tooltip=\"Search records\"\r\n [value]=\"searchTerm\"\r\n (input)=\"onSearchInput($event)\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"ndt-table-wrap\">\r\n <table class=\"ndt-table\">\r\n <colgroup>\r\n <col *ngIf=\"isFeatureOn('checkboxSelection')\" style=\"width: 44px\" />\r\n <col *ngFor=\"let column of mergedColumns\" [style.width]=\"toColumnWidth(column.width)\" />\r\n <col *ngIf=\"isFeatureOn('actions')\" style=\"width: 78px\" />\r\n </colgroup>\r\n\r\n <thead>\r\n <tr>\r\n <th *ngIf=\"isFeatureOn('checkboxSelection')\">\r\n <input\r\n type=\"checkbox\"\r\n data-tooltip=\"Select all rows on current page\"\r\n [checked]=\"isCurrentPageFullySelected()\"\r\n (change)=\"toggleSelectAllCurrentPage($event)\"\r\n />\r\n </th>\r\n <th\r\n *ngFor=\"let column of mergedColumns\"\r\n [class.ndt-sortable]=\"isFeatureOn('sorting') && !!column.sortable\"\r\n [attr.data-tooltip]=\"getColumnTooltip(column)\"\r\n data-tooltip-position=\"top\"\r\n (click)=\"toggleSort(column)\"\r\n >\r\n <span class=\"ndt-th-content\">\r\n <span class=\"ndt-th-label\">{{ column.label }}</span>\r\n <i\r\n *ngIf=\"isFeatureOn('sorting') && column.sortable\"\r\n [ngClass]=\"[\r\n 'ndt-sort-indicator',\r\n getSortIconClass(column.key.toString()),\r\n isSortColumn(column.key.toString()) ? 'active' : ''\r\n ]\"\r\n [attr.data-tooltip]=\"getColumnTooltip(column)\"\r\n data-tooltip-position=\"top\"\r\n ></i>\r\n </span>\r\n </th>\r\n <th *ngIf=\"isFeatureOn('actions')\" data-tooltip=\"Available row actions\" data-tooltip-position=\"top\">Actions</th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n <tr *ngIf=\"!pagedRows.length\">\r\n <td [attr.colspan]=\"getColumnCount()\" class=\"ndt-empty\" data-tooltip=\"No records found\">No records found.</td>\r\n </tr>\r\n\r\n <tr *ngFor=\"let row of pagedRows\" [class.ndt-selected]=\"isRowSelected(row.id)\">\r\n <td *ngIf=\"isFeatureOn('checkboxSelection')\">\r\n <input\r\n type=\"checkbox\"\r\n [attr.data-tooltip]=\"'Select row ' + row.id\"\r\n [checked]=\"isRowSelected(row.id)\"\r\n (change)=\"toggleRowSelection(row, $event)\"\r\n />\r\n </td>\r\n\r\n <td\r\n *ngFor=\"let column of mergedColumns\"\r\n [attr.data-tooltip]=\"getCellTooltip(row.data, column)\"\r\n data-tooltip-position=\"bottom\"\r\n [innerHTML]=\"getRenderedCell(row.data, column)\">\r\n </td>\r\n\r\n <td *ngIf=\"isFeatureOn('actions')\" class=\"ndt-actions-cell\">\r\n <div class=\"ndt-action-icons\" (click)=\"$event.stopPropagation()\">\r\n <button\r\n *ngFor=\"let action of mergedConfig.actions || []; let i = index\"\r\n type=\"button\"\r\n class=\"ndt-actions-btn\"\r\n [class.ndt-danger]=\"!!action.danger\"\r\n [attr.data-tooltip]=\"action.label\"\r\n data-tooltip-position=\"top\"\r\n [attr.aria-label]=\"action.label\"\r\n (click)=\"onActionItemClick(i, row, $event)\"\r\n >\r\n <i *ngIf=\"action.icon\" [class]=\"action.icon\"></i>\r\n <span *ngIf=\"!action.icon\" class=\"ndt-action-fallback\">{{ action.label.charAt(0) }}</span>\r\n </button>\r\n </div>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div class=\"ndt-footer\">\r\n <div [attr.data-tooltip]=\"selectedRows.size + ' rows selected'\">\r\n {{ selectedRows.size }} selected\r\n </div>\r\n\r\n <div [attr.data-tooltip]=\"'Showing ' + getStartEntry() + ' to ' + getEndEntry() + ' of ' + filteredRows.length + ' entries'\">\r\n Showing {{ getStartEntry() }} to {{ getEndEntry() }} of {{ filteredRows.length }} entries\r\n </div>\r\n\r\n <ul class=\"ndt-pagination\" *ngIf=\"isFeatureOn('pagination') && totalPages > 1\">\r\n <li [class.disabled]=\"currentPage <= 1\">\r\n <button type=\"button\" class=\"ndt-page-link\" data-tooltip=\"Go to previous page\" data-tooltip-position=\"top\" (click)=\"goToPage(currentPage - 1)\" [disabled]=\"currentPage <= 1\">Prev</button>\r\n </li>\r\n <li *ngFor=\"let page of getPaginationPages()\" [class.active]=\"page === currentPage\">\r\n <button type=\"button\" class=\"ndt-page-link\" [attr.data-tooltip]=\"'Go to page ' + page\" data-tooltip-position=\"top\" (click)=\"goToPage(page)\">{{ page }}</button>\r\n </li>\r\n <li [class.disabled]=\"currentPage >= totalPages\">\r\n <button type=\"button\" class=\"ndt-page-link\" data-tooltip=\"Go to next page\" data-tooltip-position=\"top\" (click)=\"goToPage(currentPage + 1)\" [disabled]=\"currentPage >= totalPages\">Next</button>\r\n </li>\r\n </ul>\r\n </div>\r\n</div>\r\n", styles: [":host{--ndt-tooltip-bg: #111a32;--ndt-tooltip-color: #ffffff;--ndt-tooltip-shadow: 0 12px 24px rgba(16, 24, 40, .28);--ndt-tooltip-radius: 10px;--ndt-tooltip-padding-y: .4rem;--ndt-tooltip-padding-x: .55rem;--ndt-tooltip-font-size: .78rem;--ndt-tooltip-arrow-size: 7px;--ndt-tooltip-z-index: 1100}[data-tooltip]{cursor:help}.ndt-tooltip{position:fixed;top:0;left:0;z-index:var(--ndt-tooltip-z-index);max-width:min(260px,calc(100vw - 16px));border-radius:var(--ndt-tooltip-radius);background:var(--ndt-tooltip-bg);color:var(--ndt-tooltip-color);box-shadow:var(--ndt-tooltip-shadow);font-size:var(--ndt-tooltip-font-size);line-height:1.3;padding:var(--ndt-tooltip-padding-y) var(--ndt-tooltip-padding-x);opacity:0;transform:translate3d(0,4px,0) scale(.98);transition:opacity .14s ease,transform .18s ease;pointer-events:auto}.ndt-tooltip.ndt-tooltip--show{opacity:1;transform:translateZ(0) scale(1)}.ndt-tooltip__content{display:inline-flex;align-items:center;gap:.42rem;max-width:100%}.ndt-tooltip__icon{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;font-size:.78rem;flex:0 0 auto}.ndt-tooltip__text{word-break:break-word}.ndt-tooltip:before{content:\"\";position:absolute;width:0;height:0;border-style:solid}.ndt-tooltip[data-placement=bottom]:before{top:calc(-1 * var(--ndt-tooltip-arrow-size));left:calc(50% - var(--ndt-tooltip-arrow-size));border-width:0 var(--ndt-tooltip-arrow-size) var(--ndt-tooltip-arrow-size) var(--ndt-tooltip-arrow-size);border-color:transparent transparent var(--ndt-tooltip-bg) transparent}.ndt-tooltip[data-placement=top]:before{bottom:calc(-1 * var(--ndt-tooltip-arrow-size));left:calc(50% - var(--ndt-tooltip-arrow-size));border-width:var(--ndt-tooltip-arrow-size) var(--ndt-tooltip-arrow-size) 0 var(--ndt-tooltip-arrow-size);border-color:var(--ndt-tooltip-bg) transparent transparent transparent}.ndt-tooltip[data-placement=left]:before{top:calc(50% - var(--ndt-tooltip-arrow-size));right:calc(-1 * var(--ndt-tooltip-arrow-size));border-width:var(--ndt-tooltip-arrow-size) 0 var(--ndt-tooltip-arrow-size) var(--ndt-tooltip-arrow-size);border-color:transparent transparent transparent var(--ndt-tooltip-bg)}.ndt-tooltip[data-placement=right]:before{top:calc(50% - var(--ndt-tooltip-arrow-size));left:calc(-1 * var(--ndt-tooltip-arrow-size));border-width:var(--ndt-tooltip-arrow-size) var(--ndt-tooltip-arrow-size) var(--ndt-tooltip-arrow-size) 0;border-color:transparent var(--ndt-tooltip-bg) transparent transparent}.ndt-tooltip[data-no-arrow=true]:before{display:none}@media(max-width:576px){.ndt-tooltip{font-size:.75rem;max-width:min(220px,calc(100vw - 12px))}}:host{display:block;--ndt-primary: #4f46e5;--ndt-primary-dark: #4338ca;--ndt-primary-soft: #eef2ff;--ndt-border: #dbe4ff;--ndt-text: #1f2a44;--ndt-muted: #6d7895}.ndt-card{border:1px solid var(--ndt-border);border-radius:20px;padding:10px;background:#ffffffe6;backdrop-filter:blur(3px);box-shadow:0 20px 45px #2d489124;overflow:hidden;color:var(--ndt-text);font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif}.ndt-header,.ndt-toolbar,.ndt-footer{padding:1.05rem 1.35rem}.ndt-header{background:linear-gradient(180deg,#fff,#fafcff);border-bottom:1px solid #eaf0ff}.ndt-title{margin:0;font-size:1.2rem;color:#1b2550}.ndt-toolbar{display:flex;justify-content:space-between;gap:.75rem;flex-wrap:wrap;align-items:center}.ndt-left-tools,.ndt-right-tools{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap}.ndt-btn,.ndt-toolbar select,.ndt-toolbar input{border:1px solid #d5def8;background:#fff;color:#445381;border-radius:10px;padding:.36rem .62rem;font-size:.85rem}.ndt-btn:hover{border-color:var(--ndt-primary);background:#4f46e512;color:var(--ndt-primary)}.ndt-toolbar input{min-width:260px}.ndt-toolbar input:focus,.ndt-toolbar select:focus{outline:none;border-color:#4f46e58c;box-shadow:0 0 0 .2rem #4f46e51f}.ndt-inline-label{display:inline-flex;align-items:center;gap:.4rem;color:var(--ndt-muted);font-size:.85rem}.ndt-table-wrap{margin:0 1.35rem;overflow-x:auto;overflow-y:visible;border:1px solid #e5ecff;border-radius:14px;background:#fff}.ndt-table{width:100%;min-width:920px;border-collapse:collapse;table-layout:fixed}.ndt-table th,.ndt-table td{padding:.8rem .72rem;text-align:left;border-bottom:1px solid #edf2ff;vertical-align:middle}.ndt-table th{color:#4a577f;font-size:.85rem;text-transform:uppercase;letter-spacing:.03em;background:#f7faff;border-bottom:1px solid #e6edff}.ndt-th-content{display:flex;align-items:center;justify-content:space-between;gap:.4rem}.ndt-th-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ndt-sortable{cursor:pointer}.ndt-sort-indicator{font-size:.82rem;color:#8a98c2;min-width:16px;text-align:center}.ndt-sort-indicator.active{color:var(--ndt-primary)}.ndt-table tbody tr:hover{background:#f5f8ff}.ndt-selected{background:#ebf1ff}.ndt-actions-cell{text-align:center;position:relative}.ndt-action-icons{display:inline-flex;align-items:center;justify-content:center;gap:.35rem}.ndt-dropdown{position:relative;display:inline-block}.ndt-export-btn{display:inline-flex;align-items:center;gap:.42rem}.ndt-chevron{font-size:.72rem;margin-left:.12rem}.ndt-actions-btn{border:1px solid #d2dcfb;background:#f7f9ff;color:#33446e;border-radius:10px;width:34px;height:30px;padding:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center}.ndt-actions-btn:hover{border-color:var(--ndt-primary);color:var(--ndt-primary);background:#eef3ff}.ndt-dots{font-size:1rem;line-height:1}.ndt-action-fallback{font-size:.72rem;font-weight:700;line-height:1}.ndt-actions-btn.ndt-danger{color:#dc3545;border-color:#f1c2c7;background:#fff5f6}.ndt-actions-btn.ndt-danger:hover{color:#bb2d3b;border-color:#dc3545;background:#ffe6e9}.ndt-dropdown-menu{position:absolute;left:0;top:calc(100% + .35rem);list-style:none;margin:0;padding:.35rem 0;min-width:120px;border:1px solid #dbe4ff;border-radius:12px;background:#fff;box-shadow:0 12px 24px #2d489124;z-index:20}.ndt-dropdown-item{width:100%;border:0;background:#fff;color:#33446e;display:flex;align-items:center;gap:.45rem;text-align:left;padding:.42rem .72rem;font-size:.84rem;cursor:pointer}.ndt-dropdown-item i{font-size:.9rem;width:14px}.ndt-dropdown-item:hover{background:#f5f8ff;color:var(--ndt-primary)}.ndt-dropdown-item.ndt-danger{color:#dc3545}.ndt-dropdown-item.ndt-danger:hover{background:#fff1f3}.ndt-empty{text-align:center;color:var(--ndt-muted)}.ndt-footer{display:flex;align-items:center;justify-content:space-between;gap:.75rem;flex-wrap:wrap;color:#52628a;font-size:.88rem}.ndt-pagination{display:flex;list-style:none;margin:0;padding:0;align-items:center;gap:.35rem}.ndt-pagination li{display:inline-flex}.ndt-page-link{border:1px solid #d5def8;background:#fff;color:var(--ndt-primary);border-radius:8px;min-width:34px;height:30px;padding:0 .6rem;font-size:.82rem;display:inline-flex;align-items:center;justify-content:center}.ndt-page-link:hover{border-color:var(--ndt-primary);background:#4f46e512}.ndt-pagination li.active .ndt-page-link{background:var(--ndt-primary);border-color:var(--ndt-primary);color:#fff}.ndt-pagination li.disabled .ndt-page-link{opacity:.55;cursor:not-allowed}@media(max-width:900px){.ndt-toolbar,.ndt-footer{flex-direction:column;align-items:flex-start}.ndt-toolbar input{min-width:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
549
775
|
}
|
|
550
776
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DynamicDatatableComponent, decorators: [{
|
|
551
777
|
type: Component,
|
|
552
|
-
args: [{ selector: 'lib-dynamic-datatable', standalone: true, imports: [CommonModule], template: "<div class=\"ndt-card\" (click)=\"closeMenus()\">\r\n <div class=\"ndt-header\">\r\n <h3 class=\"ndt-title\">{{ mergedConfig.title }}</h3>\r\n </div>\r\n\r\n <div class=\"ndt-toolbar\">\r\n <div class=\"ndt-left-tools\">\r\n <ng-container *ngIf=\"isFeatureOn('export')\">\r\n <div class=\"ndt-dropdown\" (click)=\"$event.stopPropagation()\">\r\n <button class=\"ndt-btn ndt-export-btn\" type=\"button\" (click)=\"toggleExportMenu($event)\">\r\n <i class=\"bi bi-download\"></i>\r\n <span>Export</span>\r\n <i class=\"bi bi-chevron-down ndt-chevron\"></i>\r\n </button>\r\n\r\n <ul class=\"ndt-dropdown-menu\" *ngIf=\"isExportMenuOpen\">\r\n <li *ngIf=\"isExportFormatEnabled('csv')\">\r\n <button type=\"button\" class=\"ndt-dropdown-item\" (click)=\"exportCSV()\">\r\n <i class=\"bi bi-filetype-csv\"></i>\r\n <span>CSV</span>\r\n </button>\r\n </li>\r\n <li *ngIf=\"isExportFormatEnabled('excel')\">\r\n <button type=\"button\" class=\"ndt-dropdown-item\" (click)=\"exportExcel()\">\r\n <i class=\"bi bi-file-earmark-spreadsheet\"></i>\r\n <span>Excel (.xls)</span>\r\n </button>\r\n </li>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n\r\n <label class=\"ndt-inline-label\" *ngIf=\"isFeatureOn('rowsPerPage') && isFeatureOn('pagination')\">\r\n Rows per page:\r\n <select [value]=\"rowsPerPage\" (change)=\"onRowsPerPageChange($event)\">\r\n <option *ngFor=\"let option of mergedConfig.rowsPerPageOptions || []\" [value]=\"option\">{{ option }}</option>\r\n </select>\r\n </label>\r\n </div>\r\n\r\n <div class=\"ndt-right-tools\" *ngIf=\"isFeatureOn('searching')\">\r\n <input\r\n type=\"search\"\r\n placeholder=\"Search records\"\r\n [value]=\"searchTerm\"\r\n (input)=\"onSearchInput($event)\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"ndt-table-wrap\">\r\n <table class=\"ndt-table\">\r\n <colgroup>\r\n <col *ngIf=\"isFeatureOn('checkboxSelection')\" style=\"width: 44px\" />\r\n <col *ngFor=\"let column of mergedColumns\" [style.width]=\"toColumnWidth(column.width)\" />\r\n <col *ngIf=\"isFeatureOn('actions')\" style=\"width: 78px\" />\r\n </colgroup>\r\n\r\n <thead>\r\n <tr>\r\n <th *ngIf=\"isFeatureOn('checkboxSelection')\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"isCurrentPageFullySelected()\"\r\n (change)=\"toggleSelectAllCurrentPage($event)\"\r\n />\r\n </th>\r\n <th\r\n *ngFor=\"let column of mergedColumns\"\r\n [class.ndt-sortable]=\"isFeatureOn('sorting') && !!column.sortable\"\r\n (click)=\"toggleSort(column)\"\r\n >\r\n <span class=\"ndt-th-content\">\r\n <span class=\"ndt-th-label\">{{ column.label }}</span>\r\n <i\r\n *ngIf=\"isFeatureOn('sorting') && column.sortable\"\r\n [ngClass]=\"[\r\n 'ndt-sort-indicator',\r\n getSortIconClass(column.key.toString()),\r\n isSortColumn(column.key.toString()) ? 'active' : ''\r\n ]\"\r\n ></i>\r\n </span>\r\n </th>\r\n <th *ngIf=\"isFeatureOn('actions')\">Actions</th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n <tr *ngIf=\"!pagedRows.length\">\r\n <td [attr.colspan]=\"getColumnCount()\" class=\"ndt-empty\">No records found.</td>\r\n </tr>\r\n\r\n <tr *ngFor=\"let row of pagedRows\" [class.ndt-selected]=\"isRowSelected(row.id)\">\r\n <td *ngIf=\"isFeatureOn('checkboxSelection')\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"isRowSelected(row.id)\"\r\n (change)=\"toggleRowSelection(row, $event)\"\r\n />\r\n </td>\r\n\r\n <td *ngFor=\"let column of mergedColumns\" [innerHTML]=\"getRenderedCell(row.data, column)\"></td>\r\n\r\n <td *ngIf=\"isFeatureOn('actions')\" class=\"ndt-actions-cell\">\r\n <div class=\"ndt-dropdown\" (click)=\"$event.stopPropagation()\">\r\n <button\r\n type=\"button\"\r\n class=\"ndt-actions-btn\"\r\n (click)=\"toggleActionMenu(row.id, $event)\"\r\n [attr.aria-expanded]=\"isActionMenuOpen(row.id)\"\r\n >\r\n <span class=\"ndt-dots\">...</span>\r\n </button>\r\n\r\n <ul\r\n class=\"ndt-dropdown-menu ndt-action-menu\"\r\n *ngIf=\"isActionMenuOpen(row.id)\"\r\n [ngStyle]=\"actionMenuStyle\"\r\n [attr.data-row-id]=\"row.id\"\r\n >\r\n <li *ngFor=\"let action of mergedConfig.actions || []; let i = index\">\r\n <button\r\n type=\"button\"\r\n class=\"ndt-dropdown-item\"\r\n [class.ndt-danger]=\"!!action.danger\"\r\n (click)=\"onActionItemClick(i, row, $event)\"\r\n >\r\n <i *ngIf=\"action.icon\" [class]=\"action.icon\"></i>\r\n <span>{{ action.label }}</span>\r\n </button>\r\n </li>\r\n </ul>\r\n </div>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div class=\"ndt-footer\">\r\n <div>\r\n {{ selectedRows.size }} selected\r\n </div>\r\n\r\n <div>\r\n Showing {{ getStartEntry() }} to {{ getEndEntry() }} of {{ filteredRows.length }} entries\r\n </div>\r\n\r\n <ul class=\"ndt-pagination\" *ngIf=\"isFeatureOn('pagination') && totalPages > 1\">\r\n <li [class.disabled]=\"currentPage <= 1\">\r\n <button type=\"button\" class=\"ndt-page-link\" (click)=\"goToPage(currentPage - 1)\" [disabled]=\"currentPage <= 1\">Prev</button>\r\n </li>\r\n <li *ngFor=\"let page of getPaginationPages()\" [class.active]=\"page === currentPage\">\r\n <button type=\"button\" class=\"ndt-page-link\" (click)=\"goToPage(page)\">{{ page }}</button>\r\n </li>\r\n <li [class.disabled]=\"currentPage >= totalPages\">\r\n <button type=\"button\" class=\"ndt-page-link\" (click)=\"goToPage(currentPage + 1)\" [disabled]=\"currentPage >= totalPages\">Next</button>\r\n </li>\r\n </ul>\r\n </div>\r\n</div>\r\n", styles: [":host{display:block;--ndt-primary: #4f46e5;--ndt-primary-dark: #4338ca;--ndt-primary-soft: #eef2ff;--ndt-border: #dbe4ff;--ndt-text: #1f2a44;--ndt-muted: #6d7895}.ndt-card{border:1px solid var(--ndt-border);border-radius:20px;padding:10px;background:#ffffffe6;backdrop-filter:blur(3px);box-shadow:0 20px 45px #2d489124;overflow:hidden;color:var(--ndt-text);font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif}.ndt-header,.ndt-toolbar,.ndt-footer{padding:1.05rem 1.35rem}.ndt-header{background:linear-gradient(180deg,#fff,#fafcff);border-bottom:1px solid #eaf0ff}.ndt-title{margin:0;font-size:1.2rem;color:#1b2550}.ndt-toolbar{display:flex;justify-content:space-between;gap:.75rem;flex-wrap:wrap;align-items:center}.ndt-left-tools,.ndt-right-tools{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap}.ndt-btn,.ndt-toolbar select,.ndt-toolbar input{border:1px solid #d5def8;background:#fff;color:#445381;border-radius:10px;padding:.36rem .62rem;font-size:.85rem}.ndt-btn:hover{border-color:var(--ndt-primary);background:#4f46e512;color:var(--ndt-primary)}.ndt-toolbar input{min-width:260px}.ndt-toolbar input:focus,.ndt-toolbar select:focus{outline:none;border-color:#4f46e58c;box-shadow:0 0 0 .2rem #4f46e51f}.ndt-inline-label{display:inline-flex;align-items:center;gap:.4rem;color:var(--ndt-muted);font-size:.85rem}.ndt-table-wrap{margin:0 1.35rem;overflow-x:auto;overflow-y:visible;border:1px solid #e5ecff;border-radius:14px;background:#fff}.ndt-table{width:100%;min-width:920px;border-collapse:collapse;table-layout:fixed}.ndt-table th,.ndt-table td{padding:.8rem .72rem;text-align:left;border-bottom:1px solid #edf2ff;vertical-align:middle}.ndt-table th{color:#4a577f;font-size:.85rem;text-transform:uppercase;letter-spacing:.03em;background:#f7faff;border-bottom:1px solid #e6edff}.ndt-th-content{display:flex;align-items:center;justify-content:space-between;gap:.4rem}.ndt-th-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ndt-sortable{cursor:pointer}.ndt-sort-indicator{font-size:.82rem;color:#8a98c2;min-width:16px;text-align:center}.ndt-sort-indicator.active{color:var(--ndt-primary)}.ndt-table tbody tr:hover{background:#f5f8ff}.ndt-selected{background:#ebf1ff}.ndt-actions-cell{text-align:center;position:relative}.ndt-dropdown{position:relative;display:inline-block}.ndt-export-btn{display:inline-flex;align-items:center;gap:.42rem}.ndt-chevron{font-size:.72rem;margin-left:.12rem}.ndt-actions-btn{border:1px solid #d2dcfb;background:#f7f9ff;color:#33446e;border-radius:10px;width:34px;height:30px;padding:0;cursor:pointer}.ndt-actions-btn:hover{border-color:var(--ndt-primary);color:var(--ndt-primary);background:#eef3ff}.ndt-dots{font-size:1rem;line-height:1}.ndt-dropdown-menu{position:absolute;left:0;top:calc(100% + .35rem);list-style:none;margin:0;padding:.35rem 0;min-width:120px;border:1px solid #dbe4ff;border-radius:12px;background:#fff;box-shadow:0 12px 24px #2d489124;z-index:20}.ndt-action-menu{min-width:140px;max-height:calc(100vh - 16px);overflow-y:auto;z-index:1080}.ndt-dropdown-item{width:100%;border:0;background:#fff;color:#33446e;display:flex;align-items:center;gap:.45rem;text-align:left;padding:.42rem .72rem;font-size:.84rem;cursor:pointer}.ndt-dropdown-item i{font-size:.9rem;width:14px}.ndt-dropdown-item:hover{background:#f5f8ff;color:var(--ndt-primary)}.ndt-dropdown-item.ndt-danger{color:#dc3545}.ndt-dropdown-item.ndt-danger:hover{background:#fff1f3}.ndt-empty{text-align:center;color:var(--ndt-muted)}.ndt-footer{display:flex;align-items:center;justify-content:space-between;gap:.75rem;flex-wrap:wrap;color:#52628a;font-size:.88rem}.ndt-pagination{display:flex;list-style:none;margin:0;padding:0;align-items:center;gap:.35rem}.ndt-pagination li{display:inline-flex}.ndt-page-link{border:1px solid #d5def8;background:#fff;color:var(--ndt-primary);border-radius:8px;min-width:34px;height:30px;padding:0 .6rem;font-size:.82rem;display:inline-flex;align-items:center;justify-content:center}.ndt-page-link:hover{border-color:var(--ndt-primary);background:#4f46e512}.ndt-pagination li.active .ndt-page-link{background:var(--ndt-primary);border-color:var(--ndt-primary);color:#fff}.ndt-pagination li.disabled .ndt-page-link{opacity:.55;cursor:not-allowed}@media(max-width:900px){.ndt-toolbar,.ndt-footer{flex-direction:column;align-items:flex-start}.ndt-toolbar input{min-width:100%}}\n"] }]
|
|
553
|
-
}], propDecorators: { config: [{
|
|
778
|
+
args: [{ selector: 'lib-dynamic-datatable', standalone: true, imports: [CommonModule], template: "<div class=\"ndt-card\" (click)=\"closeMenus()\">\r\n <div class=\"ndt-header\">\r\n <h3 class=\"ndt-title\" [attr.data-tooltip]=\"mergedConfig.title\">{{ mergedConfig.title }}</h3>\r\n </div>\r\n\r\n <div class=\"ndt-toolbar\">\r\n <div class=\"ndt-left-tools\">\r\n <ng-container *ngIf=\"isFeatureOn('export')\">\r\n <div class=\"ndt-dropdown\" (click)=\"$event.stopPropagation()\">\r\n <button class=\"ndt-btn ndt-export-btn\" type=\"button\" data-tooltip=\"Export data\" data-tooltip-position=\"bottom\" (click)=\"toggleExportMenu($event)\">\r\n <i class=\"bi bi-download\"></i>\r\n <span>Export</span>\r\n <i class=\"bi bi-chevron-down ndt-chevron\"></i>\r\n </button>\r\n\r\n <ul class=\"ndt-dropdown-menu\" *ngIf=\"isExportMenuOpen\">\r\n <li *ngIf=\"isExportFormatEnabled('csv')\">\r\n <button type=\"button\" class=\"ndt-dropdown-item\" data-tooltip=\"Download CSV\" data-tooltip-position=\"right\" (click)=\"exportCSV()\">\r\n <i class=\"bi bi-filetype-csv\"></i>\r\n <span>CSV</span>\r\n </button>\r\n </li>\r\n <li *ngIf=\"isExportFormatEnabled('excel')\">\r\n <button type=\"button\" class=\"ndt-dropdown-item\" data-tooltip=\"Download Excel\" data-tooltip-position=\"right\" (click)=\"exportExcel()\">\r\n <i class=\"bi bi-file-earmark-spreadsheet\"></i>\r\n <span>Excel (.xls)</span>\r\n </button>\r\n </li>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n\r\n <label class=\"ndt-inline-label\" *ngIf=\"isFeatureOn('rowsPerPage') && isFeatureOn('pagination')\">\r\n Rows per page:\r\n <select data-tooltip=\"Rows per page\" [value]=\"rowsPerPage\" (change)=\"onRowsPerPageChange($event)\">\r\n <option *ngFor=\"let option of mergedConfig.rowsPerPageOptions || []\" [value]=\"option\" [attr.data-tooltip]=\"'Show ' + option + ' rows per page'\">{{ option }}</option>\r\n </select>\r\n </label>\r\n </div>\r\n\r\n <div class=\"ndt-right-tools\" *ngIf=\"isFeatureOn('searching')\">\r\n <input\r\n type=\"search\"\r\n placeholder=\"Search records\"\r\n data-tooltip=\"Search records\"\r\n [value]=\"searchTerm\"\r\n (input)=\"onSearchInput($event)\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"ndt-table-wrap\">\r\n <table class=\"ndt-table\">\r\n <colgroup>\r\n <col *ngIf=\"isFeatureOn('checkboxSelection')\" style=\"width: 44px\" />\r\n <col *ngFor=\"let column of mergedColumns\" [style.width]=\"toColumnWidth(column.width)\" />\r\n <col *ngIf=\"isFeatureOn('actions')\" style=\"width: 78px\" />\r\n </colgroup>\r\n\r\n <thead>\r\n <tr>\r\n <th *ngIf=\"isFeatureOn('checkboxSelection')\">\r\n <input\r\n type=\"checkbox\"\r\n data-tooltip=\"Select all rows on current page\"\r\n [checked]=\"isCurrentPageFullySelected()\"\r\n (change)=\"toggleSelectAllCurrentPage($event)\"\r\n />\r\n </th>\r\n <th\r\n *ngFor=\"let column of mergedColumns\"\r\n [class.ndt-sortable]=\"isFeatureOn('sorting') && !!column.sortable\"\r\n [attr.data-tooltip]=\"getColumnTooltip(column)\"\r\n data-tooltip-position=\"top\"\r\n (click)=\"toggleSort(column)\"\r\n >\r\n <span class=\"ndt-th-content\">\r\n <span class=\"ndt-th-label\">{{ column.label }}</span>\r\n <i\r\n *ngIf=\"isFeatureOn('sorting') && column.sortable\"\r\n [ngClass]=\"[\r\n 'ndt-sort-indicator',\r\n getSortIconClass(column.key.toString()),\r\n isSortColumn(column.key.toString()) ? 'active' : ''\r\n ]\"\r\n [attr.data-tooltip]=\"getColumnTooltip(column)\"\r\n data-tooltip-position=\"top\"\r\n ></i>\r\n </span>\r\n </th>\r\n <th *ngIf=\"isFeatureOn('actions')\" data-tooltip=\"Available row actions\" data-tooltip-position=\"top\">Actions</th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n <tr *ngIf=\"!pagedRows.length\">\r\n <td [attr.colspan]=\"getColumnCount()\" class=\"ndt-empty\" data-tooltip=\"No records found\">No records found.</td>\r\n </tr>\r\n\r\n <tr *ngFor=\"let row of pagedRows\" [class.ndt-selected]=\"isRowSelected(row.id)\">\r\n <td *ngIf=\"isFeatureOn('checkboxSelection')\">\r\n <input\r\n type=\"checkbox\"\r\n [attr.data-tooltip]=\"'Select row ' + row.id\"\r\n [checked]=\"isRowSelected(row.id)\"\r\n (change)=\"toggleRowSelection(row, $event)\"\r\n />\r\n </td>\r\n\r\n <td\r\n *ngFor=\"let column of mergedColumns\"\r\n [attr.data-tooltip]=\"getCellTooltip(row.data, column)\"\r\n data-tooltip-position=\"bottom\"\r\n [innerHTML]=\"getRenderedCell(row.data, column)\">\r\n </td>\r\n\r\n <td *ngIf=\"isFeatureOn('actions')\" class=\"ndt-actions-cell\">\r\n <div class=\"ndt-action-icons\" (click)=\"$event.stopPropagation()\">\r\n <button\r\n *ngFor=\"let action of mergedConfig.actions || []; let i = index\"\r\n type=\"button\"\r\n class=\"ndt-actions-btn\"\r\n [class.ndt-danger]=\"!!action.danger\"\r\n [attr.data-tooltip]=\"action.label\"\r\n data-tooltip-position=\"top\"\r\n [attr.aria-label]=\"action.label\"\r\n (click)=\"onActionItemClick(i, row, $event)\"\r\n >\r\n <i *ngIf=\"action.icon\" [class]=\"action.icon\"></i>\r\n <span *ngIf=\"!action.icon\" class=\"ndt-action-fallback\">{{ action.label.charAt(0) }}</span>\r\n </button>\r\n </div>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div class=\"ndt-footer\">\r\n <div [attr.data-tooltip]=\"selectedRows.size + ' rows selected'\">\r\n {{ selectedRows.size }} selected\r\n </div>\r\n\r\n <div [attr.data-tooltip]=\"'Showing ' + getStartEntry() + ' to ' + getEndEntry() + ' of ' + filteredRows.length + ' entries'\">\r\n Showing {{ getStartEntry() }} to {{ getEndEntry() }} of {{ filteredRows.length }} entries\r\n </div>\r\n\r\n <ul class=\"ndt-pagination\" *ngIf=\"isFeatureOn('pagination') && totalPages > 1\">\r\n <li [class.disabled]=\"currentPage <= 1\">\r\n <button type=\"button\" class=\"ndt-page-link\" data-tooltip=\"Go to previous page\" data-tooltip-position=\"top\" (click)=\"goToPage(currentPage - 1)\" [disabled]=\"currentPage <= 1\">Prev</button>\r\n </li>\r\n <li *ngFor=\"let page of getPaginationPages()\" [class.active]=\"page === currentPage\">\r\n <button type=\"button\" class=\"ndt-page-link\" [attr.data-tooltip]=\"'Go to page ' + page\" data-tooltip-position=\"top\" (click)=\"goToPage(page)\">{{ page }}</button>\r\n </li>\r\n <li [class.disabled]=\"currentPage >= totalPages\">\r\n <button type=\"button\" class=\"ndt-page-link\" data-tooltip=\"Go to next page\" data-tooltip-position=\"top\" (click)=\"goToPage(currentPage + 1)\" [disabled]=\"currentPage >= totalPages\">Next</button>\r\n </li>\r\n </ul>\r\n </div>\r\n</div>\r\n", styles: [":host{--ndt-tooltip-bg: #111a32;--ndt-tooltip-color: #ffffff;--ndt-tooltip-shadow: 0 12px 24px rgba(16, 24, 40, .28);--ndt-tooltip-radius: 10px;--ndt-tooltip-padding-y: .4rem;--ndt-tooltip-padding-x: .55rem;--ndt-tooltip-font-size: .78rem;--ndt-tooltip-arrow-size: 7px;--ndt-tooltip-z-index: 1100}[data-tooltip]{cursor:help}.ndt-tooltip{position:fixed;top:0;left:0;z-index:var(--ndt-tooltip-z-index);max-width:min(260px,calc(100vw - 16px));border-radius:var(--ndt-tooltip-radius);background:var(--ndt-tooltip-bg);color:var(--ndt-tooltip-color);box-shadow:var(--ndt-tooltip-shadow);font-size:var(--ndt-tooltip-font-size);line-height:1.3;padding:var(--ndt-tooltip-padding-y) var(--ndt-tooltip-padding-x);opacity:0;transform:translate3d(0,4px,0) scale(.98);transition:opacity .14s ease,transform .18s ease;pointer-events:auto}.ndt-tooltip.ndt-tooltip--show{opacity:1;transform:translateZ(0) scale(1)}.ndt-tooltip__content{display:inline-flex;align-items:center;gap:.42rem;max-width:100%}.ndt-tooltip__icon{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;font-size:.78rem;flex:0 0 auto}.ndt-tooltip__text{word-break:break-word}.ndt-tooltip:before{content:\"\";position:absolute;width:0;height:0;border-style:solid}.ndt-tooltip[data-placement=bottom]:before{top:calc(-1 * var(--ndt-tooltip-arrow-size));left:calc(50% - var(--ndt-tooltip-arrow-size));border-width:0 var(--ndt-tooltip-arrow-size) var(--ndt-tooltip-arrow-size) var(--ndt-tooltip-arrow-size);border-color:transparent transparent var(--ndt-tooltip-bg) transparent}.ndt-tooltip[data-placement=top]:before{bottom:calc(-1 * var(--ndt-tooltip-arrow-size));left:calc(50% - var(--ndt-tooltip-arrow-size));border-width:var(--ndt-tooltip-arrow-size) var(--ndt-tooltip-arrow-size) 0 var(--ndt-tooltip-arrow-size);border-color:var(--ndt-tooltip-bg) transparent transparent transparent}.ndt-tooltip[data-placement=left]:before{top:calc(50% - var(--ndt-tooltip-arrow-size));right:calc(-1 * var(--ndt-tooltip-arrow-size));border-width:var(--ndt-tooltip-arrow-size) 0 var(--ndt-tooltip-arrow-size) var(--ndt-tooltip-arrow-size);border-color:transparent transparent transparent var(--ndt-tooltip-bg)}.ndt-tooltip[data-placement=right]:before{top:calc(50% - var(--ndt-tooltip-arrow-size));left:calc(-1 * var(--ndt-tooltip-arrow-size));border-width:var(--ndt-tooltip-arrow-size) var(--ndt-tooltip-arrow-size) var(--ndt-tooltip-arrow-size) 0;border-color:transparent var(--ndt-tooltip-bg) transparent transparent}.ndt-tooltip[data-no-arrow=true]:before{display:none}@media(max-width:576px){.ndt-tooltip{font-size:.75rem;max-width:min(220px,calc(100vw - 12px))}}:host{display:block;--ndt-primary: #4f46e5;--ndt-primary-dark: #4338ca;--ndt-primary-soft: #eef2ff;--ndt-border: #dbe4ff;--ndt-text: #1f2a44;--ndt-muted: #6d7895}.ndt-card{border:1px solid var(--ndt-border);border-radius:20px;padding:10px;background:#ffffffe6;backdrop-filter:blur(3px);box-shadow:0 20px 45px #2d489124;overflow:hidden;color:var(--ndt-text);font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif}.ndt-header,.ndt-toolbar,.ndt-footer{padding:1.05rem 1.35rem}.ndt-header{background:linear-gradient(180deg,#fff,#fafcff);border-bottom:1px solid #eaf0ff}.ndt-title{margin:0;font-size:1.2rem;color:#1b2550}.ndt-toolbar{display:flex;justify-content:space-between;gap:.75rem;flex-wrap:wrap;align-items:center}.ndt-left-tools,.ndt-right-tools{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap}.ndt-btn,.ndt-toolbar select,.ndt-toolbar input{border:1px solid #d5def8;background:#fff;color:#445381;border-radius:10px;padding:.36rem .62rem;font-size:.85rem}.ndt-btn:hover{border-color:var(--ndt-primary);background:#4f46e512;color:var(--ndt-primary)}.ndt-toolbar input{min-width:260px}.ndt-toolbar input:focus,.ndt-toolbar select:focus{outline:none;border-color:#4f46e58c;box-shadow:0 0 0 .2rem #4f46e51f}.ndt-inline-label{display:inline-flex;align-items:center;gap:.4rem;color:var(--ndt-muted);font-size:.85rem}.ndt-table-wrap{margin:0 1.35rem;overflow-x:auto;overflow-y:visible;border:1px solid #e5ecff;border-radius:14px;background:#fff}.ndt-table{width:100%;min-width:920px;border-collapse:collapse;table-layout:fixed}.ndt-table th,.ndt-table td{padding:.8rem .72rem;text-align:left;border-bottom:1px solid #edf2ff;vertical-align:middle}.ndt-table th{color:#4a577f;font-size:.85rem;text-transform:uppercase;letter-spacing:.03em;background:#f7faff;border-bottom:1px solid #e6edff}.ndt-th-content{display:flex;align-items:center;justify-content:space-between;gap:.4rem}.ndt-th-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ndt-sortable{cursor:pointer}.ndt-sort-indicator{font-size:.82rem;color:#8a98c2;min-width:16px;text-align:center}.ndt-sort-indicator.active{color:var(--ndt-primary)}.ndt-table tbody tr:hover{background:#f5f8ff}.ndt-selected{background:#ebf1ff}.ndt-actions-cell{text-align:center;position:relative}.ndt-action-icons{display:inline-flex;align-items:center;justify-content:center;gap:.35rem}.ndt-dropdown{position:relative;display:inline-block}.ndt-export-btn{display:inline-flex;align-items:center;gap:.42rem}.ndt-chevron{font-size:.72rem;margin-left:.12rem}.ndt-actions-btn{border:1px solid #d2dcfb;background:#f7f9ff;color:#33446e;border-radius:10px;width:34px;height:30px;padding:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center}.ndt-actions-btn:hover{border-color:var(--ndt-primary);color:var(--ndt-primary);background:#eef3ff}.ndt-dots{font-size:1rem;line-height:1}.ndt-action-fallback{font-size:.72rem;font-weight:700;line-height:1}.ndt-actions-btn.ndt-danger{color:#dc3545;border-color:#f1c2c7;background:#fff5f6}.ndt-actions-btn.ndt-danger:hover{color:#bb2d3b;border-color:#dc3545;background:#ffe6e9}.ndt-dropdown-menu{position:absolute;left:0;top:calc(100% + .35rem);list-style:none;margin:0;padding:.35rem 0;min-width:120px;border:1px solid #dbe4ff;border-radius:12px;background:#fff;box-shadow:0 12px 24px #2d489124;z-index:20}.ndt-dropdown-item{width:100%;border:0;background:#fff;color:#33446e;display:flex;align-items:center;gap:.45rem;text-align:left;padding:.42rem .72rem;font-size:.84rem;cursor:pointer}.ndt-dropdown-item i{font-size:.9rem;width:14px}.ndt-dropdown-item:hover{background:#f5f8ff;color:var(--ndt-primary)}.ndt-dropdown-item.ndt-danger{color:#dc3545}.ndt-dropdown-item.ndt-danger:hover{background:#fff1f3}.ndt-empty{text-align:center;color:var(--ndt-muted)}.ndt-footer{display:flex;align-items:center;justify-content:space-between;gap:.75rem;flex-wrap:wrap;color:#52628a;font-size:.88rem}.ndt-pagination{display:flex;list-style:none;margin:0;padding:0;align-items:center;gap:.35rem}.ndt-pagination li{display:inline-flex}.ndt-page-link{border:1px solid #d5def8;background:#fff;color:var(--ndt-primary);border-radius:8px;min-width:34px;height:30px;padding:0 .6rem;font-size:.82rem;display:inline-flex;align-items:center;justify-content:center}.ndt-page-link:hover{border-color:var(--ndt-primary);background:#4f46e512}.ndt-pagination li.active .ndt-page-link{background:var(--ndt-primary);border-color:var(--ndt-primary);color:#fff}.ndt-pagination li.disabled .ndt-page-link{opacity:.55;cursor:not-allowed}@media(max-width:900px){.ndt-toolbar,.ndt-footer{flex-direction:column;align-items:flex-start}.ndt-toolbar input{min-width:100%}}\n"] }]
|
|
779
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { config: [{
|
|
554
780
|
type: Input
|
|
555
781
|
}], columns: [{
|
|
556
782
|
type: Input
|
|
@@ -566,12 +792,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
566
792
|
type: Output
|
|
567
793
|
}], exportTriggered: [{
|
|
568
794
|
type: Output
|
|
569
|
-
}], onWindowResize: [{
|
|
570
|
-
type: HostListener,
|
|
571
|
-
args: ['window:resize']
|
|
572
|
-
}], onWindowScroll: [{
|
|
573
|
-
type: HostListener,
|
|
574
|
-
args: ['window:scroll']
|
|
575
795
|
}] } });
|
|
576
796
|
|
|
577
797
|
/*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-dynamic-datatable.mjs","sources":["../../../projects/dynamic-datatable/src/lib/dynamic-datatable.component.ts","../../../projects/dynamic-datatable/src/lib/dynamic-datatable.component.html","../../../projects/dynamic-datatable/src/public-api.ts","../../../projects/dynamic-datatable/src/ng-dynamic-datatable.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\r\nimport { Component, EventEmitter, HostListener, Input, OnChanges, Output, SimpleChanges } from '@angular/core';\r\nimport {\r\n DataTableAction,\r\n DataTableActionEvent,\r\n DataTableColumn,\r\n DataTableExportEvent,\r\n DynamicDataTableConfig\r\n} from './models';\r\nimport { InternalSortState } from './dynamic-datatable.types';\r\n\r\ntype RowData = Record<string, unknown>;\r\n\r\ninterface InternalRow<T extends RowData = RowData> {\r\n id: string;\r\n data: T;\r\n}\r\n\r\nconst DEFAULT_CONFIG: Required<Pick<DynamicDataTableConfig, 'title' | 'rowsPerPageOptions' | 'defaultRowsPerPage'>> & {\r\n features: Required<NonNullable<DynamicDataTableConfig['features']>>;\r\n exportOptions: Required<NonNullable<DynamicDataTableConfig['exportOptions']>>;\r\n} = {\r\n title: 'Dynamic DataTable',\r\n features: {\r\n export: true,\r\n sorting: true,\r\n searching: true,\r\n pagination: true,\r\n rowsPerPage: true,\r\n actions: true,\r\n checkboxSelection: true\r\n },\r\n rowsPerPageOptions: [5, 10, 25, 50],\r\n defaultRowsPerPage: 10,\r\n exportOptions: {\r\n fileName: 'datatable-export',\r\n formats: ['csv', 'excel']\r\n }\r\n};\r\n\r\n@Component({\r\n selector: 'lib-dynamic-datatable',\r\n standalone: true,\r\n imports: [CommonModule],\r\n templateUrl: './dynamic-datatable.component.html',\r\n styleUrl: './dynamic-datatable.component.scss'\r\n})\r\nexport class DynamicDatatableComponent implements OnChanges {\r\n @Input() config: DynamicDataTableConfig = {};\r\n @Input() columns: DataTableColumn<RowData>[] = [];\r\n @Input() data: RowData[] = [];\r\n\r\n @Output() readonly actionSelected = new EventEmitter<DataTableActionEvent<RowData>>();\r\n @Output() readonly selectionChange = new EventEmitter<RowData[]>();\r\n @Output() readonly sortChange = new EventEmitter<InternalSortState>();\r\n @Output() readonly pageChange = new EventEmitter<number>();\r\n @Output() readonly exportTriggered = new EventEmitter<DataTableExportEvent<RowData>>();\r\n\r\n mergedConfig: DynamicDataTableConfig<RowData> = {\r\n title: DEFAULT_CONFIG.title,\r\n features: { ...DEFAULT_CONFIG.features },\r\n rowsPerPageOptions: [...DEFAULT_CONFIG.rowsPerPageOptions],\r\n defaultRowsPerPage: DEFAULT_CONFIG.defaultRowsPerPage,\r\n exportOptions: { ...DEFAULT_CONFIG.exportOptions },\r\n columns: [],\r\n actions: []\r\n };\r\n\r\n mergedColumns: DataTableColumn<RowData>[] = [];\r\n\r\n private allRows: InternalRow<RowData>[] = [];\r\n filteredRows: InternalRow<RowData>[] = [];\r\n pagedRows: InternalRow<RowData>[] = [];\r\n\r\n searchTerm = '';\r\n currentPage = 1;\r\n rowsPerPage = DEFAULT_CONFIG.defaultRowsPerPage;\r\n totalPages = 1;\r\n sortState: InternalSortState = { key: null, direction: 'asc' };\r\n selectedRows = new Set<string>();\r\n openActionMenuRowId: string | null = null;\r\n private openActionAnchorEl: HTMLElement | null = null;\r\n actionMenuStyle: Record<string, string> = {};\r\n isExportMenuOpen = false;\r\n\r\n ngOnChanges(_changes: SimpleChanges): void {\r\n this.refresh();\r\n }\r\n\r\n refresh(): void {\r\n this.applyConfig();\r\n this.normalizeRows();\r\n this.applyFiltersSortAndPagination();\r\n }\r\n\r\n updateData(newData: RowData[]): void {\r\n this.data = Array.isArray(newData) ? [...newData] : [];\r\n this.refresh();\r\n }\r\n\r\n updateConfig(newConfig: DynamicDataTableConfig<RowData>): void {\r\n this.config = { ...this.config, ...newConfig };\r\n this.refresh();\r\n }\r\n\r\n getSelectedRows(): RowData[] {\r\n return this.allRows.filter((row) => this.selectedRows.has(row.id)).map((row) => row.data);\r\n }\r\n\r\n clearSelection(): void {\r\n this.selectedRows.clear();\r\n this.selectionChange.emit([]);\r\n }\r\n\r\n isFeatureOn(feature: keyof NonNullable<DynamicDataTableConfig['features']>): boolean {\r\n return Boolean(this.mergedConfig.features?.[feature]);\r\n }\r\n\r\n isExportFormatEnabled(format: 'csv' | 'excel'): boolean {\r\n const formats = this.mergedConfig.exportOptions?.formats ?? [];\r\n return formats.includes(format);\r\n }\r\n\r\n onSearchInput(event: Event): void {\r\n const input = event.target as HTMLInputElement;\r\n this.searchTerm = (input.value || '').trim().toLowerCase();\r\n this.closeActionMenu();\r\n this.currentPage = 1;\r\n this.applyFiltersSortAndPagination();\r\n }\r\n\r\n onRowsPerPageChange(event: Event): void {\r\n const select = event.target as HTMLSelectElement;\r\n const value = Number(select.value);\r\n this.rowsPerPage = Number.isFinite(value) && value > 0 ? value : this.getInitialRowsPerPage();\r\n this.closeActionMenu();\r\n this.currentPage = 1;\r\n this.applyFiltersSortAndPagination();\r\n }\r\n\r\n toggleSort(column: DataTableColumn<RowData>): void {\r\n if (!this.isFeatureOn('sorting') || !column.sortable) {\r\n return;\r\n }\r\n\r\n const key = String(column.key);\r\n if (this.sortState.key === key) {\r\n this.sortState.direction = this.sortState.direction === 'asc' ? 'desc' : 'asc';\r\n } else {\r\n this.sortState = { key, direction: 'asc' };\r\n }\r\n\r\n this.closeActionMenu();\r\n this.currentPage = 1;\r\n this.sortChange.emit({ ...this.sortState });\r\n this.applyFiltersSortAndPagination();\r\n }\r\n\r\n getSortIconClass(columnKey: string): string {\r\n if (this.sortState.key !== columnKey) {\r\n return 'bi bi-arrow-down-up';\r\n }\r\n\r\n return this.sortState.direction === 'asc' ? 'bi bi-sort-down' : 'bi bi-sort-up';\r\n }\r\n\r\n isSortColumn(columnKey: string): boolean {\r\n return this.sortState.key === columnKey;\r\n }\r\n\r\n goToPage(page: number): void {\r\n if (!this.isFeatureOn('pagination')) {\r\n return;\r\n }\r\n\r\n const bounded = Math.min(Math.max(page, 1), this.totalPages);\r\n if (bounded === this.currentPage) {\r\n return;\r\n }\r\n\r\n this.closeActionMenu();\r\n this.currentPage = bounded;\r\n this.pageChange.emit(this.currentPage);\r\n this.updatePagedRowsOnly();\r\n }\r\n\r\n getPaginationPages(): number[] {\r\n return Array.from({ length: this.totalPages }, (_, idx) => idx + 1);\r\n }\r\n\r\n isRowSelected(rowId: string): boolean {\r\n return this.selectedRows.has(rowId);\r\n }\r\n\r\n toggleRowSelection(row: InternalRow<RowData>, event: Event): void {\r\n const input = event.target as HTMLInputElement;\r\n if (input.checked) {\r\n this.selectedRows.add(row.id);\r\n } else {\r\n this.selectedRows.delete(row.id);\r\n }\r\n\r\n this.emitSelection();\r\n }\r\n\r\n toggleSelectAllCurrentPage(event: Event): void {\r\n const input = event.target as HTMLInputElement;\r\n this.pagedRows.forEach((row) => {\r\n if (input.checked) {\r\n this.selectedRows.add(row.id);\r\n } else {\r\n this.selectedRows.delete(row.id);\r\n }\r\n });\r\n\r\n this.emitSelection();\r\n }\r\n\r\n isCurrentPageFullySelected(): boolean {\r\n if (!this.pagedRows.length) {\r\n return false;\r\n }\r\n\r\n return this.pagedRows.every((row) => this.selectedRows.has(row.id));\r\n }\r\n\r\n toggleActionMenu(rowId: string, event: Event): void {\r\n event.stopPropagation();\r\n const currentTarget = event.currentTarget as HTMLElement | null;\r\n const target = event.target as HTMLElement | null;\r\n const anchor = currentTarget ?? target?.closest('.ndt-actions-btn') ?? null;\r\n if (!anchor) {\r\n return;\r\n }\r\n\r\n if (this.openActionMenuRowId === rowId) {\r\n this.closeActionMenu();\r\n return;\r\n }\r\n\r\n this.openActionMenuRowId = rowId;\r\n this.openActionAnchorEl = anchor;\r\n this.updateActionMenuPosition();\r\n\r\n // Recalculate once the menu is rendered so dimensions are accurate.\r\n setTimeout(() => this.updateActionMenuPosition(), 0);\r\n }\r\n\r\n closeActionMenu(): void {\r\n this.openActionMenuRowId = null;\r\n this.openActionAnchorEl = null;\r\n this.actionMenuStyle = {};\r\n }\r\n\r\n toggleExportMenu(event: Event): void {\r\n event.stopPropagation();\r\n this.isExportMenuOpen = !this.isExportMenuOpen;\r\n }\r\n\r\n isActionMenuOpen(rowId: string): boolean {\r\n return this.openActionMenuRowId === rowId;\r\n }\r\n\r\n onActionItemClick(actionIndex: number, row: InternalRow<RowData>, event: Event): void {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n if (!Number.isInteger(actionIndex) || actionIndex < 0) {\r\n return;\r\n }\r\n\r\n const action = this.mergedConfig.actions?.[actionIndex];\r\n if (!action) {\r\n return;\r\n }\r\n\r\n const rowIndex = this.filteredRows.findIndex((item) => item.id === row.id);\r\n this.actionSelected.emit({ action, row: row.data, rowIndex });\r\n this.closeActionMenu();\r\n }\r\n\r\n exportCSV(): void {\r\n this.isExportMenuOpen = false;\r\n const rows = this.getRowsForExport();\r\n this.exportTriggered.emit({ format: 'csv', rows });\r\n\r\n const headers = this.mergedColumns.map((column) => this.escapeCsv(column.label));\r\n const lines = rows.map((row) => {\r\n return this.mergedColumns\r\n .map((column) => this.escapeCsv(this.getCellTextValue(row, column)))\r\n .join(',');\r\n });\r\n\r\n const csv = [headers.join(','), ...lines].join('\\n');\r\n this.downloadFile(csv, `${this.getExportFileName()}.csv`, 'text/csv;charset=utf-8;');\r\n }\r\n\r\n exportExcel(): void {\r\n this.isExportMenuOpen = false;\r\n const rows = this.getRowsForExport();\r\n this.exportTriggered.emit({ format: 'excel', rows });\r\n\r\n const headerCells = this.mergedColumns.map((column) => `<th>${this.escapeHtml(column.label)}</th>`).join('');\r\n const bodyRows = rows\r\n .map((row) => {\r\n const cells = this.mergedColumns\r\n .map((column) => `<td>${this.escapeHtml(this.getCellTextValue(row, column))}</td>`)\r\n .join('');\r\n return `<tr>${cells}</tr>`;\r\n })\r\n .join('');\r\n\r\n const html = `<html><head><meta charset=\"UTF-8\"></head><body><table border=\"1\"><thead><tr>${headerCells}</tr></thead><tbody>${bodyRows}</tbody></table></body></html>`;\r\n this.downloadFile(html, `${this.getExportFileName()}.xls`, 'application/vnd.ms-excel;charset=utf-8;');\r\n }\r\n\r\n getRenderedCell(row: RowData, column: DataTableColumn<RowData>): string {\r\n if (typeof column.render === 'function') {\r\n return column.render(row);\r\n }\r\n\r\n const key = String(column.key);\r\n const value = row[key];\r\n return this.escapeHtml(value == null ? '' : String(value));\r\n }\r\n\r\n toColumnWidth(width: string | number | undefined): string {\r\n if (typeof width === 'number') {\r\n return `${width}px`;\r\n }\r\n\r\n if (typeof width === 'string' && width.trim()) {\r\n return width.trim();\r\n }\r\n\r\n return 'auto';\r\n }\r\n\r\n getColumnCount(): number {\r\n let count = this.mergedColumns.length;\r\n if (this.isFeatureOn('checkboxSelection')) {\r\n count += 1;\r\n }\r\n if (this.isFeatureOn('actions')) {\r\n count += 1;\r\n }\r\n return count;\r\n }\r\n\r\n getStartEntry(): number {\r\n if (!this.filteredRows.length) {\r\n return 0;\r\n }\r\n\r\n if (!this.isFeatureOn('pagination')) {\r\n return 1;\r\n }\r\n\r\n return (this.currentPage - 1) * this.rowsPerPage + 1;\r\n }\r\n\r\n getEndEntry(): number {\r\n if (!this.filteredRows.length) {\r\n return 0;\r\n }\r\n\r\n if (!this.isFeatureOn('pagination')) {\r\n return this.filteredRows.length;\r\n }\r\n\r\n return Math.min(this.currentPage * this.rowsPerPage, this.filteredRows.length);\r\n }\r\n\r\n private applyConfig(): void {\r\n const features = {\r\n ...DEFAULT_CONFIG.features,\r\n ...(this.config.features ?? {})\r\n };\r\n\r\n const exportOptions = {\r\n ...DEFAULT_CONFIG.exportOptions,\r\n ...(this.config.exportOptions ?? {})\r\n };\r\n\r\n const rowsPerPageOptions = (this.config.rowsPerPageOptions ?? DEFAULT_CONFIG.rowsPerPageOptions).filter(\r\n (item) => Number.isFinite(item) && item > 0\r\n );\r\n\r\n this.mergedConfig = {\r\n title: this.config.title ?? DEFAULT_CONFIG.title,\r\n features,\r\n rowsPerPageOptions: rowsPerPageOptions.length ? rowsPerPageOptions : [...DEFAULT_CONFIG.rowsPerPageOptions],\r\n defaultRowsPerPage: this.config.defaultRowsPerPage ?? DEFAULT_CONFIG.defaultRowsPerPage,\r\n exportOptions,\r\n actions: [...(this.config.actions ?? [])],\r\n columns: []\r\n };\r\n\r\n this.mergedColumns = [...(this.columns.length ? this.columns : (this.config.columns ?? []))];\r\n this.rowsPerPage = this.getInitialRowsPerPage();\r\n }\r\n\r\n private normalizeRows(): void {\r\n this.allRows = (Array.isArray(this.data) ? this.data : []).map((row, index) => {\r\n const rowId = row['id'];\r\n const id = rowId == null ? `row-${index + 1}` : String(rowId);\r\n return { id, data: row };\r\n });\r\n\r\n const validIds = new Set(this.allRows.map((row) => row.id));\r\n for (const selectedId of Array.from(this.selectedRows)) {\r\n if (!validIds.has(selectedId)) {\r\n this.selectedRows.delete(selectedId);\r\n }\r\n }\r\n }\r\n\r\n private applyFiltersSortAndPagination(): void {\r\n if (!this.isFeatureOn('searching') || !this.searchTerm) {\r\n this.filteredRows = [...this.allRows];\r\n } else {\r\n this.filteredRows = this.allRows.filter((row) => {\r\n const searchSpace = this.mergedColumns\r\n .map((column) => this.getCellTextValue(row.data, column).toLowerCase())\r\n .join(' ');\r\n return searchSpace.includes(this.searchTerm);\r\n });\r\n }\r\n\r\n if (this.isFeatureOn('sorting') && this.sortState.key) {\r\n const column = this.mergedColumns.find((item) => String(item.key) === this.sortState.key);\r\n if (column?.sortable) {\r\n this.filteredRows.sort((a, b) => {\r\n const aVal = this.getCellTextValue(a.data, column);\r\n const bVal = this.getCellTextValue(b.data, column);\r\n const compare = this.compareValues(aVal, bVal);\r\n return this.sortState.direction === 'asc' ? compare : -compare;\r\n });\r\n }\r\n }\r\n\r\n this.totalPages = this.isFeatureOn('pagination')\r\n ? Math.max(1, Math.ceil(this.filteredRows.length / this.rowsPerPage))\r\n : 1;\r\n\r\n if (this.currentPage > this.totalPages) {\r\n this.currentPage = this.totalPages;\r\n }\r\n\r\n this.updatePagedRowsOnly();\r\n this.emitSelection();\r\n }\r\n\r\n private updatePagedRowsOnly(): void {\r\n if (!this.isFeatureOn('pagination')) {\r\n this.pagedRows = [...this.filteredRows];\r\n this.validateOpenActionMenuRow();\r\n return;\r\n }\r\n\r\n const start = (this.currentPage - 1) * this.rowsPerPage;\r\n this.pagedRows = this.filteredRows.slice(start, start + this.rowsPerPage);\r\n this.validateOpenActionMenuRow();\r\n }\r\n\r\n @HostListener('window:resize')\r\n onWindowResize(): void {\r\n this.updateActionMenuPosition();\r\n }\r\n\r\n @HostListener('window:scroll')\r\n onWindowScroll(): void {\r\n this.updateActionMenuPosition();\r\n }\r\n\r\n private validateOpenActionMenuRow(): void {\r\n if (!this.openActionMenuRowId) {\r\n return;\r\n }\r\n\r\n const existsOnPage = this.pagedRows.some((row) => row.id === this.openActionMenuRowId);\r\n if (!existsOnPage) {\r\n this.closeActionMenu();\r\n }\r\n }\r\n\r\n private updateActionMenuPosition(): void {\r\n if (!this.openActionMenuRowId || !this.openActionAnchorEl || typeof document === 'undefined') {\r\n return;\r\n }\r\n\r\n const menus = Array.from(document.querySelectorAll('.ndt-action-menu')) as HTMLElement[];\r\n const menu = menus.find((item) => item.getAttribute('data-row-id') === this.openActionMenuRowId) ?? null;\r\n\r\n const rect = this.openActionAnchorEl.getBoundingClientRect();\r\n const viewportWidth = window.innerWidth;\r\n const viewportHeight = window.innerHeight;\r\n const menuWidth = menu?.offsetWidth ?? 160;\r\n const menuHeight = menu?.offsetHeight ?? this.getEstimatedActionMenuHeight();\r\n const offset = 6;\r\n const edgePadding = 8;\r\n\r\n const spaceBelow = viewportHeight - rect.bottom - edgePadding;\r\n const spaceAbove = rect.top - edgePadding;\r\n const spaceRight = viewportWidth - rect.left - edgePadding;\r\n const spaceLeft = rect.right - edgePadding;\r\n\r\n let top: number;\r\n if (spaceBelow >= menuHeight) {\r\n top = rect.bottom + offset;\r\n } else if (spaceAbove >= menuHeight) {\r\n top = rect.top - menuHeight - offset;\r\n } else if (spaceBelow >= spaceAbove) {\r\n top = viewportHeight - menuHeight - edgePadding;\r\n } else {\r\n top = edgePadding;\r\n }\r\n\r\n let left: number;\r\n if (spaceRight >= menuWidth) {\r\n left = rect.left;\r\n } else if (spaceLeft >= menuWidth) {\r\n left = rect.right - menuWidth;\r\n } else {\r\n left = Math.max(edgePadding, Math.min(rect.left, viewportWidth - menuWidth - edgePadding));\r\n }\r\n\r\n const maxHeight = Math.max(140, viewportHeight - edgePadding * 2);\r\n this.actionMenuStyle = {\r\n position: 'fixed',\r\n top: `${Math.round(top)}px`,\r\n left: `${Math.round(left)}px`,\r\n zIndex: '1080',\r\n maxHeight: `${Math.round(maxHeight)}px`,\r\n overflowY: 'auto'\r\n };\r\n }\r\n\r\n private getEstimatedActionMenuHeight(): number {\r\n const count = this.mergedConfig.actions?.length ?? 0;\r\n const itemHeight = 34;\r\n const verticalPadding = 12;\r\n return Math.max(48, count * itemHeight + verticalPadding);\r\n }\r\n\r\n private getCellTextValue(row: RowData, column: DataTableColumn<RowData>): string {\r\n const key = String(column.key);\r\n if (row[key] != null) {\r\n return String(row[key]);\r\n }\r\n\r\n const rendered = this.getRenderedCell(row, column);\r\n return this.stripHtml(rendered);\r\n }\r\n\r\n private compareValues(a: string, b: string): number {\r\n const aText = a.trim();\r\n const bText = b.trim();\r\n\r\n const aNum = this.parseStrictNumber(aText);\r\n const bNum = this.parseStrictNumber(bText);\r\n if (aNum !== null && bNum !== null) {\r\n return aNum - bNum;\r\n }\r\n\r\n const aDate = this.parseDateValue(aText);\r\n const bDate = this.parseDateValue(bText);\r\n if (aDate !== null && bDate !== null) {\r\n return aDate - bDate;\r\n }\r\n\r\n return aText.localeCompare(bText, undefined, { numeric: true, sensitivity: 'base' });\r\n }\r\n\r\n private parseStrictNumber(value: string): number | null {\r\n const normalized = value.replace(/[$,\\s]/g, '');\r\n if (!/^[-+]?\\d*\\.?\\d+$/.test(normalized)) {\r\n return null;\r\n }\r\n\r\n const numberValue = Number(normalized);\r\n return Number.isNaN(numberValue) ? null : numberValue;\r\n }\r\n\r\n private parseDateValue(value: string): number | null {\r\n const usDate = value.match(/^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})$/);\r\n if (usDate) {\r\n const month = Number(usDate[1]);\r\n const day = Number(usDate[2]);\r\n const year = Number(usDate[3]);\r\n const utc = Date.UTC(year, month - 1, day);\r\n return Number.isNaN(utc) ? null : utc;\r\n }\r\n\r\n const isoDate = value.match(/^(\\d{4})-(\\d{1,2})-(\\d{1,2})$/);\r\n if (isoDate) {\r\n const year = Number(isoDate[1]);\r\n const month = Number(isoDate[2]);\r\n const day = Number(isoDate[3]);\r\n const utc = Date.UTC(year, month - 1, day);\r\n return Number.isNaN(utc) ? null : utc;\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private getRowsForExport(): RowData[] {\r\n const selected = this.getSelectedRows();\r\n if (selected.length) {\r\n return selected;\r\n }\r\n\r\n return this.filteredRows.map((item) => item.data);\r\n }\r\n\r\n private getExportFileName(): string {\r\n return this.mergedConfig.exportOptions?.fileName || 'datatable-export';\r\n }\r\n\r\n private downloadFile(content: string, fileName: string, mimeType: string): void {\r\n if (typeof document === 'undefined') {\r\n return;\r\n }\r\n\r\n const blob = new Blob([content], { type: mimeType });\r\n const url = URL.createObjectURL(blob);\r\n const anchor = document.createElement('a');\r\n anchor.href = url;\r\n anchor.download = fileName;\r\n document.body.appendChild(anchor);\r\n anchor.click();\r\n document.body.removeChild(anchor);\r\n URL.revokeObjectURL(url);\r\n }\r\n\r\n private escapeCsv(value: string): string {\r\n if (/[\",\\n]/.test(value)) {\r\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\r\n }\r\n\r\n return value;\r\n }\r\n\r\n private stripHtml(input: string): string {\r\n if (typeof document === 'undefined') {\r\n return input;\r\n }\r\n\r\n const temp = document.createElement('div');\r\n temp.innerHTML = input;\r\n return temp.textContent || temp.innerText || '';\r\n }\r\n\r\n private escapeHtml(value: string): string {\r\n return String(value)\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\r\n }\r\n\r\n private getInitialRowsPerPage(): number {\r\n const options = this.mergedConfig.rowsPerPageOptions ?? DEFAULT_CONFIG.rowsPerPageOptions;\r\n const preferred = Number(this.mergedConfig.defaultRowsPerPage ?? DEFAULT_CONFIG.defaultRowsPerPage);\r\n return options.includes(preferred) ? preferred : options[0] ?? DEFAULT_CONFIG.defaultRowsPerPage;\r\n }\r\n\r\n private emitSelection(): void {\r\n this.selectionChange.emit(this.getSelectedRows());\r\n }\r\n\r\n closeMenus(): void {\r\n this.closeActionMenu();\r\n this.isExportMenuOpen = false;\r\n }\r\n\r\n}\r\n","<div class=\"ndt-card\" (click)=\"closeMenus()\">\r\n <div class=\"ndt-header\">\r\n <h3 class=\"ndt-title\">{{ mergedConfig.title }}</h3>\r\n </div>\r\n\r\n <div class=\"ndt-toolbar\">\r\n <div class=\"ndt-left-tools\">\r\n <ng-container *ngIf=\"isFeatureOn('export')\">\r\n <div class=\"ndt-dropdown\" (click)=\"$event.stopPropagation()\">\r\n <button class=\"ndt-btn ndt-export-btn\" type=\"button\" (click)=\"toggleExportMenu($event)\">\r\n <i class=\"bi bi-download\"></i>\r\n <span>Export</span>\r\n <i class=\"bi bi-chevron-down ndt-chevron\"></i>\r\n </button>\r\n\r\n <ul class=\"ndt-dropdown-menu\" *ngIf=\"isExportMenuOpen\">\r\n <li *ngIf=\"isExportFormatEnabled('csv')\">\r\n <button type=\"button\" class=\"ndt-dropdown-item\" (click)=\"exportCSV()\">\r\n <i class=\"bi bi-filetype-csv\"></i>\r\n <span>CSV</span>\r\n </button>\r\n </li>\r\n <li *ngIf=\"isExportFormatEnabled('excel')\">\r\n <button type=\"button\" class=\"ndt-dropdown-item\" (click)=\"exportExcel()\">\r\n <i class=\"bi bi-file-earmark-spreadsheet\"></i>\r\n <span>Excel (.xls)</span>\r\n </button>\r\n </li>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n\r\n <label class=\"ndt-inline-label\" *ngIf=\"isFeatureOn('rowsPerPage') && isFeatureOn('pagination')\">\r\n Rows per page:\r\n <select [value]=\"rowsPerPage\" (change)=\"onRowsPerPageChange($event)\">\r\n <option *ngFor=\"let option of mergedConfig.rowsPerPageOptions || []\" [value]=\"option\">{{ option }}</option>\r\n </select>\r\n </label>\r\n </div>\r\n\r\n <div class=\"ndt-right-tools\" *ngIf=\"isFeatureOn('searching')\">\r\n <input\r\n type=\"search\"\r\n placeholder=\"Search records\"\r\n [value]=\"searchTerm\"\r\n (input)=\"onSearchInput($event)\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"ndt-table-wrap\">\r\n <table class=\"ndt-table\">\r\n <colgroup>\r\n <col *ngIf=\"isFeatureOn('checkboxSelection')\" style=\"width: 44px\" />\r\n <col *ngFor=\"let column of mergedColumns\" [style.width]=\"toColumnWidth(column.width)\" />\r\n <col *ngIf=\"isFeatureOn('actions')\" style=\"width: 78px\" />\r\n </colgroup>\r\n\r\n <thead>\r\n <tr>\r\n <th *ngIf=\"isFeatureOn('checkboxSelection')\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"isCurrentPageFullySelected()\"\r\n (change)=\"toggleSelectAllCurrentPage($event)\"\r\n />\r\n </th>\r\n <th\r\n *ngFor=\"let column of mergedColumns\"\r\n [class.ndt-sortable]=\"isFeatureOn('sorting') && !!column.sortable\"\r\n (click)=\"toggleSort(column)\"\r\n >\r\n <span class=\"ndt-th-content\">\r\n <span class=\"ndt-th-label\">{{ column.label }}</span>\r\n <i\r\n *ngIf=\"isFeatureOn('sorting') && column.sortable\"\r\n [ngClass]=\"[\r\n 'ndt-sort-indicator',\r\n getSortIconClass(column.key.toString()),\r\n isSortColumn(column.key.toString()) ? 'active' : ''\r\n ]\"\r\n ></i>\r\n </span>\r\n </th>\r\n <th *ngIf=\"isFeatureOn('actions')\">Actions</th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n <tr *ngIf=\"!pagedRows.length\">\r\n <td [attr.colspan]=\"getColumnCount()\" class=\"ndt-empty\">No records found.</td>\r\n </tr>\r\n\r\n <tr *ngFor=\"let row of pagedRows\" [class.ndt-selected]=\"isRowSelected(row.id)\">\r\n <td *ngIf=\"isFeatureOn('checkboxSelection')\">\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"isRowSelected(row.id)\"\r\n (change)=\"toggleRowSelection(row, $event)\"\r\n />\r\n </td>\r\n\r\n <td *ngFor=\"let column of mergedColumns\" [innerHTML]=\"getRenderedCell(row.data, column)\"></td>\r\n\r\n <td *ngIf=\"isFeatureOn('actions')\" class=\"ndt-actions-cell\">\r\n <div class=\"ndt-dropdown\" (click)=\"$event.stopPropagation()\">\r\n <button\r\n type=\"button\"\r\n class=\"ndt-actions-btn\"\r\n (click)=\"toggleActionMenu(row.id, $event)\"\r\n [attr.aria-expanded]=\"isActionMenuOpen(row.id)\"\r\n >\r\n <span class=\"ndt-dots\">...</span>\r\n </button>\r\n\r\n <ul\r\n class=\"ndt-dropdown-menu ndt-action-menu\"\r\n *ngIf=\"isActionMenuOpen(row.id)\"\r\n [ngStyle]=\"actionMenuStyle\"\r\n [attr.data-row-id]=\"row.id\"\r\n >\r\n <li *ngFor=\"let action of mergedConfig.actions || []; let i = index\">\r\n <button\r\n type=\"button\"\r\n class=\"ndt-dropdown-item\"\r\n [class.ndt-danger]=\"!!action.danger\"\r\n (click)=\"onActionItemClick(i, row, $event)\"\r\n >\r\n <i *ngIf=\"action.icon\" [class]=\"action.icon\"></i>\r\n <span>{{ action.label }}</span>\r\n </button>\r\n </li>\r\n </ul>\r\n </div>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div class=\"ndt-footer\">\r\n <div>\r\n {{ selectedRows.size }} selected\r\n </div>\r\n\r\n <div>\r\n Showing {{ getStartEntry() }} to {{ getEndEntry() }} of {{ filteredRows.length }} entries\r\n </div>\r\n\r\n <ul class=\"ndt-pagination\" *ngIf=\"isFeatureOn('pagination') && totalPages > 1\">\r\n <li [class.disabled]=\"currentPage <= 1\">\r\n <button type=\"button\" class=\"ndt-page-link\" (click)=\"goToPage(currentPage - 1)\" [disabled]=\"currentPage <= 1\">Prev</button>\r\n </li>\r\n <li *ngFor=\"let page of getPaginationPages()\" [class.active]=\"page === currentPage\">\r\n <button type=\"button\" class=\"ndt-page-link\" (click)=\"goToPage(page)\">{{ page }}</button>\r\n </li>\r\n <li [class.disabled]=\"currentPage >= totalPages\">\r\n <button type=\"button\" class=\"ndt-page-link\" (click)=\"goToPage(currentPage + 1)\" [disabled]=\"currentPage >= totalPages\">Next</button>\r\n </li>\r\n </ul>\r\n </div>\r\n</div>\r\n","/*\r\n * Public API Surface of dynamic-datatable\r\n */\r\n\r\nexport * from './lib/dynamic-datatable.component';\r\nexport * from './lib/models';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ng-dynamic-datatable.mjs","sources":["../../../projects/dynamic-datatable/src/lib/tooltip-manager.ts","../../../projects/dynamic-datatable/src/lib/dynamic-datatable.component.ts","../../../projects/dynamic-datatable/src/lib/dynamic-datatable.component.html","../../../projects/dynamic-datatable/src/public-api.ts","../../../projects/dynamic-datatable/src/ng-dynamic-datatable.ts"],"sourcesContent":["type TooltipTrigger = 'hover' | 'click';\r\ntype TooltipPosition = 'top' | 'bottom' | 'left' | 'right';\r\n\r\ninterface TooltipConfig {\r\n content?: string;\r\n html?: string;\r\n icon?: string;\r\n trigger?: TooltipTrigger;\r\n position?: TooltipPosition;\r\n noArrow?: boolean;\r\n allowHtml?: boolean;\r\n offset?: number;\r\n}\r\n\r\ninterface TooltipEntry {\r\n config: TooltipConfig;\r\n}\r\n\r\nconst VALID_TRIGGERS: Record<string, TooltipTrigger> = {\r\n hover: 'hover',\r\n click: 'click'\r\n};\r\n\r\nconst VALID_POSITIONS: Record<string, TooltipPosition> = {\r\n top: 'top',\r\n bottom: 'bottom',\r\n left: 'left',\r\n right: 'right'\r\n};\r\n\r\nexport class TooltipManager {\r\n private readonly registry = new WeakMap<HTMLElement, TooltipEntry>();\r\n private readonly root: HTMLElement;\r\n private readonly documentRef: Document;\r\n\r\n private activeTarget: HTMLElement | null = null;\r\n private activeTooltipEl: HTMLElement | null = null;\r\n\r\n private readonly offset = 10;\r\n private readonly viewportPadding = 8;\r\n\r\n private readonly onMouseOverBound = (event: Event) => this.onMouseOver(event);\r\n private readonly onMouseOutBound = (event: Event) => this.onMouseOut(event);\r\n private readonly onFocusInBound = (event: Event) => this.onFocusIn(event);\r\n private readonly onFocusOutBound = (event: Event) => this.onFocusOut(event);\r\n private readonly onClickBound = (event: Event) => this.onClick(event);\r\n private readonly onDocumentClickBound = (event: Event) => this.onDocumentClick(event);\r\n private readonly onDocumentKeydownBound = (event: KeyboardEvent) => this.onDocumentKeydown(event);\r\n private readonly onWindowResizeBound = () => this.reposition();\r\n private readonly onWindowScrollBound = () => this.reposition();\r\n\r\n constructor(root: HTMLElement, documentRef: Document = document) {\r\n this.root = root;\r\n this.documentRef = documentRef;\r\n }\r\n\r\n init(): void {\r\n this.root.addEventListener('mouseover', this.onMouseOverBound);\r\n this.root.addEventListener('mouseout', this.onMouseOutBound);\r\n this.root.addEventListener('focusin', this.onFocusInBound);\r\n this.root.addEventListener('focusout', this.onFocusOutBound);\r\n this.root.addEventListener('click', this.onClickBound);\r\n\r\n this.documentRef.addEventListener('click', this.onDocumentClickBound, true);\r\n this.documentRef.addEventListener('keydown', this.onDocumentKeydownBound);\r\n\r\n window.addEventListener('resize', this.onWindowResizeBound);\r\n window.addEventListener('scroll', this.onWindowScrollBound, true);\r\n }\r\n\r\n destroy(): void {\r\n this.hide(true);\r\n\r\n this.root.removeEventListener('mouseover', this.onMouseOverBound);\r\n this.root.removeEventListener('mouseout', this.onMouseOutBound);\r\n this.root.removeEventListener('focusin', this.onFocusInBound);\r\n this.root.removeEventListener('focusout', this.onFocusOutBound);\r\n this.root.removeEventListener('click', this.onClickBound);\r\n\r\n this.documentRef.removeEventListener('click', this.onDocumentClickBound, true);\r\n this.documentRef.removeEventListener('keydown', this.onDocumentKeydownBound);\r\n\r\n window.removeEventListener('resize', this.onWindowResizeBound);\r\n window.removeEventListener('scroll', this.onWindowScrollBound, true);\r\n }\r\n\r\n register(element: HTMLElement, config: TooltipConfig): void {\r\n this.registry.set(element, { config });\r\n }\r\n\r\n private onMouseOver(event: Event): void {\r\n const target = this.getTooltipTarget(event.target);\r\n if (!target) {\r\n return;\r\n }\r\n\r\n if (this.getTrigger(target) !== 'hover') {\r\n return;\r\n }\r\n\r\n this.show(target);\r\n }\r\n\r\n private onMouseOut(event: Event): void {\r\n const target = this.getTooltipTarget(event.target);\r\n if (!target || this.getTrigger(target) !== 'hover') {\r\n return;\r\n }\r\n\r\n const next = (event as MouseEvent).relatedTarget as Node | null;\r\n if (next && (target.contains(next) || (this.activeTooltipEl?.contains(next) ?? false))) {\r\n return;\r\n }\r\n\r\n this.hide();\r\n }\r\n\r\n private onFocusIn(event: Event): void {\r\n const target = this.getTooltipTarget(event.target);\r\n if (!target) {\r\n return;\r\n }\r\n\r\n this.show(target);\r\n }\r\n\r\n private onFocusOut(event: Event): void {\r\n const target = this.getTooltipTarget(event.target);\r\n if (!target) {\r\n return;\r\n }\r\n\r\n const next = (event as FocusEvent).relatedTarget as Node | null;\r\n if (next && (target.contains(next) || (this.activeTooltipEl?.contains(next) ?? false))) {\r\n return;\r\n }\r\n\r\n this.hide();\r\n }\r\n\r\n private onClick(event: Event): void {\r\n const target = this.getTooltipTarget(event.target);\r\n if (!target) {\r\n return;\r\n }\r\n\r\n if (this.getTrigger(target) !== 'click') {\r\n return;\r\n }\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n if (this.activeTarget === target && this.activeTooltipEl) {\r\n this.hide();\r\n return;\r\n }\r\n\r\n this.show(target);\r\n }\r\n\r\n private onDocumentClick(event: Event): void {\r\n if (!this.activeTarget || !this.activeTooltipEl) {\r\n return;\r\n }\r\n\r\n if (this.getTrigger(this.activeTarget) !== 'click') {\r\n return;\r\n }\r\n\r\n const node = event.target as Node | null;\r\n const insideTarget = !!(node && this.activeTarget.contains(node));\r\n const insideTooltip = !!(node && this.activeTooltipEl.contains(node));\r\n\r\n if (!insideTarget && !insideTooltip) {\r\n this.hide();\r\n }\r\n }\r\n\r\n private onDocumentKeydown(event: KeyboardEvent): void {\r\n if (event.key === 'Escape') {\r\n this.hide();\r\n }\r\n }\r\n\r\n private getTooltipTarget(input: EventTarget | null): HTMLElement | null {\r\n if (!(input instanceof Element)) {\r\n return null;\r\n }\r\n\r\n const target = input.closest('[data-tooltip]') as HTMLElement | null;\r\n if (!target) {\r\n return null;\r\n }\r\n\r\n if (!this.root.contains(target)) {\r\n return null;\r\n }\r\n\r\n return target;\r\n }\r\n\r\n private getEntry(target: HTMLElement): TooltipEntry | undefined {\r\n return this.registry.get(target);\r\n }\r\n\r\n private getTrigger(target: HTMLElement): TooltipTrigger {\r\n const value = this.getEntry(target)?.config.trigger ?? target.dataset['tooltipTrigger'] ?? 'hover';\r\n const normalized = String(value).toLowerCase();\r\n return VALID_TRIGGERS[normalized] ?? 'hover';\r\n }\r\n\r\n private getPosition(target: HTMLElement): TooltipPosition {\r\n const value = this.getEntry(target)?.config.position ?? target.dataset['tooltipPosition'] ?? 'bottom';\r\n const normalized = String(value).toLowerCase();\r\n return VALID_POSITIONS[normalized] ?? 'bottom';\r\n }\r\n\r\n private getContent(target: HTMLElement): { icon: string; text: string; html: string; allowHtml: boolean; noArrow: boolean; offset: number } {\r\n const entry = this.getEntry(target);\r\n\r\n const html = entry?.config.html ?? target.dataset['tooltipHtml'] ?? '';\r\n const text = entry?.config.content ?? target.dataset['tooltip'] ?? '';\r\n const icon = entry?.config.icon ?? target.dataset['tooltipIcon'] ?? '';\r\n\r\n const allowHtmlAttr = target.dataset['tooltipAllowHtml'];\r\n const allowHtml = entry?.config.allowHtml ?? (allowHtmlAttr === 'true');\r\n\r\n const noArrowAttr = target.dataset['tooltipNoArrow'];\r\n const noArrow = entry?.config.noArrow ?? (noArrowAttr === 'true');\r\n\r\n const offsetRaw = entry?.config.offset ?? target.dataset['tooltipOffset'];\r\n const offset = Number.isFinite(Number(offsetRaw)) ? Number(offsetRaw) : this.offset;\r\n\r\n return { icon, text, html, allowHtml, noArrow, offset };\r\n }\r\n\r\n private show(target: HTMLElement): void {\r\n const payload = this.getContent(target);\r\n const content = payload.allowHtml && payload.html ? payload.html : payload.text;\r\n\r\n if (!content) {\r\n this.hide();\r\n return;\r\n }\r\n\r\n this.hide(true);\r\n\r\n const tooltip = this.documentRef.createElement('div');\r\n tooltip.className = 'ndt-tooltip';\r\n tooltip.setAttribute('role', 'tooltip');\r\n tooltip.setAttribute('data-placement', this.getPosition(target));\r\n if (payload.noArrow) {\r\n tooltip.setAttribute('data-no-arrow', 'true');\r\n }\r\n\r\n const contentWrap = this.documentRef.createElement('div');\r\n contentWrap.className = 'ndt-tooltip__content';\r\n\r\n if (payload.icon) {\r\n const iconEl = this.documentRef.createElement('span');\r\n iconEl.className = `ndt-tooltip__icon ${payload.icon}`;\r\n iconEl.setAttribute('aria-hidden', 'true');\r\n contentWrap.appendChild(iconEl);\r\n }\r\n\r\n const textEl = this.documentRef.createElement('span');\r\n textEl.className = 'ndt-tooltip__text';\r\n if (payload.allowHtml && payload.html) {\r\n textEl.innerHTML = payload.html;\r\n } else {\r\n textEl.textContent = payload.text;\r\n }\r\n\r\n contentWrap.appendChild(textEl);\r\n tooltip.appendChild(contentWrap);\r\n\r\n this.documentRef.body.appendChild(tooltip);\r\n\r\n this.activeTarget = target;\r\n this.activeTooltipEl = tooltip;\r\n\r\n this.positionTooltip(target, tooltip, this.getPosition(target), payload.offset);\r\n\r\n requestAnimationFrame(() => {\r\n if (this.activeTooltipEl === tooltip) {\r\n tooltip.classList.add('ndt-tooltip--show');\r\n }\r\n });\r\n }\r\n\r\n private hide(immediate = false): void {\r\n if (!this.activeTooltipEl) {\r\n this.activeTarget = null;\r\n return;\r\n }\r\n\r\n const tooltip = this.activeTooltipEl;\r\n this.activeTooltipEl = null;\r\n this.activeTarget = null;\r\n\r\n if (immediate) {\r\n if (tooltip.parentNode) {\r\n tooltip.parentNode.removeChild(tooltip);\r\n }\r\n return;\r\n }\r\n\r\n tooltip.classList.remove('ndt-tooltip--show');\r\n window.setTimeout(() => {\r\n if (tooltip.parentNode) {\r\n tooltip.parentNode.removeChild(tooltip);\r\n }\r\n }, 180);\r\n }\r\n\r\n private reposition(): void {\r\n if (!this.activeTarget || !this.activeTooltipEl) {\r\n return;\r\n }\r\n\r\n const payload = this.getContent(this.activeTarget);\r\n this.positionTooltip(this.activeTarget, this.activeTooltipEl, this.getPosition(this.activeTarget), payload.offset);\r\n }\r\n\r\n private positionTooltip(target: HTMLElement, tooltip: HTMLElement, preferred: TooltipPosition, offset: number): void {\r\n const rect = target.getBoundingClientRect();\r\n const tipRect = tooltip.getBoundingClientRect();\r\n\r\n const vw = window.innerWidth;\r\n const vh = window.innerHeight;\r\n\r\n const placement = this.pickPlacement(preferred, rect, tipRect, vw, vh, offset);\r\n const coords = this.computeCoords(placement, rect, tipRect, offset);\r\n\r\n const minX = this.viewportPadding;\r\n const maxX = vw - tipRect.width - this.viewportPadding;\r\n const minY = this.viewportPadding;\r\n const maxY = vh - tipRect.height - this.viewportPadding;\r\n\r\n const left = Math.min(Math.max(coords.left, minX), Math.max(minX, maxX));\r\n const top = Math.min(Math.max(coords.top, minY), Math.max(minY, maxY));\r\n\r\n tooltip.style.left = `${Math.round(left)}px`;\r\n tooltip.style.top = `${Math.round(top)}px`;\r\n tooltip.setAttribute('data-placement', placement);\r\n }\r\n\r\n private pickPlacement(\r\n preferred: TooltipPosition,\r\n rect: DOMRect,\r\n tipRect: DOMRect,\r\n vw: number,\r\n vh: number,\r\n offset: number\r\n ): TooltipPosition {\r\n const fits: Record<TooltipPosition, boolean> = {\r\n top: rect.top - offset - tipRect.height >= this.viewportPadding,\r\n bottom: rect.bottom + offset + tipRect.height <= vh - this.viewportPadding,\r\n left: rect.left - offset - tipRect.width >= this.viewportPadding,\r\n right: rect.right + offset + tipRect.width <= vw - this.viewportPadding\r\n };\r\n\r\n const order: TooltipPosition[] = [preferred, 'bottom', 'top', 'right', 'left'];\r\n for (const candidate of order) {\r\n if (fits[candidate]) {\r\n return candidate;\r\n }\r\n }\r\n\r\n return preferred;\r\n }\r\n\r\n private computeCoords(\r\n placement: TooltipPosition,\r\n rect: DOMRect,\r\n tipRect: DOMRect,\r\n offset: number\r\n ): { top: number; left: number } {\r\n switch (placement) {\r\n case 'top':\r\n return {\r\n top: rect.top - tipRect.height - offset,\r\n left: rect.left + (rect.width - tipRect.width) / 2\r\n };\r\n case 'bottom':\r\n return {\r\n top: rect.bottom + offset,\r\n left: rect.left + (rect.width - tipRect.width) / 2\r\n };\r\n case 'left':\r\n return {\r\n top: rect.top + (rect.height - tipRect.height) / 2,\r\n left: rect.left - tipRect.width - offset\r\n };\r\n default:\r\n return {\r\n top: rect.top + (rect.height - tipRect.height) / 2,\r\n left: rect.right + offset\r\n };\r\n }\r\n }\r\n}\r\n","import { CommonModule } from '@angular/common';\r\nimport { AfterViewInit, Component, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, Output, SimpleChanges } from '@angular/core';\r\nimport {\r\n DataTableAction,\r\n DataTableActionEvent,\r\n DataTableColumn,\r\n DataTableExportEvent,\r\n DynamicDataTableConfig\r\n} from './models';\r\nimport { InternalSortState } from './dynamic-datatable.types';\r\nimport { TooltipManager } from './tooltip-manager';\r\n\r\ntype RowData = Record<string, unknown>;\r\n\r\ninterface InternalRow<T extends RowData = RowData> {\r\n id: string;\r\n data: T;\r\n}\r\n\r\nconst DEFAULT_CONFIG: Required<Pick<DynamicDataTableConfig, 'title' | 'rowsPerPageOptions' | 'defaultRowsPerPage'>> & {\r\n features: Required<NonNullable<DynamicDataTableConfig['features']>>;\r\n exportOptions: Required<NonNullable<DynamicDataTableConfig['exportOptions']>>;\r\n} = {\r\n title: 'Dynamic DataTable',\r\n features: {\r\n export: true,\r\n sorting: true,\r\n searching: true,\r\n pagination: true,\r\n rowsPerPage: true,\r\n actions: true,\r\n checkboxSelection: true\r\n },\r\n rowsPerPageOptions: [5, 10, 25, 50],\r\n defaultRowsPerPage: 10,\r\n exportOptions: {\r\n fileName: 'datatable-export',\r\n formats: ['csv', 'excel']\r\n }\r\n};\r\n\r\n@Component({\r\n selector: 'lib-dynamic-datatable',\r\n standalone: true,\r\n imports: [CommonModule],\r\n templateUrl: './dynamic-datatable.component.html',\r\n styleUrl: './dynamic-datatable.component.scss'\r\n})\r\nexport class DynamicDatatableComponent implements OnChanges, AfterViewInit, OnDestroy {\r\n @Input() config: DynamicDataTableConfig = {};\r\n @Input() columns: DataTableColumn<RowData>[] = [];\r\n @Input() data: RowData[] = [];\r\n\r\n @Output() readonly actionSelected = new EventEmitter<DataTableActionEvent<RowData>>();\r\n @Output() readonly selectionChange = new EventEmitter<RowData[]>();\r\n @Output() readonly sortChange = new EventEmitter<InternalSortState>();\r\n @Output() readonly pageChange = new EventEmitter<number>();\r\n @Output() readonly exportTriggered = new EventEmitter<DataTableExportEvent<RowData>>();\r\n\r\n mergedConfig: DynamicDataTableConfig<RowData> = {\r\n title: DEFAULT_CONFIG.title,\r\n features: { ...DEFAULT_CONFIG.features },\r\n rowsPerPageOptions: [...DEFAULT_CONFIG.rowsPerPageOptions],\r\n defaultRowsPerPage: DEFAULT_CONFIG.defaultRowsPerPage,\r\n exportOptions: { ...DEFAULT_CONFIG.exportOptions },\r\n columns: [],\r\n actions: []\r\n };\r\n\r\n mergedColumns: DataTableColumn<RowData>[] = [];\r\n\r\n private allRows: InternalRow<RowData>[] = [];\r\n filteredRows: InternalRow<RowData>[] = [];\r\n pagedRows: InternalRow<RowData>[] = [];\r\n\r\n searchTerm = '';\r\n currentPage = 1;\r\n rowsPerPage = DEFAULT_CONFIG.defaultRowsPerPage;\r\n totalPages = 1;\r\n sortState: InternalSortState = { key: null, direction: 'asc' };\r\n selectedRows = new Set<string>();\r\n isExportMenuOpen = false;\r\n private tooltipManager: TooltipManager | null = null;\r\n\r\n constructor(private readonly hostRef: ElementRef<HTMLElement>) {}\r\n\r\n ngAfterViewInit(): void {\r\n if (typeof document === 'undefined') {\r\n return;\r\n }\r\n\r\n this.tooltipManager = new TooltipManager(this.hostRef.nativeElement, document);\r\n this.tooltipManager.init();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.tooltipManager?.destroy();\r\n this.tooltipManager = null;\r\n }\r\n\r\n ngOnChanges(_changes: SimpleChanges): void {\r\n this.refresh();\r\n }\r\n\r\n refresh(): void {\r\n this.applyConfig();\r\n this.normalizeRows();\r\n this.applyFiltersSortAndPagination();\r\n }\r\n\r\n updateData(newData: RowData[]): void {\r\n this.data = Array.isArray(newData) ? [...newData] : [];\r\n this.refresh();\r\n }\r\n\r\n updateConfig(newConfig: DynamicDataTableConfig<RowData>): void {\r\n this.config = { ...this.config, ...newConfig };\r\n this.refresh();\r\n }\r\n\r\n getSelectedRows(): RowData[] {\r\n return this.allRows.filter((row) => this.selectedRows.has(row.id)).map((row) => row.data);\r\n }\r\n\r\n clearSelection(): void {\r\n this.selectedRows.clear();\r\n this.selectionChange.emit([]);\r\n }\r\n\r\n isFeatureOn(feature: keyof NonNullable<DynamicDataTableConfig['features']>): boolean {\r\n return Boolean(this.mergedConfig.features?.[feature]);\r\n }\r\n\r\n isExportFormatEnabled(format: 'csv' | 'excel'): boolean {\r\n const formats = this.mergedConfig.exportOptions?.formats ?? [];\r\n return formats.includes(format);\r\n }\r\n\r\n onSearchInput(event: Event): void {\r\n const input = event.target as HTMLInputElement;\r\n this.searchTerm = (input.value || '').trim().toLowerCase();\r\n this.currentPage = 1;\r\n this.applyFiltersSortAndPagination();\r\n }\r\n\r\n onRowsPerPageChange(event: Event): void {\r\n const select = event.target as HTMLSelectElement;\r\n const value = Number(select.value);\r\n this.rowsPerPage = Number.isFinite(value) && value > 0 ? value : this.getInitialRowsPerPage();\r\n this.currentPage = 1;\r\n this.applyFiltersSortAndPagination();\r\n }\r\n\r\n toggleSort(column: DataTableColumn<RowData>): void {\r\n if (!this.isFeatureOn('sorting') || !column.sortable) {\r\n return;\r\n }\r\n\r\n const key = String(column.key);\r\n if (this.sortState.key === key) {\r\n this.sortState.direction = this.sortState.direction === 'asc' ? 'desc' : 'asc';\r\n } else {\r\n this.sortState = { key, direction: 'asc' };\r\n }\r\n\r\n this.currentPage = 1;\r\n this.sortChange.emit({ ...this.sortState });\r\n this.applyFiltersSortAndPagination();\r\n }\r\n\r\n getSortIconClass(columnKey: string): string {\r\n if (this.sortState.key !== columnKey) {\r\n return 'bi bi-arrow-down-up';\r\n }\r\n\r\n return this.sortState.direction === 'asc' ? 'bi bi-sort-down' : 'bi bi-sort-up';\r\n }\r\n\r\n isSortColumn(columnKey: string): boolean {\r\n return this.sortState.key === columnKey;\r\n }\r\n\r\n goToPage(page: number): void {\r\n if (!this.isFeatureOn('pagination')) {\r\n return;\r\n }\r\n\r\n const bounded = Math.min(Math.max(page, 1), this.totalPages);\r\n if (bounded === this.currentPage) {\r\n return;\r\n }\r\n\r\n this.currentPage = bounded;\r\n this.pageChange.emit(this.currentPage);\r\n this.updatePagedRowsOnly();\r\n }\r\n\r\n getPaginationPages(): number[] {\r\n return Array.from({ length: this.totalPages }, (_, idx) => idx + 1);\r\n }\r\n\r\n isRowSelected(rowId: string): boolean {\r\n return this.selectedRows.has(rowId);\r\n }\r\n\r\n toggleRowSelection(row: InternalRow<RowData>, event: Event): void {\r\n const input = event.target as HTMLInputElement;\r\n if (input.checked) {\r\n this.selectedRows.add(row.id);\r\n } else {\r\n this.selectedRows.delete(row.id);\r\n }\r\n\r\n this.emitSelection();\r\n }\r\n\r\n toggleSelectAllCurrentPage(event: Event): void {\r\n const input = event.target as HTMLInputElement;\r\n this.pagedRows.forEach((row) => {\r\n if (input.checked) {\r\n this.selectedRows.add(row.id);\r\n } else {\r\n this.selectedRows.delete(row.id);\r\n }\r\n });\r\n\r\n this.emitSelection();\r\n }\r\n\r\n isCurrentPageFullySelected(): boolean {\r\n if (!this.pagedRows.length) {\r\n return false;\r\n }\r\n\r\n return this.pagedRows.every((row) => this.selectedRows.has(row.id));\r\n }\r\n\r\n toggleExportMenu(event: Event): void {\r\n event.stopPropagation();\r\n this.isExportMenuOpen = !this.isExportMenuOpen;\r\n }\r\n\r\n onActionItemClick(actionIndex: number, row: InternalRow<RowData>, event: Event): void {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n if (!Number.isInteger(actionIndex) || actionIndex < 0) {\r\n return;\r\n }\r\n\r\n const action = this.mergedConfig.actions?.[actionIndex];\r\n if (!action) {\r\n return;\r\n }\r\n\r\n const rowIndex = this.filteredRows.findIndex((item) => item.id === row.id);\r\n this.actionSelected.emit({ action, row: row.data, rowIndex });\r\n }\r\n\r\n exportCSV(): void {\r\n this.isExportMenuOpen = false;\r\n const rows = this.getRowsForExport();\r\n this.exportTriggered.emit({ format: 'csv', rows });\r\n\r\n const headers = this.mergedColumns.map((column) => this.escapeCsv(column.label));\r\n const lines = rows.map((row) => {\r\n return this.mergedColumns\r\n .map((column) => this.escapeCsv(this.getCellTextValue(row, column)))\r\n .join(',');\r\n });\r\n\r\n const csv = [headers.join(','), ...lines].join('\\n');\r\n this.downloadFile(csv, `${this.getExportFileName()}.csv`, 'text/csv;charset=utf-8;');\r\n }\r\n\r\n exportExcel(): void {\r\n this.isExportMenuOpen = false;\r\n const rows = this.getRowsForExport();\r\n this.exportTriggered.emit({ format: 'excel', rows });\r\n\r\n const headerCells = this.mergedColumns.map((column) => `<th>${this.escapeHtml(column.label)}</th>`).join('');\r\n const bodyRows = rows\r\n .map((row) => {\r\n const cells = this.mergedColumns\r\n .map((column) => `<td>${this.escapeHtml(this.getCellTextValue(row, column))}</td>`)\r\n .join('');\r\n return `<tr>${cells}</tr>`;\r\n })\r\n .join('');\r\n\r\n const html = `<html><head><meta charset=\"UTF-8\"></head><body><table border=\"1\"><thead><tr>${headerCells}</tr></thead><tbody>${bodyRows}</tbody></table></body></html>`;\r\n this.downloadFile(html, `${this.getExportFileName()}.xls`, 'application/vnd.ms-excel;charset=utf-8;');\r\n }\r\n\r\n getRenderedCell(row: RowData, column: DataTableColumn<RowData>): string {\r\n if (typeof column.render === 'function') {\r\n return column.render(row);\r\n }\r\n\r\n const key = String(column.key);\r\n const value = row[key];\r\n return this.escapeHtml(value == null ? '' : String(value));\r\n }\r\n\r\n toColumnWidth(width: string | number | undefined): string {\r\n if (typeof width === 'number') {\r\n return `${width}px`;\r\n }\r\n\r\n if (typeof width === 'string' && width.trim()) {\r\n return width.trim();\r\n }\r\n\r\n return 'auto';\r\n }\r\n\r\n getColumnTooltip(column: DataTableColumn<RowData>): string {\r\n const label = String(column.label || 'Column');\r\n if (this.isFeatureOn('sorting') && column.sortable) {\r\n const key = String(column.key);\r\n if (this.sortState.key === key) {\r\n const direction = this.sortState.direction === 'asc' ? 'ascending' : 'descending';\r\n return `${label} (sorted ${direction})`;\r\n }\r\n return `${label} (click to sort)`;\r\n }\r\n return label;\r\n }\r\n\r\n getCellTooltip(row: RowData, column: DataTableColumn<RowData>): string {\r\n const value = this.getCellTextValue(row, column).trim();\r\n if (!value) {\r\n return String(column.label || 'Cell');\r\n }\r\n return value;\r\n }\r\n\r\n getColumnCount(): number {\r\n let count = this.mergedColumns.length;\r\n if (this.isFeatureOn('checkboxSelection')) {\r\n count += 1;\r\n }\r\n if (this.isFeatureOn('actions')) {\r\n count += 1;\r\n }\r\n return count;\r\n }\r\n\r\n getStartEntry(): number {\r\n if (!this.filteredRows.length) {\r\n return 0;\r\n }\r\n\r\n if (!this.isFeatureOn('pagination')) {\r\n return 1;\r\n }\r\n\r\n return (this.currentPage - 1) * this.rowsPerPage + 1;\r\n }\r\n\r\n getEndEntry(): number {\r\n if (!this.filteredRows.length) {\r\n return 0;\r\n }\r\n\r\n if (!this.isFeatureOn('pagination')) {\r\n return this.filteredRows.length;\r\n }\r\n\r\n return Math.min(this.currentPage * this.rowsPerPage, this.filteredRows.length);\r\n }\r\n\r\n private applyConfig(): void {\r\n const features = {\r\n ...DEFAULT_CONFIG.features,\r\n ...(this.config.features ?? {})\r\n };\r\n\r\n const exportOptions = {\r\n ...DEFAULT_CONFIG.exportOptions,\r\n ...(this.config.exportOptions ?? {})\r\n };\r\n\r\n const rowsPerPageOptions = (this.config.rowsPerPageOptions ?? DEFAULT_CONFIG.rowsPerPageOptions).filter(\r\n (item) => Number.isFinite(item) && item > 0\r\n );\r\n\r\n this.mergedConfig = {\r\n title: this.config.title ?? DEFAULT_CONFIG.title,\r\n features,\r\n rowsPerPageOptions: rowsPerPageOptions.length ? rowsPerPageOptions : [...DEFAULT_CONFIG.rowsPerPageOptions],\r\n defaultRowsPerPage: this.config.defaultRowsPerPage ?? DEFAULT_CONFIG.defaultRowsPerPage,\r\n exportOptions,\r\n actions: [...(this.config.actions ?? [])],\r\n columns: []\r\n };\r\n\r\n this.mergedColumns = [...(this.columns.length ? this.columns : (this.config.columns ?? []))];\r\n this.rowsPerPage = this.getInitialRowsPerPage();\r\n }\r\n\r\n private normalizeRows(): void {\r\n this.allRows = (Array.isArray(this.data) ? this.data : []).map((row, index) => {\r\n const rowId = row['id'];\r\n const id = rowId == null ? `row-${index + 1}` : String(rowId);\r\n return { id, data: row };\r\n });\r\n\r\n const validIds = new Set(this.allRows.map((row) => row.id));\r\n for (const selectedId of Array.from(this.selectedRows)) {\r\n if (!validIds.has(selectedId)) {\r\n this.selectedRows.delete(selectedId);\r\n }\r\n }\r\n }\r\n\r\n private applyFiltersSortAndPagination(): void {\r\n if (!this.isFeatureOn('searching') || !this.searchTerm) {\r\n this.filteredRows = [...this.allRows];\r\n } else {\r\n this.filteredRows = this.allRows.filter((row) => {\r\n const searchSpace = this.mergedColumns\r\n .map((column) => this.getCellTextValue(row.data, column).toLowerCase())\r\n .join(' ');\r\n return searchSpace.includes(this.searchTerm);\r\n });\r\n }\r\n\r\n if (this.isFeatureOn('sorting') && this.sortState.key) {\r\n const column = this.mergedColumns.find((item) => String(item.key) === this.sortState.key);\r\n if (column?.sortable) {\r\n this.filteredRows.sort((a, b) => {\r\n const aVal = this.getCellTextValue(a.data, column);\r\n const bVal = this.getCellTextValue(b.data, column);\r\n const compare = this.compareValues(aVal, bVal);\r\n return this.sortState.direction === 'asc' ? compare : -compare;\r\n });\r\n }\r\n }\r\n\r\n this.totalPages = this.isFeatureOn('pagination')\r\n ? Math.max(1, Math.ceil(this.filteredRows.length / this.rowsPerPage))\r\n : 1;\r\n\r\n if (this.currentPage > this.totalPages) {\r\n this.currentPage = this.totalPages;\r\n }\r\n\r\n this.updatePagedRowsOnly();\r\n this.emitSelection();\r\n }\r\n\r\n private updatePagedRowsOnly(): void {\r\n if (!this.isFeatureOn('pagination')) {\r\n this.pagedRows = [...this.filteredRows];\r\n return;\r\n }\r\n\r\n const start = (this.currentPage - 1) * this.rowsPerPage;\r\n this.pagedRows = this.filteredRows.slice(start, start + this.rowsPerPage);\r\n }\r\n\r\n private getCellTextValue(row: RowData, column: DataTableColumn<RowData>): string {\r\n const key = String(column.key);\r\n if (row[key] != null) {\r\n return String(row[key]);\r\n }\r\n\r\n const rendered = this.getRenderedCell(row, column);\r\n return this.stripHtml(rendered);\r\n }\r\n\r\n private compareValues(a: string, b: string): number {\r\n const aText = a.trim();\r\n const bText = b.trim();\r\n\r\n const aNum = this.parseStrictNumber(aText);\r\n const bNum = this.parseStrictNumber(bText);\r\n if (aNum !== null && bNum !== null) {\r\n return aNum - bNum;\r\n }\r\n\r\n const aDate = this.parseDateValue(aText);\r\n const bDate = this.parseDateValue(bText);\r\n if (aDate !== null && bDate !== null) {\r\n return aDate - bDate;\r\n }\r\n\r\n return aText.localeCompare(bText, undefined, { numeric: true, sensitivity: 'base' });\r\n }\r\n\r\n private parseStrictNumber(value: string): number | null {\r\n const normalized = value.replace(/[$,\\s]/g, '');\r\n if (!/^[-+]?\\d*\\.?\\d+$/.test(normalized)) {\r\n return null;\r\n }\r\n\r\n const numberValue = Number(normalized);\r\n return Number.isNaN(numberValue) ? null : numberValue;\r\n }\r\n\r\n private parseDateValue(value: string): number | null {\r\n const usDate = value.match(/^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})$/);\r\n if (usDate) {\r\n const month = Number(usDate[1]);\r\n const day = Number(usDate[2]);\r\n const year = Number(usDate[3]);\r\n const utc = Date.UTC(year, month - 1, day);\r\n return Number.isNaN(utc) ? null : utc;\r\n }\r\n\r\n const isoDate = value.match(/^(\\d{4})-(\\d{1,2})-(\\d{1,2})$/);\r\n if (isoDate) {\r\n const year = Number(isoDate[1]);\r\n const month = Number(isoDate[2]);\r\n const day = Number(isoDate[3]);\r\n const utc = Date.UTC(year, month - 1, day);\r\n return Number.isNaN(utc) ? null : utc;\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private getRowsForExport(): RowData[] {\r\n const selected = this.getSelectedRows();\r\n if (selected.length) {\r\n return selected;\r\n }\r\n\r\n return this.filteredRows.map((item) => item.data);\r\n }\r\n\r\n private getExportFileName(): string {\r\n return this.mergedConfig.exportOptions?.fileName || 'datatable-export';\r\n }\r\n\r\n private downloadFile(content: string, fileName: string, mimeType: string): void {\r\n if (typeof document === 'undefined') {\r\n return;\r\n }\r\n\r\n const blob = new Blob([content], { type: mimeType });\r\n const url = URL.createObjectURL(blob);\r\n const anchor = document.createElement('a');\r\n anchor.href = url;\r\n anchor.download = fileName;\r\n document.body.appendChild(anchor);\r\n anchor.click();\r\n document.body.removeChild(anchor);\r\n URL.revokeObjectURL(url);\r\n }\r\n\r\n private escapeCsv(value: string): string {\r\n if (/[\",\\n]/.test(value)) {\r\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\r\n }\r\n\r\n return value;\r\n }\r\n\r\n private stripHtml(input: string): string {\r\n if (typeof document === 'undefined') {\r\n return input;\r\n }\r\n\r\n const temp = document.createElement('div');\r\n temp.innerHTML = input;\r\n return temp.textContent || temp.innerText || '';\r\n }\r\n\r\n private escapeHtml(value: string): string {\r\n return String(value)\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\r\n }\r\n\r\n private getInitialRowsPerPage(): number {\r\n const options = this.mergedConfig.rowsPerPageOptions ?? DEFAULT_CONFIG.rowsPerPageOptions;\r\n const preferred = Number(this.mergedConfig.defaultRowsPerPage ?? DEFAULT_CONFIG.defaultRowsPerPage);\r\n return options.includes(preferred) ? preferred : options[0] ?? DEFAULT_CONFIG.defaultRowsPerPage;\r\n }\r\n\r\n private emitSelection(): void {\r\n this.selectionChange.emit(this.getSelectedRows());\r\n }\r\n\r\n closeMenus(): void {\r\n this.isExportMenuOpen = false;\r\n }\r\n\r\n}\r\n","<div class=\"ndt-card\" (click)=\"closeMenus()\">\r\n <div class=\"ndt-header\">\r\n <h3 class=\"ndt-title\" [attr.data-tooltip]=\"mergedConfig.title\">{{ mergedConfig.title }}</h3>\r\n </div>\r\n\r\n <div class=\"ndt-toolbar\">\r\n <div class=\"ndt-left-tools\">\r\n <ng-container *ngIf=\"isFeatureOn('export')\">\r\n <div class=\"ndt-dropdown\" (click)=\"$event.stopPropagation()\">\r\n <button class=\"ndt-btn ndt-export-btn\" type=\"button\" data-tooltip=\"Export data\" data-tooltip-position=\"bottom\" (click)=\"toggleExportMenu($event)\">\r\n <i class=\"bi bi-download\"></i>\r\n <span>Export</span>\r\n <i class=\"bi bi-chevron-down ndt-chevron\"></i>\r\n </button>\r\n\r\n <ul class=\"ndt-dropdown-menu\" *ngIf=\"isExportMenuOpen\">\r\n <li *ngIf=\"isExportFormatEnabled('csv')\">\r\n <button type=\"button\" class=\"ndt-dropdown-item\" data-tooltip=\"Download CSV\" data-tooltip-position=\"right\" (click)=\"exportCSV()\">\r\n <i class=\"bi bi-filetype-csv\"></i>\r\n <span>CSV</span>\r\n </button>\r\n </li>\r\n <li *ngIf=\"isExportFormatEnabled('excel')\">\r\n <button type=\"button\" class=\"ndt-dropdown-item\" data-tooltip=\"Download Excel\" data-tooltip-position=\"right\" (click)=\"exportExcel()\">\r\n <i class=\"bi bi-file-earmark-spreadsheet\"></i>\r\n <span>Excel (.xls)</span>\r\n </button>\r\n </li>\r\n </ul>\r\n </div>\r\n </ng-container>\r\n\r\n <label class=\"ndt-inline-label\" *ngIf=\"isFeatureOn('rowsPerPage') && isFeatureOn('pagination')\">\r\n Rows per page:\r\n <select data-tooltip=\"Rows per page\" [value]=\"rowsPerPage\" (change)=\"onRowsPerPageChange($event)\">\r\n <option *ngFor=\"let option of mergedConfig.rowsPerPageOptions || []\" [value]=\"option\" [attr.data-tooltip]=\"'Show ' + option + ' rows per page'\">{{ option }}</option>\r\n </select>\r\n </label>\r\n </div>\r\n\r\n <div class=\"ndt-right-tools\" *ngIf=\"isFeatureOn('searching')\">\r\n <input\r\n type=\"search\"\r\n placeholder=\"Search records\"\r\n data-tooltip=\"Search records\"\r\n [value]=\"searchTerm\"\r\n (input)=\"onSearchInput($event)\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"ndt-table-wrap\">\r\n <table class=\"ndt-table\">\r\n <colgroup>\r\n <col *ngIf=\"isFeatureOn('checkboxSelection')\" style=\"width: 44px\" />\r\n <col *ngFor=\"let column of mergedColumns\" [style.width]=\"toColumnWidth(column.width)\" />\r\n <col *ngIf=\"isFeatureOn('actions')\" style=\"width: 78px\" />\r\n </colgroup>\r\n\r\n <thead>\r\n <tr>\r\n <th *ngIf=\"isFeatureOn('checkboxSelection')\">\r\n <input\r\n type=\"checkbox\"\r\n data-tooltip=\"Select all rows on current page\"\r\n [checked]=\"isCurrentPageFullySelected()\"\r\n (change)=\"toggleSelectAllCurrentPage($event)\"\r\n />\r\n </th>\r\n <th\r\n *ngFor=\"let column of mergedColumns\"\r\n [class.ndt-sortable]=\"isFeatureOn('sorting') && !!column.sortable\"\r\n [attr.data-tooltip]=\"getColumnTooltip(column)\"\r\n data-tooltip-position=\"top\"\r\n (click)=\"toggleSort(column)\"\r\n >\r\n <span class=\"ndt-th-content\">\r\n <span class=\"ndt-th-label\">{{ column.label }}</span>\r\n <i\r\n *ngIf=\"isFeatureOn('sorting') && column.sortable\"\r\n [ngClass]=\"[\r\n 'ndt-sort-indicator',\r\n getSortIconClass(column.key.toString()),\r\n isSortColumn(column.key.toString()) ? 'active' : ''\r\n ]\"\r\n [attr.data-tooltip]=\"getColumnTooltip(column)\"\r\n data-tooltip-position=\"top\"\r\n ></i>\r\n </span>\r\n </th>\r\n <th *ngIf=\"isFeatureOn('actions')\" data-tooltip=\"Available row actions\" data-tooltip-position=\"top\">Actions</th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n <tr *ngIf=\"!pagedRows.length\">\r\n <td [attr.colspan]=\"getColumnCount()\" class=\"ndt-empty\" data-tooltip=\"No records found\">No records found.</td>\r\n </tr>\r\n\r\n <tr *ngFor=\"let row of pagedRows\" [class.ndt-selected]=\"isRowSelected(row.id)\">\r\n <td *ngIf=\"isFeatureOn('checkboxSelection')\">\r\n <input\r\n type=\"checkbox\"\r\n [attr.data-tooltip]=\"'Select row ' + row.id\"\r\n [checked]=\"isRowSelected(row.id)\"\r\n (change)=\"toggleRowSelection(row, $event)\"\r\n />\r\n </td>\r\n\r\n <td\r\n *ngFor=\"let column of mergedColumns\"\r\n [attr.data-tooltip]=\"getCellTooltip(row.data, column)\"\r\n data-tooltip-position=\"bottom\"\r\n [innerHTML]=\"getRenderedCell(row.data, column)\">\r\n </td>\r\n\r\n <td *ngIf=\"isFeatureOn('actions')\" class=\"ndt-actions-cell\">\r\n <div class=\"ndt-action-icons\" (click)=\"$event.stopPropagation()\">\r\n <button\r\n *ngFor=\"let action of mergedConfig.actions || []; let i = index\"\r\n type=\"button\"\r\n class=\"ndt-actions-btn\"\r\n [class.ndt-danger]=\"!!action.danger\"\r\n [attr.data-tooltip]=\"action.label\"\r\n data-tooltip-position=\"top\"\r\n [attr.aria-label]=\"action.label\"\r\n (click)=\"onActionItemClick(i, row, $event)\"\r\n >\r\n <i *ngIf=\"action.icon\" [class]=\"action.icon\"></i>\r\n <span *ngIf=\"!action.icon\" class=\"ndt-action-fallback\">{{ action.label.charAt(0) }}</span>\r\n </button>\r\n </div>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div class=\"ndt-footer\">\r\n <div [attr.data-tooltip]=\"selectedRows.size + ' rows selected'\">\r\n {{ selectedRows.size }} selected\r\n </div>\r\n\r\n <div [attr.data-tooltip]=\"'Showing ' + getStartEntry() + ' to ' + getEndEntry() + ' of ' + filteredRows.length + ' entries'\">\r\n Showing {{ getStartEntry() }} to {{ getEndEntry() }} of {{ filteredRows.length }} entries\r\n </div>\r\n\r\n <ul class=\"ndt-pagination\" *ngIf=\"isFeatureOn('pagination') && totalPages > 1\">\r\n <li [class.disabled]=\"currentPage <= 1\">\r\n <button type=\"button\" class=\"ndt-page-link\" data-tooltip=\"Go to previous page\" data-tooltip-position=\"top\" (click)=\"goToPage(currentPage - 1)\" [disabled]=\"currentPage <= 1\">Prev</button>\r\n </li>\r\n <li *ngFor=\"let page of getPaginationPages()\" [class.active]=\"page === currentPage\">\r\n <button type=\"button\" class=\"ndt-page-link\" [attr.data-tooltip]=\"'Go to page ' + page\" data-tooltip-position=\"top\" (click)=\"goToPage(page)\">{{ page }}</button>\r\n </li>\r\n <li [class.disabled]=\"currentPage >= totalPages\">\r\n <button type=\"button\" class=\"ndt-page-link\" data-tooltip=\"Go to next page\" data-tooltip-position=\"top\" (click)=\"goToPage(currentPage + 1)\" [disabled]=\"currentPage >= totalPages\">Next</button>\r\n </li>\r\n </ul>\r\n </div>\r\n</div>\r\n","/*\r\n * Public API Surface of dynamic-datatable\r\n */\r\n\r\nexport * from './lib/dynamic-datatable.component';\r\nexport * from './lib/models';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
|
|
1
|
+
import { AfterViewInit, ElementRef, EventEmitter, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
|
|
2
2
|
import { DataTableActionEvent, DataTableColumn, DataTableExportEvent, DynamicDataTableConfig } from './models';
|
|
3
3
|
import { InternalSortState } from './dynamic-datatable.types';
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
@@ -7,7 +7,8 @@ interface InternalRow<T extends RowData = RowData> {
|
|
|
7
7
|
id: string;
|
|
8
8
|
data: T;
|
|
9
9
|
}
|
|
10
|
-
export declare class DynamicDatatableComponent implements OnChanges {
|
|
10
|
+
export declare class DynamicDatatableComponent implements OnChanges, AfterViewInit, OnDestroy {
|
|
11
|
+
private readonly hostRef;
|
|
11
12
|
config: DynamicDataTableConfig;
|
|
12
13
|
columns: DataTableColumn<RowData>[];
|
|
13
14
|
data: RowData[];
|
|
@@ -27,10 +28,11 @@ export declare class DynamicDatatableComponent implements OnChanges {
|
|
|
27
28
|
totalPages: number;
|
|
28
29
|
sortState: InternalSortState;
|
|
29
30
|
selectedRows: Set<string>;
|
|
30
|
-
openActionMenuRowId: string | null;
|
|
31
|
-
private openActionAnchorEl;
|
|
32
|
-
actionMenuStyle: Record<string, string>;
|
|
33
31
|
isExportMenuOpen: boolean;
|
|
32
|
+
private tooltipManager;
|
|
33
|
+
constructor(hostRef: ElementRef<HTMLElement>);
|
|
34
|
+
ngAfterViewInit(): void;
|
|
35
|
+
ngOnDestroy(): void;
|
|
34
36
|
ngOnChanges(_changes: SimpleChanges): void;
|
|
35
37
|
refresh(): void;
|
|
36
38
|
updateData(newData: RowData[]): void;
|
|
@@ -50,15 +52,14 @@ export declare class DynamicDatatableComponent implements OnChanges {
|
|
|
50
52
|
toggleRowSelection(row: InternalRow<RowData>, event: Event): void;
|
|
51
53
|
toggleSelectAllCurrentPage(event: Event): void;
|
|
52
54
|
isCurrentPageFullySelected(): boolean;
|
|
53
|
-
toggleActionMenu(rowId: string, event: Event): void;
|
|
54
|
-
closeActionMenu(): void;
|
|
55
55
|
toggleExportMenu(event: Event): void;
|
|
56
|
-
isActionMenuOpen(rowId: string): boolean;
|
|
57
56
|
onActionItemClick(actionIndex: number, row: InternalRow<RowData>, event: Event): void;
|
|
58
57
|
exportCSV(): void;
|
|
59
58
|
exportExcel(): void;
|
|
60
59
|
getRenderedCell(row: RowData, column: DataTableColumn<RowData>): string;
|
|
61
60
|
toColumnWidth(width: string | number | undefined): string;
|
|
61
|
+
getColumnTooltip(column: DataTableColumn<RowData>): string;
|
|
62
|
+
getCellTooltip(row: RowData, column: DataTableColumn<RowData>): string;
|
|
62
63
|
getColumnCount(): number;
|
|
63
64
|
getStartEntry(): number;
|
|
64
65
|
getEndEntry(): number;
|
|
@@ -66,11 +67,6 @@ export declare class DynamicDatatableComponent implements OnChanges {
|
|
|
66
67
|
private normalizeRows;
|
|
67
68
|
private applyFiltersSortAndPagination;
|
|
68
69
|
private updatePagedRowsOnly;
|
|
69
|
-
onWindowResize(): void;
|
|
70
|
-
onWindowScroll(): void;
|
|
71
|
-
private validateOpenActionMenuRow;
|
|
72
|
-
private updateActionMenuPosition;
|
|
73
|
-
private getEstimatedActionMenuHeight;
|
|
74
70
|
private getCellTextValue;
|
|
75
71
|
private compareValues;
|
|
76
72
|
private parseStrictNumber;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
type TooltipTrigger = 'hover' | 'click';
|
|
2
|
+
type TooltipPosition = 'top' | 'bottom' | 'left' | 'right';
|
|
3
|
+
interface TooltipConfig {
|
|
4
|
+
content?: string;
|
|
5
|
+
html?: string;
|
|
6
|
+
icon?: string;
|
|
7
|
+
trigger?: TooltipTrigger;
|
|
8
|
+
position?: TooltipPosition;
|
|
9
|
+
noArrow?: boolean;
|
|
10
|
+
allowHtml?: boolean;
|
|
11
|
+
offset?: number;
|
|
12
|
+
}
|
|
13
|
+
export declare class TooltipManager {
|
|
14
|
+
private readonly registry;
|
|
15
|
+
private readonly root;
|
|
16
|
+
private readonly documentRef;
|
|
17
|
+
private activeTarget;
|
|
18
|
+
private activeTooltipEl;
|
|
19
|
+
private readonly offset;
|
|
20
|
+
private readonly viewportPadding;
|
|
21
|
+
private readonly onMouseOverBound;
|
|
22
|
+
private readonly onMouseOutBound;
|
|
23
|
+
private readonly onFocusInBound;
|
|
24
|
+
private readonly onFocusOutBound;
|
|
25
|
+
private readonly onClickBound;
|
|
26
|
+
private readonly onDocumentClickBound;
|
|
27
|
+
private readonly onDocumentKeydownBound;
|
|
28
|
+
private readonly onWindowResizeBound;
|
|
29
|
+
private readonly onWindowScrollBound;
|
|
30
|
+
constructor(root: HTMLElement, documentRef?: Document);
|
|
31
|
+
init(): void;
|
|
32
|
+
destroy(): void;
|
|
33
|
+
register(element: HTMLElement, config: TooltipConfig): void;
|
|
34
|
+
private onMouseOver;
|
|
35
|
+
private onMouseOut;
|
|
36
|
+
private onFocusIn;
|
|
37
|
+
private onFocusOut;
|
|
38
|
+
private onClick;
|
|
39
|
+
private onDocumentClick;
|
|
40
|
+
private onDocumentKeydown;
|
|
41
|
+
private getTooltipTarget;
|
|
42
|
+
private getEntry;
|
|
43
|
+
private getTrigger;
|
|
44
|
+
private getPosition;
|
|
45
|
+
private getContent;
|
|
46
|
+
private show;
|
|
47
|
+
private hide;
|
|
48
|
+
private reposition;
|
|
49
|
+
private positionTooltip;
|
|
50
|
+
private pickPlacement;
|
|
51
|
+
private computeCoords;
|
|
52
|
+
}
|
|
53
|
+
export {};
|