@redsift/ds-mcp-server 12.5.0-muiv7 → 12.5.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/data/demos/patterns/_shared/StateDebugPanel.tsx +2 -2
- package/data/demos/patterns/_shared/columns.tsx +3 -3
- package/data/demos/patterns/_shared/defaults.ts +1 -1
- package/data/demos/patterns/_shared/filter-helpers.ts +1 -1
- package/data/demos/patterns/_shared/helpers.tsx +1 -1
- package/data/demos/patterns/_shared/server-logic.ts +1 -1
- package/data/demos/patterns/_shared/story-helpers.ts +55 -38
- package/data/demos/patterns/crossfiltered-datagrid-client-side/CrossfilteredDatagridClientSide.interaction.stories.tsx +2 -2
- package/data/demos/patterns/crossfiltered-datagrid-client-side/example.tsx +2 -2
- package/data/demos/patterns/crossfiltered-datagrid-server-side/CrossfilteredDatagridServerSide.interaction.stories.tsx +2 -2
- package/data/demos/patterns/crossfiltered-datagrid-server-side/example.tsx +5 -5
- package/data/demos/patterns/drilldowned-datagrid-client-side/DrilldownedDatagridClientSide.interaction.stories.tsx +2 -2
- package/data/demos/patterns/drilldowned-datagrid-client-side/example.tsx +1 -1
- package/data/demos/patterns/drilldowned-datagrid-server-side/DrilldownedDatagridServerSide.interaction.stories.tsx +2 -2
- package/data/demos/patterns/drilldowned-datagrid-server-side/example.tsx +1 -1
- package/data/demos/patterns/single-datagrid-client-side/SingleDatagridClientSide.interaction.stories.tsx +3 -3
- package/data/demos/patterns/single-datagrid-client-side/example.tsx +5 -5
- package/data/demos/patterns/single-datagrid-server-side/SingleDatagridServerSide.interaction.stories.tsx +3 -3
- package/data/demos/patterns/single-datagrid-server-side/example.tsx +5 -5
- package/data/demos/patterns/stateful-single-datagrid-client-side/StatefulSingleDatagridClientSide.interaction.stories.tsx +1 -1
- package/data/demos/patterns/stateful-single-datagrid-client-side/example.tsx +4 -4
- package/data/demos/patterns/stateful-single-datagrid-server-side/StatefulSingleDatagridServerSide.interaction.stories.tsx +2 -4
- package/data/demos/patterns/stateful-single-datagrid-server-side/example.tsx +4 -4
- package/data/demos/patterns/summary-dashboard/SummaryDashboard.interaction.stories.tsx +2 -2
- package/data/demos/patterns/tabbed-datagrid-client-side/TabbedDatagridClientSide.interaction.stories.tsx +2 -2
- package/data/demos/patterns/tabbed-datagrid-server-side/TabbedDatagridServerSide.interaction.stories.tsx +2 -2
- package/data/demos/patterns/tabbed-datagrid-server-side/example.tsx +1 -1
- package/data/docs/components/dashboard/Dashboard.json +2 -2
- package/data/docs/components/table/DataGrid.json +3 -30
- package/data/docs/components/table/StatefulDataGrid.json +3 -30
- package/data/docs/components-index.json +2 -2
- package/data/docs/components.json +10 -64
- package/data/docs/llms-full.txt +36 -42
- package/data/docs/llms.txt +6 -6
- package/data/docs/patterns-catalog.md +24 -25
- package/data/docs/patterns.json +4 -4
- package/data/metadata.json +2 -2
- package/data/patterns/crossfiltered-datagrid-server-side.mdx +1 -1
- package/data/patterns/drilldowned-datagrid-client-side.mdx +1 -1
- package/data/patterns/drilldowned-datagrid-server-side.mdx +1 -1
- package/data/patterns/single-datagrid-client-side.mdx +9 -9
- package/data/patterns/single-datagrid-server-side.mdx +4 -4
- package/data/patterns/stateful-single-datagrid-client-side.mdx +1 -1
- package/data/patterns/tabbed-datagrid-server-side.mdx +1 -1
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
|
-
import type {
|
|
2
|
+
import type { GridApiPremium } from '@mui/x-data-grid-premium';
|
|
3
3
|
|
|
4
4
|
// localStorage key categories — must match @redsift/table internals
|
|
5
5
|
const LS_CATEGORIES = [
|
|
@@ -13,7 +13,7 @@ const LS_CATEGORIES = [
|
|
|
13
13
|
];
|
|
14
14
|
|
|
15
15
|
interface StateDebugPanelProps {
|
|
16
|
-
apiRef: React.MutableRefObject<
|
|
16
|
+
apiRef: React.MutableRefObject<GridApiPremium | null>;
|
|
17
17
|
useRouter: () => { pathname: string; search: string; historyReplace: (newSearch: string) => void };
|
|
18
18
|
localStorageVersion?: number;
|
|
19
19
|
}
|
|
@@ -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-
|
|
5
|
+
import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid-premium';
|
|
6
6
|
import { Row } from './data';
|
|
7
7
|
|
|
8
8
|
// -- Option constants -------------------------------------------------------
|
|
@@ -110,7 +110,7 @@ export const columns: GridColDef<Row>[] = [
|
|
|
110
110
|
width: 140,
|
|
111
111
|
display: 'flex',
|
|
112
112
|
...createColumn('date'),
|
|
113
|
-
valueGetter: (value:
|
|
113
|
+
valueGetter: (value: string) => parseDate(value),
|
|
114
114
|
renderCell: ({ value }: GridRenderCellParams) => <TextCell>{value ? formatDate(value as Date) : '—'}</TextCell>,
|
|
115
115
|
},
|
|
116
116
|
// DateTime
|
|
@@ -120,7 +120,7 @@ export const columns: GridColDef<Row>[] = [
|
|
|
120
120
|
width: 180,
|
|
121
121
|
display: 'flex',
|
|
122
122
|
...createColumn('dateTime'),
|
|
123
|
-
valueGetter: (value:
|
|
123
|
+
valueGetter: (value: string) => parseDate(value),
|
|
124
124
|
renderCell: ({ value }: GridRenderCellParams) => <TextCell>{value ? formatDateTime(value as Date) : '—'}</TextCell>,
|
|
125
125
|
},
|
|
126
126
|
// Boolean — in stock
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-
|
|
1
|
+
import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-premium';
|
|
2
2
|
import { Row, allRows } from './data';
|
|
3
3
|
import { Aggregates, computeAggregates, applyFilters } from './filter-helpers';
|
|
4
4
|
|
|
@@ -320,34 +320,37 @@ export const clickHeaderCheckbox = async (canvasElement: HTMLElement) => {
|
|
|
320
320
|
const headerCheckbox = canvasElement.querySelector('.MuiDataGrid-columnHeaderCheckbox input[type="checkbox"]');
|
|
321
321
|
expect(headerCheckbox).toBeTruthy();
|
|
322
322
|
},
|
|
323
|
-
{ timeout:
|
|
323
|
+
{ timeout: 5000 }
|
|
324
324
|
);
|
|
325
325
|
// Small yield to let React finish any pending microtask re-renders
|
|
326
326
|
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
327
327
|
const headerCheckbox = canvasElement.querySelector('.MuiDataGrid-columnHeaderCheckbox input[type="checkbox"]')!;
|
|
328
|
-
fireEvent.click
|
|
328
|
+
// Use userEvent.click for reliable event dispatching — fireEvent.click on a hidden
|
|
329
|
+
// checkbox input doesn't trigger the native change event in Playwright/Chromium,
|
|
330
|
+
// causing server-side pagination grids to miss the selection update.
|
|
331
|
+
await userEvent.click(headerCheckbox);
|
|
329
332
|
// Wait for React and MUI DataGrid to process the selection change
|
|
330
333
|
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
331
334
|
};
|
|
332
335
|
|
|
333
336
|
/** Click a row checkbox by row index (0-based, within the visible page). */
|
|
334
337
|
export const clickRowCheckbox = async (canvasElement: HTMLElement, rowIndex: number) => {
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
338
|
+
// Wait for BOTH the row AND its checkbox to be present.
|
|
339
|
+
// Server-side grids may render rows before checkboxes are mounted.
|
|
340
|
+
await waitFor(
|
|
341
|
+
() => {
|
|
342
|
+
const rows = canvasElement.querySelectorAll('.MuiDataGrid-row');
|
|
343
|
+
expect(rows.length).toBeGreaterThan(rowIndex);
|
|
344
|
+
const cb = rows[rowIndex].querySelector('input[type="checkbox"]');
|
|
345
|
+
expect(cb).toBeTruthy();
|
|
346
|
+
},
|
|
347
|
+
{ timeout: 5000 }
|
|
348
|
+
);
|
|
349
|
+
const rows = canvasElement.querySelectorAll('.MuiDataGrid-row');
|
|
350
|
+
const checkbox = rows[rowIndex].querySelector('input[type="checkbox"]')!;
|
|
343
351
|
await userEvent.click(checkbox);
|
|
344
|
-
// Wait for
|
|
345
|
-
await
|
|
346
|
-
const freshRow = canvasElement.querySelector(`.MuiDataGrid-row[data-rowindex="${rowIndex}"]`);
|
|
347
|
-
const freshCheckbox = freshRow?.querySelector('input[type="checkbox"]') as HTMLInputElement | null;
|
|
348
|
-
expect(freshCheckbox).toBeTruthy();
|
|
349
|
-
expect(freshCheckbox!.checked).toBe(!wasChecked);
|
|
350
|
-
});
|
|
352
|
+
// Wait for React and MUI DataGrid to process the selection change
|
|
353
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
351
354
|
};
|
|
352
355
|
|
|
353
356
|
// ---------------------------------------------------------------------------
|
|
@@ -913,29 +916,42 @@ export const waitForPaginationEnabled = async (canvasElement: HTMLElement, direc
|
|
|
913
916
|
|
|
914
917
|
/**
|
|
915
918
|
* Change the page size via the MUI pagination "Rows per page" select.
|
|
916
|
-
*
|
|
919
|
+
* MUI Material v7's `useSlot()` applies `.MuiTablePagination-select` to the
|
|
920
|
+
* Select wrapper, NOT the inner display div that has the `onMouseDown` handler.
|
|
921
|
+
* We target `[role="combobox"]` inside the pagination toolbar instead, which is
|
|
922
|
+
* the actual interactive element rendered by `SelectInput`.
|
|
923
|
+
* `userEvent.click` in the Storybook Playwright runner doesn't reliably
|
|
924
|
+
* trigger mouseDown on MUI Select, so we use `fireEvent.mouseDown` directly,
|
|
925
|
+
* then `userEvent.click` to select the option in the dropdown.
|
|
917
926
|
*/
|
|
918
927
|
export const changePageSize = async (canvasElement: HTMLElement, newSize: number) => {
|
|
919
|
-
// Wait for the
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
928
|
+
// Wait for the pagination combobox to be present
|
|
929
|
+
await waitFor(
|
|
930
|
+
() => {
|
|
931
|
+
const el = canvasElement.querySelector('.MuiTablePagination-toolbar [role="combobox"]');
|
|
932
|
+
expect(el).toBeTruthy();
|
|
933
|
+
},
|
|
934
|
+
{ timeout: 5000 }
|
|
935
|
+
);
|
|
936
|
+
|
|
937
|
+
const select = canvasElement.querySelector('.MuiTablePagination-toolbar [role="combobox"]') as HTMLElement;
|
|
938
|
+
|
|
939
|
+
// Use fireEvent.mouseDown to reliably open MUI v7 Select dropdown
|
|
929
940
|
fireEvent.mouseDown(select);
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
941
|
+
|
|
942
|
+
// Wait for the dropdown to render (MUI uses a portal on document.body)
|
|
943
|
+
await waitFor(
|
|
944
|
+
() => {
|
|
945
|
+
const options = document.querySelectorAll('[role="option"]');
|
|
946
|
+
expect(options.length).toBeGreaterThan(0);
|
|
947
|
+
},
|
|
948
|
+
{ timeout: 5000 }
|
|
949
|
+
);
|
|
950
|
+
|
|
951
|
+
const options = document.querySelectorAll('[role="option"]');
|
|
936
952
|
const target = Array.from(options).find((opt) => opt.textContent === String(newSize));
|
|
937
953
|
if (!target) throw new Error(`Could not find page size option "${newSize}"`);
|
|
938
|
-
|
|
954
|
+
await userEvent.click(target);
|
|
939
955
|
};
|
|
940
956
|
|
|
941
957
|
// ---------------------------------------------------------------------------
|
|
@@ -949,7 +965,7 @@ export const openColumnsPanel = async (canvasElement: HTMLElement) => {
|
|
|
949
965
|
) as HTMLElement | null;
|
|
950
966
|
if (!btn) throw new Error('Could not find columns toolbar button');
|
|
951
967
|
await userEvent.click(btn);
|
|
952
|
-
// Wait for the panel to appear on document.body
|
|
968
|
+
// Wait for the panel to appear on document.body
|
|
953
969
|
await waitFor(() => {
|
|
954
970
|
const panel = document.querySelector('.MuiDataGrid-columnsManagement');
|
|
955
971
|
expect(panel).toBeTruthy();
|
|
@@ -960,8 +976,9 @@ export const openColumnsPanel = async (canvasElement: HTMLElement) => {
|
|
|
960
976
|
export const toggleColumnInPanel = async (fieldLabel: string) => {
|
|
961
977
|
const panel = document.querySelector('.MuiDataGrid-columnsManagement');
|
|
962
978
|
if (!panel) throw new Error('Columns panel is not open');
|
|
963
|
-
|
|
964
|
-
const
|
|
979
|
+
// MUI v8 renders each column toggle as a baseCheckbox slot with class columnsManagementRow
|
|
980
|
+
const rows = Array.from(panel.querySelectorAll('.MuiDataGrid-columnsManagementRow'));
|
|
981
|
+
const target = rows.find((row) => row.textContent?.includes(fieldLabel));
|
|
965
982
|
if (!target) throw new Error(`Could not find column "${fieldLabel}" in columns panel`);
|
|
966
983
|
const checkbox = target.querySelector('input[type="checkbox"]') as HTMLElement | null;
|
|
967
984
|
if (!checkbox) throw new Error(`Could not find checkbox for column "${fieldLabel}"`);
|
|
@@ -85,9 +85,9 @@ import {
|
|
|
85
85
|
RU7_RM_PASTRY,
|
|
86
86
|
} from '../_shared/expected-values';
|
|
87
87
|
|
|
88
|
-
const meta: Meta
|
|
88
|
+
const meta: Meta = {
|
|
89
89
|
title: 'Patterns/Crossfiltered Datagrid (Client)',
|
|
90
|
-
component: Example,
|
|
90
|
+
component: Example as any,
|
|
91
91
|
};
|
|
92
92
|
export default meta;
|
|
93
93
|
type Story = StoryObj;
|
|
@@ -18,7 +18,7 @@ export default () => (
|
|
|
18
18
|
{/* Category card — two-way: counts update when other cards filter */}
|
|
19
19
|
<WithFilters
|
|
20
20
|
field="Category"
|
|
21
|
-
dimension={(d:
|
|
21
|
+
dimension={(d: any) => d.Category}
|
|
22
22
|
datagridCategoryDimFilter={{ field: 'Category', operator: 'isAnyOf' }}
|
|
23
23
|
syncMode="two-way"
|
|
24
24
|
>
|
|
@@ -51,7 +51,7 @@ export default () => (
|
|
|
51
51
|
{/* Allergens card — two-way */}
|
|
52
52
|
<WithFilters
|
|
53
53
|
field="Allergens"
|
|
54
|
-
dimension={(d:
|
|
54
|
+
dimension={(d: any) => d.Allergens}
|
|
55
55
|
isDimensionArray
|
|
56
56
|
datagridCategoryDimFilter={{ field: 'Allergens', operator: 'hasAnyOf' }}
|
|
57
57
|
syncMode="two-way"
|
|
@@ -84,9 +84,9 @@ import {
|
|
|
84
84
|
RU7_RM_PASTRY,
|
|
85
85
|
} from '../_shared/expected-values';
|
|
86
86
|
|
|
87
|
-
const meta: Meta
|
|
87
|
+
const meta: Meta = {
|
|
88
88
|
title: 'Patterns/Crossfiltered Datagrid (Server)',
|
|
89
|
-
component: Example,
|
|
89
|
+
component: Example as any,
|
|
90
90
|
parameters: {
|
|
91
91
|
msw: { handlers: bakeryHandlers },
|
|
92
92
|
},
|
|
@@ -4,7 +4,7 @@ import { Flexbox } from '@redsift/design-system';
|
|
|
4
4
|
import { DataCard, DataRow } from '@redsift/dashboard';
|
|
5
5
|
import { BarChart, PieChart, ArcDatum, BarDatum } from '@redsift/charts';
|
|
6
6
|
import { mdiShapeOutline, mdiToggleSwitch, mdiFoodOff } from '@redsift/icons';
|
|
7
|
-
import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-
|
|
7
|
+
import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-premium';
|
|
8
8
|
import { Row } from '../_shared/data';
|
|
9
9
|
import { columns, CATEGORY_OPTIONS, ALLERGEN_OPTIONS } from '../_shared/columns';
|
|
10
10
|
import { fetchBakeryData, FetchResult } from '../_shared/api-client';
|
|
@@ -208,7 +208,7 @@ export default () => {
|
|
|
208
208
|
data={itemsChartData}
|
|
209
209
|
sliceRole="option"
|
|
210
210
|
onSliceClick={(datum: ArcDatum) => {
|
|
211
|
-
const key = datum.data.key
|
|
211
|
+
const key = datum.data.key;
|
|
212
212
|
setFilterModel((prev) => {
|
|
213
213
|
const selected = getSelectedFromFilterModel(prev, 'Items');
|
|
214
214
|
const next = selected.includes(key) ? selected.filter((v) => v !== key) : [...selected, key];
|
|
@@ -217,7 +217,7 @@ export default () => {
|
|
|
217
217
|
setPage(0);
|
|
218
218
|
}}
|
|
219
219
|
isSliceSelected={(datum: ArcDatum) =>
|
|
220
|
-
itemsSelection.length === 0 || itemsSelection.includes(datum.data.key
|
|
220
|
+
itemsSelection.length === 0 || itemsSelection.includes(datum.data.key)
|
|
221
221
|
}
|
|
222
222
|
/>
|
|
223
223
|
|
|
@@ -239,7 +239,7 @@ export default () => {
|
|
|
239
239
|
data={tagsChartData}
|
|
240
240
|
barRole="option"
|
|
241
241
|
onBarClick={(datum: BarDatum) => {
|
|
242
|
-
const key = datum.data.key
|
|
242
|
+
const key = String(datum.data.key);
|
|
243
243
|
setFilterModel((prev) => {
|
|
244
244
|
const selected = getSelectedFromFilterModel(prev, 'Tags');
|
|
245
245
|
const next = selected.includes(key) ? selected.filter((v) => v !== key) : [...selected, key];
|
|
@@ -248,7 +248,7 @@ export default () => {
|
|
|
248
248
|
setPage(0);
|
|
249
249
|
}}
|
|
250
250
|
isBarSelected={(datum: BarDatum) =>
|
|
251
|
-
tagsSelection.length === 0 || tagsSelection.includes(datum.data.key
|
|
251
|
+
tagsSelection.length === 0 || tagsSelection.includes(String(datum.data.key))
|
|
252
252
|
}
|
|
253
253
|
/>
|
|
254
254
|
</Flexbox>
|
|
@@ -34,9 +34,9 @@ import {
|
|
|
34
34
|
ALLERGENS_HASANYOF_GLUTEN,
|
|
35
35
|
} from '../_shared/expected-values';
|
|
36
36
|
|
|
37
|
-
const meta: Meta
|
|
37
|
+
const meta: Meta = {
|
|
38
38
|
title: 'Patterns/Drilldowned Datagrid (Client)',
|
|
39
|
-
component: Example,
|
|
39
|
+
component: Example as any,
|
|
40
40
|
};
|
|
41
41
|
export default meta;
|
|
42
42
|
type Story = StoryObj;
|
|
@@ -3,7 +3,7 @@ import { DataGrid } from '@redsift/table';
|
|
|
3
3
|
import { Flexbox } from '@redsift/design-system';
|
|
4
4
|
import { DataCard, DataRow } from '@redsift/dashboard';
|
|
5
5
|
import { mdiShapeOutline, mdiToggleSwitch, mdiFoodOff } from '@redsift/icons';
|
|
6
|
-
import { GridFilterModel } from '@mui/x-data-grid-
|
|
6
|
+
import { GridFilterModel } from '@mui/x-data-grid-premium';
|
|
7
7
|
import { rows } from '../_shared/data';
|
|
8
8
|
import { columns, CATEGORY_OPTIONS, ALLERGEN_OPTIONS } from '../_shared/columns';
|
|
9
9
|
import { CustomToolbar } from '../_shared/helpers';
|
|
@@ -35,9 +35,9 @@ import {
|
|
|
35
35
|
ALLERGENS_HASANYOF_GLUTEN,
|
|
36
36
|
} from '../_shared/expected-values';
|
|
37
37
|
|
|
38
|
-
const meta: Meta
|
|
38
|
+
const meta: Meta = {
|
|
39
39
|
title: 'Patterns/Drilldowned Datagrid (Server)',
|
|
40
|
-
component: Example,
|
|
40
|
+
component: Example as any,
|
|
41
41
|
parameters: {
|
|
42
42
|
msw: { handlers: bakeryHandlers },
|
|
43
43
|
},
|
|
@@ -3,7 +3,7 @@ import { DataGrid } from '@redsift/table';
|
|
|
3
3
|
import { Flexbox } from '@redsift/design-system';
|
|
4
4
|
import { DataCard, DataRow } from '@redsift/dashboard';
|
|
5
5
|
import { mdiShapeOutline, mdiToggleSwitch, mdiFoodOff } from '@redsift/icons';
|
|
6
|
-
import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-
|
|
6
|
+
import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-premium';
|
|
7
7
|
import { Row } from '../_shared/data';
|
|
8
8
|
import { columns, CATEGORY_OPTIONS, ALLERGEN_OPTIONS } from '../_shared/columns';
|
|
9
9
|
import { fetchBakeryData, FetchResult } from '../_shared/api-client';
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
3
|
import { within, userEvent } from '@storybook/testing-library';
|
|
4
4
|
import { expect } from '@storybook/jest';
|
|
5
|
-
import { GridFilterModel } from '@mui/x-data-grid-
|
|
5
|
+
import { GridFilterModel } from '@mui/x-data-grid-premium';
|
|
6
6
|
|
|
7
7
|
import Example from './example';
|
|
8
8
|
import WithLoadingExample from './with-loading';
|
|
@@ -51,9 +51,9 @@ import {
|
|
|
51
51
|
TAGS_HASANYOF_LOCAL_NEW,
|
|
52
52
|
} from '../_shared/expected-values';
|
|
53
53
|
|
|
54
|
-
const meta: Meta
|
|
54
|
+
const meta: Meta = {
|
|
55
55
|
title: 'Patterns/Single Datagrid (Client)',
|
|
56
|
-
component: Example,
|
|
56
|
+
component: Example as any,
|
|
57
57
|
};
|
|
58
58
|
export default meta;
|
|
59
59
|
type Story = StoryObj;
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
|
-
import { DataGrid } from '@redsift/table';
|
|
2
|
+
import { DataGrid, EMPTY_ROW_SELECTION_MODEL, getSelectionCount } from '@redsift/table';
|
|
3
3
|
import { Flexbox } from '@redsift/design-system';
|
|
4
|
-
import { GridFilterModel, GridRowSelectionModel } from '@mui/x-data-grid-
|
|
4
|
+
import { GridFilterModel, GridRowSelectionModel } from '@mui/x-data-grid-premium';
|
|
5
5
|
import { rows } from '../_shared/data';
|
|
6
6
|
import { columns } from '../_shared/columns';
|
|
7
7
|
import { CustomToolbar, BulkActionBar } from '../_shared/helpers';
|
|
8
8
|
import { DEFAULT_FILTER_MODEL, DEFAULT_SORT_MODEL } from '../_shared/defaults';
|
|
9
9
|
|
|
10
10
|
export default ({ initialFilterModel }: { initialFilterModel?: GridFilterModel }) => {
|
|
11
|
-
const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>(
|
|
11
|
+
const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>(EMPTY_ROW_SELECTION_MODEL);
|
|
12
12
|
|
|
13
13
|
return (
|
|
14
14
|
<div style={{ width: '100%' }}>
|
|
15
15
|
<Flexbox flexDirection="column" gap="0px">
|
|
16
16
|
<BulkActionBar
|
|
17
|
-
count={selectionModel
|
|
17
|
+
count={getSelectionCount(selectionModel)}
|
|
18
18
|
onLog={() => console.log('Selected:', selectionModel)}
|
|
19
19
|
onDelete={() => console.log('Delete:', selectionModel)}
|
|
20
20
|
/>
|
|
@@ -22,8 +22,8 @@ export default ({ initialFilterModel }: { initialFilterModel?: GridFilterModel }
|
|
|
22
22
|
<DataGrid
|
|
23
23
|
autoHeight
|
|
24
24
|
pagination
|
|
25
|
+
density="compact"
|
|
25
26
|
initialState={{
|
|
26
|
-
density: 'compact',
|
|
27
27
|
filter: { filterModel: initialFilterModel ?? DEFAULT_FILTER_MODEL },
|
|
28
28
|
sorting: { sortModel: DEFAULT_SORT_MODEL },
|
|
29
29
|
pagination: { paginationModel: { page: 0, pageSize: 10 } },
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
3
|
import { within, userEvent } from '@storybook/testing-library';
|
|
4
4
|
import { expect } from '@storybook/jest';
|
|
5
|
-
import { GridFilterModel } from '@mui/x-data-grid-
|
|
5
|
+
import { GridFilterModel } from '@mui/x-data-grid-premium';
|
|
6
6
|
|
|
7
7
|
import Example from './example';
|
|
8
8
|
import WithLoadingExample from './with-loading';
|
|
@@ -54,9 +54,9 @@ import {
|
|
|
54
54
|
TAGS_HASANYOF_LOCAL_NEW,
|
|
55
55
|
} from '../_shared/expected-values';
|
|
56
56
|
|
|
57
|
-
const meta: Meta
|
|
57
|
+
const meta: Meta = {
|
|
58
58
|
title: 'Patterns/Single Datagrid (Server)',
|
|
59
|
-
component: Example,
|
|
59
|
+
component: Example as any,
|
|
60
60
|
parameters: {
|
|
61
61
|
msw: { handlers: bakeryHandlers },
|
|
62
62
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
-
import { DataGrid } from '@redsift/table';
|
|
2
|
+
import { DataGrid, EMPTY_ROW_SELECTION_MODEL, getSelectionCount } from '@redsift/table';
|
|
3
3
|
import { Flexbox } from '@redsift/design-system';
|
|
4
|
-
import { GridFilterModel, GridRowSelectionModel, GridSortModel } from '@mui/x-data-grid-
|
|
4
|
+
import { GridFilterModel, GridRowSelectionModel, GridSortModel } from '@mui/x-data-grid-premium';
|
|
5
5
|
import { Row } from '../_shared/data';
|
|
6
6
|
import { columns } from '../_shared/columns';
|
|
7
7
|
import { fetchBakeryData } from '../_shared/api-client';
|
|
@@ -16,7 +16,7 @@ export default ({ initialFilterModel }: { initialFilterModel?: GridFilterModel }
|
|
|
16
16
|
const [pageSize, setPageSize] = useState(10);
|
|
17
17
|
const [sortModel, setSortModel] = useState<GridSortModel>(DEFAULT_SORT_MODEL);
|
|
18
18
|
const [filterModel, setFilterModel] = useState<GridFilterModel>(initialFilterModel ?? DEFAULT_FILTER_MODEL);
|
|
19
|
-
const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>(
|
|
19
|
+
const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>(EMPTY_ROW_SELECTION_MODEL);
|
|
20
20
|
|
|
21
21
|
const quickFilterText = (filterModel as { quickFilterValues?: string[] }).quickFilterValues?.join(' ') || '';
|
|
22
22
|
const debounceRef = useRef<ReturnType<typeof setTimeout>>();
|
|
@@ -54,7 +54,7 @@ export default ({ initialFilterModel }: { initialFilterModel?: GridFilterModel }
|
|
|
54
54
|
<div style={{ width: '100%' }}>
|
|
55
55
|
<Flexbox flexDirection="column" gap="0px">
|
|
56
56
|
<BulkActionBar
|
|
57
|
-
count={selectionModel
|
|
57
|
+
count={getSelectionCount(selectionModel)}
|
|
58
58
|
onLog={() => console.log('Selected:', selectionModel)}
|
|
59
59
|
onDelete={() => console.log('Delete:', selectionModel)}
|
|
60
60
|
/>
|
|
@@ -62,7 +62,7 @@ export default ({ initialFilterModel }: { initialFilterModel?: GridFilterModel }
|
|
|
62
62
|
<DataGrid
|
|
63
63
|
autoHeight
|
|
64
64
|
pagination
|
|
65
|
-
|
|
65
|
+
density="compact"
|
|
66
66
|
paginationMode="server"
|
|
67
67
|
sortingMode="server"
|
|
68
68
|
filterMode="server"
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
3
|
import { within, userEvent } from '@storybook/testing-library';
|
|
4
4
|
import { expect } from '@storybook/jest';
|
|
5
|
-
import { GridFilterModel } from '@mui/x-data-grid-
|
|
5
|
+
import { GridFilterModel } from '@mui/x-data-grid-premium';
|
|
6
6
|
|
|
7
7
|
import Example from './example';
|
|
8
8
|
import WithLoadingExample from './with-loading';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
|
-
import { StatefulDataGrid } from '@redsift/table';
|
|
2
|
+
import { StatefulDataGrid, EMPTY_ROW_SELECTION_MODEL, getSelectionCount } from '@redsift/table';
|
|
3
3
|
import { Flexbox } from '@redsift/design-system';
|
|
4
|
-
import { GridFilterModel, GridRowSelectionModel, useGridApiRef } from '@mui/x-data-grid-
|
|
4
|
+
import { GridFilterModel, GridRowSelectionModel, useGridApiRef } from '@mui/x-data-grid-premium';
|
|
5
5
|
import { rows } from '../_shared/data';
|
|
6
6
|
import { columns } from '../_shared/columns';
|
|
7
7
|
import { CustomToolbar, BulkActionBar } from '../_shared/helpers';
|
|
@@ -16,14 +16,14 @@ interface Props {
|
|
|
16
16
|
|
|
17
17
|
export default ({ initialFilterModel, useRouter = useRouterAdapter }: Props) => {
|
|
18
18
|
const apiRef = useGridApiRef();
|
|
19
|
-
const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>(
|
|
19
|
+
const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>(EMPTY_ROW_SELECTION_MODEL);
|
|
20
20
|
|
|
21
21
|
return (
|
|
22
22
|
<div style={{ width: '100%' }}>
|
|
23
23
|
<StateDebugPanel apiRef={apiRef} useRouter={useRouter} localStorageVersion={1} />
|
|
24
24
|
<Flexbox flexDirection="column" gap="0px">
|
|
25
25
|
<BulkActionBar
|
|
26
|
-
count={selectionModel
|
|
26
|
+
count={getSelectionCount(selectionModel)}
|
|
27
27
|
onLog={() => console.log('Selected:', selectionModel)}
|
|
28
28
|
onDelete={() => console.log('Delete:', selectionModel)}
|
|
29
29
|
/>
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
3
|
import { within, userEvent } from '@storybook/testing-library';
|
|
4
4
|
import { expect } from '@storybook/jest';
|
|
5
|
-
import { GridFilterModel } from '@mui/x-data-grid-
|
|
5
|
+
import { GridFilterModel } from '@mui/x-data-grid-premium';
|
|
6
6
|
|
|
7
7
|
import Example from './example';
|
|
8
8
|
import WithLoadingExample from './with-loading';
|
|
@@ -385,9 +385,7 @@ export const SelectionPersistsAcrossPages: Story = {
|
|
|
385
385
|
await waitForServerResponse(canvas);
|
|
386
386
|
await assertDisplayedRowsText(canvasElement, '11–20 of 14,075');
|
|
387
387
|
await assertBulkActionBarVisible(canvasElement, 2);
|
|
388
|
-
|
|
389
|
-
// No page-2 rows are selected, so the header is unchecked (not indeterminate).
|
|
390
|
-
await assertHeaderCheckboxState(canvasElement, 'unchecked');
|
|
388
|
+
await assertHeaderCheckboxState(canvasElement, 'indeterminate');
|
|
391
389
|
await assertRowCheckboxChecked(canvasElement, 0, false);
|
|
392
390
|
await assertAllStatesInSync({ getSearch });
|
|
393
391
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
-
import { StatefulDataGrid } from '@redsift/table';
|
|
2
|
+
import { StatefulDataGrid, EMPTY_ROW_SELECTION_MODEL, getSelectionCount } from '@redsift/table';
|
|
3
3
|
import { Flexbox } from '@redsift/design-system';
|
|
4
|
-
import { GridFilterModel, GridRowSelectionModel, GridSortModel, useGridApiRef } from '@mui/x-data-grid-
|
|
4
|
+
import { GridFilterModel, GridRowSelectionModel, GridSortModel, useGridApiRef } from '@mui/x-data-grid-premium';
|
|
5
5
|
import { Row } from '../_shared/data';
|
|
6
6
|
import { columns } from '../_shared/columns';
|
|
7
7
|
import { fetchBakeryData } from '../_shared/api-client';
|
|
@@ -20,7 +20,7 @@ export default ({ initialFilterModel, useRouter = useRouterAdapter }: Props) =>
|
|
|
20
20
|
const [rows, setRows] = useState<Row[]>([]);
|
|
21
21
|
const [totalRows, setTotalRows] = useState(0);
|
|
22
22
|
const [loading, setLoading] = useState(true);
|
|
23
|
-
const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>(
|
|
23
|
+
const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>(EMPTY_ROW_SELECTION_MODEL);
|
|
24
24
|
|
|
25
25
|
// Refs track the latest model values so fetchData() always reads current state.
|
|
26
26
|
// StatefulDataGrid manages filter/sort/pagination internally — we use callbacks
|
|
@@ -55,7 +55,7 @@ export default ({ initialFilterModel, useRouter = useRouterAdapter }: Props) =>
|
|
|
55
55
|
<StateDebugPanel apiRef={apiRef} useRouter={useRouter} localStorageVersion={1} />
|
|
56
56
|
<Flexbox flexDirection="column" gap="0px">
|
|
57
57
|
<BulkActionBar
|
|
58
|
-
count={selectionModel
|
|
58
|
+
count={getSelectionCount(selectionModel)}
|
|
59
59
|
onLog={() => console.log('Selected:', selectionModel)}
|
|
60
60
|
onDelete={() => console.log('Delete:', selectionModel)}
|
|
61
61
|
/>
|
|
@@ -24,9 +24,9 @@ import {
|
|
|
24
24
|
} from '../_shared/story-helpers';
|
|
25
25
|
import { AGG_CATEGORY, AGG_ALLERGENS, AGG_INSTOCK } from '../_shared/expected-values';
|
|
26
26
|
|
|
27
|
-
const meta: Meta
|
|
27
|
+
const meta: Meta = {
|
|
28
28
|
title: 'Patterns/Summary Dashboard',
|
|
29
|
-
component: Example,
|
|
29
|
+
component: Example as any,
|
|
30
30
|
};
|
|
31
31
|
export default meta;
|
|
32
32
|
type Story = StoryObj;
|
|
@@ -16,9 +16,9 @@ import {
|
|
|
16
16
|
} from '../_shared/story-helpers';
|
|
17
17
|
import { TOTAL, CATEGORY_BAKERY, CATEGORY_BEVERAGE, CATEGORY_PASTRY, CATEGORY_OTHER } from '../_shared/expected-values';
|
|
18
18
|
|
|
19
|
-
const meta: Meta
|
|
19
|
+
const meta: Meta = {
|
|
20
20
|
title: 'Patterns/Tabbed Datagrid (Client)',
|
|
21
|
-
component: Example,
|
|
21
|
+
component: Example as any,
|
|
22
22
|
};
|
|
23
23
|
export default meta;
|
|
24
24
|
type Story = StoryObj;
|
|
@@ -18,9 +18,9 @@ import {
|
|
|
18
18
|
} from '../_shared/story-helpers';
|
|
19
19
|
import { TOTAL, CATEGORY_BAKERY, CATEGORY_BEVERAGE, CATEGORY_PASTRY, CATEGORY_OTHER } from '../_shared/expected-values';
|
|
20
20
|
|
|
21
|
-
const meta: Meta
|
|
21
|
+
const meta: Meta = {
|
|
22
22
|
title: 'Patterns/Tabbed Datagrid (Server)',
|
|
23
|
-
component: Example,
|
|
23
|
+
component: Example as any,
|
|
24
24
|
parameters: {
|
|
25
25
|
msw: { handlers: bakeryHandlers },
|
|
26
26
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { DataGrid } from '@redsift/table';
|
|
3
3
|
import { Flexbox, Pill, Number, Text, Tabs, Tab } from '@redsift/design-system';
|
|
4
|
-
import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-
|
|
4
|
+
import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-premium';
|
|
5
5
|
import { Row } from '../_shared/data';
|
|
6
6
|
import { columns, CATEGORY_OPTIONS } from '../_shared/columns';
|
|
7
7
|
import { fetchBakeryData } from '../_shared/api-client';
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"name": "dataGridApiRef",
|
|
17
|
-
"description": "Datagrid API Ref.",
|
|
18
|
-
"type": "MutableRefObject<
|
|
17
|
+
"description": "Datagrid API Ref. MUI v8: can be null initially.",
|
|
18
|
+
"type": "MutableRefObject<GridApiPremium | null>",
|
|
19
19
|
"required": false,
|
|
20
20
|
"defaultValue": null,
|
|
21
21
|
"category": "props"
|