@linzjs/step-ag-grid 7.11.8 → 7.11.9
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.js +101 -155
- package/dist/index.js.map +1 -1
- package/dist/step-ag-grid.esm.js +102 -156
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/gridForm/GridFormDropDown.tsx +100 -118
- package/src/contexts/GridContextProvider.tsx +239 -196
- package/src/react-menu3/components/ControlledMenu.tsx +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReactElement, ReactNode, useContext, useRef, useState } from "react";
|
|
1
|
+
import { ReactElement, ReactNode, useCallback, useContext, useRef, useState } from "react";
|
|
2
2
|
import { ColDef, GridApi, RowNode } from "ag-grid-community";
|
|
3
3
|
import { GridContext } from "./GridContext";
|
|
4
4
|
import { defer, delay, difference, isEmpty, last, sortBy } from "lodash-es";
|
|
@@ -22,10 +22,10 @@ export const GridContextProvider = (props: GridContextProps): ReactElement => {
|
|
|
22
22
|
const idsBeforeUpdate = useRef<number[]>([]);
|
|
23
23
|
const externallySelectedItemsAreInSync = useRef(false);
|
|
24
24
|
|
|
25
|
-
const setGridApi = (gridApi: GridApi | undefined) => {
|
|
25
|
+
const setGridApi = useCallback((gridApi: GridApi | undefined) => {
|
|
26
26
|
_setGridApi(gridApi);
|
|
27
27
|
setGridReady(!!gridApi);
|
|
28
|
-
};
|
|
28
|
+
}, []);
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Wraps things that require gridApi in common handling, for when gridApi not present.
|
|
@@ -33,27 +33,30 @@ export const GridContextProvider = (props: GridContextProps): ReactElement => {
|
|
|
33
33
|
* @param hasApiFn Execute when api is ready.
|
|
34
34
|
* @param noApiFn Execute if api is not ready.
|
|
35
35
|
*/
|
|
36
|
-
const gridApiOp =
|
|
37
|
-
hasApiFn: (gridApi: GridApi) => T,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
const gridApiOp = useCallback(
|
|
37
|
+
<T extends unknown, R extends unknown>(hasApiFn: (gridApi: GridApi) => T, noApiFn?: () => R): T | R => {
|
|
38
|
+
if (!noApiFn) {
|
|
39
|
+
noApiFn = (() => {}) as () => R;
|
|
40
|
+
}
|
|
41
|
+
return gridApi ? hasApiFn(gridApi) : noApiFn();
|
|
42
|
+
},
|
|
43
|
+
[gridApi],
|
|
44
|
+
);
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
47
|
* Set the quick filter value to grid.
|
|
48
48
|
*/
|
|
49
|
-
const setQuickFilter = (
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
const setQuickFilter = useCallback(
|
|
50
|
+
(quickFilter: string) => {
|
|
51
|
+
gridApiOp((gridApi) => gridApi.setQuickFilter(quickFilter));
|
|
52
|
+
},
|
|
53
|
+
[gridApiOp],
|
|
54
|
+
);
|
|
52
55
|
|
|
53
56
|
/**
|
|
54
57
|
* Get all row id's in grid.
|
|
55
58
|
*/
|
|
56
|
-
const _getAllRowIds = () => {
|
|
59
|
+
const _getAllRowIds = useCallback(() => {
|
|
57
60
|
const result: number[] = [];
|
|
58
61
|
return gridApiOp(
|
|
59
62
|
(gridApi) => {
|
|
@@ -62,20 +65,20 @@ export const GridContextProvider = (props: GridContextProps): ReactElement => {
|
|
|
62
65
|
},
|
|
63
66
|
() => result,
|
|
64
67
|
);
|
|
65
|
-
};
|
|
68
|
+
}, [gridApiOp]);
|
|
66
69
|
|
|
67
70
|
/**
|
|
68
71
|
* Record all row id's before update so that we can select/flash the new rows after update.
|
|
69
72
|
*/
|
|
70
|
-
const beforeUpdate = () => {
|
|
73
|
+
const beforeUpdate = useCallback(() => {
|
|
71
74
|
idsBeforeUpdate.current = _getAllRowIds();
|
|
72
|
-
};
|
|
75
|
+
}, [_getAllRowIds]);
|
|
73
76
|
|
|
74
77
|
/**
|
|
75
78
|
* Find new row ids
|
|
76
79
|
* Uses beforeUpdate ids to find new nodes.
|
|
77
80
|
*/
|
|
78
|
-
const _getNewNodes = (): RowNode[] => {
|
|
81
|
+
const _getNewNodes = useCallback((): RowNode[] => {
|
|
79
82
|
return gridApiOp(
|
|
80
83
|
(gridApi) =>
|
|
81
84
|
difference(_getAllRowIds(), idsBeforeUpdate.current)
|
|
@@ -83,7 +86,7 @@ export const GridContextProvider = (props: GridContextProps): ReactElement => {
|
|
|
83
86
|
.filter((r) => r) as RowNode[],
|
|
84
87
|
() => [],
|
|
85
88
|
);
|
|
86
|
-
};
|
|
89
|
+
}, [_getAllRowIds, gridApiOp]);
|
|
87
90
|
|
|
88
91
|
/**
|
|
89
92
|
* Get grid nodes via rowIds. If rowIds has no matching node the result may be smaller than expected.
|
|
@@ -91,15 +94,18 @@ export const GridContextProvider = (props: GridContextProps): ReactElement => {
|
|
|
91
94
|
*
|
|
92
95
|
* @param rowIds Row ids to get from grid.
|
|
93
96
|
*/
|
|
94
|
-
const _rowIdsToNodes = (
|
|
95
|
-
|
|
96
|
-
(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
97
|
+
const _rowIdsToNodes = useCallback(
|
|
98
|
+
(rowIds: number[]): RowNode[] => {
|
|
99
|
+
return gridApiOp(
|
|
100
|
+
(gridApi) =>
|
|
101
|
+
rowIds
|
|
102
|
+
.map((rowId) => gridApi.getRowNode("" + rowId)) //
|
|
103
|
+
.filter((r) => r) as RowNode[],
|
|
104
|
+
() => [] as RowNode[],
|
|
105
|
+
);
|
|
106
|
+
},
|
|
107
|
+
[gridApiOp],
|
|
108
|
+
);
|
|
103
109
|
|
|
104
110
|
/**
|
|
105
111
|
* Internal method for selecting and flashing rows.
|
|
@@ -109,214 +115,251 @@ export const GridContextProvider = (props: GridContextProps): ReactElement => {
|
|
|
109
115
|
* @param flash Whether to flash rows
|
|
110
116
|
* @param retryCount Table updates may not be present when this is called, so retry is needed.
|
|
111
117
|
*/
|
|
112
|
-
const _selectRowsWithOptionalFlash = (
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
118
|
+
const _selectRowsWithOptionalFlash = useCallback(
|
|
119
|
+
(
|
|
120
|
+
rowIds: number[] | undefined,
|
|
121
|
+
select: boolean,
|
|
122
|
+
flash: boolean,
|
|
123
|
+
retryCount = 15, // We retry for approximately 5x200ms=1s
|
|
124
|
+
) => {
|
|
125
|
+
return gridApiOp((gridApi) => {
|
|
126
|
+
const rowNodes = rowIds ? _rowIdsToNodes(rowIds) : _getNewNodes();
|
|
127
|
+
const gridRowIdsNotUpdatedYet = rowIds && rowNodes.length !== rowIds.length; // rowIds are specified
|
|
128
|
+
const gridRowIdsNotChangedYet = !rowIds && isEmpty(rowNodes); // rowIds are from beforeUpdate
|
|
129
|
+
const gridHasNotUpdated = gridRowIdsNotUpdatedYet || gridRowIdsNotChangedYet;
|
|
130
|
+
// After retry count expires we give-up and deselect all rows, then select any subset of rows that have updated
|
|
131
|
+
if (gridHasNotUpdated && retryCount > 0) {
|
|
132
|
+
delay(() => _selectRowsWithOptionalFlash(rowIds, select, flash, retryCount - 1), 250);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
128
135
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
136
|
+
const rowsThatNeedSelecting = sortBy(
|
|
137
|
+
rowNodes.filter((node) => !node.isSelected()),
|
|
138
|
+
(node) => node.data.id,
|
|
139
|
+
);
|
|
140
|
+
const firstNode = rowsThatNeedSelecting[0];
|
|
141
|
+
if (firstNode) {
|
|
142
|
+
gridApi.ensureNodeVisible(firstNode);
|
|
143
|
+
const colDefs = gridApi.getColumnDefs();
|
|
144
|
+
if (colDefs && colDefs.length) {
|
|
145
|
+
const col = colDefs[0] as ColDef; // We don't support ColGroupDef
|
|
146
|
+
const rowIndex = firstNode.rowIndex;
|
|
147
|
+
if (rowIndex != null && col != null) {
|
|
148
|
+
const colId = col.colId;
|
|
149
|
+
// We need to make sure we aren't currently editing a cell otherwise tests will fail
|
|
150
|
+
// as they will start to edit the cell before this stuff has a chance to run
|
|
151
|
+
colId != null &&
|
|
152
|
+
defer(() => isEmpty(gridApi.getEditingCells()) && gridApi.setFocusedCell(rowIndex, colId));
|
|
153
|
+
}
|
|
145
154
|
}
|
|
146
155
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
_selectRowsWithOptionalFlash
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
156
|
+
if (select) {
|
|
157
|
+
// Select rows that shouldn't be selected
|
|
158
|
+
rowsThatNeedSelecting.forEach((node) => node.setSelected(true));
|
|
159
|
+
// Unselect rows that shouldn't be selected
|
|
160
|
+
gridApi.getSelectedNodes()?.forEach((node) => {
|
|
161
|
+
if (node && !rowNodes.includes(node)) {
|
|
162
|
+
node.setSelected(false);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
if (flash) {
|
|
167
|
+
delay(() => {
|
|
168
|
+
try {
|
|
169
|
+
gridApi.flashCells({ rowNodes });
|
|
170
|
+
} catch {
|
|
171
|
+
// ignore, flash cells sometimes throws errors as nodes have gone out of scope
|
|
172
|
+
}
|
|
173
|
+
}, 250);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
},
|
|
177
|
+
[_getNewNodes, _rowIdsToNodes, gridApiOp],
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
const selectRowsById = useCallback(
|
|
181
|
+
(rowIds?: number[]) => _selectRowsWithOptionalFlash(rowIds, true, false),
|
|
182
|
+
[_selectRowsWithOptionalFlash],
|
|
183
|
+
);
|
|
184
|
+
const selectRowsByIdWithFlash = useCallback(
|
|
185
|
+
(rowIds?: number[]) => _selectRowsWithOptionalFlash(rowIds, true, true),
|
|
186
|
+
[_selectRowsWithOptionalFlash],
|
|
187
|
+
);
|
|
188
|
+
const flashRows = useCallback(
|
|
189
|
+
(rowIds?: number[]) => _selectRowsWithOptionalFlash(rowIds, false, true),
|
|
190
|
+
[_selectRowsWithOptionalFlash],
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
const selectRowsDiff = useCallback(
|
|
194
|
+
async (fn: () => Promise<any>) => {
|
|
195
|
+
beforeUpdate();
|
|
196
|
+
await fn();
|
|
197
|
+
_selectRowsWithOptionalFlash(undefined, true, false);
|
|
198
|
+
},
|
|
199
|
+
[_selectRowsWithOptionalFlash, beforeUpdate],
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
const selectRowsWithFlashDiff = useCallback(
|
|
203
|
+
async (fn: () => Promise<any>) => {
|
|
204
|
+
beforeUpdate();
|
|
205
|
+
await fn();
|
|
206
|
+
_selectRowsWithOptionalFlash(undefined, true, true);
|
|
207
|
+
},
|
|
208
|
+
[_selectRowsWithOptionalFlash, beforeUpdate],
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
const flashRowsDiff = useCallback(
|
|
212
|
+
async (fn: () => Promise<any>) => {
|
|
213
|
+
beforeUpdate();
|
|
214
|
+
await fn();
|
|
215
|
+
_selectRowsWithOptionalFlash(undefined, false, true);
|
|
216
|
+
},
|
|
217
|
+
[_selectRowsWithOptionalFlash, beforeUpdate],
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
const getSelectedRows = useCallback(<T extends unknown>(): T[] => {
|
|
193
221
|
return gridApiOp(
|
|
194
222
|
(gridApi) => gridApi.getSelectedRows(),
|
|
195
223
|
() => [],
|
|
196
224
|
);
|
|
197
|
-
};
|
|
225
|
+
}, [gridApiOp]);
|
|
198
226
|
|
|
199
|
-
const getSelectedRowIds = (
|
|
227
|
+
const getSelectedRowIds = useCallback(
|
|
228
|
+
(): number[] => getSelectedRows().map((row) => (row as any).id as number),
|
|
229
|
+
[getSelectedRows],
|
|
230
|
+
);
|
|
200
231
|
|
|
201
|
-
const editingCells = (): boolean => {
|
|
232
|
+
const editingCells = useCallback((): boolean => {
|
|
202
233
|
return gridApiOp(
|
|
203
234
|
(gridApi) => isNotEmpty(gridApi.getEditingCells()),
|
|
204
235
|
() => false,
|
|
205
236
|
);
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
const ensureRowVisible = (
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
237
|
+
}, [gridApiOp]);
|
|
238
|
+
|
|
239
|
+
const ensureRowVisible = useCallback(
|
|
240
|
+
(id: number | string): boolean => {
|
|
241
|
+
return gridApiOp((gridApi) => {
|
|
242
|
+
const node = gridApi.getRowNode(`${id}`);
|
|
243
|
+
if (!node) return false;
|
|
244
|
+
gridApi.ensureNodeVisible(node);
|
|
245
|
+
return true;
|
|
246
|
+
});
|
|
247
|
+
},
|
|
248
|
+
[gridApiOp],
|
|
249
|
+
);
|
|
216
250
|
|
|
217
251
|
/**
|
|
218
252
|
* Scroll last selected row into view on grid sort change
|
|
219
253
|
*/
|
|
220
|
-
const ensureSelectedRowIsVisible = (): void => {
|
|
254
|
+
const ensureSelectedRowIsVisible = useCallback((): void => {
|
|
221
255
|
gridApiOp((gridApi) => {
|
|
222
256
|
const selectedNodes = gridApi.getSelectedNodes();
|
|
223
257
|
if (isEmpty(selectedNodes)) return;
|
|
224
258
|
gridApi.ensureNodeVisible(last(selectedNodes));
|
|
225
259
|
});
|
|
226
|
-
};
|
|
260
|
+
}, [gridApiOp]);
|
|
227
261
|
|
|
228
262
|
/**
|
|
229
263
|
* Resize columns to fit container
|
|
230
264
|
*/
|
|
231
|
-
const sizeColumnsToFit = (): void => {
|
|
265
|
+
const sizeColumnsToFit = useCallback((): void => {
|
|
232
266
|
gridApiOp((gridApi) => {
|
|
233
267
|
// Hide size columns to fit errors in tests
|
|
234
268
|
document.body.clientWidth && gridApi.sizeColumnsToFit();
|
|
235
269
|
});
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
const stopEditing = (): void => gridApiOp((gridApi) => gridApi.stopEditing());
|
|
239
|
-
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
const selectedRows = props.selectedRows;
|
|
251
|
-
|
|
252
|
-
let ok = false;
|
|
253
|
-
await modifyUpdating(
|
|
254
|
-
props.field ?? "",
|
|
255
|
-
selectedRows.map((data) => data.id),
|
|
256
|
-
async () => {
|
|
257
|
-
// Need to refresh to get spinners to work on all rows
|
|
258
|
-
gridApi.refreshCells({ rowNodes: props.selectedRows as RowNode[], force: true });
|
|
259
|
-
ok = await fnUpdate(selectedRows).catch((ex) => {
|
|
260
|
-
console.error("Exception during modifyUpdating", ex);
|
|
261
|
-
return false;
|
|
262
|
-
});
|
|
263
|
-
},
|
|
264
|
-
);
|
|
265
|
-
|
|
266
|
-
// async processes need to refresh their own rows
|
|
267
|
-
gridApi.refreshCells({ rowNodes: selectedRows as RowNode[], force: true });
|
|
270
|
+
}, [gridApiOp]);
|
|
271
|
+
|
|
272
|
+
const stopEditing = useCallback((): void => gridApiOp((gridApi) => gridApi.stopEditing()), [gridApiOp]);
|
|
273
|
+
|
|
274
|
+
const selectNextCell = useCallback(
|
|
275
|
+
(tabDirection: -1 | 0 | 1 = 0) => {
|
|
276
|
+
gridApiOp((gridApi) => {
|
|
277
|
+
if (tabDirection == 1) gridApi.tabToNextCell();
|
|
278
|
+
if (tabDirection == -1) gridApi.tabToPreviousCell();
|
|
279
|
+
});
|
|
280
|
+
},
|
|
281
|
+
[gridApiOp],
|
|
282
|
+
);
|
|
268
283
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
284
|
+
const updatingCells = useCallback(
|
|
285
|
+
async (
|
|
286
|
+
props: { selectedRows: GridBaseRow[]; field?: string },
|
|
287
|
+
fnUpdate: (selectedRows: any[]) => Promise<boolean>,
|
|
288
|
+
setSaving?: (saving: boolean) => void,
|
|
289
|
+
tabDirection?: 1 | 0 | -1,
|
|
290
|
+
): Promise<boolean> => {
|
|
291
|
+
setSaving && setSaving(true);
|
|
292
|
+
return await gridApiOp(async (gridApi) => {
|
|
293
|
+
const preOpCell = gridApi.getFocusedCell();
|
|
294
|
+
|
|
295
|
+
const selectedRows = props.selectedRows;
|
|
296
|
+
|
|
297
|
+
let ok = false;
|
|
298
|
+
await modifyUpdating(
|
|
299
|
+
props.field ?? "",
|
|
300
|
+
selectedRows.map((data) => data.id),
|
|
301
|
+
async () => {
|
|
302
|
+
// Need to refresh to get spinners to work on all rows
|
|
303
|
+
gridApi.refreshCells({ rowNodes: props.selectedRows as RowNode[], force: true });
|
|
304
|
+
ok = await fnUpdate(selectedRows).catch((ex) => {
|
|
305
|
+
console.error("Exception during modifyUpdating", ex);
|
|
306
|
+
return false;
|
|
307
|
+
});
|
|
308
|
+
},
|
|
309
|
+
);
|
|
310
|
+
|
|
311
|
+
// async processes need to refresh their own rows
|
|
312
|
+
gridApi.refreshCells({ rowNodes: selectedRows as RowNode[], force: true });
|
|
313
|
+
|
|
314
|
+
if (ok) {
|
|
315
|
+
const cell = gridApi.getFocusedCell();
|
|
316
|
+
if (cell && gridApi.getFocusedCell() == null) {
|
|
317
|
+
gridApi.setFocusedCell(cell.rowIndex, cell.column);
|
|
318
|
+
}
|
|
319
|
+
// This is needed to trigger postSortRowsHook
|
|
320
|
+
gridApi.refreshClientSideRowModel();
|
|
321
|
+
} else {
|
|
322
|
+
// Don't set saving if ok as the form has already closed
|
|
323
|
+
setSaving && setSaving(false);
|
|
273
324
|
}
|
|
274
|
-
// This is needed to trigger postSortRowsHook
|
|
275
|
-
gridApi.refreshClientSideRowModel();
|
|
276
|
-
} else {
|
|
277
|
-
// Don't set saving if ok as the form has already closed
|
|
278
|
-
setSaving && setSaving(false);
|
|
279
|
-
}
|
|
280
325
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
return ok;
|
|
294
|
-
});
|
|
295
|
-
};
|
|
326
|
+
// Only focus next cell if user hasn't already manually changed focus
|
|
327
|
+
const postOpCell = gridApi.getFocusedCell();
|
|
328
|
+
if (
|
|
329
|
+
tabDirection &&
|
|
330
|
+
preOpCell &&
|
|
331
|
+
postOpCell &&
|
|
332
|
+
preOpCell.rowIndex == postOpCell.rowIndex &&
|
|
333
|
+
preOpCell.column.getColId() == postOpCell.column.getColId()
|
|
334
|
+
) {
|
|
335
|
+
selectNextCell(tabDirection);
|
|
336
|
+
}
|
|
296
337
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
338
|
+
return ok;
|
|
339
|
+
});
|
|
340
|
+
},
|
|
341
|
+
[gridApiOp, modifyUpdating, selectNextCell],
|
|
342
|
+
);
|
|
302
343
|
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
344
|
+
const redrawRows = useCallback(
|
|
345
|
+
(rowNodes?: RowNode[]) => {
|
|
346
|
+
gridApiOp((gridApi) => {
|
|
347
|
+
gridApi.redrawRows(rowNodes ? { rowNodes } : undefined);
|
|
348
|
+
});
|
|
349
|
+
},
|
|
350
|
+
[gridApiOp],
|
|
351
|
+
);
|
|
309
352
|
|
|
310
|
-
const setExternallySelectedItemsAreInSync = (inSync: boolean) => {
|
|
353
|
+
const setExternallySelectedItemsAreInSync = useCallback((inSync: boolean) => {
|
|
311
354
|
externallySelectedItemsAreInSync.current = inSync;
|
|
312
|
-
};
|
|
355
|
+
}, []);
|
|
313
356
|
|
|
314
|
-
const waitForExternallySelectedItemsToBeInSync = async () => {
|
|
357
|
+
const waitForExternallySelectedItemsToBeInSync = useCallback(async () => {
|
|
315
358
|
// Wait for up to 5 seconds
|
|
316
359
|
for (let i = 0; i < 5000 / 200 && !externallySelectedItemsAreInSync.current; i++) {
|
|
317
360
|
await wait(200);
|
|
318
361
|
}
|
|
319
|
-
};
|
|
362
|
+
}, []);
|
|
320
363
|
|
|
321
364
|
return (
|
|
322
365
|
<GridContext.Provider
|
|
@@ -137,8 +137,8 @@ export const ControlledMenuFr = (
|
|
|
137
137
|
if (activeElement !== firstInputEl && activeElement !== lastInputEl) return;
|
|
138
138
|
|
|
139
139
|
const isTextArea = activeElement.nodeName === "TEXTAREA";
|
|
140
|
-
const suppressEnterAutoSave = activeElement.getAttribute("data-disableenterautosave") || isTextArea;
|
|
141
|
-
const allowTabToSave = activeElement.getAttribute("data-allowtabtosave");
|
|
140
|
+
const suppressEnterAutoSave = activeElement.getAttribute("data-disableenterautosave") != "false" || isTextArea;
|
|
141
|
+
const allowTabToSave = activeElement.getAttribute("data-allowtabtosave") != "false";
|
|
142
142
|
const invokeSave = (reason: string) => {
|
|
143
143
|
if (!saveButtonRef?.current) return;
|
|
144
144
|
saveButtonRef.current?.setAttribute("data-reason", reason);
|