@linzjs/step-ag-grid 14.1.1 → 14.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/dist/src/components/Grid.d.ts +5 -0
- package/dist/src/components/GridCell.d.ts +1 -0
- package/dist/src/contexts/GridContext.d.ts +11 -5
- package/dist/src/contexts/GridUpdatingContext.d.ts +1 -0
- package/dist/step-ag-grid.esm.js +300 -90
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Grid.tsx +185 -27
- package/src/components/GridCell.tsx +6 -2
- package/src/components/GridPopoverHook.tsx +4 -4
- package/src/components/gridForm/GridFormDropDown.tsx +1 -8
- package/src/components/gridPopoverEdit/GridPopoverMenu.tsx +1 -0
- package/src/contexts/GridContext.tsx +19 -3
- package/src/contexts/GridContextProvider.tsx +106 -36
- package/src/contexts/GridUpdatingContext.tsx +5 -0
- package/src/contexts/GridUpdatingContextProvider.tsx +8 -3
- package/src/react-menu3/components/MenuList.tsx +21 -1
- package/src/stories/grid/GridPopoutEditGenericTextArea.stories.tsx +7 -1
- package/src/stories/grid/GridPopoverEditDropDown.stories.tsx +5 -0
- package/src/stories/grid/interactions/GridKeyboardInteractions.stories.tsx +3 -1
package/package.json
CHANGED
package/src/components/Grid.tsx
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import { CellClickedEvent, ColDef, ModelUpdatedEvent } from "ag-grid-community";
|
|
1
|
+
import { CellClickedEvent, ColDef, ColumnResizedEvent, ModelUpdatedEvent } from "ag-grid-community";
|
|
2
2
|
import { CellClassParams, EditableCallback, EditableCallbackParams } from "ag-grid-community/dist/lib/entities/colDef";
|
|
3
3
|
import { GridOptions } from "ag-grid-community/dist/lib/entities/gridOptions";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
CellEditingStoppedEvent,
|
|
6
|
+
CellEvent,
|
|
7
|
+
GridReadyEvent,
|
|
8
|
+
SelectionChangedEvent,
|
|
9
|
+
} from "ag-grid-community/dist/lib/events";
|
|
5
10
|
import { AgGridReact } from "ag-grid-react";
|
|
6
11
|
import clsx from "clsx";
|
|
7
|
-
import { difference, isEmpty, last, xorBy } from "lodash-es";
|
|
12
|
+
import { difference, isEmpty, last, omit, xorBy } from "lodash-es";
|
|
8
13
|
import { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
9
14
|
|
|
10
15
|
import { GridContext } from "../contexts/GridContext";
|
|
@@ -56,6 +61,11 @@ export interface GridProps {
|
|
|
56
61
|
* If you want to stretch to container width if width is greater than the container add a flex column.
|
|
57
62
|
*/
|
|
58
63
|
sizeColumns?: "fit" | "auto" | "auto-skip-headers" | "none";
|
|
64
|
+
/**
|
|
65
|
+
* When pressing tab whilst editing the grid will select and edit the next cell if available.
|
|
66
|
+
* Once the last cell to edit closes this callback is called.
|
|
67
|
+
*/
|
|
68
|
+
onCellEditingComplete?: () => void;
|
|
59
69
|
}
|
|
60
70
|
|
|
61
71
|
/**
|
|
@@ -78,34 +88,59 @@ export const Grid = ({
|
|
|
78
88
|
selectRowsById,
|
|
79
89
|
focusByRowById,
|
|
80
90
|
ensureSelectedRowIsVisible,
|
|
81
|
-
|
|
91
|
+
autoSizeColumns,
|
|
82
92
|
sizeColumnsToFit,
|
|
83
93
|
externallySelectedItemsAreInSync,
|
|
84
94
|
setExternallySelectedItemsAreInSync,
|
|
85
95
|
isExternalFilterPresent,
|
|
86
96
|
doesExternalFilterPass,
|
|
97
|
+
setOnCellEditingComplete,
|
|
87
98
|
} = useContext(GridContext);
|
|
88
|
-
const { checkUpdating } = useContext(GridUpdatingContext);
|
|
99
|
+
const { checkUpdating, updatedDep, isUpdating } = useContext(GridUpdatingContext);
|
|
89
100
|
|
|
90
101
|
const lastSelectedIds = useRef<number[]>([]);
|
|
91
102
|
const [staleGrid, setStaleGrid] = useState(false);
|
|
92
103
|
const postSortRows = usePostSortRowsHook({ setStaleGrid });
|
|
93
104
|
|
|
105
|
+
/**
|
|
106
|
+
* onContentSize should only be called at maximum twice.
|
|
107
|
+
* Once when an empty grid is loaded.
|
|
108
|
+
* And again when the grid has content.
|
|
109
|
+
*/
|
|
110
|
+
const hasSetContentSize = useRef(false);
|
|
111
|
+
const hasSetContentSizeEmpty = useRef(false);
|
|
112
|
+
|
|
94
113
|
const setInitialContentSize = useCallback(() => {
|
|
95
|
-
const
|
|
96
|
-
if (sizeColumns === "auto" ||
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
114
|
+
const skipHeader = sizeColumns === "auto-skip-headers";
|
|
115
|
+
if (sizeColumns === "auto" || skipHeader) {
|
|
116
|
+
const result = autoSizeColumns({ skipHeader, userSizedColIds: userSizedColIds.current });
|
|
117
|
+
if (isEmpty(params.rowData)) {
|
|
118
|
+
if (!hasSetContentSizeEmpty.current && !hasSetContentSize.current) {
|
|
119
|
+
hasSetContentSizeEmpty.current = true;
|
|
120
|
+
params.onContentSize && result && params.onContentSize(result);
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
if (!hasSetContentSize.current) {
|
|
124
|
+
hasSetContentSize.current = true;
|
|
125
|
+
params.onContentSize && result && params.onContentSize(result);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
100
128
|
}
|
|
101
129
|
|
|
102
130
|
if (sizeColumns !== "none") {
|
|
103
131
|
sizeColumnsToFit();
|
|
104
132
|
}
|
|
105
|
-
}, [
|
|
133
|
+
}, [autoSizeColumns, params, sizeColumns, sizeColumnsToFit]);
|
|
106
134
|
|
|
135
|
+
/**
|
|
136
|
+
* When the grid becomes ready resize it
|
|
137
|
+
*/
|
|
138
|
+
const previousGridReady = useRef(gridReady);
|
|
107
139
|
useEffect(() => {
|
|
108
|
-
|
|
140
|
+
if (!previousGridReady.current && gridReady) {
|
|
141
|
+
previousGridReady.current = true;
|
|
142
|
+
setInitialContentSize();
|
|
143
|
+
}
|
|
109
144
|
}, [gridReady, setInitialContentSize]);
|
|
110
145
|
|
|
111
146
|
/**
|
|
@@ -182,12 +217,17 @@ export const Grid = ({
|
|
|
182
217
|
|
|
183
218
|
const selectedIds = params.externalSelectedItems.map((row) => row.id) as number[];
|
|
184
219
|
const lastNewId = last(difference(selectedIds, lastSelectedIds.current));
|
|
185
|
-
if (lastNewId != null)
|
|
220
|
+
if (lastNewId != null) {
|
|
221
|
+
ensureRowVisible(lastNewId);
|
|
222
|
+
}
|
|
186
223
|
lastSelectedIds.current = selectedIds;
|
|
187
224
|
selectRowsById(selectedIds);
|
|
188
225
|
setExternallySelectedItemsAreInSync(true);
|
|
189
226
|
}, [gridReady, params.externalSelectedItems, ensureRowVisible, selectRowsById, setExternallySelectedItemsAreInSync]);
|
|
190
227
|
|
|
228
|
+
/**
|
|
229
|
+
* Combine grid and cell editable into one function
|
|
230
|
+
*/
|
|
191
231
|
const combineEditables =
|
|
192
232
|
(...editables: (boolean | EditableCallback | undefined)[]) =>
|
|
193
233
|
(params: EditableCallbackParams): boolean => {
|
|
@@ -201,10 +241,11 @@ export const Grid = ({
|
|
|
201
241
|
/**
|
|
202
242
|
* Synchronise externally selected items to grid on externalSelectedItems change
|
|
203
243
|
*/
|
|
204
|
-
useEffect(
|
|
205
|
-
synchroniseExternallySelectedItemsToGrid();
|
|
206
|
-
}, [synchroniseExternallySelectedItemsToGrid]);
|
|
244
|
+
useEffect(synchroniseExternallySelectedItemsToGrid, [synchroniseExternallySelectedItemsToGrid]);
|
|
207
245
|
|
|
246
|
+
/**
|
|
247
|
+
* Add selectable column to colDefs. Adjust column defs to block fit for auto sized columns.
|
|
248
|
+
*/
|
|
208
249
|
const columnDefs = useMemo((): ColDef[] => {
|
|
209
250
|
const adjustColDefs = params.columnDefs.map((colDef) => {
|
|
210
251
|
const colDefEditable = colDef.editable;
|
|
@@ -255,6 +296,9 @@ export const Grid = ({
|
|
|
255
296
|
clickSelectorCheckboxWhenContainingCellClicked,
|
|
256
297
|
]);
|
|
257
298
|
|
|
299
|
+
/**
|
|
300
|
+
* When grid is ready set the apis to the grid context and sync selected items to grid.
|
|
301
|
+
*/
|
|
258
302
|
const onGridReady = useCallback(
|
|
259
303
|
(event: GridReadyEvent) => {
|
|
260
304
|
setApis(event.api, event.columnApi, dataTestId);
|
|
@@ -268,28 +312,56 @@ export const Grid = ({
|
|
|
268
312
|
* This will resize columns when we have at least one row.
|
|
269
313
|
*/
|
|
270
314
|
const previousRowDataLength = useRef(0);
|
|
271
|
-
|
|
315
|
+
|
|
316
|
+
const onRowDataChanged = useCallback(() => {
|
|
272
317
|
const length = params.rowData?.length ?? 0;
|
|
273
318
|
if (previousRowDataLength.current !== length) {
|
|
274
|
-
|
|
275
|
-
setInitialContentSize();
|
|
276
|
-
}
|
|
319
|
+
setInitialContentSize();
|
|
277
320
|
previousRowDataLength.current = length;
|
|
278
321
|
}
|
|
279
|
-
}, [params.rowData?.length, setInitialContentSize]);
|
|
280
322
|
|
|
323
|
+
if (lastUpdatedDep.current === updatedDep || isEmpty(colIdsEdited.current)) return;
|
|
324
|
+
lastUpdatedDep.current = updatedDep;
|
|
325
|
+
|
|
326
|
+
// Don't update while there are spinners
|
|
327
|
+
if (isUpdating()) return;
|
|
328
|
+
|
|
329
|
+
const skipHeader = sizeColumns === "auto-skip-headers";
|
|
330
|
+
autoSizeColumns({ skipHeader, userSizedColIds: userSizedColIds.current, colIds: colIdsEdited.current });
|
|
331
|
+
colIdsEdited.current.clear();
|
|
332
|
+
}, [autoSizeColumns, isUpdating, params.rowData?.length, setInitialContentSize, sizeColumns, updatedDep]);
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Show/hide no rows overlay when model changes.
|
|
336
|
+
*/
|
|
337
|
+
const isShowingNoRowsOverlay = useRef(false);
|
|
281
338
|
const onModelUpdated = useCallback((event: ModelUpdatedEvent) => {
|
|
282
|
-
event.api.getDisplayedRowCount() === 0
|
|
339
|
+
if (event.api.getDisplayedRowCount() === 0) {
|
|
340
|
+
if (!isShowingNoRowsOverlay.current) {
|
|
341
|
+
event.api.showNoRowsOverlay();
|
|
342
|
+
isShowingNoRowsOverlay.current = true;
|
|
343
|
+
}
|
|
344
|
+
} else {
|
|
345
|
+
if (isShowingNoRowsOverlay.current) {
|
|
346
|
+
event.api.hideOverlay();
|
|
347
|
+
isShowingNoRowsOverlay.current = false;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
283
350
|
}, []);
|
|
284
351
|
|
|
352
|
+
/**
|
|
353
|
+
* Force-refresh all selected rows to re-run class function, to update selection highlighting
|
|
354
|
+
*/
|
|
285
355
|
const refreshSelectedRows = useCallback((event: CellEvent): void => {
|
|
286
|
-
// Force-refresh all selected rows to re-run class function, to update selection highlighting
|
|
287
356
|
event.api.refreshCells({
|
|
288
357
|
force: true,
|
|
289
358
|
rowNodes: event.api.getSelectedNodes(),
|
|
290
359
|
});
|
|
291
360
|
}, []);
|
|
292
361
|
|
|
362
|
+
/**
|
|
363
|
+
* Make sure node is selected for editing and start edit
|
|
364
|
+
*/
|
|
293
365
|
const startCellEditing = useCallback(
|
|
294
366
|
(event: CellEvent) => {
|
|
295
367
|
prePopupOps();
|
|
@@ -311,6 +383,9 @@ export const Grid = ({
|
|
|
311
383
|
[checkUpdating, prePopupOps],
|
|
312
384
|
);
|
|
313
385
|
|
|
386
|
+
/**
|
|
387
|
+
* Handle double click edit
|
|
388
|
+
*/
|
|
314
389
|
const onCellDoubleClick = useCallback(
|
|
315
390
|
(event: CellEvent) => {
|
|
316
391
|
if (!invokeEditAction(event)) startCellEditing(event);
|
|
@@ -318,6 +393,9 @@ export const Grid = ({
|
|
|
318
393
|
[startCellEditing],
|
|
319
394
|
);
|
|
320
395
|
|
|
396
|
+
/**
|
|
397
|
+
* Handle single click edits
|
|
398
|
+
*/
|
|
321
399
|
const onCellClicked = useCallback(
|
|
322
400
|
(event: CellEvent) => {
|
|
323
401
|
if (event.colDef?.cellRendererParams?.singleClickEdit) {
|
|
@@ -327,6 +405,9 @@ export const Grid = ({
|
|
|
327
405
|
[startCellEditing],
|
|
328
406
|
);
|
|
329
407
|
|
|
408
|
+
/**
|
|
409
|
+
* If cell has an edit action invoke it (if editable)
|
|
410
|
+
*/
|
|
330
411
|
const invokeEditAction = (e: CellEvent): boolean => {
|
|
331
412
|
const editAction = e.colDef?.cellRendererParams?.editAction;
|
|
332
413
|
if (!editAction) return false;
|
|
@@ -341,6 +422,9 @@ export const Grid = ({
|
|
|
341
422
|
return true;
|
|
342
423
|
};
|
|
343
424
|
|
|
425
|
+
/**
|
|
426
|
+
* Start editing on pressing Enter
|
|
427
|
+
*/
|
|
344
428
|
const onCellKeyPress = useCallback(
|
|
345
429
|
(e: CellEvent) => {
|
|
346
430
|
if ((e.event as KeyboardEvent).key === "Enter") {
|
|
@@ -350,10 +434,6 @@ export const Grid = ({
|
|
|
350
434
|
[startCellEditing],
|
|
351
435
|
);
|
|
352
436
|
|
|
353
|
-
const onGridSizeChanged = useCallback(() => {
|
|
354
|
-
sizeColumns !== "none" && sizeColumnsToFit();
|
|
355
|
-
}, [sizeColumns, sizeColumnsToFit]);
|
|
356
|
-
|
|
357
437
|
/**
|
|
358
438
|
* Once the grid has auto-sized we want to run fit to fit the grid in its container,
|
|
359
439
|
* but we don't want the non-flex auto-sized columns to "fit" size, so suppressSizeToFit is set to true.
|
|
@@ -367,6 +447,80 @@ export const Grid = ({
|
|
|
367
447
|
[columnDefs, sizeColumns],
|
|
368
448
|
);
|
|
369
449
|
|
|
450
|
+
/**
|
|
451
|
+
* Set of colIds that need auto-sizing.
|
|
452
|
+
*/
|
|
453
|
+
const colIdsEdited = useRef(new Set<string>());
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* When cell editing has completed tag the colId as needing auto-sizing
|
|
457
|
+
*/
|
|
458
|
+
const onCellEditingStopped = useCallback(
|
|
459
|
+
(e: CellEditingStoppedEvent) => {
|
|
460
|
+
const skipHeader = sizeColumns === "auto-skip-headers";
|
|
461
|
+
if (sizeColumns === "auto" || skipHeader) {
|
|
462
|
+
// This may be wrong as the cell update hasn't completed?
|
|
463
|
+
const colId = e.colDef.colId;
|
|
464
|
+
if (colId && !e.colDef.flex) {
|
|
465
|
+
// This auto-sizes based on updatingContext completing
|
|
466
|
+
colIdsEdited.current.add(colId);
|
|
467
|
+
// This auto-sizes immediately in case it was an in place update
|
|
468
|
+
!isUpdating() && autoSizeColumns({ skipHeader, userSizedColIds: userSizedColIds.current, colIds: [colId] });
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
},
|
|
472
|
+
[autoSizeColumns, isUpdating, sizeColumns],
|
|
473
|
+
);
|
|
474
|
+
|
|
475
|
+
const lastUpdatedDep = useRef(updatedDep);
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* If columns are edited, wait for the updating context to complete then auto-size them.
|
|
479
|
+
*/
|
|
480
|
+
useEffect(() => {
|
|
481
|
+
if (lastUpdatedDep.current === updatedDep || isEmpty(colIdsEdited.current)) return;
|
|
482
|
+
lastUpdatedDep.current = updatedDep;
|
|
483
|
+
|
|
484
|
+
// Don't update while there are spinners
|
|
485
|
+
if (isUpdating()) return;
|
|
486
|
+
|
|
487
|
+
const skipHeader = sizeColumns === "auto-skip-headers";
|
|
488
|
+
autoSizeColumns({ skipHeader, userSizedColIds: userSizedColIds.current, colIds: colIdsEdited.current });
|
|
489
|
+
colIdsEdited.current.clear();
|
|
490
|
+
}, [autoSizeColumns, updatedDep, sizeColumns, isUpdating]);
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Resize columns to fit if required on window/container resize
|
|
494
|
+
*/
|
|
495
|
+
const onGridSizeChanged = useCallback(() => {
|
|
496
|
+
if (sizeColumns !== "none") {
|
|
497
|
+
sizeColumnsToFit();
|
|
498
|
+
}
|
|
499
|
+
}, [sizeColumns, sizeColumnsToFit]);
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Set of column Id's that are prevented from auto-sizing as they are user set
|
|
503
|
+
*/
|
|
504
|
+
const userSizedColIds = useRef(new Set<string>());
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* Lock/unlock column width on user edit/reset.
|
|
508
|
+
*/
|
|
509
|
+
const onColumnResized = useCallback((e: ColumnResizedEvent) => {
|
|
510
|
+
const colId = e.column?.getColId();
|
|
511
|
+
if (colId == null) return;
|
|
512
|
+
switch (e.source) {
|
|
513
|
+
case "uiColumnDragged":
|
|
514
|
+
userSizedColIds.current.add(colId);
|
|
515
|
+
break;
|
|
516
|
+
case "autosizeColumns":
|
|
517
|
+
userSizedColIds.current.delete(colId);
|
|
518
|
+
break;
|
|
519
|
+
}
|
|
520
|
+
}, []);
|
|
521
|
+
|
|
522
|
+
setOnCellEditingComplete(params.onCellEditingComplete);
|
|
523
|
+
|
|
370
524
|
return (
|
|
371
525
|
<div
|
|
372
526
|
data-testid={dataTestId}
|
|
@@ -388,11 +542,15 @@ export const Grid = ({
|
|
|
388
542
|
onGridSizeChanged={onGridSizeChanged}
|
|
389
543
|
suppressColumnVirtualisation={suppressColumnVirtualization}
|
|
390
544
|
suppressClickEdit={true}
|
|
545
|
+
onRowDataChanged={onRowDataChanged}
|
|
391
546
|
onCellKeyPress={onCellKeyPress}
|
|
392
547
|
onCellClicked={onCellClicked}
|
|
393
548
|
onCellDoubleClicked={onCellDoubleClick}
|
|
394
549
|
onCellEditingStarted={refreshSelectedRows}
|
|
395
550
|
domLayout={params.domLayout}
|
|
551
|
+
onCellEditingStopped={onCellEditingStopped}
|
|
552
|
+
onColumnResized={onColumnResized}
|
|
553
|
+
defaultColDef={{ minWidth: 48, ...omit(params.defaultColDef, ["editable"]) }}
|
|
396
554
|
columnDefs={columnDefsAdjusted}
|
|
397
555
|
rowData={params.rowData}
|
|
398
556
|
noRowsOverlayComponent={GridNoRowsOverlay}
|
|
@@ -105,6 +105,7 @@ export const GridCell = <RowType extends GridBaseRow, Props extends CellEditorCo
|
|
|
105
105
|
props: GenericCellColDef<RowType>,
|
|
106
106
|
custom?: {
|
|
107
107
|
multiEdit?: boolean;
|
|
108
|
+
preventAutoEdit?: boolean;
|
|
108
109
|
editor?: (editorProps: Props) => JSX.Element;
|
|
109
110
|
editorParams?: Props;
|
|
110
111
|
},
|
|
@@ -123,7 +124,6 @@ export const GridCell = <RowType extends GridBaseRow, Props extends CellEditorCo
|
|
|
123
124
|
headerTooltip: props.headerName,
|
|
124
125
|
sortable: !!(props?.field || props?.valueGetter),
|
|
125
126
|
resizable: true,
|
|
126
|
-
minWidth: props.flex ? 150 : 48,
|
|
127
127
|
editable: props.editable ?? false,
|
|
128
128
|
...(custom?.editor && {
|
|
129
129
|
cellClassRules: GridCellMultiSelectClassRules,
|
|
@@ -132,7 +132,11 @@ export const GridCell = <RowType extends GridBaseRow, Props extends CellEditorCo
|
|
|
132
132
|
}),
|
|
133
133
|
suppressKeyboardEvent: suppressCellKeyboardEvents,
|
|
134
134
|
...(custom?.editorParams && {
|
|
135
|
-
cellEditorParams: {
|
|
135
|
+
cellEditorParams: {
|
|
136
|
+
...custom.editorParams,
|
|
137
|
+
multiEdit: custom.multiEdit,
|
|
138
|
+
preventAutoEdit: custom.preventAutoEdit ?? false,
|
|
139
|
+
},
|
|
136
140
|
}),
|
|
137
141
|
// If there's a valueFormatter and no filterValueGetter then create a filterValueGetter
|
|
138
142
|
filterValueGetter,
|
|
@@ -21,7 +21,7 @@ export interface GridPopoverHookProps<RowType> {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export const useGridPopoverHook = <RowType extends GridBaseRow>(props: GridPopoverHookProps<RowType>) => {
|
|
24
|
-
const { stopEditing } = useContext(GridContext);
|
|
24
|
+
const { stopEditing, cancelEdit } = useContext(GridContext);
|
|
25
25
|
const { anchorRef, saving, updateValue } = useGridPopoverContext<RowType>();
|
|
26
26
|
const saveButtonRef = useRef<HTMLButtonElement>(null);
|
|
27
27
|
const [isOpen, setOpen] = useState(false);
|
|
@@ -33,7 +33,7 @@ export const useGridPopoverHook = <RowType extends GridBaseRow>(props: GridPopov
|
|
|
33
33
|
const triggerSave = useCallback(
|
|
34
34
|
async (reason?: string) => {
|
|
35
35
|
if (reason == CloseReason.CANCEL) {
|
|
36
|
-
|
|
36
|
+
cancelEdit();
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
39
39
|
if (props.invalid && props.invalid()) {
|
|
@@ -41,7 +41,7 @@ export const useGridPopoverHook = <RowType extends GridBaseRow>(props: GridPopov
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
if (!props.save) {
|
|
44
|
-
|
|
44
|
+
cancelEdit();
|
|
45
45
|
} else if (props.save) {
|
|
46
46
|
// forms that don't provide an invalid fn must wait until they have saved to close
|
|
47
47
|
if (props.invalid) stopEditing();
|
|
@@ -55,7 +55,7 @@ export const useGridPopoverHook = <RowType extends GridBaseRow>(props: GridPopov
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
},
|
|
58
|
-
[props, stopEditing, updateValue],
|
|
58
|
+
[cancelEdit, props, stopEditing, updateValue],
|
|
59
59
|
);
|
|
60
60
|
|
|
61
61
|
const popoverWrapper = useCallback(
|
|
@@ -115,14 +115,7 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormDro
|
|
|
115
115
|
: item,
|
|
116
116
|
);
|
|
117
117
|
|
|
118
|
-
|
|
119
|
-
// This is needed otherwise when filter input is rendered and sets autofocus
|
|
120
|
-
// the mouse up of the double click edit triggers the cell to cancel editing
|
|
121
|
-
setOptions(optionsList);
|
|
122
|
-
//delay(() => setOptions(optionsList), 100);
|
|
123
|
-
} else {
|
|
124
|
-
setOptions(optionsList);
|
|
125
|
-
}
|
|
118
|
+
setOptions(optionsList);
|
|
126
119
|
}
|
|
127
120
|
})();
|
|
128
121
|
}, [filter, options, props, selectedRows]);
|
|
@@ -6,6 +6,14 @@ import { ColDefT, GridBaseRow } from "../components";
|
|
|
6
6
|
|
|
7
7
|
export type GridFilterExternal<RowType extends GridBaseRow> = (data: RowType, rowNode: RowNode) => boolean;
|
|
8
8
|
|
|
9
|
+
export interface AutoSizeColumnsProps {
|
|
10
|
+
skipHeader?: boolean;
|
|
11
|
+
colIds?: Set<string> | string[];
|
|
12
|
+
userSizedColIds?: Set<string>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type AutoSizeColumnsResult = { width: number } | null;
|
|
16
|
+
|
|
9
17
|
export interface GridContextType<RowType extends GridBaseRow> {
|
|
10
18
|
gridReady: boolean;
|
|
11
19
|
setApis: (gridApi: GridApi | undefined, columnApi: ColumnApi | undefined, dataTestId?: string) => void;
|
|
@@ -26,8 +34,9 @@ export interface GridContextType<RowType extends GridBaseRow> {
|
|
|
26
34
|
ensureRowVisible: (id: number | string) => boolean;
|
|
27
35
|
ensureSelectedRowIsVisible: () => void;
|
|
28
36
|
getFirstRowId: () => number;
|
|
29
|
-
|
|
37
|
+
autoSizeColumns: (props?: AutoSizeColumnsProps) => AutoSizeColumnsResult;
|
|
30
38
|
sizeColumnsToFit: () => void;
|
|
39
|
+
cancelEdit: () => void;
|
|
31
40
|
stopEditing: () => void;
|
|
32
41
|
updatingCells: (
|
|
33
42
|
props: { selectedRows: GridBaseRow[]; field?: string },
|
|
@@ -47,6 +56,7 @@ export interface GridContextType<RowType extends GridBaseRow> {
|
|
|
47
56
|
invisibleColumnIds: string[];
|
|
48
57
|
setInvisibleColumnIds: (colIds: string[]) => void;
|
|
49
58
|
downloadCsv: (csvExportParams?: CsvExportParams) => void;
|
|
59
|
+
setOnCellEditingComplete: (callback: (() => void) | undefined) => void;
|
|
50
60
|
}
|
|
51
61
|
|
|
52
62
|
export const GridContext = createContext<GridContextType<any>>({
|
|
@@ -117,8 +127,8 @@ export const GridContext = createContext<GridContextType<any>>({
|
|
|
117
127
|
console.error("no context provider for getFirstRowId");
|
|
118
128
|
return -1;
|
|
119
129
|
},
|
|
120
|
-
|
|
121
|
-
console.error("no context provider for
|
|
130
|
+
autoSizeColumns: () => {
|
|
131
|
+
console.error("no context provider for autoSizeColumns");
|
|
122
132
|
return null;
|
|
123
133
|
},
|
|
124
134
|
sizeColumnsToFit: () => {
|
|
@@ -129,6 +139,9 @@ export const GridContext = createContext<GridContextType<any>>({
|
|
|
129
139
|
console.error("no context provider for editingCells");
|
|
130
140
|
return false;
|
|
131
141
|
},
|
|
142
|
+
cancelEdit: () => {
|
|
143
|
+
console.error("no context provider for cancelEdit");
|
|
144
|
+
},
|
|
132
145
|
stopEditing: () => {
|
|
133
146
|
console.error("no context provider for stopEditing");
|
|
134
147
|
},
|
|
@@ -162,6 +175,9 @@ export const GridContext = createContext<GridContextType<any>>({
|
|
|
162
175
|
downloadCsv: () => {
|
|
163
176
|
console.error("no context provider for downloadCsv");
|
|
164
177
|
},
|
|
178
|
+
setOnCellEditingComplete: () => {
|
|
179
|
+
console.error("no context provider for setOnCellEditingComplete");
|
|
180
|
+
},
|
|
165
181
|
});
|
|
166
182
|
|
|
167
183
|
export const useGridContext = <RowType extends GridBaseRow>() => useContext<GridContextType<RowType>>(GridContext);
|