ng-dynamic-datatable 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,114 +1,343 @@
|
|
|
1
|
-
# dynamic-datatable
|
|
1
|
+
# ng-dynamic-datatable
|
|
2
2
|
|
|
3
|
-
Config-driven Angular DataTable library
|
|
3
|
+
Config-driven Angular DataTable library for rendering reusable tables from JSON data and column definitions.
|
|
4
|
+
|
|
5
|
+
The package is designed for Angular standalone applications and supports sorting, searching, pagination, selection, actions, and export.
|
|
4
6
|
|
|
5
7
|
## Features
|
|
6
8
|
|
|
7
|
-
- Dynamic columns
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
9
|
+
- Dynamic columns from config
|
|
10
|
+
- JSON data input
|
|
11
|
+
- Column sorting
|
|
12
|
+
- Global search across visible columns
|
|
13
|
+
- Pagination
|
|
14
|
+
- Rows per page selector
|
|
15
|
+
- Checkbox row selection
|
|
16
|
+
- Row action menu
|
|
17
|
+
- CSV export
|
|
18
|
+
- Excel export
|
|
19
|
+
- Custom cell rendering with HTML strings
|
|
20
|
+
|
|
21
|
+
## Package Name
|
|
22
|
+
|
|
23
|
+
Install the published package with:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install ng-dynamic-datatable
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Do not use `dynamic-datatable`. The published npm package name is `ng-dynamic-datatable`.
|
|
30
|
+
|
|
31
|
+
## Requirements
|
|
32
|
+
|
|
33
|
+
- Angular 19.x
|
|
34
|
+
- `@angular/common` and `@angular/core` compatible with `^19.2.0`
|
|
35
|
+
- `bootstrap` is recommended for layout consistency
|
|
36
|
+
- `bootstrap-icons` is recommended if you use action icons like `bi bi-eye`
|
|
14
37
|
|
|
15
|
-
## Install
|
|
38
|
+
## Install In Your Angular App
|
|
16
39
|
|
|
17
40
|
```bash
|
|
18
|
-
npm install dynamic-datatable
|
|
41
|
+
npm install ng-dynamic-datatable
|
|
42
|
+
npm install bootstrap bootstrap-icons
|
|
19
43
|
```
|
|
20
44
|
|
|
21
|
-
|
|
45
|
+
Add Bootstrap styles in your Angular app configuration.
|
|
22
46
|
|
|
23
|
-
|
|
47
|
+
Example `angular.json` styles section:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"styles": [
|
|
52
|
+
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
|
53
|
+
"node_modules/bootstrap-icons/font/bootstrap-icons.css",
|
|
54
|
+
"src/styles.css"
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Quick Start
|
|
60
|
+
|
|
61
|
+
Import the standalone component directly into your Angular component.
|
|
24
62
|
|
|
25
63
|
```ts
|
|
26
64
|
import { Component } from '@angular/core';
|
|
27
65
|
import {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
66
|
+
DynamicDatatableComponent,
|
|
67
|
+
DynamicDataTableConfig,
|
|
68
|
+
DataTableColumn,
|
|
69
|
+
DataTableActionEvent
|
|
31
70
|
} from 'ng-dynamic-datatable';
|
|
32
71
|
|
|
33
72
|
@Component({
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
73
|
+
selector: 'app-users',
|
|
74
|
+
standalone: true,
|
|
75
|
+
imports: [DynamicDatatableComponent],
|
|
76
|
+
template: `
|
|
77
|
+
<lib-dynamic-datatable
|
|
78
|
+
[config]="config"
|
|
79
|
+
[columns]="columns"
|
|
80
|
+
[data]="rows"
|
|
81
|
+
(actionSelected)="onAction($event)"
|
|
82
|
+
(selectionChange)="onSelection($event)"
|
|
83
|
+
(sortChange)="onSort($event)"
|
|
84
|
+
(pageChange)="onPage($event)"
|
|
85
|
+
(exportTriggered)="onExport($event)"
|
|
86
|
+
></lib-dynamic-datatable>
|
|
87
|
+
`
|
|
46
88
|
})
|
|
47
89
|
export class UsersComponent {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
rows = [
|
|
91
|
+
{
|
|
92
|
+
id: 1,
|
|
93
|
+
initials: 'AS',
|
|
94
|
+
name: 'Aarav Sharma',
|
|
95
|
+
designation: 'Tax Accountant',
|
|
96
|
+
email: 'aarav.sharma@company.in',
|
|
97
|
+
salary: '19366.53',
|
|
98
|
+
status: 'Resigned'
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
id: 2,
|
|
102
|
+
initials: 'AP',
|
|
103
|
+
name: 'Ananya Patel',
|
|
104
|
+
designation: 'Staff Accountant',
|
|
105
|
+
email: 'ananya.patel@company.in',
|
|
106
|
+
salary: '10745.32',
|
|
107
|
+
status: 'Applied'
|
|
108
|
+
}
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
columns: DataTableColumn[] = [
|
|
112
|
+
{
|
|
113
|
+
key: 'name',
|
|
114
|
+
label: 'Name',
|
|
115
|
+
sortable: true,
|
|
116
|
+
width: '240px',
|
|
117
|
+
render: (row) => `
|
|
118
|
+
<div class="demo-user">
|
|
119
|
+
<div class="demo-avatar">${String(row['initials'] ?? '')}</div>
|
|
120
|
+
<div>
|
|
121
|
+
<div class="demo-name">${String(row['name'] ?? '')}</div>
|
|
122
|
+
<div class="demo-subtitle">${String(row['designation'] ?? '')}</div>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
`
|
|
126
|
+
},
|
|
127
|
+
{ key: 'email', label: 'Email', sortable: true, width: '260px' },
|
|
128
|
+
{ key: 'salary', label: 'Salary', sortable: true, width: '120px' },
|
|
129
|
+
{
|
|
130
|
+
key: 'status',
|
|
131
|
+
label: 'Status',
|
|
132
|
+
sortable: true,
|
|
133
|
+
width: '120px',
|
|
134
|
+
render: (row) => `<span class="demo-badge">${String(row['status'] ?? '')}</span>`
|
|
135
|
+
}
|
|
136
|
+
];
|
|
137
|
+
|
|
138
|
+
config: DynamicDataTableConfig = {
|
|
139
|
+
title: 'Users',
|
|
140
|
+
features: {
|
|
141
|
+
export: true,
|
|
142
|
+
sorting: true,
|
|
143
|
+
searching: true,
|
|
144
|
+
pagination: true,
|
|
145
|
+
rowsPerPage: true,
|
|
146
|
+
actions: true,
|
|
147
|
+
checkboxSelection: true
|
|
148
|
+
},
|
|
149
|
+
rowsPerPageOptions: [5, 10, 25],
|
|
150
|
+
defaultRowsPerPage: 10,
|
|
151
|
+
exportOptions: {
|
|
152
|
+
fileName: 'users-export',
|
|
153
|
+
formats: ['csv', 'excel']
|
|
154
|
+
},
|
|
155
|
+
actions: [
|
|
156
|
+
{ label: 'Details', icon: 'bi bi-eye', id: 'details' },
|
|
157
|
+
{ label: 'Archive', icon: 'bi bi-archive', id: 'archive' },
|
|
158
|
+
{ label: 'Delete', icon: 'bi bi-trash', id: 'delete', danger: true }
|
|
159
|
+
]
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
onAction(event: DataTableActionEvent): void {
|
|
163
|
+
console.log('Action event:', event);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
onSelection(rows: unknown[]): void {
|
|
167
|
+
console.log('Selected rows:', rows);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
onSort(event: { key: string | null; direction: 'asc' | 'desc' }): void {
|
|
171
|
+
console.log('Sort changed:', event);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
onPage(page: number): void {
|
|
175
|
+
console.log('Page changed:', page);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
onExport(event: unknown): void {
|
|
179
|
+
console.log('Export triggered:', event);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Global Styles For Custom Rendered HTML
|
|
185
|
+
|
|
186
|
+
If you use the `render` function in a column, it returns an HTML string.
|
|
187
|
+
Those styles should usually be defined in your app's global stylesheet, for example `src/styles.css`.
|
|
188
|
+
|
|
189
|
+
Example:
|
|
190
|
+
|
|
191
|
+
```css
|
|
192
|
+
.demo-user {
|
|
193
|
+
display: flex;
|
|
194
|
+
align-items: center;
|
|
195
|
+
gap: 10px;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.demo-avatar {
|
|
199
|
+
width: 34px;
|
|
200
|
+
height: 34px;
|
|
201
|
+
border-radius: 999px;
|
|
202
|
+
display: grid;
|
|
203
|
+
place-items: center;
|
|
204
|
+
color: #fff;
|
|
205
|
+
background: linear-gradient(145deg, #4f46e5, #6d67ff);
|
|
206
|
+
font-size: 12px;
|
|
207
|
+
font-weight: 700;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.demo-name {
|
|
211
|
+
font-weight: 600;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.demo-subtitle {
|
|
215
|
+
font-size: 12px;
|
|
216
|
+
color: #6d7895;
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Inputs
|
|
221
|
+
|
|
222
|
+
### `config: DynamicDataTableConfig`
|
|
223
|
+
|
|
224
|
+
Main table configuration.
|
|
225
|
+
|
|
226
|
+
### `columns: DataTableColumn[]`
|
|
227
|
+
|
|
228
|
+
Column definitions for the table.
|
|
229
|
+
|
|
230
|
+
### `data: Record<string, unknown>[]`
|
|
231
|
+
|
|
232
|
+
Array of row objects.
|
|
233
|
+
|
|
234
|
+
## Outputs
|
|
235
|
+
|
|
236
|
+
### `actionSelected`
|
|
237
|
+
|
|
238
|
+
Triggered when a row action is clicked.
|
|
239
|
+
|
|
240
|
+
Type:
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
DataTableActionEvent<T>
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Shape:
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
{
|
|
250
|
+
action: DataTableAction<T>;
|
|
251
|
+
row: T;
|
|
252
|
+
rowIndex: number;
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### `selectionChange`
|
|
257
|
+
|
|
258
|
+
Triggered when selected rows change.
|
|
259
|
+
|
|
260
|
+
### `sortChange`
|
|
261
|
+
|
|
262
|
+
Triggered when sorting changes.
|
|
263
|
+
|
|
264
|
+
Shape:
|
|
265
|
+
|
|
266
|
+
```ts
|
|
267
|
+
{ key: string | null; direction: 'asc' | 'desc' }
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### `pageChange`
|
|
271
|
+
|
|
272
|
+
Triggered when the current page changes.
|
|
273
|
+
|
|
274
|
+
### `exportTriggered`
|
|
275
|
+
|
|
276
|
+
Triggered before CSV or Excel export is downloaded.
|
|
277
|
+
|
|
278
|
+
## Type Reference
|
|
279
|
+
|
|
280
|
+
### `DataTableColumn`
|
|
281
|
+
|
|
282
|
+
```ts
|
|
283
|
+
export interface DataTableColumn<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
284
|
+
key: keyof T | string;
|
|
285
|
+
label: string;
|
|
286
|
+
sortable?: boolean;
|
|
287
|
+
width?: string | number;
|
|
288
|
+
render?: (row: T) => string;
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### `DataTableAction`
|
|
293
|
+
|
|
294
|
+
```ts
|
|
295
|
+
export interface DataTableAction<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
296
|
+
label: string;
|
|
297
|
+
icon?: string;
|
|
298
|
+
danger?: boolean;
|
|
299
|
+
id?: string;
|
|
92
300
|
}
|
|
93
301
|
```
|
|
94
302
|
|
|
95
|
-
|
|
303
|
+
### `DynamicDataTableConfig`
|
|
96
304
|
|
|
97
|
-
|
|
305
|
+
```ts
|
|
306
|
+
export interface DynamicDataTableConfig<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
307
|
+
title?: string;
|
|
308
|
+
features?: {
|
|
309
|
+
export?: boolean;
|
|
310
|
+
sorting?: boolean;
|
|
311
|
+
searching?: boolean;
|
|
312
|
+
pagination?: boolean;
|
|
313
|
+
rowsPerPage?: boolean;
|
|
314
|
+
actions?: boolean;
|
|
315
|
+
checkboxSelection?: boolean;
|
|
316
|
+
};
|
|
317
|
+
rowsPerPageOptions?: number[];
|
|
318
|
+
defaultRowsPerPage?: number;
|
|
319
|
+
exportOptions?: {
|
|
320
|
+
fileName?: string;
|
|
321
|
+
formats?: ('csv' | 'excel')[];
|
|
322
|
+
};
|
|
323
|
+
columns?: DataTableColumn<T>[];
|
|
324
|
+
actions?: DataTableAction<T>[];
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## Public Methods
|
|
98
329
|
|
|
99
|
-
|
|
100
|
-
- `columns: DataTableColumn[]`
|
|
101
|
-
- `data: Record<string, unknown>[]`
|
|
330
|
+
You can access the component instance with `@ViewChild`.
|
|
102
331
|
|
|
103
|
-
|
|
332
|
+
```ts
|
|
333
|
+
import { ViewChild } from '@angular/core';
|
|
334
|
+
import { DynamicDatatableComponent } from 'ng-dynamic-datatable';
|
|
104
335
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
- `pageChange`
|
|
109
|
-
- `exportTriggered`
|
|
336
|
+
@ViewChild(DynamicDatatableComponent)
|
|
337
|
+
private table?: DynamicDatatableComponent;
|
|
338
|
+
```
|
|
110
339
|
|
|
111
|
-
|
|
340
|
+
Available methods:
|
|
112
341
|
|
|
113
342
|
- `refresh()`
|
|
114
343
|
- `updateData(newData)`
|
|
@@ -116,19 +345,138 @@ Public methods:
|
|
|
116
345
|
- `getSelectedRows()`
|
|
117
346
|
- `clearSelection()`
|
|
118
347
|
|
|
119
|
-
|
|
348
|
+
Example:
|
|
349
|
+
|
|
350
|
+
```ts
|
|
351
|
+
reloadData(): void {
|
|
352
|
+
this.table?.updateData([
|
|
353
|
+
{ id: 1, name: 'Updated User' }
|
|
354
|
+
]);
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Local Development
|
|
359
|
+
|
|
360
|
+
### 1. Install workspace dependencies
|
|
361
|
+
|
|
362
|
+
From the workspace root:
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
npm install
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
If your workspace contains a separate Angular demo app, install its dependencies too.
|
|
369
|
+
|
|
370
|
+
### 2. Build the library
|
|
371
|
+
|
|
372
|
+
From the workspace root:
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
npx ng build dynamic-datatable
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Build output is generated in:
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
dist/dynamic-datatable
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### 3. Test inside a consumer Angular app
|
|
385
|
+
|
|
386
|
+
In a separate Angular app:
|
|
387
|
+
|
|
388
|
+
```bash
|
|
389
|
+
npm install ng-dynamic-datatable@latest
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
Then build the app:
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
npm run build
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
## Publishing A New Version
|
|
399
|
+
|
|
400
|
+
### 1. Update version
|
|
401
|
+
|
|
402
|
+
Update the version in:
|
|
120
403
|
|
|
121
404
|
```bash
|
|
122
|
-
|
|
405
|
+
projects/dynamic-datatable/package.json
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
Example:
|
|
409
|
+
|
|
410
|
+
```json
|
|
411
|
+
{
|
|
412
|
+
"version": "0.0.7"
|
|
413
|
+
}
|
|
123
414
|
```
|
|
124
415
|
|
|
125
|
-
|
|
416
|
+
### 2. Build the library
|
|
126
417
|
|
|
127
|
-
|
|
418
|
+
```bash
|
|
419
|
+
npx ng build dynamic-datatable
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### 3. Publish from the dist package
|
|
128
423
|
|
|
129
424
|
```bash
|
|
130
425
|
cd dist/dynamic-datatable
|
|
131
426
|
npm publish --access public
|
|
132
427
|
```
|
|
133
428
|
|
|
134
|
-
|
|
429
|
+
Important:
|
|
430
|
+
|
|
431
|
+
- Always publish from `dist/dynamic-datatable`
|
|
432
|
+
- Do not publish from the workspace root
|
|
433
|
+
- Make sure you are logged into npm
|
|
434
|
+
- Wait a few moments after publishing before installing the new version in another app
|
|
435
|
+
|
|
436
|
+
### 4. Upgrade a consuming Angular app
|
|
437
|
+
|
|
438
|
+
```bash
|
|
439
|
+
npm install ng-dynamic-datatable@latest
|
|
440
|
+
npm run build
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
If npm does not find the new version immediately, wait briefly and retry.
|
|
444
|
+
|
|
445
|
+
## Troubleshooting
|
|
446
|
+
|
|
447
|
+
### Icons are not showing
|
|
448
|
+
|
|
449
|
+
Install and include `bootstrap-icons` in your app styles.
|
|
450
|
+
|
|
451
|
+
### Custom rendered HTML styles are not applied
|
|
452
|
+
|
|
453
|
+
Move those styles to the consuming app's global stylesheet.
|
|
454
|
+
|
|
455
|
+
### Sorting does not work as expected
|
|
456
|
+
|
|
457
|
+
Ensure the column has `sortable: true` and that values are consistently formatted.
|
|
458
|
+
|
|
459
|
+
### Action dropdown appears clipped
|
|
460
|
+
|
|
461
|
+
This usually depends on available space around the row and container overflow. Use the latest package version because menu positioning has been improved in recent patches.
|
|
462
|
+
|
|
463
|
+
## Build Command
|
|
464
|
+
|
|
465
|
+
```bash
|
|
466
|
+
npx ng build dynamic-datatable
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
## Exported API
|
|
470
|
+
|
|
471
|
+
This package exports:
|
|
472
|
+
|
|
473
|
+
- `DynamicDatatableComponent`
|
|
474
|
+
- `DataTableColumn`
|
|
475
|
+
- `DataTableAction`
|
|
476
|
+
- `DynamicDataTableConfig`
|
|
477
|
+
- `DataTableActionEvent`
|
|
478
|
+
- `DataTableExportEvent`
|
|
479
|
+
|
|
480
|
+
## License
|
|
481
|
+
|
|
482
|
+
MIT
|
|
@@ -182,9 +182,14 @@ class DynamicDatatableComponent {
|
|
|
182
182
|
if (!this.pagedRows.length) {
|
|
183
183
|
return false;
|
|
184
184
|
}
|
|
185
|
-
|
|
185
|
+
if (this.pagedRows.length === 1) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
if (this.pagedRows.length <= 3) {
|
|
189
|
+
return rowIndex === this.pagedRows.length - 1;
|
|
190
|
+
}
|
|
186
191
|
const isNearBottom = rowIndex >= this.pagedRows.length - 2;
|
|
187
|
-
return
|
|
192
|
+
return isNearBottom;
|
|
188
193
|
}
|
|
189
194
|
onActionItemClick(actionIndex, row, event) {
|
|
190
195
|
event.preventDefault();
|
|
@@ -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, 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 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.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 toggleActionMenu(rowId: string, event: Event): void {\r\n event.stopPropagation();\r\n this.openActionMenuRowId = this.openActionMenuRowId === rowId ? null : rowId;\r\n }\r\n\r\n closeActionMenu(): void {\r\n this.openActionMenuRowId = null;\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 shouldOpenActionUp(rowIndex: number): boolean {\r\n if (!this.pagedRows.length) {\r\n return false;\r\n }\r\n\r\n const isShortList = this.pagedRows.length <= 3;\r\n const isNearBottom = rowIndex >= this.pagedRows.length - 2;\r\n return isShortList || isNearBottom;\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 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.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; let rowIndex = index\" [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\" [class.ndt-dropup]=\"shouldOpenActionUp(rowIndex)\" (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 class=\"ndt-dropdown-menu\" *ngIf=\"isActionMenuOpen(row.id)\">\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/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, 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 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.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 toggleActionMenu(rowId: string, event: Event): void {\r\n event.stopPropagation();\r\n this.openActionMenuRowId = this.openActionMenuRowId === rowId ? null : rowId;\r\n }\r\n\r\n closeActionMenu(): void {\r\n this.openActionMenuRowId = null;\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 shouldOpenActionUp(rowIndex: number): boolean {\r\n if (!this.pagedRows.length) {\r\n return false;\r\n }\r\n\r\n if (this.pagedRows.length === 1) {\r\n return false;\r\n }\r\n\r\n if (this.pagedRows.length <= 3) {\r\n return rowIndex === this.pagedRows.length - 1;\r\n }\r\n\r\n const isNearBottom = rowIndex >= this.pagedRows.length - 2;\r\n return isNearBottom;\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 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.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; let rowIndex = index\" [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\" [class.ndt-dropup]=\"shouldOpenActionUp(rowIndex)\" (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 class=\"ndt-dropdown-menu\" *ngIf=\"isActionMenuOpen(row.id)\">\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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"}
|