Skip to main content

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

  • 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:

  1. Large Datasets: Handle 10k+ rows efficiently
  2. Feature Rich: Sorting, filtering, grouping
  3. Column Customization: Show/hide, reorder, resize
  4. Selection: Row selection for bulk operations
  5. 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

  1. DataGrid Pro: Licensed version with advanced features
  2. Server-Side Mode: Pagination/sorting on backend
  3. Column Configuration: Persisted to localStorage
  4. Row Selection: Checkbox-based multi-select
  5. 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

FeatureDataGridProPremium
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:

  1. State Management: localStorage persistence breaks SRE link-sharing workflows
  2. Reference Stability: rows={data?.items ?? []} creates new array each render → performance issues
  3. Live Data Thrashing: WebSocket updates without throttling overwhelms virtualization
  4. Custom Cell Accessibility: Status chips and action buttons often break focus management

Required Modifications:

  1. 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)
  2. Stable References:
    const stableColumns = useMemo(() => columns, [columns]);
    <DataGridPro getRowId={(row) => row.id} rows={data?.items ?? []} />
  3. Throttle Updates: Buffer live data updates (500ms) before grid re-render
  4. Add filterMode="server": Missing from standard config
  5. Accessibility Audit: Status chips must use text+color (not color alone)
  6. Loading States: Use loading={isLoading} and keepNonExistentRowsSelected
  7. Specify Tier: Document Pro vs Premium decision (Premium only for Excel export, row grouping)

Modifications Applied

  1. Documented URL state synchronization requirement
  2. Added stable reference patterns
  3. Documented live data throttling
  4. 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