ng-dynamic-datatable 0.0.0 → 0.0.2
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 +109 -34
- package/fesm2022/ng-dynamic-datatable.mjs +483 -0
- package/fesm2022/ng-dynamic-datatable.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/dynamic-datatable.component.d.ts +83 -0
- package/lib/dynamic-datatable.types.d.ts +4 -0
- package/lib/models.d.ts +45 -0
- package/package.json +35 -38
- package/{projects/dynamic-datatable/src/public-api.ts → public-api.d.ts} +2 -6
- package/.editorconfig +0 -17
- package/.vscode/extensions.json +0 -4
- package/.vscode/launch.json +0 -20
- package/.vscode/tasks.json +0 -42
- package/angular.json +0 -44
- package/projects/dynamic-datatable/README.md +0 -134
- package/projects/dynamic-datatable/ng-package.json +0 -7
- package/projects/dynamic-datatable/package.json +0 -24
- package/projects/dynamic-datatable/src/lib/dynamic-datatable.component.html +0 -137
- package/projects/dynamic-datatable/src/lib/dynamic-datatable.component.scss +0 -237
- package/projects/dynamic-datatable/src/lib/dynamic-datatable.component.spec.ts +0 -23
- package/projects/dynamic-datatable/src/lib/dynamic-datatable.component.ts +0 -556
- package/projects/dynamic-datatable/src/lib/dynamic-datatable.service.spec.ts +0 -16
- package/projects/dynamic-datatable/src/lib/dynamic-datatable.service.ts +0 -9
- package/projects/dynamic-datatable/src/lib/dynamic-datatable.types.ts +0 -4
- package/projects/dynamic-datatable/src/lib/models.ts +0 -52
- package/projects/dynamic-datatable/tsconfig.lib.json +0 -15
- package/projects/dynamic-datatable/tsconfig.lib.prod.json +0 -11
- package/projects/dynamic-datatable/tsconfig.spec.json +0 -15
- package/tsconfig.json +0 -32
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
|
|
2
|
+
import { DataTableActionEvent, DataTableColumn, DataTableExportEvent, DynamicDataTableConfig } from './models';
|
|
3
|
+
import { InternalSortState } from './dynamic-datatable.types';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
type RowData = Record<string, unknown>;
|
|
6
|
+
interface InternalRow<T extends RowData = RowData> {
|
|
7
|
+
id: string;
|
|
8
|
+
data: T;
|
|
9
|
+
}
|
|
10
|
+
export declare class DynamicDatatableComponent implements OnChanges {
|
|
11
|
+
config: DynamicDataTableConfig;
|
|
12
|
+
columns: DataTableColumn<RowData>[];
|
|
13
|
+
data: RowData[];
|
|
14
|
+
readonly actionSelected: EventEmitter<DataTableActionEvent<RowData>>;
|
|
15
|
+
readonly selectionChange: EventEmitter<RowData[]>;
|
|
16
|
+
readonly sortChange: EventEmitter<InternalSortState>;
|
|
17
|
+
readonly pageChange: EventEmitter<number>;
|
|
18
|
+
readonly exportTriggered: EventEmitter<DataTableExportEvent<RowData>>;
|
|
19
|
+
mergedConfig: DynamicDataTableConfig<RowData>;
|
|
20
|
+
mergedColumns: DataTableColumn<RowData>[];
|
|
21
|
+
private allRows;
|
|
22
|
+
filteredRows: InternalRow<RowData>[];
|
|
23
|
+
pagedRows: InternalRow<RowData>[];
|
|
24
|
+
searchTerm: string;
|
|
25
|
+
currentPage: number;
|
|
26
|
+
rowsPerPage: number;
|
|
27
|
+
totalPages: number;
|
|
28
|
+
sortState: InternalSortState;
|
|
29
|
+
selectedRows: Set<string>;
|
|
30
|
+
openActionMenuRowId: string | null;
|
|
31
|
+
isExportMenuOpen: boolean;
|
|
32
|
+
ngOnChanges(_changes: SimpleChanges): void;
|
|
33
|
+
refresh(): void;
|
|
34
|
+
updateData(newData: RowData[]): void;
|
|
35
|
+
updateConfig(newConfig: DynamicDataTableConfig<RowData>): void;
|
|
36
|
+
getSelectedRows(): RowData[];
|
|
37
|
+
clearSelection(): void;
|
|
38
|
+
isFeatureOn(feature: keyof NonNullable<DynamicDataTableConfig['features']>): boolean;
|
|
39
|
+
isExportFormatEnabled(format: 'csv' | 'excel'): boolean;
|
|
40
|
+
onSearchInput(event: Event): void;
|
|
41
|
+
onRowsPerPageChange(event: Event): void;
|
|
42
|
+
toggleSort(column: DataTableColumn<RowData>): void;
|
|
43
|
+
getSortIconClass(columnKey: string): string;
|
|
44
|
+
isSortColumn(columnKey: string): boolean;
|
|
45
|
+
goToPage(page: number): void;
|
|
46
|
+
getPaginationPages(): number[];
|
|
47
|
+
isRowSelected(rowId: string): boolean;
|
|
48
|
+
toggleRowSelection(row: InternalRow<RowData>, event: Event): void;
|
|
49
|
+
toggleSelectAllCurrentPage(event: Event): void;
|
|
50
|
+
isCurrentPageFullySelected(): boolean;
|
|
51
|
+
toggleActionMenu(rowId: string, event: Event): void;
|
|
52
|
+
closeActionMenu(): void;
|
|
53
|
+
toggleExportMenu(event: Event): void;
|
|
54
|
+
isActionMenuOpen(rowId: string): boolean;
|
|
55
|
+
onActionItemClick(actionIndex: number, row: InternalRow<RowData>): void;
|
|
56
|
+
exportCSV(): void;
|
|
57
|
+
exportExcel(): void;
|
|
58
|
+
getRenderedCell(row: RowData, column: DataTableColumn<RowData>): string;
|
|
59
|
+
toColumnWidth(width: string | number | undefined): string;
|
|
60
|
+
getColumnCount(): number;
|
|
61
|
+
getStartEntry(): number;
|
|
62
|
+
getEndEntry(): number;
|
|
63
|
+
private applyConfig;
|
|
64
|
+
private normalizeRows;
|
|
65
|
+
private applyFiltersSortAndPagination;
|
|
66
|
+
private updatePagedRowsOnly;
|
|
67
|
+
private getCellTextValue;
|
|
68
|
+
private compareValues;
|
|
69
|
+
private parseStrictNumber;
|
|
70
|
+
private parseDateValue;
|
|
71
|
+
private getRowsForExport;
|
|
72
|
+
private getExportFileName;
|
|
73
|
+
private downloadFile;
|
|
74
|
+
private escapeCsv;
|
|
75
|
+
private stripHtml;
|
|
76
|
+
private escapeHtml;
|
|
77
|
+
private getInitialRowsPerPage;
|
|
78
|
+
private emitSelection;
|
|
79
|
+
closeMenus(): void;
|
|
80
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<DynamicDatatableComponent, never>;
|
|
81
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<DynamicDatatableComponent, "lib-dynamic-datatable", never, { "config": { "alias": "config"; "required": false; }; "columns": { "alias": "columns"; "required": false; }; "data": { "alias": "data"; "required": false; }; }, { "actionSelected": "actionSelected"; "selectionChange": "selectionChange"; "sortChange": "sortChange"; "pageChange": "pageChange"; "exportTriggered": "exportTriggered"; }, never, never, true, never>;
|
|
82
|
+
}
|
|
83
|
+
export {};
|
package/lib/models.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export type DataTableExportFormat = 'csv' | 'excel';
|
|
2
|
+
export interface DataTableFeatureConfig {
|
|
3
|
+
export?: boolean;
|
|
4
|
+
sorting?: boolean;
|
|
5
|
+
searching?: boolean;
|
|
6
|
+
pagination?: boolean;
|
|
7
|
+
rowsPerPage?: boolean;
|
|
8
|
+
actions?: boolean;
|
|
9
|
+
checkboxSelection?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface DataTableExportOptions {
|
|
12
|
+
fileName?: string;
|
|
13
|
+
formats?: DataTableExportFormat[];
|
|
14
|
+
}
|
|
15
|
+
export interface DataTableColumn<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
16
|
+
key: keyof T | string;
|
|
17
|
+
label: string;
|
|
18
|
+
sortable?: boolean;
|
|
19
|
+
width?: string | number;
|
|
20
|
+
render?: (row: T) => string;
|
|
21
|
+
}
|
|
22
|
+
export interface DataTableAction<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
23
|
+
label: string;
|
|
24
|
+
icon?: string;
|
|
25
|
+
danger?: boolean;
|
|
26
|
+
id?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface DynamicDataTableConfig<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
29
|
+
title?: string;
|
|
30
|
+
features?: DataTableFeatureConfig;
|
|
31
|
+
rowsPerPageOptions?: number[];
|
|
32
|
+
defaultRowsPerPage?: number;
|
|
33
|
+
exportOptions?: DataTableExportOptions;
|
|
34
|
+
columns?: DataTableColumn<T>[];
|
|
35
|
+
actions?: DataTableAction<T>[];
|
|
36
|
+
}
|
|
37
|
+
export interface DataTableActionEvent<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
38
|
+
action: DataTableAction<T>;
|
|
39
|
+
row: T;
|
|
40
|
+
rowIndex: number;
|
|
41
|
+
}
|
|
42
|
+
export interface DataTableExportEvent<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
43
|
+
format: DataTableExportFormat;
|
|
44
|
+
rows: T[];
|
|
45
|
+
}
|
package/package.json
CHANGED
|
@@ -1,38 +1,35 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "ng-dynamic-datatable",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"@angular/
|
|
18
|
-
"@angular/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"tslib": "^2.3.0"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"typescript": "~5.7.2"
|
|
37
|
-
}
|
|
38
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "ng-dynamic-datatable",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Config-driven Angular DataTable library with sorting, searching, pagination, selection, and export.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"angular",
|
|
7
|
+
"datatable",
|
|
8
|
+
"table",
|
|
9
|
+
"grid",
|
|
10
|
+
"sorting",
|
|
11
|
+
"pagination",
|
|
12
|
+
"search"
|
|
13
|
+
],
|
|
14
|
+
"author": "",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"peerDependencies": {
|
|
17
|
+
"@angular/common": "^19.2.0",
|
|
18
|
+
"@angular/core": "^19.2.0"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"tslib": "^2.3.0"
|
|
22
|
+
},
|
|
23
|
+
"sideEffects": false,
|
|
24
|
+
"module": "fesm2022/ng-dynamic-datatable.mjs",
|
|
25
|
+
"typings": "index.d.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
"./package.json": {
|
|
28
|
+
"default": "./package.json"
|
|
29
|
+
},
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./index.d.ts",
|
|
32
|
+
"default": "./fesm2022/ng-dynamic-datatable.mjs"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
package/.editorconfig
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# Editor configuration, see https://editorconfig.org
|
|
2
|
-
root = true
|
|
3
|
-
|
|
4
|
-
[*]
|
|
5
|
-
charset = utf-8
|
|
6
|
-
indent_style = space
|
|
7
|
-
indent_size = 2
|
|
8
|
-
insert_final_newline = true
|
|
9
|
-
trim_trailing_whitespace = true
|
|
10
|
-
|
|
11
|
-
[*.ts]
|
|
12
|
-
quote_type = single
|
|
13
|
-
ij_typescript_use_double_quotes = false
|
|
14
|
-
|
|
15
|
-
[*.md]
|
|
16
|
-
max_line_length = off
|
|
17
|
-
trim_trailing_whitespace = false
|
package/.vscode/extensions.json
DELETED
package/.vscode/launch.json
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
3
|
-
"version": "0.2.0",
|
|
4
|
-
"configurations": [
|
|
5
|
-
{
|
|
6
|
-
"name": "ng serve",
|
|
7
|
-
"type": "chrome",
|
|
8
|
-
"request": "launch",
|
|
9
|
-
"preLaunchTask": "npm: start",
|
|
10
|
-
"url": "http://localhost:4200/"
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
"name": "ng test",
|
|
14
|
-
"type": "chrome",
|
|
15
|
-
"request": "launch",
|
|
16
|
-
"preLaunchTask": "npm: test",
|
|
17
|
-
"url": "http://localhost:9876/debug.html"
|
|
18
|
-
}
|
|
19
|
-
]
|
|
20
|
-
}
|
package/.vscode/tasks.json
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
// For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
|
|
3
|
-
"version": "2.0.0",
|
|
4
|
-
"tasks": [
|
|
5
|
-
{
|
|
6
|
-
"type": "npm",
|
|
7
|
-
"script": "start",
|
|
8
|
-
"isBackground": true,
|
|
9
|
-
"problemMatcher": {
|
|
10
|
-
"owner": "typescript",
|
|
11
|
-
"pattern": "$tsc",
|
|
12
|
-
"background": {
|
|
13
|
-
"activeOnStart": true,
|
|
14
|
-
"beginsPattern": {
|
|
15
|
-
"regexp": "(.*?)"
|
|
16
|
-
},
|
|
17
|
-
"endsPattern": {
|
|
18
|
-
"regexp": "bundle generation complete"
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
"type": "npm",
|
|
25
|
-
"script": "test",
|
|
26
|
-
"isBackground": true,
|
|
27
|
-
"problemMatcher": {
|
|
28
|
-
"owner": "typescript",
|
|
29
|
-
"pattern": "$tsc",
|
|
30
|
-
"background": {
|
|
31
|
-
"activeOnStart": true,
|
|
32
|
-
"beginsPattern": {
|
|
33
|
-
"regexp": "(.*?)"
|
|
34
|
-
},
|
|
35
|
-
"endsPattern": {
|
|
36
|
-
"regexp": "bundle generation complete"
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
]
|
|
42
|
-
}
|
package/angular.json
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
|
3
|
-
"version": 1,
|
|
4
|
-
"cli": {
|
|
5
|
-
"packageManager": "npm",
|
|
6
|
-
"analytics": "b83209c5-de58-447d-b95e-ff75c77b7196"
|
|
7
|
-
},
|
|
8
|
-
"newProjectRoot": "projects",
|
|
9
|
-
"projects": {
|
|
10
|
-
"dynamic-datatable": {
|
|
11
|
-
"projectType": "library",
|
|
12
|
-
"root": "projects/dynamic-datatable",
|
|
13
|
-
"sourceRoot": "projects/dynamic-datatable/src",
|
|
14
|
-
"prefix": "lib",
|
|
15
|
-
"architect": {
|
|
16
|
-
"build": {
|
|
17
|
-
"builder": "@angular-devkit/build-angular:ng-packagr",
|
|
18
|
-
"options": {
|
|
19
|
-
"project": "projects/dynamic-datatable/ng-package.json"
|
|
20
|
-
},
|
|
21
|
-
"configurations": {
|
|
22
|
-
"production": {
|
|
23
|
-
"tsConfig": "projects/dynamic-datatable/tsconfig.lib.prod.json"
|
|
24
|
-
},
|
|
25
|
-
"development": {
|
|
26
|
-
"tsConfig": "projects/dynamic-datatable/tsconfig.lib.json"
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
"defaultConfiguration": "production"
|
|
30
|
-
},
|
|
31
|
-
"test": {
|
|
32
|
-
"builder": "@angular-devkit/build-angular:karma",
|
|
33
|
-
"options": {
|
|
34
|
-
"tsConfig": "projects/dynamic-datatable/tsconfig.spec.json",
|
|
35
|
-
"polyfills": [
|
|
36
|
-
"zone.js",
|
|
37
|
-
"zone.js/testing"
|
|
38
|
-
]
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
# dynamic-datatable
|
|
2
|
-
|
|
3
|
-
Config-driven Angular DataTable library that accepts columns, JSON data, and feature configuration.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- Dynamic columns and data inputs
|
|
8
|
-
- Sorting (column-wise)
|
|
9
|
-
- Searching across visible columns
|
|
10
|
-
- Pagination and rows-per-page selection
|
|
11
|
-
- Row selection and select-all
|
|
12
|
-
- Row action events
|
|
13
|
-
- CSV and Excel export
|
|
14
|
-
|
|
15
|
-
## Install
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npm install dynamic-datatable
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## Usage
|
|
22
|
-
|
|
23
|
-
Import the standalone component directly in your consuming component:
|
|
24
|
-
|
|
25
|
-
```ts
|
|
26
|
-
import { Component } from '@angular/core';
|
|
27
|
-
import {
|
|
28
|
-
DynamicDatatableComponent,
|
|
29
|
-
DynamicDataTableConfig,
|
|
30
|
-
DataTableColumn
|
|
31
|
-
} from 'dynamic-datatable';
|
|
32
|
-
|
|
33
|
-
@Component({
|
|
34
|
-
selector: 'app-users',
|
|
35
|
-
standalone: true,
|
|
36
|
-
imports: [DynamicDatatableComponent],
|
|
37
|
-
template: `
|
|
38
|
-
<lib-dynamic-datatable
|
|
39
|
-
[config]="config"
|
|
40
|
-
[columns]="columns"
|
|
41
|
-
[data]="rows"
|
|
42
|
-
(actionSelected)="onAction($event)"
|
|
43
|
-
(selectionChange)="onSelection($event)"
|
|
44
|
-
/>
|
|
45
|
-
`
|
|
46
|
-
})
|
|
47
|
-
export class UsersComponent {
|
|
48
|
-
rows = [
|
|
49
|
-
{ id: 1, name: 'Aarav Sharma', email: 'aarav.sharma@company.in', salary: '19366.53', status: 'Resigned' },
|
|
50
|
-
{ id: 2, name: 'Ananya Patel', email: 'ananya.patel@company.in', salary: '10745.32', status: 'Applied' }
|
|
51
|
-
];
|
|
52
|
-
|
|
53
|
-
columns: DataTableColumn[] = [
|
|
54
|
-
{ key: 'name', label: 'Name', sortable: true, width: '220px' },
|
|
55
|
-
{ key: 'email', label: 'Email', sortable: true, width: '260px' },
|
|
56
|
-
{ key: 'salary', label: 'Salary', sortable: true, width: '120px' },
|
|
57
|
-
{
|
|
58
|
-
key: 'status',
|
|
59
|
-
label: 'Status',
|
|
60
|
-
sortable: true,
|
|
61
|
-
render: (row) => `<span>${row['status']}</span>`
|
|
62
|
-
}
|
|
63
|
-
];
|
|
64
|
-
|
|
65
|
-
config: DynamicDataTableConfig = {
|
|
66
|
-
title: 'Users',
|
|
67
|
-
features: {
|
|
68
|
-
export: true,
|
|
69
|
-
sorting: true,
|
|
70
|
-
searching: true,
|
|
71
|
-
pagination: true,
|
|
72
|
-
rowsPerPage: true,
|
|
73
|
-
actions: true,
|
|
74
|
-
checkboxSelection: true
|
|
75
|
-
},
|
|
76
|
-
rowsPerPageOptions: [5, 10, 25],
|
|
77
|
-
defaultRowsPerPage: 10,
|
|
78
|
-
exportOptions: { fileName: 'users-export', formats: ['csv', 'excel'] },
|
|
79
|
-
actions: [
|
|
80
|
-
{ label: 'Details', id: 'details' },
|
|
81
|
-
{ label: 'Delete', id: 'delete', danger: true }
|
|
82
|
-
]
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
onAction(event: unknown): void {
|
|
86
|
-
console.log(event);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
onSelection(rows: unknown[]): void {
|
|
90
|
-
console.log(rows);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
## Component API
|
|
96
|
-
|
|
97
|
-
Inputs:
|
|
98
|
-
|
|
99
|
-
- `config: DynamicDataTableConfig`
|
|
100
|
-
- `columns: DataTableColumn[]`
|
|
101
|
-
- `data: Record<string, unknown>[]`
|
|
102
|
-
|
|
103
|
-
Outputs:
|
|
104
|
-
|
|
105
|
-
- `actionSelected`
|
|
106
|
-
- `selectionChange`
|
|
107
|
-
- `sortChange`
|
|
108
|
-
- `pageChange`
|
|
109
|
-
- `exportTriggered`
|
|
110
|
-
|
|
111
|
-
Public methods:
|
|
112
|
-
|
|
113
|
-
- `refresh()`
|
|
114
|
-
- `updateData(newData)`
|
|
115
|
-
- `updateConfig(newConfig)`
|
|
116
|
-
- `getSelectedRows()`
|
|
117
|
-
- `clearSelection()`
|
|
118
|
-
|
|
119
|
-
## Build
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
ng build dynamic-datatable
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
Artifacts are generated in `dist/dynamic-datatable`.
|
|
126
|
-
|
|
127
|
-
## Publish to npm
|
|
128
|
-
|
|
129
|
-
```bash
|
|
130
|
-
cd dist/dynamic-datatable
|
|
131
|
-
npm publish --access public
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
Before publishing, ensure the package name in `projects/dynamic-datatable/package.json` is unique on npm.
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dynamic-datatable",
|
|
3
|
-
"version": "0.0.1",
|
|
4
|
-
"description": "Config-driven Angular DataTable library with sorting, searching, pagination, selection, and export.",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"angular",
|
|
7
|
-
"datatable",
|
|
8
|
-
"table",
|
|
9
|
-
"grid",
|
|
10
|
-
"sorting",
|
|
11
|
-
"pagination",
|
|
12
|
-
"search"
|
|
13
|
-
],
|
|
14
|
-
"author": "",
|
|
15
|
-
"license": "MIT",
|
|
16
|
-
"peerDependencies": {
|
|
17
|
-
"@angular/common": "^19.2.0",
|
|
18
|
-
"@angular/core": "^19.2.0"
|
|
19
|
-
},
|
|
20
|
-
"dependencies": {
|
|
21
|
-
"tslib": "^2.3.0"
|
|
22
|
-
},
|
|
23
|
-
"sideEffects": false
|
|
24
|
-
}
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
<div class="ndt-card">
|
|
2
|
-
<div class="ndt-header">
|
|
3
|
-
<h3 class="ndt-title">{{ mergedConfig.title }}</h3>
|
|
4
|
-
</div>
|
|
5
|
-
|
|
6
|
-
<div class="ndt-toolbar">
|
|
7
|
-
<div class="ndt-left-tools">
|
|
8
|
-
<ng-container *ngIf="isFeatureOn('export')">
|
|
9
|
-
<button class="ndt-btn" type="button" (click)="exportCSV()" *ngIf="isExportFormatEnabled('csv')">
|
|
10
|
-
Export CSV
|
|
11
|
-
</button>
|
|
12
|
-
<button class="ndt-btn" type="button" (click)="exportExcel()" *ngIf="isExportFormatEnabled('excel')">
|
|
13
|
-
Export Excel
|
|
14
|
-
</button>
|
|
15
|
-
</ng-container>
|
|
16
|
-
|
|
17
|
-
<label class="ndt-inline-label" *ngIf="isFeatureOn('rowsPerPage') && isFeatureOn('pagination')">
|
|
18
|
-
Rows per page:
|
|
19
|
-
<select [value]="rowsPerPage" (change)="onRowsPerPageChange($event)">
|
|
20
|
-
<option *ngFor="let option of mergedConfig.rowsPerPageOptions || []" [value]="option">{{ option }}</option>
|
|
21
|
-
</select>
|
|
22
|
-
</label>
|
|
23
|
-
</div>
|
|
24
|
-
|
|
25
|
-
<div class="ndt-right-tools" *ngIf="isFeatureOn('searching')">
|
|
26
|
-
<input
|
|
27
|
-
type="search"
|
|
28
|
-
placeholder="Search records"
|
|
29
|
-
[value]="searchTerm"
|
|
30
|
-
(input)="onSearchInput($event)"
|
|
31
|
-
/>
|
|
32
|
-
</div>
|
|
33
|
-
</div>
|
|
34
|
-
|
|
35
|
-
<div class="ndt-table-wrap">
|
|
36
|
-
<table class="ndt-table">
|
|
37
|
-
<colgroup>
|
|
38
|
-
<col *ngIf="isFeatureOn('checkboxSelection')" style="width: 44px" />
|
|
39
|
-
<col *ngFor="let column of mergedColumns" [style.width]="toColumnWidth(column.width)" />
|
|
40
|
-
<col *ngIf="isFeatureOn('actions')" style="width: 78px" />
|
|
41
|
-
</colgroup>
|
|
42
|
-
|
|
43
|
-
<thead>
|
|
44
|
-
<tr>
|
|
45
|
-
<th *ngIf="isFeatureOn('checkboxSelection')">
|
|
46
|
-
<input
|
|
47
|
-
type="checkbox"
|
|
48
|
-
[checked]="isCurrentPageFullySelected()"
|
|
49
|
-
(change)="toggleSelectAllCurrentPage($event)"
|
|
50
|
-
/>
|
|
51
|
-
</th>
|
|
52
|
-
<th
|
|
53
|
-
*ngFor="let column of mergedColumns"
|
|
54
|
-
[class.ndt-sortable]="isFeatureOn('sorting') && !!column.sortable"
|
|
55
|
-
(click)="toggleSort(column)"
|
|
56
|
-
>
|
|
57
|
-
<span class="ndt-th-content">
|
|
58
|
-
<span class="ndt-th-label">{{ column.label }}</span>
|
|
59
|
-
<span class="ndt-sort-indicator" *ngIf="isFeatureOn('sorting') && column.sortable">
|
|
60
|
-
{{ getSortIndicator(column.key.toString()) }}
|
|
61
|
-
</span>
|
|
62
|
-
</span>
|
|
63
|
-
</th>
|
|
64
|
-
<th *ngIf="isFeatureOn('actions')">Actions</th>
|
|
65
|
-
</tr>
|
|
66
|
-
</thead>
|
|
67
|
-
|
|
68
|
-
<tbody>
|
|
69
|
-
<tr *ngIf="!pagedRows.length">
|
|
70
|
-
<td [attr.colspan]="getColumnCount()" class="ndt-empty">No records found.</td>
|
|
71
|
-
</tr>
|
|
72
|
-
|
|
73
|
-
<tr *ngFor="let row of pagedRows; let rowIndex = index" [class.ndt-selected]="isRowSelected(row.id)">
|
|
74
|
-
<td *ngIf="isFeatureOn('checkboxSelection')">
|
|
75
|
-
<input
|
|
76
|
-
type="checkbox"
|
|
77
|
-
[checked]="isRowSelected(row.id)"
|
|
78
|
-
(change)="toggleRowSelection(row, $event)"
|
|
79
|
-
/>
|
|
80
|
-
</td>
|
|
81
|
-
|
|
82
|
-
<td *ngFor="let column of mergedColumns" [innerHTML]="getRenderedCell(row.data, column)"></td>
|
|
83
|
-
|
|
84
|
-
<td *ngIf="isFeatureOn('actions')" class="ndt-actions-cell">
|
|
85
|
-
<div class="ndt-dropdown" (click)="$event.stopPropagation()">
|
|
86
|
-
<button
|
|
87
|
-
type="button"
|
|
88
|
-
class="ndt-actions-btn"
|
|
89
|
-
(click)="toggleActionMenu(row.id, $event)"
|
|
90
|
-
[attr.aria-expanded]="isActionMenuOpen(row.id)"
|
|
91
|
-
>
|
|
92
|
-
<span class="ndt-dots">...</span>
|
|
93
|
-
</button>
|
|
94
|
-
|
|
95
|
-
<ul class="ndt-dropdown-menu" *ngIf="isActionMenuOpen(row.id)">
|
|
96
|
-
<li *ngFor="let action of mergedConfig.actions || []; let i = index">
|
|
97
|
-
<button
|
|
98
|
-
type="button"
|
|
99
|
-
class="ndt-dropdown-item"
|
|
100
|
-
[class.ndt-danger]="!!action.danger"
|
|
101
|
-
(click)="onActionItemClick(i, row)"
|
|
102
|
-
>
|
|
103
|
-
<i *ngIf="action.icon" [class]="action.icon"></i>
|
|
104
|
-
<span>{{ action.label }}</span>
|
|
105
|
-
</button>
|
|
106
|
-
</li>
|
|
107
|
-
</ul>
|
|
108
|
-
</div>
|
|
109
|
-
</td>
|
|
110
|
-
</tr>
|
|
111
|
-
</tbody>
|
|
112
|
-
</table>
|
|
113
|
-
</div>
|
|
114
|
-
|
|
115
|
-
<div class="ndt-footer">
|
|
116
|
-
<div>
|
|
117
|
-
{{ selectedRows.size }} selected
|
|
118
|
-
</div>
|
|
119
|
-
|
|
120
|
-
<div>
|
|
121
|
-
Showing {{ getStartEntry() }} to {{ getEndEntry() }} of {{ filteredRows.length }} entries
|
|
122
|
-
</div>
|
|
123
|
-
|
|
124
|
-
<div class="ndt-pagination" *ngIf="isFeatureOn('pagination') && totalPages > 1">
|
|
125
|
-
<button type="button" (click)="goToPage(currentPage - 1)" [disabled]="currentPage <= 1">Prev</button>
|
|
126
|
-
<button
|
|
127
|
-
type="button"
|
|
128
|
-
*ngFor="let page of getPaginationPages()"
|
|
129
|
-
[class.active]="page === currentPage"
|
|
130
|
-
(click)="goToPage(page)"
|
|
131
|
-
>
|
|
132
|
-
{{ page }}
|
|
133
|
-
</button>
|
|
134
|
-
<button type="button" (click)="goToPage(currentPage + 1)" [disabled]="currentPage >= totalPages">Next</button>
|
|
135
|
-
</div>
|
|
136
|
-
</div>
|
|
137
|
-
</div>
|