cats-data-grid 2.0.82 → 2.0.84

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,63 +1,495 @@
1
- # CatsDataGrid
1
+ # Cats Data Grid
2
2
 
3
- This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.3.15.
3
+ Cats Data Grid is an Angular library for showing tabular and hierarchical data.
4
+ It provides two standalone components:
4
5
 
5
- ## Code scaffolding
6
+ - `CatsDataGridComponent` for normal flat tables.
7
+ - `CommonTreeTableComponent` for tree or parent-child tables.
6
8
 
7
- Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
9
+ The library supports sorting, filtering, pagination, row selection, column
10
+ settings, column pinning, grouping, editable cells, skeleton loading, and custom
11
+ cell renderers.
12
+
13
+ ## Requirements
14
+
15
+ - Angular `>=18 <22`
16
+ - `@angular/core`
17
+ - `@angular/common`
18
+
19
+ ## Install
8
20
 
9
21
  ```bash
10
- ng generate component component-name
22
+ npm install cats-data-grid
11
23
  ```
12
24
 
13
- For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
25
+ If you are using this library from the local workspace, build it first:
14
26
 
15
27
  ```bash
16
- ng generate --help
28
+ ng build cats-data-grid
17
29
  ```
18
30
 
19
- ## Building
31
+ ## Configure Assets And Styles
20
32
 
21
- To build the library, run:
33
+ Add the library assets and styles to your application's `angular.json`.
22
34
 
23
- ```bash
24
- ng build cats-data-grid
35
+ For an installed npm package:
36
+
37
+ ```json
38
+ {
39
+ "assets": [
40
+ {
41
+ "glob": "**/*",
42
+ "input": "node_modules/cats-data-grid/assets"
43
+ }
44
+ ],
45
+ "styles": ["node_modules/cats-data-grid/styles/_index.scss"]
46
+ }
25
47
  ```
26
48
 
27
- This command will compile your project, and the build artifacts will be placed in the `dist/` directory.
49
+ ## Import In Angular
28
50
 
29
- ### Publishing the Library
51
+ The components are standalone, so import them in the component where you use
52
+ them.
30
53
 
31
- Once the project is built, you can publish your library by following these steps:
54
+ ```ts
55
+ import { Component } from "@angular/core";
56
+ import { CatsDataGridComponent, CommonRendererComponent } from "cats-data-grid";
32
57
 
33
- 1. Navigate to the `dist` directory:
34
- ```bash
35
- cd dist/cats-data-grid
36
- ```
58
+ @Component({
59
+ selector: "app-users",
60
+ standalone: true,
61
+ imports: [CatsDataGridComponent],
62
+ templateUrl: "./users.component.html",
63
+ })
64
+ export class UsersComponent {
65
+ // Component code shown below.
66
+ }
67
+ ```
37
68
 
38
- 2. Run the `npm publish` command to publish your library to the npm registry:
39
- ```bash
40
- npm publish
41
- ```
69
+ ## Basic Data Grid
42
70
 
43
- ## Running unit tests
71
+ ### Template
44
72
 
45
- To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
73
+ ```html
74
+ <cats-data-grid [rowData]="rowData" [colDefs]="colDefs" [totalRecords]="totalRecords" [paginationRequired]="true" [sortingRequired]="true" [filterRequired]="true" [checkBoxSelection]="true" [checkboxSelectionType]="'multiple'" [settingsRequired]="true" [threeDotsMenuRequired]="true" [pageSizeList]="[10, 20, 50]" [pageNumber]="pageNumber" [pageSize]="pageSize" [rowId]="'id'" (onPaginationChange)="onPaginationChange($event)" (onCheckboxSelection)="onCheckboxSelection($event)" (onRowClicked)="onRowClicked($event)" (onCellClicked)="onCellClicked($event)" (onCellEdit)="onCellEdit($event)" (onColConfigChange)="onColConfigChange($event)"></cats-data-grid>
75
+ ```
46
76
 
47
- ```bash
48
- ng test
77
+ ### Component
78
+
79
+ ```ts
80
+ import { Component } from "@angular/core";
81
+ import { CatsDataGridComponent, CommonRendererComponent } from "cats-data-grid";
82
+
83
+ @Component({
84
+ selector: "app-users",
85
+ standalone: true,
86
+ imports: [CatsDataGridComponent],
87
+ templateUrl: "./users.component.html",
88
+ })
89
+ export class UsersComponent {
90
+ pageNumber = 0;
91
+ pageSize = 20;
92
+ totalRecords = 3;
93
+
94
+ colDefs = [
95
+ {
96
+ headerName: "ID",
97
+ fieldName: "id",
98
+ width: 100,
99
+ filterType: "number",
100
+ headerLocked: true,
101
+ },
102
+ {
103
+ headerName: "Name",
104
+ fieldName: "name",
105
+ width: 200,
106
+ filterType: "text",
107
+ editable: true,
108
+ },
109
+ {
110
+ headerName: "Status",
111
+ fieldName: "status",
112
+ width: 160,
113
+ filterType: "set",
114
+ cellRenderer: CommonRendererComponent,
115
+ cellRendererParams: {
116
+ type: "tag",
117
+ },
118
+ },
119
+ {
120
+ headerName: "Action",
121
+ fieldName: "action",
122
+ width: 90,
123
+ filterable: false,
124
+ columnAction: false,
125
+ isAction: true,
126
+ cellRenderer: CommonRendererComponent,
127
+ cellRendererParams: {
128
+ type: "action-menu",
129
+ actions: [
130
+ { label: "View", value: "view", image: "images/eye.svg" },
131
+ { label: "Edit", value: "edit", image: "images/edit.svg" },
132
+ ],
133
+ onAction: (event: any) => this.onAction(event),
134
+ },
135
+ },
136
+ ];
137
+
138
+ rowData = [
139
+ { id: 1, name: "Aarav", status: ["Active"] },
140
+ { id: 2, name: "Diya", status: ["Pending"] },
141
+ { id: 3, name: "Kabir", status: ["Inactive"] },
142
+ ];
143
+
144
+ onPaginationChange(event: { page: number; pageSize: number }): void {
145
+ this.pageNumber = event.page;
146
+ this.pageSize = event.pageSize;
147
+ // Call your API here when using server-side pagination.
148
+ }
149
+
150
+ onCheckboxSelection(selectedRows: any[]): void {
151
+ console.log("Selected rows", selectedRows);
152
+ }
153
+
154
+ onRowClicked(event: any): void {
155
+ console.log("Row clicked", event.row);
156
+ }
157
+
158
+ onCellClicked(event: any): void {
159
+ console.log("Cell clicked", event.row, event.col);
160
+ }
161
+
162
+ onCellEdit(event: any): void {
163
+ console.log("Cell edited", event);
164
+ }
165
+
166
+ onColConfigChange(activeFields: string[]): void {
167
+ console.log("Visible columns", activeFields);
168
+ }
169
+
170
+ onAction(event: any): void {
171
+ console.log("Action clicked", event);
172
+ }
173
+ }
49
174
  ```
50
175
 
51
- ## Running end-to-end tests
176
+ ## Column Definition
52
177
 
53
- For end-to-end (e2e) testing, run:
178
+ Use `colDefs` to configure table columns.
54
179
 
55
- ```bash
56
- ng e2e
180
+ | Property | Type | Description |
181
+ | -------------------- | --------------------------------------- | ---------------------------------------------------------------------- |
182
+ | `headerName` | `string` | Column title shown in the header. |
183
+ | `fieldName` | `string` | Field to read from row data. Dot paths like `user.name` are supported. |
184
+ | `width` | `number` | Column width in pixels. |
185
+ | `minWidth` | `number` | Minimum column width in pixels. |
186
+ | `maxWidth` | `number` | Maximum column width in pixels. |
187
+ | `filterType` | `'text' \| 'number' \| 'date' \| 'set'` | Type of filter to show. |
188
+ | `sortable` | `boolean` | Enables or disables sorting for this column. |
189
+ | `filterable` | `boolean` | Enables or disables filtering for this column. |
190
+ | `active` | `boolean` | Shows or hides the column initially. |
191
+ | `headerLocked` | `boolean` | Keeps the column visible in column settings. |
192
+ | `editable` | `boolean` | Allows cell editing on double click. |
193
+ | `category` | `string` | Groups columns inside the column settings panel. |
194
+ | `disableGrouping` | `boolean` | Prevents this column from being used in grouping. |
195
+ | `cellRenderer` | `any` | Angular component or function used to render the cell. |
196
+ | `cellRendererParams` | `object` | Extra configuration passed to the renderer. |
197
+ | `isAction` | `boolean` | Marks the column as a sticky action column. |
198
+ | `columnAction` | `boolean` | Shows or hides the column menu for this column. |
199
+
200
+ ## Data Grid Inputs
201
+
202
+ | Input | Type | Default | Description |
203
+ | -------------------------- | ---------------- | ------------------- | -------------------------------------------------------------- |
204
+ | `rowData` | `any[]` | `[]` | Rows displayed in the grid. Required. |
205
+ | `colDefs` | `any[]` | `[]` | Column definitions. Required. |
206
+ | `tableOptions` | `any` | - | Extra options, such as custom row classes or no-data template. |
207
+ | `totalRecords` | `number` | `0` | Total record count for pagination. |
208
+ | `sortingRequired` | `boolean` | `true` | Enables sorting. |
209
+ | `filterRequired` | `boolean` | `true` | Enables filtering. |
210
+ | `paginationRequired` | `boolean` | `true` | Shows pagination. |
211
+ | `checkBoxSelection` | `boolean` | `false` | Shows row checkboxes. |
212
+ | `checkboxSelectionType` | `string` | `'multiple'` | Use `'single'` or `'multiple'`. |
213
+ | `settingsRequired` | `boolean` | `true` | Enables column settings. |
214
+ | `settingsClicked` | `boolean` | `false` | Opens or closes the settings panel from parent component. |
215
+ | `threeDotsMenuRequired` | `boolean` | `true` | Shows the column action menu. |
216
+ | `groupByRequired` | `boolean` | `false` | Enables grouping UI. |
217
+ | `groupByField` | `string` | `''` | Applies an initial group field. |
218
+ | `dynamicGroupingFiltering` | `boolean` | `false` | Emits grouping/filter events for server-side handling. |
219
+ | `appliedFilters` | `ColumnFilter[]` | `[]` | Pre-applied filters. |
220
+ | `pageSizeList` | `number[]` | `[20, 50, 75, 100]` | Page size options. |
221
+ | `pageNumber` | `number` | - | Current page number. |
222
+ | `pageSize` | `number` | - | Current page size. |
223
+ | `resetPage` | `boolean` | `true` | Resets page when total records change. |
224
+ | `rowId` | `string` | `null` | Unique row id field. |
225
+ | `rowGripFieldName` | `string` | - | Field used for row drag grip. |
226
+ | `bigRows` | `boolean` | `false` | Uses larger row height. |
227
+ | `height` | `number` | `400` | Grid height in pixels. |
228
+ | `isRowsEditable` | `boolean` | `false` | Enables row edit behavior. |
229
+ | `showSkeleton` | `boolean` | `false` | Shows skeleton loading rows. |
230
+ | `skeletonRowsLength` | `number` | `8` | Number of skeleton rows. |
231
+ | `skeletonColsLength` | `number` | `8` | Number of skeleton columns. |
232
+
233
+ ## Data Grid Events
234
+
235
+ | Event | Payload | Description |
236
+ | --------------------- | ---------------------------- | ------------------------------------------- |
237
+ | `onPaginationChange` | `{ page, pageSize }` | Emits when page or page size changes. |
238
+ | `onCheckboxSelection` | `any[]` | Emits selected rows. |
239
+ | `onRowClicked` | `{ row }` | Emits when a row is clicked. |
240
+ | `onCellClicked` | `{ row, col }` | Emits when a cell is clicked. |
241
+ | `onCellEdit` | `{ row, col, changedValue }` | Emits after editable cell value changes. |
242
+ | `onColConfigChange` | `string[]` | Emits visible column field names. |
243
+ | `appliedFiltersEvent` | `ColumnFilter[]` | Emits applied filters. |
244
+ | `activeGroupsEvent` | `string[]` | Emits active group fields. |
245
+ | `onScrollEmitter` | `void` | Emits when the table reaches bottom scroll. |
246
+ | `filter` | `any` | Emits filtered data/filter changes. |
247
+ | `onHideSettings` | `boolean` | Emits when settings panel is hidden. |
248
+
249
+ ## Built-In Cell Renderers
250
+
251
+ Import `CommonRendererComponent` and use it in `cellRenderer`.
252
+
253
+ ### Tag
254
+
255
+ ```ts
256
+ {
257
+ headerName: 'Status',
258
+ fieldName: 'status',
259
+ filterType: 'set',
260
+ cellRenderer: CommonRendererComponent,
261
+ cellRendererParams: {
262
+ type: 'tag',
263
+ tagKey: 'name',
264
+ class: 'active',
265
+ },
266
+ }
267
+ ```
268
+
269
+ ### Link
270
+
271
+ ```ts
272
+ {
273
+ headerName: 'Customer',
274
+ fieldName: 'customer.name',
275
+ cellRenderer: CommonRendererComponent,
276
+ cellRendererParams: {
277
+ type: 'link',
278
+ onLinkClick: (event: any) => this.onCustomerClick(event),
279
+ },
280
+ }
281
+ ```
282
+
283
+ ### Switch
284
+
285
+ ```ts
286
+ {
287
+ headerName: 'Enabled',
288
+ fieldName: 'enabled',
289
+ cellRenderer: CommonRendererComponent,
290
+ cellRendererParams: {
291
+ type: 'switch',
292
+ onToggle: (event: any) => this.onStatusToggle(event),
293
+ },
294
+ }
295
+ ```
296
+
297
+ ### Action Menu
298
+
299
+ ```ts
300
+ {
301
+ headerName: 'Action',
302
+ fieldName: 'action',
303
+ filterable: false,
304
+ columnAction: false,
305
+ isAction: true,
306
+ cellRenderer: CommonRendererComponent,
307
+ cellRendererParams: {
308
+ type: 'action-menu',
309
+ actions: [
310
+ { label: 'View', value: 'view', image: 'images/eye.svg' },
311
+ { label: 'Delete', value: 'delete', image: 'images/trash.svg' },
312
+ ],
313
+ onAction: (event: any) => this.onAction(event),
314
+ },
315
+ }
316
+ ```
317
+
318
+ ## Tree Table
319
+
320
+ Use `cats-tree-table` when your data has children or nested rows.
321
+
322
+ ### Import
323
+
324
+ ```ts
325
+ import { Component } from "@angular/core";
326
+ import { CatsTreeExpandEvent, CatsTreeSelectionChangeEvent, CatsTreeTableColumn, CommonTreeTableComponent } from "cats-data-grid";
327
+
328
+ @Component({
329
+ selector: "app-tree-demo",
330
+ standalone: true,
331
+ imports: [CommonTreeTableComponent],
332
+ templateUrl: "./tree-demo.component.html",
333
+ })
334
+ export class TreeDemoComponent {
335
+ // Component code shown below.
336
+ }
337
+ ```
338
+
339
+ ### Template
340
+
341
+ ```html
342
+ <cats-tree-table [data]="treeData" [columns]="columns" childrenField="children" labelField="name" [showCheckbox]="true" [sortingRequired]="true" [filterRequired]="true" [paginationRequired]="true" [totalRecords]="treeData.length" [pageSizeList]="[10, 20, 50]" [expandAllNodes]="false" [isExpandable]="isExpandable" [rowOptionsResolver]="rowOptionsResolver" [nodeIconResolver]="nodeIconResolver" [linkResolver]="linkResolver" (nodeToggle)="onNodeToggle($event)" (selectionChange)="onSelectionChange($event)" (linkClick)="onLinkClick($event)" (linkDoubleClick)="onLinkDoubleClick($event)"></cats-tree-table>
343
+ ```
344
+
345
+ ### Component
346
+
347
+ ```ts
348
+ columns: CatsTreeTableColumn[] = [
349
+ { fieldName: 'name', header: 'Name', width: 260, filterType: 'text' },
350
+ { fieldName: 'type', header: 'Type', width: 140, filterType: 'set' },
351
+ { fieldName: 'owner', header: 'Owner', width: 180, filterType: 'text' },
352
+ ];
353
+
354
+ treeData = [
355
+ {
356
+ id: 1,
357
+ name: 'Network',
358
+ type: 'group',
359
+ owner: 'Admin',
360
+ children: [
361
+ { id: 11, name: 'Router Template', type: 'template', owner: 'NOC' },
362
+ { id: 12, name: 'Switch Template', type: 'template', owner: 'NOC' },
363
+ ],
364
+ },
365
+ ];
366
+
367
+ isExpandable = (node: any): boolean => {
368
+ return Array.isArray(node.children) && node.children.length > 0;
369
+ };
370
+
371
+ rowOptionsResolver = (node: any) => {
372
+ if (node.type === 'template') {
373
+ return { showCheckbox: false, showLink: true, showNodeIcon: true };
374
+ }
375
+
376
+ return { showCheckbox: true, showNodeIcon: true };
377
+ };
378
+
379
+ nodeIconResolver = (node: any, level: number, path: any[], expanded: boolean) => {
380
+ if (node.type === 'group') {
381
+ return expanded ? 'folder-minus.svg' : 'folder-plus.svg';
382
+ }
383
+
384
+ return 'file-text.svg';
385
+ };
386
+
387
+ linkResolver = (node: any): string | null => {
388
+ return node.type === 'template' ? `/templates/${node.id}` : null;
389
+ };
390
+
391
+ onNodeToggle(event: CatsTreeExpandEvent<any>): void {
392
+ console.log('Node toggled', event);
393
+ }
394
+
395
+ onSelectionChange(event: CatsTreeSelectionChangeEvent<any>): void {
396
+ console.log('Selection changed', event.selectedNodes);
397
+ }
398
+
399
+ onLinkClick(event: any): void {
400
+ console.log('Link clicked', event);
401
+ }
402
+
403
+ onLinkDoubleClick(event: any): void {
404
+ console.log('Link double clicked', event);
405
+ }
57
406
  ```
58
407
 
59
- Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
408
+ ## Tree Table Inputs
409
+
410
+ | Input | Type | Default | Description |
411
+ | -------------------------- | ----------------------- | ----------------------------------------- | ------------------------------------------------------------------ |
412
+ | `data` | `any[]` | `[]` | Root nodes for the tree. |
413
+ | `columns` | `CatsTreeTableColumn[]` | `[{ fieldName: 'name', header: 'Name' }]` | Tree table columns. |
414
+ | `idField` | `string` | `'id'` | Unique id field. |
415
+ | `labelField` | `string` | `'name'` | Field displayed as the tree label. |
416
+ | `childrenField` | `string` | `'array'` | Field containing child nodes. |
417
+ | `treeColumnField` | `string` | - | Column used as the tree column. |
418
+ | `indentPx` | `number` | `24` | Indentation per tree level. |
419
+ | `showHeader` | `boolean` | `true` | Shows the header row. |
420
+ | `showCheckbox` | `boolean` | `false` | Shows node checkboxes. |
421
+ | `showNodeIcon` | `boolean` | `true` | Shows node icons. |
422
+ | `expandAllNodes` | `boolean` | `false` | Expands all nodes. |
423
+ | `expandAllControlRequired` | `boolean` | `true` | Shows expand-all control. |
424
+ | `isExpandable` | `function` | checks children | Controls whether a node can expand. |
425
+ | `rowOptionsResolver` | `function` | `{}` | Controls checkbox, toggle, icon, link, and disabled state per row. |
426
+ | `nodeIconResolver` | `function` | `null` | Returns an icon path or file name for each node. |
427
+ | `linkResolver` | `function` | `null` | Returns the URL used for link rows. |
428
+ | `iconBasePath` | `string` | `'images'` | Base folder for icon file names. |
429
+ | `sortingRequired` | `boolean` | `true` | Enables sorting. |
430
+ | `filterRequired` | `boolean` | `false` | Enables filtering. |
431
+ | `paginationRequired` | `boolean` | `true` | Shows pagination. |
432
+ | `settingsRequired` | `boolean` | `true` | Enables column settings. |
433
+ | `threeDotsMenuRequired` | `boolean` | `true` | Shows column action menu. |
434
+ | `pageSizeList` | `number[]` | `[20, 50, 75, 100]` | Page size options. |
435
+ | `totalRecords` | `number` | `0` | Total records for pagination. |
436
+ | `showSkeleton` | `boolean` | `false` | Shows loading skeleton. |
437
+
438
+ ## Tree Table Events
439
+
440
+ | Event | Payload | Description |
441
+ | -------------------- | ----------------------------------------------- | --------------------------------------- |
442
+ | `nodeToggle` | `{ node, level, path, expanded }` | Emits when a node expands or collapses. |
443
+ | `selectionChange` | `{ node, level, path, checked, selectedNodes }` | Emits when tree selection changes. |
444
+ | `linkClick` | `{ node, level, path, url, col }` | Emits on link click. |
445
+ | `linkDoubleClick` | `{ node, level, path, url, col }` | Emits on link double click. |
446
+ | `onPaginationChange` | `{ page, pageSize }` | Emits when page changes. |
447
+ | `onColConfigChange` | `string[]` | Emits visible column field names. |
448
+ | `onHideSettings` | `boolean` | Emits when settings panel is hidden. |
449
+
450
+ ## Custom No Data Template
451
+
452
+ Pass a template from the parent component through `tableOptions`.
453
+
454
+ ```html
455
+ <cats-data-grid [rowData]="[]" [colDefs]="colDefs" [tableOptions]="tableOptions"></cats-data-grid>
456
+
457
+ <ng-template #noDataTemplate>
458
+ <div class="no-data">No records found</div>
459
+ </ng-template>
460
+ ```
461
+
462
+ ```ts
463
+ import { AfterViewInit, ViewChild } from "@angular/core";
464
+
465
+ export class UsersComponent implements AfterViewInit {
466
+ @ViewChild("noDataTemplate") noDataTemplate!: any;
467
+
468
+ tableOptions: any = {};
469
+
470
+ ngAfterViewInit(): void {
471
+ this.tableOptions.noDataTemplate = this.noDataTemplate;
472
+ }
473
+ }
474
+ ```
475
+
476
+ ## Common Usage Tips
477
+
478
+ - Use `rowId` for stable row selection and row drag behavior.
479
+ - Use dot notation in `fieldName` for nested object values.
480
+ - Use `filterType: 'set'` for columns with repeated predefined values.
481
+ - Use `dynamicGroupingFiltering` when grouping/filtering should be handled by an API.
482
+ - Use `showSkeleton` while data is loading.
483
+ - Use `active: false` to hide a column initially.
484
+ - Use `headerLocked: true` for columns that must always remain visible.
485
+
486
+ ## Build And Test
487
+
488
+ ```bash
489
+ ng build cats-data-grid
490
+ ng test cats-data-grid
491
+ ```
60
492
 
61
- ## Additional Resources
493
+ ## License
62
494
 
63
- For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
495
+ MIT