@linzjs/step-ag-grid 7.11.8 → 7.11.9

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": "7.11.8",
5
+ "version": "7.11.9",
6
6
  "keywords": [
7
7
  "aggrid",
8
8
  "ag-grid",
@@ -1,16 +1,14 @@
1
1
  import { FocusableItem, MenuDivider, MenuHeader, MenuItem } from "../../react-menu3";
2
- import { KeyboardEvent, useCallback, useContext, useEffect, useRef, useState } from "react";
2
+ import { useCallback, useEffect, useRef, useState } from "react";
3
3
  import { GridBaseRow } from "../Grid";
4
4
  import { ComponentLoadingWrapper } from "../ComponentLoadingWrapper";
5
- import { delay } from "lodash-es";
5
+ import { delay, isEmpty } from "lodash-es";
6
6
  import debounce from "debounce-promise";
7
7
  import { CellEditorCommon } from "../GridCell";
8
8
  import { useGridPopoverHook } from "../GridPopoverHook";
9
9
  import { useGridPopoverContext } from "../../contexts/GridPopoverContext";
10
10
  import { GridSubComponentContext } from "contexts/GridSubComponentContext";
11
11
  import { ClickEvent, MenuInstance } from "../../react-menu3/types";
12
- import { CloseReason } from "../../react-menu3/utils";
13
- import { GridContext } from "../../contexts/GridContext";
14
12
  import { FormError } from "../../lui/FormError";
15
13
  import { isNotEmpty } from "../../utils/util";
16
14
 
@@ -62,8 +60,7 @@ const fieldToString = (field: any) => {
62
60
  };
63
61
 
64
62
  export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPopoutDropDownProps<RowType>) => {
65
- const { stopEditing } = useContext(GridContext);
66
- const { selectedRows, field, updateValue, data } = useGridPopoverContext<RowType>();
63
+ const { selectedRows, field, data } = useGridPopoverContext<RowType>();
67
64
 
68
65
  // Save triggers during async action processing which triggers another selectItem(), this ref blocks that
69
66
  const [filter, setFilter] = useState("");
@@ -73,7 +70,8 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
73
70
  const subComponentIsValid = useRef(false);
74
71
  const subComponentInitialValue = useRef<string | null>(null);
75
72
  const [subSelectedValue, setSubSelectedValue] = useState<any>(null);
76
- const [selectedSubComponent, setSelectedSubComponent] = useState<FinalSelectOption | null>(null);
73
+ // Note: null is assumed to be the filter
74
+ const [selectedItem, setSelectedItem] = useState<FinalSelectOption | null>(null);
77
75
 
78
76
  const selectItemHandler = useCallback(
79
77
  async (value: any, subComponentValue?: any): Promise<boolean> => {
@@ -92,29 +90,6 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
92
90
  [field, props, selectedRows],
93
91
  );
94
92
 
95
- const clickItemHandler = useCallback(
96
- async (value: any, subComponentValue?: any, reason?: string): Promise<boolean> => {
97
- if (subComponentValue !== undefined && !subComponentIsValid.current) return false;
98
- return updateValue(
99
- async () => {
100
- return await selectItemHandler(value, subComponentValue);
101
- },
102
- reason === CloseReason.TAB_FORWARD ? 1 : reason === CloseReason.TAB_BACKWARD ? -1 : 0,
103
- );
104
- },
105
- [selectItemHandler, updateValue],
106
- );
107
-
108
- const selectFilterHandler = useCallback(
109
- async (value: string) => {
110
- await updateValue(async (selectedRows) => {
111
- props.onSelectFilter && (await props.onSelectFilter({ selectedRows, value }));
112
- return true;
113
- }, 0);
114
- },
115
- [props, updateValue],
116
- );
117
-
118
93
  // Load up options list if it's async function
119
94
  useEffect(() => {
120
95
  if (options || optionsInitialising.current) return;
@@ -159,7 +134,7 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
159
134
  return undefined;
160
135
  }
161
136
  const str = (option.label as string) || "";
162
- return str.toLowerCase().indexOf(filter.toLowerCase()) === -1 ? option.value : undefined;
137
+ return str.toLowerCase().indexOf(filter.toLowerCase()) !== -1 ? option : undefined;
163
138
  })
164
139
  .filter((r) => r !== undefined),
165
140
  );
@@ -190,65 +165,58 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
190
165
  const save = useCallback(async () => {
191
166
  if (!options) return true;
192
167
 
193
- // Handler for sub-selected value
194
- if (!selectedSubComponent) return true;
195
- if (selectedSubComponent.subComponent && !subComponentIsValid.current) return false;
196
- await selectItemHandler(selectedSubComponent.value, subSelectedValue);
168
+ // Filter saved
169
+ if (selectedItem === null) {
170
+ if (props.onSelectFilter) {
171
+ const { onSelectFilter } = props;
172
+ await onSelectFilter({ selectedRows, value: filter });
173
+ return true;
174
+ } else {
175
+ if (filteredValues.length === 1) {
176
+ if (filteredValues[0].subComponent) return false;
177
+ return await selectItemHandler(filteredValues[0].value, null);
178
+ }
179
+ }
180
+ return false;
181
+ }
182
+ if (selectedItem.subComponent && !subComponentIsValid.current) return false;
183
+ await selectItemHandler(selectedItem.value, subSelectedValue);
197
184
 
198
185
  return true;
199
- }, [options, selectItemHandler, selectedSubComponent, subSelectedValue]);
186
+ }, [filter, filteredValues, options, props, selectItemHandler, selectedItem, selectedRows, subSelectedValue]);
200
187
 
201
188
  const { popoverWrapper } = useGridPopoverHook({
202
189
  className: props.className,
203
- invalid: () => !!(selectedSubComponent && !subComponentIsValid.current),
190
+ invalid: () => !!(selectedItem && !subComponentIsValid.current),
204
191
  save,
205
192
  });
206
193
 
207
- const enterKeyPressedRef = useRef(false);
208
- const handleKeyDown = useCallback((e: KeyboardEvent) => {
209
- if (e.key === "Enter") {
210
- e.stopPropagation();
211
- e.preventDefault();
212
- enterKeyPressedRef.current = true;
213
- }
214
- }, []);
215
-
216
- const handleKeyUp = useCallback(
217
- async (e: KeyboardEvent) => {
218
- if (!options) return;
219
-
220
- if (e.key === "Enter") {
221
- e.stopPropagation();
222
- e.preventDefault();
223
- if (!enterKeyPressedRef.current) return;
224
-
225
- props.onSelectFilter && (await selectFilterHandler(filter));
226
- stopEditing();
227
- }
228
- },
229
- [filter, options, props.onSelectFilter, selectFilterHandler, stopEditing],
230
- );
231
-
232
194
  return popoverWrapper(
233
195
  <>
234
196
  {props.filtered && (
235
197
  <div className={"GridFormDropDown-filter"}>
236
- <FocusableItem className={"filter-item"}>
198
+ <FocusableItem
199
+ className={"filter-item"}
200
+ onFocus={() => {
201
+ setSelectedItem(null);
202
+ setSubSelectedValue(null);
203
+ subComponentIsValid.current = true;
204
+ }}
205
+ >
237
206
  {({ ref }: any) => (
238
207
  <div style={{ display: "flex", flexDirection: "column", width: "100%" }}>
239
208
  <input
240
- autoFocus
241
209
  className={"LuiTextInput-input"}
242
210
  ref={ref}
243
211
  type="text"
244
212
  placeholder={props.filterPlaceholder ?? "Placeholder"}
245
213
  data-testid={"filteredMenu-free-text-input"}
246
214
  defaultValue={filter}
247
- data-disableenterautosave={true}
248
215
  data-allowtabtosave={true}
216
+ data-disableenterautosave={
217
+ !props.onSelectFilter && !(filteredValues.length === 1 && !filteredValues[0].subComponent)
218
+ }
249
219
  onChange={(e) => setFilter(e.target.value)}
250
- onKeyDown={handleKeyDown}
251
- onKeyUp={handleKeyUp}
252
220
  />
253
221
  {props.filterHelpText && isNotEmpty(filter) && (
254
222
  <FormError error={null} helpText={props.filterHelpText} />
@@ -261,7 +229,7 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
261
229
  )}
262
230
  <ComponentLoadingWrapper loading={!options} className={"GridFormDropDown-options"}>
263
231
  <>
264
- {options && options.length == filteredValues?.length && (
232
+ {options && isEmpty(filteredValues) && (
265
233
  <MenuItem key={`${fieldToString(field)}-empty`} className={"GridPopoverEditDropDown-noOptions"}>
266
234
  No Options
267
235
  </MenuItem>
@@ -271,19 +239,33 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
271
239
  <MenuDivider key={`$$divider_${index}`} />
272
240
  ) : item.value === MenuHeaderString ? (
273
241
  <MenuHeader key={`$$header_${index}`}>{item.label}</MenuHeader>
274
- ) : filteredValues.includes(item.value) ? null : (
275
- <div key={`menu-wrapper-${index}`}>
276
- <MenuItem
277
- key={`${fieldToString(field)}-${index}`}
278
- disabled={!!item.disabled}
279
- title={item.disabled && typeof item.disabled !== "boolean" ? item.disabled : ""}
280
- value={item.value}
281
- onClick={(e: ClickEvent) => {
242
+ ) : (
243
+ filteredValues.includes(item) && (
244
+ <div key={`menu-wrapper-${index}`}>
245
+ <MenuItem
246
+ key={`${fieldToString(field)}-${index}`}
247
+ disabled={!!item.disabled}
248
+ title={item.disabled && typeof item.disabled !== "boolean" ? item.disabled : ""}
249
+ value={item.value}
250
+ onFocus={() => {
251
+ setSelectedItem(item);
252
+ if (item.subComponent) {
253
+ setSelectedItem(item);
254
+ subComponentIsValid.current = true;
255
+ subComponentInitialValue.current = null;
256
+ } else {
257
+ setSubSelectedValue(null);
258
+ subComponentIsValid.current = true;
259
+ }
260
+ }}
261
+ onClick={(e: ClickEvent) => {
262
+ if (item.subComponent) {
263
+ e.keepOpen = true;
264
+ }
265
+ }}
266
+ >
267
+ {/*onClick={(e: ClickEvent) => {
282
268
  if (item.subComponent) {
283
- // toggle selection
284
- setSelectedSubComponent(selectedSubComponent === item ? null : item);
285
- subComponentIsValid.current = true;
286
- subComponentInitialValue.current = null;
287
269
  e.keepOpen = true;
288
270
  } else {
289
271
  clickItemHandler(
@@ -296,45 +278,45 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
296
278
  : CloseReason.CLICK,
297
279
  ).then();
298
280
  }
299
- }}
300
- >
301
- {item.label ?? (item.value == null ? `<${item.value}>` : `${item.value}`)}
302
- {item.subComponent ? "..." : ""}
303
- </MenuItem>
281
+ }*/}
282
+ {item.label ?? (item.value == null ? `<${item.value}>` : `${item.value}`)}
283
+ {item.subComponent ? "..." : ""}
284
+ </MenuItem>
304
285
 
305
- {item.subComponent && selectedSubComponent === item && (
306
- <FocusableItem className={"LuiDeprecatedForms"} key={`${item.label}_subcomponent`}>
307
- {(ref: MenuInstance) => (
308
- <GridSubComponentContext.Provider
309
- value={{
310
- context: { options },
311
- data,
312
- value: subSelectedValue,
313
- setValue: (value: any) => {
314
- setSubSelectedValue(value);
315
- if (subComponentInitialValue.current === null) {
316
- // copy the default value of the sub-component so we can change detect on save
317
- subComponentInitialValue.current = JSON.stringify(value);
318
- }
319
- },
320
- setValid: (valid: boolean) => {
321
- subComponentIsValid.current = valid;
322
- },
323
- triggerSave: async () => {
324
- ref.closeMenu();
325
- },
326
- }}
327
- >
328
- {item.subComponent && (
329
- <div className={"subComponent"}>
330
- <item.subComponent key={`${fieldToString(field)}-${index}_subcomponent_inner`} />
331
- </div>
332
- )}
333
- </GridSubComponentContext.Provider>
334
- )}
335
- </FocusableItem>
336
- )}
337
- </div>
286
+ {item.subComponent && selectedItem === item && (
287
+ <FocusableItem className={"LuiDeprecatedForms"} key={`${item.label}_subcomponent`}>
288
+ {(ref: MenuInstance) => (
289
+ <GridSubComponentContext.Provider
290
+ value={{
291
+ context: { options },
292
+ data,
293
+ value: subSelectedValue,
294
+ setValue: (value: any) => {
295
+ setSubSelectedValue(value);
296
+ if (subComponentInitialValue.current === null) {
297
+ // copy the default value of the sub-component so we can change detect on save
298
+ subComponentInitialValue.current = JSON.stringify(value);
299
+ }
300
+ },
301
+ setValid: (valid: boolean) => {
302
+ subComponentIsValid.current = valid;
303
+ },
304
+ triggerSave: async () => {
305
+ ref.closeMenu();
306
+ },
307
+ }}
308
+ >
309
+ {item.subComponent && (
310
+ <div className={"subComponent"}>
311
+ <item.subComponent key={`${fieldToString(field)}-${index}_subcomponent_inner`} />
312
+ </div>
313
+ )}
314
+ </GridSubComponentContext.Provider>
315
+ )}
316
+ </FocusableItem>
317
+ )}
318
+ </div>
319
+ )
338
320
  ),
339
321
  )}
340
322
  </>