@linzjs/step-ag-grid 7.19.6 → 8.1.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 +4 -0
- package/dist/src/components/Grid.d.ts +2 -1
- package/dist/src/components/gridForm/GridFormDropDown.d.ts +1 -0
- package/dist/src/components/gridForm/GridFormEditBearing.d.ts +5 -1
- package/dist/src/components/gridForm/GridFormMultiSelect.d.ts +8 -2
- package/dist/src/components/gridForm/GridFormPopoverMenu.d.ts +11 -6
- package/dist/src/components/gridForm/GridFormTextArea.d.ts +4 -1
- package/dist/src/components/gridForm/GridFormTextInput.d.ts +4 -1
- package/dist/src/components/gridPopoverEdit/GridPopoverEditBearing.d.ts +10 -1
- package/dist/src/components/gridPopoverEdit/GridPopoverMenu.d.ts +2 -2
- package/dist/src/lui/ActionButton.d.ts +2 -1
- package/dist/src/utils/bearing.d.ts +2 -3
- package/dist/step-ag-grid.esm.js +135 -98
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Grid.tsx +3 -3
- package/src/components/gridForm/GridFormDropDown.tsx +86 -71
- package/src/components/gridForm/GridFormEditBearing.tsx +9 -4
- package/src/components/gridForm/GridFormMultiSelect.tsx +7 -7
- package/src/components/gridForm/GridFormPopoverMenu.tsx +62 -53
- package/src/components/gridForm/GridFormTextArea.tsx +2 -2
- package/src/components/gridForm/GridFormTextInput.tsx +2 -2
- package/src/components/gridPopoverEdit/GridPopoverEditBearing.ts +40 -32
- package/src/components/gridPopoverEdit/GridPopoverMenu.tsx +3 -3
- package/src/lui/ActionButton.tsx +3 -1
- package/src/react-menu3/components/ControlledMenu.tsx +5 -1
- package/src/react-menu3/styles/index.scss +4 -0
- package/src/stories/components/ActionButton.stories.tsx +11 -0
- package/src/stories/grid/GridNonEditableRow.stories.tsx +6 -6
- package/src/stories/grid/GridPopoutBearing.stories.tsx +1 -1
- package/src/stories/grid/GridPopoutEditGenericTextArea.stories.tsx +5 -5
- package/src/stories/grid/GridPopoutEditMultiSelect.stories.tsx +3 -3
- package/src/stories/grid/GridReadOnly.stories.tsx +6 -6
- package/src/stories/grid/gridForm/GridFormDropDown.stories.tsx +109 -0
- package/src/stories/grid/gridForm/GridFormEditBearing.stories.tsx +54 -0
- package/src/stories/grid/gridForm/GridFormEditBearingCorrection.stories.tsx +54 -0
- package/src/stories/grid/gridForm/GridFormMessage.stories.tsx +32 -0
- package/src/stories/grid/gridForm/GridFormPopoverMenu.stories.tsx +55 -0
- package/src/utils/bearing.ts +10 -12
package/package.json
CHANGED
package/src/components/Grid.tsx
CHANGED
|
@@ -27,7 +27,7 @@ export interface GridProps {
|
|
|
27
27
|
externalSelectedItems?: any[];
|
|
28
28
|
setExternalSelectedItems?: (items: any[]) => void;
|
|
29
29
|
defaultColDef?: GridOptions["defaultColDef"];
|
|
30
|
-
columnDefs:
|
|
30
|
+
columnDefs: ColDef[];
|
|
31
31
|
rowData: GridOptions["rowData"];
|
|
32
32
|
noRowsOverlayText?: string;
|
|
33
33
|
postSortRows?: GridOptions["postSortRows"];
|
|
@@ -168,8 +168,8 @@ export const Grid = (params: GridProps): JSX.Element => {
|
|
|
168
168
|
synchroniseExternallySelectedItemsToGrid();
|
|
169
169
|
}, [synchroniseExternallySelectedItemsToGrid]);
|
|
170
170
|
|
|
171
|
-
const columnDefs = useMemo(():
|
|
172
|
-
const adjustColDefs =
|
|
171
|
+
const columnDefs = useMemo((): ColDef[] => {
|
|
172
|
+
const adjustColDefs = params.columnDefs.map((colDef) => {
|
|
173
173
|
return {
|
|
174
174
|
...colDef,
|
|
175
175
|
editable: params.readOnly ? false : params.defaultColDef?.editable ?? colDef.editable,
|
|
@@ -45,8 +45,9 @@ export interface GridFormPopoutDropDownProps<RowType extends GridBaseRow> extend
|
|
|
45
45
|
| "GridPopoverEditDropDown-containerUnlimited"
|
|
46
46
|
| string
|
|
47
47
|
| undefined;
|
|
48
|
-
// local means the
|
|
48
|
+
// local means the use the local filter, otherwise it's expected options will be passed a function that takes a filter
|
|
49
49
|
filtered?: "local" | "reload";
|
|
50
|
+
filterDefaultValue?: string;
|
|
50
51
|
filterPlaceholder?: string;
|
|
51
52
|
filterHelpText?: string;
|
|
52
53
|
noOptionsMessage?: string;
|
|
@@ -66,7 +67,7 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
|
|
|
66
67
|
const { selectedRows, field, data } = useGridPopoverContext<RowType>();
|
|
67
68
|
|
|
68
69
|
// Save triggers during async action processing which triggers another selectItem(), this ref blocks that
|
|
69
|
-
const [filter, setFilter] = useState("");
|
|
70
|
+
const [filter, setFilter] = useState(props.filterDefaultValue ?? "");
|
|
70
71
|
const [filteredValues, setFilteredValues] = useState<any[]>();
|
|
71
72
|
const [options, setOptions] = useState<FinalSelectOption[] | null>(null);
|
|
72
73
|
const subComponentIsValid = useRef(false);
|
|
@@ -143,7 +144,7 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
|
|
|
143
144
|
}
|
|
144
145
|
}, [props.filtered, filter, options]);
|
|
145
146
|
|
|
146
|
-
const
|
|
147
|
+
const reSearchOnFilterChange = useMemo(
|
|
147
148
|
() =>
|
|
148
149
|
debounce(() => {
|
|
149
150
|
setOptions(null);
|
|
@@ -157,9 +158,9 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
|
|
|
157
158
|
useEffect(() => {
|
|
158
159
|
if (previousFilter.current != filter && props.filtered == "reload") {
|
|
159
160
|
previousFilter.current = filter;
|
|
160
|
-
|
|
161
|
+
reSearchOnFilterChange().then();
|
|
161
162
|
}
|
|
162
|
-
}, [filter, props,
|
|
163
|
+
}, [filter, props, reSearchOnFilterChange]);
|
|
163
164
|
|
|
164
165
|
/**
|
|
165
166
|
* Saves are wrapped in updateValue and triggered by blur events
|
|
@@ -193,6 +194,9 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
|
|
|
193
194
|
save,
|
|
194
195
|
});
|
|
195
196
|
|
|
197
|
+
let lastHeader: JSX.Element | null = null;
|
|
198
|
+
let showHeader: JSX.Element | null = null;
|
|
199
|
+
|
|
196
200
|
return popoverWrapper(
|
|
197
201
|
<>
|
|
198
202
|
{props.filtered && (
|
|
@@ -237,76 +241,87 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
|
|
|
237
241
|
{props.noOptionsMessage ?? "No Options"}
|
|
238
242
|
</MenuItem>
|
|
239
243
|
)}
|
|
240
|
-
{options?.map((item: FinalSelectOption, index) =>
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
244
|
+
{options?.map((item: FinalSelectOption, index) => {
|
|
245
|
+
showHeader = null;
|
|
246
|
+
if (item.value === MenuSeparatorString) {
|
|
247
|
+
return <MenuDivider key={`$$divider_${index}`} />;
|
|
248
|
+
} else if (item.value === MenuHeaderString) {
|
|
249
|
+
lastHeader = <MenuHeader key={`$$header_${index}`}>{item.label}</MenuHeader>;
|
|
250
|
+
return <></>;
|
|
251
|
+
} else {
|
|
252
|
+
if (lastHeader) {
|
|
253
|
+
showHeader = lastHeader;
|
|
254
|
+
lastHeader = null;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return (
|
|
246
258
|
(!filteredValues || filteredValues.includes(item)) && (
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
259
|
+
<>
|
|
260
|
+
{showHeader}
|
|
261
|
+
<div key={`menu-wrapper-${index}`}>
|
|
262
|
+
<MenuItem
|
|
263
|
+
key={`${fieldToString(field)}-${index}`}
|
|
264
|
+
disabled={!!item.disabled}
|
|
265
|
+
title={item.disabled && typeof item.disabled !== "boolean" ? item.disabled : ""}
|
|
266
|
+
value={item.value}
|
|
267
|
+
onFocus={() => {
|
|
256
268
|
setSelectedItem(item);
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
269
|
+
if (item.subComponent) {
|
|
270
|
+
setSelectedItem(item);
|
|
271
|
+
subComponentIsValid.current = true;
|
|
272
|
+
subComponentInitialValue.current = null;
|
|
273
|
+
} else {
|
|
274
|
+
setSubSelectedValue(null);
|
|
275
|
+
subComponentIsValid.current = true;
|
|
276
|
+
}
|
|
277
|
+
}}
|
|
278
|
+
onClick={(e: ClickEvent) => {
|
|
279
|
+
if (item.subComponent) {
|
|
280
|
+
e.keepOpen = true;
|
|
281
|
+
}
|
|
282
|
+
}}
|
|
283
|
+
>
|
|
284
|
+
{item.label ?? (item.value == null ? `<${item.value}>` : `${item.value}`)}
|
|
285
|
+
{item.subComponent ? "..." : ""}
|
|
286
|
+
</MenuItem>
|
|
273
287
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
288
|
+
{item.subComponent && selectedItem === item && (
|
|
289
|
+
<FocusableItem className={"LuiDeprecatedForms"} key={`${item.label}_subcomponent`}>
|
|
290
|
+
{(ref: MenuInstance) => (
|
|
291
|
+
<GridSubComponentContext.Provider
|
|
292
|
+
value={{
|
|
293
|
+
context: { options },
|
|
294
|
+
data,
|
|
295
|
+
value: subSelectedValue,
|
|
296
|
+
setValue: (value: any) => {
|
|
297
|
+
setSubSelectedValue(value);
|
|
298
|
+
if (subComponentInitialValue.current === null) {
|
|
299
|
+
// copy the default value of the subcomponent so we can change detect on save
|
|
300
|
+
subComponentInitialValue.current = JSON.stringify(value);
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
setValid: (valid: boolean) => {
|
|
304
|
+
subComponentIsValid.current = valid;
|
|
305
|
+
},
|
|
306
|
+
triggerSave: async () => {
|
|
307
|
+
ref.closeMenu();
|
|
308
|
+
},
|
|
309
|
+
}}
|
|
310
|
+
>
|
|
311
|
+
{item.subComponent && (
|
|
312
|
+
<div className={"subComponent"}>
|
|
313
|
+
<item.subComponent key={`${fieldToString(field)}-${index}_subcomponent_inner`} />
|
|
314
|
+
</div>
|
|
315
|
+
)}
|
|
316
|
+
</GridSubComponentContext.Provider>
|
|
317
|
+
)}
|
|
318
|
+
</FocusableItem>
|
|
319
|
+
)}
|
|
320
|
+
</div>
|
|
321
|
+
</>
|
|
307
322
|
)
|
|
308
|
-
)
|
|
309
|
-
)}
|
|
323
|
+
);
|
|
324
|
+
})}
|
|
310
325
|
</>
|
|
311
326
|
</ComponentLoadingWrapper>
|
|
312
327
|
</>,
|
|
@@ -7,13 +7,14 @@ import { CellEditorCommon } from "../GridCell";
|
|
|
7
7
|
import { useGridPopoverContext } from "../../contexts/GridPopoverContext";
|
|
8
8
|
|
|
9
9
|
export interface GridFormEditBearingProps<RowType extends GridBaseRow> extends CellEditorCommon {
|
|
10
|
+
formatValue?: (value: any) => string;
|
|
10
11
|
placeHolder?: string;
|
|
11
12
|
range?: (value: number | null) => string | null;
|
|
12
|
-
onSave?: (selectedRows: RowType[]
|
|
13
|
+
onSave?: (props: { selectedRows: RowType[]; value: number | null }) => Promise<boolean>;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
export const GridFormEditBearing = <RowType extends GridBaseRow>(props: GridFormEditBearingProps<RowType>) => {
|
|
16
|
-
const { field, value: initialValue
|
|
17
|
+
const { field, value: initialValue } = useGridPopoverContext<RowType>();
|
|
17
18
|
|
|
18
19
|
// This clears out any scientific precision
|
|
19
20
|
const defaultValue = useMemo(
|
|
@@ -34,7 +35,7 @@ export const GridFormEditBearing = <RowType extends GridBaseRow>(props: GridForm
|
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
if (props.onSave) {
|
|
37
|
-
return await props.onSave(selectedRows, parsedValue);
|
|
38
|
+
return await props.onSave({ selectedRows, value: parsedValue });
|
|
38
39
|
} else {
|
|
39
40
|
if (field == null) {
|
|
40
41
|
console.error("field is not defined in ColDef");
|
|
@@ -63,7 +64,11 @@ export const GridFormEditBearing = <RowType extends GridBaseRow>(props: GridForm
|
|
|
63
64
|
}}
|
|
64
65
|
autoFocus={true}
|
|
65
66
|
placeholder={props.placeHolder}
|
|
66
|
-
formatted={
|
|
67
|
+
formatted={
|
|
68
|
+
bearingStringValidator(value, props.range) || !props.formatValue
|
|
69
|
+
? "?"
|
|
70
|
+
: props.formatValue(bearingNumberParser(value))
|
|
71
|
+
}
|
|
67
72
|
error={bearingStringValidator(value, props.range)}
|
|
68
73
|
helpText={"Press enter or tab to save"}
|
|
69
74
|
/>
|
|
@@ -52,8 +52,8 @@ export interface GridFormMultiSelectProps<RowType extends GridBaseRow> extends C
|
|
|
52
52
|
filtered?: boolean;
|
|
53
53
|
filterPlaceholder?: string;
|
|
54
54
|
filterHelpText?: string | ((filter: string, options: MultiSelectOption[]) => string | undefined);
|
|
55
|
-
onSelectFilter?: (filter: string
|
|
56
|
-
onSave?: (selectedRows: RowType[]
|
|
55
|
+
onSelectFilter?: (props: { filter: string; options: MultiSelectOption[] }) => void;
|
|
56
|
+
onSave?: (props: { selectedRows: RowType[]; selectedOptions: MultiSelectOption[] }) => Promise<boolean>;
|
|
57
57
|
headers?: GridFormMultiSelectGroup[];
|
|
58
58
|
options: MultiSelectOption[] | ((selectedRows: RowType[]) => Promise<MultiSelectOption[]> | MultiSelectOption[]);
|
|
59
59
|
invalid?: (selectedRows: RowType[], selectedOptions: MultiSelectOption[]) => boolean;
|
|
@@ -90,10 +90,10 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow>(props: GridForm
|
|
|
90
90
|
// Any changes to save?
|
|
91
91
|
if (initialValues === JSON.stringify(options)) return true;
|
|
92
92
|
|
|
93
|
-
return props.onSave(
|
|
93
|
+
return props.onSave({
|
|
94
94
|
selectedRows,
|
|
95
|
-
options.filter((o) => o.checked),
|
|
96
|
-
);
|
|
95
|
+
selectedOptions: options.filter((o) => o.checked),
|
|
96
|
+
});
|
|
97
97
|
},
|
|
98
98
|
[initialValues, options, props],
|
|
99
99
|
);
|
|
@@ -203,7 +203,7 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow>(props: GridForm
|
|
|
203
203
|
const FilterInput = (props: {
|
|
204
204
|
options: MultiSelectOption[];
|
|
205
205
|
setOptions: (options: MultiSelectOption[]) => void;
|
|
206
|
-
onSelectFilter?: (filter: string
|
|
206
|
+
onSelectFilter?: (props: { filter: string; options: MultiSelectOption[] }) => void;
|
|
207
207
|
filter: string;
|
|
208
208
|
setFilter: Dispatch<SetStateAction<string>>;
|
|
209
209
|
headerGroups: HeaderGroupType;
|
|
@@ -259,7 +259,7 @@ const FilterInput = (props: {
|
|
|
259
259
|
}
|
|
260
260
|
|
|
261
261
|
const preFilterOptions = JSON.stringify(options);
|
|
262
|
-
onSelectFilter(filterTrimmed, options);
|
|
262
|
+
onSelectFilter({ filter: filterTrimmed, options });
|
|
263
263
|
// Detect if options list changed and update
|
|
264
264
|
if (preFilterOptions === JSON.stringify(options)) return;
|
|
265
265
|
|
|
@@ -8,13 +8,14 @@ import { GridSubComponentContext } from "../../contexts/GridSubComponentContext"
|
|
|
8
8
|
import { ClickEvent } from "../../react-menu3/types";
|
|
9
9
|
import { useGridPopoverContext } from "../../contexts/GridPopoverContext";
|
|
10
10
|
|
|
11
|
-
export interface
|
|
11
|
+
export interface GridFormPopoverMenuProps<RowType extends GridBaseRow> extends CellEditorCommon {
|
|
12
12
|
options: (selectedRows: RowType[]) => Promise<MenuOption<RowType>[]>;
|
|
13
|
-
defaultAction?: (selectedRows: RowType[]
|
|
13
|
+
defaultAction?: (props: { selectedRows: RowType[]; menuOption: SelectedMenuOptionResult<RowType> }) => Promise<void>;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/** Menu configuration types **/
|
|
17
|
-
|
|
17
|
+
const __isMenuSeparator__ = "__isMenuSeparator__";
|
|
18
|
+
export const PopoutMenuSeparator = Object.freeze({ label: __isMenuSeparator__ });
|
|
18
19
|
|
|
19
20
|
interface MenuSeparatorType {
|
|
20
21
|
__isMenuSeparator__: boolean;
|
|
@@ -26,7 +27,7 @@ export interface SelectedMenuOptionResult<RowType extends GridBaseRow> extends M
|
|
|
26
27
|
|
|
27
28
|
export interface MenuOption<RowType extends GridBaseRow> {
|
|
28
29
|
label: JSX.Element | string | MenuSeparatorType;
|
|
29
|
-
action?: (selectedRows: RowType[]
|
|
30
|
+
action?: (props: { selectedRows: RowType[]; menuOption: SelectedMenuOptionResult<RowType> }) => Promise<void>;
|
|
30
31
|
disabled?: string | boolean;
|
|
31
32
|
hidden?: boolean;
|
|
32
33
|
subComponent?: (props: any) => JSX.Element;
|
|
@@ -36,7 +37,7 @@ export interface MenuOption<RowType extends GridBaseRow> {
|
|
|
36
37
|
* NOTE: If the popout menu doesn't appear on single click when also selecting row it's because
|
|
37
38
|
* you need a useMemo around your columnDefs
|
|
38
39
|
*/
|
|
39
|
-
export const GridFormPopoverMenu = <RowType extends GridBaseRow>(props:
|
|
40
|
+
export const GridFormPopoverMenu = <RowType extends GridBaseRow>(props: GridFormPopoverMenuProps<RowType>) => {
|
|
40
41
|
const { selectedRows, updateValue, data } = useGridPopoverContext<RowType>();
|
|
41
42
|
|
|
42
43
|
const optionsInitialising = useRef(false);
|
|
@@ -47,9 +48,9 @@ export const GridFormPopoverMenu = <RowType extends GridBaseRow>(props: GridForm
|
|
|
47
48
|
const [subSelectedValue, setSubSelectedValue] = useState<any>();
|
|
48
49
|
|
|
49
50
|
const defaultAction = useCallback(
|
|
50
|
-
async (selectedRows: RowType[]
|
|
51
|
-
if (props.defaultAction) await props.defaultAction(
|
|
52
|
-
else console.error(`No action specified for ${menuOption.label} menu options`);
|
|
51
|
+
async (params: { selectedRows: RowType[]; menuOption: SelectedMenuOptionResult<RowType> }) => {
|
|
52
|
+
if (props.defaultAction) await props.defaultAction(params);
|
|
53
|
+
else console.error(`No action specified for ${params.menuOption.label} menu options`);
|
|
53
54
|
},
|
|
54
55
|
[props],
|
|
55
56
|
);
|
|
@@ -77,8 +78,10 @@ export const GridFormPopoverMenu = <RowType extends GridBaseRow>(props: GridForm
|
|
|
77
78
|
|
|
78
79
|
const actionClick = useCallback(
|
|
79
80
|
async (menuOption: MenuOption<RowType>) => {
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
await (menuOption.action ?? defaultAction)({
|
|
82
|
+
selectedRows,
|
|
83
|
+
menuOption: { ...menuOption, subValue: subSelectedValue },
|
|
84
|
+
});
|
|
82
85
|
return true;
|
|
83
86
|
},
|
|
84
87
|
[defaultAction, selectedRows, subSelectedValue],
|
|
@@ -117,49 +120,55 @@ export const GridFormPopoverMenu = <RowType extends GridBaseRow>(props: GridForm
|
|
|
117
120
|
return popoverWrapper(
|
|
118
121
|
<ComponentLoadingWrapper loading={!options} className={"GridFormPopupMenu"}>
|
|
119
122
|
<>
|
|
120
|
-
{options?.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
123
|
+
{options?.length === 0 ? (
|
|
124
|
+
<MenuItem key={`GridPopoverMenu-empty`} className={"GridPopoverMenu-noOptions"} disabled={true}>
|
|
125
|
+
No actions
|
|
126
|
+
</MenuItem>
|
|
127
|
+
) : (
|
|
128
|
+
options?.map((item, index) =>
|
|
129
|
+
item.label === "__isMenuSeparator__" ? (
|
|
130
|
+
<MenuDivider key={`$$divider_${index}`} />
|
|
131
|
+
) : (
|
|
132
|
+
!item.hidden && (
|
|
133
|
+
<Fragment key={`${item.label}`}>
|
|
134
|
+
<MenuItem
|
|
135
|
+
key={`${item.label}`}
|
|
136
|
+
onClick={(e: ClickEvent) => onMenuItemClick(e, item)}
|
|
137
|
+
disabled={!!item.disabled}
|
|
138
|
+
title={item.disabled && typeof item.disabled !== "boolean" ? item.disabled : ""}
|
|
139
|
+
>
|
|
140
|
+
{item.label as JSX.Element | string}
|
|
141
|
+
</MenuItem>
|
|
142
|
+
{item.subComponent && subComponentSelected === item && (
|
|
143
|
+
<FocusableItem className={"LuiDeprecatedForms"} key={`${item.label}_subcomponent`}>
|
|
144
|
+
{(_: any) =>
|
|
145
|
+
item.subComponent && (
|
|
146
|
+
<GridSubComponentContext.Provider
|
|
147
|
+
value={{
|
|
148
|
+
context: {},
|
|
149
|
+
data,
|
|
150
|
+
value: subSelectedValue,
|
|
151
|
+
setValue: (value: any) => {
|
|
152
|
+
setSubSelectedValue(value);
|
|
153
|
+
},
|
|
154
|
+
setValid: (valid: boolean) => {
|
|
155
|
+
subComponentIsValid.current = valid;
|
|
156
|
+
},
|
|
157
|
+
triggerSave,
|
|
158
|
+
}}
|
|
159
|
+
>
|
|
160
|
+
<div className={"subComponent"}>
|
|
161
|
+
<item.subComponent />
|
|
162
|
+
</div>
|
|
163
|
+
</GridSubComponentContext.Provider>
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
</FocusableItem>
|
|
167
|
+
)}
|
|
168
|
+
</Fragment>
|
|
169
|
+
)
|
|
170
|
+
),
|
|
171
|
+
)
|
|
163
172
|
)}
|
|
164
173
|
</>
|
|
165
174
|
</ComponentLoadingWrapper>,
|
|
@@ -11,7 +11,7 @@ export interface GridFormTextAreaProps<RowType extends GridBaseRow>
|
|
|
11
11
|
CellEditorCommon {
|
|
12
12
|
placeholder?: string;
|
|
13
13
|
width?: string | number;
|
|
14
|
-
onSave?: (selectedRows: RowType[]
|
|
14
|
+
onSave?: (props: { selectedRows: RowType[]; value: string }) => Promise<boolean>;
|
|
15
15
|
helpText?: string;
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -34,7 +34,7 @@ export const GridFormTextArea = <RowType extends GridBaseRow>(props: GridFormTex
|
|
|
34
34
|
if (initValue === trimmedValue) return true;
|
|
35
35
|
|
|
36
36
|
if (props.onSave) {
|
|
37
|
-
return await props.onSave(selectedRows, trimmedValue);
|
|
37
|
+
return await props.onSave({ selectedRows, value: trimmedValue });
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
selectedRows.forEach((row) => (row[field] = trimmedValue as any));
|
|
@@ -12,7 +12,7 @@ export interface GridFormTextInputProps<RowType extends GridBaseRow>
|
|
|
12
12
|
placeholder?: string;
|
|
13
13
|
units?: string;
|
|
14
14
|
width?: string | number;
|
|
15
|
-
onSave?: (selectedRows: RowType[]
|
|
15
|
+
onSave?: (props: { selectedRows: RowType[]; value: string }) => Promise<boolean>;
|
|
16
16
|
helpText?: string;
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -35,7 +35,7 @@ export const GridFormTextInput = <RowType extends GridBaseRow>(props: GridFormTe
|
|
|
35
35
|
if (initValue === trimmedValue) return true;
|
|
36
36
|
|
|
37
37
|
if (props.onSave) {
|
|
38
|
-
return await props.onSave(selectedRows, trimmedValue);
|
|
38
|
+
return await props.onSave({ selectedRows, value: trimmedValue });
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
selectedRows.forEach((row) => (row[field] = trimmedValue as any));
|
|
@@ -3,15 +3,19 @@ import { ColDefT, GenericCellEditorProps, GridCell } from "../GridCell";
|
|
|
3
3
|
import { GridFormEditBearing, GridFormEditBearingProps } from "../gridForm/GridFormEditBearing";
|
|
4
4
|
import { GridBaseRow } from "../Grid";
|
|
5
5
|
import { GenericCellColDef } from "../gridRender/GridRenderGenericCell";
|
|
6
|
+
import { ValueFormatterParams } from "ag-grid-community/dist/lib/entities/colDef";
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
const GridPopoverEditBearingLike = <RowType extends GridBaseRow>(
|
|
8
9
|
colDef: GenericCellColDef<RowType>,
|
|
9
|
-
props: GenericCellEditorProps<GridFormEditBearingProps<RowType
|
|
10
|
+
props: GenericCellEditorProps<GridFormEditBearingProps<RowType>> & {
|
|
11
|
+
editorParams: { formatValue: (value: any) => any };
|
|
12
|
+
},
|
|
10
13
|
): ColDefT<RowType> =>
|
|
11
14
|
GridCell(
|
|
12
15
|
{
|
|
13
16
|
initialWidth: 65,
|
|
14
17
|
maxWidth: 150,
|
|
18
|
+
valueFormatter: (params: ValueFormatterParams) => props.editorParams?.formatValue(params.value) ?? "",
|
|
15
19
|
...colDef,
|
|
16
20
|
},
|
|
17
21
|
{
|
|
@@ -20,44 +24,48 @@ export const GridPopoverEditBearingLike = <RowType extends GridBaseRow>(
|
|
|
20
24
|
},
|
|
21
25
|
);
|
|
22
26
|
|
|
27
|
+
export const GridPopoverEditBearingEditorParams = {
|
|
28
|
+
placeHolder: "Enter bearing",
|
|
29
|
+
formatValue: bearingValueFormatter,
|
|
30
|
+
range: (value: number | null) => {
|
|
31
|
+
if (value === null) return "Bearing is required";
|
|
32
|
+
if (value >= 360) return "Bearing must be less than 360 degrees";
|
|
33
|
+
if (value < 0) return "Bearing must not be negative";
|
|
34
|
+
return null;
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
23
38
|
export const GridPopoverEditBearing = <RowType extends GridBaseRow>(
|
|
24
39
|
colDef: GenericCellColDef<RowType>,
|
|
25
40
|
props: GenericCellEditorProps<GridFormEditBearingProps<RowType>>,
|
|
26
41
|
): ColDefT<RowType> =>
|
|
27
|
-
GridPopoverEditBearingLike(
|
|
28
|
-
|
|
29
|
-
{
|
|
30
|
-
|
|
31
|
-
editorParams
|
|
32
|
-
placeHolder: "Enter bearing correction",
|
|
33
|
-
range: (value: number | null) => {
|
|
34
|
-
if (value === null) return "Bearing correction is required";
|
|
35
|
-
if (value >= 360) return "Bearing correction must be less than 360 degrees";
|
|
36
|
-
if (value < 0) return "Bearing correction must not be negative";
|
|
37
|
-
return null;
|
|
38
|
-
},
|
|
39
|
-
...props.editorParams,
|
|
40
|
-
},
|
|
42
|
+
GridPopoverEditBearingLike(colDef, {
|
|
43
|
+
multiEdit: !!props.multiEdit,
|
|
44
|
+
editorParams: {
|
|
45
|
+
...GridPopoverEditBearingEditorParams,
|
|
46
|
+
...props.editorParams,
|
|
41
47
|
},
|
|
42
|
-
);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export const GridPopoverEditBearingCorrectionEditorParams = {
|
|
51
|
+
placeHolder: "Enter bearing correction",
|
|
52
|
+
formatValue: bearingCorrectionValueFormatter,
|
|
53
|
+
range: (value: number | null) => {
|
|
54
|
+
if (value === null) return "Bearing correction is required";
|
|
55
|
+
if (value >= 360) return "Bearing correction must be less than 360 degrees";
|
|
56
|
+
if (value <= -180) return "Bearing correction must be greater then -180 degrees";
|
|
57
|
+
return null;
|
|
58
|
+
},
|
|
59
|
+
};
|
|
43
60
|
|
|
44
61
|
export const GridPopoverEditBearingCorrection = <RowType extends GridBaseRow>(
|
|
45
62
|
colDef: GenericCellColDef<RowType>,
|
|
46
63
|
props: GenericCellEditorProps<GridFormEditBearingProps<RowType>>,
|
|
47
64
|
): ColDefT<RowType> =>
|
|
48
|
-
GridPopoverEditBearingLike(
|
|
49
|
-
|
|
50
|
-
{
|
|
51
|
-
|
|
52
|
-
editorParams
|
|
53
|
-
placeHolder: "Enter bearing correction",
|
|
54
|
-
range: (value: number | null) => {
|
|
55
|
-
if (value === null) return "Bearing is required";
|
|
56
|
-
if (value >= 360) return "Bearing must be less than 360 degrees";
|
|
57
|
-
if (value <= -180) return "Bearing must be greater then -180 degrees";
|
|
58
|
-
return null;
|
|
59
|
-
},
|
|
60
|
-
...props.editorParams,
|
|
61
|
-
},
|
|
65
|
+
GridPopoverEditBearingLike(colDef, {
|
|
66
|
+
multiEdit: !!props.multiEdit,
|
|
67
|
+
editorParams: {
|
|
68
|
+
...GridPopoverEditBearingCorrectionEditorParams,
|
|
69
|
+
...props.editorParams,
|
|
62
70
|
},
|
|
63
|
-
);
|
|
71
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GridBaseRow } from "../Grid";
|
|
2
2
|
import { ColDefT, GenericCellEditorProps, GridCell } from "../GridCell";
|
|
3
|
-
import { GridFormPopoverMenu,
|
|
3
|
+
import { GridFormPopoverMenu, GridFormPopoverMenuProps } from "../gridForm/GridFormPopoverMenu";
|
|
4
4
|
import { GridRenderPopoutMenuCell } from "../gridRender/GridRenderPopoutMenuCell";
|
|
5
5
|
import { GenericCellColDef } from "../gridRender/GridRenderGenericCell";
|
|
6
6
|
|
|
@@ -9,9 +9,9 @@ import { GenericCellColDef } from "../gridRender/GridRenderGenericCell";
|
|
|
9
9
|
*/
|
|
10
10
|
export const GridPopoverMenu = <RowType extends GridBaseRow>(
|
|
11
11
|
colDef: GenericCellColDef<RowType>,
|
|
12
|
-
custom: GenericCellEditorProps<
|
|
12
|
+
custom: GenericCellEditorProps<GridFormPopoverMenuProps<RowType>>,
|
|
13
13
|
): ColDefT<RowType> =>
|
|
14
|
-
GridCell<RowType,
|
|
14
|
+
GridCell<RowType, GridFormPopoverMenuProps<RowType>>(
|
|
15
15
|
{
|
|
16
16
|
minWidth: 40,
|
|
17
17
|
maxWidth: 40,
|