@linzjs/step-ag-grid 13.5.1 → 14.0.1
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 +12 -7
- package/dist/index.css +33 -3
- package/dist/src/components/Grid.d.ts +21 -1
- package/dist/src/components/GridCellMultiEditor.d.ts +4 -1
- package/dist/src/components/GridLoadableCell.d.ts +1 -5
- package/dist/src/contexts/GridContext.d.ts +5 -0
- package/dist/src/react-menu3/components/ControlledMenu.d.ts +1 -1
- package/dist/src/react-menu3/components/FocusableItem.d.ts +1 -1
- package/dist/src/react-menu3/components/Menu.d.ts +1 -1
- package/dist/src/react-menu3/components/MenuButton.d.ts +1 -1
- package/dist/src/react-menu3/components/MenuDivider.d.ts +1 -1
- package/dist/src/react-menu3/components/MenuGroup.d.ts +1 -1
- package/dist/src/react-menu3/components/MenuHeader.d.ts +1 -1
- package/dist/src/react-menu3/components/MenuItem.d.ts +1 -1
- package/dist/src/react-menu3/components/MenuRadioGroup.d.ts +1 -1
- package/dist/src/react-menu3/components/SubMenu.d.ts +1 -1
- package/dist/src/react-menu3/utils/utils.d.ts +1 -1
- package/dist/step-ag-grid.esm.js +3383 -625
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +34 -34
- package/src/components/ComponentLoadingWrapper.tsx +1 -13
- package/src/components/Grid.tsx +87 -13
- package/src/components/GridCell.tsx +20 -19
- package/src/components/GridCellMultiEditor.tsx +9 -27
- package/src/components/GridLoadableCell.tsx +5 -10
- package/src/components/GridPopoverHook.tsx +1 -11
- package/src/components/gridForm/GridFormPopoverMenu.tsx +2 -1
- package/src/components/gridPopoverEdit/GridPopoverEditBearing.ts +0 -2
- package/src/components/gridPopoverEdit/GridPopoverMenu.tsx +1 -1
- package/src/components/gridRender/GridRenderPopoutMenuCell.tsx +2 -1
- package/src/contexts/GridContext.tsx +7 -1
- package/src/contexts/GridContextProvider.tsx +18 -6
- package/src/stories/grid/GridFilterButtons.stories.tsx +8 -2
- package/src/stories/grid/GridNonEditableRow.stories.tsx +0 -8
- package/src/stories/grid/GridPopoutEditGeneric.stories.tsx +0 -3
- package/src/stories/grid/GridPopoutEditGenericTextArea.stories.tsx +1 -7
- package/src/stories/grid/GridPopoverEditBearing.stories.tsx +0 -2
- package/src/stories/grid/GridPopoverEditDropDown.stories.tsx +0 -15
- package/src/stories/grid/GridPopoverEditMultiSelect.stories.tsx +0 -6
- package/src/stories/grid/GridReadOnly.stories.tsx +3 -24
- package/src/stories/grid/interactions/GridKeyboardInteractions.stories.tsx +0 -8
- package/src/styles/ComponentLoadingWrapper.scss +9 -0
- package/src/styles/Grid.scss +5 -0
- package/src/styles/GridCell.scss +12 -0
- package/src/styles/GridLoadableCell.scss +1 -0
- package/src/styles/GridPopoverMenu.scss +3 -2
- package/src/styles/index.scss +2 -0
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": "14.0.1",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"aggrid",
|
|
8
8
|
"ag-grid",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"access": "public"
|
|
25
25
|
},
|
|
26
26
|
"engines": {
|
|
27
|
-
"node": ">=
|
|
27
|
+
"node": ">=16"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"@linzjs/lui": ">=17",
|
|
@@ -82,10 +82,10 @@
|
|
|
82
82
|
]
|
|
83
83
|
},
|
|
84
84
|
"devDependencies": {
|
|
85
|
-
"@rollup/plugin-commonjs": "^
|
|
85
|
+
"@rollup/plugin-commonjs": "^25.0.0",
|
|
86
86
|
"@rollup/plugin-json": "^6.0.0",
|
|
87
|
-
"@rollup/plugin-node-resolve": "^15.0.
|
|
88
|
-
"@semantic-release/changelog": "^6.0.
|
|
87
|
+
"@rollup/plugin-node-resolve": "^15.0.2",
|
|
88
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
89
89
|
"@semantic-release/git": "^10.0.1",
|
|
90
90
|
"@storybook/addon-essentials": "^6.5.16",
|
|
91
91
|
"@storybook/addon-interactions": "^6.5.16",
|
|
@@ -96,62 +96,62 @@
|
|
|
96
96
|
"@storybook/react": "^6.5.16",
|
|
97
97
|
"@storybook/test-runner": "^0.9.4",
|
|
98
98
|
"@storybook/testing-library": "^0.0.13",
|
|
99
|
-
"@testing-library/dom": "^
|
|
99
|
+
"@testing-library/dom": "^9.3.0",
|
|
100
100
|
"@testing-library/jest-dom": "^5.16.5",
|
|
101
101
|
"@testing-library/react": "^12.1.5",
|
|
102
102
|
"@testing-library/user-event": "^13.5.0",
|
|
103
|
-
"@trivago/prettier-plugin-sort-imports": "^4.
|
|
103
|
+
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
|
|
104
104
|
"@types/debounce-promise": "^3.1.6",
|
|
105
|
-
"@types/jest": "^29.
|
|
106
|
-
"@types/lodash-es": "^4.17.
|
|
107
|
-
"@types/node": "^
|
|
108
|
-
"@types/react": "^17.0.
|
|
109
|
-
"@types/react-dom": "^17.0.
|
|
110
|
-
"@types/uuid": "^9.0.
|
|
111
|
-
"@typescript-eslint/parser": "^5.
|
|
112
|
-
"babel-jest": "^29.
|
|
105
|
+
"@types/jest": "^29.5.1",
|
|
106
|
+
"@types/lodash-es": "^4.17.7",
|
|
107
|
+
"@types/node": "^20.2.3",
|
|
108
|
+
"@types/react": "^17.0.59",
|
|
109
|
+
"@types/react-dom": "^17.0.20",
|
|
110
|
+
"@types/uuid": "^9.0.1",
|
|
111
|
+
"@typescript-eslint/parser": "^5.59.7",
|
|
112
|
+
"babel-jest": "^29.5.0",
|
|
113
113
|
"babel-preset-react-app": "^10.0.1",
|
|
114
|
-
"chromatic": "^6.17.
|
|
114
|
+
"chromatic": "^6.17.4",
|
|
115
115
|
"conventional-changelog-conventionalcommits": "^5.0.0",
|
|
116
|
-
"eslint": "^8.
|
|
117
|
-
"eslint-config-prettier": "^8.
|
|
116
|
+
"eslint": "^8.41.0",
|
|
117
|
+
"eslint-config-prettier": "^8.8.0",
|
|
118
118
|
"eslint-config-react-app": "^7.0.1",
|
|
119
|
-
"eslint-plugin-deprecation": "^1.
|
|
119
|
+
"eslint-plugin-deprecation": "^1.4.1",
|
|
120
120
|
"eslint-plugin-import": "^2.27.5",
|
|
121
121
|
"eslint-plugin-jest": "^27.2.1",
|
|
122
122
|
"eslint-plugin-jsx-a11y": "^6.7.1",
|
|
123
123
|
"eslint-plugin-prettier": "^4.2.1",
|
|
124
124
|
"eslint-plugin-react": "^7.32.2",
|
|
125
125
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
126
|
-
"eslint-plugin-testing-library": "^5.
|
|
127
|
-
"jest": "^29.
|
|
128
|
-
"jest-canvas-mock": "^2.
|
|
129
|
-
"jest-environment-jsdom": "^29.
|
|
126
|
+
"eslint-plugin-testing-library": "^5.11.0",
|
|
127
|
+
"jest": "^29.5.0",
|
|
128
|
+
"jest-canvas-mock": "^2.5.1",
|
|
129
|
+
"jest-environment-jsdom": "^29.5.0",
|
|
130
130
|
"jest-expect-message": "^1.1.3",
|
|
131
|
-
"mkdirp": "^
|
|
131
|
+
"mkdirp": "^3.0.1",
|
|
132
132
|
"npm-run-all": "^4.1.5",
|
|
133
|
-
"postcss": "^8.4.
|
|
134
|
-
"postcss-loader": "^7.0
|
|
133
|
+
"postcss": "^8.4.23",
|
|
134
|
+
"postcss-loader": "^7.3.0",
|
|
135
135
|
"postcss-scss": "^4.0.6",
|
|
136
|
-
"prettier": "^2.8.
|
|
136
|
+
"prettier": "^2.8.8",
|
|
137
137
|
"react-app-polyfill": "^3.0.0",
|
|
138
138
|
"react-scripts": "^5.0.1",
|
|
139
|
-
"rollup": "^3.
|
|
139
|
+
"rollup": "^3.23.0",
|
|
140
140
|
"rollup-plugin-copy": "^3.4.0",
|
|
141
141
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
142
142
|
"rollup-plugin-postcss": "^4.0.2",
|
|
143
143
|
"rollup-plugin-typescript2": "^0.34.1",
|
|
144
|
-
"sass": "^1.
|
|
145
|
-
"sass-loader": "^13.
|
|
144
|
+
"sass": "^1.62.1",
|
|
145
|
+
"sass-loader": "^13.3.0",
|
|
146
146
|
"semantic-release": "^19.0.5",
|
|
147
|
-
"style-loader": "^3.3.
|
|
147
|
+
"style-loader": "^3.3.3",
|
|
148
148
|
"stylelint": "^14.16.1",
|
|
149
149
|
"stylelint-config-prettier": "^9.0.4",
|
|
150
150
|
"stylelint-config-recommended-scss": "^8.0.0",
|
|
151
151
|
"stylelint-config-standard": "^29.0.0",
|
|
152
|
-
"stylelint-prettier": "
|
|
153
|
-
"stylelint-scss": "
|
|
154
|
-
"tsconfig-paths-webpack-plugin": "^4.0.
|
|
152
|
+
"stylelint-prettier": "3.0.0",
|
|
153
|
+
"stylelint-scss": "5.0.0",
|
|
154
|
+
"tsconfig-paths-webpack-plugin": "^4.0.1",
|
|
155
155
|
"typescript": "^4.9.5"
|
|
156
156
|
},
|
|
157
157
|
"babel": {
|
|
@@ -13,19 +13,7 @@ export const ComponentLoadingWrapper = (props: {
|
|
|
13
13
|
<LuiMiniSpinner size={22} divProps={{ role: "status", ["aria-label"]: "Loading", style: { padding: 16 } }} />
|
|
14
14
|
) : (
|
|
15
15
|
<div style={{ pointerEvents: props.saving ? "none" : "inherit" }} className={props.className}>
|
|
16
|
-
{props.saving &&
|
|
17
|
-
<div
|
|
18
|
-
style={{
|
|
19
|
-
position: "absolute",
|
|
20
|
-
left: 0,
|
|
21
|
-
top: 0,
|
|
22
|
-
bottom: 0,
|
|
23
|
-
right: 0,
|
|
24
|
-
backgroundColor: "rgba(64,64,64,0.1)",
|
|
25
|
-
zIndex: 1000,
|
|
26
|
-
}}
|
|
27
|
-
/>
|
|
28
|
-
)}
|
|
16
|
+
{props.saving && <div className={"ComponentLoadingWrapper-saveOverlay"} />}
|
|
29
17
|
{props.children}
|
|
30
18
|
</div>
|
|
31
19
|
);
|
package/src/components/Grid.tsx
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { CellClickedEvent, ColDef, 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
|
+
CellEvent,
|
|
6
|
+
FirstDataRenderedEvent,
|
|
7
|
+
GridReadyEvent,
|
|
8
|
+
GridSizeChangedEvent,
|
|
9
|
+
SelectionChangedEvent,
|
|
10
|
+
} from "ag-grid-community/dist/lib/events";
|
|
5
11
|
import { AgGridReact } from "ag-grid-react";
|
|
6
12
|
import clsx from "clsx";
|
|
7
13
|
import { difference, isEmpty, last, xorBy } from "lodash-es";
|
|
@@ -40,6 +46,24 @@ export interface GridProps {
|
|
|
40
46
|
onGridSizeChanged?: GridOptions["onGridSizeChanged"];
|
|
41
47
|
onFirstDataRendered?: GridOptions["onFirstDataRendered"];
|
|
42
48
|
suppressColumnVirtualization?: GridOptions["suppressColumnVirtualisation"];
|
|
49
|
+
/**
|
|
50
|
+
* When the grid is rendered using sizeColumns=="auto" this is called initially with the required container size to fit all content.
|
|
51
|
+
* This allows you set the size of the panel to fit perfectly.
|
|
52
|
+
*/
|
|
53
|
+
onContentSize?: (props: { width: number }) => void;
|
|
54
|
+
/**
|
|
55
|
+
* <ul>
|
|
56
|
+
* <li>"none" to use aggrid defaults.</li>
|
|
57
|
+
* <li>"fit" will adjust columns to fit within panel via min/max/initial sizing.
|
|
58
|
+
* <b>Note:</b> This is only really needed if you have auto-height columns which prevents "auto" from working.
|
|
59
|
+
* </li>
|
|
60
|
+
* <li>"auto" (default) will size columns based on their content but still obeying min/max sizing.</li>
|
|
61
|
+
* <li>"auto-skip-headers" same as auto but does not take headers into account.</li>
|
|
62
|
+
* </ul>
|
|
63
|
+
*
|
|
64
|
+
* If you want to stretch to container width if width is greater than the container add a flex column.
|
|
65
|
+
*/
|
|
66
|
+
sizeColumns?: "fit" | "auto" | "auto-skip-headers" | "none";
|
|
43
67
|
}
|
|
44
68
|
|
|
45
69
|
/**
|
|
@@ -50,6 +74,7 @@ export const Grid = ({
|
|
|
50
74
|
rowSelection = "multiple",
|
|
51
75
|
suppressColumnVirtualization = true,
|
|
52
76
|
theme = "ag-theme-alpine",
|
|
77
|
+
sizeColumns = "auto",
|
|
53
78
|
...params
|
|
54
79
|
}: GridProps): JSX.Element => {
|
|
55
80
|
const {
|
|
@@ -60,6 +85,7 @@ export const Grid = ({
|
|
|
60
85
|
selectRowsById,
|
|
61
86
|
focusByRowById,
|
|
62
87
|
ensureSelectedRowIsVisible,
|
|
88
|
+
autoSizeAllColumns,
|
|
63
89
|
sizeColumnsToFit,
|
|
64
90
|
externallySelectedItemsAreInSync,
|
|
65
91
|
setExternallySelectedItemsAreInSync,
|
|
@@ -72,6 +98,27 @@ export const Grid = ({
|
|
|
72
98
|
const [staleGrid, setStaleGrid] = useState(false);
|
|
73
99
|
const postSortRows = usePostSortRowsHook({ setStaleGrid });
|
|
74
100
|
|
|
101
|
+
const setInitialContentSize = useCallback(() => {
|
|
102
|
+
const skipHeaders = sizeColumns === "auto-skip-headers";
|
|
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
|
+
params.onContentSize && result && params.onContentSize(result);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (sizeColumns !== "none") {
|
|
110
|
+
sizeColumnsToFit();
|
|
111
|
+
}
|
|
112
|
+
}, [autoSizeAllColumns, params, sizeColumns, sizeColumnsToFit]);
|
|
113
|
+
|
|
114
|
+
const onFirstDataRendered = useCallback(
|
|
115
|
+
(event: FirstDataRenderedEvent) => {
|
|
116
|
+
params.onFirstDataRendered && params.onFirstDataRendered(event);
|
|
117
|
+
setInitialContentSize();
|
|
118
|
+
},
|
|
119
|
+
[params, setInitialContentSize],
|
|
120
|
+
);
|
|
121
|
+
|
|
75
122
|
/**
|
|
76
123
|
* On data load select the first row of the grid if required.
|
|
77
124
|
*/
|
|
@@ -187,11 +234,10 @@ export const Grid = ({
|
|
|
187
234
|
colId: "selection",
|
|
188
235
|
editable: false,
|
|
189
236
|
minWidth: 42,
|
|
237
|
+
maxWidth: 42,
|
|
190
238
|
headerComponentParams: {
|
|
191
239
|
exportable: false,
|
|
192
240
|
},
|
|
193
|
-
maxWidth: 42,
|
|
194
|
-
suppressSizeToFit: true,
|
|
195
241
|
checkboxSelection: true,
|
|
196
242
|
headerComponent: rowSelection === "multiple" ? GridHeaderSelect : null,
|
|
197
243
|
suppressHeaderKeyboardEvent: (e) => {
|
|
@@ -227,6 +273,21 @@ export const Grid = ({
|
|
|
227
273
|
[dataTestId, setApis, synchroniseExternallySelectedItemsToGrid],
|
|
228
274
|
);
|
|
229
275
|
|
|
276
|
+
/**
|
|
277
|
+
* When the grid is being initialized the data may be empty.
|
|
278
|
+
* This will resize columns when we have at least one row.
|
|
279
|
+
*/
|
|
280
|
+
const previousRowDataLength = useRef(0);
|
|
281
|
+
useEffect(() => {
|
|
282
|
+
const length = params.rowData?.length ?? 0;
|
|
283
|
+
if (previousRowDataLength.current !== length) {
|
|
284
|
+
if (previousRowDataLength.current === 0 && length > 0) {
|
|
285
|
+
setInitialContentSize();
|
|
286
|
+
}
|
|
287
|
+
previousRowDataLength.current = length;
|
|
288
|
+
}
|
|
289
|
+
}, [params.rowData?.length, setInitialContentSize]);
|
|
290
|
+
|
|
230
291
|
const onModelUpdated = useCallback((event: ModelUpdatedEvent) => {
|
|
231
292
|
event.api.getDisplayedRowCount() === 0 ? event.api.showNoRowsOverlay() : event.api.hideOverlay();
|
|
232
293
|
}, []);
|
|
@@ -299,12 +360,26 @@ export const Grid = ({
|
|
|
299
360
|
[startCellEditing],
|
|
300
361
|
);
|
|
301
362
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
sizeColumnsToFit();
|
|
306
|
-
}
|
|
307
|
-
|
|
363
|
+
const onGridSizeChanged = useCallback(
|
|
364
|
+
(event: GridSizeChangedEvent) => {
|
|
365
|
+
params.onGridSizeChanged && params.onGridSizeChanged(event);
|
|
366
|
+
sizeColumns !== "none" && sizeColumnsToFit();
|
|
367
|
+
},
|
|
368
|
+
[params, sizeColumns, sizeColumnsToFit],
|
|
369
|
+
);
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Once the grid has auto-sized we want to run fit to fit the grid in its container,
|
|
373
|
+
* but we don't want the non-flex auto-sized columns to "fit" size, so suppressSizeToFit is set to true.
|
|
374
|
+
*/
|
|
375
|
+
const columnDefsAdjusted = useMemo(
|
|
376
|
+
() =>
|
|
377
|
+
columnDefs.map((colDef) => ({
|
|
378
|
+
...colDef,
|
|
379
|
+
suppressSizeToFit: (sizeColumns === "auto" || sizeColumns === "auto-skip-headers") && !colDef.flex,
|
|
380
|
+
})),
|
|
381
|
+
[columnDefs, sizeColumns],
|
|
382
|
+
);
|
|
308
383
|
|
|
309
384
|
return (
|
|
310
385
|
<div
|
|
@@ -324,9 +399,8 @@ export const Grid = ({
|
|
|
324
399
|
suppressRowClickSelection={true}
|
|
325
400
|
rowSelection={rowSelection}
|
|
326
401
|
suppressBrowserResizeObserver={true}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
onGridSizeChanged={params.onGridSizeChanged ?? sizeColumnsToFit}
|
|
402
|
+
onFirstDataRendered={onFirstDataRendered}
|
|
403
|
+
onGridSizeChanged={onGridSizeChanged}
|
|
330
404
|
suppressColumnVirtualisation={suppressColumnVirtualization}
|
|
331
405
|
suppressClickEdit={true}
|
|
332
406
|
onCellKeyPress={onCellKeyPress}
|
|
@@ -334,7 +408,7 @@ export const Grid = ({
|
|
|
334
408
|
onCellDoubleClicked={onCellDoubleClick}
|
|
335
409
|
onCellEditingStarted={refreshSelectedRows}
|
|
336
410
|
domLayout={params.domLayout}
|
|
337
|
-
columnDefs={
|
|
411
|
+
columnDefs={columnDefsAdjusted}
|
|
338
412
|
rowData={params.rowData}
|
|
339
413
|
noRowsOverlayComponent={GridNoRowsOverlay}
|
|
340
414
|
noRowsOverlayComponentParams={{ rowData: params.rowData, noRowsOverlayText: params.noRowsOverlayText }}
|
|
@@ -34,25 +34,25 @@ export const GridCellRenderer = (props: ICellRendererParams) => {
|
|
|
34
34
|
if (Array.isArray(warningText)) warningText = warningText.join("\n");
|
|
35
35
|
if (Array.isArray(infoText)) infoText = infoText.join("\n");
|
|
36
36
|
|
|
37
|
-
return (
|
|
38
|
-
<GridLoadableCell
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
return checkUpdating(colDef.field ?? colDef.colId ?? "", props.data.id) ? (
|
|
38
|
+
<GridLoadableCell />
|
|
39
|
+
) : (
|
|
40
|
+
<>
|
|
41
|
+
{!!warningText && (
|
|
42
|
+
<GridIcon icon={"ic_warning_outline"} title={typeof warningText === "string" ? warningText : "Warning"} />
|
|
43
|
+
)}
|
|
44
|
+
{!!infoText && <GridIcon icon={"ic_info_outline"} title={typeof infoText === "string" ? infoText : "Info"} />}
|
|
45
|
+
<div className={"GridCell-container"}>
|
|
46
|
+
{colDef.cellRendererParams?.originalCellRenderer ? (
|
|
47
|
+
<colDef.cellRendererParams.originalCellRenderer {...props} />
|
|
48
|
+
) : (
|
|
49
|
+
<span title={props.valueFormatted ?? undefined}>{props.valueFormatted}</span>
|
|
42
50
|
)}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
<span title={props.valueFormatted ?? undefined}>{props.valueFormatted}</span>
|
|
49
|
-
)}
|
|
50
|
-
</div>
|
|
51
|
-
{fnOrVar(colDef.editable, props) && rendererParams?.rightHoverElement && (
|
|
52
|
-
<div style={{ display: "flex", alignItems: "center" }}>{rendererParams?.rightHoverElement}</div>
|
|
53
|
-
)}
|
|
54
|
-
</>
|
|
55
|
-
</GridLoadableCell>
|
|
51
|
+
</div>
|
|
52
|
+
{fnOrVar(colDef.editable, props) && rendererParams?.rightHoverElement && (
|
|
53
|
+
<div className={"GridCell-hoverRight"}>{rendererParams?.rightHoverElement}</div>
|
|
54
|
+
)}
|
|
55
|
+
</>
|
|
56
56
|
);
|
|
57
57
|
};
|
|
58
58
|
|
|
@@ -119,9 +119,10 @@ export const GridCell = <RowType extends GridBaseRow, Props extends CellEditorCo
|
|
|
119
119
|
delete props.exportable;
|
|
120
120
|
|
|
121
121
|
return {
|
|
122
|
-
colId: props.field,
|
|
122
|
+
colId: props.field ?? props.field,
|
|
123
123
|
sortable: !!(props?.field || props?.valueGetter),
|
|
124
124
|
resizable: true,
|
|
125
|
+
minWidth: props.flex ? 150 : 48,
|
|
125
126
|
editable: props.editable ?? false,
|
|
126
127
|
...(custom?.editor && {
|
|
127
128
|
cellClassRules: GridCellMultiSelectClassRules,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { CellEditorSelectorResult
|
|
1
|
+
import { CellEditorSelectorResult } from "ag-grid-community/dist/lib/entities/colDef";
|
|
2
2
|
import { ICellEditorParams } from "ag-grid-community/dist/lib/interfaces/iCellEditor";
|
|
3
3
|
import { ComponentProps } from "react";
|
|
4
4
|
|
|
5
5
|
import { GridBaseRow } from "./Grid";
|
|
6
|
-
import { ColDefT, GenericCellEditorComponentWrapper,
|
|
6
|
+
import { ColDefT, GenericCellEditorComponentWrapper, GridCell } from "./GridCell";
|
|
7
7
|
import { GridCellMultiSelectClassRules } from "./GridCellMultiSelectClassRules";
|
|
8
|
-
import { GenericCellColDef } from "./gridRender
|
|
8
|
+
import { GenericCellColDef } from "./gridRender";
|
|
9
9
|
|
|
10
10
|
export const Editor = <FN extends (param: any) => JSX.Element>(props: {
|
|
11
11
|
multiEdit: boolean;
|
|
@@ -20,34 +20,16 @@ export interface RowCellEditorParams<RowType extends GridBaseRow> extends ICellE
|
|
|
20
20
|
data: RowType;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
*
|
|
23
|
+
/**
|
|
24
|
+
* Used to choose between cell editors based in data.
|
|
25
25
|
*/
|
|
26
26
|
export const GridCellMultiEditor = <RowType extends GridBaseRow>(
|
|
27
27
|
props: GenericCellColDef<RowType>,
|
|
28
28
|
cellEditorSelector: (params: RowCellEditorParams<RowType>) => CellEditorSelectorResult,
|
|
29
|
-
): ColDefT<RowType> =>
|
|
30
|
-
|
|
31
|
-
colId: props.colId ?? props.field,
|
|
32
|
-
field: props.field,
|
|
33
|
-
sortable: !!(props?.field || props?.valueGetter),
|
|
34
|
-
resizable: true,
|
|
35
|
-
editable: props.editable ?? true,
|
|
29
|
+
): ColDefT<RowType> =>
|
|
30
|
+
GridCell({
|
|
36
31
|
cellClassRules: GridCellMultiSelectClassRules,
|
|
37
32
|
cellEditorSelector,
|
|
38
|
-
|
|
39
|
-
// Default value formatter, otherwise react freaks out on objects
|
|
40
|
-
valueFormatter: (params: ValueFormatterParams) => {
|
|
41
|
-
if (params.value == null) return "–";
|
|
42
|
-
const types = ["number", "boolean", "string"];
|
|
43
|
-
if (types.includes(typeof params.value)) return `${params.value}`;
|
|
44
|
-
else return JSON.stringify(params.value);
|
|
45
|
-
},
|
|
33
|
+
editable: props.editable ?? true,
|
|
46
34
|
...props,
|
|
47
|
-
|
|
48
|
-
cellRendererParams: {
|
|
49
|
-
originalCellRenderer: props.cellRenderer,
|
|
50
|
-
...props.cellRendererParams,
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
};
|
|
35
|
+
});
|
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import clsx from "clsx";
|
|
2
|
-
|
|
3
1
|
import { LuiMiniSpinner } from "@linzjs/lui";
|
|
4
2
|
|
|
5
|
-
export const GridLoadableCell = (
|
|
6
|
-
<
|
|
7
|
-
{
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
props.children
|
|
11
|
-
)}
|
|
12
|
-
</div>
|
|
3
|
+
export const GridLoadableCell = () => (
|
|
4
|
+
<LuiMiniSpinner
|
|
5
|
+
size={22}
|
|
6
|
+
divProps={{ className: "GridLoadableCell-container", role: "status", "aria-label": "Loading" }}
|
|
7
|
+
/>
|
|
13
8
|
);
|
|
@@ -81,17 +81,7 @@ export const useGridPopoverHook = <RowType extends GridBaseRow>(props: GridPopov
|
|
|
81
81
|
closeMenuExclusionClassName={"ReactModal__Content"}
|
|
82
82
|
>
|
|
83
83
|
{saving && ( // This is the overlay that prevents editing when the editor is saving
|
|
84
|
-
<div
|
|
85
|
-
style={{
|
|
86
|
-
position: "absolute",
|
|
87
|
-
left: 0,
|
|
88
|
-
top: 0,
|
|
89
|
-
bottom: 0,
|
|
90
|
-
right: 0,
|
|
91
|
-
backgroundColor: "rgba(64,64,64,0.1)",
|
|
92
|
-
zIndex: 1000,
|
|
93
|
-
}}
|
|
94
|
-
/>
|
|
84
|
+
<div className={"ComponentLoadingWrapper-saveOverlay"} />
|
|
95
85
|
)}
|
|
96
86
|
{children}
|
|
97
87
|
<button
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isEmpty } from "lodash-es";
|
|
1
2
|
import { Fragment, useCallback, useEffect, useRef, useState } from "react";
|
|
2
3
|
|
|
3
4
|
import { useGridPopoverContext } from "../../contexts/GridPopoverContext";
|
|
@@ -123,7 +124,7 @@ export const GridFormPopoverMenu = <RowType extends GridBaseRow>(props: GridForm
|
|
|
123
124
|
return popoverWrapper(
|
|
124
125
|
<ComponentLoadingWrapper loading={!options} className={"GridFormPopupMenu"}>
|
|
125
126
|
<>
|
|
126
|
-
{options
|
|
127
|
+
{isEmpty(options) ? (
|
|
127
128
|
<MenuItem key={`GridPopoverMenu-empty`} className={"GridPopoverMenu-noOptions"} disabled={true}>
|
|
128
129
|
No actions
|
|
129
130
|
</MenuItem>
|
|
@@ -19,8 +19,6 @@ const GridPopoverEditBearingLike = <RowType extends GridBaseRow>(
|
|
|
19
19
|
): ColDefT<RowType> =>
|
|
20
20
|
GridCell(
|
|
21
21
|
{
|
|
22
|
-
initialWidth: 65,
|
|
23
|
-
maxWidth: 150,
|
|
24
22
|
valueFormatter: (params: ValueFormatterParams) => props.editorParams?.formatValue(params.value) ?? "",
|
|
25
23
|
...colDef,
|
|
26
24
|
},
|
|
@@ -18,7 +18,7 @@ export const GridPopoverMenu = <RowType extends GridBaseRow>(
|
|
|
18
18
|
width: 40,
|
|
19
19
|
editable: colDef.editable != null ? colDef.editable : true,
|
|
20
20
|
exportable: false,
|
|
21
|
-
cellStyle: { justifyContent: "center" },
|
|
21
|
+
cellStyle: { flex: 1, justifyContent: "center" },
|
|
22
22
|
cellRenderer: GridRenderPopoutMenuCell,
|
|
23
23
|
...colDef,
|
|
24
24
|
cellRendererParams: {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ICellRendererParams } from "ag-grid-community";
|
|
2
|
+
import clsx from "clsx";
|
|
2
3
|
|
|
3
4
|
import { LuiIcon } from "@linzjs/lui";
|
|
4
5
|
|
|
@@ -12,7 +13,7 @@ export const GridRenderPopoutMenuCell = (props: ICellRendererParams) => {
|
|
|
12
13
|
name={"ic_more_vert"}
|
|
13
14
|
alt={"More actions"}
|
|
14
15
|
size={"md"}
|
|
15
|
-
className={disabled
|
|
16
|
+
className={clsx("GridPopoutMenu-burger", disabled && "GridPopoutMenu-burgerDisabled")}
|
|
16
17
|
/>
|
|
17
18
|
);
|
|
18
19
|
};
|
|
@@ -25,6 +25,7 @@ export interface GridContextType<RowType extends GridBaseRow> {
|
|
|
25
25
|
focusByRowById: (rowId: number) => void;
|
|
26
26
|
ensureRowVisible: (id: number | string) => boolean;
|
|
27
27
|
ensureSelectedRowIsVisible: () => void;
|
|
28
|
+
autoSizeAllColumns: (props?: { skipHeader?: boolean }) => { width: number } | null;
|
|
28
29
|
sizeColumnsToFit: () => void;
|
|
29
30
|
stopEditing: () => void;
|
|
30
31
|
updatingCells: (
|
|
@@ -111,8 +112,13 @@ export const GridContext = createContext<GridContextType<any>>({
|
|
|
111
112
|
ensureSelectedRowIsVisible: () => {
|
|
112
113
|
console.error("no context provider for ensureSelectedRowIsVisible");
|
|
113
114
|
},
|
|
115
|
+
autoSizeAllColumns: () => {
|
|
116
|
+
console.error("no context provider for autoSizeAllColumns");
|
|
117
|
+
return null;
|
|
118
|
+
},
|
|
114
119
|
sizeColumnsToFit: () => {
|
|
115
|
-
console.error("no context provider for
|
|
120
|
+
console.error("no context provider for autoSizeAllColumns");
|
|
121
|
+
return null;
|
|
116
122
|
},
|
|
117
123
|
editingCells: () => {
|
|
118
124
|
console.error("no context provider for editingCells");
|
|
@@ -2,7 +2,8 @@ import { ColDef, ColumnApi, GridApi, RowNode } from "ag-grid-community";
|
|
|
2
2
|
import { CellPosition } from "ag-grid-community/dist/lib/entities/cellPosition";
|
|
3
3
|
import { ValueFormatterParams } from "ag-grid-community/dist/lib/entities/colDef";
|
|
4
4
|
import { CsvExportParams, ProcessCellForExportParams } from "ag-grid-community/dist/lib/interfaces/exportParams";
|
|
5
|
-
import
|
|
5
|
+
import debounce from "debounce-promise";
|
|
6
|
+
import { compact, defer, delay, difference, isEmpty, last, remove, sortBy, sumBy } from "lodash-es";
|
|
6
7
|
import { ReactElement, ReactNode, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
7
8
|
|
|
8
9
|
import { ColDefT, GridBaseRow } from "../components";
|
|
@@ -326,15 +327,25 @@ export const GridContextProvider = <RowType extends GridBaseRow>(props: GridCont
|
|
|
326
327
|
});
|
|
327
328
|
}, [gridApiOp]);
|
|
328
329
|
|
|
330
|
+
/**
|
|
331
|
+
* Resize columns to fit container
|
|
332
|
+
*/
|
|
333
|
+
const autoSizeAllColumns = useCallback((): { width: number } | null => {
|
|
334
|
+
if (columnApi) {
|
|
335
|
+
columnApi.autoSizeAllColumns();
|
|
336
|
+
return { width: sumBy(columnApi.getColumnState(), "width") };
|
|
337
|
+
}
|
|
338
|
+
return null;
|
|
339
|
+
}, [columnApi]);
|
|
340
|
+
|
|
329
341
|
/**
|
|
330
342
|
* Resize columns to fit container
|
|
331
343
|
*/
|
|
332
344
|
const sizeColumnsToFit = useCallback((): void => {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
}, [gridApiOp]);
|
|
345
|
+
if (gridApi) {
|
|
346
|
+
gridApi.sizeColumnsToFit();
|
|
347
|
+
}
|
|
348
|
+
}, [gridApi]);
|
|
338
349
|
|
|
339
350
|
const stopEditing = useCallback((): void => {
|
|
340
351
|
if (prePopupFocusedCell.current) {
|
|
@@ -523,6 +534,7 @@ export const GridContextProvider = <RowType extends GridBaseRow>(props: GridCont
|
|
|
523
534
|
ensureRowVisible,
|
|
524
535
|
ensureSelectedRowIsVisible,
|
|
525
536
|
sizeColumnsToFit,
|
|
537
|
+
autoSizeAllColumns,
|
|
526
538
|
stopEditing,
|
|
527
539
|
updatingCells,
|
|
528
540
|
redrawRows,
|
|
@@ -66,13 +66,19 @@ const GridFilterButtonsTemplate: ComponentStory<typeof Grid> = (props: GridProps
|
|
|
66
66
|
GridCell({
|
|
67
67
|
field: "desc",
|
|
68
68
|
headerName: "Description",
|
|
69
|
+
flex: 1,
|
|
69
70
|
}),
|
|
70
71
|
],
|
|
71
72
|
[],
|
|
72
73
|
);
|
|
73
74
|
|
|
74
75
|
const [rowData] = useState([
|
|
75
|
-
{
|
|
76
|
+
{
|
|
77
|
+
id: 1000,
|
|
78
|
+
position: "Tester",
|
|
79
|
+
age: 30,
|
|
80
|
+
desc: "Integration tester - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur a lectus neque. Nunc congue magna ut lorem pretium, vitae congue lorem malesuada. Etiam eget eleifend sapien, sed egestas felis. Aliquam ac augue sapien.",
|
|
81
|
+
},
|
|
76
82
|
{ id: 1001, position: "Developer", age: 12, desc: "Frontend developer" },
|
|
77
83
|
{ id: 1002, position: "Manager", age: 65, desc: "Technical Manager" },
|
|
78
84
|
{ id: 1003, position: "Tester", age: 30, desc: "E2E tester" },
|
|
@@ -102,7 +108,7 @@ const GridFilterButtonsTemplate: ComponentStory<typeof Grid> = (props: GridProps
|
|
|
102
108
|
]}
|
|
103
109
|
/>
|
|
104
110
|
</GridFilters>
|
|
105
|
-
<Grid {...props} columnDefs={columnDefs} rowData={rowData} />
|
|
111
|
+
<Grid {...props} columnDefs={columnDefs} rowData={rowData} sizeColumns={"auto-skip-headers"} />
|
|
106
112
|
</GridWrapper>
|
|
107
113
|
);
|
|
108
114
|
};
|
|
@@ -60,14 +60,10 @@ const GridNonEditableRowTemplate: ComponentStory<typeof Grid> = (props: GridProp
|
|
|
60
60
|
GridCell({
|
|
61
61
|
field: "id",
|
|
62
62
|
headerName: "Id",
|
|
63
|
-
initialWidth: 65,
|
|
64
|
-
maxWidth: 85,
|
|
65
63
|
}),
|
|
66
64
|
GridPopoverEditDropDown(
|
|
67
65
|
{
|
|
68
66
|
field: "position",
|
|
69
|
-
initialWidth: 65,
|
|
70
|
-
maxWidth: 150,
|
|
71
67
|
headerName: "Position",
|
|
72
68
|
},
|
|
73
69
|
{
|
|
@@ -82,15 +78,11 @@ const GridNonEditableRowTemplate: ComponentStory<typeof Grid> = (props: GridProp
|
|
|
82
78
|
GridCell({
|
|
83
79
|
field: "age",
|
|
84
80
|
headerName: "Age",
|
|
85
|
-
initialWidth: 65,
|
|
86
|
-
maxWidth: 85,
|
|
87
81
|
}),
|
|
88
82
|
GridPopoverTextArea(
|
|
89
83
|
{
|
|
90
84
|
field: "desc",
|
|
91
85
|
headerName: "Description",
|
|
92
|
-
initialWidth: 150,
|
|
93
|
-
maxWidth: 200,
|
|
94
86
|
},
|
|
95
87
|
{},
|
|
96
88
|
),
|