@linzjs/step-ag-grid 14.9.4 → 15.0.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/README.md +5 -0
- package/dist/src/components/GridCellFiller.d.ts +4 -0
- package/dist/src/components/gridUtil.d.ts +3 -0
- package/dist/src/components/index.d.ts +1 -0
- package/dist/src/contexts/GridContext.d.ts +2 -1
- package/dist/step-ag-grid.cjs.js +27801 -0
- package/dist/step-ag-grid.cjs.js.map +1 -0
- package/dist/step-ag-grid.esm.js +60 -42
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +2 -2
- package/src/components/GridCellFiller.tsx +11 -0
- package/src/components/gridFilter/GridFilterColumnsToggle.tsx +43 -53
- package/src/components/gridUtil.ts +6 -0
- package/src/components/index.ts +1 -0
- package/src/contexts/GridContext.tsx +8 -1
- package/src/contexts/GridContextProvider.tsx +53 -31
- package/src/stories/grid/GridReadOnly.stories.tsx +2 -0
package/dist/step-ag-grid.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { LuiMiniSpinner, LuiIcon, LuiButton, LuiCheckboxInput, LuiButtonGroup } from '@linzjs/lui';
|
|
3
3
|
import { AgGridReact } from 'ag-grid-react';
|
|
4
|
-
import { negate, isEmpty, xorBy, last, difference, defer as defer$1, omit, sortBy, findIndex, debounce as debounce$1,
|
|
4
|
+
import { negate, isEmpty, xorBy, last, difference, defer as defer$1, omit, sortBy, findIndex, debounce as debounce$1, delay, partition, pick, groupBy, fromPairs, toPairs, isEqual, compact, filter, sumBy, pull, remove, castArray, flatten } from 'lodash-es';
|
|
5
5
|
import * as React from 'react';
|
|
6
6
|
import { createContext, useContext, useRef, useEffect, useCallback, useState, useMemo, forwardRef, useLayoutEffect, memo, useReducer, cloneElement, useImperativeHandle, Fragment as Fragment$1 } from 'react';
|
|
7
7
|
import ReactDOM, { unstable_batchedUpdates, flushSync, createPortal } from 'react-dom';
|
|
@@ -42,6 +42,10 @@ const GridContext = createContext({
|
|
|
42
42
|
console.error("no context provider for getColumns");
|
|
43
43
|
return [];
|
|
44
44
|
},
|
|
45
|
+
getColumnIds: () => {
|
|
46
|
+
console.error("no context provider for getColumnIds");
|
|
47
|
+
return [];
|
|
48
|
+
},
|
|
45
49
|
invisibleColumnIds: undefined,
|
|
46
50
|
setInvisibleColumnIds: () => {
|
|
47
51
|
console.error("no context provider for setInvisibleColumnIds");
|
|
@@ -1068,6 +1072,14 @@ const GenericCellEditorComponentWrapper = (editor) => {
|
|
|
1068
1072
|
});
|
|
1069
1073
|
};
|
|
1070
1074
|
|
|
1075
|
+
const GridCellFillerColId = "gridCellFiller";
|
|
1076
|
+
const isGridCellFiller = (col) => col.colId === GridCellFillerColId;
|
|
1077
|
+
const GridCellFiller = () => ({
|
|
1078
|
+
colId: GridCellFillerColId,
|
|
1079
|
+
headerName: "",
|
|
1080
|
+
flex: 1,
|
|
1081
|
+
});
|
|
1082
|
+
|
|
1071
1083
|
const Editor = (props) => ({
|
|
1072
1084
|
component: GenericCellEditorComponentWrapper(props.editor),
|
|
1073
1085
|
params: { ...props.editorParams, multiEdit: props.multiEdit },
|
|
@@ -2903,13 +2915,12 @@ const MenuRadioGroup = forwardRef(MenuRadioGroupFr);
|
|
|
2903
2915
|
|
|
2904
2916
|
const GridFilterColumnsToggle = ({ saveState = true }) => {
|
|
2905
2917
|
const [loaded, setLoaded] = useState(false);
|
|
2906
|
-
const { getColumns, invisibleColumnIds, setInvisibleColumnIds } = useContext(GridContext);
|
|
2907
|
-
const columnStorageKey = useMemo(() => isEmpty(
|
|
2918
|
+
const { getColumns, getColumnIds, invisibleColumnIds, setInvisibleColumnIds } = useContext(GridContext);
|
|
2919
|
+
const columnStorageKey = useMemo(() => isEmpty(getColumnIds())
|
|
2908
2920
|
? null // Grid hasn't been initialised yet
|
|
2909
|
-
: "stepAgGrid_invisibleColumnIds_" +
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
.join("_"), [getColumns]);
|
|
2921
|
+
: "stepAgGrid_invisibleColumnIds_" + getColumnIds().join("_"), [getColumnIds]);
|
|
2922
|
+
// infer the invisible ids from colDefs
|
|
2923
|
+
const resetColumns = useCallback(() => setInvisibleColumnIds(getColumnIds("initialHide")), [getColumnIds, setInvisibleColumnIds]);
|
|
2913
2924
|
// Load state on start
|
|
2914
2925
|
useEffect(() => {
|
|
2915
2926
|
if (!columnStorageKey || loaded)
|
|
@@ -2918,10 +2929,7 @@ const GridFilterColumnsToggle = ({ saveState = true }) => {
|
|
|
2918
2929
|
try {
|
|
2919
2930
|
const stored = window.localStorage.getItem(columnStorageKey);
|
|
2920
2931
|
if (!stored) {
|
|
2921
|
-
|
|
2922
|
-
setInvisibleColumnIds(compact(getColumns()
|
|
2923
|
-
.filter((col) => col.initialHide)
|
|
2924
|
-
.map((col) => col.colId)));
|
|
2932
|
+
resetColumns();
|
|
2925
2933
|
}
|
|
2926
2934
|
else {
|
|
2927
2935
|
const invisibleIds = JSON.parse(stored ?? "[]");
|
|
@@ -2941,7 +2949,7 @@ const GridFilterColumnsToggle = ({ saveState = true }) => {
|
|
|
2941
2949
|
}
|
|
2942
2950
|
setLoaded(true);
|
|
2943
2951
|
}
|
|
2944
|
-
}, [columnStorageKey, getColumns, loaded, saveState, setInvisibleColumnIds]);
|
|
2952
|
+
}, [columnStorageKey, getColumns, loaded, resetColumns, saveState, setInvisibleColumnIds]);
|
|
2945
2953
|
// Save state on column visibility change
|
|
2946
2954
|
useEffect(() => {
|
|
2947
2955
|
loaded &&
|
|
@@ -2956,16 +2964,11 @@ const GridFilterColumnsToggle = ({ saveState = true }) => {
|
|
|
2956
2964
|
? invisibleColumnIds.filter((id) => id !== colId)
|
|
2957
2965
|
: [...invisibleColumnIds, colId]);
|
|
2958
2966
|
}, [invisibleColumnIds, setInvisibleColumnIds]);
|
|
2959
|
-
const resetColumns = () => {
|
|
2960
|
-
setInvisibleColumnIds([]);
|
|
2961
|
-
};
|
|
2962
2967
|
const numericRegExp = /^\d+$/;
|
|
2963
2968
|
const isNonManageableColumn = (col) => {
|
|
2964
2969
|
return col.lockVisible || col.colId == null || numericRegExp.test(col.colId);
|
|
2965
2970
|
};
|
|
2966
|
-
return (jsxs(Menu, { menuButton: jsx(GridFilterHeaderIconButton, { icon: "ic_columns", title: "Column visibility" }), menuClassName: "step-ag-grid-react-menu", portal: true, unmountOnClose: true, children: [jsx("div", { className: "GridFilterColumnsToggle-container", children: getColumns()
|
|
2967
|
-
.filter((col) => !!col.headerName)
|
|
2968
|
-
.map((col) => (jsx(MenuItem, { disabled: isNonManageableColumn(col), onClick: (e) => {
|
|
2971
|
+
return (jsxs(Menu, { menuButton: jsx(GridFilterHeaderIconButton, { icon: "ic_columns", title: "Column visibility" }), menuClassName: "step-ag-grid-react-menu", portal: true, unmountOnClose: true, children: [jsx("div", { className: "GridFilterColumnsToggle-container", children: getColumns("headerName").map((col) => (jsx(MenuItem, { disabled: isNonManageableColumn(col), onClick: (e) => {
|
|
2969
2972
|
// Global react-menu MenuItem handler handles tabs
|
|
2970
2973
|
if (e.key !== "Tab") {
|
|
2971
2974
|
e.keepOpen = true;
|
|
@@ -4444,6 +4447,9 @@ const GridPopoverTextInput = (colDef, params) => GridCell(colDef, {
|
|
|
4444
4447
|
|
|
4445
4448
|
const GridWrapper = ({ children, maxHeight }) => (jsx("div", { className: "Grid-wrapper", style: { maxHeight }, children: children }));
|
|
4446
4449
|
|
|
4450
|
+
const getColId = (colDef) => colDef.colId ?? "";
|
|
4451
|
+
const isFlexColumn = (colDef) => !!colDef.flex && !isGridCellFiller(colDef);
|
|
4452
|
+
|
|
4447
4453
|
/**
|
|
4448
4454
|
* Context for AgGrid operations.
|
|
4449
4455
|
* Make sure you wrap AgGrid in this.
|
|
@@ -4455,12 +4461,16 @@ const GridContextProvider = (props) => {
|
|
|
4455
4461
|
const [columnApi, setColumnApi] = useState();
|
|
4456
4462
|
const [gridReady, setGridReady] = useState(false);
|
|
4457
4463
|
const [quickFilter, setQuickFilter] = useState("");
|
|
4458
|
-
const [invisibleColumnIds,
|
|
4464
|
+
const [invisibleColumnIds, _setInvisibleColumnIds] = useState();
|
|
4459
4465
|
const testId = useRef();
|
|
4460
4466
|
const idsBeforeUpdate = useRef([]);
|
|
4461
4467
|
const prePopupFocusedCell = useRef();
|
|
4462
4468
|
const [externallySelectedItemsAreInSync, setExternallySelectedItemsAreInSync] = useState(false);
|
|
4463
4469
|
const externalFilters = useRef([]);
|
|
4470
|
+
/**
|
|
4471
|
+
* Make extra sure the GridCellFillerColId never gets added to invisibleColumnIds as it's dynamically determined
|
|
4472
|
+
*/
|
|
4473
|
+
const setInvisibleColumnIds = (invisibleColumnIds) => _setInvisibleColumnIds(pull(invisibleColumnIds, GridCellFillerColId));
|
|
4464
4474
|
/**
|
|
4465
4475
|
* Set quick filter directly on grid, based on previously save quickFilter state.
|
|
4466
4476
|
*/
|
|
@@ -4560,9 +4570,7 @@ const GridContextProvider = (props) => {
|
|
|
4560
4570
|
* Uses beforeUpdate ids to find new nodes.
|
|
4561
4571
|
*/
|
|
4562
4572
|
const _getNewNodes = useCallback(() => {
|
|
4563
|
-
return gridApiOp((gridApi) => difference(_getAllRowIds(), idsBeforeUpdate.current)
|
|
4564
|
-
.map((rowId) => gridApi.getRowNode("" + rowId)) //
|
|
4565
|
-
.filter((r) => r), () => []);
|
|
4573
|
+
return gridApiOp((gridApi) => compact(difference(_getAllRowIds(), idsBeforeUpdate.current).map((rowId) => gridApi.getRowNode("" + rowId))), () => []);
|
|
4566
4574
|
}, [_getAllRowIds, gridApiOp]);
|
|
4567
4575
|
/**
|
|
4568
4576
|
* Get grid nodes via rowIds. If rowIds has no matching node the result may be smaller than expected.
|
|
@@ -4571,14 +4579,13 @@ const GridContextProvider = (props) => {
|
|
|
4571
4579
|
* @param rowIds Row ids to get from grid.
|
|
4572
4580
|
*/
|
|
4573
4581
|
const _rowIdsToNodes = useCallback((rowIds) => {
|
|
4574
|
-
return gridApiOp((gridApi) => rowIds
|
|
4575
|
-
.map((rowId) => gridApi.getRowNode("" + rowId)) //
|
|
4576
|
-
.filter((r) => r), () => []);
|
|
4582
|
+
return gridApiOp((gridApi) => compact(rowIds.map((rowId) => gridApi.getRowNode("" + rowId))), () => []);
|
|
4577
4583
|
}, [gridApiOp]);
|
|
4578
4584
|
/**
|
|
4579
4585
|
* Get ColDefs, with flattened ColGroupDefs
|
|
4580
4586
|
*/
|
|
4581
|
-
const getColumns = useCallback(() => columnApi?.getAllColumns()?.map((col) => col.getColDef()) ?? [], [columnApi]);
|
|
4587
|
+
const getColumns = useCallback((filterDef = () => true) => filter(columnApi?.getAllColumns()?.map((col) => col.getColDef()) ?? [], filterDef), [columnApi]);
|
|
4588
|
+
const getColumnIds = useCallback((filterDef = () => true) => compact(getColumns(filterDef).map(getColId)), [getColumns]);
|
|
4582
4589
|
/**
|
|
4583
4590
|
* Internal method for selecting and flashing rows.
|
|
4584
4591
|
*
|
|
@@ -4837,9 +4844,7 @@ const GridContextProvider = (props) => {
|
|
|
4837
4844
|
});
|
|
4838
4845
|
}, [gridApiOp, modifyUpdating, selectNextEditableCell]);
|
|
4839
4846
|
const redrawRows = useCallback((rowNodes) => {
|
|
4840
|
-
gridApiOp((gridApi) => {
|
|
4841
|
-
gridApi.redrawRows(rowNodes ? { rowNodes } : undefined);
|
|
4842
|
-
});
|
|
4847
|
+
gridApiOp((gridApi) => gridApi.redrawRows(rowNodes ? { rowNodes } : undefined));
|
|
4843
4848
|
}, [gridApiOp]);
|
|
4844
4849
|
// waitForExternallySelectedItemsToBeInSync can't use the state as it won't be updated during function execution
|
|
4845
4850
|
const externallySelectedItemsAreInSyncRef = useRef(false);
|
|
@@ -4863,20 +4868,29 @@ const GridContextProvider = (props) => {
|
|
|
4863
4868
|
remove(externalFilters.current, (v) => v === filter);
|
|
4864
4869
|
onFilterChanged().then();
|
|
4865
4870
|
};
|
|
4866
|
-
const isExternalFilterPresent = () => externalFilters.current
|
|
4867
|
-
const doesExternalFilterPass = (node) =>
|
|
4868
|
-
return externalFilters.current.every((filter) => filter(node.data, node));
|
|
4869
|
-
};
|
|
4871
|
+
const isExternalFilterPresent = () => !isEmpty(externalFilters.current);
|
|
4872
|
+
const doesExternalFilterPass = (node) => externalFilters.current.every((filter) => filter(node.data, node));
|
|
4870
4873
|
const getColDef = useCallback((colId) => (!!colId && gridApi?.getColumnDef(colId)) || undefined, [gridApi]);
|
|
4874
|
+
/**
|
|
4875
|
+
* Apply column visibility
|
|
4876
|
+
*/
|
|
4871
4877
|
useEffect(() => {
|
|
4872
|
-
if (columnApi
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4878
|
+
if (!columnApi || !invisibleColumnIds)
|
|
4879
|
+
return;
|
|
4880
|
+
// show all columns that aren't invisible
|
|
4881
|
+
const newVisibleColumns = getColumns((col) => !col.lockVisible && col.colId && !invisibleColumnIds.includes(col.colId) && !isGridCellFiller(col));
|
|
4882
|
+
// If there's no flex column showing add the filler column if defined
|
|
4883
|
+
const visibleColumnsContainsAFlex = newVisibleColumns.some(isFlexColumn);
|
|
4884
|
+
if (!visibleColumnsContainsAFlex) {
|
|
4885
|
+
const fillerColumn = getColumns(isGridCellFiller)[0];
|
|
4886
|
+
fillerColumn && newVisibleColumns.push(fillerColumn);
|
|
4879
4887
|
}
|
|
4888
|
+
columnApi.setColumnsVisible(compact(newVisibleColumns.map(getColId)), true);
|
|
4889
|
+
// Hide the filler column if there's already a flex column
|
|
4890
|
+
const invisibleColumnIdsWithOptionalFiller = visibleColumnsContainsAFlex
|
|
4891
|
+
? [...invisibleColumnIds, GridCellFillerColId]
|
|
4892
|
+
: invisibleColumnIds;
|
|
4893
|
+
columnApi.setColumnsVisible(invisibleColumnIdsWithOptionalFiller, false);
|
|
4880
4894
|
}, [invisibleColumnIds, columnApi, getColumns]);
|
|
4881
4895
|
/**
|
|
4882
4896
|
* Download visible columns as a CSV
|
|
@@ -4887,7 +4901,10 @@ const GridContextProvider = (props) => {
|
|
|
4887
4901
|
const fileName = csvExportParams?.fileName && sanitiseFileName(csvExportParams.fileName);
|
|
4888
4902
|
const columnKeys = columnApi
|
|
4889
4903
|
?.getColumnState()
|
|
4890
|
-
.filter((cs) =>
|
|
4904
|
+
.filter((cs) => {
|
|
4905
|
+
const colDef = gridApi.getColumnDef(cs.colId);
|
|
4906
|
+
return !cs.hide && colDef && !isGridCellFiller(colDef) && colDef.headerComponentParams?.exportable !== false;
|
|
4907
|
+
})
|
|
4891
4908
|
.map((cs) => cs.colId);
|
|
4892
4909
|
gridApi.exportDataAsCsv({
|
|
4893
4910
|
columnKeys,
|
|
@@ -4899,6 +4916,7 @@ const GridContextProvider = (props) => {
|
|
|
4899
4916
|
return (jsx(GridContext.Provider, { value: {
|
|
4900
4917
|
getColDef,
|
|
4901
4918
|
getColumns,
|
|
4919
|
+
getColumnIds,
|
|
4902
4920
|
invisibleColumnIds,
|
|
4903
4921
|
setInvisibleColumnIds,
|
|
4904
4922
|
gridReady,
|
|
@@ -27634,5 +27652,5 @@ const clickActionButton = async (text, container) => {
|
|
|
27634
27652
|
});
|
|
27635
27653
|
};
|
|
27636
27654
|
|
|
27637
|
-
export { ActionButton, ComponentLoadingWrapper, ControlledMenu, Editor, FocusableItem, FormError, GenericCellEditorComponentWrapper, Grid, GridCell, GridCellMultiEditor, GridCellMultiSelectClassRules, GridCellRenderer, GridContext, GridContextProvider, GridFilterButtons, GridFilterColumnsToggle, GridFilterDownloadCsvButton, GridFilterHeaderIconButton, GridFilterQuick, GridFilters, GridFormDropDown, GridFormEditBearing, GridFormMessage, GridFormMultiSelect, GridFormMultiSelectGrid, GridFormPopoverMenu, GridFormSubComponentTextArea, GridFormSubComponentTextInput, GridFormTextArea, GridFormTextInput, GridHeaderSelect, GridIcon, GridLoadableCell, GridNoRowsOverlay, GridPopoutEditMultiSelect, GridPopoutEditMultiSelectGrid, GridPopoverContext, GridPopoverContextProvider, GridPopoverEditBearing, GridPopoverEditBearingCorrection, GridPopoverEditBearingCorrectionEditorParams, GridPopoverEditBearingEditorParams, GridPopoverEditDropDown, GridPopoverMenu, GridPopoverMessage, GridPopoverTextArea, GridPopoverTextInput, GridRenderPopoutMenuCell, GridSubComponentContext, GridUpdatingContext, GridUpdatingContextProvider, GridWrapper, Menu, MenuButton, MenuDivider, MenuGroup, MenuHeader, MenuHeaderItem, MenuHeaderString, MenuItem, MenuRadioGroup, MenuSeparator, MenuSeparatorString, PopoutMenuSeparator, SubMenu, TextAreaInput, TextInputFormatted, bearingCorrectionRangeValidator, bearingCorrectionValueFormatter, bearingNumberParser, bearingRangeValidator, bearingStringValidator, bearingValueFormatter, clickActionButton, clickMenuOption, clickMultiSelectOption, closeMenu, closePopover, convertDDToDMS, countRows, deselectRow, downloadCsvUseValueFormattersProcessCellCallback, editCell, findActionButton, findCell, findCellContains, findMenuOption, findMultiSelectOption, findOpenPopover, findParentWithClass, findRow, fnOrVar, generateFilterGetter, getMultiSelectOptions, hasParentClass, isCellReadOnly, isFloat, isNotEmpty, openAndClickMenuOption, openAndFindMenuOption, queryMenuOption, queryRow, sanitiseFileName, selectCell, selectRow, stringByteLengthIsInvalid, suppressCellKeyboardEvents, typeInputByLabel, typeInputByPlaceholder, typeOnlyInput, typeOtherInput, typeOtherTextArea, useDeferredPromise, useGenerateOrDefaultId, useGridContext, useGridFilter, useGridPopoverContext, useGridPopoverHook, useMenuState, usePostSortRowsHook, validateMenuOptions, wait$2 as wait };
|
|
27655
|
+
export { ActionButton, ComponentLoadingWrapper, ControlledMenu, Editor, FocusableItem, FormError, GenericCellEditorComponentWrapper, Grid, GridCell, GridCellFiller, GridCellFillerColId, GridCellMultiEditor, GridCellMultiSelectClassRules, GridCellRenderer, GridContext, GridContextProvider, GridFilterButtons, GridFilterColumnsToggle, GridFilterDownloadCsvButton, GridFilterHeaderIconButton, GridFilterQuick, GridFilters, GridFormDropDown, GridFormEditBearing, GridFormMessage, GridFormMultiSelect, GridFormMultiSelectGrid, GridFormPopoverMenu, GridFormSubComponentTextArea, GridFormSubComponentTextInput, GridFormTextArea, GridFormTextInput, GridHeaderSelect, GridIcon, GridLoadableCell, GridNoRowsOverlay, GridPopoutEditMultiSelect, GridPopoutEditMultiSelectGrid, GridPopoverContext, GridPopoverContextProvider, GridPopoverEditBearing, GridPopoverEditBearingCorrection, GridPopoverEditBearingCorrectionEditorParams, GridPopoverEditBearingEditorParams, GridPopoverEditDropDown, GridPopoverMenu, GridPopoverMessage, GridPopoverTextArea, GridPopoverTextInput, GridRenderPopoutMenuCell, GridSubComponentContext, GridUpdatingContext, GridUpdatingContextProvider, GridWrapper, Menu, MenuButton, MenuDivider, MenuGroup, MenuHeader, MenuHeaderItem, MenuHeaderString, MenuItem, MenuRadioGroup, MenuSeparator, MenuSeparatorString, PopoutMenuSeparator, SubMenu, TextAreaInput, TextInputFormatted, bearingCorrectionRangeValidator, bearingCorrectionValueFormatter, bearingNumberParser, bearingRangeValidator, bearingStringValidator, bearingValueFormatter, clickActionButton, clickMenuOption, clickMultiSelectOption, closeMenu, closePopover, convertDDToDMS, countRows, deselectRow, downloadCsvUseValueFormattersProcessCellCallback, editCell, findActionButton, findCell, findCellContains, findMenuOption, findMultiSelectOption, findOpenPopover, findParentWithClass, findRow, fnOrVar, generateFilterGetter, getMultiSelectOptions, hasParentClass, isCellReadOnly, isFloat, isGridCellFiller, isNotEmpty, openAndClickMenuOption, openAndFindMenuOption, queryMenuOption, queryRow, sanitiseFileName, selectCell, selectRow, stringByteLengthIsInvalid, suppressCellKeyboardEvents, typeInputByLabel, typeInputByPlaceholder, typeOnlyInput, typeOtherInput, typeOtherTextArea, useDeferredPromise, useGenerateOrDefaultId, useGridContext, useGridFilter, useGridPopoverContext, useGridPopoverHook, useMenuState, usePostSortRowsHook, validateMenuOptions, wait$2 as wait };
|
|
27638
27656
|
//# sourceMappingURL=step-ag-grid.esm.js.map
|