@linzjs/step-ag-grid 3.0.0 → 3.0.2

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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@linzjs/step-ag-grid",
3
3
  "repository": "github:linz/step-ag-grid.git",
4
4
  "license": "MIT",
5
- "version": "3.0.0",
5
+ "version": "3.0.2",
6
6
  "keywords": [
7
7
  "aggrid",
8
8
  "ag-grid",
@@ -2,7 +2,7 @@ import { useCallback, useContext, useEffect, useRef, useState } from "react";
2
2
  import { GridContext } from "../contexts/GridContext";
3
3
  import { GridBaseRow } from "./Grid";
4
4
  import { ControlledMenu } from "../react-menu3";
5
- import { GridPopoverContext } from "../contexts/GridPopoverContext";
5
+ import { useGridPopoverContext } from "../contexts/GridPopoverContext";
6
6
  import { MenuCloseEvent } from "../react-menu3/types";
7
7
 
8
8
  export interface GridPopoverHookProps<RowType> {
@@ -12,7 +12,7 @@ export interface GridPopoverHookProps<RowType> {
12
12
 
13
13
  export const useGridPopoverHook = <RowType extends GridBaseRow>(props: GridPopoverHookProps<RowType>) => {
14
14
  const { stopEditing } = useContext(GridContext);
15
- const { anchorRef, saving, updateValue } = useContext(GridPopoverContext);
15
+ const { anchorRef, saving, updateValue } = useGridPopoverContext<RowType>();
16
16
  const saveButtonRef = useRef<HTMLButtonElement>(null);
17
17
  const [isOpen, setOpen] = useState(false);
18
18
 
@@ -9,7 +9,7 @@ import { delay } from "lodash-es";
9
9
  import debounce from "debounce-promise";
10
10
  import { CellEditorCommon } from "../GridCell";
11
11
  import { useGridPopoverHook } from "../GridPopoverHook";
12
- import { GridPopoverContext } from "../../contexts/GridPopoverContext";
12
+ import { useGridPopoverContext } from "../../contexts/GridPopoverContext";
13
13
 
14
14
  export interface GridPopoutEditDropDownSelectedItem<RowType, ValueType> {
15
15
  // Note the row that was clicked on will be first
@@ -44,6 +44,7 @@ export interface GridFormPopoutDropDownProps<RowType extends GridBaseRow, ValueT
44
44
  | "GridPopoverEditDropDown-containerUnlimited"
45
45
  | string
46
46
  | undefined;
47
+ // local means the filter won't change if it's reloaded, reload means it does change
47
48
  filtered?: "local" | "reload";
48
49
  filterPlaceholder?: string;
49
50
  onSelectedItem?: (props: GridPopoutEditDropDownSelectedItem<RowType, ValueType>) => Promise<void>;
@@ -54,10 +55,14 @@ export interface GridFormPopoutDropDownProps<RowType extends GridBaseRow, ValueT
54
55
  optionsRequestCancel?: () => void;
55
56
  }
56
57
 
58
+ const fieldToString = (field: any) => {
59
+ return typeof field == "symbol" ? field.toString() : `${field}`;
60
+ };
61
+
57
62
  export const GridFormDropDown = <RowType extends GridBaseRow, ValueType>(
58
63
  props: GridFormPopoutDropDownProps<RowType, ValueType>,
59
64
  ) => {
60
- const { selectedRows, field, updateValue } = useContext(GridPopoverContext);
65
+ const { selectedRows, field, updateValue } = useGridPopoverContext<RowType>();
61
66
  const { stopEditing } = useContext(GridContext);
62
67
 
63
68
  const [filter, setFilter] = useState("");
@@ -208,7 +213,9 @@ export const GridFormDropDown = <RowType extends GridBaseRow, ValueType>(
208
213
  )}
209
214
  <ComponentLoadingWrapper loading={!options} className={"GridFormDropDown-options"}>
210
215
  <>
211
- {options && options.length == filteredValues?.length && <MenuItem key={`${field}-empty`}>[Empty]</MenuItem>}
216
+ {options && options.length == filteredValues?.length && (
217
+ <MenuItem key={`${fieldToString(field)}-empty`}>[Empty]</MenuItem>
218
+ )}
212
219
  {options?.map((item: FinalSelectOption<ValueType | string>, index) =>
213
220
  item.value === MenuSeparatorString ? (
214
221
  <MenuDivider key={`$$divider_${index}`} />
@@ -218,7 +225,7 @@ export const GridFormDropDown = <RowType extends GridBaseRow, ValueType>(
218
225
  <div key={`menu-wrapper-${index}`}>
219
226
  {!item.subComponent ? (
220
227
  <MenuItem
221
- key={`${field}-${index}`}
228
+ key={`${fieldToString(field)}-${index}`}
222
229
  disabled={!!item.disabled}
223
230
  title={item.disabled && typeof item.disabled !== "boolean" ? item.disabled : ""}
224
231
  value={item.value}
@@ -229,12 +236,11 @@ export const GridFormDropDown = <RowType extends GridBaseRow, ValueType>(
229
236
  {item.label ?? (item.value == null ? `<${item.value}>` : `${item.value}`)}
230
237
  </MenuItem>
231
238
  ) : (
232
- <FocusableItem className={"LuiDeprecatedForms"} key={`${field}-${index}_subcomponent`}>
239
+ <FocusableItem className={"LuiDeprecatedForms"} key={`${fieldToString(field)}-${index}_subcomponent`}>
233
240
  {(ref: any) =>
234
- item.subComponent &&
235
- item.subComponent(
236
- {
237
- setValue: (value: any) => {
241
+ item.subComponent && (
242
+ <item.subComponent
243
+ setValue={(value: any) => {
238
244
  const localSubComponentValues = [...subComponentValues];
239
245
  const subComponentValueIndex = localSubComponentValues.findIndex(
240
246
  ({ optionValue }) => optionValue === item.value,
@@ -248,8 +254,8 @@ export const GridFormDropDown = <RowType extends GridBaseRow, ValueType>(
248
254
  });
249
255
  }
250
256
  setSubComponentValues(localSubComponentValues);
251
- },
252
- keyDown: (key: string, event: KeyboardEvent<HTMLInputElement>) => {
257
+ }}
258
+ keyDown={(key: string, event: KeyboardEvent<HTMLInputElement>) => {
253
259
  const subComponentItem = subComponentValues.find(
254
260
  ({ optionValue }) => optionValue === item.value,
255
261
  );
@@ -265,10 +271,9 @@ export const GridFormDropDown = <RowType extends GridBaseRow, ValueType>(
265
271
  });
266
272
  }
267
273
  return false;
268
- },
269
- key: `${field}-${index}_subcomponent_inner`,
270
- },
271
- ref,
274
+ }}
275
+ key={`${fieldToString(field)}-${index}_subcomponent_inner`}
276
+ />
272
277
  )
273
278
  }
274
279
  </FocusableItem>
@@ -1,12 +1,12 @@
1
1
  import "../../styles/GridFormEditBearing.scss";
2
2
 
3
- import { useCallback, useContext, useState } from "react";
3
+ import { useCallback, useState } from "react";
4
4
  import { GridBaseRow } from "../Grid";
5
5
  import { TextInputFormatted } from "../../lui/TextInputFormatted";
6
6
  import { bearingNumberParser, bearingStringValidator, convertDDToDMS } from "../../utils/bearing";
7
7
  import { useGridPopoverHook } from "../GridPopoverHook";
8
8
  import { CellEditorCommon } from "../GridCell";
9
- import { GridPopoverContext } from "../../contexts/GridPopoverContext";
9
+ import { useGridPopoverContext } from "../../contexts/GridPopoverContext";
10
10
 
11
11
  export interface GridFormEditBearingProps<RowType extends GridBaseRow> extends CellEditorCommon {
12
12
  placeHolder?: string;
@@ -15,7 +15,7 @@ export interface GridFormEditBearingProps<RowType extends GridBaseRow> extends C
15
15
  }
16
16
 
17
17
  export const GridFormEditBearing = <RowType extends GridBaseRow>(props: GridFormEditBearingProps<RowType>) => {
18
- const { field, value: initialValue } = useContext(GridPopoverContext);
18
+ const { field, value: initialValue } = useGridPopoverContext<RowType>();
19
19
 
20
20
  const [value, setValue] = useState<string>(`${initialValue ?? ""}`);
21
21
 
@@ -34,7 +34,9 @@ export const GridFormEditBearing = <RowType extends GridBaseRow>(props: GridForm
34
34
  if (field == null) {
35
35
  console.error("field is not defined in ColDef");
36
36
  } else {
37
- selectedRows.forEach((row) => ((row as Record<string, any>)[field] = parsedValue));
37
+ selectedRows.forEach((row) => {
38
+ row[field] = parsedValue as any;
39
+ });
38
40
  }
39
41
  }
40
42
  return true;
@@ -1,17 +1,17 @@
1
1
  import clsx from "clsx";
2
- import { useContext, useEffect, useState } from "react";
2
+ import { useEffect, useState } from "react";
3
3
  import { ComponentLoadingWrapper } from "../ComponentLoadingWrapper";
4
4
  import { GridBaseRow } from "../Grid";
5
5
  import { useGridPopoverHook } from "../GridPopoverHook";
6
6
  import { CellEditorCommon } from "../GridCell";
7
- import { GridPopoverContext } from "../../contexts/GridPopoverContext";
7
+ import { useGridPopoverContext } from "../../contexts/GridPopoverContext";
8
8
 
9
9
  export interface GridFormMessageProps<RowType extends GridBaseRow> extends CellEditorCommon {
10
10
  message: (selectedRows: RowType[]) => Promise<string | JSX.Element> | string | JSX.Element;
11
11
  }
12
12
 
13
13
  export const GridFormMessage = <RowType extends GridBaseRow>(props: GridFormMessageProps<RowType>) => {
14
- const { selectedRows } = useContext(GridPopoverContext);
14
+ const { selectedRows } = useGridPopoverContext<RowType>();
15
15
 
16
16
  const [message, setMessage] = useState<string | JSX.Element | null>(null);
17
17
  const { popoverWrapper } = useGridPopoverHook({ className: props.className });
@@ -1,7 +1,7 @@
1
1
  import "../../styles/GridFormMultiSelect.scss";
2
2
 
3
3
  import { FocusableItem, MenuDivider, MenuItem } from "../../react-menu3";
4
- import { KeyboardEvent, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
4
+ import { KeyboardEvent, useCallback, useEffect, useMemo, useRef, useState } from "react";
5
5
  import { GridBaseRow } from "../Grid";
6
6
  import { ComponentLoadingWrapper } from "../ComponentLoadingWrapper";
7
7
  import { delay, fromPairs, isEqual, omit, pick, toPairs } from "lodash-es";
@@ -11,7 +11,7 @@ import { MenuSeparatorString } from "./GridFormDropDown";
11
11
  import { CellEditorCommon } from "../GridCell";
12
12
  import { ClickEvent } from "../../react-menu3/types";
13
13
  import { GridSubComponentContext } from "contexts/GridSubComponentContext";
14
- import { GridPopoverContext } from "../../contexts/GridPopoverContext";
14
+ import { useGridPopoverContext } from "../../contexts/GridPopoverContext";
15
15
 
16
16
  interface MultiFinalSelectOption<ValueType> {
17
17
  value: ValueType;
@@ -45,7 +45,7 @@ export interface GridFormMultiSelectProps<RowType extends GridBaseRow, ValueType
45
45
  export const GridFormMultiSelect = <RowType extends GridBaseRow, ValueType>(
46
46
  props: GridFormMultiSelectProps<RowType, ValueType>,
47
47
  ) => {
48
- const { selectedRows } = useContext(GridPopoverContext);
48
+ const { selectedRows } = useGridPopoverContext<RowType>();
49
49
 
50
50
  const initialiseValues = useMemo(() => {
51
51
  const r = props.initialSelectedValues && props.initialSelectedValues(selectedRows);
@@ -1,15 +1,16 @@
1
1
  import { GridBaseRow } from "../Grid";
2
- import { useCallback, useContext, useEffect, useRef, useState } from "react";
2
+ import { useCallback, useEffect, useRef, useState } from "react";
3
3
  import { ComponentLoadingWrapper } from "../ComponentLoadingWrapper";
4
4
  import { FocusableItem, MenuDivider, MenuItem } from "../../react-menu3";
5
5
  import { useGridPopoverHook } from "../GridPopoverHook";
6
6
  import { CellEditorCommon } from "../GridCell";
7
7
  import { GridSubComponentContext } from "../../contexts/GridSubComponentContext";
8
8
  import { ClickEvent } from "../../react-menu3/types";
9
- import { GridPopoverContext } from "../../contexts/GridPopoverContext";
9
+ import { useGridPopoverContext } from "../../contexts/GridPopoverContext";
10
10
 
11
11
  export interface GridFormPopoutMenuProps<RowType extends GridBaseRow> extends CellEditorCommon {
12
12
  options: (selectedRows: RowType[]) => Promise<MenuOption<RowType>[]>;
13
+ defaultAction?: (selectedRows: RowType[], menuOption: SelectedMenuOptionResult<RowType>) => Promise<void>;
13
14
  }
14
15
 
15
16
  /** Menu configuration types **/
@@ -37,7 +38,7 @@ export interface MenuOption<RowType extends GridBaseRow> {
37
38
  * you need a useMemo around your columnDefs
38
39
  */
39
40
  export const GridFormPopoverMenu = <RowType extends GridBaseRow>(props: GridFormPopoutMenuProps<RowType>) => {
40
- const { selectedRows, updateValue } = useContext(GridPopoverContext);
41
+ const { selectedRows, updateValue } = useGridPopoverContext<RowType>();
41
42
 
42
43
  const optionsInitialising = useRef(false);
43
44
  const [options, setOptions] = useState<MenuOption<RowType>[]>();
@@ -48,6 +49,14 @@ export const GridFormPopoverMenu = <RowType extends GridBaseRow>(props: GridForm
48
49
  const subComponentIsValid = useRef(false);
49
50
  const [subSelectedValue, setSubSelectedValue] = useState<any>();
50
51
 
52
+ const defaultAction = useCallback(
53
+ async (selectedRows: RowType[], menuOption: SelectedMenuOptionResult<RowType>) => {
54
+ if (props.defaultAction) await props.defaultAction(selectedRows, menuOption);
55
+ else console.error(`No action specified for ${menuOption.label} menu options`);
56
+ },
57
+ [props],
58
+ );
59
+
51
60
  // Load up options list if it's async function
52
61
  useEffect(() => {
53
62
  if (options || optionsInitialising.current) return;
@@ -55,22 +64,31 @@ export const GridFormPopoverMenu = <RowType extends GridBaseRow>(props: GridForm
55
64
  const optionsConf = props.options ?? [];
56
65
 
57
66
  (async () => {
58
- setOptions(typeof optionsConf == "function" ? await optionsConf(selectedRows) : optionsConf);
67
+ const newOptions = typeof optionsConf == "function" ? await optionsConf(selectedRows) : optionsConf;
68
+ setOptions(newOptions);
69
+ if (!props.defaultAction) {
70
+ const anyOptionsAreMissingAction = newOptions.some((option) => !option.action);
71
+ if (anyOptionsAreMissingAction) {
72
+ console.error("There's no default action handler and some Menu options are missing an action handler", {
73
+ invalidMenuOptions: newOptions.filter((option) => !option.action),
74
+ });
75
+ }
76
+ }
59
77
  optionsInitialising.current = false;
60
78
  })();
61
- }, [options, props.options, selectedRows]);
79
+ }, [options, props.defaultAction, props.options, selectedRows]);
62
80
 
63
81
  const actionClick = useCallback(
64
82
  async (menuOption: MenuOption<RowType>) => {
65
83
  actionProcessing.current = true;
66
84
  return updateValue(async () => {
67
85
  const result = { ...menuOption, subValue: subSelectedValue };
68
- menuOption.action && (await menuOption.action(selectedRows, result));
86
+ await (menuOption.action ?? defaultAction)(selectedRows, result);
69
87
  actionProcessing.current = false;
70
88
  return true;
71
89
  });
72
90
  },
73
- [selectedRows, subSelectedValue, updateValue],
91
+ [defaultAction, selectedRows, subSelectedValue, updateValue],
74
92
  );
75
93
 
76
94
  const onMenuItemClick = useCallback(
@@ -1,9 +1,9 @@
1
- import { useCallback, useContext, useState } from "react";
1
+ import { useCallback, useState } from "react";
2
2
  import { TextAreaInput } from "../../lui/TextAreaInput";
3
3
  import { useGridPopoverHook } from "../GridPopoverHook";
4
4
  import { GridBaseRow } from "../Grid";
5
5
  import { CellEditorCommon } from "../GridCell";
6
- import { GridPopoverContext } from "../../contexts/GridPopoverContext";
6
+ import { useGridPopoverContext } from "../../contexts/GridPopoverContext";
7
7
 
8
8
  export interface GridFormTextAreaProps<RowType extends GridBaseRow> extends CellEditorCommon {
9
9
  placeholder?: string;
@@ -15,8 +15,8 @@ export interface GridFormTextAreaProps<RowType extends GridBaseRow> extends Cell
15
15
  }
16
16
 
17
17
  export const GridFormTextArea = <RowType extends GridBaseRow>(props: GridFormTextAreaProps<RowType>) => {
18
- const { field, value: initialVale } = useContext(GridPopoverContext);
19
- const [value, setValue] = useState(initialVale ?? "");
18
+ const { field, value: initialVale } = useGridPopoverContext<RowType>();
19
+ const [value, setValue] = useState(initialVale != null ? `${initialVale}` : "");
20
20
 
21
21
  const invalid = useCallback(() => {
22
22
  if (props.required && value.length == 0) {
@@ -32,7 +32,7 @@ export const GridFormTextArea = <RowType extends GridBaseRow>(props: GridFormTex
32
32
  }, [props, value]);
33
33
 
34
34
  const save = useCallback(
35
- async (selectedRows: any[]): Promise<boolean> => {
35
+ async (selectedRows: RowType[]): Promise<boolean> => {
36
36
  if (invalid()) return false;
37
37
 
38
38
  if (initialVale === (value ?? "")) return true;
@@ -45,7 +45,9 @@ export const GridFormTextArea = <RowType extends GridBaseRow>(props: GridFormTex
45
45
  console.error("ColDef has no field set");
46
46
  return false;
47
47
  }
48
- selectedRows.forEach((row) => (row[field] = value));
48
+ selectedRows.forEach((row) => {
49
+ row[field] = value as any;
50
+ });
49
51
  return true;
50
52
  },
51
53
  [invalid, initialVale, value, props, field],
@@ -1,9 +1,9 @@
1
- import { useCallback, useContext, useState } from "react";
1
+ import { useCallback, useState } from "react";
2
2
  import { TextInputFormatted } from "../../lui/TextInputFormatted";
3
3
  import { useGridPopoverHook } from "../GridPopoverHook";
4
4
  import { GridBaseRow } from "../Grid";
5
5
  import { CellEditorCommon } from "../GridCell";
6
- import { GridPopoverContext } from "../../contexts/GridPopoverContext";
6
+ import { useGridPopoverContext } from "../../contexts/GridPopoverContext";
7
7
 
8
8
  export interface GridFormTextInputProps<RowType extends GridBaseRow> extends CellEditorCommon {
9
9
  placeholder?: string;
@@ -17,7 +17,7 @@ export interface GridFormTextInputProps<RowType extends GridBaseRow> extends Cel
17
17
  }
18
18
 
19
19
  export const GridFormTextInput = <RowType extends GridBaseRow>(props: GridFormTextInputProps<RowType>) => {
20
- const { field, data, value: initialVale } = useContext(GridPopoverContext);
20
+ const { field, data, value: initialVale } = useGridPopoverContext<RowType>();
21
21
 
22
22
  const initValue = initialVale == null ? "" : `${initialVale}`;
23
23
  const [value, setValue] = useState(initValue);
@@ -50,8 +50,9 @@ export const GridFormTextInput = <RowType extends GridBaseRow>(props: GridFormTe
50
50
  console.error("ColDef has no field set");
51
51
  return false;
52
52
  }
53
- // @ts-ignore row[field] row is of type any
54
- selectedRows.forEach((row) => (row[field] = trimmedValue));
53
+ selectedRows.forEach((row) => {
54
+ row[field] = trimmedValue as any;
55
+ });
55
56
  return true;
56
57
  },
57
58
  [invalid, value, initValue, props, field],
@@ -1,4 +1,5 @@
1
- import { createContext, RefObject } from "react";
1
+ import { createContext, RefObject, useContext } from "react";
2
+ import { GridBaseRow } from "../components/Grid";
2
3
 
3
4
  export interface PropsType {
4
5
  value: any;
@@ -8,24 +9,27 @@ export interface PropsType {
8
9
  updateValue: (saveFn: (selectedRows: any[]) => Promise<boolean>) => Promise<boolean>;
9
10
  }
10
11
 
11
- export type GridPopoverContextType = {
12
+ export interface GridPopoverContextType<RowType extends GridBaseRow> {
12
13
  anchorRef: RefObject<Element>;
13
14
  saving: boolean;
14
15
  setSaving: (saving: boolean) => void;
15
- field: string;
16
+ field: keyof RowType;
16
17
  value: any;
17
- data: any;
18
- selectedRows: any[];
18
+ data: RowType;
19
+ selectedRows: RowType[];
19
20
  updateValue: (saveFn: (selectedRows: any[]) => Promise<boolean>) => Promise<boolean>;
20
- };
21
+ }
21
22
 
22
- export const GridPopoverContext = createContext<GridPopoverContextType>({
23
+ export const GridPopoverContext = createContext<GridPopoverContextType<any>>({
23
24
  anchorRef: { current: null },
24
25
  saving: false,
25
26
  setSaving: () => {},
26
27
  field: "",
27
28
  value: null,
28
- data: null,
29
+ data: {} as GridBaseRow,
29
30
  selectedRows: [],
30
31
  updateValue: async () => false,
31
32
  });
33
+
34
+ export const useGridPopoverContext = <RowType extends GridBaseRow>() =>
35
+ useContext<GridPopoverContextType<RowType>>(GridPopoverContext);
package/src/index.ts CHANGED
@@ -1,10 +1,13 @@
1
1
  export * from "./react-menu3/index";
2
2
  export * from "./react-menu3/types";
3
3
 
4
- export * from "./contexts/GridUpdatingContext";
5
- export * from "./contexts/GridUpdatingContextProvider";
6
4
  export * from "./contexts/GridContext";
7
5
  export * from "./contexts/GridContextProvider";
6
+ export * from "./contexts/GridUpdatingContext";
7
+ export * from "./contexts/GridUpdatingContextProvider";
8
+ export * from "./contexts/GridPopoverContext";
9
+ export * from "./contexts/GridPopoverContextProvider";
10
+ export * from "./contexts/GridSubComponentContext";
8
11
 
9
12
  export type { GridBaseRow } from "./components/Grid";
10
13
  export { Grid } from "./components/Grid";
@@ -1,11 +1,11 @@
1
1
  import "./FormTest.scss";
2
2
 
3
- import { useCallback, useContext, useState } from "react";
3
+ import { useCallback, useState } from "react";
4
4
  import { LuiAlertModal, LuiAlertModalButtons, LuiButton, LuiTextInput } from "@linzjs/lui";
5
5
  import { wait } from "../../utils/util";
6
6
  import { CellEditorCommon } from "../../components/GridCell";
7
7
  import { useGridPopoverHook } from "../../components/GridPopoverHook";
8
- import { GridPopoverContext } from "../../contexts/GridPopoverContext";
8
+ import { useGridPopoverContext } from "../../contexts/GridPopoverContext";
9
9
 
10
10
  export interface IFormTestRow {
11
11
  id: number;
@@ -17,7 +17,7 @@ export interface IFormTestRow {
17
17
  }
18
18
 
19
19
  export const FormTest = (props: CellEditorCommon): JSX.Element => {
20
- const { value } = useContext(GridPopoverContext);
20
+ const { value } = useGridPopoverContext<IFormTestRow>();
21
21
  const [v1, ...v2] = value.split(" ");
22
22
 
23
23
  const [nameType, setNameType] = useState(v1);
@@ -135,7 +135,9 @@ const GridEditDropDownTemplate: ComponentStory<typeof Grid> = (props: GridProps)
135
135
  options: [null, "Architect", "Developer", "Product Owner", "Scrum Master", "Tester", "(other)"],
136
136
  onSelectedItem: async (selected) => {
137
137
  await wait(2000);
138
- selected.selectedRows.forEach((row) => (row.position3 = selected.value));
138
+ selected.selectedRows.forEach((row) => {
139
+ row.position3 = selected.value;
140
+ });
139
141
  },
140
142
  },
141
143
  },