@linzjs/step-ag-grid 14.1.2 → 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 +293 -95
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Grid.tsx +178 -31
- 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 -41
- 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,47 +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
|
+
*/
|
|
94
110
|
const hasSetContentSize = useRef(false);
|
|
95
111
|
const hasSetContentSizeEmpty = useRef(false);
|
|
96
112
|
|
|
97
113
|
const setInitialContentSize = useCallback(() => {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if (sizeColumns === "auto" || skipHeaders) {
|
|
104
|
-
// If we aren't skipping headers and there's no data, then don't skip headers
|
|
105
|
-
const result = autoSizeAllColumns({ skipHeader: skipHeaders && !isEmpty(params.rowData) });
|
|
106
|
-
if (isEmpty(params.rowData)) {
|
|
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) {
|
|
107
119
|
hasSetContentSizeEmpty.current = true;
|
|
108
|
-
|
|
120
|
+
params.onContentSize && result && params.onContentSize(result);
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
if (!hasSetContentSize.current) {
|
|
109
124
|
hasSetContentSize.current = true;
|
|
125
|
+
params.onContentSize && result && params.onContentSize(result);
|
|
110
126
|
}
|
|
111
|
-
params.onContentSize && result && params.onContentSize(result);
|
|
112
127
|
}
|
|
113
128
|
}
|
|
114
129
|
|
|
115
130
|
if (sizeColumns !== "none") {
|
|
116
131
|
sizeColumnsToFit();
|
|
117
132
|
}
|
|
118
|
-
}, [
|
|
133
|
+
}, [autoSizeColumns, params, sizeColumns, sizeColumnsToFit]);
|
|
119
134
|
|
|
135
|
+
/**
|
|
136
|
+
* When the grid becomes ready resize it
|
|
137
|
+
*/
|
|
138
|
+
const previousGridReady = useRef(gridReady);
|
|
120
139
|
useEffect(() => {
|
|
121
|
-
|
|
140
|
+
if (!previousGridReady.current && gridReady) {
|
|
141
|
+
previousGridReady.current = true;
|
|
142
|
+
setInitialContentSize();
|
|
143
|
+
}
|
|
122
144
|
}, [gridReady, setInitialContentSize]);
|
|
123
145
|
|
|
124
146
|
/**
|
|
@@ -195,12 +217,17 @@ export const Grid = ({
|
|
|
195
217
|
|
|
196
218
|
const selectedIds = params.externalSelectedItems.map((row) => row.id) as number[];
|
|
197
219
|
const lastNewId = last(difference(selectedIds, lastSelectedIds.current));
|
|
198
|
-
if (lastNewId != null)
|
|
220
|
+
if (lastNewId != null) {
|
|
221
|
+
ensureRowVisible(lastNewId);
|
|
222
|
+
}
|
|
199
223
|
lastSelectedIds.current = selectedIds;
|
|
200
224
|
selectRowsById(selectedIds);
|
|
201
225
|
setExternallySelectedItemsAreInSync(true);
|
|
202
226
|
}, [gridReady, params.externalSelectedItems, ensureRowVisible, selectRowsById, setExternallySelectedItemsAreInSync]);
|
|
203
227
|
|
|
228
|
+
/**
|
|
229
|
+
* Combine grid and cell editable into one function
|
|
230
|
+
*/
|
|
204
231
|
const combineEditables =
|
|
205
232
|
(...editables: (boolean | EditableCallback | undefined)[]) =>
|
|
206
233
|
(params: EditableCallbackParams): boolean => {
|
|
@@ -214,10 +241,11 @@ export const Grid = ({
|
|
|
214
241
|
/**
|
|
215
242
|
* Synchronise externally selected items to grid on externalSelectedItems change
|
|
216
243
|
*/
|
|
217
|
-
useEffect(
|
|
218
|
-
synchroniseExternallySelectedItemsToGrid();
|
|
219
|
-
}, [synchroniseExternallySelectedItemsToGrid]);
|
|
244
|
+
useEffect(synchroniseExternallySelectedItemsToGrid, [synchroniseExternallySelectedItemsToGrid]);
|
|
220
245
|
|
|
246
|
+
/**
|
|
247
|
+
* Add selectable column to colDefs. Adjust column defs to block fit for auto sized columns.
|
|
248
|
+
*/
|
|
221
249
|
const columnDefs = useMemo((): ColDef[] => {
|
|
222
250
|
const adjustColDefs = params.columnDefs.map((colDef) => {
|
|
223
251
|
const colDefEditable = colDef.editable;
|
|
@@ -268,6 +296,9 @@ export const Grid = ({
|
|
|
268
296
|
clickSelectorCheckboxWhenContainingCellClicked,
|
|
269
297
|
]);
|
|
270
298
|
|
|
299
|
+
/**
|
|
300
|
+
* When grid is ready set the apis to the grid context and sync selected items to grid.
|
|
301
|
+
*/
|
|
271
302
|
const onGridReady = useCallback(
|
|
272
303
|
(event: GridReadyEvent) => {
|
|
273
304
|
setApis(event.api, event.columnApi, dataTestId);
|
|
@@ -281,30 +312,56 @@ export const Grid = ({
|
|
|
281
312
|
* This will resize columns when we have at least one row.
|
|
282
313
|
*/
|
|
283
314
|
const previousRowDataLength = useRef(0);
|
|
284
|
-
useEffect(() => {
|
|
285
|
-
if (!gridReady) return;
|
|
286
315
|
|
|
316
|
+
const onRowDataChanged = useCallback(() => {
|
|
287
317
|
const length = params.rowData?.length ?? 0;
|
|
288
318
|
if (previousRowDataLength.current !== length) {
|
|
289
|
-
|
|
290
|
-
setInitialContentSize();
|
|
291
|
-
}
|
|
319
|
+
setInitialContentSize();
|
|
292
320
|
previousRowDataLength.current = length;
|
|
293
321
|
}
|
|
294
|
-
}, [gridReady, params.rowData?.length, setInitialContentSize]);
|
|
295
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);
|
|
296
338
|
const onModelUpdated = useCallback((event: ModelUpdatedEvent) => {
|
|
297
|
-
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
|
+
}
|
|
298
350
|
}, []);
|
|
299
351
|
|
|
352
|
+
/**
|
|
353
|
+
* Force-refresh all selected rows to re-run class function, to update selection highlighting
|
|
354
|
+
*/
|
|
300
355
|
const refreshSelectedRows = useCallback((event: CellEvent): void => {
|
|
301
|
-
// Force-refresh all selected rows to re-run class function, to update selection highlighting
|
|
302
356
|
event.api.refreshCells({
|
|
303
357
|
force: true,
|
|
304
358
|
rowNodes: event.api.getSelectedNodes(),
|
|
305
359
|
});
|
|
306
360
|
}, []);
|
|
307
361
|
|
|
362
|
+
/**
|
|
363
|
+
* Make sure node is selected for editing and start edit
|
|
364
|
+
*/
|
|
308
365
|
const startCellEditing = useCallback(
|
|
309
366
|
(event: CellEvent) => {
|
|
310
367
|
prePopupOps();
|
|
@@ -326,6 +383,9 @@ export const Grid = ({
|
|
|
326
383
|
[checkUpdating, prePopupOps],
|
|
327
384
|
);
|
|
328
385
|
|
|
386
|
+
/**
|
|
387
|
+
* Handle double click edit
|
|
388
|
+
*/
|
|
329
389
|
const onCellDoubleClick = useCallback(
|
|
330
390
|
(event: CellEvent) => {
|
|
331
391
|
if (!invokeEditAction(event)) startCellEditing(event);
|
|
@@ -333,6 +393,9 @@ export const Grid = ({
|
|
|
333
393
|
[startCellEditing],
|
|
334
394
|
);
|
|
335
395
|
|
|
396
|
+
/**
|
|
397
|
+
* Handle single click edits
|
|
398
|
+
*/
|
|
336
399
|
const onCellClicked = useCallback(
|
|
337
400
|
(event: CellEvent) => {
|
|
338
401
|
if (event.colDef?.cellRendererParams?.singleClickEdit) {
|
|
@@ -342,6 +405,9 @@ export const Grid = ({
|
|
|
342
405
|
[startCellEditing],
|
|
343
406
|
);
|
|
344
407
|
|
|
408
|
+
/**
|
|
409
|
+
* If cell has an edit action invoke it (if editable)
|
|
410
|
+
*/
|
|
345
411
|
const invokeEditAction = (e: CellEvent): boolean => {
|
|
346
412
|
const editAction = e.colDef?.cellRendererParams?.editAction;
|
|
347
413
|
if (!editAction) return false;
|
|
@@ -356,6 +422,9 @@ export const Grid = ({
|
|
|
356
422
|
return true;
|
|
357
423
|
};
|
|
358
424
|
|
|
425
|
+
/**
|
|
426
|
+
* Start editing on pressing Enter
|
|
427
|
+
*/
|
|
359
428
|
const onCellKeyPress = useCallback(
|
|
360
429
|
(e: CellEvent) => {
|
|
361
430
|
if ((e.event as KeyboardEvent).key === "Enter") {
|
|
@@ -378,6 +447,80 @@ export const Grid = ({
|
|
|
378
447
|
[columnDefs, sizeColumns],
|
|
379
448
|
);
|
|
380
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
|
+
|
|
381
524
|
return (
|
|
382
525
|
<div
|
|
383
526
|
data-testid={dataTestId}
|
|
@@ -396,14 +539,18 @@ export const Grid = ({
|
|
|
396
539
|
suppressRowClickSelection={true}
|
|
397
540
|
rowSelection={rowSelection}
|
|
398
541
|
suppressBrowserResizeObserver={true}
|
|
399
|
-
onGridSizeChanged={
|
|
542
|
+
onGridSizeChanged={onGridSizeChanged}
|
|
400
543
|
suppressColumnVirtualisation={suppressColumnVirtualization}
|
|
401
544
|
suppressClickEdit={true}
|
|
545
|
+
onRowDataChanged={onRowDataChanged}
|
|
402
546
|
onCellKeyPress={onCellKeyPress}
|
|
403
547
|
onCellClicked={onCellClicked}
|
|
404
548
|
onCellDoubleClicked={onCellDoubleClick}
|
|
405
549
|
onCellEditingStarted={refreshSelectedRows}
|
|
406
550
|
domLayout={params.domLayout}
|
|
551
|
+
onCellEditingStopped={onCellEditingStopped}
|
|
552
|
+
onColumnResized={onColumnResized}
|
|
553
|
+
defaultColDef={{ minWidth: 48, ...omit(params.defaultColDef, ["editable"]) }}
|
|
407
554
|
columnDefs={columnDefsAdjusted}
|
|
408
555
|
rowData={params.rowData}
|
|
409
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);
|