@object-ui/plugin-aggrid 0.4.1 → 2.0.0
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/.turbo/turbo-build.log +99 -0
- package/CHANGELOG.md +16 -0
- package/OBJECT_AGGRID_CN.md +483 -0
- package/QUICKSTART.md +186 -0
- package/README.md +221 -1
- package/dist/AddressField-Bntpynvd.js +95 -0
- package/dist/AgGridImpl-3Mmf2qrR.js +229 -0
- package/dist/AutoNumberField-C1kBJaxh.js +8 -0
- package/dist/FileField-BDwbJvor.js +101 -0
- package/dist/FormulaField-BXNiyGoh.js +9 -0
- package/dist/GeolocationField-Df3yYcM9.js +141 -0
- package/dist/GridField-CcjQp4WM.js +29 -0
- package/dist/LocationField-BIfN5QIq.js +33 -0
- package/dist/MasterDetailField-CAEmxbIT.js +117 -0
- package/dist/ObjectAgGridImpl-EjifM4aY.js +28727 -0
- package/dist/ObjectField-BpkQpIF-.js +51 -0
- package/dist/QRCodeField-VCBewTDG.js +96 -0
- package/dist/RichTextField-CyQwSi2C.js +37 -0
- package/dist/SignatureField-Cr4tsEbj.js +96 -0
- package/dist/SummaryField-CnEJ_GZI.js +9 -0
- package/dist/UserField-DJjaVyrV.js +49 -0
- package/dist/VectorField-cPYmcKnV.js +25 -0
- package/dist/{index-B6NPAFZx.js → index-B87wd1E0.js} +301 -143
- package/dist/index.css +1 -1
- package/dist/index.js +4 -3
- package/dist/index.umd.cjs +225 -2
- package/dist/src/AgGridImpl.d.ts +5 -2
- package/dist/src/ObjectAgGridImpl.d.ts +6 -0
- package/dist/src/VirtualScrolling.d.ts +72 -0
- package/dist/src/field-renderers.d.ts +67 -0
- package/dist/src/index.d.ts +47 -2
- package/dist/src/object-aggrid.types.d.ts +74 -0
- package/dist/src/types.d.ts +48 -1
- package/package.json +11 -9
- package/src/AgGridImpl.tsx +100 -11
- package/src/ObjectAgGridImpl.tsx +501 -0
- package/src/VirtualScrolling.ts +74 -0
- package/src/field-renderers.test.tsx +383 -0
- package/src/field-renderers.tsx +224 -0
- package/src/index.test.ts +1 -1
- package/src/index.tsx +211 -2
- package/src/object-aggrid.test.ts +99 -0
- package/src/object-aggrid.types.ts +123 -0
- package/src/types.ts +57 -1
- package/vite.config.ts +13 -0
- package/dist/AgGridImpl-DKkq6v1B.js +0 -171
package/dist/src/AgGridImpl.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ColDef, GridOptions } from 'ag-grid-community';
|
|
2
|
-
import { AgGridCallbacks, ExportConfig, StatusBarConfig, ColumnConfig, ContextMenuConfig } from './types';
|
|
2
|
+
import { AgGridCallbacks, ExportConfig, StatusBarConfig, ColumnConfig, ContextMenuConfig, TreeDataConfig, RowGroupingConfig, ExcelExportConfig } from './types';
|
|
3
3
|
export interface AgGridImplProps {
|
|
4
4
|
rowData?: any[];
|
|
5
5
|
columnDefs?: ColDef[];
|
|
@@ -23,9 +23,12 @@ export interface AgGridImplProps {
|
|
|
23
23
|
enableRangeSelection?: boolean;
|
|
24
24
|
enableCharts?: boolean;
|
|
25
25
|
contextMenu?: ContextMenuConfig;
|
|
26
|
+
treeData?: TreeDataConfig;
|
|
27
|
+
rowGrouping?: RowGroupingConfig;
|
|
28
|
+
excelExport?: ExcelExportConfig;
|
|
26
29
|
}
|
|
27
30
|
/**
|
|
28
31
|
* AgGridImpl - The heavy implementation that imports AG Grid
|
|
29
32
|
* This component is lazy-loaded to avoid including AG Grid in the initial bundle
|
|
30
33
|
*/
|
|
31
|
-
export default function AgGridImpl({ rowData, columnDefs, gridOptions, pagination, paginationPageSize, domLayout, animateRows, rowSelection, theme, height, className, editable, editType, singleClickEdit, stopEditingWhenCellsLoseFocus, exportConfig, statusBar, callbacks, columnConfig, enableRangeSelection, enableCharts, contextMenu, }: AgGridImplProps): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
export default function AgGridImpl({ rowData, columnDefs, gridOptions, pagination, paginationPageSize, domLayout, animateRows, rowSelection, theme, height, className, editable, editType, singleClickEdit, stopEditingWhenCellsLoseFocus, exportConfig, statusBar, callbacks, columnConfig, enableRangeSelection, enableCharts, contextMenu, treeData, rowGrouping, excelExport, }: AgGridImplProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ObjectAgGridImplProps } from './object-aggrid.types';
|
|
2
|
+
/**
|
|
3
|
+
* ObjectAgGridImpl - Metadata-driven AG Grid implementation
|
|
4
|
+
* Fetches object metadata and data from ObjectStack and renders the grid
|
|
5
|
+
*/
|
|
6
|
+
export default function ObjectAgGridImpl({ objectName, dataSource, fields: providedFields, fieldNames, filters, sort, pageSize, pagination, domLayout, animateRows, rowSelection, theme, height, className, editable, editType, singleClickEdit, stopEditingWhenCellsLoseFocus, exportConfig, statusBar, callbacks, columnConfig, enableRangeSelection, enableCharts, contextMenu, }: ObjectAgGridImplProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Virtual Scrolling in AG Grid
|
|
10
|
+
*
|
|
11
|
+
* AG Grid provides built-in virtual scrolling by default, which renders only
|
|
12
|
+
* the visible rows in the viewport. This is a core feature of AG Grid and
|
|
13
|
+
* requires no additional configuration.
|
|
14
|
+
*
|
|
15
|
+
* ## How It Works
|
|
16
|
+
*
|
|
17
|
+
* - AG Grid automatically virtualizes rows by rendering only visible rows
|
|
18
|
+
* - As you scroll, rows are recycled and reused for new data
|
|
19
|
+
* - This provides excellent performance even with datasets of 100,000+ rows
|
|
20
|
+
*
|
|
21
|
+
* ## Performance Tips
|
|
22
|
+
*
|
|
23
|
+
* 1. **Row Buffer**: Adjust `rowBuffer` to control how many extra rows are rendered
|
|
24
|
+
* ```ts
|
|
25
|
+
* gridOptions: { rowBuffer: 10 } // Render 10 extra rows above/below viewport
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* 2. **Suppress Animations**: Disable animations for very large datasets
|
|
29
|
+
* ```ts
|
|
30
|
+
* animateRows: false
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* 3. **Debounce Vertical Scroll**: Add delay to vertical scroll updates
|
|
34
|
+
* ```ts
|
|
35
|
+
* gridOptions: { debounceVerticalScrollbar: true }
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* 4. **Row Height**: Use fixed row heights for better performance
|
|
39
|
+
* ```ts
|
|
40
|
+
* gridOptions: { rowHeight: 40 }
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* ## Example Usage
|
|
44
|
+
*
|
|
45
|
+
* ```tsx
|
|
46
|
+
* <AgGrid
|
|
47
|
+
* rowData={largeDataset} // 10,000+ items
|
|
48
|
+
* columnDefs={columns}
|
|
49
|
+
* gridOptions={{
|
|
50
|
+
* rowBuffer: 10,
|
|
51
|
+
* rowHeight: 40,
|
|
52
|
+
* debounceVerticalScrollbar: true,
|
|
53
|
+
* }}
|
|
54
|
+
* animateRows={false}
|
|
55
|
+
* />
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* ## References
|
|
59
|
+
*
|
|
60
|
+
* - [AG Grid Row Virtualisation](https://www.ag-grid.com/javascript-data-grid/dom-virtualisation/)
|
|
61
|
+
* - [Performance Best Practices](https://www.ag-grid.com/javascript-data-grid/performance/)
|
|
62
|
+
*/
|
|
63
|
+
export declare const VIRTUAL_SCROLLING_DOCS: {
|
|
64
|
+
enabled: boolean;
|
|
65
|
+
automatic: boolean;
|
|
66
|
+
recommendedSettings: {
|
|
67
|
+
rowBuffer: number;
|
|
68
|
+
rowHeight: number;
|
|
69
|
+
debounceVerticalScrollbar: boolean;
|
|
70
|
+
animateRows: boolean;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Root } from 'react-dom/client';
|
|
2
|
+
import { ICellRendererParams, ICellEditorParams } from 'ag-grid-community';
|
|
3
|
+
import { FieldMetadata } from '../../types/src';
|
|
4
|
+
/**
|
|
5
|
+
* AG Grid Cell Renderer using Field Widgets (Read-only mode)
|
|
6
|
+
*/
|
|
7
|
+
export declare class FieldWidgetCellRenderer {
|
|
8
|
+
eGui: HTMLDivElement;
|
|
9
|
+
root: Root | null;
|
|
10
|
+
init(params: ICellRendererParams & {
|
|
11
|
+
field: FieldMetadata;
|
|
12
|
+
}): void;
|
|
13
|
+
getGui(): HTMLDivElement;
|
|
14
|
+
refresh(params: ICellRendererParams & {
|
|
15
|
+
field: FieldMetadata;
|
|
16
|
+
}): boolean;
|
|
17
|
+
destroy(): void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* AG Grid Cell Editor using Field Widgets (Edit mode)
|
|
21
|
+
*/
|
|
22
|
+
export declare class FieldWidgetCellEditor {
|
|
23
|
+
eGui: HTMLDivElement;
|
|
24
|
+
root: Root | null;
|
|
25
|
+
currentValue: unknown;
|
|
26
|
+
params: ICellEditorParams & {
|
|
27
|
+
field: FieldMetadata;
|
|
28
|
+
};
|
|
29
|
+
init(params: ICellEditorParams & {
|
|
30
|
+
field: FieldMetadata;
|
|
31
|
+
}): void;
|
|
32
|
+
getGui(): HTMLDivElement;
|
|
33
|
+
getValue(): unknown;
|
|
34
|
+
destroy(): void;
|
|
35
|
+
isPopup(): boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Factory function to create cell renderer with field metadata
|
|
39
|
+
*/
|
|
40
|
+
export declare function createFieldCellRenderer(field: FieldMetadata): {
|
|
41
|
+
new (): {
|
|
42
|
+
init(params: ICellRendererParams): void;
|
|
43
|
+
refresh(params: ICellRendererParams): boolean;
|
|
44
|
+
eGui: HTMLDivElement;
|
|
45
|
+
root: Root | null;
|
|
46
|
+
getGui(): HTMLDivElement;
|
|
47
|
+
destroy(): void;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Factory function to create cell editor with field metadata
|
|
52
|
+
*/
|
|
53
|
+
export declare function createFieldCellEditor(field: FieldMetadata): {
|
|
54
|
+
new (): {
|
|
55
|
+
init(params: ICellEditorParams): void;
|
|
56
|
+
eGui: HTMLDivElement;
|
|
57
|
+
root: Root | null;
|
|
58
|
+
currentValue: unknown;
|
|
59
|
+
params: ICellEditorParams & {
|
|
60
|
+
field: FieldMetadata;
|
|
61
|
+
};
|
|
62
|
+
getGui(): HTMLDivElement;
|
|
63
|
+
getValue(): unknown;
|
|
64
|
+
destroy(): void;
|
|
65
|
+
isPopup(): boolean;
|
|
66
|
+
};
|
|
67
|
+
};
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
import { AgGridCallbacks, ExportConfig, StatusBarConfig, ColumnConfig, ContextMenuConfig } from './types';
|
|
3
|
-
|
|
2
|
+
import { AgGridCallbacks, ExportConfig, StatusBarConfig, ColumnConfig, ContextMenuConfig, TreeDataConfig, RowGroupingConfig, ExcelExportConfig } from './types';
|
|
3
|
+
import { DataSource } from '../../types/src';
|
|
4
|
+
export type { AgGridSchema, SimpleColumnDef, AgGridCallbacks, ExportConfig, StatusBarConfig, ColumnConfig, ContextMenuConfig, TreeDataConfig, RowGroupingConfig, ExcelExportConfig } from './types';
|
|
5
|
+
export type { ObjectAgGridSchema } from './object-aggrid.types';
|
|
4
6
|
export interface AgGridRendererProps {
|
|
5
7
|
schema: {
|
|
6
8
|
type: string;
|
|
@@ -27,6 +29,9 @@ export interface AgGridRendererProps {
|
|
|
27
29
|
enableRangeSelection?: boolean;
|
|
28
30
|
enableCharts?: boolean;
|
|
29
31
|
contextMenu?: ContextMenuConfig;
|
|
32
|
+
treeData?: TreeDataConfig;
|
|
33
|
+
rowGrouping?: RowGroupingConfig;
|
|
34
|
+
excelExport?: ExcelExportConfig;
|
|
30
35
|
};
|
|
31
36
|
}
|
|
32
37
|
/**
|
|
@@ -34,6 +39,46 @@ export interface AgGridRendererProps {
|
|
|
34
39
|
* This wrapper handles lazy loading internally using React.Suspense
|
|
35
40
|
*/
|
|
36
41
|
export declare const AgGridRenderer: React.FC<AgGridRendererProps>;
|
|
42
|
+
/**
|
|
43
|
+
* ObjectAgGridRenderer - The public API for the metadata-driven AG Grid component
|
|
44
|
+
* This wrapper handles lazy loading internally using React.Suspense
|
|
45
|
+
*/
|
|
46
|
+
export interface ObjectAgGridRendererProps {
|
|
47
|
+
schema: {
|
|
48
|
+
type: string;
|
|
49
|
+
id?: string;
|
|
50
|
+
className?: string;
|
|
51
|
+
objectName: string;
|
|
52
|
+
dataSource?: DataSource;
|
|
53
|
+
fields?: any[];
|
|
54
|
+
fieldNames?: string[];
|
|
55
|
+
filters?: Record<string, any>;
|
|
56
|
+
sort?: Record<string, 'asc' | 'desc'>;
|
|
57
|
+
pageSize?: number;
|
|
58
|
+
pagination?: boolean;
|
|
59
|
+
domLayout?: 'normal' | 'autoHeight' | 'print';
|
|
60
|
+
animateRows?: boolean;
|
|
61
|
+
rowSelection?: 'single' | 'multiple';
|
|
62
|
+
theme?: 'alpine' | 'balham' | 'material' | 'quartz';
|
|
63
|
+
height?: number | string;
|
|
64
|
+
editable?: boolean;
|
|
65
|
+
editType?: 'fullRow';
|
|
66
|
+
singleClickEdit?: boolean;
|
|
67
|
+
stopEditingWhenCellsLoseFocus?: boolean;
|
|
68
|
+
exportConfig?: ExportConfig;
|
|
69
|
+
statusBar?: StatusBarConfig;
|
|
70
|
+
callbacks?: AgGridCallbacks & {
|
|
71
|
+
onDataLoaded?: (data: any[]) => void;
|
|
72
|
+
onDataError?: (error: Error) => void;
|
|
73
|
+
};
|
|
74
|
+
columnConfig?: ColumnConfig;
|
|
75
|
+
enableRangeSelection?: boolean;
|
|
76
|
+
enableCharts?: boolean;
|
|
77
|
+
contextMenu?: ContextMenuConfig;
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export declare const ObjectAgGridRenderer: React.FC<ObjectAgGridRendererProps>;
|
|
37
81
|
export declare const aggridComponents: {
|
|
38
82
|
aggrid: React.FC<AgGridRendererProps>;
|
|
83
|
+
'object-aggrid': React.FC<ObjectAgGridRendererProps>;
|
|
39
84
|
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { DataSource, FieldMetadata } from '../../types/src';
|
|
2
|
+
import { AgGridCallbacks, ExportConfig, StatusBarConfig, ColumnConfig, ContextMenuConfig } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Object AgGrid schema for metadata-driven grid
|
|
5
|
+
*/
|
|
6
|
+
export interface ObjectAgGridSchema {
|
|
7
|
+
type: 'object-aggrid';
|
|
8
|
+
id?: string;
|
|
9
|
+
className?: string;
|
|
10
|
+
objectName: string;
|
|
11
|
+
dataSource: DataSource;
|
|
12
|
+
fields?: FieldMetadata[];
|
|
13
|
+
fieldNames?: string[];
|
|
14
|
+
filters?: Record<string, any>;
|
|
15
|
+
sort?: Record<string, 'asc' | 'desc'>;
|
|
16
|
+
pageSize?: number;
|
|
17
|
+
pagination?: boolean;
|
|
18
|
+
domLayout?: 'normal' | 'autoHeight' | 'print';
|
|
19
|
+
animateRows?: boolean;
|
|
20
|
+
rowSelection?: 'single' | 'multiple';
|
|
21
|
+
editable?: boolean;
|
|
22
|
+
editType?: 'fullRow';
|
|
23
|
+
singleClickEdit?: boolean;
|
|
24
|
+
stopEditingWhenCellsLoseFocus?: boolean;
|
|
25
|
+
exportConfig?: ExportConfig;
|
|
26
|
+
statusBar?: StatusBarConfig;
|
|
27
|
+
columnConfig?: ColumnConfig;
|
|
28
|
+
enableRangeSelection?: boolean;
|
|
29
|
+
enableCharts?: boolean;
|
|
30
|
+
contextMenu?: ContextMenuConfig;
|
|
31
|
+
callbacks?: AgGridCallbacks & {
|
|
32
|
+
onDataLoaded?: (data: any[]) => void;
|
|
33
|
+
onDataError?: (error: Error) => void;
|
|
34
|
+
};
|
|
35
|
+
theme?: 'alpine' | 'balham' | 'material' | 'quartz';
|
|
36
|
+
height?: number | string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Props for ObjectAgGridImpl component
|
|
40
|
+
*/
|
|
41
|
+
export interface ObjectAgGridImplProps {
|
|
42
|
+
objectName: string;
|
|
43
|
+
dataSource?: DataSource;
|
|
44
|
+
fields?: FieldMetadata[];
|
|
45
|
+
fieldNames?: string[];
|
|
46
|
+
filters?: Record<string, any>;
|
|
47
|
+
sort?: Record<string, 'asc' | 'desc'>;
|
|
48
|
+
pageSize?: number;
|
|
49
|
+
pagination?: boolean;
|
|
50
|
+
domLayout?: 'normal' | 'autoHeight' | 'print';
|
|
51
|
+
animateRows?: boolean;
|
|
52
|
+
rowSelection?: 'single' | 'multiple';
|
|
53
|
+
theme?: 'alpine' | 'balham' | 'material' | 'quartz';
|
|
54
|
+
height?: number | string;
|
|
55
|
+
className?: string;
|
|
56
|
+
editable?: boolean;
|
|
57
|
+
editType?: 'fullRow';
|
|
58
|
+
singleClickEdit?: boolean;
|
|
59
|
+
stopEditingWhenCellsLoseFocus?: boolean;
|
|
60
|
+
exportConfig?: ExportConfig;
|
|
61
|
+
statusBar?: StatusBarConfig;
|
|
62
|
+
callbacks?: AgGridCallbacks & {
|
|
63
|
+
onDataLoaded?: (data: any[]) => void;
|
|
64
|
+
onDataError?: (error: Error) => void;
|
|
65
|
+
};
|
|
66
|
+
columnConfig?: ColumnConfig;
|
|
67
|
+
enableRangeSelection?: boolean;
|
|
68
|
+
enableCharts?: boolean;
|
|
69
|
+
contextMenu?: ContextMenuConfig;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Field type to AG Grid filter type mapping
|
|
73
|
+
*/
|
|
74
|
+
export declare const FIELD_TYPE_TO_FILTER_TYPE: Record<string, string | boolean>;
|
package/dist/src/types.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface AgGridCallbacks {
|
|
|
7
7
|
onRowClicked?: (event: RowClickedEvent) => void;
|
|
8
8
|
onSelectionChanged?: (event: SelectionChangedEvent) => void;
|
|
9
9
|
onCellValueChanged?: (event: CellValueChangedEvent) => void;
|
|
10
|
-
onExport?: (data: any[], format: 'csv') => void;
|
|
10
|
+
onExport?: (data: any[], format: 'csv' | 'excel') => void;
|
|
11
11
|
onContextMenuAction?: (action: string, rowData: any) => void;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
@@ -19,6 +19,50 @@ export interface ExportConfig {
|
|
|
19
19
|
skipColumnHeaders?: boolean;
|
|
20
20
|
allColumns?: boolean;
|
|
21
21
|
onlySelected?: boolean;
|
|
22
|
+
format?: 'csv' | 'excel';
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Tree data configuration
|
|
26
|
+
*/
|
|
27
|
+
export interface TreeDataConfig {
|
|
28
|
+
enabled?: boolean;
|
|
29
|
+
/** Field that contains the hierarchy path (array of strings) */
|
|
30
|
+
pathField?: string;
|
|
31
|
+
/** Field that contains parent ID for parent-child relationships */
|
|
32
|
+
parentIdField?: string;
|
|
33
|
+
/** Field that contains the unique ID */
|
|
34
|
+
idField?: string;
|
|
35
|
+
/** Whether to expand all rows by default */
|
|
36
|
+
expandAll?: boolean;
|
|
37
|
+
/** Depth to expand to by default */
|
|
38
|
+
expandDepth?: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Row grouping configuration
|
|
42
|
+
*/
|
|
43
|
+
export interface RowGroupingConfig {
|
|
44
|
+
enabled?: boolean;
|
|
45
|
+
/** Fields to group by */
|
|
46
|
+
groupByFields?: string[];
|
|
47
|
+
/** Whether to show group row count */
|
|
48
|
+
showRowCount?: boolean;
|
|
49
|
+
/** Whether to allow user to change grouping */
|
|
50
|
+
userGroupable?: boolean;
|
|
51
|
+
/** Aggregation functions for grouped columns */
|
|
52
|
+
aggregations?: Record<string, 'sum' | 'avg' | 'count' | 'min' | 'max' | 'first' | 'last'>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Excel export configuration
|
|
56
|
+
*/
|
|
57
|
+
export interface ExcelExportConfig {
|
|
58
|
+
enabled?: boolean;
|
|
59
|
+
fileName?: string;
|
|
60
|
+
sheetName?: string;
|
|
61
|
+
includeHeaders?: boolean;
|
|
62
|
+
includeGrouping?: boolean;
|
|
63
|
+
onlySelected?: boolean;
|
|
64
|
+
/** Custom column widths */
|
|
65
|
+
columnWidths?: Record<string, number>;
|
|
22
66
|
}
|
|
23
67
|
/**
|
|
24
68
|
* Status bar configuration
|
|
@@ -72,6 +116,9 @@ export interface AgGridSchema {
|
|
|
72
116
|
enableRangeSelection?: boolean;
|
|
73
117
|
enableCharts?: boolean;
|
|
74
118
|
contextMenu?: ContextMenuConfig;
|
|
119
|
+
treeData?: TreeDataConfig;
|
|
120
|
+
rowGrouping?: RowGroupingConfig;
|
|
121
|
+
excelExport?: ExcelExportConfig;
|
|
75
122
|
callbacks?: AgGridCallbacks;
|
|
76
123
|
theme?: 'alpine' | 'balham' | 'material' | 'quartz';
|
|
77
124
|
height?: number | string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/plugin-aggrid",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "AG Grid data grid plugin for Object UI, powered by AG Grid Community",
|
|
@@ -25,10 +25,12 @@
|
|
|
25
25
|
"./style.css": "./dist/index.css"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@object-ui/components": "0.
|
|
29
|
-
"@object-ui/core": "0.
|
|
30
|
-
"@object-ui/
|
|
31
|
-
"@object-ui/
|
|
28
|
+
"@object-ui/components": "2.0.0",
|
|
29
|
+
"@object-ui/core": "2.0.0",
|
|
30
|
+
"@object-ui/fields": "2.0.0",
|
|
31
|
+
"@object-ui/react": "2.0.0",
|
|
32
|
+
"@object-ui/types": "2.0.0",
|
|
33
|
+
"@object-ui/data-objectstack": "2.0.0"
|
|
32
34
|
},
|
|
33
35
|
"peerDependencies": {
|
|
34
36
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -37,11 +39,11 @@
|
|
|
37
39
|
"ag-grid-react": "^32.0.0"
|
|
38
40
|
},
|
|
39
41
|
"devDependencies": {
|
|
40
|
-
"@types/react": "^19.2.
|
|
42
|
+
"@types/react": "^19.2.13",
|
|
41
43
|
"@types/react-dom": "^19.2.3",
|
|
42
|
-
"@vitejs/plugin-react": "^
|
|
43
|
-
"ag-grid-community": "^
|
|
44
|
-
"ag-grid-react": "^32.3.
|
|
44
|
+
"@vitejs/plugin-react": "^5.1.3",
|
|
45
|
+
"ag-grid-community": "^32.3.9",
|
|
46
|
+
"ag-grid-react": "^32.3.9",
|
|
45
47
|
"typescript": "^5.9.3",
|
|
46
48
|
"vite": "^7.3.1",
|
|
47
49
|
"vite-plugin-dts": "^4.5.4"
|
package/src/AgGridImpl.tsx
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import React, { useMemo, useRef, useCallback } from 'react';
|
|
10
10
|
import { AgGridReact } from 'ag-grid-react';
|
|
11
11
|
import type { ColDef, GridOptions, GridReadyEvent, CellClickedEvent, RowClickedEvent, SelectionChangedEvent, CellValueChangedEvent, StatusPanelDef, GetContextMenuItemsParams, MenuItemDef } from 'ag-grid-community';
|
|
12
|
-
import type { AgGridCallbacks, ExportConfig, StatusBarConfig, ColumnConfig, ContextMenuConfig } from './types';
|
|
12
|
+
import type { AgGridCallbacks, ExportConfig, StatusBarConfig, ColumnConfig, ContextMenuConfig, TreeDataConfig, RowGroupingConfig, ExcelExportConfig } from './types';
|
|
13
13
|
|
|
14
14
|
export interface AgGridImplProps {
|
|
15
15
|
rowData?: any[];
|
|
@@ -34,6 +34,9 @@ export interface AgGridImplProps {
|
|
|
34
34
|
enableRangeSelection?: boolean;
|
|
35
35
|
enableCharts?: boolean;
|
|
36
36
|
contextMenu?: ContextMenuConfig;
|
|
37
|
+
treeData?: TreeDataConfig;
|
|
38
|
+
rowGrouping?: RowGroupingConfig;
|
|
39
|
+
excelExport?: ExcelExportConfig;
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
/**
|
|
@@ -63,6 +66,9 @@ export default function AgGridImpl({
|
|
|
63
66
|
enableRangeSelection = false,
|
|
64
67
|
enableCharts = false,
|
|
65
68
|
contextMenu,
|
|
69
|
+
treeData,
|
|
70
|
+
rowGrouping,
|
|
71
|
+
excelExport,
|
|
66
72
|
}: AgGridImplProps) {
|
|
67
73
|
const gridRef = useRef<any>(null);
|
|
68
74
|
|
|
@@ -113,6 +119,31 @@ export default function AgGridImpl({
|
|
|
113
119
|
}
|
|
114
120
|
}, [exportConfig, callbacks, rowData]);
|
|
115
121
|
|
|
122
|
+
// Excel-compatible CSV Export handler
|
|
123
|
+
// Exports CSV format which can be opened directly in Excel
|
|
124
|
+
const handleExportExcel = useCallback(() => {
|
|
125
|
+
if (!gridRef.current?.api) return;
|
|
126
|
+
|
|
127
|
+
const fileName = excelExport?.fileName || exportConfig?.fileName || 'export.csv';
|
|
128
|
+
const includeHeaders = excelExport?.includeHeaders !== false;
|
|
129
|
+
|
|
130
|
+
const params = {
|
|
131
|
+
fileName,
|
|
132
|
+
skipColumnHeaders: !includeHeaders,
|
|
133
|
+
allColumns: true,
|
|
134
|
+
onlySelected: excelExport?.onlySelected || false,
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
gridRef.current.api.exportDataAsCsv(params);
|
|
138
|
+
|
|
139
|
+
if (callbacks?.onExport) {
|
|
140
|
+
const data = excelExport?.onlySelected
|
|
141
|
+
? gridRef.current.api.getSelectedRows()
|
|
142
|
+
: rowData;
|
|
143
|
+
callbacks.onExport(data || [], 'excel');
|
|
144
|
+
}
|
|
145
|
+
}, [excelExport, exportConfig, callbacks, rowData]);
|
|
146
|
+
|
|
116
147
|
// Context Menu handler
|
|
117
148
|
const getContextMenuItems = useCallback((params: GetContextMenuItemsParams): (string | MenuItemDef)[] => {
|
|
118
149
|
if (!contextMenu?.enabled) return [];
|
|
@@ -127,6 +158,12 @@ export default function AgGridImpl({
|
|
|
127
158
|
icon: '<span>📥</span>',
|
|
128
159
|
action: () => handleExportCSV(),
|
|
129
160
|
});
|
|
161
|
+
} else if (item === 'export-excel') {
|
|
162
|
+
items.push({
|
|
163
|
+
name: 'Export Excel (CSV)',
|
|
164
|
+
icon: '<span>📊</span>',
|
|
165
|
+
action: () => handleExportExcel(),
|
|
166
|
+
});
|
|
130
167
|
} else if (item === 'autoSizeAll') {
|
|
131
168
|
items.push({
|
|
132
169
|
name: 'Auto-size All Columns',
|
|
@@ -170,7 +207,7 @@ export default function AgGridImpl({
|
|
|
170
207
|
}
|
|
171
208
|
|
|
172
209
|
return items;
|
|
173
|
-
}, [contextMenu, handleExportCSV, callbacks]);
|
|
210
|
+
}, [contextMenu, handleExportCSV, handleExportExcel, callbacks]);
|
|
174
211
|
|
|
175
212
|
// Event handlers
|
|
176
213
|
const handleCellClicked = useCallback((event: CellClickedEvent) => {
|
|
@@ -218,12 +255,23 @@ export default function AgGridImpl({
|
|
|
218
255
|
}
|
|
219
256
|
}
|
|
220
257
|
|
|
258
|
+
// Apply grouping
|
|
259
|
+
if (rowGrouping?.enabled && rowGrouping.groupByFields?.includes(col.field || '')) {
|
|
260
|
+
processed.rowGroup = true;
|
|
261
|
+
processed.hide = true;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Apply aggregation
|
|
265
|
+
if (rowGrouping?.aggregations && col.field && rowGrouping.aggregations[col.field]) {
|
|
266
|
+
processed.aggFunc = rowGrouping.aggregations[col.field];
|
|
267
|
+
}
|
|
268
|
+
|
|
221
269
|
return processed;
|
|
222
270
|
});
|
|
223
|
-
}, [columnDefs, editable, columnConfig]);
|
|
271
|
+
}, [columnDefs, editable, columnConfig, rowGrouping]);
|
|
224
272
|
|
|
225
273
|
// Merge grid options with props
|
|
226
|
-
const mergedGridOptions
|
|
274
|
+
const mergedGridOptions = useMemo(() => ({
|
|
227
275
|
...gridOptions,
|
|
228
276
|
pagination,
|
|
229
277
|
paginationPageSize,
|
|
@@ -237,10 +285,38 @@ export default function AgGridImpl({
|
|
|
237
285
|
enableRangeSelection,
|
|
238
286
|
enableCharts,
|
|
239
287
|
getContextMenuItems: contextMenu?.enabled ? getContextMenuItems : undefined,
|
|
288
|
+
// Tree data support
|
|
289
|
+
...(treeData?.enabled ? {
|
|
290
|
+
treeData: true,
|
|
291
|
+
getDataPath: treeData.pathField
|
|
292
|
+
? (data: any) => data[treeData.pathField as string]
|
|
293
|
+
: undefined,
|
|
294
|
+
autoGroupColumnDef: {
|
|
295
|
+
headerName: 'Hierarchy',
|
|
296
|
+
minWidth: 250,
|
|
297
|
+
cellRendererParams: {
|
|
298
|
+
suppressCount: false,
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
groupDefaultExpanded: treeData.expandAll ? -1 : (treeData.expandDepth ?? 0),
|
|
302
|
+
} : {}),
|
|
303
|
+
// Row grouping
|
|
304
|
+
...(rowGrouping?.enabled ? {
|
|
305
|
+
groupDefaultExpanded: rowGrouping.groupByFields?.length ? 1 : 0,
|
|
306
|
+
autoGroupColumnDef: {
|
|
307
|
+
minWidth: 200,
|
|
308
|
+
cellRendererParams: {
|
|
309
|
+
suppressCount: !rowGrouping.showRowCount,
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
} : {}),
|
|
240
313
|
// Default options for better UX
|
|
241
314
|
suppressCellFocus: !editable,
|
|
242
315
|
enableCellTextSelection: true,
|
|
243
316
|
ensureDomOrder: true,
|
|
317
|
+
// Virtual scrolling optimizations for large datasets
|
|
318
|
+
rowBuffer: gridOptions.rowBuffer ?? 10,
|
|
319
|
+
debounceVerticalScrollbar: gridOptions.debounceVerticalScrollbar ?? (rowData.length > 1000),
|
|
244
320
|
// Event handlers
|
|
245
321
|
onCellClicked: handleCellClicked,
|
|
246
322
|
onRowClicked: handleRowClicked,
|
|
@@ -262,7 +338,10 @@ export default function AgGridImpl({
|
|
|
262
338
|
enableCharts,
|
|
263
339
|
contextMenu,
|
|
264
340
|
getContextMenuItems,
|
|
341
|
+
treeData,
|
|
342
|
+
rowGrouping,
|
|
265
343
|
editable,
|
|
344
|
+
rowData.length,
|
|
266
345
|
handleCellClicked,
|
|
267
346
|
handleRowClicked,
|
|
268
347
|
handleSelectionChanged,
|
|
@@ -290,14 +369,24 @@ export default function AgGridImpl({
|
|
|
290
369
|
|
|
291
370
|
return (
|
|
292
371
|
<div className="ag-grid-container">
|
|
293
|
-
{exportConfig?.enabled && (
|
|
372
|
+
{(exportConfig?.enabled || excelExport?.enabled) && (
|
|
294
373
|
<div className="mb-2 flex gap-2">
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
374
|
+
{exportConfig?.enabled && (
|
|
375
|
+
<button
|
|
376
|
+
onClick={handleExportCSV}
|
|
377
|
+
className="px-3 py-1.5 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-md transition-colors"
|
|
378
|
+
>
|
|
379
|
+
Export CSV
|
|
380
|
+
</button>
|
|
381
|
+
)}
|
|
382
|
+
{excelExport?.enabled && (
|
|
383
|
+
<button
|
|
384
|
+
onClick={handleExportExcel}
|
|
385
|
+
className="px-3 py-1.5 text-sm font-medium text-white bg-green-600 hover:bg-green-700 rounded-md transition-colors"
|
|
386
|
+
>
|
|
387
|
+
Export Excel (CSV)
|
|
388
|
+
</button>
|
|
389
|
+
)}
|
|
301
390
|
</div>
|
|
302
391
|
)}
|
|
303
392
|
<div
|