@redsift/ds-mcp-server 12.4.0 → 12.5.0-muiv7

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.
Files changed (60) hide show
  1. package/data/demos/patterns/_shared/StateDebugPanel.tsx +153 -0
  2. package/data/demos/patterns/_shared/columns.tsx +12 -3
  3. package/data/demos/patterns/_shared/defaults.ts +1 -1
  4. package/data/demos/patterns/_shared/filter-helpers.ts +1 -1
  5. package/data/demos/patterns/_shared/helpers.tsx +1 -1
  6. package/data/demos/patterns/_shared/server-logic.ts +1 -1
  7. package/data/demos/patterns/_shared/story-helpers.ts +578 -14
  8. package/data/demos/patterns/_shared/use-router-adapter.ts +51 -0
  9. package/data/demos/patterns/crossfiltered-datagrid-client-side/CrossfilteredDatagridClientSide.interaction.stories.tsx +2 -2
  10. package/data/demos/patterns/crossfiltered-datagrid-client-side/example.tsx +2 -2
  11. package/data/demos/patterns/crossfiltered-datagrid-server-side/CrossfilteredDatagridServerSide.interaction.stories.tsx +2 -2
  12. package/data/demos/patterns/crossfiltered-datagrid-server-side/example.tsx +6 -6
  13. package/data/demos/patterns/drilldowned-datagrid-client-side/DrilldownedDatagridClientSide.interaction.stories.tsx +2 -2
  14. package/data/demos/patterns/drilldowned-datagrid-client-side/example.tsx +1 -1
  15. package/data/demos/patterns/drilldowned-datagrid-server-side/DrilldownedDatagridServerSide.interaction.stories.tsx +2 -2
  16. package/data/demos/patterns/drilldowned-datagrid-server-side/example.tsx +1 -1
  17. package/data/demos/patterns/single-datagrid-client-side/SingleDatagridClientSide.interaction.stories.tsx +382 -169
  18. package/data/demos/patterns/single-datagrid-client-side/example.tsx +6 -6
  19. package/data/demos/patterns/single-datagrid-client-side/with-empty-state.tsx +1 -1
  20. package/data/demos/patterns/single-datagrid-client-side/with-error.tsx +1 -1
  21. package/data/demos/patterns/single-datagrid-client-side/with-loading.tsx +1 -1
  22. package/data/demos/patterns/single-datagrid-server-side/SingleDatagridServerSide.interaction.stories.tsx +426 -54
  23. package/data/demos/patterns/single-datagrid-server-side/example.tsx +6 -5
  24. package/data/demos/patterns/stateful-single-datagrid-client-side/StatefulSingleDatagridClientSide.interaction.stories.tsx +671 -0
  25. package/data/demos/patterns/stateful-single-datagrid-client-side/example.tsx +55 -0
  26. package/data/demos/patterns/stateful-single-datagrid-client-side/with-empty-state.tsx +27 -0
  27. package/data/demos/patterns/stateful-single-datagrid-client-side/with-error.tsx +39 -0
  28. package/data/demos/patterns/stateful-single-datagrid-client-side/with-loading.tsx +25 -0
  29. package/data/demos/patterns/stateful-single-datagrid-server-side/StatefulSingleDatagridServerSide.interaction.stories.tsx +692 -0
  30. package/data/demos/patterns/stateful-single-datagrid-server-side/example.tsx +108 -0
  31. package/data/demos/patterns/stateful-single-datagrid-server-side/with-empty-state.tsx +31 -0
  32. package/data/demos/patterns/stateful-single-datagrid-server-side/with-error.tsx +43 -0
  33. package/data/demos/patterns/stateful-single-datagrid-server-side/with-loading.tsx +29 -0
  34. package/data/demos/patterns/summary-dashboard/SummaryDashboard.interaction.stories.tsx +44 -24
  35. package/data/demos/patterns/summary-dashboard/example.tsx +66 -28
  36. package/data/demos/patterns/summary-dashboard/with-loading.tsx +12 -3
  37. package/data/demos/patterns/tabbed-datagrid-client-side/TabbedDatagridClientSide.interaction.stories.tsx +2 -2
  38. package/data/demos/patterns/tabbed-datagrid-server-side/TabbedDatagridServerSide.interaction.stories.tsx +2 -2
  39. package/data/demos/patterns/tabbed-datagrid-server-side/example.tsx +1 -1
  40. package/data/docs/components/dashboard/Dashboard.json +2 -2
  41. package/data/docs/components/table/DataGrid.json +30 -3
  42. package/data/docs/components/table/StatefulDataGrid.json +30 -3
  43. package/data/docs/components-index.json +2 -2
  44. package/data/docs/components.json +64 -10
  45. package/data/docs/llms-full.txt +799 -44
  46. package/data/docs/llms.txt +20 -6
  47. package/data/docs/patterns-catalog.md +25 -24
  48. package/data/docs/patterns.json +82 -8
  49. package/data/metadata.json +2 -2
  50. package/data/patterns/crossfiltered-datagrid-server-side.mdx +1 -1
  51. package/data/patterns/drilldowned-datagrid-client-side.mdx +1 -1
  52. package/data/patterns/drilldowned-datagrid-server-side.mdx +1 -1
  53. package/data/patterns/single-datagrid-client-side.mdx +9 -9
  54. package/data/patterns/single-datagrid-server-side.mdx +6 -6
  55. package/data/patterns/stateful-single-datagrid-client-side.mdx +304 -0
  56. package/data/patterns/stateful-single-datagrid-server-side.mdx +347 -0
  57. package/data/patterns/summary-dashboard.mdx +47 -7
  58. package/data/patterns/tabbed-datagrid-client-side.mdx +72 -2
  59. package/data/patterns/tabbed-datagrid-server-side.mdx +105 -2
  60. package/package.json +2 -2
@@ -0,0 +1,153 @@
1
+ import React, { useCallback, useEffect, useState } from 'react';
2
+ import type { GridApiPro } from '@mui/x-data-grid-pro/models/gridApiPro';
3
+
4
+ // localStorage key categories — must match @redsift/table internals
5
+ const LS_CATEGORIES = [
6
+ 'paginationModel',
7
+ 'searchModel',
8
+ 'sortModel',
9
+ 'visibilityModel',
10
+ 'pinnedColumns',
11
+ 'dimension',
12
+ 'densityModel',
13
+ ];
14
+
15
+ interface StateDebugPanelProps {
16
+ apiRef: React.MutableRefObject<GridApiPro>;
17
+ useRouter: () => { pathname: string; search: string; historyReplace: (newSearch: string) => void };
18
+ localStorageVersion?: number;
19
+ }
20
+
21
+ const sectionStyle: React.CSSProperties = {
22
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',
23
+ fontSize: '11px',
24
+ lineHeight: '1.4',
25
+ padding: '8px 12px',
26
+ borderRadius: '4px',
27
+ overflow: 'auto',
28
+ maxHeight: '200px',
29
+ whiteSpace: 'pre-wrap',
30
+ wordBreak: 'break-all',
31
+ };
32
+
33
+ const labelStyle: React.CSSProperties = {
34
+ fontFamily: 'inherit',
35
+ fontSize: '11px',
36
+ fontWeight: 600,
37
+ cursor: 'pointer',
38
+ userSelect: 'none',
39
+ display: 'flex',
40
+ alignItems: 'center',
41
+ gap: '4px',
42
+ };
43
+
44
+ /**
45
+ * Reads the real DataGrid state from apiRef, URL from useRouter, and localStorage keys.
46
+ * Renders three collapsible JSON panels for debugging.
47
+ */
48
+ export const StateDebugPanel: React.FC<StateDebugPanelProps> = ({ apiRef, useRouter, localStorageVersion = 1 }) => {
49
+ const { pathname, search } = useRouter();
50
+ const [_tick, setTick] = useState(0);
51
+ const rerender = useCallback(() => setTick((t) => t + 1), []);
52
+
53
+ // Subscribe to grid events so we re-read state after every change
54
+ useEffect(() => {
55
+ const api = apiRef.current;
56
+ if (!api?.subscribeEvent) return;
57
+
58
+ const unsubs = [
59
+ api.subscribeEvent('filterModelChange', rerender),
60
+ api.subscribeEvent('sortModelChange', rerender),
61
+ api.subscribeEvent('paginationModelChange', rerender),
62
+ api.subscribeEvent('columnVisibilityModelChange', rerender),
63
+ api.subscribeEvent('pinnedColumnsChange', rerender),
64
+ api.subscribeEvent('stateChange', rerender),
65
+ ];
66
+
67
+ return () => unsubs.forEach((u) => u());
68
+ }, [apiRef, rerender]);
69
+
70
+ // Also update after URL changes (historyReplace doesn't trigger re-render)
71
+ useEffect(() => {
72
+ rerender();
73
+ }, [search, rerender]);
74
+
75
+ // -- Read grid state from apiRef --
76
+ let gridState: Record<string, unknown> = {};
77
+ try {
78
+ const api = apiRef.current;
79
+ if (api?.state) {
80
+ gridState = {
81
+ filterModel: api.state.filter?.filterModel ?? null,
82
+ sortModel: api.state.sorting?.sortModel ?? null,
83
+ paginationModel: api.state.pagination?.paginationModel ?? null,
84
+ columnVisibilityModel: api.state.columns?.columnVisibilityModel ?? null,
85
+ pinnedColumns: api.state.pinnedColumns ?? null,
86
+ density: api.state.density ?? null,
87
+ };
88
+ }
89
+ } catch {
90
+ gridState = { error: 'Grid not yet initialized' };
91
+ }
92
+
93
+ // -- Read URL query params --
94
+ const urlParams: Record<string, string> = {};
95
+ const sp = new URLSearchParams(search);
96
+ sp.forEach((v, k) => {
97
+ urlParams[k] = v;
98
+ });
99
+
100
+ // -- Read localStorage --
101
+ const lsState: Record<string, string | null> = {};
102
+ for (const cat of LS_CATEGORIES) {
103
+ const key = `${pathname}:${localStorageVersion}:${cat}`;
104
+ try {
105
+ const raw = localStorage.getItem(key);
106
+ lsState[cat] = raw;
107
+ } catch {
108
+ lsState[cat] = null;
109
+ }
110
+ }
111
+
112
+ return (
113
+ <div
114
+ data-testid="state-debug-panel"
115
+ style={{
116
+ border: '1px solid #e0e0e0',
117
+ borderRadius: '6px',
118
+ padding: '8px 12px',
119
+ marginBottom: '8px',
120
+ background: '#fafafa',
121
+ fontSize: '11px',
122
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',
123
+ }}
124
+ >
125
+ <div style={{ fontWeight: 700, marginBottom: '6px', fontSize: '12px' }}>State Inspector</div>
126
+ <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
127
+ <Section title="DataGrid State" data={gridState} bg="#f0f4ff" />
128
+ <Section
129
+ title="URL Query Params"
130
+ data={Object.keys(urlParams).length > 0 ? urlParams : '(empty)'}
131
+ bg="#f0fff4"
132
+ />
133
+ <Section title="localStorage" data={lsState} bg="#fff8f0" />
134
+ </div>
135
+ </div>
136
+ );
137
+ };
138
+
139
+ const Section: React.FC<{ title: string; data: unknown; bg: string }> = ({ title, data, bg }) => {
140
+ const [open, setOpen] = useState(true);
141
+ return (
142
+ <div style={{ flex: '1 1 280px', minWidth: '280px' }}>
143
+ <div style={labelStyle} onClick={() => setOpen((o) => !o)}>
144
+ <span>{open ? '▾' : '▸'}</span> {title}
145
+ </div>
146
+ {open && (
147
+ <pre style={{ ...sectionStyle, background: bg, margin: '4px 0 0' }}>
148
+ {typeof data === 'string' ? data : JSON.stringify(data, null, 2)}
149
+ </pre>
150
+ )}
151
+ </div>
152
+ );
153
+ };
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { createColumn, TextCell } from '@redsift/table';
3
3
  import { Flexbox, Icon, IconButtonLink, Pill } from '@redsift/design-system';
4
4
  import { mdiArrowRight, mdiCheck, mdiClose } from '@redsift/icons';
5
- import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid-premium';
5
+ import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid-pro';
6
6
  import { Row } from './data';
7
7
 
8
8
  // -- Option constants -------------------------------------------------------
@@ -80,6 +80,7 @@ export const columns: GridColDef<Row>[] = [
80
80
  field: 'Items',
81
81
  headerName: 'Item',
82
82
  flex: 1,
83
+ display: 'flex',
83
84
  ...createColumn('string'),
84
85
  renderCell: ({ value }: GridRenderCellParams) => <TextCell>{value}</TextCell>,
85
86
  },
@@ -88,6 +89,7 @@ export const columns: GridColDef<Row>[] = [
88
89
  field: 'Category',
89
90
  headerName: 'Category',
90
91
  width: 120,
92
+ display: 'flex',
91
93
  ...createColumn('singleSelect'),
92
94
  valueOptions: CATEGORY_OPTIONS,
93
95
  renderCell: ({ value }: GridRenderCellParams) => <Pill color={categoryColor(value)}>{value}</Pill>,
@@ -97,6 +99,7 @@ export const columns: GridColDef<Row>[] = [
97
99
  field: 'Paid',
98
100
  headerName: 'Price',
99
101
  width: 100,
102
+ display: 'flex',
100
103
  ...createColumn('number'),
101
104
  renderCell: ({ value }: GridRenderCellParams) => <TextCell>{formatCurrency(value as number)}</TextCell>,
102
105
  },
@@ -105,8 +108,9 @@ export const columns: GridColDef<Row>[] = [
105
108
  field: 'Date',
106
109
  headerName: 'Date',
107
110
  width: 140,
111
+ display: 'flex',
108
112
  ...createColumn('date'),
109
- valueGetter: (value: string) => parseDate(value),
113
+ valueGetter: (value: unknown) => parseDate(value),
110
114
  renderCell: ({ value }: GridRenderCellParams) => <TextCell>{value ? formatDate(value as Date) : '—'}</TextCell>,
111
115
  },
112
116
  // DateTime
@@ -114,8 +118,9 @@ export const columns: GridColDef<Row>[] = [
114
118
  field: 'DateTime',
115
119
  headerName: 'Date & Time',
116
120
  width: 180,
121
+ display: 'flex',
117
122
  ...createColumn('dateTime'),
118
- valueGetter: (value: string) => parseDate(value),
123
+ valueGetter: (value: unknown) => parseDate(value),
119
124
  renderCell: ({ value }: GridRenderCellParams) => <TextCell>{value ? formatDateTime(value as Date) : '—'}</TextCell>,
120
125
  },
121
126
  // Boolean — in stock
@@ -123,6 +128,7 @@ export const columns: GridColDef<Row>[] = [
123
128
  field: 'InStock',
124
129
  headerName: 'In Stock',
125
130
  width: 90,
131
+ display: 'flex',
126
132
  type: 'boolean',
127
133
  renderCell: ({ value }: GridRenderCellParams) =>
128
134
  value ? (
@@ -136,6 +142,7 @@ export const columns: GridColDef<Row>[] = [
136
142
  field: 'Allergens',
137
143
  headerName: 'Allergens',
138
144
  flex: 1,
145
+ display: 'flex',
139
146
  ...createColumn('multiSelect'),
140
147
  valueOptions: ALLERGEN_OPTIONS,
141
148
  sortable: false,
@@ -158,6 +165,7 @@ export const columns: GridColDef<Row>[] = [
158
165
  field: 'Tags',
159
166
  headerName: 'Tags',
160
167
  flex: 1,
168
+ display: 'flex',
161
169
  ...createColumn('tags'),
162
170
  valueOptions: TAG_OPTIONS,
163
171
  sortable: false,
@@ -180,6 +188,7 @@ export const columns: GridColDef<Row>[] = [
180
188
  field: 'actions',
181
189
  headerName: '',
182
190
  width: 56,
191
+ display: 'flex',
183
192
  hideable: false,
184
193
  sortable: false,
185
194
  filterable: false,
@@ -1,4 +1,4 @@
1
- import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-premium';
1
+ import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-pro';
2
2
 
3
3
  /**
4
4
  * Default filter model applied to all pattern examples.
@@ -1,4 +1,4 @@
1
- import { GridFilterModel } from '@mui/x-data-grid-premium';
1
+ import { GridFilterModel } from '@mui/x-data-grid-pro';
2
2
  import { Row } from './data';
3
3
 
4
4
  // -- Types ------------------------------------------------------------------
@@ -8,7 +8,7 @@ import {
8
8
  GridToolbarExport,
9
9
  GridToolbarFilterButton,
10
10
  GridToolbarQuickFilter,
11
- } from '@mui/x-data-grid-premium';
11
+ } from '@mui/x-data-grid-pro';
12
12
 
13
13
  // -- Toolbar ----------------------------------------------------------------
14
14
 
@@ -1,4 +1,4 @@
1
- import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-premium';
1
+ import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-pro';
2
2
  import { Row, allRows } from './data';
3
3
  import { Aggregates, computeAggregates, applyFilters } from './filter-helpers';
4
4