@linzjs/step-ag-grid 25.0.1 → 26.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/README.md +1 -1
- package/dist/GridTheme.scss +29 -61
- package/dist/src/components/Grid.d.ts +9 -7
- package/dist/src/components/GridCell.d.ts +4 -5
- package/dist/src/components/gridForm/GridFormDropDown.d.ts +1 -1
- package/dist/src/components/gridPopoverEdit/GridEditBoolean.d.ts +1 -1
- package/dist/src/components/index.d.ts +0 -2
- package/dist/src/contexts/GridContext.d.ts +1 -1
- package/dist/step-ag-grid.cjs +652 -265
- package/dist/step-ag-grid.cjs.map +1 -1
- package/dist/step-ag-grid.esm.js +658 -269
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +39 -45
- package/src/components/Grid.tsx +111 -139
- package/src/components/GridCell.tsx +4 -6
- package/src/components/gridForm/GridFormDropDown.tsx +1 -1
- package/src/components/gridHeader/GridHeaderSelect.tsx +1 -1
- package/src/components/gridPopoverEdit/GridEditBoolean.tsx +5 -1
- package/src/components/index.ts +0 -2
- package/src/contexts/GridContext.tsx +3 -2
- package/src/contexts/GridContextProvider.tsx +85 -48
- package/src/react-menu3/components/ControlledMenu.tsx +15 -2
- package/src/stories/grid/GridDragRow.stories.tsx +16 -13
- package/src/stories/grid/GridFilterButtons.stories.tsx +7 -1
- package/src/stories/grid/GridPopoverEditDropDown.stories.tsx +1 -1
- package/src/stories/grid/gridFormStatic/GridFormDropDown.stories.tsx +1 -1
- package/src/stories/grid/interactions/GridKeyboardInteractions.stories.tsx +6 -4
- package/src/styles/GridTheme.scss +29 -61
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@linzjs/step-ag-grid",
|
|
3
3
|
"repository": "github:linz/step-ag-grid.git",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "26.0.0",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"aggrid",
|
|
8
8
|
"ag-grid",
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
"access": "public"
|
|
25
25
|
},
|
|
26
26
|
"engines": {
|
|
27
|
-
"node": ">=
|
|
27
|
+
"node": ">=20"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"@linzjs/lui": ">=21",
|
|
31
|
-
"ag-grid-community": "^
|
|
32
|
-
"ag-grid-react": "^
|
|
31
|
+
"ag-grid-community": "^33.2.4",
|
|
32
|
+
"ag-grid-react": "^33.2.4",
|
|
33
33
|
"lodash-es": ">=4",
|
|
34
34
|
"react": ">=18",
|
|
35
35
|
"react-dom": ">=18"
|
|
@@ -38,15 +38,14 @@
|
|
|
38
38
|
"clsx": "^2.1.1",
|
|
39
39
|
"debounce-promise": "^3.1.2",
|
|
40
40
|
"matcher": "^5.0.0",
|
|
41
|
-
"react-transition-state": "^2.3.
|
|
42
|
-
"usehooks-ts": "^3.1.
|
|
41
|
+
"react-transition-state": "^2.3.1",
|
|
42
|
+
"usehooks-ts": "^3.1.1"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
|
-
"build": "run-s clean
|
|
45
|
+
"build": "run-s clean lint css bundle",
|
|
46
46
|
"yalc": "run-s clean css bundle && yalc push",
|
|
47
47
|
"clean": "rimraf dist && mkdirp ./dist",
|
|
48
48
|
"bundle": "rollup -c",
|
|
49
|
-
"stylelint": "stylelint src/**/*.scss src/**/*.css --fix",
|
|
50
49
|
"css": "sass ./src/styles/index.scss:dist/index.css --no-source-map",
|
|
51
50
|
"test": "vitest run",
|
|
52
51
|
"test:watch": "vitest --watch",
|
|
@@ -77,67 +76,62 @@
|
|
|
77
76
|
]
|
|
78
77
|
},
|
|
79
78
|
"devDependencies": {
|
|
80
|
-
"@chromatic-com/storybook": "^3.2.
|
|
81
|
-
"@linzjs/lui": "^22.
|
|
79
|
+
"@chromatic-com/storybook": "^3.2.6",
|
|
80
|
+
"@linzjs/lui": "^22.12.0",
|
|
82
81
|
"@linzjs/style": "^5.4.0",
|
|
83
|
-
"@rollup/plugin-commonjs": "^
|
|
82
|
+
"@rollup/plugin-commonjs": "^28.0.3",
|
|
84
83
|
"@rollup/plugin-json": "^6.1.0",
|
|
85
|
-
"@rollup/plugin-node-resolve": "^
|
|
84
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
86
85
|
"@semantic-release/git": "^10.0.1",
|
|
87
|
-
"@storybook/addon-essentials": "^8.
|
|
88
|
-
"@storybook/addon-interactions": "^8.
|
|
89
|
-
"@storybook/addon-links": "^8.
|
|
90
|
-
"@storybook/react": "^8.
|
|
91
|
-
"@storybook/react-vite": "^8.
|
|
92
|
-
"@storybook/test": "^8.
|
|
93
|
-
"@storybook/test-runner": "^0.
|
|
86
|
+
"@storybook/addon-essentials": "^8.6.12",
|
|
87
|
+
"@storybook/addon-interactions": "^8.6.12",
|
|
88
|
+
"@storybook/addon-links": "^8.6.12",
|
|
89
|
+
"@storybook/react": "^8.6.12",
|
|
90
|
+
"@storybook/react-vite": "^8.6.12",
|
|
91
|
+
"@storybook/test": "^8.6.12",
|
|
92
|
+
"@storybook/test-runner": "^0.22.0",
|
|
94
93
|
"@testing-library/dom": "^10.4.0",
|
|
95
|
-
"@testing-library/react": "^16.
|
|
94
|
+
"@testing-library/react": "^16.3.0",
|
|
96
95
|
"@testing-library/user-event": "^14.6.1",
|
|
97
96
|
"@types/debounce-promise": "^3.1.9",
|
|
98
97
|
"@types/lodash-es": "^4.17.12",
|
|
99
|
-
"@types/node": "^22.
|
|
100
|
-
"@types/react": "^18.3.
|
|
101
|
-
"@types/react-dom": "^18.3.
|
|
98
|
+
"@types/node": "^22.15.3",
|
|
99
|
+
"@types/react": "^18.3.20",
|
|
100
|
+
"@types/react-dom": "^18.3.7",
|
|
102
101
|
"@types/uuid": "^10.0.0",
|
|
103
|
-
"@vitejs/plugin-react-swc": "^3.
|
|
104
|
-
"@vitest/ui": "^3.
|
|
105
|
-
"ag-grid-community": "^
|
|
106
|
-
"ag-grid-react": "^
|
|
107
|
-
"babel-preset-react-app": "^10.0
|
|
108
|
-
"chromatic": "^11.
|
|
102
|
+
"@vitejs/plugin-react-swc": "^3.9.0",
|
|
103
|
+
"@vitest/ui": "^3.1.2",
|
|
104
|
+
"ag-grid-community": "^33.2.4",
|
|
105
|
+
"ag-grid-react": "^33.2.4",
|
|
106
|
+
"babel-preset-react-app": "^10.1.0",
|
|
107
|
+
"chromatic": "^11.28.2",
|
|
109
108
|
"css-loader": "^7.1.2",
|
|
110
|
-
"jsdom": "^26.
|
|
109
|
+
"jsdom": "^26.1.0",
|
|
111
110
|
"lodash-es": "^4.17.21",
|
|
112
111
|
"mkdirp": "^3.0.1",
|
|
113
112
|
"npm-run-all": "^4.1.5",
|
|
114
|
-
"postcss": "^8.5.
|
|
115
|
-
"postcss-loader": "^
|
|
113
|
+
"postcss": "^8.5.3",
|
|
114
|
+
"postcss-loader": "^8.1.1",
|
|
116
115
|
"postcss-scss": "^4.0.9",
|
|
117
116
|
"react": ">=18",
|
|
118
117
|
"react-app-polyfill": "^3.0.0",
|
|
119
118
|
"react-dom": "^18.3.1",
|
|
120
|
-
"rollup": "^4.
|
|
119
|
+
"rollup": "^4.40.1",
|
|
121
120
|
"rollup-plugin-copy": "^3.5.0",
|
|
122
121
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
123
122
|
"rollup-plugin-postcss": "^4.0.2",
|
|
124
123
|
"rollup-plugin-typescript2": "^0.36.0",
|
|
125
|
-
"sass": "^1.
|
|
126
|
-
"sass-loader": "^
|
|
127
|
-
"semantic-release": "^
|
|
128
|
-
"storybook": "^8.
|
|
124
|
+
"sass": "^1.87.0",
|
|
125
|
+
"sass-loader": "^16.0.5",
|
|
126
|
+
"semantic-release": "^24.2.3",
|
|
127
|
+
"storybook": "^8.6.12",
|
|
129
128
|
"storybook-css-modules-preset": "^1.1.1",
|
|
130
129
|
"style-loader": "^4.0.0",
|
|
131
|
-
"
|
|
132
|
-
"
|
|
133
|
-
"stylelint-config-standard": "^34.0.0",
|
|
134
|
-
"stylelint-prettier": "^4.1.0",
|
|
135
|
-
"stylelint-scss": "^5.3.2",
|
|
136
|
-
"typescript": "^5.7.3",
|
|
137
|
-
"vite": "^6.0.11",
|
|
130
|
+
"typescript": "^5.8.3",
|
|
131
|
+
"vite": "^6.3.4",
|
|
138
132
|
"vite-plugin-html": "^3.2.2",
|
|
139
133
|
"vite-tsconfig-paths": "^5.1.4",
|
|
140
|
-
"vitest": "^3.
|
|
134
|
+
"vitest": "^3.1.2",
|
|
141
135
|
"vitest-canvas-mock": "^0.3.3"
|
|
142
136
|
},
|
|
143
137
|
"babel": {
|
package/src/components/Grid.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AgGridEvent,
|
|
3
|
+
AllCommunityModule,
|
|
3
4
|
CellClassParams,
|
|
4
5
|
CellClickedEvent,
|
|
5
6
|
CellDoubleClickedEvent,
|
|
@@ -12,13 +13,10 @@ import {
|
|
|
12
13
|
EditableCallbackParams,
|
|
13
14
|
GridOptions,
|
|
14
15
|
GridReadyEvent,
|
|
15
|
-
IClientSideRowModel,
|
|
16
16
|
ModelUpdatedEvent,
|
|
17
|
+
ModuleRegistry,
|
|
17
18
|
RowDragEndEvent,
|
|
18
|
-
RowDragLeaveEvent,
|
|
19
19
|
RowDragMoveEvent,
|
|
20
|
-
RowHighlightPosition,
|
|
21
|
-
RowNode,
|
|
22
20
|
SelectionChangedEvent,
|
|
23
21
|
} from 'ag-grid-community';
|
|
24
22
|
import { AgGridReact } from 'ag-grid-react';
|
|
@@ -27,7 +25,7 @@ import { defer, difference, isEmpty, last, omit, xorBy } from 'lodash-es';
|
|
|
27
25
|
import { ReactElement, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
28
26
|
import { useInterval } from 'usehooks-ts';
|
|
29
27
|
|
|
30
|
-
import { GridContext } from '../contexts/GridContext';
|
|
28
|
+
import { GridContext, useGridContext } from '../contexts/GridContext';
|
|
31
29
|
import { GridUpdatingContext } from '../contexts/GridUpdatingContext';
|
|
32
30
|
import { fnOrVar, isNotEmpty } from '../utils/util';
|
|
33
31
|
import { clickInputWhenContainingCellClicked } from './clickInputWhenContainingCellClicked';
|
|
@@ -36,11 +34,19 @@ import { GridContextMenuComponent, useGridContextMenu } from './gridHook';
|
|
|
36
34
|
import { GridNoRowsOverlay } from './GridNoRowsOverlay';
|
|
37
35
|
import { usePostSortRowsHook } from './PostSortRowsHook';
|
|
38
36
|
|
|
37
|
+
ModuleRegistry.registerModules([AllCommunityModule]);
|
|
38
|
+
|
|
39
39
|
export interface GridBaseRow {
|
|
40
40
|
id: string | number;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
export interface
|
|
43
|
+
export interface GridOnRowDragEndProps<TData extends GridBaseRow> {
|
|
44
|
+
movedRow: TData;
|
|
45
|
+
targetRow: TData;
|
|
46
|
+
direction: -1 | 1;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface GridProps<TData extends GridBaseRow = GridBaseRow> {
|
|
44
50
|
readOnly?: boolean; // set all editables to false when read only, make all styles black, otherwise style is gray for not editable
|
|
45
51
|
defaultPostSort?: boolean; // Retain sort order after edit, Defaults to true.
|
|
46
52
|
selectable?: boolean;
|
|
@@ -50,11 +56,8 @@ export interface GridProps {
|
|
|
50
56
|
externalSelectedItems?: any[];
|
|
51
57
|
setExternalSelectedItems?: (items: any[]) => void;
|
|
52
58
|
defaultColDef?: GridOptions['defaultColDef'];
|
|
53
|
-
columnDefs: ColDef[];
|
|
59
|
+
columnDefs: ColDef<TData>[];
|
|
54
60
|
rowData: GridOptions['rowData'];
|
|
55
|
-
/**
|
|
56
|
-
* Whether select column is pinned. Defaults to "left".
|
|
57
|
-
*/
|
|
58
61
|
selectColumnPinned?: ColDef['pinned'];
|
|
59
62
|
noRowsOverlayText?: string;
|
|
60
63
|
noRowsMatchingOverlayText?: string;
|
|
@@ -65,7 +68,7 @@ export interface GridProps {
|
|
|
65
68
|
autoSelectFirstRow?: boolean;
|
|
66
69
|
onColumnMoved?: GridOptions['onColumnMoved'];
|
|
67
70
|
rowDragText?: GridOptions['rowDragText'];
|
|
68
|
-
onRowDragEnd?: (
|
|
71
|
+
onRowDragEnd?: (props: GridOnRowDragEndProps<TData>) => Promise<void> | void;
|
|
69
72
|
alwaysShowVerticalScroll?: boolean;
|
|
70
73
|
suppressColumnVirtualization?: GridOptions['suppressColumnVirtualisation'];
|
|
71
74
|
/**
|
|
@@ -116,20 +119,21 @@ export interface GridProps {
|
|
|
116
119
|
/**
|
|
117
120
|
* Wrapper for AgGrid to add commonly used functionality.
|
|
118
121
|
*/
|
|
119
|
-
export const Grid = ({
|
|
122
|
+
export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
120
123
|
'data-testid': dataTestId,
|
|
121
124
|
defaultPostSort = true,
|
|
122
125
|
rowSelection = 'multiple',
|
|
123
126
|
suppressColumnVirtualization = true,
|
|
124
127
|
theme = 'ag-theme-step-default',
|
|
125
128
|
sizeColumns = 'auto',
|
|
126
|
-
selectColumnPinned =
|
|
129
|
+
selectColumnPinned = 'left',
|
|
127
130
|
contextMenuSelectRow = false,
|
|
128
131
|
singleClickEdit = false,
|
|
129
132
|
rowData,
|
|
130
133
|
rowHeight = theme === 'ag-theme-step-default' ? 40 : theme === 'ag-theme-step-compact' ? 36 : 40,
|
|
134
|
+
selectable,
|
|
131
135
|
...params
|
|
132
|
-
}: GridProps): ReactElement => {
|
|
136
|
+
}: GridProps<TData>): ReactElement => {
|
|
133
137
|
const {
|
|
134
138
|
gridReady,
|
|
135
139
|
gridRenderState,
|
|
@@ -151,7 +155,8 @@ export const Grid = ({
|
|
|
151
155
|
prePopupOps,
|
|
152
156
|
stopEditing,
|
|
153
157
|
} = useContext(GridContext);
|
|
154
|
-
const {
|
|
158
|
+
const { startCellEditing } = useGridContext();
|
|
159
|
+
const { updatedDep, updatingCols } = useContext(GridUpdatingContext);
|
|
155
160
|
|
|
156
161
|
const gridDivRef = useRef<HTMLDivElement>(null);
|
|
157
162
|
const lastSelectedIds = useRef<number[]>([]);
|
|
@@ -335,7 +340,7 @@ export const Grid = ({
|
|
|
335
340
|
* Add selectable column to colDefs. Adjust column defs to block fit for auto sized columns.
|
|
336
341
|
*/
|
|
337
342
|
const columnDefs = useMemo((): (ColDef | ColGroupDef)[] => {
|
|
338
|
-
|
|
343
|
+
return params.columnDefs.map((colDef) => {
|
|
339
344
|
const colDefEditable = colDef.editable;
|
|
340
345
|
const editable = combineEditables(
|
|
341
346
|
params.loading !== true && params.readOnly !== true,
|
|
@@ -351,49 +356,7 @@ export const Grid = ({
|
|
|
351
356
|
},
|
|
352
357
|
};
|
|
353
358
|
});
|
|
354
|
-
|
|
355
|
-
return params.selectable || params.onRowDragEnd
|
|
356
|
-
? [
|
|
357
|
-
{
|
|
358
|
-
colId: 'selection',
|
|
359
|
-
editable: false,
|
|
360
|
-
rowDrag: !!params.onRowDragEnd,
|
|
361
|
-
minWidth: params.selectable && params.onRowDragEnd ? 76 : 48,
|
|
362
|
-
maxWidth: params.selectable && params.onRowDragEnd ? 76 : 48,
|
|
363
|
-
pinned: selectColumnPinned,
|
|
364
|
-
headerComponentParams: {
|
|
365
|
-
exportable: false,
|
|
366
|
-
},
|
|
367
|
-
checkboxSelection: params.selectable,
|
|
368
|
-
headerClass: params.onRowDragEnd ? 'ag-header-select-draggable' : undefined,
|
|
369
|
-
headerComponent: rowSelection === 'multiple' ? GridHeaderSelect : null,
|
|
370
|
-
suppressHeaderKeyboardEvent: (e) => {
|
|
371
|
-
if (!params.selectable) return false;
|
|
372
|
-
if ((e.event.key === 'Enter' || e.event.key === ' ') && !e.event.repeat) {
|
|
373
|
-
if (isEmpty(e.api.getSelectedRows())) {
|
|
374
|
-
e.api.selectAllFiltered();
|
|
375
|
-
} else {
|
|
376
|
-
e.api.deselectAll();
|
|
377
|
-
}
|
|
378
|
-
return true;
|
|
379
|
-
}
|
|
380
|
-
return false;
|
|
381
|
-
},
|
|
382
|
-
onCellClicked: clickInputWhenContainingCellClicked,
|
|
383
|
-
},
|
|
384
|
-
...adjustColDefs,
|
|
385
|
-
]
|
|
386
|
-
: adjustColDefs;
|
|
387
|
-
}, [
|
|
388
|
-
params.columnDefs,
|
|
389
|
-
params.selectable,
|
|
390
|
-
params.onRowDragEnd,
|
|
391
|
-
params.loading,
|
|
392
|
-
params.readOnly,
|
|
393
|
-
params.defaultColDef?.editable,
|
|
394
|
-
selectColumnPinned,
|
|
395
|
-
rowSelection,
|
|
396
|
-
]);
|
|
359
|
+
}, [params.columnDefs, params.loading, params.readOnly, params.defaultColDef?.editable]);
|
|
397
360
|
|
|
398
361
|
/**
|
|
399
362
|
* When grid is ready set the apis to the grid context and sync selected items to grid.
|
|
@@ -443,43 +406,23 @@ export const Grid = ({
|
|
|
443
406
|
/**
|
|
444
407
|
* Force-refresh all selected rows to re-run class function, to update selection highlighting
|
|
445
408
|
*/
|
|
446
|
-
const refreshSelectedRows = useCallback((
|
|
447
|
-
|
|
409
|
+
const refreshSelectedRows = useCallback((_event: CellEditingStartedEvent): void => {
|
|
410
|
+
// MATT Disabled I don't believe these are needed anymore
|
|
411
|
+
// I've left them here just in case they are
|
|
412
|
+
/*event.api.refreshCells({
|
|
448
413
|
force: true,
|
|
449
414
|
rowNodes: event.api.getSelectedNodes(),
|
|
450
|
-
})
|
|
415
|
+
});*/
|
|
451
416
|
}, []);
|
|
452
417
|
|
|
453
|
-
/**
|
|
454
|
-
* Make sure node is selected for editing and start edit
|
|
455
|
-
*/
|
|
456
|
-
const startCellEditing = useCallback(
|
|
457
|
-
(event: CellKeyDownEvent | CellClickedEvent | CellDoubleClickedEvent) => {
|
|
458
|
-
prePopupOps();
|
|
459
|
-
if (!event.node.isSelected()) {
|
|
460
|
-
event.node.setSelected(true, true);
|
|
461
|
-
}
|
|
462
|
-
// Cell already being edited, so don't re-edit until finished
|
|
463
|
-
if (checkUpdating([event.colDef.field ?? ''], event.data.id)) {
|
|
464
|
-
return;
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
if (event.rowIndex !== null) {
|
|
468
|
-
event.api.startEditingCell({
|
|
469
|
-
rowIndex: event.rowIndex,
|
|
470
|
-
colKey: event.column.getColId(),
|
|
471
|
-
});
|
|
472
|
-
}
|
|
473
|
-
},
|
|
474
|
-
[checkUpdating, prePopupOps],
|
|
475
|
-
);
|
|
476
|
-
|
|
477
418
|
/**
|
|
478
419
|
* Handle double click edit
|
|
479
420
|
*/
|
|
480
421
|
const onCellDoubleClick = useCallback(
|
|
481
422
|
(event: CellDoubleClickedEvent) => {
|
|
482
|
-
if (!invokeEditAction(event))
|
|
423
|
+
if (!invokeEditAction(event)) {
|
|
424
|
+
void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
|
|
425
|
+
}
|
|
483
426
|
},
|
|
484
427
|
[startCellEditing],
|
|
485
428
|
);
|
|
@@ -490,7 +433,7 @@ export const Grid = ({
|
|
|
490
433
|
const onCellClicked = useCallback(
|
|
491
434
|
(event: CellClickedEvent) => {
|
|
492
435
|
if (event.colDef?.cellRendererParams?.singleClickEdit ?? singleClickEdit) {
|
|
493
|
-
startCellEditing(event);
|
|
436
|
+
void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
|
|
494
437
|
}
|
|
495
438
|
},
|
|
496
439
|
[singleClickEdit, startCellEditing],
|
|
@@ -520,10 +463,11 @@ export const Grid = ({
|
|
|
520
463
|
(e: CellKeyDownEvent) => {
|
|
521
464
|
const kbe = e.event as KeyboardEvent;
|
|
522
465
|
if (kbe.key === 'Enter') {
|
|
523
|
-
if (!invokeEditAction(e))
|
|
466
|
+
if (!invokeEditAction(e)) {
|
|
467
|
+
void startCellEditing({ rowId: e.data.id, colId: e.column.getColId() });
|
|
468
|
+
}
|
|
524
469
|
}
|
|
525
470
|
if (kbe.key === 'Tab') {
|
|
526
|
-
// eslint-disable-next-line
|
|
527
471
|
prePopupOps();
|
|
528
472
|
}
|
|
529
473
|
},
|
|
@@ -535,15 +479,15 @@ export const Grid = ({
|
|
|
535
479
|
* but we don't want the non-flex auto-sized columns to "fit" size, so suppressSizeToFit is set to true.
|
|
536
480
|
*/
|
|
537
481
|
const columnDefsAdjusted = useMemo(() => {
|
|
538
|
-
const adjustColDefOrGroup = (colDef: ColDef | ColGroupDef) =>
|
|
482
|
+
const adjustColDefOrGroup = (colDef: ColDef<TData> | ColGroupDef<TData>) =>
|
|
539
483
|
'children' in colDef ? adjustGroupColDef(colDef) : adjustColDef(colDef);
|
|
540
484
|
|
|
541
|
-
const adjustGroupColDef = (colDef: ColGroupDef): ColGroupDef => ({
|
|
485
|
+
const adjustGroupColDef = (colDef: ColGroupDef<TData>): ColGroupDef<TData> => ({
|
|
542
486
|
...colDef,
|
|
543
487
|
children: colDef.children.map((colDef) => adjustColDefOrGroup(colDef)),
|
|
544
488
|
});
|
|
545
489
|
|
|
546
|
-
const adjustColDef = (colDef: ColDef): ColDef => ({
|
|
490
|
+
const adjustColDef = (colDef: ColDef<TData>): ColDef<TData> => ({
|
|
547
491
|
...colDef,
|
|
548
492
|
suppressSizeToFit: (sizeColumns === 'auto' || sizeColumns === 'auto-skip-headers') && !colDef.flex,
|
|
549
493
|
sortable: colDef.sortable && params.defaultColDef?.sortable !== false,
|
|
@@ -636,59 +580,59 @@ export const Grid = ({
|
|
|
636
580
|
|
|
637
581
|
const gridContextMenu = useGridContextMenu({ contextMenu: params.contextMenu, contextMenuSelectRow });
|
|
638
582
|
|
|
639
|
-
const
|
|
640
|
-
const clientSideRowModel = event.api.getModel() as IClientSideRowModel;
|
|
641
|
-
clientSideRowModel.highlightRowAtPixel(null);
|
|
642
|
-
}, []);
|
|
583
|
+
const startDragYRef = useRef<number | null>(null);
|
|
643
584
|
|
|
644
|
-
const
|
|
645
|
-
|
|
646
|
-
|
|
585
|
+
const clearHighlightRowClasses = useCallback(() => {
|
|
586
|
+
document.querySelectorAll(`.ag-row-highlight-above`)?.forEach((el) => {
|
|
587
|
+
el.classList.remove('ag-row-highlight-above');
|
|
588
|
+
});
|
|
589
|
+
document.querySelectorAll(`.ag-row-highlight-below`)?.forEach((el) => {
|
|
590
|
+
el.classList.remove('ag-row-highlight-below');
|
|
591
|
+
});
|
|
592
|
+
}, []);
|
|
647
593
|
|
|
648
|
-
|
|
649
|
-
|
|
594
|
+
const onRowDragMove = useCallback(
|
|
595
|
+
(event: RowDragMoveEvent) => {
|
|
596
|
+
if (startDragYRef.current === null) {
|
|
597
|
+
startDragYRef.current = event.y;
|
|
598
|
+
}
|
|
650
599
|
|
|
651
|
-
|
|
652
|
-
const
|
|
653
|
-
if (
|
|
654
|
-
|
|
600
|
+
const yDiff = event.y - startDragYRef.current;
|
|
601
|
+
const data = event.overNode?.data;
|
|
602
|
+
if (data) {
|
|
603
|
+
clearHighlightRowClasses();
|
|
604
|
+
document.querySelectorAll(`[row-id='${data.id}']`)?.forEach((el) => {
|
|
605
|
+
el.classList.add(yDiff < 0 ? 'ag-row-highlight-above' : 'ag-row-highlight-below');
|
|
606
|
+
});
|
|
655
607
|
}
|
|
656
|
-
}
|
|
657
|
-
|
|
608
|
+
},
|
|
609
|
+
[clearHighlightRowClasses],
|
|
610
|
+
);
|
|
658
611
|
|
|
659
612
|
const onRowDragEnd = useCallback(
|
|
660
|
-
(event: RowDragEndEvent) => {
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
const moved = event.node.data;
|
|
675
|
-
const target = event.overNode?.data;
|
|
676
|
-
moved.id !== target?.id && //moved over a different row
|
|
677
|
-
event.node.rowIndex != targetIndex && //moved to a different index
|
|
678
|
-
params.onRowDragEnd &&
|
|
679
|
-
(await params.onRowDragEnd(moved, target, targetIndex));
|
|
613
|
+
(event: RowDragEndEvent<TData>) => {
|
|
614
|
+
clearHighlightRowClasses();
|
|
615
|
+
if (!params.onRowDragEnd || startDragYRef.current === null) {
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
const yDiff = event.y - startDragYRef.current;
|
|
619
|
+
startDragYRef.current = null;
|
|
620
|
+
if (event.node.rowIndex != null) {
|
|
621
|
+
const movedRow = event.node.data;
|
|
622
|
+
const targetRow = event.overNode?.data;
|
|
623
|
+
if (!movedRow || !targetRow || movedRow === targetRow || yDiff === 0) {
|
|
624
|
+
return;
|
|
680
625
|
}
|
|
681
|
-
|
|
682
|
-
}
|
|
626
|
+
void params.onRowDragEnd({ movedRow, targetRow, direction: yDiff > 0 ? 1 : -1 });
|
|
627
|
+
}
|
|
683
628
|
},
|
|
684
|
-
[params],
|
|
629
|
+
[params, clearHighlightRowClasses],
|
|
685
630
|
);
|
|
686
631
|
|
|
687
632
|
// This is setting a ref in the GridContext so won't be triggering an update loop
|
|
688
633
|
setOnCellEditingComplete(params.onCellEditingComplete);
|
|
689
634
|
|
|
690
635
|
const headerRowCount = columnDefs.some((c) => (c as any).children) ? 2 : 1;
|
|
691
|
-
|
|
692
636
|
return (
|
|
693
637
|
<div
|
|
694
638
|
data-testid={dataTestId}
|
|
@@ -703,19 +647,23 @@ export const Grid = ({
|
|
|
703
647
|
{gridContextMenu.component}
|
|
704
648
|
<div style={{ flex: 1 }} ref={gridDivRef}>
|
|
705
649
|
<AgGridReact
|
|
650
|
+
theme={'legacy'}
|
|
651
|
+
rowSelection={
|
|
652
|
+
selectable
|
|
653
|
+
? {
|
|
654
|
+
enableClickSelection: false,
|
|
655
|
+
mode: rowSelection == 'single' ? 'singleRow' : 'multiRow',
|
|
656
|
+
}
|
|
657
|
+
: undefined
|
|
658
|
+
}
|
|
706
659
|
rowHeight={rowHeight}
|
|
707
660
|
animateRows={params.animateRows ?? false}
|
|
708
661
|
rowClassRules={params.rowClassRules}
|
|
709
662
|
getRowId={(params) => `${params.data.id}`}
|
|
710
|
-
suppressRowClickSelection={true}
|
|
711
|
-
rowSelection={rowSelection}
|
|
712
|
-
suppressBrowserResizeObserver={true}
|
|
713
663
|
onGridSizeChanged={onGridSizeChanged}
|
|
714
664
|
suppressColumnVirtualisation={suppressColumnVirtualization}
|
|
715
665
|
suppressClickEdit={true}
|
|
716
|
-
onColumnVisible={
|
|
717
|
-
setInitialContentSize();
|
|
718
|
-
}}
|
|
666
|
+
onColumnVisible={setInitialContentSize}
|
|
719
667
|
onRowDataUpdated={onRowDataChanged}
|
|
720
668
|
onCellKeyDown={onCellKeyPress}
|
|
721
669
|
onCellClicked={onCellClicked}
|
|
@@ -753,12 +701,36 @@ export const Grid = ({
|
|
|
753
701
|
preventDefaultOnContextMenu={true}
|
|
754
702
|
onCellContextMenu={gridContextMenu.cellContextMenu}
|
|
755
703
|
rowDragText={params.rowDragText}
|
|
704
|
+
onRowDragCancel={clearHighlightRowClasses}
|
|
756
705
|
onRowDragMove={onRowDragMove}
|
|
757
706
|
onRowDragEnd={onRowDragEnd}
|
|
758
|
-
onRowDragLeave={onRowDragLeave}
|
|
759
707
|
suppressCellFocus={params.suppressCellFocus}
|
|
760
708
|
pinnedTopRowData={params.pinnedTopRowData}
|
|
761
709
|
pinnedBottomRowData={params.pinnedBottomRowData}
|
|
710
|
+
selectionColumnDef={{
|
|
711
|
+
rowDrag: !!params.onRowDragEnd,
|
|
712
|
+
minWidth: selectable && params.onRowDragEnd ? 76 : 48,
|
|
713
|
+
maxWidth: selectable && params.onRowDragEnd ? 76 : 48,
|
|
714
|
+
pinned: selectColumnPinned,
|
|
715
|
+
headerComponentParams: {
|
|
716
|
+
exportable: false,
|
|
717
|
+
},
|
|
718
|
+
headerClass: clsx('ag-header-hide-default-select', params.onRowDragEnd && 'ag-header-select-draggable'),
|
|
719
|
+
headerComponent: rowSelection == 'multiple' ? GridHeaderSelect : undefined,
|
|
720
|
+
suppressHeaderKeyboardEvent: (e) => {
|
|
721
|
+
if (!selectable) return false;
|
|
722
|
+
if ((e.event.key === 'Enter' || e.event.key === ' ') && !e.event.repeat) {
|
|
723
|
+
if (isEmpty(e.api.getSelectedRows())) {
|
|
724
|
+
e.api.selectAll('filtered');
|
|
725
|
+
} else {
|
|
726
|
+
e.api.deselectAll();
|
|
727
|
+
}
|
|
728
|
+
return true;
|
|
729
|
+
}
|
|
730
|
+
return false;
|
|
731
|
+
},
|
|
732
|
+
onCellClicked: clickInputWhenContainingCellClicked,
|
|
733
|
+
}}
|
|
762
734
|
/>
|
|
763
735
|
</div>
|
|
764
736
|
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ColDef, ICellEditorParams, ICellRendererParams } from 'ag-grid-community';
|
|
1
|
+
import { ColDef, EditableCallback, ICellEditorParams, ICellRendererParams } from 'ag-grid-community';
|
|
2
2
|
import {
|
|
3
3
|
EditableCallbackParams,
|
|
4
4
|
SuppressKeyboardEventParams,
|
|
@@ -92,12 +92,10 @@ export interface SAValueFormatterFunc<TData = any, TValue = any> {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
// This is so that typescript retains the row type to pass to the GridCells
|
|
95
|
-
// @ts-expect-error types
|
|
96
95
|
export interface ColDefT<TData extends GridBaseRow, ValueType = any> extends ColDef<TData, ValueType> {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
valueFormatter?: string | SAValueFormatterFunc<TData, ValueType>;
|
|
96
|
+
editable?: boolean | EditableCallback<TData, ValueType>;
|
|
97
|
+
valueGetter?: string | ValueGetterFunc<TData, ValueType>;
|
|
98
|
+
valueFormatter?: string | ValueFormatterFunc<TData, ValueType>;
|
|
101
99
|
cellRenderer?:
|
|
102
100
|
| ((props: SAICellRendererParams<TData, ValueType>) => ReactElement | string | false | null | undefined)
|
|
103
101
|
| string;
|
|
@@ -39,7 +39,7 @@ export const MenuHeaderItem = (title: string) => {
|
|
|
39
39
|
|
|
40
40
|
export type SelectOption = null | string | FinalSelectOption;
|
|
41
41
|
|
|
42
|
-
export interface GridFormDropDownProps<TData extends GridBaseRow, TValue> extends CellEditorCommon {
|
|
42
|
+
export interface GridFormDropDownProps<TData extends GridBaseRow, TValue = any> extends CellEditorCommon {
|
|
43
43
|
// This overrides CellEditorCommon to provide some common class options
|
|
44
44
|
className?: // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
|
45
45
|
| 'GridPopoverEditDropDown-containerSmall'
|
|
@@ -67,7 +67,11 @@ const BooleanCellRenderer = (props: CustomCellEditorProps) => {
|
|
|
67
67
|
};
|
|
68
68
|
|
|
69
69
|
export interface GridEditBooleanEditorProps<TData extends GridBaseRow> extends CellEditorCommon {
|
|
70
|
-
onClick: (props: {
|
|
70
|
+
onClick: (props: {
|
|
71
|
+
selectedRows: TData[];
|
|
72
|
+
selectedRowIds: TData['id'][];
|
|
73
|
+
checked: boolean;
|
|
74
|
+
}) => Promise<boolean> | boolean;
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
export const GridEditBoolean = <TData extends GridBaseRow>(
|
package/src/components/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export * from './clickInputWhenContainingCellClicked';
|
|
2
1
|
export * from './ComponentLoadingWrapper';
|
|
3
2
|
export * from './Grid';
|
|
4
3
|
export * from './GridCell';
|
|
@@ -7,7 +6,6 @@ export * from './GridCellMultiEditor';
|
|
|
7
6
|
export * from './GridCellMultiSelectClassRules';
|
|
8
7
|
export * from './gridFilter';
|
|
9
8
|
export * from './gridForm';
|
|
10
|
-
export * from './gridHeader';
|
|
11
9
|
export * from './gridHook';
|
|
12
10
|
export * from './GridIcon';
|
|
13
11
|
export * from './GridLoadableCell';
|
|
@@ -45,7 +45,7 @@ export interface GridContextType<TData extends GridBaseRow> {
|
|
|
45
45
|
autoSizeColumns: (props?: AutoSizeColumnsProps) => AutoSizeColumnsResult;
|
|
46
46
|
sizeColumnsToFit: () => void;
|
|
47
47
|
cancelEdit: () => void;
|
|
48
|
-
startCellEditing: ({ rowId, colId }: { rowId: number; colId: string }) => void
|
|
48
|
+
startCellEditing: ({ rowId, colId }: { rowId: number; colId: string }) => Promise<void>;
|
|
49
49
|
stopEditing: () => void;
|
|
50
50
|
updatingCells: (
|
|
51
51
|
props: { selectedRows: GridBaseRow[]; field?: string },
|
|
@@ -167,7 +167,8 @@ export const GridContext = createContext<GridContextType<any>>({
|
|
|
167
167
|
cancelEdit: () => {
|
|
168
168
|
console.error('no context provider for cancelEdit');
|
|
169
169
|
},
|
|
170
|
-
|
|
170
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
171
|
+
startCellEditing: async () => {
|
|
171
172
|
console.error('no context provider for startCellEditing');
|
|
172
173
|
},
|
|
173
174
|
stopEditing: () => {
|