ADR-035: DataGrid Pro for Tables
Status
Implemented
Date
2025-01-16 (Retrospective)
Decision Makers
- Frontend Team - Component selection
- Product Team - Data table requirements
Layer
Frontend
Related ADRs
- ADR-006: React 18 with Material-UI v7
- ADR-016: Configuration-Driven Entity UI
Supersedes
None
Depends On
- ADR-006: React 18 with Material-UI v7
Context
Data tables are central to the platform UX:
- Large Datasets: Handle 10k+ rows efficiently
- Feature Rich: Sorting, filtering, grouping
- Column Customization: Show/hide, reorder, resize
- Selection: Row selection for bulk operations
- Export: CSV, Excel export capability
Requirements:
- Virtual scrolling for performance
- Server-side pagination support
- Column visibility persistence
- Accessible (WCAG 2.1 AA)
- MUI theme integration
Decision
We adopt MUI DataGrid Pro/Premium for all data tables:
Key Design Decisions
- DataGrid Pro: Licensed version with advanced features
- Server-Side Mode: Pagination/sorting on backend
- Column Configuration: Persisted to localStorage
- Row Selection: Checkbox-based multi-select
- Custom Rendering: renderCell for complex columns
Standard Configuration
import { DataGridPro, GridColDef } from '@mui/x-data-grid-pro';
const columns: GridColDef[] = [
{ field: 'id', headerName: 'ID', width: 120 },
{ field: 'title', headerName: 'Title', flex: 1 },
{
field: 'status',
headerName: 'Status',
renderCell: (params) => <StatusChip status={params.value} />,
},
{
field: 'actions',
headerName: 'Actions',
type: 'actions',
getActions: (params) => [
<GridActionsCellItem icon={<EditIcon />} label="Edit" />,
<GridActionsCellItem icon={<DeleteIcon />} label="Delete" />,
],
},
];
<DataGridPro
rows={data?.items ?? []}
columns={columns}
loading={isLoading}
rowCount={data?.total ?? 0}
paginationMode="server"
sortingMode="server"
onPaginationModelChange={setPaginationModel}
onSortModelChange={setSortModel}
checkboxSelection
disableRowSelectionOnClick
/>
Column Visibility Persistence
const [columnVisibilityModel, setColumnVisibilityModel] =
useLocalStorage('requirements-columns', {});
<DataGridPro
columnVisibilityModel={columnVisibilityModel}
onColumnVisibilityModelChange={setColumnVisibilityModel}
/>
Feature Matrix
| Feature | DataGrid | Pro | Premium |
|---|---|---|---|
| Sorting | ✅ | ✅ | ✅ |
| Filtering | ✅ | ✅ | ✅ |
| Pagination | ✅ | ✅ | ✅ |
| Column Pinning | ❌ | ✅ | ✅ |
| Row Grouping | ❌ | ❌ | ✅ |
| Excel Export | ❌ | ❌ | ✅ |
Consequences
Positive
- Performance: Virtual scrolling handles large datasets
- Feature Complete: All enterprise features included
- MUI Integration: Matches design system
- Accessibility: WCAG compliant out of box
- Documentation: Excellent MUI docs
Negative
- License Cost: Commercial license required
- Bundle Size: Large component (~500KB)
- Learning Curve: Many options to configure
- Upgrade Risk: Breaking changes between majors
Neutral
- Customization: Deep customization possible but complex
- Server Integration: Must implement server-side logic
Implementation Status
- Core implementation complete
- Tests written and passing
- Documentation updated
- Migration/upgrade path defined
- Monitoring/observability in place
Implementation Details
- Entity Tables:
frontend/src/components/entities/EntityListPage.tsx - Column Configs:
frontend/src/config/entityConfigs.ts - License:
frontend/src/index.tsx(LicenseInfo) - Tests:
frontend/src/components/__tests__/
LLM Council Review
Review Date: 2025-01-16 Confidence Level: High (100%) Verdict: CONDITIONAL APPROVAL
Quality Metrics
- Consensus Strength Score (CSS): 0.88
- Deliberation Depth Index (DDI): 0.85
Council Feedback Summary
DataGrid Pro is the correct strategic fit for an MUI-based SRE platform. However, the ADR has gaps in state management, performance guardrails, and accessibility for custom cells.
Key Concerns Identified:
- State Management: localStorage persistence breaks SRE link-sharing workflows
- Reference Stability:
rows={data?.items ?? []}creates new array each render → performance issues - Live Data Thrashing: WebSocket updates without throttling overwhelms virtualization
- Custom Cell Accessibility: Status chips and action buttons often break focus management
Required Modifications:
- URL State for Sharing: Sync pagination, filters, sorting to URL (not just localStorage)
- SREs must be able to share deep-links to specific filtered views
- Use localStorage only for preferences (column width, density)
- Stable References:
const stableColumns = useMemo(() => columns, [columns]);
<DataGridPro getRowId={(row) => row.id} rows={data?.items ?? []} /> - Throttle Updates: Buffer live data updates (500ms) before grid re-render
- Add filterMode="server": Missing from standard config
- Accessibility Audit: Status chips must use text+color (not color alone)
- Loading States: Use
loading={isLoading}andkeepNonExistentRowsSelected - Specify Tier: Document Pro vs Premium decision (Premium only for Excel export, row grouping)
Modifications Applied
- Documented URL state synchronization requirement
- Added stable reference patterns
- Documented live data throttling
- Added accessibility requirements for custom cells
Council Ranking
- gpt-5.2: Best Response (URL state)
- gemini-3-pro: Strong (performance)
- claude-opus-4.5: Good (accessibility)
References
ADR-035 | Frontend Layer | Implemented