@linzjs/step-ag-grid 8.0.0 → 8.2.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 +23 -5
- package/dist/src/components/gridForm/GridFormDropDown.d.ts +3 -2
- package/dist/src/components/gridForm/GridFormMultiSelect.d.ts +1 -0
- package/dist/src/components/gridForm/GridFormPopoverMenu.d.ts +3 -4
- package/dist/src/components/gridPopoverEdit/GridPopoverEditDropDown.d.ts +2 -2
- 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 -0
- package/dist/step-ag-grid.esm.js +107 -87
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/GridCell.tsx +2 -2
- package/src/components/gridForm/GridFormDropDown.tsx +94 -75
- package/src/components/gridForm/GridFormEditBearing.tsx +1 -1
- package/src/components/gridForm/GridFormMultiSelect.tsx +10 -8
- package/src/components/gridForm/GridFormPopoverMenu.tsx +53 -46
- package/src/components/gridPopoverEdit/GridPopoverEditBearing.ts +8 -13
- package/src/components/gridPopoverEdit/GridPopoverEditDropDown.ts +3 -3
- package/src/components/gridPopoverEdit/GridPopoverMenu.tsx +3 -3
- package/src/lui/ActionButton.tsx +3 -1
- package/src/react-menu3/styles/_var.scss +1 -1
- package/src/react-menu3/styles/index.scss +4 -0
- package/src/stories/components/ActionButton.stories.tsx +11 -0
- package/src/stories/grid/gridForm/GridFormDropDown.stories.tsx +81 -36
- package/src/stories/grid/gridForm/GridFormEditBearing.stories.tsx +9 -15
- package/src/stories/grid/gridForm/GridFormEditBearingCorrection.stories.tsx +9 -15
- package/src/stories/grid/gridForm/GridFormMessage.stories.tsx +31 -0
- package/src/stories/grid/gridForm/GridFormMultiSelect.stories.tsx +70 -0
- package/src/stories/grid/gridForm/GridFormPopoverMenu.stories.tsx +55 -0
- package/src/stories/grid/gridForm/GridFormTextArea.stories.tsx +44 -0
- package/src/stories/grid/gridForm/GridFormTextInput.stories.tsx +44 -0
- package/src/styles/Grid.scss +1 -1
- package/src/styles/GridFormMultiSelect.scss +4 -0
- package/src/styles/GridIcon.scss +10 -0
- package/src/styles/lui-overrides.scss +1 -1
- package/src/styles/react-menu-customisations.scss +2 -2
- package/src/utils/bearing.test.ts +46 -3
- package/src/utils/bearing.ts +14 -0
- package/src/stories/grid/gridForm/reactMenuTest.scss +0 -3
package/package.json
CHANGED
|
@@ -29,8 +29,8 @@ export const GridCellRenderer = (props: ICellRendererParams) => {
|
|
|
29
29
|
return (
|
|
30
30
|
<GridLoadableCell isLoading={checkUpdating(colDef.field ?? colDef.colId ?? "", props.data.id)}>
|
|
31
31
|
<>
|
|
32
|
-
{typeof warningText === "string" && <GridIcon icon={"
|
|
33
|
-
{typeof infoText === "string" && <GridIcon icon={"
|
|
32
|
+
{typeof warningText === "string" && <GridIcon icon={"ic_warning_outline"} title={warningText} />}
|
|
33
|
+
{typeof infoText === "string" && <GridIcon icon={"ic_info_outline"} title={infoText} />}
|
|
34
34
|
<div style={{ display: "flex", flex: 1, overflow: "hidden" }}>
|
|
35
35
|
{colDef?.cellRendererParams?.originalCellRenderer ? (
|
|
36
36
|
<colDef.cellRendererParams.originalCellRenderer {...props} />
|
|
@@ -36,7 +36,7 @@ export const MenuHeaderItem = (title: string) => {
|
|
|
36
36
|
|
|
37
37
|
export type SelectOption = null | string | FinalSelectOption;
|
|
38
38
|
|
|
39
|
-
export interface
|
|
39
|
+
export interface GridFormDropDownProps<RowType extends GridBaseRow> extends CellEditorCommon {
|
|
40
40
|
// This overrides CellEditorCommon to provide some common class options
|
|
41
41
|
className?:
|
|
42
42
|
| "GridPopoverEditDropDown-containerSmall"
|
|
@@ -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;
|
|
@@ -62,11 +63,11 @@ const fieldToString = (field: any) => {
|
|
|
62
63
|
return typeof field == "symbol" ? field.toString() : `${field}`;
|
|
63
64
|
};
|
|
64
65
|
|
|
65
|
-
export const GridFormDropDown = <RowType extends GridBaseRow>(props:
|
|
66
|
+
export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormDropDownProps<RowType>) => {
|
|
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 && (
|
|
@@ -211,7 +215,7 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
|
|
|
211
215
|
className={"LuiTextInput-input"}
|
|
212
216
|
ref={ref}
|
|
213
217
|
type="text"
|
|
214
|
-
placeholder={props.filterPlaceholder ?? "
|
|
218
|
+
placeholder={props.filterPlaceholder ?? "Filter..."}
|
|
215
219
|
data-testid={"filteredMenu-free-text-input"}
|
|
216
220
|
defaultValue={filter}
|
|
217
221
|
data-allowtabtosave={true}
|
|
@@ -233,80 +237,95 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
|
|
|
233
237
|
<ComponentLoadingWrapper loading={!options} className={"GridFormDropDown-options"}>
|
|
234
238
|
<>
|
|
235
239
|
{options && (isEmpty(options) || (filteredValues && isEmpty(filteredValues))) && (
|
|
236
|
-
<MenuItem
|
|
240
|
+
<MenuItem
|
|
241
|
+
key={`${fieldToString(field)}-empty`}
|
|
242
|
+
className={"GridPopoverEditDropDown-noOptions"}
|
|
243
|
+
disabled={true}
|
|
244
|
+
>
|
|
237
245
|
{props.noOptionsMessage ?? "No Options"}
|
|
238
246
|
</MenuItem>
|
|
239
247
|
)}
|
|
240
|
-
{options?.map((item: FinalSelectOption, index) =>
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
248
|
+
{options?.map((item: FinalSelectOption, index) => {
|
|
249
|
+
showHeader = null;
|
|
250
|
+
if (item.value === MenuSeparatorString) {
|
|
251
|
+
return <MenuDivider key={`$$divider_${index}`} />;
|
|
252
|
+
} else if (item.value === MenuHeaderString) {
|
|
253
|
+
lastHeader = <MenuHeader key={`$$header_${index}`}>{item.label}</MenuHeader>;
|
|
254
|
+
return <></>;
|
|
255
|
+
} else {
|
|
256
|
+
if (lastHeader) {
|
|
257
|
+
showHeader = lastHeader;
|
|
258
|
+
lastHeader = null;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return (
|
|
246
262
|
(!filteredValues || filteredValues.includes(item)) && (
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
263
|
+
<>
|
|
264
|
+
{showHeader}
|
|
265
|
+
<div key={`menu-wrapper-${index}`}>
|
|
266
|
+
<MenuItem
|
|
267
|
+
key={`${fieldToString(field)}-${index}`}
|
|
268
|
+
disabled={!!item.disabled}
|
|
269
|
+
title={item.disabled && typeof item.disabled !== "boolean" ? item.disabled : ""}
|
|
270
|
+
value={item.value}
|
|
271
|
+
onFocus={() => {
|
|
256
272
|
setSelectedItem(item);
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
+
if (item.subComponent) {
|
|
274
|
+
setSelectedItem(item);
|
|
275
|
+
subComponentIsValid.current = true;
|
|
276
|
+
subComponentInitialValue.current = null;
|
|
277
|
+
} else {
|
|
278
|
+
setSubSelectedValue(null);
|
|
279
|
+
subComponentIsValid.current = true;
|
|
280
|
+
}
|
|
281
|
+
}}
|
|
282
|
+
onClick={(e: ClickEvent) => {
|
|
283
|
+
if (item.subComponent) {
|
|
284
|
+
e.keepOpen = true;
|
|
285
|
+
}
|
|
286
|
+
}}
|
|
287
|
+
>
|
|
288
|
+
{item.label ?? (item.value == null ? `<${item.value}>` : `${item.value}`)}
|
|
289
|
+
{item.subComponent ? "..." : ""}
|
|
290
|
+
</MenuItem>
|
|
273
291
|
|
|
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
|
-
|
|
292
|
+
{item.subComponent && selectedItem === item && (
|
|
293
|
+
<FocusableItem className={"LuiDeprecatedForms"} key={`${item.label}_subcomponent`}>
|
|
294
|
+
{(ref: MenuInstance) => (
|
|
295
|
+
<GridSubComponentContext.Provider
|
|
296
|
+
value={{
|
|
297
|
+
context: { options },
|
|
298
|
+
data,
|
|
299
|
+
value: subSelectedValue,
|
|
300
|
+
setValue: (value: any) => {
|
|
301
|
+
setSubSelectedValue(value);
|
|
302
|
+
if (subComponentInitialValue.current === null) {
|
|
303
|
+
// copy the default value of the subcomponent so we can change detect on save
|
|
304
|
+
subComponentInitialValue.current = JSON.stringify(value);
|
|
305
|
+
}
|
|
306
|
+
},
|
|
307
|
+
setValid: (valid: boolean) => {
|
|
308
|
+
subComponentIsValid.current = valid;
|
|
309
|
+
},
|
|
310
|
+
triggerSave: async () => {
|
|
311
|
+
ref.closeMenu();
|
|
312
|
+
},
|
|
313
|
+
}}
|
|
314
|
+
>
|
|
315
|
+
{item.subComponent && (
|
|
316
|
+
<div className={"subComponent"}>
|
|
317
|
+
<item.subComponent key={`${fieldToString(field)}-${index}_subcomponent_inner`} />
|
|
318
|
+
</div>
|
|
319
|
+
)}
|
|
320
|
+
</GridSubComponentContext.Provider>
|
|
321
|
+
)}
|
|
322
|
+
</FocusableItem>
|
|
323
|
+
)}
|
|
324
|
+
</div>
|
|
325
|
+
</>
|
|
307
326
|
)
|
|
308
|
-
)
|
|
309
|
-
)}
|
|
327
|
+
);
|
|
328
|
+
})}
|
|
310
329
|
</>
|
|
311
330
|
</ComponentLoadingWrapper>
|
|
312
331
|
</>,
|
|
@@ -56,7 +56,7 @@ export const GridFormEditBearing = <RowType extends GridBaseRow>(props: GridForm
|
|
|
56
56
|
});
|
|
57
57
|
|
|
58
58
|
return popoverWrapper(
|
|
59
|
-
<div className={"GridFormEditBearing-input
|
|
59
|
+
<div className={"GridFormEditBearing-input"}>
|
|
60
60
|
<TextInputFormatted
|
|
61
61
|
value={defaultValue}
|
|
62
62
|
onChange={(e) => {
|
|
@@ -52,6 +52,7 @@ 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
|
+
noOptionsMessage?: string;
|
|
55
56
|
onSelectFilter?: (props: { filter: string; options: MultiSelectOption[] }) => void;
|
|
56
57
|
onSave?: (props: { selectedRows: RowType[]; selectedOptions: MultiSelectOption[] }) => Promise<boolean>;
|
|
57
58
|
headers?: GridFormMultiSelectGroup[];
|
|
@@ -117,7 +118,7 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow>(props: GridForm
|
|
|
117
118
|
const headerGroups = useMemo(() => {
|
|
118
119
|
if (!options) return undefined;
|
|
119
120
|
const result = groupBy(
|
|
120
|
-
options.filter((o) => textMatch(o.label, filter) && o.value),
|
|
121
|
+
options.filter((o) => textMatch(o.label, filter) && o.value != null),
|
|
121
122
|
"filter",
|
|
122
123
|
);
|
|
123
124
|
// remove leading/trailing/duplicate dividers
|
|
@@ -163,8 +164,12 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow>(props: GridForm
|
|
|
163
164
|
filterPlaceholder={props.filterPlaceholder}
|
|
164
165
|
/>
|
|
165
166
|
)}
|
|
166
|
-
|
|
167
|
-
|
|
167
|
+
{headerGroups && (isEmpty(headerGroups) || !toPairs(headerGroups).some(([_, options]) => !isEmpty(options))) && (
|
|
168
|
+
<MenuItem key={"noOptions"} className={"GridMultiSelect-noOptions"} disabled={true}>
|
|
169
|
+
{props.noOptionsMessage ?? "No Options"}
|
|
170
|
+
</MenuItem>
|
|
171
|
+
)}
|
|
172
|
+
{headerGroups && !isEmpty(headerGroups) && (
|
|
168
173
|
<div className={"GridFormMultiSelect-options"}>
|
|
169
174
|
{headers.map((header, index) => {
|
|
170
175
|
const subOptions = headerGroups[`${header.filter}`];
|
|
@@ -307,7 +312,7 @@ const FilterInput = (props: {
|
|
|
307
312
|
<input
|
|
308
313
|
className={"LuiTextInput-input"}
|
|
309
314
|
type="text"
|
|
310
|
-
placeholder={filterPlaceholder ?? "
|
|
315
|
+
placeholder={filterPlaceholder ?? "Filter..."}
|
|
311
316
|
data-testid={"filteredMenu-free-text-input"}
|
|
312
317
|
value={filter}
|
|
313
318
|
data-disableenterautosave={true}
|
|
@@ -328,9 +333,6 @@ const FilterInput = (props: {
|
|
|
328
333
|
)}
|
|
329
334
|
</FocusableItem>
|
|
330
335
|
<MenuDivider key={`$$divider_filter`} />
|
|
331
|
-
{headerGroups && !toPairs(headerGroups).some(([_, options]) => !isEmpty(options)) && (
|
|
332
|
-
<div className={"szh-menu__item GridPopoverEditDropDown-noOptions"}>No Options</div>
|
|
333
|
-
)}
|
|
334
336
|
</>
|
|
335
337
|
);
|
|
336
338
|
};
|
|
@@ -365,7 +367,7 @@ const MenuRadioItem = (props: {
|
|
|
365
367
|
value={`${item.value}`}
|
|
366
368
|
label={
|
|
367
369
|
<>
|
|
368
|
-
{item.warning && <GridIcon icon={"
|
|
370
|
+
{item.warning && <GridIcon icon={"ic_warning_outline"} title={item.warning} />}
|
|
369
371
|
{item.label ?? (item.value == null ? `<${item.value}>` : `${item.value}`)}
|
|
370
372
|
</>
|
|
371
373
|
}
|
|
@@ -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
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;
|
|
@@ -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);
|
|
@@ -119,49 +120,55 @@ export const GridFormPopoverMenu = <RowType extends GridBaseRow>(props: GridForm
|
|
|
119
120
|
return popoverWrapper(
|
|
120
121
|
<ComponentLoadingWrapper loading={!options} className={"GridFormPopupMenu"}>
|
|
121
122
|
<>
|
|
122
|
-
{options?.
|
|
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
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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
|
+
)
|
|
165
172
|
)}
|
|
166
173
|
</>
|
|
167
174
|
</ComponentLoadingWrapper>,
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
bearingCorrectionRangeValidator,
|
|
3
|
+
bearingCorrectionValueFormatter,
|
|
4
|
+
bearingRangeValidator,
|
|
5
|
+
bearingValueFormatter,
|
|
6
|
+
} from "../../utils/bearing";
|
|
2
7
|
import { ColDefT, GenericCellEditorProps, GridCell } from "../GridCell";
|
|
3
8
|
import { GridFormEditBearing, GridFormEditBearingProps } from "../gridForm/GridFormEditBearing";
|
|
4
9
|
import { GridBaseRow } from "../Grid";
|
|
@@ -27,12 +32,7 @@ const GridPopoverEditBearingLike = <RowType extends GridBaseRow>(
|
|
|
27
32
|
export const GridPopoverEditBearingEditorParams = {
|
|
28
33
|
placeHolder: "Enter bearing",
|
|
29
34
|
formatValue: bearingValueFormatter,
|
|
30
|
-
range:
|
|
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
|
-
},
|
|
35
|
+
range: bearingRangeValidator,
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
export const GridPopoverEditBearing = <RowType extends GridBaseRow>(
|
|
@@ -50,12 +50,7 @@ export const GridPopoverEditBearing = <RowType extends GridBaseRow>(
|
|
|
50
50
|
export const GridPopoverEditBearingCorrectionEditorParams = {
|
|
51
51
|
placeHolder: "Enter bearing correction",
|
|
52
52
|
formatValue: bearingCorrectionValueFormatter,
|
|
53
|
-
range:
|
|
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
|
-
},
|
|
53
|
+
range: bearingCorrectionRangeValidator,
|
|
59
54
|
};
|
|
60
55
|
|
|
61
56
|
export const GridPopoverEditBearingCorrection = <RowType extends GridBaseRow>(
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ColDefT, GenericCellEditorProps, GridCell } from "../GridCell";
|
|
2
2
|
import { GridBaseRow } from "../Grid";
|
|
3
|
-
import { GridFormDropDown,
|
|
3
|
+
import { GridFormDropDown, GridFormDropDownProps } from "../gridForm/GridFormDropDown";
|
|
4
4
|
import { GenericCellColDef } from "../gridRender/GridRenderGenericCell";
|
|
5
5
|
|
|
6
6
|
export const GridPopoverEditDropDown = <RowType extends GridBaseRow>(
|
|
7
7
|
colDef: GenericCellColDef<RowType>,
|
|
8
|
-
props: GenericCellEditorProps<
|
|
8
|
+
props: GenericCellEditorProps<GridFormDropDownProps<RowType>>,
|
|
9
9
|
): ColDefT<RowType> =>
|
|
10
10
|
GridCell(colDef, {
|
|
11
11
|
editor: GridFormDropDown,
|
|
@@ -13,6 +13,6 @@ export const GridPopoverEditDropDown = <RowType extends GridBaseRow>(
|
|
|
13
13
|
editorParams: {
|
|
14
14
|
// Defaults to large size container
|
|
15
15
|
className: "GridPopoverEditDropDown-containerLarge",
|
|
16
|
-
...(props.editorParams as
|
|
16
|
+
...(props.editorParams as GridFormDropDownProps<RowType>),
|
|
17
17
|
},
|
|
18
18
|
});
|
|
@@ -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,
|
package/src/lui/ActionButton.tsx
CHANGED
|
@@ -21,6 +21,7 @@ export interface ActionButtonProps {
|
|
|
21
21
|
onClick: () => Promise<void> | void;
|
|
22
22
|
level?: LuiButtonProps["level"];
|
|
23
23
|
style?: CSSProperties;
|
|
24
|
+
disabled?: boolean;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
// Kept this less than one second, so I don't have issues with waitFor as it defaults to 1s
|
|
@@ -30,6 +31,7 @@ export const ActionButton = ({
|
|
|
30
31
|
icon,
|
|
31
32
|
name,
|
|
32
33
|
inProgressName,
|
|
34
|
+
disabled,
|
|
33
35
|
dataTestId,
|
|
34
36
|
style,
|
|
35
37
|
className,
|
|
@@ -83,7 +85,7 @@ export const ActionButton = ({
|
|
|
83
85
|
setInProgress(false);
|
|
84
86
|
}
|
|
85
87
|
}}
|
|
86
|
-
disabled={localInProgress}
|
|
88
|
+
disabled={localInProgress || disabled}
|
|
87
89
|
>
|
|
88
90
|
{iconPosition === "right" && buttonText}
|
|
89
91
|
{localInProgress ? (
|
|
@@ -39,6 +39,17 @@ const ActionButtonTemplate: ComponentStory<typeof ActionButton> = () => {
|
|
|
39
39
|
className={"ActionButton-fill"}
|
|
40
40
|
style={{ maxWidth: 160 }}
|
|
41
41
|
/>
|
|
42
|
+
<br />
|
|
43
|
+
<ActionButton
|
|
44
|
+
icon={"ic_arrow_forward_right"}
|
|
45
|
+
name={"Disabled"}
|
|
46
|
+
onClick={performAction}
|
|
47
|
+
iconPosition={"right"}
|
|
48
|
+
level={"secondary"}
|
|
49
|
+
className={"ActionButton-fill"}
|
|
50
|
+
style={{ maxWidth: 160 }}
|
|
51
|
+
disabled={true}
|
|
52
|
+
/>
|
|
42
53
|
</>
|
|
43
54
|
);
|
|
44
55
|
};
|