@visns-studio/visns-components 5.6.10 → 5.6.11
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 +476 -12
- package/package.json +1 -1
- package/src/components/crm/DataGrid.jsx +22 -0
package/README.md
CHANGED
|
@@ -191,12 +191,28 @@ A powerful data table component with sorting, filtering, and pagination.
|
|
|
191
191
|
params: {},
|
|
192
192
|
}}
|
|
193
193
|
columns={[
|
|
194
|
-
{
|
|
195
|
-
{
|
|
194
|
+
{ name: 'id', headerName: 'ID', width: 90 },
|
|
195
|
+
{ name: 'name', headerName: 'Name', width: 150 },
|
|
196
|
+
{
|
|
197
|
+
name: 'department',
|
|
198
|
+
headerName: 'Department',
|
|
199
|
+
width: 180,
|
|
200
|
+
groupSummaryReducer: 'count',
|
|
201
|
+
groupSummaryRenderer: (count) => `${count} employees`,
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
name: 'salary',
|
|
205
|
+
headerName: 'Salary',
|
|
206
|
+
width: 120,
|
|
207
|
+
type: 'number',
|
|
208
|
+
groupSummaryReducer: 'sum',
|
|
209
|
+
groupSummaryRenderer: (sum) => `$${sum.toLocaleString()}`,
|
|
210
|
+
},
|
|
196
211
|
// More columns...
|
|
197
212
|
]}
|
|
198
213
|
form={formConfig}
|
|
199
214
|
gridHeight={500}
|
|
215
|
+
defaultGroupBy={[{ name: 'department' }]}
|
|
200
216
|
settings={{
|
|
201
217
|
pagination: true,
|
|
202
218
|
pageSize: 25,
|
|
@@ -214,16 +230,26 @@ A powerful data table component with sorting, filtering, and pagination.
|
|
|
214
230
|
|
|
215
231
|
#### DataGrid Props
|
|
216
232
|
|
|
217
|
-
| Prop
|
|
218
|
-
|
|
|
219
|
-
| ajaxSetting
|
|
220
|
-
| columns
|
|
221
|
-
|
|
|
222
|
-
|
|
|
223
|
-
|
|
|
224
|
-
|
|
|
225
|
-
|
|
|
226
|
-
|
|
|
233
|
+
| Prop | Description | Type | Default |
|
|
234
|
+
| --------------------- | ------------------------------------------ | -------- | ------- |
|
|
235
|
+
| ajaxSetting | Configuration for data fetching | Object | - |
|
|
236
|
+
| columns | Column definitions | Array | - |
|
|
237
|
+
| defaultExpandedNodes | Initial expanded nodes for TreeGrid | Object | - |
|
|
238
|
+
| defaultGroupBy | Initial grouping configuration | Array | - |
|
|
239
|
+
| expandedNodes | Current expanded nodes for TreeGrid | Object | - |
|
|
240
|
+
| form | Form configuration for editing | Object | - |
|
|
241
|
+
| gridHeight | Height of the grid | Number | 500 |
|
|
242
|
+
| groupBy | Current grouping configuration | Array | - |
|
|
243
|
+
| loadNode | Function to load TreeGrid nodes on demand | Function | - |
|
|
244
|
+
| onExpandedNodesChange | Callback for TreeGrid node expand/collapse | Function | - |
|
|
245
|
+
| onGroupByChange | Callback for grouping changes | Function | - |
|
|
246
|
+
| renderGroupTitle | Custom renderer for group headers | Function | - |
|
|
247
|
+
| settings | Grid settings (pagination, etc.) | Object | - |
|
|
248
|
+
| setFilterData | Callback for filter changes | Function | - |
|
|
249
|
+
| setConfig | Callback for configuration changes | Function | - |
|
|
250
|
+
| style | Custom styles | Object | - |
|
|
251
|
+
| treeColumn | Column name to display TreeGrid hierarchy | String | - |
|
|
252
|
+
| treeNestingSize | Indentation size for TreeGrid levels | Number | 20 |
|
|
227
253
|
|
|
228
254
|
#### Auto-Refresh Functionality
|
|
229
255
|
|
|
@@ -253,6 +279,444 @@ When auto-refresh is configured:
|
|
|
253
279
|
- Setting `autoRefresh: true` uses the default 30-second interval
|
|
254
280
|
- The component silently refreshes data without showing notifications
|
|
255
281
|
|
|
282
|
+
#### Group By Functionality
|
|
283
|
+
|
|
284
|
+
The DataGrid component supports grouping data by one or more columns, allowing you to organize and visualize data in hierarchical structures.
|
|
285
|
+
|
|
286
|
+
##### Using defaultGroupBy
|
|
287
|
+
|
|
288
|
+
The `defaultGroupBy` property allows you to specify initial grouping when the DataGrid loads:
|
|
289
|
+
|
|
290
|
+
```jsx
|
|
291
|
+
<DataGrid
|
|
292
|
+
// Other props...
|
|
293
|
+
defaultGroupBy={[
|
|
294
|
+
{ name: 'category' }, // Group by a single column
|
|
295
|
+
]}
|
|
296
|
+
/>
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
For more complex grouping with multiple levels:
|
|
300
|
+
|
|
301
|
+
```jsx
|
|
302
|
+
<DataGrid
|
|
303
|
+
// Other props...
|
|
304
|
+
defaultGroupBy={[
|
|
305
|
+
{ name: 'department' }, // First level grouping
|
|
306
|
+
{ name: 'role' }, // Second level grouping
|
|
307
|
+
]}
|
|
308
|
+
/>
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
##### Dynamic Grouping
|
|
312
|
+
|
|
313
|
+
You can also control grouping programmatically:
|
|
314
|
+
|
|
315
|
+
```jsx
|
|
316
|
+
const [groupBy, setGroupBy] = useState([{ name: 'category' }]);
|
|
317
|
+
|
|
318
|
+
// Later in your component
|
|
319
|
+
<DataGrid
|
|
320
|
+
// Other props...
|
|
321
|
+
groupBy={groupBy}
|
|
322
|
+
onGroupByChange={setGroupBy}
|
|
323
|
+
/>;
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
##### Server-Side Grouping
|
|
327
|
+
|
|
328
|
+
For server-side grouping, the DataGrid sends the groupBy information to your API endpoint:
|
|
329
|
+
|
|
330
|
+
```jsx
|
|
331
|
+
<DataGrid
|
|
332
|
+
ajaxSetting={{
|
|
333
|
+
url: '/api/data',
|
|
334
|
+
method: 'POST',
|
|
335
|
+
// Other settings...
|
|
336
|
+
}}
|
|
337
|
+
defaultGroupBy={[{ name: 'category' }]}
|
|
338
|
+
// Other props...
|
|
339
|
+
/>
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Your server will receive a request with groupBy information:
|
|
343
|
+
|
|
344
|
+
```json
|
|
345
|
+
{
|
|
346
|
+
"page": 1,
|
|
347
|
+
"take": 25,
|
|
348
|
+
"groupBy": [{ "name": "category" }]
|
|
349
|
+
// Other parameters...
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
##### Group Summaries
|
|
354
|
+
|
|
355
|
+
You can add summary calculations to grouped data:
|
|
356
|
+
|
|
357
|
+
```jsx
|
|
358
|
+
<DataGrid
|
|
359
|
+
// Other props...
|
|
360
|
+
columns={[
|
|
361
|
+
{
|
|
362
|
+
name: 'amount',
|
|
363
|
+
headerName: 'Amount',
|
|
364
|
+
type: 'number',
|
|
365
|
+
groupSummaryReducer: 'sum', // Options: 'sum', 'avg', 'min', 'max', 'count'
|
|
366
|
+
groupSummaryRenderer: (summary) => `Total: $${summary.toFixed(2)}`,
|
|
367
|
+
},
|
|
368
|
+
// Other columns...
|
|
369
|
+
]}
|
|
370
|
+
defaultGroupBy={[{ name: 'category' }]}
|
|
371
|
+
/>
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
##### Customizing Group Rendering
|
|
375
|
+
|
|
376
|
+
You can customize how groups are displayed:
|
|
377
|
+
|
|
378
|
+
```jsx
|
|
379
|
+
<DataGrid
|
|
380
|
+
// Other props...
|
|
381
|
+
renderGroupTitle={(groupData) => (
|
|
382
|
+
<div style={{ fontWeight: 'bold', color: 'var(--primary-color)' }}>
|
|
383
|
+
{groupData.name}: {groupData.value} ({groupData.count} items)
|
|
384
|
+
</div>
|
|
385
|
+
)}
|
|
386
|
+
defaultGroupBy={[{ name: 'category' }]}
|
|
387
|
+
/>
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
##### Complete Example with Dynamic Grouping
|
|
391
|
+
|
|
392
|
+
Here's a complete example of a component that uses DataGrid with dynamic grouping controls:
|
|
393
|
+
|
|
394
|
+
```jsx
|
|
395
|
+
import React, { useState, useEffect } from 'react';
|
|
396
|
+
import { DataGrid } from 'visns-components';
|
|
397
|
+
|
|
398
|
+
const EmployeeDataGrid = () => {
|
|
399
|
+
// State for grouping
|
|
400
|
+
const [groupBy, setGroupBy] = useState([]);
|
|
401
|
+
|
|
402
|
+
// Sample data for the grid
|
|
403
|
+
const [employees, setEmployees] = useState([]);
|
|
404
|
+
|
|
405
|
+
// Fetch data on component mount
|
|
406
|
+
useEffect(() => {
|
|
407
|
+
const fetchEmployees = async () => {
|
|
408
|
+
try {
|
|
409
|
+
const response = await fetch('/api/employees');
|
|
410
|
+
const data = await response.json();
|
|
411
|
+
setEmployees(data);
|
|
412
|
+
} catch (error) {
|
|
413
|
+
console.error('Error fetching employees:', error);
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
fetchEmployees();
|
|
418
|
+
}, []);
|
|
419
|
+
|
|
420
|
+
// Column definitions
|
|
421
|
+
const columns = [
|
|
422
|
+
{
|
|
423
|
+
name: 'id',
|
|
424
|
+
headerName: 'ID',
|
|
425
|
+
width: 80,
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
name: 'name',
|
|
429
|
+
headerName: 'Name',
|
|
430
|
+
width: 180,
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
name: 'department',
|
|
434
|
+
headerName: 'Department',
|
|
435
|
+
width: 150,
|
|
436
|
+
groupSummaryReducer: 'count',
|
|
437
|
+
groupSummaryRenderer: (count) => `${count} employees`,
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
name: 'role',
|
|
441
|
+
headerName: 'Role',
|
|
442
|
+
width: 150,
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
name: 'salary',
|
|
446
|
+
headerName: 'Salary',
|
|
447
|
+
width: 120,
|
|
448
|
+
type: 'number',
|
|
449
|
+
groupSummaryReducer: 'sum',
|
|
450
|
+
groupSummaryRenderer: (sum) => `$${sum.toLocaleString()}`,
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
name: 'hireDate',
|
|
454
|
+
headerName: 'Hire Date',
|
|
455
|
+
width: 120,
|
|
456
|
+
type: 'date',
|
|
457
|
+
},
|
|
458
|
+
];
|
|
459
|
+
|
|
460
|
+
// Group by options for the dropdown
|
|
461
|
+
const groupByOptions = [
|
|
462
|
+
{ label: 'No Grouping', value: 'none' },
|
|
463
|
+
{ label: 'Department', value: 'department' },
|
|
464
|
+
{ label: 'Role', value: 'role' },
|
|
465
|
+
{ label: 'Department & Role', value: 'department-role' },
|
|
466
|
+
];
|
|
467
|
+
|
|
468
|
+
// Handle group by change
|
|
469
|
+
const handleGroupByChange = (e) => {
|
|
470
|
+
const value = e.target.value;
|
|
471
|
+
|
|
472
|
+
switch (value) {
|
|
473
|
+
case 'department':
|
|
474
|
+
setGroupBy([{ name: 'department' }]);
|
|
475
|
+
break;
|
|
476
|
+
case 'role':
|
|
477
|
+
setGroupBy([{ name: 'role' }]);
|
|
478
|
+
break;
|
|
479
|
+
case 'department-role':
|
|
480
|
+
setGroupBy([{ name: 'department' }, { name: 'role' }]);
|
|
481
|
+
break;
|
|
482
|
+
default:
|
|
483
|
+
setGroupBy([]);
|
|
484
|
+
break;
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
return (
|
|
489
|
+
<div>
|
|
490
|
+
<div style={{ marginBottom: '1rem' }}>
|
|
491
|
+
<label htmlFor="groupBy">Group By: </label>
|
|
492
|
+
<select
|
|
493
|
+
id="groupBy"
|
|
494
|
+
onChange={handleGroupByChange}
|
|
495
|
+
style={{ padding: '0.5rem', borderRadius: '4px' }}
|
|
496
|
+
>
|
|
497
|
+
{groupByOptions.map((option) => (
|
|
498
|
+
<option key={option.value} value={option.value}>
|
|
499
|
+
{option.label}
|
|
500
|
+
</option>
|
|
501
|
+
))}
|
|
502
|
+
</select>
|
|
503
|
+
</div>
|
|
504
|
+
|
|
505
|
+
<DataGrid
|
|
506
|
+
columns={columns}
|
|
507
|
+
dataSource={employees}
|
|
508
|
+
groupBy={groupBy}
|
|
509
|
+
onGroupByChange={setGroupBy}
|
|
510
|
+
gridHeight={600}
|
|
511
|
+
settings={{
|
|
512
|
+
pagination: true,
|
|
513
|
+
pageSize: 25,
|
|
514
|
+
}}
|
|
515
|
+
renderGroupTitle={(groupData) => (
|
|
516
|
+
<div
|
|
517
|
+
style={{
|
|
518
|
+
fontWeight: 'bold',
|
|
519
|
+
color: 'var(--primary-color)',
|
|
520
|
+
padding: '0.25rem 0',
|
|
521
|
+
}}
|
|
522
|
+
>
|
|
523
|
+
{groupData.name === 'department'
|
|
524
|
+
? 'Department'
|
|
525
|
+
: 'Role'}
|
|
526
|
+
:<span style={{ marginLeft: '0.5rem' }}>
|
|
527
|
+
{groupData.value} ({groupData.count} employees)
|
|
528
|
+
</span>
|
|
529
|
+
</div>
|
|
530
|
+
)}
|
|
531
|
+
/>
|
|
532
|
+
</div>
|
|
533
|
+
);
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
export default EmployeeDataGrid;
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
#### TreeGrid Functionality
|
|
540
|
+
|
|
541
|
+
The DataGrid component also supports hierarchical data display through its TreeGrid functionality. This allows you to represent parent-child relationships in your data with expandable/collapsible nodes.
|
|
542
|
+
|
|
543
|
+
##### Basic TreeGrid Configuration
|
|
544
|
+
|
|
545
|
+
To use the TreeGrid functionality:
|
|
546
|
+
|
|
547
|
+
```jsx
|
|
548
|
+
<DataGrid
|
|
549
|
+
// Other props...
|
|
550
|
+
treeColumn="name" // Specify which column will display the expand/collapse icons
|
|
551
|
+
dataSource={hierarchicalData} // Data with parent-child relationships
|
|
552
|
+
/>
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
Your data should have a structure where parent nodes contain child nodes:
|
|
556
|
+
|
|
557
|
+
```jsx
|
|
558
|
+
const hierarchicalData = [
|
|
559
|
+
{
|
|
560
|
+
id: 1,
|
|
561
|
+
name: 'Parent 1',
|
|
562
|
+
nodes: [
|
|
563
|
+
// Child nodes
|
|
564
|
+
{ id: 11, name: 'Child 1.1' },
|
|
565
|
+
{
|
|
566
|
+
id: 12,
|
|
567
|
+
name: 'Child 1.2',
|
|
568
|
+
nodes: [
|
|
569
|
+
// Nested children
|
|
570
|
+
{ id: 121, name: 'Grandchild 1.2.1' },
|
|
571
|
+
],
|
|
572
|
+
},
|
|
573
|
+
],
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
id: 2,
|
|
577
|
+
name: 'Parent 2',
|
|
578
|
+
nodes: [{ id: 21, name: 'Child 2.1' }],
|
|
579
|
+
},
|
|
580
|
+
];
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
##### Controlling Expanded Nodes
|
|
584
|
+
|
|
585
|
+
You can control which nodes are expanded:
|
|
586
|
+
|
|
587
|
+
```jsx
|
|
588
|
+
const [expandedNodes, setExpandedNodes] = useState({
|
|
589
|
+
1: true, // Node with ID 1 is expanded
|
|
590
|
+
'1/12': true, // Node with path 1/12 is expanded
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
<DataGrid
|
|
594
|
+
// Other props...
|
|
595
|
+
treeColumn="name"
|
|
596
|
+
dataSource={hierarchicalData}
|
|
597
|
+
expandedNodes={expandedNodes}
|
|
598
|
+
onExpandedNodesChange={setExpandedNodes}
|
|
599
|
+
/>;
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
##### Asynchronous Node Loading
|
|
603
|
+
|
|
604
|
+
For large datasets, you can load child nodes on demand:
|
|
605
|
+
|
|
606
|
+
```jsx
|
|
607
|
+
<DataGrid
|
|
608
|
+
// Other props...
|
|
609
|
+
treeColumn="name"
|
|
610
|
+
dataSource={asyncHierarchicalData}
|
|
611
|
+
loadNode={({ node }) => {
|
|
612
|
+
// Return a Promise that resolves to the child nodes
|
|
613
|
+
return fetchChildNodes(node.id);
|
|
614
|
+
}}
|
|
615
|
+
/>
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
For asynchronous loading, parent nodes should have `nodes: null` to indicate they have children that need to be loaded.
|
|
619
|
+
|
|
620
|
+
##### Complete TreeGrid Example
|
|
621
|
+
|
|
622
|
+
Here's a complete example of a component that uses DataGrid with TreeGrid functionality:
|
|
623
|
+
|
|
624
|
+
```jsx
|
|
625
|
+
import React, { useState } from 'react';
|
|
626
|
+
import { DataGrid } from 'visns-components';
|
|
627
|
+
|
|
628
|
+
const OrganizationTreeGrid = () => {
|
|
629
|
+
// Sample hierarchical data
|
|
630
|
+
const departments = [
|
|
631
|
+
{
|
|
632
|
+
id: 1,
|
|
633
|
+
name: 'Executive',
|
|
634
|
+
budget: 1500000,
|
|
635
|
+
nodes: [
|
|
636
|
+
{
|
|
637
|
+
id: 11,
|
|
638
|
+
name: 'Finance',
|
|
639
|
+
budget: 850000,
|
|
640
|
+
nodes: [
|
|
641
|
+
{ id: 111, name: 'Accounting', budget: 350000 },
|
|
642
|
+
{ id: 112, name: 'Investment', budget: 500000 },
|
|
643
|
+
],
|
|
644
|
+
},
|
|
645
|
+
{
|
|
646
|
+
id: 12,
|
|
647
|
+
name: 'Operations',
|
|
648
|
+
budget: 650000,
|
|
649
|
+
nodes: [
|
|
650
|
+
{ id: 121, name: 'HR', budget: 200000 },
|
|
651
|
+
{ id: 122, name: 'Facilities', budget: 450000 },
|
|
652
|
+
],
|
|
653
|
+
},
|
|
654
|
+
],
|
|
655
|
+
},
|
|
656
|
+
{
|
|
657
|
+
id: 2,
|
|
658
|
+
name: 'Sales & Marketing',
|
|
659
|
+
budget: 1200000,
|
|
660
|
+
nodes: [
|
|
661
|
+
{ id: 21, name: 'Sales', budget: 700000 },
|
|
662
|
+
{ id: 22, name: 'Marketing', budget: 500000 },
|
|
663
|
+
],
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
id: 3,
|
|
667
|
+
name: 'Technology',
|
|
668
|
+
budget: 2000000,
|
|
669
|
+
nodes: [
|
|
670
|
+
{ id: 31, name: 'Development', budget: 1200000 },
|
|
671
|
+
{ id: 32, name: 'IT Support', budget: 800000 },
|
|
672
|
+
],
|
|
673
|
+
},
|
|
674
|
+
];
|
|
675
|
+
|
|
676
|
+
// State for expanded nodes
|
|
677
|
+
const [expandedNodes, setExpandedNodes] = useState({
|
|
678
|
+
1: true, // Executive department is expanded by default
|
|
679
|
+
3: true, // Technology department is expanded by default
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
// Column definitions
|
|
683
|
+
const columns = [
|
|
684
|
+
{
|
|
685
|
+
name: 'name',
|
|
686
|
+
headerName: 'Department',
|
|
687
|
+
width: 250,
|
|
688
|
+
// This column will display the tree expand/collapse icons
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
name: 'budget',
|
|
692
|
+
headerName: 'Budget',
|
|
693
|
+
width: 150,
|
|
694
|
+
type: 'number',
|
|
695
|
+
render: ({ value }) => `$${value.toLocaleString()}`,
|
|
696
|
+
},
|
|
697
|
+
];
|
|
698
|
+
|
|
699
|
+
return (
|
|
700
|
+
<div>
|
|
701
|
+
<h2>Organization Structure</h2>
|
|
702
|
+
|
|
703
|
+
<DataGrid
|
|
704
|
+
columns={columns}
|
|
705
|
+
dataSource={departments}
|
|
706
|
+
treeColumn="name"
|
|
707
|
+
expandedNodes={expandedNodes}
|
|
708
|
+
onExpandedNodesChange={setExpandedNodes}
|
|
709
|
+
treeNestingSize={30} // Indentation size for nested levels
|
|
710
|
+
gridHeight={500}
|
|
711
|
+
idProperty="id"
|
|
712
|
+
/>
|
|
713
|
+
</div>
|
|
714
|
+
);
|
|
715
|
+
};
|
|
716
|
+
|
|
717
|
+
export default OrganizationTreeGrid;
|
|
718
|
+
```
|
|
719
|
+
|
|
256
720
|
### Form Components
|
|
257
721
|
|
|
258
722
|
#### Form
|
package/package.json
CHANGED
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
85
85
|
},
|
|
86
86
|
"name": "@visns-studio/visns-components",
|
|
87
|
-
"version": "5.6.
|
|
87
|
+
"version": "5.6.11",
|
|
88
88
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
89
89
|
"main": "src/index.js",
|
|
90
90
|
"files": [
|
|
@@ -3206,6 +3206,22 @@ const DataGrid = forwardRef(
|
|
|
3206
3206
|
};
|
|
3207
3207
|
}, []);
|
|
3208
3208
|
|
|
3209
|
+
// Reset state when ajaxSetting changes (e.g., when navigating to a new page)
|
|
3210
|
+
useEffect(() => {
|
|
3211
|
+
// Reset selected state
|
|
3212
|
+
setSelected({});
|
|
3213
|
+
|
|
3214
|
+
// Reset filter value if needed
|
|
3215
|
+
if (setFilterData) {
|
|
3216
|
+
setFilterData([]);
|
|
3217
|
+
}
|
|
3218
|
+
|
|
3219
|
+
// Force reload of data
|
|
3220
|
+
if (gridRef.current && gridRef.current.paginationProps) {
|
|
3221
|
+
gridRef.current.paginationProps.reload();
|
|
3222
|
+
}
|
|
3223
|
+
}, [ajaxSetting?.url]);
|
|
3224
|
+
|
|
3209
3225
|
// Auto-refresh effect
|
|
3210
3226
|
useEffect(() => {
|
|
3211
3227
|
// Clear any existing timer
|
|
@@ -3258,9 +3274,15 @@ const DataGrid = forwardRef(
|
|
|
3258
3274
|
<div className={styles.dataGridContainer}>
|
|
3259
3275
|
{limit && limit > 0 ? (
|
|
3260
3276
|
<ReactDataGrid
|
|
3277
|
+
key={`datagrid-${ajaxSetting?.url || ''}-${
|
|
3278
|
+
ajaxSetting?.groupBy ? 'grouped' : 'ungrouped'
|
|
3279
|
+
}`}
|
|
3261
3280
|
{...tableSetting}
|
|
3262
3281
|
columns={gridColumns}
|
|
3263
3282
|
dataSource={dataSource}
|
|
3283
|
+
{...(ajaxSetting && ajaxSetting.groupBy
|
|
3284
|
+
? { defaultGroupBy: ajaxSetting.groupBy }
|
|
3285
|
+
: {})}
|
|
3264
3286
|
filterValue={filterValue}
|
|
3265
3287
|
limit={limit}
|
|
3266
3288
|
enableColumnAutosize={false}
|