@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.
@@ -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, compact, delay, partition, pick, groupBy, fromPairs, toPairs, isEqual, sumBy, remove, castArray, flatten } from 'lodash-es';
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(getColumns())
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
- getColumns()
2911
- .map((col) => col.colId || "")
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
- // infer the invisible ids from colDefs
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, setInvisibleColumnIds] = useState();
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.length > 0;
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 && invisibleColumnIds) {
4873
- // show all columns that aren't invisible
4874
- columnApi.setColumnsVisible(compact(getColumns()
4875
- .filter((col) => !col.lockVisible && col.colId && !invisibleColumnIds.includes(col.colId))
4876
- .map((col) => col.colId)), true);
4877
- // hide all invisible columns
4878
- columnApi.setColumnsVisible(invisibleColumnIds, false);
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) => !cs.hide && gridApi.getColumnDef(cs.colId)?.headerComponentParams?.exportable !== false)
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