@linzjs/step-ag-grid 28.5.0 → 29.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/dist/index.css +11 -7
- package/dist/src/components/Grid.d.ts +5 -1
- package/dist/src/contexts/GridContext.d.ts +3 -4
- package/dist/src/contexts/GridPopoverContext.d.ts +1 -0
- package/dist/src/contexts/GridUpdatingContext.d.ts +1 -0
- package/dist/src/lui/reactUtils.d.ts +4 -0
- package/dist/step-ag-grid.cjs +265 -247
- package/dist/step-ag-grid.cjs.map +1 -1
- package/dist/step-ag-grid.esm.js +266 -248
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +21 -22
- package/src/components/Grid.tsx +118 -113
- package/src/components/GridPopoverHook.tsx +25 -20
- package/src/components/gridFilter/useGridFilter.ts +3 -3
- package/src/components/gridHook/useGridContextMenu.tsx +3 -3
- package/src/contexts/GridContext.tsx +11 -14
- package/src/contexts/GridContextProvider.tsx +164 -137
- package/src/contexts/GridPopoverContext.tsx +2 -0
- package/src/contexts/GridPopoverContextProvider.tsx +9 -5
- package/src/contexts/GridUpdatingContext.tsx +5 -0
- package/src/contexts/GridUpdatingContextProvider.tsx +35 -28
- package/src/lui/reactUtils.tsx +24 -0
- package/src/react-menu3/components/MenuList.tsx +3 -0
- package/src/stories/grid/GridFilterButtons.stories.tsx +1 -1
- package/src/stories/grid/GridNonEditableRow.stories.tsx +1 -1
- package/src/stories/grid/GridPinnedRow.stories.tsx +1 -1
- package/src/stories/grid/GridPopoutContextMenu.stories.tsx +3 -3
- package/src/stories/grid/GridPopoutEditGenericTextArea.stories.tsx +2 -2
- package/src/stories/grid/GridPopoverEditDropDown.stories.tsx +8 -4
- package/src/stories/grid/GridPopoverEditMultiSelect.stories.tsx +1 -0
- package/src/stories/grid/GridReadOnly.stories.tsx +1 -1
- package/src/stories/grid/GridViewList.stories.tsx +1 -1
- package/src/stories/grid/gridFormInteraction/GridFormDropDownInteraction.stories.tsx +5 -3
- package/src/stories/grid/gridFormInteraction/GridFormEditBearingCorrectionInteraction.stories.tsx +3 -2
- package/src/stories/grid/gridFormInteraction/GridFormEditBearingInteraction.stories.tsx +3 -2
- package/src/stories/grid/gridFormInteraction/GridFormMultiSelectGridInteraction.stories.tsx +3 -2
- package/src/stories/grid/gridFormInteraction/GridFormMultiSelectInteraction.stories.tsx +3 -2
- package/src/stories/grid/gridFormInteraction/GridFormPopoverMenuInteraction.stories.tsx +3 -2
- package/src/stories/grid/gridFormInteraction/GridFormTextAreaInteraction.stories.tsx +3 -2
- package/src/stories/grid/gridFormInteraction/GridFormTextInputInteraction.stories.tsx +3 -2
- package/src/stories/grid/gridFormStatic/GridFormDropDown.stories.tsx +2 -2
- package/src/stories/grid/interactions/GridKeyboardInteractions.stories.tsx +2 -2
package/dist/step-ag-grid.esm.js
CHANGED
|
@@ -2,7 +2,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
2
2
|
import { LuiMiniSpinner, LuiStatusSpinner, LuiIcon, LuiButtonGroup, LuiButton, LuiCheckboxInput } from '@linzjs/lui';
|
|
3
3
|
import { ModuleRegistry, AllCommunityModule } from 'ag-grid-community';
|
|
4
4
|
import { AgGridReact } from 'ag-grid-react';
|
|
5
|
-
import { negate, isEmpty, findIndex, defer, debounce as debounce$1, xorBy, last, difference, omit, sortBy, delay, partition, pick, groupBy, fromPairs, toPairs, isEqual, compact, filter, sumBy, remove,
|
|
5
|
+
import { negate, isEmpty, findIndex, defer, debounce as debounce$1, xorBy, last, difference, omit, sortBy, delay, partition, pick, groupBy, fromPairs, toPairs, isEqual, pull, compact, filter, sumBy, remove, flatten, castArray } from 'lodash-es';
|
|
6
6
|
import React, { useRef, useLayoutEffect, useEffect, createContext, useContext, useState, useMemo, memo, forwardRef, useCallback, useReducer, cloneElement, useImperativeHandle, Fragment as Fragment$1, useId } from 'react';
|
|
7
7
|
import { unstable_batchedUpdates, flushSync, createPortal } from 'react-dom';
|
|
8
8
|
|
|
@@ -447,9 +447,6 @@ const GridContext = createContext({
|
|
|
447
447
|
prePopupOps: () => {
|
|
448
448
|
console.error('no context provider for prePopupOps');
|
|
449
449
|
},
|
|
450
|
-
postPopupOps: () => {
|
|
451
|
-
console.error('no context provider for prePopupOps');
|
|
452
|
-
},
|
|
453
450
|
externallySelectedItemsAreInSync: false,
|
|
454
451
|
setApis: () => {
|
|
455
452
|
console.error('no context provider for setApis');
|
|
@@ -521,15 +518,12 @@ const GridContext = createContext({
|
|
|
521
518
|
console.error('no context provider for editingCells');
|
|
522
519
|
return false;
|
|
523
520
|
},
|
|
524
|
-
cancelEdit: () => {
|
|
525
|
-
console.error('no context provider for cancelEdit');
|
|
526
|
-
},
|
|
527
521
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
528
522
|
startCellEditing: async () => {
|
|
529
523
|
console.error('no context provider for startCellEditing');
|
|
530
524
|
},
|
|
531
|
-
|
|
532
|
-
console.error('no context provider for
|
|
525
|
+
resetFocusedCellAfterCellEditing: () => {
|
|
526
|
+
console.error('no context provider for resetFocusedCellAfterCellEditing');
|
|
533
527
|
},
|
|
534
528
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
535
529
|
updatingCells: async () => {
|
|
@@ -563,8 +557,11 @@ const GridContext = createContext({
|
|
|
563
557
|
downloadCsv: () => {
|
|
564
558
|
console.error('no context provider for downloadCsv');
|
|
565
559
|
},
|
|
566
|
-
|
|
567
|
-
console.error('no context provider for
|
|
560
|
+
onBulkEditingComplete: () => {
|
|
561
|
+
console.error('no context provider for onBulkEditingComplete');
|
|
562
|
+
},
|
|
563
|
+
setOnBulkEditingComplete: () => {
|
|
564
|
+
console.error('no context provider for setOnBulkEditingComplete');
|
|
568
565
|
},
|
|
569
566
|
showNoRowsOverlay: () => {
|
|
570
567
|
console.error('no context provider for showLoadingOverlay');
|
|
@@ -573,6 +570,10 @@ const GridContext = createContext({
|
|
|
573
570
|
const useGridContext = () => useContext(GridContext);
|
|
574
571
|
|
|
575
572
|
const GridUpdatingContext = createContext({
|
|
573
|
+
anyUpdating: () => {
|
|
574
|
+
console.error('Missing GridUpdatingContext');
|
|
575
|
+
return false;
|
|
576
|
+
},
|
|
576
577
|
checkUpdating: () => {
|
|
577
578
|
console.error('Missing GridUpdatingContext');
|
|
578
579
|
return false;
|
|
@@ -1794,6 +1795,9 @@ const MenuList = ({ ariaLabel, menuClassName, menuStyle, arrowClassName, arrowSt
|
|
|
1794
1795
|
return;
|
|
1795
1796
|
}
|
|
1796
1797
|
const callback = debounce$1(() => {
|
|
1798
|
+
if (!menuRef.current) {
|
|
1799
|
+
return;
|
|
1800
|
+
}
|
|
1797
1801
|
const { width, height } = menuRef.current.ownerDocument.body.getBoundingClientRect();
|
|
1798
1802
|
if (width === 0 || height === 0)
|
|
1799
1803
|
return;
|
|
@@ -2539,7 +2543,7 @@ const SubMenuFr = ({ 'aria-label': ariaLabel, className, disabled, direction, la
|
|
|
2539
2543
|
const SubMenu = withHovering('SubMenu', SubMenuFr);
|
|
2540
2544
|
|
|
2541
2545
|
const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, }) => {
|
|
2542
|
-
const { redrawRows, prePopupOps,
|
|
2546
|
+
const { redrawRows, prePopupOps, resetFocusedCellAfterCellEditing, getSelectedRows } = useContext(GridContext);
|
|
2543
2547
|
const [isOpen, setOpen] = useState(false);
|
|
2544
2548
|
const [anchorPoint, setAnchorPoint] = useState({ x: 0, y: 0 });
|
|
2545
2549
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
@@ -2556,8 +2560,8 @@ const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, })
|
|
|
2556
2560
|
const closeMenu = useCallback(() => {
|
|
2557
2561
|
setOpen(false);
|
|
2558
2562
|
redrawRows();
|
|
2559
|
-
|
|
2560
|
-
}, [
|
|
2563
|
+
resetFocusedCellAfterCellEditing();
|
|
2564
|
+
}, [resetFocusedCellAfterCellEditing, redrawRows]);
|
|
2561
2565
|
const cellContextMenu = useCallback((event) => {
|
|
2562
2566
|
if (contextMenuSelectRow && !event.node.isSelected()) {
|
|
2563
2567
|
event.node.setSelected(true, true);
|
|
@@ -2753,36 +2757,11 @@ const usePostSortRowsHook = ({ setStaleGrid }) => {
|
|
|
2753
2757
|
};
|
|
2754
2758
|
|
|
2755
2759
|
ModuleRegistry.registerModules([AllCommunityModule]);
|
|
2756
|
-
let timeOfLastSingleClick = 0;
|
|
2757
|
-
let lastClickColId;
|
|
2758
|
-
let lastClickRowIndex;
|
|
2759
|
-
const resetClickDebounce = () => {
|
|
2760
|
-
timeOfLastSingleClick = 0;
|
|
2761
|
-
lastClickColId = '';
|
|
2762
|
-
lastClickRowIndex = -1;
|
|
2763
|
-
};
|
|
2764
|
-
/**
|
|
2765
|
-
* If click is more than 200ms since last click return true.
|
|
2766
|
-
*/
|
|
2767
|
-
const clickDebounceSkipClick = (colId, rowIndex) => {
|
|
2768
|
-
const doubleClickMs = 200;
|
|
2769
|
-
if (Date.now() - timeOfLastSingleClick < doubleClickMs &&
|
|
2770
|
-
lastClickColId === colId &&
|
|
2771
|
-
lastClickRowIndex === rowIndex) {
|
|
2772
|
-
// Skipping double click due to single click edit
|
|
2773
|
-
return true;
|
|
2774
|
-
}
|
|
2775
|
-
timeOfLastSingleClick = Date.now();
|
|
2776
|
-
lastClickColId = colId;
|
|
2777
|
-
lastClickRowIndex = rowIndex;
|
|
2778
|
-
return false;
|
|
2779
|
-
};
|
|
2780
2760
|
/**
|
|
2781
2761
|
* Wrapper for AgGrid to add commonly used functionality.
|
|
2782
2762
|
*/
|
|
2783
2763
|
const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection = 'multiple', suppressColumnVirtualization = true, theme = 'ag-theme-step-default', sizeColumns = 'auto', selectColumnPinned = 'left', contextMenuSelectRow = false, singleClickEdit = false, rowData, rowHeight = theme === 'ag-theme-step-default' ? 40 : theme === 'ag-theme-step-compact' ? 36 : 40, selectable, ...params }) => {
|
|
2784
|
-
const { gridReady, gridRenderState, setApis, ensureRowVisible, getFirstRowId, selectRowsById, focusByRowById, ensureSelectedRowIsVisible, autoSizeColumns, sizeColumnsToFit, externallySelectedItemsAreInSync, setExternallySelectedItemsAreInSync, isExternalFilterPresent, doesExternalFilterPass,
|
|
2785
|
-
const { startCellEditing } = useGridContext();
|
|
2764
|
+
const { gridReady, gridRenderState, setApis, ensureRowVisible, getFirstRowId, selectRowsById, focusByRowById, ensureSelectedRowIsVisible, autoSizeColumns, sizeColumnsToFit, externallySelectedItemsAreInSync, setExternallySelectedItemsAreInSync, isExternalFilterPresent, doesExternalFilterPass, setOnBulkEditingComplete, getColDef, showNoRowsOverlay, prePopupOps, startCellEditing, } = useGridContext();
|
|
2786
2765
|
const { updatedDep, updatingCols } = useContext(GridUpdatingContext);
|
|
2787
2766
|
const gridDivRef = useRef(null);
|
|
2788
2767
|
const lastSelectedIds = useRef([]);
|
|
@@ -2859,7 +2838,8 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
2859
2838
|
needsAutoSize.current = true;
|
|
2860
2839
|
}
|
|
2861
2840
|
}
|
|
2862
|
-
if (needsAutoSize.current ||
|
|
2841
|
+
if (needsAutoSize.current ||
|
|
2842
|
+
(!hasSetContentSize.current && (sizeColumns === 'auto' || sizeColumns === 'auto-skip-headers'))) {
|
|
2863
2843
|
needsAutoSize.current = false;
|
|
2864
2844
|
setInitialContentSize();
|
|
2865
2845
|
}
|
|
@@ -3000,26 +2980,10 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3000
2980
|
const onModelUpdated = useCallback((event) => {
|
|
3001
2981
|
event.api.showNoRowsOverlay();
|
|
3002
2982
|
}, []);
|
|
3003
|
-
/**
|
|
3004
|
-
* Force-refresh all selected rows to re-run class function, to update selection highlighting
|
|
3005
|
-
*/
|
|
3006
|
-
const refreshSelectedRows = useCallback((_event) => {
|
|
3007
|
-
// MATT Disabled I don't believe these are needed anymore
|
|
3008
|
-
// I've left them here just in case they are
|
|
3009
|
-
/*event.api.refreshCells({
|
|
3010
|
-
force: true,
|
|
3011
|
-
rowNodes: event.api.getSelectedNodes(),
|
|
3012
|
-
});*/
|
|
3013
|
-
}, []);
|
|
3014
2983
|
/**
|
|
3015
2984
|
* Handle double click edit
|
|
3016
2985
|
*/
|
|
3017
2986
|
const onCellDoubleClick = useCallback((event) => {
|
|
3018
|
-
if (clickDebounceSkipClick(event.colDef.colId, event.rowIndex)) {
|
|
3019
|
-
// the next click will be a single click, we want it to pass
|
|
3020
|
-
resetClickDebounce();
|
|
3021
|
-
return;
|
|
3022
|
-
}
|
|
3023
2987
|
const editable = fnOrVar(event.colDef?.editable, event);
|
|
3024
2988
|
if (editable && !invokeEditAction(event)) {
|
|
3025
2989
|
void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
|
|
@@ -3031,9 +2995,6 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3031
2995
|
const onCellClicked = useCallback((event) => {
|
|
3032
2996
|
const editable = fnOrVar(event.colDef?.editable, event);
|
|
3033
2997
|
if ((editable && event.colDef.singleClickEdit) ?? singleClickEdit) {
|
|
3034
|
-
if (clickDebounceSkipClick(event.colDef.colId, event.rowIndex)) {
|
|
3035
|
-
return;
|
|
3036
|
-
}
|
|
3037
2998
|
void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
|
|
3038
2999
|
}
|
|
3039
3000
|
}, [singleClickEdit, startCellEditing]);
|
|
@@ -3129,11 +3090,10 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3129
3090
|
useEffect(() => {
|
|
3130
3091
|
const newLoading = !rowData || params.loading === true;
|
|
3131
3092
|
if (newLoading && !prevLoading.current) {
|
|
3132
|
-
stopEditing();
|
|
3133
3093
|
showNoRowsOverlay();
|
|
3134
3094
|
}
|
|
3135
3095
|
prevLoading.current = newLoading;
|
|
3136
|
-
}, [params.loading, rowData, showNoRowsOverlay
|
|
3096
|
+
}, [params.loading, rowData, showNoRowsOverlay]);
|
|
3137
3097
|
/**
|
|
3138
3098
|
* Resize columns to fit if required on window/container resize
|
|
3139
3099
|
*/
|
|
@@ -3195,6 +3155,23 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3195
3155
|
});
|
|
3196
3156
|
}
|
|
3197
3157
|
}, [clearHighlightRowClasses]);
|
|
3158
|
+
const onCellFocused = useCallback((event) => {
|
|
3159
|
+
if (!params.onCellFocused || event.rowIndex == null) {
|
|
3160
|
+
return;
|
|
3161
|
+
}
|
|
3162
|
+
const api = event.api;
|
|
3163
|
+
const rowNode = api.getDisplayedRowAtIndex(event.rowIndex);
|
|
3164
|
+
const data = rowNode?.data;
|
|
3165
|
+
const column = event.column;
|
|
3166
|
+
if (!data || !column || typeof column === 'string') {
|
|
3167
|
+
return;
|
|
3168
|
+
}
|
|
3169
|
+
const colDef = column.getColDef();
|
|
3170
|
+
if (!colDef || typeof colDef === 'string') {
|
|
3171
|
+
return;
|
|
3172
|
+
}
|
|
3173
|
+
params.onCellFocused({ colDef, data });
|
|
3174
|
+
}, [params]);
|
|
3198
3175
|
const onRowDragEnd = useCallback((event) => {
|
|
3199
3176
|
clearHighlightRowClasses();
|
|
3200
3177
|
gridElementRef.current = undefined;
|
|
@@ -3219,57 +3196,76 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3219
3196
|
}
|
|
3220
3197
|
}, [params.setExternalSelectedItems, selectable]);
|
|
3221
3198
|
// This is setting a ref in the GridContext so won't be triggering an update loop
|
|
3222
|
-
|
|
3223
|
-
const
|
|
3224
|
-
const
|
|
3199
|
+
setOnBulkEditingComplete(params.onBulkEditingComplete);
|
|
3200
|
+
const getRowId = useCallback((params) => `${params.data.id}`, []);
|
|
3201
|
+
const defaultColDef = useMemo(() => ({
|
|
3202
|
+
minWidth: 48,
|
|
3203
|
+
...omit(params.defaultColDef, ['editable', 'field', 'colId', 'tooltipField']),
|
|
3204
|
+
}), [params.defaultColDef]);
|
|
3205
|
+
const noRowsOverlayComponent = useCallback((event) => {
|
|
3206
|
+
const headerRowCount = columnDefs.some((c) => c.children) ? 2 : 1;
|
|
3207
|
+
let rowCount = 0;
|
|
3208
|
+
event.api.forEachNode(() => rowCount++);
|
|
3209
|
+
return (jsx(GridNoRowsOverlay, { loading: !rowData || params.loading === true, rowCount: rowCount, headerRowHeight: headerRowCount * rowHeight, filteredRowCount: event.api.getDisplayedRowCount(), noRowsOverlayText: params.noRowsOverlayText, noRowsMatchingOverlayText: params.noRowsMatchingOverlayText }));
|
|
3210
|
+
}, [columnDefs, params.loading, params.noRowsMatchingOverlayText, params.noRowsOverlayText, rowData, rowHeight]);
|
|
3211
|
+
const selectionColumnDef = useMemo(() => {
|
|
3212
|
+
const selectWidth = params.hideSelectColumn ? 0 : selectable && params.onRowDragEnd ? 76 : 48;
|
|
3213
|
+
return {
|
|
3214
|
+
suppressNavigable: params.hideSelectColumn,
|
|
3215
|
+
rowDrag: !!params.onRowDragEnd,
|
|
3216
|
+
minWidth: selectWidth,
|
|
3217
|
+
maxWidth: selectWidth,
|
|
3218
|
+
pinned: selectColumnPinned,
|
|
3219
|
+
headerComponentParams: {
|
|
3220
|
+
exportable: false,
|
|
3221
|
+
},
|
|
3222
|
+
headerClass: clsx('ag-header-hide-default-select', params.onRowDragEnd && 'ag-header-select-draggable'),
|
|
3223
|
+
headerComponent: rowSelection == 'multiple' ? GridHeaderSelect : undefined,
|
|
3224
|
+
suppressHeaderKeyboardEvent: (e) => {
|
|
3225
|
+
if (!selectable)
|
|
3226
|
+
return false;
|
|
3227
|
+
if ((e.event.key === 'Enter' || e.event.key === ' ') && !e.event.repeat) {
|
|
3228
|
+
if (isEmpty(e.api.getSelectedRows())) {
|
|
3229
|
+
e.api.selectAll('filtered');
|
|
3230
|
+
}
|
|
3231
|
+
else {
|
|
3232
|
+
e.api.deselectAll();
|
|
3233
|
+
}
|
|
3234
|
+
return true;
|
|
3235
|
+
}
|
|
3236
|
+
return false;
|
|
3237
|
+
},
|
|
3238
|
+
onCellClicked: params.enableSelectionWithoutKeys || params.enableClickSelection
|
|
3239
|
+
? undefined
|
|
3240
|
+
: clickInputWhenContainingCellClicked,
|
|
3241
|
+
};
|
|
3242
|
+
}, [
|
|
3243
|
+
params.enableClickSelection,
|
|
3244
|
+
params.enableSelectionWithoutKeys,
|
|
3245
|
+
params.hideSelectColumn,
|
|
3246
|
+
params.onRowDragEnd,
|
|
3247
|
+
rowSelection,
|
|
3248
|
+
selectColumnPinned,
|
|
3249
|
+
selectable,
|
|
3250
|
+
]);
|
|
3225
3251
|
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, { theme: 'legacy', rowSelection: selectable
|
|
3226
3252
|
? {
|
|
3227
3253
|
enableSelectionWithoutKeys: params.enableSelectionWithoutKeys ?? false,
|
|
3228
3254
|
enableClickSelection: params.enableClickSelection ?? false,
|
|
3229
3255
|
mode: rowSelection == 'single' ? 'singleRow' : 'multiRow',
|
|
3230
3256
|
}
|
|
3231
|
-
: undefined, rowHeight: rowHeight, animateRows: params.animateRows ?? false, rowClassRules: params.rowClassRules, getRowId:
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
// filter is exact matches exactly groups separated by commas
|
|
3237
|
-
return filterStr.split(',').map((str) => str.trim());
|
|
3238
|
-
}, onModelUpdated: onModelUpdated, onGridReady: onGridReady, onSortChanged: ensureSelectedRowIsVisible, postSortRows: params.onRowDragEnd || !defaultPostSort ? undefined : postSortRows, onSelectionChanged: synchroniseExternalStateToGridSelection, onColumnMoved: params.onColumnMoved, alwaysShowVerticalScroll: params.alwaysShowVerticalScroll, isExternalFilterPresent: isExternalFilterPresent, doesExternalFilterPass: doesExternalFilterPass, maintainColumnOrder: true, preventDefaultOnContextMenu: true, onCellContextMenu: gridContextMenu.cellContextMenu, rowDragText: params.rowDragText, onRowDragCancel: clearHighlightRowClasses, onRowDragMove: onRowDragMove, onRowDragEnd: onRowDragEnd, suppressCellFocus: params.suppressCellFocus, pinnedTopRowData: params.pinnedTopRowData, pinnedBottomRowData: params.pinnedBottomRowData, selectionColumnDef: {
|
|
3239
|
-
suppressNavigable: params.hideSelectColumn,
|
|
3240
|
-
rowDrag: !!params.onRowDragEnd,
|
|
3241
|
-
minWidth: selectWidth,
|
|
3242
|
-
maxWidth: selectWidth,
|
|
3243
|
-
pinned: selectColumnPinned,
|
|
3244
|
-
headerComponentParams: {
|
|
3245
|
-
exportable: false,
|
|
3246
|
-
},
|
|
3247
|
-
headerClass: clsx('ag-header-hide-default-select', params.onRowDragEnd && 'ag-header-select-draggable'),
|
|
3248
|
-
headerComponent: rowSelection == 'multiple' ? GridHeaderSelect : undefined,
|
|
3249
|
-
suppressHeaderKeyboardEvent: (e) => {
|
|
3250
|
-
if (!selectable)
|
|
3251
|
-
return false;
|
|
3252
|
-
if ((e.event.key === 'Enter' || e.event.key === ' ') && !e.event.repeat) {
|
|
3253
|
-
if (isEmpty(e.api.getSelectedRows())) {
|
|
3254
|
-
e.api.selectAll('filtered');
|
|
3255
|
-
}
|
|
3256
|
-
else {
|
|
3257
|
-
e.api.deselectAll();
|
|
3258
|
-
}
|
|
3259
|
-
return true;
|
|
3260
|
-
}
|
|
3261
|
-
return false;
|
|
3262
|
-
},
|
|
3263
|
-
onCellClicked: params.enableSelectionWithoutKeys || params.enableClickSelection
|
|
3264
|
-
? undefined
|
|
3265
|
-
: clickInputWhenContainingCellClicked,
|
|
3266
|
-
} }) })] }));
|
|
3257
|
+
: undefined, rowHeight: rowHeight, animateRows: params.animateRows ?? false, rowClassRules: params.rowClassRules, getRowId: getRowId, onGridSizeChanged: onGridSizeChanged, suppressColumnVirtualisation: suppressColumnVirtualization, suppressClickEdit: true, onColumnVisible: setInitialContentSize, onRowDataUpdated: onRowDataChanged, onCellFocused: onCellFocused, onCellKeyDown: onCellKeyPress, onCellClicked: onCellClicked, onCellDoubleClicked: onCellDoubleClick, domLayout: params.domLayout, onColumnResized: onColumnResized, defaultColDef: defaultColDef, columnDefs: columnDefsAdjusted, selectionColumnDef: selectionColumnDef, rowData: rowData, postSortRows: params.onRowDragEnd || !defaultPostSort ? undefined : postSortRows, onModelUpdated: onModelUpdated, onGridReady: onGridReady, onSortChanged: ensureSelectedRowIsVisible, quickFilterParser: quickFilterParser, onSelectionChanged: synchroniseExternalStateToGridSelection, onColumnMoved: params.onColumnMoved, noRowsOverlayComponent: noRowsOverlayComponent, alwaysShowVerticalScroll: params.alwaysShowVerticalScroll, isExternalFilterPresent: isExternalFilterPresent, doesExternalFilterPass: doesExternalFilterPass, maintainColumnOrder: true, preventDefaultOnContextMenu: true, onCellContextMenu: gridContextMenu.cellContextMenu, rowDragText: params.rowDragText, onRowDragCancel: clearHighlightRowClasses, onRowDragMove: onRowDragMove, onRowDragEnd: onRowDragEnd, suppressCellFocus: params.suppressCellFocus, pinnedTopRowData: params.pinnedTopRowData, pinnedBottomRowData: params.pinnedBottomRowData }) })] }));
|
|
3258
|
+
};
|
|
3259
|
+
const quickFilterParser = (filterStr) => {
|
|
3260
|
+
// filter is exact matches exactly groups separated by commas
|
|
3261
|
+
return filterStr.split(',').map((str) => str.trim());
|
|
3267
3262
|
};
|
|
3268
3263
|
|
|
3269
3264
|
const GridPopoverContext = createContext({
|
|
3270
3265
|
anchorRef: { current: null },
|
|
3271
3266
|
saving: false,
|
|
3272
3267
|
setSaving: () => { },
|
|
3268
|
+
stopEditing: () => { },
|
|
3273
3269
|
colId: '',
|
|
3274
3270
|
field: '',
|
|
3275
3271
|
value: null,
|
|
@@ -3287,7 +3283,7 @@ const GridPopoverContextProvider = (props2) => {
|
|
|
3287
3283
|
const anchorRef = useRef(props.eGridCell);
|
|
3288
3284
|
const hasSaved = useRef(false);
|
|
3289
3285
|
const [saving, setSaving] = useState(false);
|
|
3290
|
-
const { colDef } = props;
|
|
3286
|
+
const { colDef, stopEditing, formatValue, data, value } = props;
|
|
3291
3287
|
const { cellEditorParams } = colDef;
|
|
3292
3288
|
const multiEdit = cellEditorParams?.multiEdit ?? false;
|
|
3293
3289
|
// Then item that is clicked on will always be first in the list
|
|
@@ -3295,8 +3291,10 @@ const GridPopoverContextProvider = (props2) => {
|
|
|
3295
3291
|
const field = props.colDef?.field ?? '';
|
|
3296
3292
|
const colId = props.colDef?.colId ?? field ?? '';
|
|
3297
3293
|
const updateValue = useCallback(async (saveFn, tabDirection) => {
|
|
3298
|
-
if (hasSaved.current)
|
|
3294
|
+
if (hasSaved.current) {
|
|
3295
|
+
// already called save so ignore
|
|
3299
3296
|
return true;
|
|
3297
|
+
}
|
|
3300
3298
|
hasSaved.current = true;
|
|
3301
3299
|
return saving ? false : await updatingCells({ selectedRows, field }, saveFn, setSaving, tabDirection);
|
|
3302
3300
|
}, [field, saving, selectedRows, updatingCells]);
|
|
@@ -3307,10 +3305,11 @@ const GridPopoverContextProvider = (props2) => {
|
|
|
3307
3305
|
selectedRows,
|
|
3308
3306
|
colId,
|
|
3309
3307
|
field,
|
|
3310
|
-
data
|
|
3311
|
-
value
|
|
3308
|
+
data,
|
|
3309
|
+
value,
|
|
3312
3310
|
updateValue,
|
|
3313
|
-
formatValue
|
|
3311
|
+
formatValue,
|
|
3312
|
+
stopEditing,
|
|
3314
3313
|
}, children: children }));
|
|
3315
3314
|
};
|
|
3316
3315
|
|
|
@@ -3460,7 +3459,7 @@ const GridCellMultiEditor = (props, cellEditorSelector) => GridCell({
|
|
|
3460
3459
|
});
|
|
3461
3460
|
|
|
3462
3461
|
const useGridFilter = (filter) => {
|
|
3463
|
-
const { addExternalFilter, removeExternalFilter } =
|
|
3462
|
+
const { addExternalFilter, removeExternalFilter } = useGridContext();
|
|
3464
3463
|
useEffect(() => {
|
|
3465
3464
|
const thisFilter = filter;
|
|
3466
3465
|
thisFilter && addExternalFilter(thisFilter);
|
|
@@ -3935,8 +3934,8 @@ const textMatch = (text, filter) => {
|
|
|
3935
3934
|
};
|
|
3936
3935
|
|
|
3937
3936
|
const useGridPopoverHook = (props) => {
|
|
3938
|
-
const {
|
|
3939
|
-
const { anchorRef, saving, updateValue } = useGridPopoverContext();
|
|
3937
|
+
const { onBulkEditingComplete } = useGridContext();
|
|
3938
|
+
const { anchorRef, saving, updateValue, stopEditing } = useGridPopoverContext();
|
|
3940
3939
|
const saveButtonRef = useRef(null);
|
|
3941
3940
|
const [isOpen, setOpen] = useState(false);
|
|
3942
3941
|
useEffect(() => {
|
|
@@ -3944,30 +3943,30 @@ const useGridPopoverHook = (props) => {
|
|
|
3944
3943
|
}, []);
|
|
3945
3944
|
const triggerSave = useCallback(async (reason) => {
|
|
3946
3945
|
if (reason == CloseReason.CANCEL) {
|
|
3947
|
-
|
|
3946
|
+
stopEditing();
|
|
3947
|
+
onBulkEditingComplete();
|
|
3948
3948
|
return;
|
|
3949
3949
|
}
|
|
3950
|
-
if (props
|
|
3950
|
+
if (props?.invalid?.()) {
|
|
3951
|
+
// Don't close, don't do anything it's invalid
|
|
3951
3952
|
return;
|
|
3952
3953
|
}
|
|
3953
3954
|
if (!props.save) {
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
if (props.invalid)
|
|
3959
|
-
stopEditing();
|
|
3960
|
-
if (await updateValue(props.save, reason === CloseReason.TAB_FORWARD ? 1 : reason === CloseReason.TAB_BACKWARD ? -1 : 0)) {
|
|
3961
|
-
if (!props.invalid)
|
|
3962
|
-
stopEditing();
|
|
3963
|
-
}
|
|
3955
|
+
// No save method so just close
|
|
3956
|
+
stopEditing();
|
|
3957
|
+
onBulkEditingComplete();
|
|
3958
|
+
return;
|
|
3964
3959
|
}
|
|
3965
|
-
|
|
3960
|
+
if (await updateValue(props.save, reason === CloseReason.TAB_FORWARD ? 1 : reason === CloseReason.TAB_BACKWARD ? -1 : 0)) {
|
|
3961
|
+
stopEditing();
|
|
3962
|
+
}
|
|
3963
|
+
}, [onBulkEditingComplete, props, stopEditing, updateValue]);
|
|
3966
3964
|
const popoverWrapper = useCallback((children) => {
|
|
3967
3965
|
return (jsx(Fragment, { children: anchorRef.current && (jsxs(ControlledMenu, { state: isOpen ? 'open' : 'closed', portal: true, unmountOnClose: true, anchorRef: anchorRef, saveButtonRef: saveButtonRef, menuClassName: 'step-ag-grid-react-menu', onClose: (event) => {
|
|
3968
3966
|
// Prevent menu from closing when modals are invoked
|
|
3969
|
-
if (event.reason === CloseReason.BLUR)
|
|
3967
|
+
if (event.reason === CloseReason.BLUR) {
|
|
3970
3968
|
return;
|
|
3969
|
+
}
|
|
3971
3970
|
void triggerSave(event.reason);
|
|
3972
3971
|
}, viewScroll: 'auto', dontShrinkIfDirectionIsTop: true, className: props.className, children: [saving && ( // This is the overlay that prevents editing when the editor is saving
|
|
3973
3972
|
jsx("div", { className: 'ComponentLoadingWrapper-saveOverlay' })), children, jsx("button", { ref: saveButtonRef, "data-reason": '', onClick: (e) => {
|
|
@@ -5061,7 +5060,7 @@ const isFlexColumn = (colDef) => !!colDef.flex && !isGridCellFiller(colDef);
|
|
|
5061
5060
|
* Also, make sure the provider is created in a separate component, otherwise it won't be found.
|
|
5062
5061
|
*/
|
|
5063
5062
|
const GridContextProvider = (props) => {
|
|
5064
|
-
const { modifyUpdating,
|
|
5063
|
+
const { modifyUpdating, anyUpdating } = useContext(GridUpdatingContext);
|
|
5065
5064
|
const [gridApi, setGridApi] = useState();
|
|
5066
5065
|
const [gridReady, setGridReady] = useState(false);
|
|
5067
5066
|
const [quickFilter, _setQuickFilter] = useState('');
|
|
@@ -5080,7 +5079,7 @@ const GridContextProvider = (props) => {
|
|
|
5080
5079
|
/**
|
|
5081
5080
|
* Make extra sure the GridCellFillerColId never gets added to invisibleColumnIds as it's dynamically determined
|
|
5082
5081
|
*/
|
|
5083
|
-
const setInvisibleColumnIds = (invisibleColumnIds) => _setInvisibleColumnIds(pull(invisibleColumnIds, GridCellFillerColId));
|
|
5082
|
+
const setInvisibleColumnIds = useCallback((invisibleColumnIds) => _setInvisibleColumnIds(pull(invisibleColumnIds, GridCellFillerColId)), []);
|
|
5084
5083
|
/**
|
|
5085
5084
|
* Set quick filter directly on grid, based on previously save quickFilter state.
|
|
5086
5085
|
*/
|
|
@@ -5175,17 +5174,6 @@ const GridContextProvider = (props) => {
|
|
|
5175
5174
|
}
|
|
5176
5175
|
prePopupFocusedCell.current = gridApi.getFocusedCell() ?? undefined;
|
|
5177
5176
|
}, [gridApi]);
|
|
5178
|
-
/**
|
|
5179
|
-
* After a popup refocus the cell.
|
|
5180
|
-
*/
|
|
5181
|
-
const postPopupOps = useCallback(() => {
|
|
5182
|
-
if (!gridApi || gridApi.isDestroyed()) {
|
|
5183
|
-
return;
|
|
5184
|
-
}
|
|
5185
|
-
if (prePopupFocusedCell.current) {
|
|
5186
|
-
gridApi.setFocusedCell(prePopupFocusedCell.current.rowIndex, prePopupFocusedCell.current.column);
|
|
5187
|
-
}
|
|
5188
|
-
}, [gridApi]);
|
|
5189
5177
|
/**
|
|
5190
5178
|
* Get all row id's in grid.
|
|
5191
5179
|
*/
|
|
@@ -5373,13 +5361,16 @@ const GridContextProvider = (props) => {
|
|
|
5373
5361
|
gridApi.sizeColumnsToFit();
|
|
5374
5362
|
}
|
|
5375
5363
|
}, [gridApi]);
|
|
5376
|
-
|
|
5377
|
-
|
|
5364
|
+
/**
|
|
5365
|
+
*
|
|
5366
|
+
*/
|
|
5367
|
+
const resetFocusedCellAfterCellEditing = useCallback(() => {
|
|
5368
|
+
if (!gridApi || gridApi.isDestroyed() || startCellEditingInProgressRef.current) {
|
|
5378
5369
|
return;
|
|
5379
5370
|
}
|
|
5380
|
-
gridApi.stopEditing();
|
|
5381
5371
|
if (prePopupFocusedCell.current) {
|
|
5382
5372
|
gridApi.setFocusedCell(prePopupFocusedCell.current.rowIndex, prePopupFocusedCell.current.column);
|
|
5373
|
+
prePopupFocusedCell.current = undefined;
|
|
5383
5374
|
}
|
|
5384
5375
|
}, [gridApi]);
|
|
5385
5376
|
// waitForExternallySelectedItemsToBeInSync can't use the state as it won't be updated during function execution
|
|
@@ -5400,58 +5391,65 @@ const GridContextProvider = (props) => {
|
|
|
5400
5391
|
console.error('externallySelectedItems did not sync with ag-grid selection');
|
|
5401
5392
|
}
|
|
5402
5393
|
}, []);
|
|
5394
|
+
const startCellEditingInProgressRef = useRef(false);
|
|
5403
5395
|
const startCellEditing = useCallback(async ({ rowId, colId }) => {
|
|
5404
|
-
if (!gridApi)
|
|
5405
|
-
return;
|
|
5406
|
-
const colDef = gridApi.getColumnDef(colId);
|
|
5407
|
-
if (!colDef) {
|
|
5408
|
-
return;
|
|
5409
|
-
}
|
|
5410
|
-
const rowNode = gridApi.getRowNode(`${rowId}`);
|
|
5411
|
-
if (!rowNode) {
|
|
5412
|
-
return;
|
|
5413
|
-
}
|
|
5414
|
-
prePopupOps();
|
|
5415
|
-
const shouldSelectNode = !rowNode.isSelected();
|
|
5416
|
-
if (shouldSelectNode) {
|
|
5417
|
-
externallySelectedItemsAreInSyncRef.current = false;
|
|
5418
|
-
setExternallySelectedItemsAreInSync(false);
|
|
5419
|
-
rowNode.setSelected(true, true);
|
|
5420
|
-
await waitForExternallySelectedItemsToBeInSync();
|
|
5421
|
-
}
|
|
5422
|
-
// Cell already being edited, so don't re-edit until finished
|
|
5423
|
-
if (checkUpdating([colDef.field ?? colDef.colId ?? ''], rowId)) {
|
|
5396
|
+
if (!gridApi || startCellEditingInProgressRef.current) {
|
|
5424
5397
|
return;
|
|
5425
5398
|
}
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5399
|
+
startCellEditingInProgressRef.current = true;
|
|
5400
|
+
try {
|
|
5401
|
+
// Edit in progress so don't edit until finished, timeout waiting after 5s
|
|
5402
|
+
if (!(await waitForCondition(() => !anyUpdating(), 5000))) {
|
|
5403
|
+
console.error("Could not start edit because previous edit hasn't finished after 5 seconds");
|
|
5404
|
+
return;
|
|
5405
|
+
}
|
|
5406
|
+
const colDef = gridApi.getColumnDef(colId);
|
|
5407
|
+
if (!colDef) {
|
|
5408
|
+
return;
|
|
5409
|
+
}
|
|
5410
|
+
const rowNode = gridApi.getRowNode(`${rowId}`);
|
|
5411
|
+
if (!rowNode) {
|
|
5412
|
+
return;
|
|
5413
|
+
}
|
|
5414
|
+
prePopupOps();
|
|
5415
|
+
const shouldSelectNode = !rowNode.isSelected();
|
|
5416
|
+
if (shouldSelectNode) {
|
|
5417
|
+
externallySelectedItemsAreInSyncRef.current = false;
|
|
5418
|
+
setExternallySelectedItemsAreInSync(false);
|
|
5419
|
+
rowNode.setSelected(true, true);
|
|
5420
|
+
await waitForExternallySelectedItemsToBeInSync();
|
|
5421
|
+
}
|
|
5422
|
+
const rowIndex = rowNode.rowIndex;
|
|
5423
|
+
if (rowIndex != null) {
|
|
5424
|
+
defer(() => {
|
|
5425
|
+
!gridApi.isDestroyed() &&
|
|
5426
|
+
gridApi.startEditingCell({
|
|
5427
|
+
rowIndex,
|
|
5428
|
+
colKey: colId,
|
|
5429
|
+
});
|
|
5430
|
+
});
|
|
5431
|
+
}
|
|
5435
5432
|
}
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
const
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
const
|
|
5446
|
-
|
|
5433
|
+
finally {
|
|
5434
|
+
startCellEditingInProgressRef.current = false;
|
|
5435
|
+
}
|
|
5436
|
+
}, [anyUpdating, gridApi, prePopupOps, waitForExternallySelectedItemsToBeInSync]);
|
|
5437
|
+
const bulkEditingCompleteCallbackRef = useRef();
|
|
5438
|
+
const onBulkEditingComplete = useCallback(() => {
|
|
5439
|
+
resetFocusedCellAfterCellEditing();
|
|
5440
|
+
bulkEditingCompleteCallbackRef.current?.();
|
|
5441
|
+
}, [resetFocusedCellAfterCellEditing]);
|
|
5442
|
+
const setOnBulkEditingComplete = useCallback((cellEditingCompleteCallback) => {
|
|
5443
|
+
bulkEditingCompleteCallbackRef.current = cellEditingCompleteCallback;
|
|
5447
5444
|
}, []);
|
|
5448
5445
|
/**
|
|
5449
5446
|
* Returns true if an editable cell on same row was selected, else false.
|
|
5450
5447
|
*/
|
|
5451
5448
|
const selectNextEditableCell = useCallback(async (tabDirection) => {
|
|
5452
5449
|
// Pretend it succeeded to prevent unwanted cellEditingCompleteCallback
|
|
5453
|
-
if (!gridApi)
|
|
5450
|
+
if (!gridApi) {
|
|
5454
5451
|
return true;
|
|
5452
|
+
}
|
|
5455
5453
|
const focusedCellIsEditable = () => {
|
|
5456
5454
|
const focusedCell = gridApi.isDestroyed() ? null : gridApi.getFocusedCell();
|
|
5457
5455
|
const nextColumn = focusedCell?.column;
|
|
@@ -5467,16 +5465,16 @@ const GridContextProvider = (props) => {
|
|
|
5467
5465
|
if (gridApi.isDestroyed()) {
|
|
5468
5466
|
return true;
|
|
5469
5467
|
}
|
|
5468
|
+
// Prevent resetting focus to original editing cell
|
|
5469
|
+
prePopupFocusedCell.current = undefined;
|
|
5470
5470
|
const preRow = gridApi.getFocusedCell();
|
|
5471
5471
|
if (tabDirection === 1) {
|
|
5472
|
+
gridApi.stopEditing();
|
|
5472
5473
|
gridApi.tabToNextCell();
|
|
5473
5474
|
}
|
|
5474
5475
|
else {
|
|
5475
5476
|
gridApi.tabToPreviousCell();
|
|
5476
5477
|
}
|
|
5477
|
-
// If we don't wait the tab to next element won't work
|
|
5478
|
-
// I think this is due to the grid resizing
|
|
5479
|
-
await wait(150);
|
|
5480
5478
|
if (gridApi.isDestroyed()) {
|
|
5481
5479
|
return true;
|
|
5482
5480
|
}
|
|
@@ -5489,64 +5487,71 @@ const GridContextProvider = (props) => {
|
|
|
5489
5487
|
if (focusedCellIsEditable()) {
|
|
5490
5488
|
const focusedCell = gridApi.getFocusedCell();
|
|
5491
5489
|
if (focusedCell) {
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
}
|
|
5490
|
+
const rowNode = gridApi.getDisplayedRowAtIndex(focusedCell.rowIndex);
|
|
5491
|
+
const rowId = rowNode?.data?.id;
|
|
5492
|
+
if (rowId == null) {
|
|
5493
|
+
return false;
|
|
5494
|
+
}
|
|
5495
|
+
await startCellEditing({ rowId, colId: focusedCell.column.getColId() });
|
|
5497
5496
|
return true;
|
|
5498
5497
|
}
|
|
5499
5498
|
}
|
|
5500
5499
|
}
|
|
5501
5500
|
return false;
|
|
5502
|
-
}, [gridApi,
|
|
5501
|
+
}, [gridApi, startCellEditing]);
|
|
5503
5502
|
const updatingCells = useCallback(async (props, fnUpdate, setSaving, tabDirection) => {
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
|
|
5508
|
-
|
|
5503
|
+
try {
|
|
5504
|
+
setSaving?.(true);
|
|
5505
|
+
return await gridApiOp(async (gridApi) => {
|
|
5506
|
+
const selectedRows = props.selectedRows;
|
|
5507
|
+
let ok = false;
|
|
5508
|
+
await modifyUpdating(props.field ?? '', selectedRows.map((data) => data.id), async () => {
|
|
5509
|
+
// MATT Disabled I don't believe these are needed anymore
|
|
5510
|
+
// I've left them here just in case they are
|
|
5511
|
+
// Need to refresh to get spinners to work on all rows
|
|
5512
|
+
// gridApi.refreshCells({ rowNodes: props.selectedRows as RowNode[], force: true });
|
|
5513
|
+
ok = await fnUpdate(selectedRows).catch((ex) => {
|
|
5514
|
+
console.error('Exception during modifyUpdating', ex);
|
|
5515
|
+
return false;
|
|
5516
|
+
});
|
|
5517
|
+
});
|
|
5509
5518
|
// MATT Disabled I don't believe these are needed anymore
|
|
5510
5519
|
// I've left them here just in case they are
|
|
5511
|
-
//
|
|
5512
|
-
// gridApi.refreshCells({ rowNodes:
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
return false;
|
|
5516
|
-
});
|
|
5517
|
-
});
|
|
5518
|
-
// MATT Disabled I don't believe these are needed anymore
|
|
5519
|
-
// I've left them here just in case they are
|
|
5520
|
-
// async processes need to refresh their own rows
|
|
5521
|
-
// gridApi.refreshCells({ rowNodes: selectedRows as RowNode[], force: true });
|
|
5522
|
-
if (gridApi.isDestroyed()) {
|
|
5523
|
-
return ok;
|
|
5524
|
-
}
|
|
5525
|
-
if (ok) {
|
|
5526
|
-
const cell = gridApi.getFocusedCell();
|
|
5527
|
-
if (cell && gridApi.getFocusedCell() == null) {
|
|
5528
|
-
!gridApi.isDestroyed && gridApi.setFocusedCell(cell.rowIndex, cell.column);
|
|
5520
|
+
// async processes need to refresh their own rows
|
|
5521
|
+
// gridApi.refreshCells({ rowNodes: selectedRows as RowNode[], force: true });
|
|
5522
|
+
if (gridApi.isDestroyed()) {
|
|
5523
|
+
return ok;
|
|
5529
5524
|
}
|
|
5530
|
-
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
// Only focus next cell if user hasn't already manually changed focus
|
|
5538
|
-
const postPopupFocusedCell = gridApi.getFocusedCell();
|
|
5539
|
-
if (prePopupFocusedCell.current &&
|
|
5540
|
-
postPopupFocusedCell &&
|
|
5541
|
-
prePopupFocusedCell.current.rowIndex == postPopupFocusedCell.rowIndex &&
|
|
5542
|
-
prePopupFocusedCell.current.column.getColId() == postPopupFocusedCell.column.getColId()) {
|
|
5543
|
-
if (!tabDirection || !(await selectNextEditableCell(tabDirection))) {
|
|
5544
|
-
cellEditingCompleteCallbackRef.current && cellEditingCompleteCallbackRef.current();
|
|
5525
|
+
if (ok) {
|
|
5526
|
+
const cell = gridApi.getFocusedCell();
|
|
5527
|
+
if (cell && gridApi.getFocusedCell() == null) {
|
|
5528
|
+
!gridApi.isDestroyed && gridApi.setFocusedCell(cell.rowIndex, cell.column);
|
|
5529
|
+
}
|
|
5530
|
+
// This is needed to trigger postSortRowsHook
|
|
5531
|
+
gridApi.refreshClientSideRowModel();
|
|
5545
5532
|
}
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
|
|
5533
|
+
void (async () => {
|
|
5534
|
+
// Only focus next cell if user hasn't already manually changed focus
|
|
5535
|
+
const postPopupFocusedCell = gridApi.getFocusedCell();
|
|
5536
|
+
if (prePopupFocusedCell.current &&
|
|
5537
|
+
postPopupFocusedCell &&
|
|
5538
|
+
prePopupFocusedCell.current.rowIndex == postPopupFocusedCell.rowIndex &&
|
|
5539
|
+
prePopupFocusedCell.current.column.getColId() == postPopupFocusedCell.column.getColId()) {
|
|
5540
|
+
if (!tabDirection || !(await selectNextEditableCell(tabDirection))) {
|
|
5541
|
+
onBulkEditingComplete();
|
|
5542
|
+
}
|
|
5543
|
+
}
|
|
5544
|
+
else {
|
|
5545
|
+
onBulkEditingComplete();
|
|
5546
|
+
}
|
|
5547
|
+
})();
|
|
5548
|
+
return ok;
|
|
5549
|
+
});
|
|
5550
|
+
}
|
|
5551
|
+
finally {
|
|
5552
|
+
setSaving?.(false);
|
|
5553
|
+
}
|
|
5554
|
+
}, [gridApiOp, modifyUpdating, onBulkEditingComplete, selectNextEditableCell]);
|
|
5550
5555
|
const redrawRows = useMemo(() => debounce((rowNodes) => {
|
|
5551
5556
|
try {
|
|
5552
5557
|
gridApi && gridApi.redrawRows(rowNodes ? { rowNodes } : undefined);
|
|
@@ -5577,16 +5582,16 @@ const GridContextProvider = (props) => {
|
|
|
5577
5582
|
preHash !== postHash && gridApi.clearFocusedCell();
|
|
5578
5583
|
}
|
|
5579
5584
|
}, 200), [gridApi]);
|
|
5580
|
-
const addExternalFilter = (filter) => {
|
|
5585
|
+
const addExternalFilter = useCallback((filter) => {
|
|
5581
5586
|
externalFilters.current.push(filter);
|
|
5582
5587
|
void onFilterChanged();
|
|
5583
|
-
};
|
|
5584
|
-
const removeExternalFilter = (filter) => {
|
|
5588
|
+
}, [onFilterChanged]);
|
|
5589
|
+
const removeExternalFilter = useCallback((filter) => {
|
|
5585
5590
|
remove(externalFilters.current, (v) => v === filter);
|
|
5586
5591
|
void onFilterChanged();
|
|
5587
|
-
};
|
|
5588
|
-
const isExternalFilterPresent = () => !isEmpty(externalFilters.current);
|
|
5589
|
-
const doesExternalFilterPass = (node) => externalFilters.current.every((filter) => filter(node.data, node));
|
|
5592
|
+
}, [onFilterChanged]);
|
|
5593
|
+
const isExternalFilterPresent = useCallback(() => !isEmpty(externalFilters.current), []);
|
|
5594
|
+
const doesExternalFilterPass = useCallback((node) => externalFilters.current.every((filter) => filter(node.data, node)), []);
|
|
5590
5595
|
const getColDef = useCallback((colId) => (!!colId && gridApi?.getColumnDef(colId)) || undefined, [gridApi]);
|
|
5591
5596
|
const showNoRowsOverlay = useCallback(() => {
|
|
5592
5597
|
gridApi?.showNoRowsOverlay();
|
|
@@ -5642,7 +5647,6 @@ const GridContextProvider = (props) => {
|
|
|
5642
5647
|
setInvisibleColumnIds,
|
|
5643
5648
|
gridReady,
|
|
5644
5649
|
prePopupOps,
|
|
5645
|
-
postPopupOps,
|
|
5646
5650
|
setApis,
|
|
5647
5651
|
setQuickFilter,
|
|
5648
5652
|
selectRowsById,
|
|
@@ -5663,8 +5667,7 @@ const GridContextProvider = (props) => {
|
|
|
5663
5667
|
sizeColumnsToFit,
|
|
5664
5668
|
autoSizeColumns,
|
|
5665
5669
|
startCellEditing,
|
|
5666
|
-
|
|
5667
|
-
cancelEdit,
|
|
5670
|
+
resetFocusedCellAfterCellEditing,
|
|
5668
5671
|
updatingCells,
|
|
5669
5672
|
redrawRows,
|
|
5670
5673
|
externallySelectedItemsAreInSync,
|
|
@@ -5675,7 +5678,8 @@ const GridContextProvider = (props) => {
|
|
|
5675
5678
|
isExternalFilterPresent,
|
|
5676
5679
|
doesExternalFilterPass,
|
|
5677
5680
|
downloadCsv,
|
|
5678
|
-
|
|
5681
|
+
onBulkEditingComplete,
|
|
5682
|
+
setOnBulkEditingComplete,
|
|
5679
5683
|
showNoRowsOverlay,
|
|
5680
5684
|
}, children: props.children }));
|
|
5681
5685
|
};
|
|
@@ -5722,12 +5726,23 @@ const downloadCsvUseValueFormattersProcessCellCallback = (params) => {
|
|
|
5722
5726
|
// We add an extra encodeToString here just in case valueFormatter is returning non string values
|
|
5723
5727
|
return encodeToString(result);
|
|
5724
5728
|
};
|
|
5729
|
+
const waitForCondition = async (condition, timeoutMs) => {
|
|
5730
|
+
const endTime = Date.now() + timeoutMs;
|
|
5731
|
+
while (Date.now() < endTime) {
|
|
5732
|
+
if (condition()) {
|
|
5733
|
+
return true;
|
|
5734
|
+
}
|
|
5735
|
+
await wait(100);
|
|
5736
|
+
}
|
|
5737
|
+
console.warn('waitForCondition failed');
|
|
5738
|
+
return false;
|
|
5739
|
+
};
|
|
5725
5740
|
|
|
5726
5741
|
const GridUpdatingContextProvider = (props) => {
|
|
5727
5742
|
const updatingBlocks = useRef({});
|
|
5728
5743
|
const updating = useRef({});
|
|
5729
5744
|
const [updatedDep, setUpdatedDep] = useState(0);
|
|
5730
|
-
const resetUpdating = () => {
|
|
5745
|
+
const resetUpdating = useCallback(() => {
|
|
5731
5746
|
const mergedUpdatingBlocks = {};
|
|
5732
5747
|
for (const key in updatingBlocks.current) {
|
|
5733
5748
|
const arr = flatten(updatingBlocks.current[key]);
|
|
@@ -5737,9 +5752,9 @@ const GridUpdatingContextProvider = (props) => {
|
|
|
5737
5752
|
}
|
|
5738
5753
|
updating.current = mergedUpdatingBlocks;
|
|
5739
5754
|
setUpdatedDep((updatedDep) => updatedDep + 1);
|
|
5740
|
-
};
|
|
5741
|
-
const updatingCols = () => Object.keys(updating.current);
|
|
5742
|
-
const modifyUpdating = async (fields, ids, fn) => {
|
|
5755
|
+
}, []);
|
|
5756
|
+
const updatingCols = useCallback(() => Object.keys(updating.current), []);
|
|
5757
|
+
const modifyUpdating = useCallback(async (fields, ids, fn) => {
|
|
5743
5758
|
const idRef = [...ids];
|
|
5744
5759
|
castArray(fields).forEach((field) => {
|
|
5745
5760
|
const fieldUpdatingIds = updatingBlocks.current[field] ?? (updatingBlocks.current[field] = []);
|
|
@@ -5752,9 +5767,12 @@ const GridUpdatingContextProvider = (props) => {
|
|
|
5752
5767
|
remove(fieldUpdatingIds, (idList) => idList === idRef);
|
|
5753
5768
|
});
|
|
5754
5769
|
resetUpdating();
|
|
5755
|
-
};
|
|
5756
|
-
const
|
|
5757
|
-
|
|
5770
|
+
}, [resetUpdating]);
|
|
5771
|
+
const anyUpdating = useCallback(() => {
|
|
5772
|
+
return !isEmpty(updating.current);
|
|
5773
|
+
}, []);
|
|
5774
|
+
const checkUpdating = useCallback((fields, id) => castArray(fields).some((f) => updating.current[f]?.includes(id)), []);
|
|
5775
|
+
return (jsx(GridUpdatingContext.Provider, { value: { modifyUpdating, anyUpdating, checkUpdating, updatingCols, updatedDep }, children: props.children }));
|
|
5758
5776
|
};
|
|
5759
5777
|
|
|
5760
5778
|
var css_248z = ".ActionButton{align-items:center;display:flex}.ActionButton-inProgress .LuiIcon{visibility:hidden}.ActionButton-minimal.lui-button-lg.lui-button-icon-right{padding-right:38px}.ActionButton.lui-button-lg.lui-button-icon-right:not(.ActionButton-tight) .LuiIcon{margin:0 4px}.ActionButton.ActionButton-tight.lui-button-lg.lui-button-icon-right .LuiIcon{margin:0}.ActionButton-iconOnly.lui-button-lg.lui-button-icon-right:not(.ActionButton-tight){padding:8px 5px}.ActionButton-iconOnly.lui-button-lg.lui-button-icon-right.ActionButton-tight{padding:0}.ActionButton-minimalArea{position:relative}.ActionButton-minimalAreaDisplay{position:absolute}.ActionButton-minimalAreaExpand{visibility:hidden}.ActionButton-inProgress.lui-button-lg.lui-button-icon-right{background-color:#e2f3f7;color:#007198;cursor:progress}.ActionButton-fill{justify-content:center;width:100%}";
|