@linzjs/step-ag-grid 21.0.0 → 21.0.1
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/dist/index.css +3 -4
- package/dist/src/components/PostSortRowsHook.d.ts +1 -1
- package/dist/src/contexts/GridContext.d.ts +2 -2
- package/dist/step-ag-grid.cjs.js +41 -42
- package/dist/step-ag-grid.cjs.js.map +1 -1
- package/dist/step-ag-grid.esm.js +41 -42
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +4 -4
- package/src/components/Grid.tsx +6 -5
- package/src/components/PostSortRowsHook.ts +5 -5
- package/src/components/gridHeader/GridHeaderSelect.tsx +10 -8
- package/src/contexts/GridContext.tsx +2 -2
- package/src/contexts/GridContextProvider.tsx +24 -28
- package/src/stories/grid/GridDragRow.stories.tsx +9 -3
- package/src/stories/grid/GridPopoverEditDropDown.stories.tsx +9 -0
- package/src/styles/Grid.scss +3 -6
package/dist/step-ag-grid.esm.js
CHANGED
|
@@ -300,15 +300,15 @@ const usePostSortRowsHook = ({ setStaleGrid }) => {
|
|
|
300
300
|
// As a sort on a stale row should just resort, not change sort direction
|
|
301
301
|
const previousColSort = useRef([]);
|
|
302
302
|
const previousQuickFilter = useRef("");
|
|
303
|
-
return useCallback(({ api,
|
|
303
|
+
return useCallback(({ api, nodes }) => {
|
|
304
304
|
// Grid is destroyed
|
|
305
|
-
if (!api
|
|
305
|
+
if (!api)
|
|
306
306
|
return;
|
|
307
307
|
const previousRowSortIndex = previousRowSortIndexRef.current;
|
|
308
308
|
const hashNode = (node) => {
|
|
309
309
|
return node ? JSON.stringify(node.data) : "";
|
|
310
310
|
};
|
|
311
|
-
const copyCurrentSortSettings = () =>
|
|
311
|
+
const copyCurrentSortSettings = () => api.getColumnState().map((row) => ({ colId: row.colId, sort: row.sort, sortIndex: row.sortIndex }));
|
|
312
312
|
const backupSortOrder = () => {
|
|
313
313
|
for (const x in previousRowSortIndex)
|
|
314
314
|
delete previousRowSortIndex[x];
|
|
@@ -317,7 +317,7 @@ const usePostSortRowsHook = ({ setStaleGrid }) => {
|
|
|
317
317
|
// Check if column is the first sorted column. Note: column is preconfigured to sort its sortIndex is null not 1
|
|
318
318
|
const isFirstSortColumn = (row) => row.sort && [0, null].includes(row.sortIndex ?? null);
|
|
319
319
|
const isSameColumnAndDifferentSort = (col1, col2) => col1 && col2 && col1.colId === col2.colId && col1.sort != col2.sort;
|
|
320
|
-
const restorePreviousSortColumnState = () =>
|
|
320
|
+
const restorePreviousSortColumnState = () => api.applyColumnState({ state: previousColSort.current });
|
|
321
321
|
const sortNodesByPreviousSort = () => {
|
|
322
322
|
nodes.sort((a, b) => (previousRowSortIndex[`${a.data.id}`]?.index ?? Number.MAX_SAFE_INTEGER) -
|
|
323
323
|
(previousRowSortIndex[`${b.data.id}`]?.index ?? Number.MAX_SAFE_INTEGER));
|
|
@@ -395,7 +395,7 @@ const usePostSortRowsHook = ({ setStaleGrid }) => {
|
|
|
395
395
|
wasStale = true;
|
|
396
396
|
}
|
|
397
397
|
else if (changedRowCount === 2 && newRowCount === 0) {
|
|
398
|
-
// This must be a swap rows
|
|
398
|
+
// This must be a swap rows (sometimes it's not, needs further attention)
|
|
399
399
|
backupSortOrder();
|
|
400
400
|
wasStale = false;
|
|
401
401
|
}
|
|
@@ -443,13 +443,15 @@ const GridHeaderSelect = ({ api }) => {
|
|
|
443
443
|
// This is used to force an update on selection change
|
|
444
444
|
const [updateCounter, setUpdateCounter] = useState(0);
|
|
445
445
|
const selectedNodeCount = api.getSelectedRows().length;
|
|
446
|
-
const clickHandler = useCallback(() => {
|
|
447
|
-
setUpdateCounter(updateCounter + 1);
|
|
448
|
-
}, [updateCounter]);
|
|
449
446
|
useEffect(() => {
|
|
447
|
+
const clickHandler = () => {
|
|
448
|
+
setUpdateCounter(updateCounter + 1);
|
|
449
|
+
};
|
|
450
450
|
api.addEventListener("selectionChanged", clickHandler);
|
|
451
|
-
return () =>
|
|
452
|
-
|
|
451
|
+
return () => {
|
|
452
|
+
!api.isDestroyed() && api.removeEventListener("selectionChanged", clickHandler);
|
|
453
|
+
};
|
|
454
|
+
}, [api, updateCounter]);
|
|
453
455
|
const handleMultiSelect = () => {
|
|
454
456
|
if (selectedNodeCount == 0) {
|
|
455
457
|
api.selectAllFiltered();
|
|
@@ -458,7 +460,7 @@ const GridHeaderSelect = ({ api }) => {
|
|
|
458
460
|
api.deselectAll();
|
|
459
461
|
}
|
|
460
462
|
};
|
|
461
|
-
const totalNodeCount = api.
|
|
463
|
+
const totalNodeCount = api.getDisplayedRowCount();
|
|
462
464
|
const partialSelect = selectedNodeCount != 0 && selectedNodeCount != totalNodeCount;
|
|
463
465
|
const allSelected = selectedNodeCount != 0 && selectedNodeCount == totalNodeCount;
|
|
464
466
|
return (jsx("div", { className: clsx("ag-wrapper ag-input-wrapper ag-checkbox-input-wrapper", partialSelect && "ag-indeterminate", allSelected && "ag-checked"), onClick: handleMultiSelect, children: jsx("input", { type: "checkbox", className: "ag-checkbox-input-wrapper", onChange: () => {
|
|
@@ -2363,13 +2365,13 @@ const Grid = ({ "data-testid": dataTestId, rowSelection = "multiple", suppressCo
|
|
|
2363
2365
|
if (gridRendered === "empty") {
|
|
2364
2366
|
if (!hasSetContentSizeEmpty.current && result && !hasSetContentSize.current) {
|
|
2365
2367
|
hasSetContentSizeEmpty.current = true;
|
|
2366
|
-
params.onContentSize
|
|
2368
|
+
params.onContentSize?.(result);
|
|
2367
2369
|
}
|
|
2368
2370
|
}
|
|
2369
2371
|
else if (gridRendered === "rows-visible") {
|
|
2370
2372
|
if (result && !hasSetContentSize.current) {
|
|
2371
2373
|
hasSetContentSize.current = true;
|
|
2372
|
-
params.onContentSize
|
|
2374
|
+
params.onContentSize?.(result);
|
|
2373
2375
|
}
|
|
2374
2376
|
}
|
|
2375
2377
|
else {
|
|
@@ -2396,7 +2398,7 @@ const Grid = ({ "data-testid": dataTestId, rowSelection = "multiple", suppressCo
|
|
|
2396
2398
|
needsAutoSize.current = true;
|
|
2397
2399
|
}
|
|
2398
2400
|
}
|
|
2399
|
-
if (needsAutoSize.current) {
|
|
2401
|
+
if (needsAutoSize.current || (!hasSetContentSize.current && sizeColumns === "auto")) {
|
|
2400
2402
|
needsAutoSize.current = false;
|
|
2401
2403
|
setInitialContentSize();
|
|
2402
2404
|
}
|
|
@@ -2556,7 +2558,7 @@ const Grid = ({ "data-testid": dataTestId, rowSelection = "multiple", suppressCo
|
|
|
2556
2558
|
* When grid is ready set the apis to the grid context and sync selected items to grid.
|
|
2557
2559
|
*/
|
|
2558
2560
|
const onGridReady = useCallback((event) => {
|
|
2559
|
-
setApis(event.api,
|
|
2561
|
+
setApis(event.api, dataTestId);
|
|
2560
2562
|
event.api.showNoRowsOverlay();
|
|
2561
2563
|
synchroniseExternallySelectedItemsToGrid();
|
|
2562
2564
|
}, [dataTestId, setApis, synchroniseExternallySelectedItemsToGrid]);
|
|
@@ -2777,7 +2779,7 @@ const Grid = ({ "data-testid": dataTestId, rowSelection = "multiple", suppressCo
|
|
|
2777
2779
|
}
|
|
2778
2780
|
const moved = event.node.data;
|
|
2779
2781
|
const target = event.overNode?.data;
|
|
2780
|
-
moved.id
|
|
2782
|
+
moved.id !== target?.id && //moved over a different row
|
|
2781
2783
|
event.node.rowIndex != targetIndex && //moved to a different index
|
|
2782
2784
|
params.onRowDragEnd &&
|
|
2783
2785
|
(await params.onRowDragEnd(moved, target, targetIndex));
|
|
@@ -2787,7 +2789,7 @@ const Grid = ({ "data-testid": dataTestId, rowSelection = "multiple", suppressCo
|
|
|
2787
2789
|
// This is setting a ref in the GridContext so won't be triggering an update loop
|
|
2788
2790
|
setOnCellEditingComplete(params.onCellEditingComplete);
|
|
2789
2791
|
const headerRowCount = columnDefs.some((c) => c.children) ? 2 : 1;
|
|
2790
|
-
return (jsxs("div", { "data-testid": dataTestId, className: clsx("Grid-container", theme, "theme-specific", staleGrid && "Grid-sortIsStale", gridReady && rowData && autoSized && "Grid-ready"), children: [gridContextMenu.component, jsx("div", { style: { flex: 1 }, ref: gridDivRef, children: jsx(AgGridReact, { rowHeight: rowHeight, animateRows: params.animateRows ?? false, rowClassRules: params.rowClassRules, getRowId: (params) => `${params.data.id}`, suppressRowClickSelection: true, rowSelection: rowSelection, suppressBrowserResizeObserver: true, onGridSizeChanged: onGridSizeChanged, suppressColumnVirtualisation: suppressColumnVirtualization, suppressClickEdit: true, onColumnVisible: () => {
|
|
2792
|
+
return (jsxs("div", { "data-testid": dataTestId, className: clsx("Grid-container", theme, "theme-specific", staleGrid && "Grid-sortIsStale", gridReady && rowData && autoSized && "Grid-ready"), children: [gridContextMenu.component, jsx("div", { style: { flex: 1 }, ref: gridDivRef, children: jsx(AgGridReact, { reactiveCustomComponents: true, rowHeight: rowHeight, animateRows: params.animateRows ?? false, rowClassRules: params.rowClassRules, getRowId: (params) => `${params.data.id}`, suppressRowClickSelection: true, rowSelection: rowSelection, suppressBrowserResizeObserver: true, onGridSizeChanged: onGridSizeChanged, suppressColumnVirtualisation: suppressColumnVirtualization, suppressClickEdit: true, onColumnVisible: () => {
|
|
2791
2793
|
setInitialContentSize();
|
|
2792
2794
|
}, onRowDataUpdated: onRowDataChanged, onCellKeyDown: onCellKeyPress, onCellClicked: onCellClicked, onCellDoubleClicked: onCellDoubleClick, onCellEditingStarted: refreshSelectedRows, domLayout: params.domLayout, onColumnResized: onColumnResized, defaultColDef: { minWidth: 48, ...omit(params.defaultColDef, ["editable"]) }, columnDefs: columnDefsAdjusted, rowData: rowData, noRowsOverlayComponent: (event) => {
|
|
2793
2795
|
let rowCount = 0;
|
|
@@ -4551,7 +4553,6 @@ const isFlexColumn = (colDef) => !!colDef.flex && !isGridCellFiller(colDef);
|
|
|
4551
4553
|
const GridContextProvider = (props) => {
|
|
4552
4554
|
const { modifyUpdating, checkUpdating } = useContext(GridUpdatingContext);
|
|
4553
4555
|
const [gridApi, setGridApi] = useState();
|
|
4554
|
-
const [columnApi, setColumnApi] = useState();
|
|
4555
4556
|
const [gridReady, setGridReady] = useState(false);
|
|
4556
4557
|
const [quickFilter, setQuickFilter] = useState("");
|
|
4557
4558
|
const [invisibleColumnIds, _setInvisibleColumnIds] = useState();
|
|
@@ -4568,7 +4569,7 @@ const GridContextProvider = (props) => {
|
|
|
4568
4569
|
* Set quick filter directly on grid, based on previously save quickFilter state.
|
|
4569
4570
|
*/
|
|
4570
4571
|
useEffect(() => {
|
|
4571
|
-
gridApi?.
|
|
4572
|
+
gridApi?.setGridOption("quickFilterText", quickFilter);
|
|
4572
4573
|
}, [gridApi, quickFilter]);
|
|
4573
4574
|
/**
|
|
4574
4575
|
* Wraps things that require gridApi in common handling, for when gridApi not present.
|
|
@@ -4614,21 +4615,19 @@ const GridContextProvider = (props) => {
|
|
|
4614
4615
|
/**
|
|
4615
4616
|
* Set the grid api when the grid is ready.
|
|
4616
4617
|
*/
|
|
4617
|
-
const setApis = useCallback((gridApi,
|
|
4618
|
+
const setApis = useCallback((gridApi, dataTestId) => {
|
|
4618
4619
|
testId.current = dataTestId;
|
|
4619
4620
|
setGridApi(gridApi);
|
|
4620
|
-
|
|
4621
|
-
gridApi?.setQuickFilter(quickFilter);
|
|
4621
|
+
gridApi?.setGridOption("quickFilterText", quickFilter);
|
|
4622
4622
|
setGridReady(!!gridApi);
|
|
4623
4623
|
}, [quickFilter]);
|
|
4624
4624
|
/**
|
|
4625
4625
|
* Used to check if it's OK to autosize.
|
|
4626
4626
|
*/
|
|
4627
4627
|
const gridRenderState = useCallback(() => {
|
|
4628
|
-
|
|
4629
|
-
if (!gridApi || !gridApi.getModel())
|
|
4628
|
+
if (!gridApi)
|
|
4630
4629
|
return null;
|
|
4631
|
-
if (!gridApi.
|
|
4630
|
+
if (!gridApi.getDisplayedRowCount())
|
|
4632
4631
|
return "empty";
|
|
4633
4632
|
if (!isEmpty(gridApi.getRenderedNodes()))
|
|
4634
4633
|
return "rows-visible";
|
|
@@ -4701,7 +4700,7 @@ const GridContextProvider = (props) => {
|
|
|
4701
4700
|
/**
|
|
4702
4701
|
* Get ColDefs, with flattened ColGroupDefs
|
|
4703
4702
|
*/
|
|
4704
|
-
const getColumns = useCallback((filterDef = () => true) => filter(
|
|
4703
|
+
const getColumns = useCallback((filterDef = () => true) => filter(gridApi?.getColumns()?.map((col) => col.getColDef()) ?? [], filterDef), [gridApi]);
|
|
4705
4704
|
const getColumnIds = useCallback((filterDef = () => true) => compact(getColumns(filterDef).map(getColId)), [getColumns]);
|
|
4706
4705
|
/**
|
|
4707
4706
|
* Internal method for selecting and flashing rows.
|
|
@@ -4824,22 +4823,22 @@ const GridContextProvider = (props) => {
|
|
|
4824
4823
|
* Resize columns to fit container
|
|
4825
4824
|
*/
|
|
4826
4825
|
const autoSizeColumns = useCallback(({ skipHeader, colIds, userSizedColIds, includeFlex } = {}) => {
|
|
4827
|
-
if (!
|
|
4826
|
+
if (!gridApi)
|
|
4828
4827
|
return null;
|
|
4829
4828
|
const colIdsSet = colIds instanceof Set ? colIds : new Set(colIds);
|
|
4830
|
-
const colsToResize =
|
|
4829
|
+
const colsToResize = gridApi.getColumnState().filter((colState) => {
|
|
4831
4830
|
const colId = colState.colId;
|
|
4832
4831
|
return ((isEmpty(colIdsSet) || colIdsSet.has(colId)) &&
|
|
4833
4832
|
!userSizedColIds?.has(colId) &&
|
|
4834
4833
|
(includeFlex || !colState.flex));
|
|
4835
4834
|
});
|
|
4836
4835
|
if (!isEmpty(colsToResize)) {
|
|
4837
|
-
|
|
4836
|
+
gridApi.autoSizeColumns(colsToResize.map((colState) => colState.colId), skipHeader);
|
|
4838
4837
|
}
|
|
4839
4838
|
return {
|
|
4840
|
-
width: sumBy(
|
|
4839
|
+
width: sumBy(gridApi.getColumnState().filter((col) => !col.hide), "width"),
|
|
4841
4840
|
};
|
|
4842
|
-
}, [
|
|
4841
|
+
}, [gridApi]);
|
|
4843
4842
|
/**
|
|
4844
4843
|
* Resize columns to fit container
|
|
4845
4844
|
*/
|
|
@@ -4888,7 +4887,7 @@ const GridContextProvider = (props) => {
|
|
|
4888
4887
|
*/
|
|
4889
4888
|
const cancelEdit = useCallback(() => {
|
|
4890
4889
|
stopEditing();
|
|
4891
|
-
cellEditingCompleteCallbackRef.current
|
|
4890
|
+
cellEditingCompleteCallbackRef.current?.();
|
|
4892
4891
|
}, [stopEditing]);
|
|
4893
4892
|
const cellEditingCompleteCallbackRef = useRef();
|
|
4894
4893
|
const setOnCellEditingComplete = useCallback((cellEditingCompleteCallback) => {
|
|
@@ -4960,7 +4959,7 @@ const GridContextProvider = (props) => {
|
|
|
4960
4959
|
}
|
|
4961
4960
|
else {
|
|
4962
4961
|
// Don't set saving if ok as the form has already closed
|
|
4963
|
-
setSaving
|
|
4962
|
+
setSaving?.(false);
|
|
4964
4963
|
}
|
|
4965
4964
|
// Only focus next cell if user hasn't already manually changed focus
|
|
4966
4965
|
const postPopupFocusedCell = gridApi.getFocusedCell();
|
|
@@ -5017,7 +5016,7 @@ const GridContextProvider = (props) => {
|
|
|
5017
5016
|
* Apply column visibility
|
|
5018
5017
|
*/
|
|
5019
5018
|
useEffect(() => {
|
|
5020
|
-
if (!
|
|
5019
|
+
if (!gridApi || !invisibleColumnIds)
|
|
5021
5020
|
return;
|
|
5022
5021
|
// show all columns that aren't invisible
|
|
5023
5022
|
const newVisibleColumns = getColumns((col) => !col.lockVisible && col.colId && !invisibleColumnIds.includes(col.colId) && !isGridCellFiller(col));
|
|
@@ -5027,22 +5026,22 @@ const GridContextProvider = (props) => {
|
|
|
5027
5026
|
const fillerColumn = getColumns(isGridCellFiller)[0];
|
|
5028
5027
|
fillerColumn && newVisibleColumns.push(fillerColumn);
|
|
5029
5028
|
}
|
|
5030
|
-
|
|
5029
|
+
gridApi.setColumnsVisible(compact(newVisibleColumns.map(getColId)), true);
|
|
5031
5030
|
// Hide the filler column if there's already a flex column
|
|
5032
5031
|
const invisibleColumnIdsWithOptionalFiller = visibleColumnsContainsAFlex
|
|
5033
5032
|
? [...invisibleColumnIds, GridCellFillerColId]
|
|
5034
5033
|
: invisibleColumnIds;
|
|
5035
|
-
|
|
5036
|
-
}, [invisibleColumnIds,
|
|
5034
|
+
gridApi.setColumnsVisible(invisibleColumnIdsWithOptionalFiller, false);
|
|
5035
|
+
}, [invisibleColumnIds, getColumns, gridApi]);
|
|
5037
5036
|
/**
|
|
5038
5037
|
* Download visible columns as a CSV
|
|
5039
5038
|
*/
|
|
5040
5039
|
const downloadCsv = useCallback((csvExportParams) => {
|
|
5041
|
-
if (!gridApi
|
|
5040
|
+
if (!gridApi)
|
|
5042
5041
|
return;
|
|
5043
5042
|
const fileName = csvExportParams?.fileName && sanitiseFileName(fnOrVar(csvExportParams.fileName));
|
|
5044
|
-
const columnKeys =
|
|
5045
|
-
|
|
5043
|
+
const columnKeys = gridApi
|
|
5044
|
+
.getColumnState()
|
|
5046
5045
|
.filter((cs) => {
|
|
5047
5046
|
const colDef = gridApi.getColumnDef(cs.colId);
|
|
5048
5047
|
return !cs.hide && colDef && !isGridCellFiller(colDef) && colDef.headerComponentParams?.exportable !== false;
|
|
@@ -5054,7 +5053,7 @@ const GridContextProvider = (props) => {
|
|
|
5054
5053
|
...csvExportParams,
|
|
5055
5054
|
fileName,
|
|
5056
5055
|
});
|
|
5057
|
-
}, [
|
|
5056
|
+
}, [gridApi]);
|
|
5058
5057
|
return (jsx(GridContext.Provider, { value: {
|
|
5059
5058
|
gridRenderState,
|
|
5060
5059
|
getColDef,
|
|
@@ -5136,7 +5135,7 @@ const downloadCsvUseValueFormattersProcessCellCallback = (params) => {
|
|
|
5136
5135
|
console.error(`downloadCsv: String type (registered) value formatters are unsupported in downloadCsv, colId: ${colDef.colId}`);
|
|
5137
5136
|
return encodeToString(params.value);
|
|
5138
5137
|
}
|
|
5139
|
-
const result = valueFormatter({ ...params, data: params.node?.data, colDef });
|
|
5138
|
+
const result = valueFormatter({ ...params, data: params.node?.data, colDef, node: null });
|
|
5140
5139
|
// type may not be string due to casting, leave the type check in
|
|
5141
5140
|
if (params.value != null && typeof result !== "string") {
|
|
5142
5141
|
console.error(`downloadCsv: valueFormatter is returning non string values, colDef:", colId: ${colDef.colId}`);
|