@linzjs/step-ag-grid 28.5.1 → 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 +263 -246
- package/dist/step-ag-grid.cjs.map +1 -1
- package/dist/step-ag-grid.esm.js +264 -247
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +21 -22
- package/src/components/Grid.tsx +114 -112
- 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.cjs
CHANGED
|
@@ -449,9 +449,6 @@ const GridContext = React.createContext({
|
|
|
449
449
|
prePopupOps: () => {
|
|
450
450
|
console.error('no context provider for prePopupOps');
|
|
451
451
|
},
|
|
452
|
-
postPopupOps: () => {
|
|
453
|
-
console.error('no context provider for prePopupOps');
|
|
454
|
-
},
|
|
455
452
|
externallySelectedItemsAreInSync: false,
|
|
456
453
|
setApis: () => {
|
|
457
454
|
console.error('no context provider for setApis');
|
|
@@ -523,15 +520,12 @@ const GridContext = React.createContext({
|
|
|
523
520
|
console.error('no context provider for editingCells');
|
|
524
521
|
return false;
|
|
525
522
|
},
|
|
526
|
-
cancelEdit: () => {
|
|
527
|
-
console.error('no context provider for cancelEdit');
|
|
528
|
-
},
|
|
529
523
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
530
524
|
startCellEditing: async () => {
|
|
531
525
|
console.error('no context provider for startCellEditing');
|
|
532
526
|
},
|
|
533
|
-
|
|
534
|
-
console.error('no context provider for
|
|
527
|
+
resetFocusedCellAfterCellEditing: () => {
|
|
528
|
+
console.error('no context provider for resetFocusedCellAfterCellEditing');
|
|
535
529
|
},
|
|
536
530
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
537
531
|
updatingCells: async () => {
|
|
@@ -565,8 +559,11 @@ const GridContext = React.createContext({
|
|
|
565
559
|
downloadCsv: () => {
|
|
566
560
|
console.error('no context provider for downloadCsv');
|
|
567
561
|
},
|
|
568
|
-
|
|
569
|
-
console.error('no context provider for
|
|
562
|
+
onBulkEditingComplete: () => {
|
|
563
|
+
console.error('no context provider for onBulkEditingComplete');
|
|
564
|
+
},
|
|
565
|
+
setOnBulkEditingComplete: () => {
|
|
566
|
+
console.error('no context provider for setOnBulkEditingComplete');
|
|
570
567
|
},
|
|
571
568
|
showNoRowsOverlay: () => {
|
|
572
569
|
console.error('no context provider for showLoadingOverlay');
|
|
@@ -575,6 +572,10 @@ const GridContext = React.createContext({
|
|
|
575
572
|
const useGridContext = () => React.useContext(GridContext);
|
|
576
573
|
|
|
577
574
|
const GridUpdatingContext = React.createContext({
|
|
575
|
+
anyUpdating: () => {
|
|
576
|
+
console.error('Missing GridUpdatingContext');
|
|
577
|
+
return false;
|
|
578
|
+
},
|
|
578
579
|
checkUpdating: () => {
|
|
579
580
|
console.error('Missing GridUpdatingContext');
|
|
580
581
|
return false;
|
|
@@ -1796,6 +1797,9 @@ const MenuList = ({ ariaLabel, menuClassName, menuStyle, arrowClassName, arrowSt
|
|
|
1796
1797
|
return;
|
|
1797
1798
|
}
|
|
1798
1799
|
const callback = lodashEs.debounce(() => {
|
|
1800
|
+
if (!menuRef.current) {
|
|
1801
|
+
return;
|
|
1802
|
+
}
|
|
1799
1803
|
const { width, height } = menuRef.current.ownerDocument.body.getBoundingClientRect();
|
|
1800
1804
|
if (width === 0 || height === 0)
|
|
1801
1805
|
return;
|
|
@@ -2541,7 +2545,7 @@ const SubMenuFr = ({ 'aria-label': ariaLabel, className, disabled, direction, la
|
|
|
2541
2545
|
const SubMenu = withHovering('SubMenu', SubMenuFr);
|
|
2542
2546
|
|
|
2543
2547
|
const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, }) => {
|
|
2544
|
-
const { redrawRows, prePopupOps,
|
|
2548
|
+
const { redrawRows, prePopupOps, resetFocusedCellAfterCellEditing, getSelectedRows } = React.useContext(GridContext);
|
|
2545
2549
|
const [isOpen, setOpen] = React.useState(false);
|
|
2546
2550
|
const [anchorPoint, setAnchorPoint] = React.useState({ x: 0, y: 0 });
|
|
2547
2551
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
@@ -2558,8 +2562,8 @@ const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, })
|
|
|
2558
2562
|
const closeMenu = React.useCallback(() => {
|
|
2559
2563
|
setOpen(false);
|
|
2560
2564
|
redrawRows();
|
|
2561
|
-
|
|
2562
|
-
}, [
|
|
2565
|
+
resetFocusedCellAfterCellEditing();
|
|
2566
|
+
}, [resetFocusedCellAfterCellEditing, redrawRows]);
|
|
2563
2567
|
const cellContextMenu = React.useCallback((event) => {
|
|
2564
2568
|
if (contextMenuSelectRow && !event.node.isSelected()) {
|
|
2565
2569
|
event.node.setSelected(true, true);
|
|
@@ -2755,36 +2759,11 @@ const usePostSortRowsHook = ({ setStaleGrid }) => {
|
|
|
2755
2759
|
};
|
|
2756
2760
|
|
|
2757
2761
|
agGridCommunity.ModuleRegistry.registerModules([agGridCommunity.AllCommunityModule]);
|
|
2758
|
-
let timeOfLastSingleClick = 0;
|
|
2759
|
-
let lastClickColId;
|
|
2760
|
-
let lastClickRowIndex;
|
|
2761
|
-
const resetClickDebounce = () => {
|
|
2762
|
-
timeOfLastSingleClick = 0;
|
|
2763
|
-
lastClickColId = '';
|
|
2764
|
-
lastClickRowIndex = -1;
|
|
2765
|
-
};
|
|
2766
|
-
/**
|
|
2767
|
-
* If click is more than 200ms since last click return true.
|
|
2768
|
-
*/
|
|
2769
|
-
const clickDebounceSkipClick = (colId, rowIndex) => {
|
|
2770
|
-
const doubleClickMs = 200;
|
|
2771
|
-
if (Date.now() - timeOfLastSingleClick < doubleClickMs &&
|
|
2772
|
-
lastClickColId === colId &&
|
|
2773
|
-
lastClickRowIndex === rowIndex) {
|
|
2774
|
-
// Skipping double click due to single click edit
|
|
2775
|
-
return true;
|
|
2776
|
-
}
|
|
2777
|
-
timeOfLastSingleClick = Date.now();
|
|
2778
|
-
lastClickColId = colId;
|
|
2779
|
-
lastClickRowIndex = rowIndex;
|
|
2780
|
-
return false;
|
|
2781
|
-
};
|
|
2782
2762
|
/**
|
|
2783
2763
|
* Wrapper for AgGrid to add commonly used functionality.
|
|
2784
2764
|
*/
|
|
2785
2765
|
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 }) => {
|
|
2786
|
-
const { gridReady, gridRenderState, setApis, ensureRowVisible, getFirstRowId, selectRowsById, focusByRowById, ensureSelectedRowIsVisible, autoSizeColumns, sizeColumnsToFit, externallySelectedItemsAreInSync, setExternallySelectedItemsAreInSync, isExternalFilterPresent, doesExternalFilterPass,
|
|
2787
|
-
const { startCellEditing } = useGridContext();
|
|
2766
|
+
const { gridReady, gridRenderState, setApis, ensureRowVisible, getFirstRowId, selectRowsById, focusByRowById, ensureSelectedRowIsVisible, autoSizeColumns, sizeColumnsToFit, externallySelectedItemsAreInSync, setExternallySelectedItemsAreInSync, isExternalFilterPresent, doesExternalFilterPass, setOnBulkEditingComplete, getColDef, showNoRowsOverlay, prePopupOps, startCellEditing, } = useGridContext();
|
|
2788
2767
|
const { updatedDep, updatingCols } = React.useContext(GridUpdatingContext);
|
|
2789
2768
|
const gridDivRef = React.useRef(null);
|
|
2790
2769
|
const lastSelectedIds = React.useRef([]);
|
|
@@ -3003,26 +2982,10 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3003
2982
|
const onModelUpdated = React.useCallback((event) => {
|
|
3004
2983
|
event.api.showNoRowsOverlay();
|
|
3005
2984
|
}, []);
|
|
3006
|
-
/**
|
|
3007
|
-
* Force-refresh all selected rows to re-run class function, to update selection highlighting
|
|
3008
|
-
*/
|
|
3009
|
-
const refreshSelectedRows = React.useCallback((_event) => {
|
|
3010
|
-
// MATT Disabled I don't believe these are needed anymore
|
|
3011
|
-
// I've left them here just in case they are
|
|
3012
|
-
/*event.api.refreshCells({
|
|
3013
|
-
force: true,
|
|
3014
|
-
rowNodes: event.api.getSelectedNodes(),
|
|
3015
|
-
});*/
|
|
3016
|
-
}, []);
|
|
3017
2985
|
/**
|
|
3018
2986
|
* Handle double click edit
|
|
3019
2987
|
*/
|
|
3020
2988
|
const onCellDoubleClick = React.useCallback((event) => {
|
|
3021
|
-
if (clickDebounceSkipClick(event.colDef.colId, event.rowIndex)) {
|
|
3022
|
-
// the next click will be a single click, we want it to pass
|
|
3023
|
-
resetClickDebounce();
|
|
3024
|
-
return;
|
|
3025
|
-
}
|
|
3026
2989
|
const editable = fnOrVar(event.colDef?.editable, event);
|
|
3027
2990
|
if (editable && !invokeEditAction(event)) {
|
|
3028
2991
|
void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
|
|
@@ -3034,9 +2997,6 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3034
2997
|
const onCellClicked = React.useCallback((event) => {
|
|
3035
2998
|
const editable = fnOrVar(event.colDef?.editable, event);
|
|
3036
2999
|
if ((editable && event.colDef.singleClickEdit) ?? singleClickEdit) {
|
|
3037
|
-
if (clickDebounceSkipClick(event.colDef.colId, event.rowIndex)) {
|
|
3038
|
-
return;
|
|
3039
|
-
}
|
|
3040
3000
|
void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
|
|
3041
3001
|
}
|
|
3042
3002
|
}, [singleClickEdit, startCellEditing]);
|
|
@@ -3132,11 +3092,10 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3132
3092
|
React.useEffect(() => {
|
|
3133
3093
|
const newLoading = !rowData || params.loading === true;
|
|
3134
3094
|
if (newLoading && !prevLoading.current) {
|
|
3135
|
-
stopEditing();
|
|
3136
3095
|
showNoRowsOverlay();
|
|
3137
3096
|
}
|
|
3138
3097
|
prevLoading.current = newLoading;
|
|
3139
|
-
}, [params.loading, rowData, showNoRowsOverlay
|
|
3098
|
+
}, [params.loading, rowData, showNoRowsOverlay]);
|
|
3140
3099
|
/**
|
|
3141
3100
|
* Resize columns to fit if required on window/container resize
|
|
3142
3101
|
*/
|
|
@@ -3198,6 +3157,23 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3198
3157
|
});
|
|
3199
3158
|
}
|
|
3200
3159
|
}, [clearHighlightRowClasses]);
|
|
3160
|
+
const onCellFocused = React.useCallback((event) => {
|
|
3161
|
+
if (!params.onCellFocused || event.rowIndex == null) {
|
|
3162
|
+
return;
|
|
3163
|
+
}
|
|
3164
|
+
const api = event.api;
|
|
3165
|
+
const rowNode = api.getDisplayedRowAtIndex(event.rowIndex);
|
|
3166
|
+
const data = rowNode?.data;
|
|
3167
|
+
const column = event.column;
|
|
3168
|
+
if (!data || !column || typeof column === 'string') {
|
|
3169
|
+
return;
|
|
3170
|
+
}
|
|
3171
|
+
const colDef = column.getColDef();
|
|
3172
|
+
if (!colDef || typeof colDef === 'string') {
|
|
3173
|
+
return;
|
|
3174
|
+
}
|
|
3175
|
+
params.onCellFocused({ colDef, data });
|
|
3176
|
+
}, [params]);
|
|
3201
3177
|
const onRowDragEnd = React.useCallback((event) => {
|
|
3202
3178
|
clearHighlightRowClasses();
|
|
3203
3179
|
gridElementRef.current = undefined;
|
|
@@ -3222,57 +3198,76 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3222
3198
|
}
|
|
3223
3199
|
}, [params.setExternalSelectedItems, selectable]);
|
|
3224
3200
|
// This is setting a ref in the GridContext so won't be triggering an update loop
|
|
3225
|
-
|
|
3226
|
-
const
|
|
3227
|
-
const
|
|
3201
|
+
setOnBulkEditingComplete(params.onBulkEditingComplete);
|
|
3202
|
+
const getRowId = React.useCallback((params) => `${params.data.id}`, []);
|
|
3203
|
+
const defaultColDef = React.useMemo(() => ({
|
|
3204
|
+
minWidth: 48,
|
|
3205
|
+
...lodashEs.omit(params.defaultColDef, ['editable', 'field', 'colId', 'tooltipField']),
|
|
3206
|
+
}), [params.defaultColDef]);
|
|
3207
|
+
const noRowsOverlayComponent = React.useCallback((event) => {
|
|
3208
|
+
const headerRowCount = columnDefs.some((c) => c.children) ? 2 : 1;
|
|
3209
|
+
let rowCount = 0;
|
|
3210
|
+
event.api.forEachNode(() => rowCount++);
|
|
3211
|
+
return (jsxRuntime.jsx(GridNoRowsOverlay, { loading: !rowData || params.loading === true, rowCount: rowCount, headerRowHeight: headerRowCount * rowHeight, filteredRowCount: event.api.getDisplayedRowCount(), noRowsOverlayText: params.noRowsOverlayText, noRowsMatchingOverlayText: params.noRowsMatchingOverlayText }));
|
|
3212
|
+
}, [columnDefs, params.loading, params.noRowsMatchingOverlayText, params.noRowsOverlayText, rowData, rowHeight]);
|
|
3213
|
+
const selectionColumnDef = React.useMemo(() => {
|
|
3214
|
+
const selectWidth = params.hideSelectColumn ? 0 : selectable && params.onRowDragEnd ? 76 : 48;
|
|
3215
|
+
return {
|
|
3216
|
+
suppressNavigable: params.hideSelectColumn,
|
|
3217
|
+
rowDrag: !!params.onRowDragEnd,
|
|
3218
|
+
minWidth: selectWidth,
|
|
3219
|
+
maxWidth: selectWidth,
|
|
3220
|
+
pinned: selectColumnPinned,
|
|
3221
|
+
headerComponentParams: {
|
|
3222
|
+
exportable: false,
|
|
3223
|
+
},
|
|
3224
|
+
headerClass: clsx('ag-header-hide-default-select', params.onRowDragEnd && 'ag-header-select-draggable'),
|
|
3225
|
+
headerComponent: rowSelection == 'multiple' ? GridHeaderSelect : undefined,
|
|
3226
|
+
suppressHeaderKeyboardEvent: (e) => {
|
|
3227
|
+
if (!selectable)
|
|
3228
|
+
return false;
|
|
3229
|
+
if ((e.event.key === 'Enter' || e.event.key === ' ') && !e.event.repeat) {
|
|
3230
|
+
if (lodashEs.isEmpty(e.api.getSelectedRows())) {
|
|
3231
|
+
e.api.selectAll('filtered');
|
|
3232
|
+
}
|
|
3233
|
+
else {
|
|
3234
|
+
e.api.deselectAll();
|
|
3235
|
+
}
|
|
3236
|
+
return true;
|
|
3237
|
+
}
|
|
3238
|
+
return false;
|
|
3239
|
+
},
|
|
3240
|
+
onCellClicked: params.enableSelectionWithoutKeys || params.enableClickSelection
|
|
3241
|
+
? undefined
|
|
3242
|
+
: clickInputWhenContainingCellClicked,
|
|
3243
|
+
};
|
|
3244
|
+
}, [
|
|
3245
|
+
params.enableClickSelection,
|
|
3246
|
+
params.enableSelectionWithoutKeys,
|
|
3247
|
+
params.hideSelectColumn,
|
|
3248
|
+
params.onRowDragEnd,
|
|
3249
|
+
rowSelection,
|
|
3250
|
+
selectColumnPinned,
|
|
3251
|
+
selectable,
|
|
3252
|
+
]);
|
|
3228
3253
|
return (jsxRuntime.jsxs("div", { "data-testid": dataTestId, className: clsx('Grid-container', theme, 'theme-specific', staleGrid && 'Grid-sortIsStale', gridReady && rowData && autoSized && 'Grid-ready'), children: [gridContextMenu.component, jsxRuntime.jsx("div", { style: { flex: 1 }, ref: gridDivRef, children: jsxRuntime.jsx(agGridReact.AgGridReact, { theme: 'legacy', rowSelection: selectable
|
|
3229
3254
|
? {
|
|
3230
3255
|
enableSelectionWithoutKeys: params.enableSelectionWithoutKeys ?? false,
|
|
3231
3256
|
enableClickSelection: params.enableClickSelection ?? false,
|
|
3232
3257
|
mode: rowSelection == 'single' ? 'singleRow' : 'multiRow',
|
|
3233
3258
|
}
|
|
3234
|
-
: undefined, rowHeight: rowHeight, animateRows: params.animateRows ?? false, rowClassRules: params.rowClassRules, getRowId:
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
// filter is exact matches exactly groups separated by commas
|
|
3240
|
-
return filterStr.split(',').map((str) => str.trim());
|
|
3241
|
-
}, 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: {
|
|
3242
|
-
suppressNavigable: params.hideSelectColumn,
|
|
3243
|
-
rowDrag: !!params.onRowDragEnd,
|
|
3244
|
-
minWidth: selectWidth,
|
|
3245
|
-
maxWidth: selectWidth,
|
|
3246
|
-
pinned: selectColumnPinned,
|
|
3247
|
-
headerComponentParams: {
|
|
3248
|
-
exportable: false,
|
|
3249
|
-
},
|
|
3250
|
-
headerClass: clsx('ag-header-hide-default-select', params.onRowDragEnd && 'ag-header-select-draggable'),
|
|
3251
|
-
headerComponent: rowSelection == 'multiple' ? GridHeaderSelect : undefined,
|
|
3252
|
-
suppressHeaderKeyboardEvent: (e) => {
|
|
3253
|
-
if (!selectable)
|
|
3254
|
-
return false;
|
|
3255
|
-
if ((e.event.key === 'Enter' || e.event.key === ' ') && !e.event.repeat) {
|
|
3256
|
-
if (lodashEs.isEmpty(e.api.getSelectedRows())) {
|
|
3257
|
-
e.api.selectAll('filtered');
|
|
3258
|
-
}
|
|
3259
|
-
else {
|
|
3260
|
-
e.api.deselectAll();
|
|
3261
|
-
}
|
|
3262
|
-
return true;
|
|
3263
|
-
}
|
|
3264
|
-
return false;
|
|
3265
|
-
},
|
|
3266
|
-
onCellClicked: params.enableSelectionWithoutKeys || params.enableClickSelection
|
|
3267
|
-
? undefined
|
|
3268
|
-
: clickInputWhenContainingCellClicked,
|
|
3269
|
-
} }) })] }));
|
|
3259
|
+
: 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 }) })] }));
|
|
3260
|
+
};
|
|
3261
|
+
const quickFilterParser = (filterStr) => {
|
|
3262
|
+
// filter is exact matches exactly groups separated by commas
|
|
3263
|
+
return filterStr.split(',').map((str) => str.trim());
|
|
3270
3264
|
};
|
|
3271
3265
|
|
|
3272
3266
|
const GridPopoverContext = React.createContext({
|
|
3273
3267
|
anchorRef: { current: null },
|
|
3274
3268
|
saving: false,
|
|
3275
3269
|
setSaving: () => { },
|
|
3270
|
+
stopEditing: () => { },
|
|
3276
3271
|
colId: '',
|
|
3277
3272
|
field: '',
|
|
3278
3273
|
value: null,
|
|
@@ -3290,7 +3285,7 @@ const GridPopoverContextProvider = (props2) => {
|
|
|
3290
3285
|
const anchorRef = React.useRef(props.eGridCell);
|
|
3291
3286
|
const hasSaved = React.useRef(false);
|
|
3292
3287
|
const [saving, setSaving] = React.useState(false);
|
|
3293
|
-
const { colDef } = props;
|
|
3288
|
+
const { colDef, stopEditing, formatValue, data, value } = props;
|
|
3294
3289
|
const { cellEditorParams } = colDef;
|
|
3295
3290
|
const multiEdit = cellEditorParams?.multiEdit ?? false;
|
|
3296
3291
|
// Then item that is clicked on will always be first in the list
|
|
@@ -3298,8 +3293,10 @@ const GridPopoverContextProvider = (props2) => {
|
|
|
3298
3293
|
const field = props.colDef?.field ?? '';
|
|
3299
3294
|
const colId = props.colDef?.colId ?? field ?? '';
|
|
3300
3295
|
const updateValue = React.useCallback(async (saveFn, tabDirection) => {
|
|
3301
|
-
if (hasSaved.current)
|
|
3296
|
+
if (hasSaved.current) {
|
|
3297
|
+
// already called save so ignore
|
|
3302
3298
|
return true;
|
|
3299
|
+
}
|
|
3303
3300
|
hasSaved.current = true;
|
|
3304
3301
|
return saving ? false : await updatingCells({ selectedRows, field }, saveFn, setSaving, tabDirection);
|
|
3305
3302
|
}, [field, saving, selectedRows, updatingCells]);
|
|
@@ -3310,10 +3307,11 @@ const GridPopoverContextProvider = (props2) => {
|
|
|
3310
3307
|
selectedRows,
|
|
3311
3308
|
colId,
|
|
3312
3309
|
field,
|
|
3313
|
-
data
|
|
3314
|
-
value
|
|
3310
|
+
data,
|
|
3311
|
+
value,
|
|
3315
3312
|
updateValue,
|
|
3316
|
-
formatValue
|
|
3313
|
+
formatValue,
|
|
3314
|
+
stopEditing,
|
|
3317
3315
|
}, children: children }));
|
|
3318
3316
|
};
|
|
3319
3317
|
|
|
@@ -3463,7 +3461,7 @@ const GridCellMultiEditor = (props, cellEditorSelector) => GridCell({
|
|
|
3463
3461
|
});
|
|
3464
3462
|
|
|
3465
3463
|
const useGridFilter = (filter) => {
|
|
3466
|
-
const { addExternalFilter, removeExternalFilter } =
|
|
3464
|
+
const { addExternalFilter, removeExternalFilter } = useGridContext();
|
|
3467
3465
|
React.useEffect(() => {
|
|
3468
3466
|
const thisFilter = filter;
|
|
3469
3467
|
thisFilter && addExternalFilter(thisFilter);
|
|
@@ -3938,8 +3936,8 @@ const textMatch = (text, filter) => {
|
|
|
3938
3936
|
};
|
|
3939
3937
|
|
|
3940
3938
|
const useGridPopoverHook = (props) => {
|
|
3941
|
-
const {
|
|
3942
|
-
const { anchorRef, saving, updateValue } = useGridPopoverContext();
|
|
3939
|
+
const { onBulkEditingComplete } = useGridContext();
|
|
3940
|
+
const { anchorRef, saving, updateValue, stopEditing } = useGridPopoverContext();
|
|
3943
3941
|
const saveButtonRef = React.useRef(null);
|
|
3944
3942
|
const [isOpen, setOpen] = React.useState(false);
|
|
3945
3943
|
React.useEffect(() => {
|
|
@@ -3947,30 +3945,30 @@ const useGridPopoverHook = (props) => {
|
|
|
3947
3945
|
}, []);
|
|
3948
3946
|
const triggerSave = React.useCallback(async (reason) => {
|
|
3949
3947
|
if (reason == CloseReason.CANCEL) {
|
|
3950
|
-
|
|
3948
|
+
stopEditing();
|
|
3949
|
+
onBulkEditingComplete();
|
|
3951
3950
|
return;
|
|
3952
3951
|
}
|
|
3953
|
-
if (props
|
|
3952
|
+
if (props?.invalid?.()) {
|
|
3953
|
+
// Don't close, don't do anything it's invalid
|
|
3954
3954
|
return;
|
|
3955
3955
|
}
|
|
3956
3956
|
if (!props.save) {
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
if (props.invalid)
|
|
3962
|
-
stopEditing();
|
|
3963
|
-
if (await updateValue(props.save, reason === CloseReason.TAB_FORWARD ? 1 : reason === CloseReason.TAB_BACKWARD ? -1 : 0)) {
|
|
3964
|
-
if (!props.invalid)
|
|
3965
|
-
stopEditing();
|
|
3966
|
-
}
|
|
3957
|
+
// No save method so just close
|
|
3958
|
+
stopEditing();
|
|
3959
|
+
onBulkEditingComplete();
|
|
3960
|
+
return;
|
|
3967
3961
|
}
|
|
3968
|
-
|
|
3962
|
+
if (await updateValue(props.save, reason === CloseReason.TAB_FORWARD ? 1 : reason === CloseReason.TAB_BACKWARD ? -1 : 0)) {
|
|
3963
|
+
stopEditing();
|
|
3964
|
+
}
|
|
3965
|
+
}, [onBulkEditingComplete, props, stopEditing, updateValue]);
|
|
3969
3966
|
const popoverWrapper = React.useCallback((children) => {
|
|
3970
3967
|
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: anchorRef.current && (jsxRuntime.jsxs(ControlledMenu, { state: isOpen ? 'open' : 'closed', portal: true, unmountOnClose: true, anchorRef: anchorRef, saveButtonRef: saveButtonRef, menuClassName: 'step-ag-grid-react-menu', onClose: (event) => {
|
|
3971
3968
|
// Prevent menu from closing when modals are invoked
|
|
3972
|
-
if (event.reason === CloseReason.BLUR)
|
|
3969
|
+
if (event.reason === CloseReason.BLUR) {
|
|
3973
3970
|
return;
|
|
3971
|
+
}
|
|
3974
3972
|
void triggerSave(event.reason);
|
|
3975
3973
|
}, viewScroll: 'auto', dontShrinkIfDirectionIsTop: true, className: props.className, children: [saving && ( // This is the overlay that prevents editing when the editor is saving
|
|
3976
3974
|
jsxRuntime.jsx("div", { className: 'ComponentLoadingWrapper-saveOverlay' })), children, jsxRuntime.jsx("button", { ref: saveButtonRef, "data-reason": '', onClick: (e) => {
|
|
@@ -5064,7 +5062,7 @@ const isFlexColumn = (colDef) => !!colDef.flex && !isGridCellFiller(colDef);
|
|
|
5064
5062
|
* Also, make sure the provider is created in a separate component, otherwise it won't be found.
|
|
5065
5063
|
*/
|
|
5066
5064
|
const GridContextProvider = (props) => {
|
|
5067
|
-
const { modifyUpdating,
|
|
5065
|
+
const { modifyUpdating, anyUpdating } = React.useContext(GridUpdatingContext);
|
|
5068
5066
|
const [gridApi, setGridApi] = React.useState();
|
|
5069
5067
|
const [gridReady, setGridReady] = React.useState(false);
|
|
5070
5068
|
const [quickFilter, _setQuickFilter] = React.useState('');
|
|
@@ -5083,7 +5081,7 @@ const GridContextProvider = (props) => {
|
|
|
5083
5081
|
/**
|
|
5084
5082
|
* Make extra sure the GridCellFillerColId never gets added to invisibleColumnIds as it's dynamically determined
|
|
5085
5083
|
*/
|
|
5086
|
-
const setInvisibleColumnIds = (invisibleColumnIds) => _setInvisibleColumnIds(lodashEs.pull(invisibleColumnIds, GridCellFillerColId));
|
|
5084
|
+
const setInvisibleColumnIds = React.useCallback((invisibleColumnIds) => _setInvisibleColumnIds(lodashEs.pull(invisibleColumnIds, GridCellFillerColId)), []);
|
|
5087
5085
|
/**
|
|
5088
5086
|
* Set quick filter directly on grid, based on previously save quickFilter state.
|
|
5089
5087
|
*/
|
|
@@ -5178,17 +5176,6 @@ const GridContextProvider = (props) => {
|
|
|
5178
5176
|
}
|
|
5179
5177
|
prePopupFocusedCell.current = gridApi.getFocusedCell() ?? undefined;
|
|
5180
5178
|
}, [gridApi]);
|
|
5181
|
-
/**
|
|
5182
|
-
* After a popup refocus the cell.
|
|
5183
|
-
*/
|
|
5184
|
-
const postPopupOps = React.useCallback(() => {
|
|
5185
|
-
if (!gridApi || gridApi.isDestroyed()) {
|
|
5186
|
-
return;
|
|
5187
|
-
}
|
|
5188
|
-
if (prePopupFocusedCell.current) {
|
|
5189
|
-
gridApi.setFocusedCell(prePopupFocusedCell.current.rowIndex, prePopupFocusedCell.current.column);
|
|
5190
|
-
}
|
|
5191
|
-
}, [gridApi]);
|
|
5192
5179
|
/**
|
|
5193
5180
|
* Get all row id's in grid.
|
|
5194
5181
|
*/
|
|
@@ -5376,13 +5363,16 @@ const GridContextProvider = (props) => {
|
|
|
5376
5363
|
gridApi.sizeColumnsToFit();
|
|
5377
5364
|
}
|
|
5378
5365
|
}, [gridApi]);
|
|
5379
|
-
|
|
5380
|
-
|
|
5366
|
+
/**
|
|
5367
|
+
*
|
|
5368
|
+
*/
|
|
5369
|
+
const resetFocusedCellAfterCellEditing = React.useCallback(() => {
|
|
5370
|
+
if (!gridApi || gridApi.isDestroyed() || startCellEditingInProgressRef.current) {
|
|
5381
5371
|
return;
|
|
5382
5372
|
}
|
|
5383
|
-
gridApi.stopEditing();
|
|
5384
5373
|
if (prePopupFocusedCell.current) {
|
|
5385
5374
|
gridApi.setFocusedCell(prePopupFocusedCell.current.rowIndex, prePopupFocusedCell.current.column);
|
|
5375
|
+
prePopupFocusedCell.current = undefined;
|
|
5386
5376
|
}
|
|
5387
5377
|
}, [gridApi]);
|
|
5388
5378
|
// waitForExternallySelectedItemsToBeInSync can't use the state as it won't be updated during function execution
|
|
@@ -5403,58 +5393,65 @@ const GridContextProvider = (props) => {
|
|
|
5403
5393
|
console.error('externallySelectedItems did not sync with ag-grid selection');
|
|
5404
5394
|
}
|
|
5405
5395
|
}, []);
|
|
5396
|
+
const startCellEditingInProgressRef = React.useRef(false);
|
|
5406
5397
|
const startCellEditing = React.useCallback(async ({ rowId, colId }) => {
|
|
5407
|
-
if (!gridApi)
|
|
5408
|
-
return;
|
|
5409
|
-
const colDef = gridApi.getColumnDef(colId);
|
|
5410
|
-
if (!colDef) {
|
|
5411
|
-
return;
|
|
5412
|
-
}
|
|
5413
|
-
const rowNode = gridApi.getRowNode(`${rowId}`);
|
|
5414
|
-
if (!rowNode) {
|
|
5415
|
-
return;
|
|
5416
|
-
}
|
|
5417
|
-
prePopupOps();
|
|
5418
|
-
const shouldSelectNode = !rowNode.isSelected();
|
|
5419
|
-
if (shouldSelectNode) {
|
|
5420
|
-
externallySelectedItemsAreInSyncRef.current = false;
|
|
5421
|
-
setExternallySelectedItemsAreInSync(false);
|
|
5422
|
-
rowNode.setSelected(true, true);
|
|
5423
|
-
await waitForExternallySelectedItemsToBeInSync();
|
|
5424
|
-
}
|
|
5425
|
-
// Cell already being edited, so don't re-edit until finished
|
|
5426
|
-
if (checkUpdating([colDef.field ?? colDef.colId ?? ''], rowId)) {
|
|
5398
|
+
if (!gridApi || startCellEditingInProgressRef.current) {
|
|
5427
5399
|
return;
|
|
5428
5400
|
}
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5401
|
+
startCellEditingInProgressRef.current = true;
|
|
5402
|
+
try {
|
|
5403
|
+
// Edit in progress so don't edit until finished, timeout waiting after 5s
|
|
5404
|
+
if (!(await waitForCondition(() => !anyUpdating(), 5000))) {
|
|
5405
|
+
console.error("Could not start edit because previous edit hasn't finished after 5 seconds");
|
|
5406
|
+
return;
|
|
5407
|
+
}
|
|
5408
|
+
const colDef = gridApi.getColumnDef(colId);
|
|
5409
|
+
if (!colDef) {
|
|
5410
|
+
return;
|
|
5411
|
+
}
|
|
5412
|
+
const rowNode = gridApi.getRowNode(`${rowId}`);
|
|
5413
|
+
if (!rowNode) {
|
|
5414
|
+
return;
|
|
5415
|
+
}
|
|
5416
|
+
prePopupOps();
|
|
5417
|
+
const shouldSelectNode = !rowNode.isSelected();
|
|
5418
|
+
if (shouldSelectNode) {
|
|
5419
|
+
externallySelectedItemsAreInSyncRef.current = false;
|
|
5420
|
+
setExternallySelectedItemsAreInSync(false);
|
|
5421
|
+
rowNode.setSelected(true, true);
|
|
5422
|
+
await waitForExternallySelectedItemsToBeInSync();
|
|
5423
|
+
}
|
|
5424
|
+
const rowIndex = rowNode.rowIndex;
|
|
5425
|
+
if (rowIndex != null) {
|
|
5426
|
+
lodashEs.defer(() => {
|
|
5427
|
+
!gridApi.isDestroyed() &&
|
|
5428
|
+
gridApi.startEditingCell({
|
|
5429
|
+
rowIndex,
|
|
5430
|
+
colKey: colId,
|
|
5431
|
+
});
|
|
5432
|
+
});
|
|
5433
|
+
}
|
|
5438
5434
|
}
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
const
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
const
|
|
5449
|
-
|
|
5435
|
+
finally {
|
|
5436
|
+
startCellEditingInProgressRef.current = false;
|
|
5437
|
+
}
|
|
5438
|
+
}, [anyUpdating, gridApi, prePopupOps, waitForExternallySelectedItemsToBeInSync]);
|
|
5439
|
+
const bulkEditingCompleteCallbackRef = React.useRef();
|
|
5440
|
+
const onBulkEditingComplete = React.useCallback(() => {
|
|
5441
|
+
resetFocusedCellAfterCellEditing();
|
|
5442
|
+
bulkEditingCompleteCallbackRef.current?.();
|
|
5443
|
+
}, [resetFocusedCellAfterCellEditing]);
|
|
5444
|
+
const setOnBulkEditingComplete = React.useCallback((cellEditingCompleteCallback) => {
|
|
5445
|
+
bulkEditingCompleteCallbackRef.current = cellEditingCompleteCallback;
|
|
5450
5446
|
}, []);
|
|
5451
5447
|
/**
|
|
5452
5448
|
* Returns true if an editable cell on same row was selected, else false.
|
|
5453
5449
|
*/
|
|
5454
5450
|
const selectNextEditableCell = React.useCallback(async (tabDirection) => {
|
|
5455
5451
|
// Pretend it succeeded to prevent unwanted cellEditingCompleteCallback
|
|
5456
|
-
if (!gridApi)
|
|
5452
|
+
if (!gridApi) {
|
|
5457
5453
|
return true;
|
|
5454
|
+
}
|
|
5458
5455
|
const focusedCellIsEditable = () => {
|
|
5459
5456
|
const focusedCell = gridApi.isDestroyed() ? null : gridApi.getFocusedCell();
|
|
5460
5457
|
const nextColumn = focusedCell?.column;
|
|
@@ -5470,16 +5467,16 @@ const GridContextProvider = (props) => {
|
|
|
5470
5467
|
if (gridApi.isDestroyed()) {
|
|
5471
5468
|
return true;
|
|
5472
5469
|
}
|
|
5470
|
+
// Prevent resetting focus to original editing cell
|
|
5471
|
+
prePopupFocusedCell.current = undefined;
|
|
5473
5472
|
const preRow = gridApi.getFocusedCell();
|
|
5474
5473
|
if (tabDirection === 1) {
|
|
5474
|
+
gridApi.stopEditing();
|
|
5475
5475
|
gridApi.tabToNextCell();
|
|
5476
5476
|
}
|
|
5477
5477
|
else {
|
|
5478
5478
|
gridApi.tabToPreviousCell();
|
|
5479
5479
|
}
|
|
5480
|
-
// If we don't wait the tab to next element won't work
|
|
5481
|
-
// I think this is due to the grid resizing
|
|
5482
|
-
await wait(150);
|
|
5483
5480
|
if (gridApi.isDestroyed()) {
|
|
5484
5481
|
return true;
|
|
5485
5482
|
}
|
|
@@ -5492,64 +5489,71 @@ const GridContextProvider = (props) => {
|
|
|
5492
5489
|
if (focusedCellIsEditable()) {
|
|
5493
5490
|
const focusedCell = gridApi.getFocusedCell();
|
|
5494
5491
|
if (focusedCell) {
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5499
|
-
}
|
|
5492
|
+
const rowNode = gridApi.getDisplayedRowAtIndex(focusedCell.rowIndex);
|
|
5493
|
+
const rowId = rowNode?.data?.id;
|
|
5494
|
+
if (rowId == null) {
|
|
5495
|
+
return false;
|
|
5496
|
+
}
|
|
5497
|
+
await startCellEditing({ rowId, colId: focusedCell.column.getColId() });
|
|
5500
5498
|
return true;
|
|
5501
5499
|
}
|
|
5502
5500
|
}
|
|
5503
5501
|
}
|
|
5504
5502
|
return false;
|
|
5505
|
-
}, [gridApi,
|
|
5503
|
+
}, [gridApi, startCellEditing]);
|
|
5506
5504
|
const updatingCells = React.useCallback(async (props, fnUpdate, setSaving, tabDirection) => {
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5511
|
-
|
|
5505
|
+
try {
|
|
5506
|
+
setSaving?.(true);
|
|
5507
|
+
return await gridApiOp(async (gridApi) => {
|
|
5508
|
+
const selectedRows = props.selectedRows;
|
|
5509
|
+
let ok = false;
|
|
5510
|
+
await modifyUpdating(props.field ?? '', selectedRows.map((data) => data.id), async () => {
|
|
5511
|
+
// MATT Disabled I don't believe these are needed anymore
|
|
5512
|
+
// I've left them here just in case they are
|
|
5513
|
+
// Need to refresh to get spinners to work on all rows
|
|
5514
|
+
// gridApi.refreshCells({ rowNodes: props.selectedRows as RowNode[], force: true });
|
|
5515
|
+
ok = await fnUpdate(selectedRows).catch((ex) => {
|
|
5516
|
+
console.error('Exception during modifyUpdating', ex);
|
|
5517
|
+
return false;
|
|
5518
|
+
});
|
|
5519
|
+
});
|
|
5512
5520
|
// MATT Disabled I don't believe these are needed anymore
|
|
5513
5521
|
// I've left them here just in case they are
|
|
5514
|
-
//
|
|
5515
|
-
// gridApi.refreshCells({ rowNodes:
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
return false;
|
|
5519
|
-
});
|
|
5520
|
-
});
|
|
5521
|
-
// MATT Disabled I don't believe these are needed anymore
|
|
5522
|
-
// I've left them here just in case they are
|
|
5523
|
-
// async processes need to refresh their own rows
|
|
5524
|
-
// gridApi.refreshCells({ rowNodes: selectedRows as RowNode[], force: true });
|
|
5525
|
-
if (gridApi.isDestroyed()) {
|
|
5526
|
-
return ok;
|
|
5527
|
-
}
|
|
5528
|
-
if (ok) {
|
|
5529
|
-
const cell = gridApi.getFocusedCell();
|
|
5530
|
-
if (cell && gridApi.getFocusedCell() == null) {
|
|
5531
|
-
!gridApi.isDestroyed && gridApi.setFocusedCell(cell.rowIndex, cell.column);
|
|
5522
|
+
// async processes need to refresh their own rows
|
|
5523
|
+
// gridApi.refreshCells({ rowNodes: selectedRows as RowNode[], force: true });
|
|
5524
|
+
if (gridApi.isDestroyed()) {
|
|
5525
|
+
return ok;
|
|
5532
5526
|
}
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
|
|
5540
|
-
// Only focus next cell if user hasn't already manually changed focus
|
|
5541
|
-
const postPopupFocusedCell = gridApi.getFocusedCell();
|
|
5542
|
-
if (prePopupFocusedCell.current &&
|
|
5543
|
-
postPopupFocusedCell &&
|
|
5544
|
-
prePopupFocusedCell.current.rowIndex == postPopupFocusedCell.rowIndex &&
|
|
5545
|
-
prePopupFocusedCell.current.column.getColId() == postPopupFocusedCell.column.getColId()) {
|
|
5546
|
-
if (!tabDirection || !(await selectNextEditableCell(tabDirection))) {
|
|
5547
|
-
cellEditingCompleteCallbackRef.current && cellEditingCompleteCallbackRef.current();
|
|
5527
|
+
if (ok) {
|
|
5528
|
+
const cell = gridApi.getFocusedCell();
|
|
5529
|
+
if (cell && gridApi.getFocusedCell() == null) {
|
|
5530
|
+
!gridApi.isDestroyed && gridApi.setFocusedCell(cell.rowIndex, cell.column);
|
|
5531
|
+
}
|
|
5532
|
+
// This is needed to trigger postSortRowsHook
|
|
5533
|
+
gridApi.refreshClientSideRowModel();
|
|
5548
5534
|
}
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5535
|
+
void (async () => {
|
|
5536
|
+
// Only focus next cell if user hasn't already manually changed focus
|
|
5537
|
+
const postPopupFocusedCell = gridApi.getFocusedCell();
|
|
5538
|
+
if (prePopupFocusedCell.current &&
|
|
5539
|
+
postPopupFocusedCell &&
|
|
5540
|
+
prePopupFocusedCell.current.rowIndex == postPopupFocusedCell.rowIndex &&
|
|
5541
|
+
prePopupFocusedCell.current.column.getColId() == postPopupFocusedCell.column.getColId()) {
|
|
5542
|
+
if (!tabDirection || !(await selectNextEditableCell(tabDirection))) {
|
|
5543
|
+
onBulkEditingComplete();
|
|
5544
|
+
}
|
|
5545
|
+
}
|
|
5546
|
+
else {
|
|
5547
|
+
onBulkEditingComplete();
|
|
5548
|
+
}
|
|
5549
|
+
})();
|
|
5550
|
+
return ok;
|
|
5551
|
+
});
|
|
5552
|
+
}
|
|
5553
|
+
finally {
|
|
5554
|
+
setSaving?.(false);
|
|
5555
|
+
}
|
|
5556
|
+
}, [gridApiOp, modifyUpdating, onBulkEditingComplete, selectNextEditableCell]);
|
|
5553
5557
|
const redrawRows = React.useMemo(() => debounce((rowNodes) => {
|
|
5554
5558
|
try {
|
|
5555
5559
|
gridApi && gridApi.redrawRows(rowNodes ? { rowNodes } : undefined);
|
|
@@ -5580,16 +5584,16 @@ const GridContextProvider = (props) => {
|
|
|
5580
5584
|
preHash !== postHash && gridApi.clearFocusedCell();
|
|
5581
5585
|
}
|
|
5582
5586
|
}, 200), [gridApi]);
|
|
5583
|
-
const addExternalFilter = (filter) => {
|
|
5587
|
+
const addExternalFilter = React.useCallback((filter) => {
|
|
5584
5588
|
externalFilters.current.push(filter);
|
|
5585
5589
|
void onFilterChanged();
|
|
5586
|
-
};
|
|
5587
|
-
const removeExternalFilter = (filter) => {
|
|
5590
|
+
}, [onFilterChanged]);
|
|
5591
|
+
const removeExternalFilter = React.useCallback((filter) => {
|
|
5588
5592
|
lodashEs.remove(externalFilters.current, (v) => v === filter);
|
|
5589
5593
|
void onFilterChanged();
|
|
5590
|
-
};
|
|
5591
|
-
const isExternalFilterPresent = () => !lodashEs.isEmpty(externalFilters.current);
|
|
5592
|
-
const doesExternalFilterPass = (node) => externalFilters.current.every((filter) => filter(node.data, node));
|
|
5594
|
+
}, [onFilterChanged]);
|
|
5595
|
+
const isExternalFilterPresent = React.useCallback(() => !lodashEs.isEmpty(externalFilters.current), []);
|
|
5596
|
+
const doesExternalFilterPass = React.useCallback((node) => externalFilters.current.every((filter) => filter(node.data, node)), []);
|
|
5593
5597
|
const getColDef = React.useCallback((colId) => (!!colId && gridApi?.getColumnDef(colId)) || undefined, [gridApi]);
|
|
5594
5598
|
const showNoRowsOverlay = React.useCallback(() => {
|
|
5595
5599
|
gridApi?.showNoRowsOverlay();
|
|
@@ -5645,7 +5649,6 @@ const GridContextProvider = (props) => {
|
|
|
5645
5649
|
setInvisibleColumnIds,
|
|
5646
5650
|
gridReady,
|
|
5647
5651
|
prePopupOps,
|
|
5648
|
-
postPopupOps,
|
|
5649
5652
|
setApis,
|
|
5650
5653
|
setQuickFilter,
|
|
5651
5654
|
selectRowsById,
|
|
@@ -5666,8 +5669,7 @@ const GridContextProvider = (props) => {
|
|
|
5666
5669
|
sizeColumnsToFit,
|
|
5667
5670
|
autoSizeColumns,
|
|
5668
5671
|
startCellEditing,
|
|
5669
|
-
|
|
5670
|
-
cancelEdit,
|
|
5672
|
+
resetFocusedCellAfterCellEditing,
|
|
5671
5673
|
updatingCells,
|
|
5672
5674
|
redrawRows,
|
|
5673
5675
|
externallySelectedItemsAreInSync,
|
|
@@ -5678,7 +5680,8 @@ const GridContextProvider = (props) => {
|
|
|
5678
5680
|
isExternalFilterPresent,
|
|
5679
5681
|
doesExternalFilterPass,
|
|
5680
5682
|
downloadCsv,
|
|
5681
|
-
|
|
5683
|
+
onBulkEditingComplete,
|
|
5684
|
+
setOnBulkEditingComplete,
|
|
5682
5685
|
showNoRowsOverlay,
|
|
5683
5686
|
}, children: props.children }));
|
|
5684
5687
|
};
|
|
@@ -5725,12 +5728,23 @@ const downloadCsvUseValueFormattersProcessCellCallback = (params) => {
|
|
|
5725
5728
|
// We add an extra encodeToString here just in case valueFormatter is returning non string values
|
|
5726
5729
|
return encodeToString(result);
|
|
5727
5730
|
};
|
|
5731
|
+
const waitForCondition = async (condition, timeoutMs) => {
|
|
5732
|
+
const endTime = Date.now() + timeoutMs;
|
|
5733
|
+
while (Date.now() < endTime) {
|
|
5734
|
+
if (condition()) {
|
|
5735
|
+
return true;
|
|
5736
|
+
}
|
|
5737
|
+
await wait(100);
|
|
5738
|
+
}
|
|
5739
|
+
console.warn('waitForCondition failed');
|
|
5740
|
+
return false;
|
|
5741
|
+
};
|
|
5728
5742
|
|
|
5729
5743
|
const GridUpdatingContextProvider = (props) => {
|
|
5730
5744
|
const updatingBlocks = React.useRef({});
|
|
5731
5745
|
const updating = React.useRef({});
|
|
5732
5746
|
const [updatedDep, setUpdatedDep] = React.useState(0);
|
|
5733
|
-
const resetUpdating = () => {
|
|
5747
|
+
const resetUpdating = React.useCallback(() => {
|
|
5734
5748
|
const mergedUpdatingBlocks = {};
|
|
5735
5749
|
for (const key in updatingBlocks.current) {
|
|
5736
5750
|
const arr = lodashEs.flatten(updatingBlocks.current[key]);
|
|
@@ -5740,9 +5754,9 @@ const GridUpdatingContextProvider = (props) => {
|
|
|
5740
5754
|
}
|
|
5741
5755
|
updating.current = mergedUpdatingBlocks;
|
|
5742
5756
|
setUpdatedDep((updatedDep) => updatedDep + 1);
|
|
5743
|
-
};
|
|
5744
|
-
const updatingCols = () => Object.keys(updating.current);
|
|
5745
|
-
const modifyUpdating = async (fields, ids, fn) => {
|
|
5757
|
+
}, []);
|
|
5758
|
+
const updatingCols = React.useCallback(() => Object.keys(updating.current), []);
|
|
5759
|
+
const modifyUpdating = React.useCallback(async (fields, ids, fn) => {
|
|
5746
5760
|
const idRef = [...ids];
|
|
5747
5761
|
lodashEs.castArray(fields).forEach((field) => {
|
|
5748
5762
|
const fieldUpdatingIds = updatingBlocks.current[field] ?? (updatingBlocks.current[field] = []);
|
|
@@ -5755,9 +5769,12 @@ const GridUpdatingContextProvider = (props) => {
|
|
|
5755
5769
|
lodashEs.remove(fieldUpdatingIds, (idList) => idList === idRef);
|
|
5756
5770
|
});
|
|
5757
5771
|
resetUpdating();
|
|
5758
|
-
};
|
|
5759
|
-
const
|
|
5760
|
-
|
|
5772
|
+
}, [resetUpdating]);
|
|
5773
|
+
const anyUpdating = React.useCallback(() => {
|
|
5774
|
+
return !lodashEs.isEmpty(updating.current);
|
|
5775
|
+
}, []);
|
|
5776
|
+
const checkUpdating = React.useCallback((fields, id) => lodashEs.castArray(fields).some((f) => updating.current[f]?.includes(id)), []);
|
|
5777
|
+
return (jsxRuntime.jsx(GridUpdatingContext.Provider, { value: { modifyUpdating, anyUpdating, checkUpdating, updatingCols, updatedDep }, children: props.children }));
|
|
5761
5778
|
};
|
|
5762
5779
|
|
|
5763
5780
|
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%}";
|