@linzjs/step-ag-grid 29.12.0 → 29.14.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.css +26 -2
- package/dist/src/components/Grid.d.ts +37 -67
- package/dist/src/components/GridCell.d.ts +2 -19
- package/dist/src/components/GridCellFiller.d.ts +1 -1
- package/dist/src/components/GridCellMultiEditor.d.ts +1 -2
- package/dist/src/components/GridPopoverHook.d.ts +1 -1
- package/dist/src/components/GridRangeSelectContextMenu.d.ts +10 -0
- package/dist/src/components/gridFilter/GridFilterButtons.d.ts +1 -1
- package/dist/src/components/gridFilter/useGridFilter.d.ts +1 -1
- package/dist/src/components/gridForm/GridFormDropDown.d.ts +2 -2
- package/dist/src/components/gridForm/GridFormEditBearing.d.ts +1 -1
- package/dist/src/components/gridForm/GridFormMessage.d.ts +1 -1
- package/dist/src/components/gridForm/GridFormMultiSelect.d.ts +1 -1
- package/dist/src/components/gridForm/GridFormMultiSelectGrid.d.ts +1 -1
- package/dist/src/components/gridForm/GridFormPopoverMenu.d.ts +3 -2
- package/dist/src/components/gridForm/GridFormSubComponentTextArea.d.ts +1 -1
- package/dist/src/components/gridForm/GridFormSubComponentTextInput.d.ts +1 -1
- package/dist/src/components/gridForm/GridFormTextArea.d.ts +1 -1
- package/dist/src/components/gridForm/GridFormTextInput.d.ts +1 -1
- package/dist/src/components/gridHook/useGridContextMenu.d.ts +13 -8
- package/dist/src/components/gridHook/useGridCopy.d.ts +15 -0
- package/dist/src/components/gridHook/useGridCopySettings.d.ts +11 -0
- package/dist/src/components/gridHook/useGridRangeSelection.d.ts +25 -0
- package/dist/src/components/gridPopoverEdit/GridButton.d.ts +1 -2
- package/dist/src/components/gridPopoverEdit/GridEditBoolean.d.ts +2 -2
- package/dist/src/components/gridPopoverEdit/GridPopoutEditMultiSelect.d.ts +2 -2
- package/dist/src/components/gridPopoverEdit/GridPopoutEditMultiSelectGrid.d.ts +2 -2
- package/dist/src/components/gridPopoverEdit/GridPopoverEditBearing.d.ts +4 -2
- package/dist/src/components/gridPopoverEdit/GridPopoverEditDropDown.d.ts +2 -2
- package/dist/src/components/gridPopoverEdit/GridPopoverMenu.d.ts +2 -2
- package/dist/src/components/gridPopoverEdit/GridPopoverMessage.d.ts +2 -2
- package/dist/src/components/gridPopoverEdit/GridPopoverTextArea.d.ts +2 -2
- package/dist/src/components/gridPopoverEdit/GridPopoverTextInput.d.ts +2 -2
- package/dist/src/components/gridRender/GridRenderGenericCell.d.ts +1 -2
- package/dist/src/components/index.d.ts +1 -0
- package/dist/src/components/types.d.ts +27 -0
- package/dist/src/contexts/GridContext.d.ts +13 -12
- package/dist/src/contexts/GridPopoverContext.d.ts +1 -1
- package/dist/src/lui/timeoutHook.d.ts +0 -6
- package/dist/src/lui/tsUtils.d.ts +5 -0
- package/dist/src/utils/__tests__/random.ts +19 -0
- package/dist/src/utils/textValidator.d.ts +1 -1
- package/dist/src/utils/util.d.ts +1 -0
- package/dist/step-ag-grid.cjs +650 -242
- package/dist/step-ag-grid.cjs.map +1 -1
- package/dist/step-ag-grid.esm.js +651 -245
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +4 -2
- package/src/components/Grid.tsx +312 -221
- package/src/components/GridCell.tsx +1 -25
- package/src/components/GridCellFiller.tsx +1 -1
- package/src/components/GridCellMultiEditor.tsx +2 -2
- package/src/components/GridPopoverHook.tsx +1 -1
- package/src/components/GridRangeSelectContextMenu.tsx +73 -0
- package/src/components/gridFilter/GridFilterButtons.tsx +1 -1
- package/src/components/gridFilter/useGridFilter.ts +1 -1
- package/src/components/gridForm/GridFormDropDown.tsx +2 -4
- package/src/components/gridForm/GridFormEditBearing.tsx +1 -1
- package/src/components/gridForm/GridFormMessage.tsx +1 -1
- package/src/components/gridForm/GridFormMultiSelect.tsx +1 -1
- package/src/components/gridForm/GridFormMultiSelectGrid.tsx +1 -1
- package/src/components/gridForm/GridFormPopoverMenu.tsx +3 -2
- package/src/components/gridForm/GridFormSubComponentTextArea.tsx +1 -1
- package/src/components/gridForm/GridFormSubComponentTextInput.tsx +1 -1
- package/src/components/gridForm/GridFormTextArea.tsx +1 -1
- package/src/components/gridForm/GridFormTextInput.tsx +1 -1
- package/src/components/gridHook/useGridContextMenu.tsx +23 -10
- package/src/components/gridHook/useGridCopy.ts +279 -0
- package/src/components/gridHook/useGridCopySettings.ts +28 -0
- package/src/components/gridHook/useGridRangeSelection.ts +235 -0
- package/src/components/gridPopoverEdit/GridButton.tsx +2 -2
- package/src/components/gridPopoverEdit/GridEditBoolean.tsx +2 -2
- package/src/components/gridPopoverEdit/GridPopoutEditMultiSelect.ts +2 -2
- package/src/components/gridPopoverEdit/GridPopoutEditMultiSelectGrid.ts +2 -2
- package/src/components/gridPopoverEdit/GridPopoverEditBearing.ts +5 -2
- package/src/components/gridPopoverEdit/GridPopoverEditDropDown.ts +2 -2
- package/src/components/gridPopoverEdit/GridPopoverMenu.tsx +2 -2
- package/src/components/gridPopoverEdit/GridPopoverMessage.ts +2 -2
- package/src/components/gridPopoverEdit/GridPopoverTextArea.ts +2 -2
- package/src/components/gridPopoverEdit/GridPopoverTextInput.ts +2 -2
- package/src/components/gridRender/GridRenderGenericCell.tsx +1 -2
- package/src/components/index.ts +1 -0
- package/src/components/types.ts +34 -0
- package/src/contexts/GridContext.tsx +57 -148
- package/src/contexts/GridContextProvider.tsx +16 -13
- package/src/contexts/GridPopoverContext.tsx +1 -1
- package/src/contexts/GridPopoverContextProvider.tsx +1 -1
- package/src/lui/timeoutHook.tsx +0 -19
- package/src/lui/tsUtils.ts +8 -0
- package/src/react-menu3/components/MenuButton.tsx +2 -2
- package/src/react-menu3/hooks/useItemState.ts +1 -1
- package/src/stories/grid/GridCopy.stories.tsx +175 -0
- package/src/stories/grid/GridPopoverEditBearing.stories.tsx +4 -4
- package/src/stories/grid/GridPopoverEditDropDown.stories.tsx +3 -3
- package/src/stories/grid/GridReadOnly.stories.tsx +4 -3
- package/src/stories/grid/interactions/GridKeyboardInteractions.stories.tsx +2 -2
- package/src/styles/ContextMenu.scss +61 -0
- package/src/styles/Grid.scss +26 -2
- package/src/utils/__tests__/random.ts +19 -0
- package/src/utils/bearing.ts +2 -2
- package/src/utils/textValidator.test.ts +1 -1
- package/src/utils/textValidator.ts +1 -1
- package/src/utils/util.ts +2 -0
package/src/components/index.ts
CHANGED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ColDef, EditableCallback, ICellRendererParams, ValueFormatterFunc, ValueGetterFunc } from 'ag-grid-community';
|
|
2
|
+
import { ReactElement } from 'react';
|
|
3
|
+
|
|
4
|
+
export const agGridSelectRowColId = 'ag-Grid-SelectionColumn';
|
|
5
|
+
|
|
6
|
+
export interface GridBaseRow {
|
|
7
|
+
id: string | number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface GridOnRowDragEndProps<TData extends GridBaseRow> {
|
|
11
|
+
movedRow: TData;
|
|
12
|
+
targetRow: TData;
|
|
13
|
+
direction: -1 | 1;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// This is so that typescript retains the row type to pass to the GridCells
|
|
17
|
+
export interface ColDefT<TData extends GridBaseRow, ValueType = any> extends ColDef<TData, ValueType> {
|
|
18
|
+
editable?: boolean | EditableCallback<TData, ValueType>;
|
|
19
|
+
valueGetter?: string | ValueGetterFunc<TData, ValueType>;
|
|
20
|
+
valueFormatter?: string | ValueFormatterFunc<TData, ValueType>;
|
|
21
|
+
cellRenderer?:
|
|
22
|
+
| ((props: ICellRendererParams<TData, ValueType>) => ReactElement | string | false | null | undefined)
|
|
23
|
+
| string;
|
|
24
|
+
cellRendererParams?: {
|
|
25
|
+
rightHoverElement?: ReactElement;
|
|
26
|
+
originalCellRenderer?: any;
|
|
27
|
+
editAction?: (selectedRows: TData[]) => void;
|
|
28
|
+
shortcutKeys?: Record<string, () => void>;
|
|
29
|
+
error?: (props: ICellRendererParams<TData, ValueType>) => ReactElement | string | false | null | undefined;
|
|
30
|
+
warning?: (props: ICellRendererParams<TData, ValueType>) => ReactElement | string | false | null | undefined;
|
|
31
|
+
info?: (props: ICellRendererParams<TData, ValueType>) => ReactElement | string | false | null | undefined;
|
|
32
|
+
};
|
|
33
|
+
editor?: (editorProps: any) => ReactElement;
|
|
34
|
+
}
|
|
@@ -2,7 +2,7 @@ import { ColDef, GridApi, IRowNode, ISizeColumnsToFitParams } from 'ag-grid-comm
|
|
|
2
2
|
import { CsvExportParams } from 'ag-grid-community';
|
|
3
3
|
import { createContext, useContext } from 'react';
|
|
4
4
|
|
|
5
|
-
import { ColDefT, GridBaseRow } from '../components';
|
|
5
|
+
import { ColDefT, GridBaseRow } from '../components/types';
|
|
6
6
|
|
|
7
7
|
export type GridFilterExternal<TData extends GridBaseRow> = (data: TData, rowNode: IRowNode) => boolean;
|
|
8
8
|
|
|
@@ -14,8 +14,8 @@ export interface AutoSizeColumnsProps {
|
|
|
14
14
|
|
|
15
15
|
export type AutoSizeColumnsResult = { width: number } | null;
|
|
16
16
|
|
|
17
|
-
export interface StartCellEditingProps {
|
|
18
|
-
rowId:
|
|
17
|
+
export interface StartCellEditingProps<TData extends GridBaseRow> {
|
|
18
|
+
rowId: TData['id'];
|
|
19
19
|
colId: string;
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -33,21 +33,21 @@ export interface GridContextType<TData extends GridBaseRow> {
|
|
|
33
33
|
editingCells: () => boolean;
|
|
34
34
|
getSelectedRows: <T extends GridBaseRow>() => T[];
|
|
35
35
|
getFilteredSelectedRows: <T extends GridBaseRow>() => T[];
|
|
36
|
-
getSelectedRowIds: () =>
|
|
37
|
-
getFilteredSelectedRowIds: () =>
|
|
36
|
+
getSelectedRowIds: () => TData['id'][];
|
|
37
|
+
getFilteredSelectedRowIds: () => TData['id'][];
|
|
38
38
|
selectRowsDiff: (updateFn: () => Promise<any>) => Promise<void>;
|
|
39
39
|
selectRowsWithFlashDiff: (updateFn: () => Promise<any>) => Promise<void>;
|
|
40
|
-
selectRowsById: (rowIds?:
|
|
41
|
-
selectRowsByIdWithFlash: (rowIds?:
|
|
42
|
-
flashRows: (rowIds?:
|
|
40
|
+
selectRowsById: (rowIds?: TData['id'][]) => void;
|
|
41
|
+
selectRowsByIdWithFlash: (rowIds?: TData['id'][]) => void;
|
|
42
|
+
flashRows: (rowIds?: TData['id'][]) => void;
|
|
43
43
|
flashRowsDiff: (updateFn: () => Promise<any>) => Promise<void>;
|
|
44
|
-
focusByRowById: (rowId:
|
|
45
|
-
ensureRowVisible: (id:
|
|
44
|
+
focusByRowById: (rowId: TData['id'], ifNoCellFocused?: boolean) => void;
|
|
45
|
+
ensureRowVisible: (id: TData['id'] | string) => boolean;
|
|
46
46
|
ensureSelectedRowIsVisible: () => void;
|
|
47
|
-
getFirstRowId: () =>
|
|
47
|
+
getFirstRowId: () => TData['id'];
|
|
48
48
|
autoSizeColumns: (props?: AutoSizeColumnsProps) => Promise<AutoSizeColumnsResult>;
|
|
49
49
|
sizeColumnsToFit: (paramsOrGridWidth?: ISizeColumnsToFitParams) => void;
|
|
50
|
-
startCellEditing: ({ rowId, colId }: StartCellEditingProps) => Promise<void>;
|
|
50
|
+
startCellEditing: ({ rowId, colId }: StartCellEditingProps<TData>) => Promise<void>;
|
|
51
51
|
// Restores the previous focus after cell editing
|
|
52
52
|
resetFocusedCellAfterCellEditing: () => void;
|
|
53
53
|
updatingCells: (
|
|
@@ -70,149 +70,58 @@ export interface GridContextType<TData extends GridBaseRow> {
|
|
|
70
70
|
onBulkEditingComplete: () => Promise<void> | void;
|
|
71
71
|
setOnBulkEditingComplete: (callback: (() => Promise<void> | void) | undefined) => void;
|
|
72
72
|
showNoRowsOverlay: () => void;
|
|
73
|
+
getCellValue: GridApi['getCellValue'];
|
|
73
74
|
}
|
|
74
75
|
|
|
76
|
+
const NoContext = <T,>(): T => {
|
|
77
|
+
console.error('Missing GridContextProvider');
|
|
78
|
+
return null as T;
|
|
79
|
+
};
|
|
80
|
+
|
|
75
81
|
export const GridContext = createContext<GridContextType<any>>({
|
|
76
82
|
gridReady: false,
|
|
77
83
|
gridRenderState: () => null,
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
getColumns: () => {
|
|
83
|
-
console.error('no context provider for getColumns');
|
|
84
|
-
return [];
|
|
85
|
-
},
|
|
86
|
-
getColumnIds: () => {
|
|
87
|
-
console.error('no context provider for getColumnIds');
|
|
88
|
-
return [];
|
|
89
|
-
},
|
|
84
|
+
getCellValue: NoContext,
|
|
85
|
+
getColDef: NoContext,
|
|
86
|
+
getColumns: NoContext,
|
|
87
|
+
getColumnIds: NoContext,
|
|
90
88
|
invisibleColumnIds: undefined,
|
|
91
|
-
setInvisibleColumnIds:
|
|
92
|
-
|
|
93
|
-
},
|
|
94
|
-
prePopupOps: () => {
|
|
95
|
-
console.error('no context provider for prePopupOps');
|
|
96
|
-
},
|
|
89
|
+
setInvisibleColumnIds: NoContext,
|
|
90
|
+
prePopupOps: NoContext,
|
|
97
91
|
externallySelectedItemsAreInSync: false,
|
|
98
|
-
setApis:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
selectRowsWithFlashDiff: async () => {
|
|
132
|
-
console.error('no context provider for selectRowsWithFlashDiff');
|
|
133
|
-
},
|
|
134
|
-
flashRows: () => {
|
|
135
|
-
console.error('no context provider for flashRows');
|
|
136
|
-
},
|
|
137
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
138
|
-
flashRowsDiff: async () => {
|
|
139
|
-
console.error('no context provider for flashRows');
|
|
140
|
-
},
|
|
141
|
-
// eslint-disable-next-line @typescript-eslint/require-await,@typescript-eslint/no-misused-promises
|
|
142
|
-
focusByRowById: async () => {
|
|
143
|
-
console.error('no context provider for focusByRowById');
|
|
144
|
-
},
|
|
145
|
-
ensureRowVisible: () => {
|
|
146
|
-
console.error('no context provider for ensureRowVisible');
|
|
147
|
-
return true;
|
|
148
|
-
},
|
|
149
|
-
ensureSelectedRowIsVisible: () => {
|
|
150
|
-
console.error('no context provider for ensureSelectedRowIsVisible');
|
|
151
|
-
},
|
|
152
|
-
getFirstRowId: () => {
|
|
153
|
-
console.error('no context provider for getFirstRowId');
|
|
154
|
-
return -1;
|
|
155
|
-
},
|
|
156
|
-
autoSizeColumns: async () => {
|
|
157
|
-
console.error('no context provider for autoSizeColumns');
|
|
158
|
-
return Promise.resolve(null);
|
|
159
|
-
},
|
|
160
|
-
sizeColumnsToFit: () => {
|
|
161
|
-
console.error('no context provider for autoSizeAllColumns');
|
|
162
|
-
return null;
|
|
163
|
-
},
|
|
164
|
-
editingCells: () => {
|
|
165
|
-
console.error('no context provider for editingCells');
|
|
166
|
-
return false;
|
|
167
|
-
},
|
|
168
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
169
|
-
startCellEditing: async () => {
|
|
170
|
-
console.error('no context provider for startCellEditing');
|
|
171
|
-
},
|
|
172
|
-
resetFocusedCellAfterCellEditing: () => {
|
|
173
|
-
console.error('no context provider for resetFocusedCellAfterCellEditing');
|
|
174
|
-
},
|
|
175
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
176
|
-
updatingCells: async () => {
|
|
177
|
-
console.error('no context provider for modifyUpdating');
|
|
178
|
-
return false;
|
|
179
|
-
},
|
|
180
|
-
redrawRows: () => {
|
|
181
|
-
console.error('no context provider for redrawRows');
|
|
182
|
-
},
|
|
183
|
-
setExternallySelectedItemsAreInSync: () => {
|
|
184
|
-
console.error('no context provider for setExternallySelectedItemsAreInSync');
|
|
185
|
-
},
|
|
186
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
187
|
-
waitForExternallySelectedItemsToBeInSync: async () => {
|
|
188
|
-
console.error('no context provider for waitForExternallySelectedItemsToBeInSync');
|
|
189
|
-
},
|
|
190
|
-
addExternalFilter: () => {
|
|
191
|
-
console.error('no context provider for addExternalFilter');
|
|
192
|
-
},
|
|
193
|
-
removeExternalFilter: () => {
|
|
194
|
-
console.error('no context provider for removeExternalFilter');
|
|
195
|
-
},
|
|
196
|
-
isExternalFilterPresent: () => {
|
|
197
|
-
console.error('no context provider for isExternalFilterPresent');
|
|
198
|
-
return false;
|
|
199
|
-
},
|
|
200
|
-
doesExternalFilterPass: () => {
|
|
201
|
-
console.error('no context provider for doesExternalFilterPass');
|
|
202
|
-
return true;
|
|
203
|
-
},
|
|
204
|
-
downloadCsv: () => {
|
|
205
|
-
console.error('no context provider for downloadCsv');
|
|
206
|
-
},
|
|
207
|
-
onBulkEditingComplete: () => {
|
|
208
|
-
console.error('no context provider for onBulkEditingComplete');
|
|
209
|
-
},
|
|
210
|
-
setOnBulkEditingComplete: () => {
|
|
211
|
-
console.error('no context provider for setOnBulkEditingComplete');
|
|
212
|
-
},
|
|
213
|
-
showNoRowsOverlay: () => {
|
|
214
|
-
console.error('no context provider for showLoadingOverlay');
|
|
215
|
-
},
|
|
92
|
+
setApis: NoContext,
|
|
93
|
+
setQuickFilter: NoContext,
|
|
94
|
+
selectRowsById: NoContext,
|
|
95
|
+
getSelectedRows: NoContext,
|
|
96
|
+
getFilteredSelectedRows: NoContext,
|
|
97
|
+
getSelectedRowIds: NoContext,
|
|
98
|
+
getFilteredSelectedRowIds: NoContext,
|
|
99
|
+
selectRowsDiff: NoContext,
|
|
100
|
+
selectRowsByIdWithFlash: NoContext,
|
|
101
|
+
selectRowsWithFlashDiff: NoContext,
|
|
102
|
+
flashRows: NoContext,
|
|
103
|
+
flashRowsDiff: NoContext,
|
|
104
|
+
focusByRowById: NoContext,
|
|
105
|
+
ensureRowVisible: NoContext,
|
|
106
|
+
ensureSelectedRowIsVisible: NoContext,
|
|
107
|
+
getFirstRowId: NoContext,
|
|
108
|
+
autoSizeColumns: NoContext,
|
|
109
|
+
sizeColumnsToFit: NoContext,
|
|
110
|
+
editingCells: NoContext,
|
|
111
|
+
startCellEditing: NoContext,
|
|
112
|
+
resetFocusedCellAfterCellEditing: NoContext,
|
|
113
|
+
updatingCells: NoContext,
|
|
114
|
+
redrawRows: NoContext,
|
|
115
|
+
setExternallySelectedItemsAreInSync: NoContext,
|
|
116
|
+
waitForExternallySelectedItemsToBeInSync: NoContext,
|
|
117
|
+
addExternalFilter: NoContext,
|
|
118
|
+
removeExternalFilter: NoContext,
|
|
119
|
+
isExternalFilterPresent: NoContext,
|
|
120
|
+
doesExternalFilterPass: NoContext,
|
|
121
|
+
downloadCsv: NoContext,
|
|
122
|
+
onBulkEditingComplete: NoContext,
|
|
123
|
+
setOnBulkEditingComplete: NoContext,
|
|
124
|
+
showNoRowsOverlay: NoContext,
|
|
216
125
|
});
|
|
217
126
|
|
|
218
127
|
export const useGridContext = <TData extends GridBaseRow>() => useContext<GridContextType<TData>>(GridContext);
|
|
@@ -13,7 +13,7 @@ import debounce from 'debounce-promise';
|
|
|
13
13
|
import { compact, defer, delay, difference, filter, isEmpty, last, pull, remove, sortBy, sumBy } from 'lodash-es';
|
|
14
14
|
import { PropsWithChildren, ReactElement, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
15
15
|
|
|
16
|
-
import { ColDefT, GridBaseRow } from '../components';
|
|
16
|
+
import { agGridSelectRowColId, ColDefT, GridBaseRow } from '../components';
|
|
17
17
|
import { GridCellFillerColId, isGridCellFiller } from '../components/GridCellFiller';
|
|
18
18
|
import { getColId, isFlexColumn } from '../components/gridUtil';
|
|
19
19
|
import { fnOrVar, isNotEmpty, sanitiseFileName, wait } from '../utils/util';
|
|
@@ -38,7 +38,7 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
38
38
|
const [invisibleColumnIds, _setInvisibleColumnIds] = useState<string[]>();
|
|
39
39
|
const testId = useRef<string | undefined>();
|
|
40
40
|
const hasExternallySelectedItemsRef = useRef(false);
|
|
41
|
-
const idsBeforeUpdate = useRef<
|
|
41
|
+
const idsBeforeUpdate = useRef<TData['id'][]>([]);
|
|
42
42
|
const prePopupFocusedCell = useRef<CellPosition>();
|
|
43
43
|
const [externallySelectedItemsAreInSync, setExternallySelectedItemsAreInSync] = useState(false);
|
|
44
44
|
const externalFilters = useRef<GridFilterExternal<TData>[]>([]);
|
|
@@ -83,6 +83,8 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
83
83
|
[gridApi],
|
|
84
84
|
);
|
|
85
85
|
|
|
86
|
+
const getCellValue = useCallback<GridApi['getCellValue']>((...props) => gridApi?.getCellValue(...props), [gridApi]);
|
|
87
|
+
|
|
86
88
|
/**
|
|
87
89
|
* Scroll row into view by Id.
|
|
88
90
|
*
|
|
@@ -169,7 +171,7 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
169
171
|
* Get all row id's in grid.
|
|
170
172
|
*/
|
|
171
173
|
const _getAllRowIds = useCallback(() => {
|
|
172
|
-
const result:
|
|
174
|
+
const result: TData['id'][] = [];
|
|
173
175
|
return gridApiOp(
|
|
174
176
|
(gridApi) => {
|
|
175
177
|
gridApi.forEachNode((node) => result.push(node.data.id));
|
|
@@ -205,7 +207,7 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
205
207
|
* @param rowIds Row ids to get from grid.
|
|
206
208
|
*/
|
|
207
209
|
const _rowIdsToNodes = useCallback(
|
|
208
|
-
(rowIds:
|
|
210
|
+
(rowIds: TData['id'][]): IRowNode[] => {
|
|
209
211
|
return gridApiOp(
|
|
210
212
|
(gridApi) => compact(rowIds.map((rowId) => gridApi.getRowNode('' + rowId))),
|
|
211
213
|
() => [] as RowNode[],
|
|
@@ -248,7 +250,7 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
248
250
|
ifNoCellFocused = false,
|
|
249
251
|
retryCount = 15,
|
|
250
252
|
}: {
|
|
251
|
-
rowIds:
|
|
253
|
+
rowIds: TData['id'][] | undefined;
|
|
252
254
|
select: boolean;
|
|
253
255
|
flash: boolean;
|
|
254
256
|
ifNoCellFocused?: boolean;
|
|
@@ -302,7 +304,7 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
302
304
|
// It may be that the first cell is the selection cell, this doesn't exist as a colDef
|
|
303
305
|
// so instead, I just try and select it. If it doesn't exist selection will stay on the
|
|
304
306
|
// previously focused cell
|
|
305
|
-
gridApi.setFocusedCell(rowIndex,
|
|
307
|
+
gridApi.setFocusedCell(rowIndex, agGridSelectRowColId);
|
|
306
308
|
}
|
|
307
309
|
}, 100);
|
|
308
310
|
}
|
|
@@ -333,17 +335,17 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
333
335
|
);
|
|
334
336
|
|
|
335
337
|
const selectRowsById = useCallback(
|
|
336
|
-
(rowIds?:
|
|
338
|
+
(rowIds?: TData['id'][]) => _selectRowsWithOptionalFlash({ rowIds, select: true, flash: false }),
|
|
337
339
|
[_selectRowsWithOptionalFlash],
|
|
338
340
|
);
|
|
339
341
|
|
|
340
342
|
const selectRowsByIdWithFlash = useCallback(
|
|
341
|
-
(rowIds?:
|
|
343
|
+
(rowIds?: TData['id'][]) => _selectRowsWithOptionalFlash({ rowIds, select: true, flash: true }),
|
|
342
344
|
[_selectRowsWithOptionalFlash],
|
|
343
345
|
);
|
|
344
346
|
|
|
345
347
|
const flashRows = useCallback(
|
|
346
|
-
(rowIds?:
|
|
348
|
+
(rowIds?: TData['id'][]) => _selectRowsWithOptionalFlash({ rowIds, select: false, flash: true }),
|
|
347
349
|
[_selectRowsWithOptionalFlash],
|
|
348
350
|
);
|
|
349
351
|
|
|
@@ -375,7 +377,7 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
375
377
|
);
|
|
376
378
|
|
|
377
379
|
const focusByRowById = useCallback(
|
|
378
|
-
(rowId:
|
|
380
|
+
(rowId: TData['id'], ifNoCellFocused?: boolean) =>
|
|
379
381
|
_selectRowsWithOptionalFlash({ rowIds: [rowId], select: false, flash: false, ifNoCellFocused }),
|
|
380
382
|
[_selectRowsWithOptionalFlash],
|
|
381
383
|
);
|
|
@@ -398,12 +400,12 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
398
400
|
}, [gridApiOp]);
|
|
399
401
|
|
|
400
402
|
const getSelectedRowIds = useCallback(
|
|
401
|
-
():
|
|
403
|
+
(): TData['id'][] => getSelectedRows().map((row) => (row as any).id as number),
|
|
402
404
|
[getSelectedRows],
|
|
403
405
|
);
|
|
404
406
|
|
|
405
407
|
const getFilteredSelectedRowIds = useCallback(
|
|
406
|
-
():
|
|
408
|
+
(): TData['id'][] => getFilteredSelectedRows().map((row) => (row as any).id as number),
|
|
407
409
|
[getFilteredSelectedRows],
|
|
408
410
|
);
|
|
409
411
|
|
|
@@ -548,7 +550,7 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
548
550
|
|
|
549
551
|
const startCellEditingInProgressRef = useRef(false);
|
|
550
552
|
const startCellEditing = useCallback(
|
|
551
|
-
async ({ rowId, colId }: { rowId:
|
|
553
|
+
async ({ rowId, colId }: { rowId: TData['id']; colId: string }) => {
|
|
552
554
|
if (!gridApi || startCellEditingInProgressRef.current) {
|
|
553
555
|
return;
|
|
554
556
|
}
|
|
@@ -902,6 +904,7 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
902
904
|
getSelectedRowIds,
|
|
903
905
|
getFilteredSelectedRowIds,
|
|
904
906
|
getFirstRowId,
|
|
907
|
+
getCellValue,
|
|
905
908
|
editingCells,
|
|
906
909
|
ensureRowVisible,
|
|
907
910
|
ensureSelectedRowIsVisible,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createContext, RefObject, useContext } from 'react';
|
|
2
2
|
|
|
3
|
-
import { GridBaseRow } from '../components/
|
|
3
|
+
import { GridBaseRow } from '../components/types';
|
|
4
4
|
|
|
5
5
|
export interface GridPopoverContextType<TData extends GridBaseRow> {
|
|
6
6
|
anchorRef: RefObject<Element>;
|
|
@@ -2,7 +2,7 @@ import { ICellEditorParams } from 'ag-grid-community';
|
|
|
2
2
|
import { sortBy } from 'lodash-es';
|
|
3
3
|
import { PropsWithChildren, RefObject, useCallback, useContext, useMemo, useRef, useState } from 'react';
|
|
4
4
|
|
|
5
|
-
import { GridBaseRow } from '../components/
|
|
5
|
+
import { GridBaseRow } from '../components/types';
|
|
6
6
|
import { GridContext } from './GridContext';
|
|
7
7
|
import { GridPopoverContext } from './GridPopoverContext';
|
|
8
8
|
|
package/src/lui/timeoutHook.tsx
CHANGED
|
@@ -38,22 +38,3 @@ export const useTimeoutHook = () => {
|
|
|
38
38
|
|
|
39
39
|
return invoke;
|
|
40
40
|
};
|
|
41
|
-
|
|
42
|
-
interface IntervalHookProps {
|
|
43
|
-
timeoutMs: number;
|
|
44
|
-
callback: () => void;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export const useIntervalHook = ({ callback, timeoutMs }: IntervalHookProps) => {
|
|
48
|
-
const callbackRef = useRef(callback);
|
|
49
|
-
callbackRef.current = callback;
|
|
50
|
-
|
|
51
|
-
useEffect(() => {
|
|
52
|
-
const interval = setInterval(() => {
|
|
53
|
-
callbackRef.current && callbackRef.current();
|
|
54
|
-
}, timeoutMs);
|
|
55
|
-
return () => {
|
|
56
|
-
clearInterval(interval);
|
|
57
|
-
};
|
|
58
|
-
}, [timeoutMs]);
|
|
59
|
-
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type KeysOfType<TObject, TValue> = {
|
|
2
|
+
[K in keyof TObject]: TObject[K] extends TValue ? K : never;
|
|
3
|
+
}[keyof TObject];
|
|
4
|
+
|
|
5
|
+
export const typedKeys = <T extends object>(obj: T): (keyof T)[] => Object.keys(obj) as (keyof T)[];
|
|
6
|
+
|
|
7
|
+
export const typedEntries = <T extends object>(obj: T): { [K in keyof T]-?: [K, T[K]] }[keyof T][] =>
|
|
8
|
+
Object.entries(obj) as { [K in keyof T]-?: [K, T[K]] }[keyof T][];
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { forwardRef, LegacyRef, ReactNode, useMemo } from 'react';
|
|
2
2
|
|
|
3
|
-
import { useBEM } from '../hooks';
|
|
3
|
+
import { useBEM } from '../hooks/useBEM';
|
|
4
4
|
import { BaseProps, MenuButtonModifiers } from '../types';
|
|
5
|
-
import { menuButtonClass } from '../utils';
|
|
5
|
+
import { menuButtonClass } from '../utils/constants';
|
|
6
6
|
|
|
7
7
|
export interface MenuButtonProps extends BaseProps<MenuButtonModifiers> {
|
|
8
8
|
disabled?: boolean;
|
|
@@ -2,7 +2,7 @@ import { FocusEvent, MutableRefObject, useContext, useEffect, useRef } from 'rea
|
|
|
2
2
|
|
|
3
3
|
import { ItemSettingsContext } from '../contexts/ItemSettingsContext';
|
|
4
4
|
import { MenuListItemContext } from '../contexts/MenuListItemContext';
|
|
5
|
-
import { HoverActionTypes } from '../utils';
|
|
5
|
+
import { HoverActionTypes } from '../utils/constants';
|
|
6
6
|
import { useItemEffect } from './useItemEffect';
|
|
7
7
|
|
|
8
8
|
// This hook includes some common stateful logic in MenuItem and FocusableItem
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import '../../styles/GridTheme.scss';
|
|
2
|
+
import '../../styles/index.scss';
|
|
3
|
+
import '@linzjs/lui/dist/scss/base.scss';
|
|
4
|
+
import '@linzjs/lui/dist/fonts';
|
|
5
|
+
|
|
6
|
+
import { LuiMessagingContextProvider } from '@linzjs/lui';
|
|
7
|
+
import { Meta, StoryFn } from '@storybook/react-vite';
|
|
8
|
+
import { useMemo, useState } from 'react';
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
ColDefT,
|
|
12
|
+
Grid,
|
|
13
|
+
GridCell,
|
|
14
|
+
GridCellBearingValueFormatter,
|
|
15
|
+
GridContextProvider,
|
|
16
|
+
GridFilterQuick,
|
|
17
|
+
GridFilters,
|
|
18
|
+
GridPopoverMenu,
|
|
19
|
+
GridProps,
|
|
20
|
+
GridUpdatingContextProvider,
|
|
21
|
+
GridWrapper,
|
|
22
|
+
} from '../..';
|
|
23
|
+
import { GridFilterColumnsToggle, GridFilterDownloadCsvButton } from '../../components';
|
|
24
|
+
import { GridCellFiller } from '../../components/GridCellFiller';
|
|
25
|
+
import { SeededRandomForTests } from '../../utils/__tests__/random';
|
|
26
|
+
import { waitForGridReady } from '../../utils/__tests__/storybookTestUtil';
|
|
27
|
+
|
|
28
|
+
export default {
|
|
29
|
+
title: 'Components / Grids',
|
|
30
|
+
component: Grid,
|
|
31
|
+
args: {
|
|
32
|
+
quickFilter: true,
|
|
33
|
+
quickFilterValue: '',
|
|
34
|
+
quickFilterPlaceholder: 'Quick filter...',
|
|
35
|
+
selectable: false,
|
|
36
|
+
rowSelection: 'multiple',
|
|
37
|
+
}, // Storybook hangs otherwise
|
|
38
|
+
parameters: {
|
|
39
|
+
docs: {
|
|
40
|
+
source: {
|
|
41
|
+
type: 'code',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
decorators: [
|
|
46
|
+
(Story) => (
|
|
47
|
+
<LuiMessagingContextProvider version="v2">
|
|
48
|
+
<div style={{ maxWidth: 1024, height: '80vh', display: 'flex', flexDirection: 'column' }}>
|
|
49
|
+
<GridUpdatingContextProvider>
|
|
50
|
+
<GridContextProvider>
|
|
51
|
+
<Story />
|
|
52
|
+
</GridContextProvider>
|
|
53
|
+
</GridUpdatingContextProvider>
|
|
54
|
+
</div>
|
|
55
|
+
</LuiMessagingContextProvider>
|
|
56
|
+
),
|
|
57
|
+
],
|
|
58
|
+
} as Meta<typeof Grid>;
|
|
59
|
+
|
|
60
|
+
interface ITestRow {
|
|
61
|
+
id: number;
|
|
62
|
+
position?: string;
|
|
63
|
+
age: number;
|
|
64
|
+
height: string;
|
|
65
|
+
bearing: string | number | null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const GridCopyTemplate: StoryFn<typeof Grid<ITestRow>> = (props: GridProps<ITestRow>) => {
|
|
69
|
+
const [externalSelectedIds, setExternalSelectedIds] = useState<number[]>([]);
|
|
70
|
+
const columnDefs: ColDefT<ITestRow>[] = useMemo(
|
|
71
|
+
() => [
|
|
72
|
+
GridCell({
|
|
73
|
+
field: 'id',
|
|
74
|
+
headerName: 'Id',
|
|
75
|
+
lockVisible: true,
|
|
76
|
+
}),
|
|
77
|
+
GridCell<ITestRow, ITestRow['position']>({
|
|
78
|
+
field: 'position',
|
|
79
|
+
headerName: 'Position',
|
|
80
|
+
cellRendererParams: {
|
|
81
|
+
error: ({ value }) => value === 'Manager' && 'Managers need management',
|
|
82
|
+
warning: ({ value }) => value === 'Tester' && 'Testers are testing',
|
|
83
|
+
info: ({ value }) => value === 'Developer' && 'Developers are awesome',
|
|
84
|
+
},
|
|
85
|
+
}),
|
|
86
|
+
{
|
|
87
|
+
headerName: 'Metrics',
|
|
88
|
+
marryChildren: true,
|
|
89
|
+
children: [
|
|
90
|
+
GridCell<ITestRow, ITestRow['age']>({
|
|
91
|
+
field: 'age',
|
|
92
|
+
headerName: 'Age',
|
|
93
|
+
}),
|
|
94
|
+
GridCell<ITestRow, ITestRow['height']>({
|
|
95
|
+
field: 'height',
|
|
96
|
+
headerName: 'Height',
|
|
97
|
+
}),
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
GridCell({
|
|
101
|
+
field: 'bearing',
|
|
102
|
+
headerName: 'Bearing',
|
|
103
|
+
valueFormatter: GridCellBearingValueFormatter,
|
|
104
|
+
}),
|
|
105
|
+
GridCellFiller(),
|
|
106
|
+
GridPopoverMenu(
|
|
107
|
+
{},
|
|
108
|
+
{
|
|
109
|
+
editorParams: {
|
|
110
|
+
options: () => [
|
|
111
|
+
{
|
|
112
|
+
label: 'Test menu',
|
|
113
|
+
action: () => {},
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
),
|
|
119
|
+
],
|
|
120
|
+
[],
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
const [rowData] = useState<ITestRow[]>(() => {
|
|
124
|
+
const random = new SeededRandomForTests(1000);
|
|
125
|
+
let id = 1000;
|
|
126
|
+
const positions = [
|
|
127
|
+
undefined,
|
|
128
|
+
'Tester',
|
|
129
|
+
'Developer',
|
|
130
|
+
'Lawyer',
|
|
131
|
+
'Barrista """',
|
|
132
|
+
'Manager',
|
|
133
|
+
'CEO',
|
|
134
|
+
'CTO',
|
|
135
|
+
'Architect',
|
|
136
|
+
];
|
|
137
|
+
const result: ITestRow[] = [];
|
|
138
|
+
for (let i = 0; i < 1000; i++) {
|
|
139
|
+
result.push({
|
|
140
|
+
id: id++,
|
|
141
|
+
position: random.fromArray(positions),
|
|
142
|
+
age: 30,
|
|
143
|
+
height: `${random.next(3) + 3}'${random.next(12)}"`,
|
|
144
|
+
bearing: Math.random() * 360,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return result;
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
return (
|
|
151
|
+
<GridWrapper>
|
|
152
|
+
<GridFilters>
|
|
153
|
+
<GridFilterQuick />
|
|
154
|
+
<GridFilterColumnsToggle />
|
|
155
|
+
<GridFilterDownloadCsvButton fileName={'readOnlyGrid'} />
|
|
156
|
+
</GridFilters>
|
|
157
|
+
<Grid
|
|
158
|
+
data-testid={'readonly'}
|
|
159
|
+
{...props}
|
|
160
|
+
enableRangeSelection={true}
|
|
161
|
+
selectable={true}
|
|
162
|
+
enableClickSelection={true}
|
|
163
|
+
enableSelectionWithoutKeys={true}
|
|
164
|
+
autoSelectFirstRow={true}
|
|
165
|
+
externalSelectedIds={externalSelectedIds}
|
|
166
|
+
setExternalSelectedIds={setExternalSelectedIds}
|
|
167
|
+
columnDefs={columnDefs}
|
|
168
|
+
rowData={rowData}
|
|
169
|
+
/>
|
|
170
|
+
</GridWrapper>
|
|
171
|
+
);
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export const GridCopy = GridCopyTemplate.bind({});
|
|
175
|
+
GridCopy.play = waitForGridReady;
|