11import * as React from "react"
22import { AgGridReact } from "ag-grid-react"
3- import type {
4- ColDef ,
5- GridReadyEvent ,
6- CellClickedEvent ,
7- GridApi ,
8- ICellRendererParams
3+ import {
4+ ModuleRegistry ,
5+ AllCommunityModule ,
6+ type ColDef ,
7+ type GridReadyEvent ,
8+ type CellClickedEvent ,
9+ type GridApi ,
10+ type ICellRendererParams
911} from "ag-grid-community"
12+
13+ // Register AG Grid Modules
14+ ModuleRegistry . registerModules ( [ AllCommunityModule ] ) ;
15+
1016import "ag-grid-community/styles/ag-grid.css"
1117import "ag-grid-community/styles/ag-theme-alpine.css"
1218import { format } from "date-fns"
@@ -79,25 +85,19 @@ const BooleanCellRenderer = (props: ICellRendererParams) => {
7985/**
8086 * Cell renderer for date/datetime fields
8187 */
82- const DateCellRenderer = ( props : ICellRendererParams ) => {
83- const { value, colDef } = props
88+ const DateCellRenderer = ( props : ICellRendererParams & { fieldType ?: FieldType } ) => {
89+ const { value, fieldType } = props
8490
8591 if ( ! value ) {
8692 return < span className = "text-muted-foreground" > -</ span >
8793 }
8894
8995 try {
90- const date = value instanceof Date ? value : new Date ( value )
91-
92- // Check if date is valid
96+ const date = new Date ( value )
9397 if ( isNaN ( date . getTime ( ) ) ) {
9498 return < span className = "text-muted-foreground" > { String ( value ) } </ span >
9599 }
96100
97- // Format based on field type from colDef
98- const extendedColDef = colDef as ExtendedColDef
99- const fieldType = extendedColDef . fieldType
100-
101101 if ( fieldType === 'datetime' ) {
102102 return (
103103 < div className = "flex items-center gap-1.5" >
@@ -121,15 +121,13 @@ const DateCellRenderer = (props: ICellRendererParams) => {
121121/**
122122 * Cell renderer for number fields (including currency and percent)
123123 */
124- const NumberCellRenderer = ( props : ICellRendererParams ) => {
125- const { value, colDef } = props
124+ const NumberCellRenderer = ( props : ICellRendererParams & { fieldType ?: FieldType } ) => {
125+ const { value, fieldType } = props
126126
127127 if ( value === null || value === undefined ) {
128128 return < span className = "text-muted-foreground" > -</ span >
129129 }
130130
131- const extendedColDef = colDef as ExtendedColDef
132- const fieldType = extendedColDef . fieldType
133131 const num = Number ( value )
134132
135133 if ( isNaN ( num ) ) {
@@ -158,10 +156,9 @@ const NumberCellRenderer = (props: ICellRendererParams) => {
158156/**
159157 * Cell renderer for select fields with options
160158 */
161- const SelectCellRenderer = ( props : ICellRendererParams ) => {
162- const { value, colDef } = props
163- const extendedColDef = colDef as ExtendedColDef
164- const options = extendedColDef . fieldOptions || [ ]
159+ const SelectCellRenderer = ( props : ICellRendererParams & { fieldOptions ?: any [ ] } ) => {
160+ const { value, fieldOptions } = props
161+ const options = fieldOptions || [ ]
165162
166163 if ( ! value ) {
167164 return < span className = "text-muted-foreground" > -</ span >
@@ -337,26 +334,32 @@ function getCellRendererForFieldType(fieldType: FieldType): any {
337334/**
338335 * Generate AG Grid column definitions from ObjectQL object metadata
339336 */
340- function generateColumnDefs ( objectConfig : ObjectConfig ) : ExtendedColDef [ ] {
341- const columnDefs : ExtendedColDef [ ] = [ ]
337+ function generateColumnDefs ( objectConfig : ObjectConfig ) : ColDef [ ] {
338+ const columnDefs : ColDef [ ] = [ ]
342339
343340 const fields = objectConfig . fields || { }
344341
345- Object . entries ( fields ) . forEach ( ( [ fieldName , fieldConfig ] : [ string , FieldConfig ] ) => {
342+ const entries : [ string , FieldConfig ] [ ] = Array . isArray ( fields )
343+ ? fields . map ( ( f : any ) => [ f . name , f ] )
344+ : Object . entries ( fields ) ;
345+
346+ entries . forEach ( ( [ fieldName , fieldConfig ] : [ string , FieldConfig ] ) => {
346347 // Skip hidden fields
347348 if ( fieldConfig . hidden ) {
348349 return
349350 }
350351
351- const colDef : ExtendedColDef = {
352+ const colDef : ColDef = {
352353 field : fieldName ,
353354 headerName : fieldConfig . label || fieldName ,
354355 sortable : true ,
355356 filter : true ,
356357 resizable : true ,
357358 // Store field type and options for cell renderers
358- fieldType : fieldConfig . type ,
359- fieldOptions : fieldConfig . options ,
359+ cellRendererParams : {
360+ fieldType : fieldConfig . type ,
361+ fieldOptions : fieldConfig . options ,
362+ }
360363 }
361364
362365 // Set appropriate cell renderer based on field type
@@ -435,24 +438,33 @@ export function ObjectGridTable({
435438 onSelectionChanged ( selectedRows )
436439 } , [ gridApi , onSelectionChanged ] )
437440
441+ const selection = React . useMemo ( ( ) => {
442+ if ( ! rowSelection ) return undefined ;
443+ return {
444+ mode : rowSelection === true || rowSelection === 'multiple' ? 'multiRow' : 'singleRow' ,
445+ enableClickSelection : false ,
446+ } as const ;
447+ } , [ rowSelection ] ) ;
448+
438449 return (
439450 < div
440451 className = "ag-theme-alpine dark:ag-theme-alpine-dark overflow-hidden rounded-lg border"
441452 style = { { height : typeof height === 'number' ? `${ height } px` : height , width : '100%' } }
442453 >
443454 < AgGridReact
455+ theme = "legacy"
444456 ref = { gridRef }
445457 rowData = { data }
446458 columnDefs = { columnDefs }
447459 defaultColDef = { defaultColDef }
448460 onGridReady = { handleGridReady }
449461 onCellClicked = { onCellClicked }
450462 onSelectionChanged = { handleSelectionChanged }
451- rowSelection = { rowSelection === true ? 'multiple' : rowSelection || undefined }
452- suppressRowClickSelection = { true }
463+ rowSelection = { selection }
453464 animateRows = { true }
454465 pagination = { pagination }
455466 paginationPageSize = { pageSize }
467+ paginationPageSizeSelector = { [ 10 , 20 , 50 , 100 ] }
456468 getRowId = { ( params ) => params . data . _id || params . data . id }
457469 />
458470 </ div >
0 commit comments