@linzjs/step-ag-grid 7.10.1 → 7.11.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/dist/index.js +79 -29
- package/dist/index.js.map +1 -1
- package/dist/src/components/Grid.d.ts +1 -0
- package/dist/src/contexts/GridContext.d.ts +3 -1
- package/dist/step-ag-grid.esm.js +79 -29
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Grid.tsx +34 -6
- package/src/contexts/GridContext.tsx +10 -5
- package/src/contexts/GridContextProvider.tsx +22 -17
- package/src/stories/grid/GridPopoutBearing.stories.tsx +1 -0
- package/src/stories/grid/GridReadOnly.stories.tsx +1 -0
- package/src/utils/bearing.ts +2 -2
package/package.json
CHANGED
package/src/components/Grid.tsx
CHANGED
|
@@ -34,6 +34,7 @@ export interface GridProps {
|
|
|
34
34
|
animateRows?: boolean;
|
|
35
35
|
rowClassRules?: GridOptions["rowClassRules"];
|
|
36
36
|
rowSelection?: "single" | "multiple";
|
|
37
|
+
autoSelectFirstRow?: boolean;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
/**
|
|
@@ -48,6 +49,7 @@ export const Grid = (params: GridProps): JSX.Element => {
|
|
|
48
49
|
selectRowsById,
|
|
49
50
|
ensureSelectedRowIsVisible,
|
|
50
51
|
sizeColumnsToFit,
|
|
52
|
+
setExternallySelectedItemsAreInSync,
|
|
51
53
|
} = useContext(GridContext);
|
|
52
54
|
const { checkUpdating } = useContext(GridUpdatingContext);
|
|
53
55
|
|
|
@@ -56,6 +58,22 @@ export const Grid = (params: GridProps): JSX.Element => {
|
|
|
56
58
|
const [staleGrid, setStaleGrid] = useState(false);
|
|
57
59
|
const postSortRows = usePostSortRowsHook({ setStaleGrid });
|
|
58
60
|
|
|
61
|
+
/**
|
|
62
|
+
* On data load select the first row of the grid if required.
|
|
63
|
+
*/
|
|
64
|
+
const hasSelectedFirstItem = useRef(false);
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (!gridReady || !params.autoSelectFirstRow || hasSelectedFirstItem.current || !params.rowData) return;
|
|
67
|
+
hasSelectedFirstItem.current = true;
|
|
68
|
+
if (isNotEmpty(params.rowData)) {
|
|
69
|
+
if (params.setExternalSelectedItems) {
|
|
70
|
+
params.setExternalSelectedItems([params.rowData[0]]);
|
|
71
|
+
} else {
|
|
72
|
+
selectRowsById([params.rowData[0].id]);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}, [gridReady, params, params.autoSelectFirstRow, params.rowData, selectRowsById]);
|
|
76
|
+
|
|
59
77
|
/**
|
|
60
78
|
* AgGrid checkbox select does not pass clicks within cell but not on the checkbox to checkbox.
|
|
61
79
|
* This passes the event to the checkbox when you click anywhere in the cell.
|
|
@@ -71,7 +89,10 @@ export const Grid = (params: GridProps): JSX.Element => {
|
|
|
71
89
|
*/
|
|
72
90
|
const synchroniseExternalStateToGridSelection = useCallback(
|
|
73
91
|
({ api }: SelectionChangedEvent) => {
|
|
74
|
-
if (!params.externalSelectedItems || !params.setExternalSelectedItems)
|
|
92
|
+
if (!params.externalSelectedItems || !params.setExternalSelectedItems) {
|
|
93
|
+
setExternallySelectedItemsAreInSync(true);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
75
96
|
|
|
76
97
|
const selectedRows = api.getSelectedRows();
|
|
77
98
|
// We don't want to update selected Items if it hasn't changed to prevent excess renders
|
|
@@ -79,10 +100,13 @@ export const Grid = (params: GridProps): JSX.Element => {
|
|
|
79
100
|
params.externalSelectedItems.length != selectedRows.length ||
|
|
80
101
|
isNotEmpty(xorBy(selectedRows, params.externalSelectedItems, (row) => row.id))
|
|
81
102
|
) {
|
|
103
|
+
setExternallySelectedItemsAreInSync(false);
|
|
82
104
|
params.setExternalSelectedItems([...selectedRows]);
|
|
105
|
+
} else {
|
|
106
|
+
setExternallySelectedItemsAreInSync(true);
|
|
83
107
|
}
|
|
84
108
|
},
|
|
85
|
-
[params],
|
|
109
|
+
[params, setExternallySelectedItemsAreInSync],
|
|
86
110
|
);
|
|
87
111
|
|
|
88
112
|
/**
|
|
@@ -90,21 +114,25 @@ export const Grid = (params: GridProps): JSX.Element => {
|
|
|
90
114
|
* If new ids are selected scroll them into view.
|
|
91
115
|
*/
|
|
92
116
|
const synchroniseExternallySelectedItemsToGrid = useCallback(() => {
|
|
93
|
-
if (!gridReady
|
|
94
|
-
if (!params.externalSelectedItems)
|
|
117
|
+
if (!gridReady) return;
|
|
118
|
+
if (!params.externalSelectedItems) {
|
|
119
|
+
setExternallySelectedItemsAreInSync(true);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
95
122
|
|
|
96
123
|
const selectedIds = params.externalSelectedItems.map((row) => row.id) as number[];
|
|
97
124
|
const lastNewId = last(difference(selectedIds, lastSelectedIds.current));
|
|
98
125
|
if (lastNewId != null) ensureRowVisible(lastNewId);
|
|
99
126
|
lastSelectedIds.current = selectedIds;
|
|
100
127
|
selectRowsById(selectedIds);
|
|
101
|
-
|
|
128
|
+
setExternallySelectedItemsAreInSync(true);
|
|
129
|
+
}, [gridReady, params.externalSelectedItems, ensureRowVisible, selectRowsById, setExternallySelectedItemsAreInSync]);
|
|
102
130
|
|
|
103
131
|
/**
|
|
104
132
|
* Synchronise quick filter to grid
|
|
105
133
|
*/
|
|
106
134
|
const updateQuickFilter = useCallback(() => {
|
|
107
|
-
if (!gridReady
|
|
135
|
+
if (!gridReady) return;
|
|
108
136
|
if (params.quickFilter) {
|
|
109
137
|
setQuickFilter(internalQuickFilter);
|
|
110
138
|
return;
|
|
@@ -3,7 +3,7 @@ import { GridApi, RowNode } from "ag-grid-community";
|
|
|
3
3
|
import { GridBaseRow } from "../components/Grid";
|
|
4
4
|
|
|
5
5
|
export interface GridContextType {
|
|
6
|
-
gridReady:
|
|
6
|
+
gridReady: boolean;
|
|
7
7
|
setGridApi: (gridApi: GridApi | undefined) => void;
|
|
8
8
|
setQuickFilter: (quickFilter: string) => void;
|
|
9
9
|
editingCells: () => boolean;
|
|
@@ -26,13 +26,12 @@ export interface GridContextType {
|
|
|
26
26
|
tabDirection?: 1 | 0 | -1,
|
|
27
27
|
) => Promise<boolean>;
|
|
28
28
|
redrawRows: (rowNodes?: RowNode[]) => void;
|
|
29
|
+
setExternallySelectedItemsAreInSync: (inSync: boolean) => void;
|
|
30
|
+
waitForExternallySelectedItemsToBeInSync: () => Promise<void>;
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
export const GridContext = createContext<GridContextType>({
|
|
32
|
-
gridReady:
|
|
33
|
-
console.error("no context provider for gridReady");
|
|
34
|
-
return false;
|
|
35
|
-
},
|
|
34
|
+
gridReady: false,
|
|
36
35
|
setGridApi: () => {
|
|
37
36
|
console.error("no context provider for setGridApi");
|
|
38
37
|
},
|
|
@@ -89,4 +88,10 @@ export const GridContext = createContext<GridContextType>({
|
|
|
89
88
|
redrawRows: () => {
|
|
90
89
|
console.error("no context provider for redrawRows");
|
|
91
90
|
},
|
|
91
|
+
setExternallySelectedItemsAreInSync: () => {
|
|
92
|
+
console.error("no context provider for setExternallySelectedItemsAreInSync");
|
|
93
|
+
},
|
|
94
|
+
waitForExternallySelectedItemsToBeInSync: async () => {
|
|
95
|
+
console.error("no context provider for waitForExternallySelectedItemsToBeInSync");
|
|
96
|
+
},
|
|
92
97
|
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ReactElement, ReactNode, useContext, useRef } from "react";
|
|
1
|
+
import { ReactElement, ReactNode, useContext, useRef, useState } from "react";
|
|
2
2
|
import { GridApi, RowNode } from "ag-grid-community";
|
|
3
3
|
import { GridContext } from "./GridContext";
|
|
4
4
|
import { delay, difference, isEmpty, last, sortBy } from "lodash-es";
|
|
5
|
-
import { isNotEmpty } from "../utils/util";
|
|
5
|
+
import { isNotEmpty, wait } from "../utils/util";
|
|
6
6
|
import { GridUpdatingContext } from "./GridUpdatingContext";
|
|
7
7
|
import { GridBaseRow } from "../components/Grid";
|
|
8
8
|
|
|
@@ -17,21 +17,14 @@ interface GridContextProps {
|
|
|
17
17
|
*/
|
|
18
18
|
export const GridContextProvider = (props: GridContextProps): ReactElement => {
|
|
19
19
|
const { modifyUpdating } = useContext(GridUpdatingContext);
|
|
20
|
-
const
|
|
20
|
+
const [gridApi, _setGridApi] = useState<GridApi>();
|
|
21
|
+
const [gridReady, setGridReady] = useState(false);
|
|
21
22
|
const idsBeforeUpdate = useRef<number[]>([]);
|
|
23
|
+
const externallySelectedItemsAreInSync = useRef(false);
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
* and thus will need to check grid is ready before calling.
|
|
27
|
-
*/
|
|
28
|
-
const gridReady = () => gridApiRef.current != null;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Set current ref to grid api.
|
|
32
|
-
*/
|
|
33
|
-
const setGridApi = (_gridApi: GridApi | undefined) => {
|
|
34
|
-
gridApiRef.current = _gridApi;
|
|
25
|
+
const setGridApi = (gridApi: GridApi | undefined) => {
|
|
26
|
+
_setGridApi(gridApi);
|
|
27
|
+
setGridReady(!!gridApi);
|
|
35
28
|
};
|
|
36
29
|
|
|
37
30
|
/**
|
|
@@ -47,7 +40,6 @@ export const GridContextProvider = (props: GridContextProps): ReactElement => {
|
|
|
47
40
|
if (!noApiFn) {
|
|
48
41
|
noApiFn = (() => {}) as () => R;
|
|
49
42
|
}
|
|
50
|
-
const gridApi = gridApiRef.current;
|
|
51
43
|
return gridApi ? hasApiFn(gridApi) : noApiFn();
|
|
52
44
|
};
|
|
53
45
|
|
|
@@ -121,7 +113,7 @@ export const GridContextProvider = (props: GridContextProps): ReactElement => {
|
|
|
121
113
|
rowIds: number[] | undefined,
|
|
122
114
|
select: boolean,
|
|
123
115
|
flash: boolean,
|
|
124
|
-
retryCount =
|
|
116
|
+
retryCount = 15, // We retry for approximately 5x200ms=1s
|
|
125
117
|
) => {
|
|
126
118
|
return gridApiOp((gridApi) => {
|
|
127
119
|
const rowNodes = rowIds ? _rowIdsToNodes(rowIds) : _getNewNodes();
|
|
@@ -302,6 +294,17 @@ export const GridContextProvider = (props: GridContextProps): ReactElement => {
|
|
|
302
294
|
});
|
|
303
295
|
};
|
|
304
296
|
|
|
297
|
+
const setExternallySelectedItemsAreInSync = (inSync: boolean) => {
|
|
298
|
+
externallySelectedItemsAreInSync.current = inSync;
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
const waitForExternallySelectedItemsToBeInSync = async () => {
|
|
302
|
+
// Wait for up to 5 seconds
|
|
303
|
+
for (let i = 0; i < 5000 / 200 && !externallySelectedItemsAreInSync.current; i++) {
|
|
304
|
+
await wait(200);
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
|
|
305
308
|
return (
|
|
306
309
|
<GridContext.Provider
|
|
307
310
|
value={{
|
|
@@ -323,6 +326,8 @@ export const GridContextProvider = (props: GridContextProps): ReactElement => {
|
|
|
323
326
|
stopEditing,
|
|
324
327
|
updatingCells,
|
|
325
328
|
redrawRows,
|
|
329
|
+
setExternallySelectedItemsAreInSync,
|
|
330
|
+
waitForExternallySelectedItemsToBeInSync,
|
|
326
331
|
}}
|
|
327
332
|
>
|
|
328
333
|
{props.children}
|
|
@@ -89,6 +89,7 @@ const GridReadOnlyTemplate: ComponentStory<typeof Grid> = (props: GridProps) =>
|
|
|
89
89
|
{ id: 1002, bearing: null, bearingCorrection: 355.1 },
|
|
90
90
|
{ id: 1003, bearing: null, bearingCorrection: 0 },
|
|
91
91
|
{ id: 1004, bearing: 5.0, bearingCorrection: "1.00500" },
|
|
92
|
+
{ id: 1005, bearing: null, bearingCorrection: "0E-12" },
|
|
92
93
|
] as ITestRow[]);
|
|
93
94
|
|
|
94
95
|
return (
|
package/src/utils/bearing.ts
CHANGED
|
@@ -14,9 +14,9 @@ export const bearingCorrectionValueFormatter = (params: ValueFormatterParams): s
|
|
|
14
14
|
return "–";
|
|
15
15
|
}
|
|
16
16
|
if (typeof value === "string") {
|
|
17
|
-
return convertDDToDMS(bearingNumberParser(value), true,
|
|
17
|
+
return convertDDToDMS(bearingNumberParser(value), true, true);
|
|
18
18
|
}
|
|
19
|
-
return convertDDToDMS(value, true,
|
|
19
|
+
return convertDDToDMS(value, true, true);
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
export const bearingNumberParser = (value: string): number | null => {
|