@linzjs/step-ag-grid 1.5.1 → 1.5.3

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": "1.5.1",
5
+ "version": "1.5.3",
6
6
  "main": "dist/index.js",
7
7
  "typings": "dist/index.d.ts",
8
8
  "module": "dist/step-ag-grid.esm.js",
@@ -72,8 +72,9 @@ export const GridCell = <RowType extends GridBaseRow, FormProps extends GenericC
72
72
  }),
73
73
  // Default value formatter, otherwise react freaks out on objects
74
74
  valueFormatter: (params: ValueFormatterParams) => {
75
- const types = ["number", "undefined", "boolean", "string"];
76
- if (types.includes(typeof params.value)) return params.value;
75
+ if (params.value == null) return "-";
76
+ const types = ["number", "boolean", "string"];
77
+ if (types.includes(typeof params.value)) return `${params.value}`;
77
78
  else return JSON.stringify(params.value);
78
79
  },
79
80
  ...props,
@@ -130,6 +131,7 @@ export const GenericCellEditorComponentFr = <RowType extends GridBaseRow, FormPr
130
131
  updateValue={updateValue}
131
132
  saving={saving}
132
133
  formProps={formProps}
134
+ data={data}
133
135
  value={value}
134
136
  field={field}
135
137
  selectedRows={selectedRows}
@@ -4,7 +4,7 @@ import { MenuItem, MenuDivider, FocusableItem, ClickEvent } from "@react-menu3";
4
4
  import { Fragment, useCallback, useEffect, useRef, useState, KeyboardEvent } from "react";
5
5
  import { GridBaseRow } from "../Grid";
6
6
  import { ComponentLoadingWrapper } from "../ComponentLoadingWrapper";
7
- import { delay } from "lodash-es";
7
+ import { delay, fromPairs } from "lodash-es";
8
8
  import { LuiCheckboxInput } from "@linzjs/lui";
9
9
  import { GenericCellEditorParams, GridFormProps } from "../GridCell";
10
10
  import { useGridPopoverHook } from "../GridPopoverHook";
@@ -33,6 +33,7 @@ export interface GridFormMultiSelectProps<RowType extends GridBaseRow, ValueType
33
33
  options:
34
34
  | SelectOption<ValueType>[]
35
35
  | ((selectedRows: RowType[]) => Promise<SelectOption<ValueType>[]> | SelectOption<ValueType>[]);
36
+ initialSelectedValues?: (selectedRows: RowType[]) => any[];
36
37
  }
37
38
 
38
39
  export const GridFormMultiSelect = <RowType extends GridBaseRow, ValueType>(props: GridFormProps<RowType>) => {
@@ -43,16 +44,17 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow, ValueType>(prop
43
44
  const optionsInitialising = useRef(false);
44
45
  const [options, setOptions] = useState<FinalSelectOption<ValueType>[]>();
45
46
  const subSelectedValues = useRef<Record<string, any>>({});
46
- const [selectedValues, setSelectedValues] = useState<any[]>([]);
47
+ const [selectedValues, setSelectedValues] = useState<any[]>(() =>
48
+ formProps.initialSelectedValues ? formProps.initialSelectedValues(props.selectedRows) : [],
49
+ );
47
50
 
48
51
  const save = useCallback(
49
52
  async (selectedRows: RowType[]): Promise<boolean> => {
50
- const values: Record<string, any> = {};
51
- selectedValues.forEach((value) => {
52
- values[value] = subSelectedValues.current[value] ?? true;
53
- });
53
+ const values: Record<string, any> = fromPairs(
54
+ selectedValues.map((value) => [value, subSelectedValues.current[value] ?? true]),
55
+ );
54
56
  if (formProps.onSave) {
55
- return await formProps.onSave({ selectedRows, values: selectedValues });
57
+ return await formProps.onSave({ selectedRows, values });
56
58
  }
57
59
  return true;
58
60
  },
@@ -6,6 +6,7 @@ import { GridBaseRow } from "../Grid";
6
6
 
7
7
  export interface GridFormTextInputProps<RowType extends GridBaseRow> extends GenericCellEditorParams<RowType> {
8
8
  placeholder?: string;
9
+ units?: string;
9
10
  required?: boolean;
10
11
  maxlength?: number;
11
12
  width?: string | number;
@@ -15,17 +16,19 @@ export interface GridFormTextInputProps<RowType extends GridBaseRow> extends Gen
15
16
 
16
17
  export const GridFormTextInput = <RowType extends GridBaseRow>(props: GridFormProps<RowType>) => {
17
18
  const formProps = props.formProps as GridFormTextInputProps<RowType>;
18
- const [value, setValue] = useState(props.value ?? "");
19
+ const initValue = props.value == null ? "" : `${props.value}`;
20
+ const [value, setValue] = useState(initValue);
19
21
 
20
22
  const invalid = useCallback(() => {
21
- if (formProps.required && value.length == 0) {
23
+ const trimmedValue = value.trim();
24
+ if (formProps.required && trimmedValue.length == 0) {
22
25
  return `Some text is required`;
23
26
  }
24
- if (formProps.maxlength && value.length > formProps.maxlength) {
27
+ if (formProps.maxlength && trimmedValue.length > formProps.maxlength) {
25
28
  return `Text must be no longer than ${formProps.maxlength} characters`;
26
29
  }
27
30
  if (formProps.validate) {
28
- return formProps.validate(value);
31
+ return formProps.validate(trimmedValue);
29
32
  }
30
33
  return null;
31
34
  }, [formProps, value]);
@@ -33,11 +36,11 @@ export const GridFormTextInput = <RowType extends GridBaseRow>(props: GridFormPr
33
36
  const save = useCallback(
34
37
  async (selectedRows: any[]): Promise<boolean> => {
35
38
  if (invalid()) return false;
36
-
37
- if (props.value === (value ?? "")) return true;
39
+ const trimmedValue = value.trim();
40
+ if (initValue === trimmedValue) return true;
38
41
 
39
42
  if (formProps.onSave) {
40
- return await formProps.onSave(selectedRows, value);
43
+ return await formProps.onSave(selectedRows, trimmedValue);
41
44
  }
42
45
 
43
46
  const field = props.field;
@@ -45,10 +48,10 @@ export const GridFormTextInput = <RowType extends GridBaseRow>(props: GridFormPr
45
48
  console.error("ColDef has no field set");
46
49
  return false;
47
50
  }
48
- selectedRows.forEach((row) => (row[field] = value));
51
+ selectedRows.forEach((row) => (row[field] = trimmedValue));
49
52
  return true;
50
53
  },
51
- [invalid, props.value, props.field, value, formProps],
54
+ [invalid, value, initValue, formProps, props.field],
52
55
  );
53
56
  const { popoverWrapper, triggerSave } = useGridPopoverHook(props, save);
54
57
 
@@ -58,7 +61,7 @@ export const GridFormTextInput = <RowType extends GridBaseRow>(props: GridFormPr
58
61
  value={value}
59
62
  onChange={(e) => setValue(e.target.value)}
60
63
  error={invalid()}
61
- formatted={""}
64
+ formatted={formProps.units}
62
65
  inputProps={{
63
66
  style: { width: "100%" },
64
67
  placeholder: formProps.placeholder,
@@ -14,9 +14,8 @@ export interface LuiTextInputProps {
14
14
  className?: string;
15
15
  value: string;
16
16
 
17
- icon?: JSX.Element;
18
17
  placeholder?: string;
19
- formatted: string;
18
+ formatted?: string;
20
19
  }
21
20
 
22
21
  export const TextInputFormatted = (props: LuiTextInputProps): JSX.Element => {
@@ -39,7 +38,6 @@ export const TextInputFormatted = (props: LuiTextInputProps): JSX.Element => {
39
38
  {...props.inputProps}
40
39
  />
41
40
  <span className={"LuiTextInput-formatted"}>{props.formatted}</span>
42
- {props.icon}
43
41
  </span>
44
42
 
45
43
  {props.error && (
@@ -13,6 +13,7 @@ export interface IFormTestRow {
13
13
  nameType: string;
14
14
  numba: string;
15
15
  plan: string;
16
+ distance: number | null;
16
17
  }
17
18
 
18
19
  export const FormTest = <RowType extends GridBaseRow>(props: GridFormProps<RowType>): JSX.Element => {
@@ -9,7 +9,7 @@ import { Grid, GridProps } from "@components/Grid";
9
9
  import { useMemo, useState } from "react";
10
10
  import { GridCell } from "@components/GridCell";
11
11
  import { IFormTestRow } from "./FormTest";
12
- import { wait } from "@utils/util";
12
+ import { isFloat, wait } from "@utils/util";
13
13
  import { GridPopoverTextArea } from "@components/gridPopoverEdit/GridPopoverTextArea";
14
14
  import { GridPopoverTextInput } from "@components/gridPopoverEdit/GridPopoverTextInput";
15
15
 
@@ -63,6 +63,30 @@ const GridPopoutEditGenericTemplate: ComponentStory<typeof Grid> = (props: GridP
63
63
  },
64
64
  },
65
65
  }),
66
+ GridPopoverTextInput<IFormTestRow>({
67
+ field: "distance",
68
+ headerName: "Number input",
69
+ maxWidth: 140,
70
+ valueFormatter: (params) => {
71
+ const v = params.data.distance;
72
+ return v != null ? `${v}${params.colDef.cellEditorParams.units}` : v;
73
+ },
74
+ cellEditorParams: {
75
+ maxlength: 12,
76
+ placeholder: "Enter distance...",
77
+ units: "m",
78
+ validate: (value: string) => {
79
+ if (value.length && !isFloat(value)) return "Value must be a number";
80
+ return null;
81
+ },
82
+ multiEdit: false,
83
+ onSave: async (selectedRows, value) => {
84
+ await wait(1000);
85
+ selectedRows.forEach((selectedRow) => (selectedRow["distance"] = value.length ? parseFloat(value) : null));
86
+ return true;
87
+ },
88
+ },
89
+ }),
66
90
  GridPopoverTextArea<IFormTestRow>({
67
91
  field: "plan",
68
92
  headerName: "Text area",
@@ -90,8 +114,8 @@ const GridPopoutEditGenericTemplate: ComponentStory<typeof Grid> = (props: GridP
90
114
  const rowData = useMemo(
91
115
  () =>
92
116
  [
93
- { id: 1000, name: "IS IS DP12345", nameType: "IS", numba: "IX", plan: "DP 12345" },
94
- { id: 1001, name: "PEG V SD523", nameType: "PEG", numba: "V", plan: "SD 523" },
117
+ { id: 1000, name: "IS IS DP12345", nameType: "IS", numba: "IX", plan: "DP 12345", distance: 10 },
118
+ { id: 1001, name: "PEG V SD523", nameType: "PEG", numba: "V", plan: "SD 523", distance: null },
95
119
  ] as IFormTestRow[],
96
120
  [],
97
121
  );
@@ -45,48 +45,71 @@ interface ITestRow {
45
45
  const GridEditMultiSelectTemplate: ComponentStory<typeof Grid> = (props: GridProps) => {
46
46
  const [externalSelectedItems, setExternalSelectedItems] = useState<any[]>([]);
47
47
 
48
- const columnDefs = useMemo(
49
- () =>
50
- [
51
- GridCell({
52
- field: "id",
53
- headerName: "Id",
54
- initialWidth: 65,
55
- maxWidth: 85,
56
- }),
57
- GridPopoutEditMultiSelect<ITestRow, ITestRow["position"]>({
58
- field: "position",
59
- initialWidth: 65,
60
- maxWidth: 150,
61
- headerName: "Position",
62
- cellEditorParams: {
63
- multiEdit: false,
64
- filtered: true,
65
- filterPlaceholder: "Filter position",
66
- options: [
67
- { value: "a", label: "Architect" },
68
- { value: "b", label: "Developer" },
69
- { value: "c", label: "Product Owner" },
70
- { value: "d", label: "Scrum Master" },
71
- { value: "e", label: "Tester" },
72
- MenuSeparator,
73
- {
74
- value: "f",
75
- label: "Other",
76
- subComponent: (props) => <GridSubComponentTextArea {...props} />,
77
- },
78
- ],
79
- onSave: async (result: MultiSelectResult<ITestRow>) => {
80
- // eslint-disable-next-line no-console
81
- console.log(result);
82
- await wait(1000);
83
- return true;
48
+ const columnDefs = useMemo(() => {
49
+ const positionTwoMap: Record<string, string> = {
50
+ "1": "One",
51
+ "2": "Two",
52
+ "3": "Three",
53
+ };
54
+ return [
55
+ GridCell({
56
+ field: "id",
57
+ headerName: "Id",
58
+ initialWidth: 65,
59
+ maxWidth: 85,
60
+ }),
61
+ GridPopoutEditMultiSelect<ITestRow, ITestRow["position"]>({
62
+ field: "position",
63
+ initialWidth: 65,
64
+ maxWidth: 150,
65
+ headerName: "Position",
66
+ cellEditorParams: {
67
+ multiEdit: false,
68
+ filtered: true,
69
+ filterPlaceholder: "Filter position",
70
+ options: [
71
+ { value: "a", label: "Architect" },
72
+ { value: "b", label: "Developer" },
73
+ { value: "c", label: "Product Owner" },
74
+ { value: "d", label: "Scrum Master" },
75
+ { value: "e", label: "Tester" },
76
+ MenuSeparator,
77
+ {
78
+ value: "f",
79
+ label: "Other",
80
+ subComponent: (props) => <GridSubComponentTextArea {...props} />,
84
81
  },
82
+ ],
83
+ onSave: async (result: MultiSelectResult<ITestRow>) => {
84
+ // eslint-disable-next-line no-console
85
+ console.log(result);
86
+ await wait(1000);
87
+ return true;
85
88
  },
86
- }),
87
- ] as ColDef[],
88
- [],
89
- );
89
+ },
90
+ }),
91
+ GridPopoutEditMultiSelect<ITestRow, ITestRow["position2"]>({
92
+ field: "position2",
93
+ initialWidth: 65,
94
+ maxWidth: 150,
95
+ headerName: "Inital editor values ",
96
+ valueGetter: (props) => positionTwoMap[props.data.position2],
97
+ cellEditorParams: {
98
+ multiEdit: false,
99
+ filtered: true,
100
+ filterPlaceholder: "Filter position",
101
+ initialSelectedValues: (selectedRows) => [selectedRows[0].position2],
102
+ options: Object.entries(positionTwoMap).map(([k, v]) => ({ value: k, label: v })),
103
+ onSave: async (result: MultiSelectResult<ITestRow>) => {
104
+ // eslint-disable-next-line no-console
105
+ console.log(result);
106
+ await wait(1000);
107
+ return true;
108
+ },
109
+ },
110
+ }),
111
+ ] as ColDef[];
112
+ }, []);
90
113
 
91
114
  const rowData = useMemo(
92
115
  () =>