@linzjs/step-ag-grid 29.1.3 → 29.1.5
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/step-ag-grid.cjs +79 -63
- package/dist/step-ag-grid.cjs.map +1 -1
- package/dist/step-ag-grid.esm.js +80 -64
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/gridForm/GridFormDropDown.tsx +87 -61
- package/src/stories/grid/gridFormInteraction/GridFormEditBearingCorrectionInteraction.stories.tsx +0 -1
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import debounce from 'debounce-promise';
|
|
2
|
-
import { isEmpty } from 'lodash-es';
|
|
2
|
+
import { compact, isEmpty } from 'lodash-es';
|
|
3
3
|
import { Fragment, ReactElement, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
4
|
|
|
5
5
|
import { useGridPopoverContext } from '../../contexts/GridPopoverContext';
|
|
6
6
|
import { GridSubComponentContext } from '../../contexts/GridSubComponentContext';
|
|
7
7
|
import { FormError } from '../../lui/FormError';
|
|
8
|
+
import { usePrevious } from '../../lui/reactUtils';
|
|
8
9
|
import { FocusableItem, MenuDivider, MenuHeader, MenuItem } from '../../react-menu3';
|
|
9
10
|
import { ClickEvent } from '../../react-menu3/types';
|
|
10
11
|
import { textMatch } from '../../utils/textMatcher';
|
|
@@ -84,11 +85,14 @@ export const GridFormDropDown = <TData extends GridBaseRow, TOptionValue>(
|
|
|
84
85
|
props: GridFormDropDownProps<TData, TOptionValue>,
|
|
85
86
|
) => {
|
|
86
87
|
const { selectedRows, field, data } = useGridPopoverContext<TData>();
|
|
88
|
+
const { onSelectFilter, options: propOptions, onSelectedItem } = props;
|
|
87
89
|
|
|
88
90
|
// Save triggers during async action processing which triggers another selectItem(), this ref blocks that
|
|
89
91
|
const [filter, setFilter] = useState(props.filterDefaultValue ?? '');
|
|
90
92
|
const [filteredValues, setFilteredValues] = useState<any[]>();
|
|
91
|
-
const [options, setOptions] = useState<FinalSelectOption<TOptionValue>[] | null>(
|
|
93
|
+
const [options, setOptions] = useState<FinalSelectOption<TOptionValue>[] | null>(
|
|
94
|
+
!!propOptions && typeof propOptions !== 'function' ? propOptions : null,
|
|
95
|
+
);
|
|
92
96
|
const subComponentIsValid = useRef(false);
|
|
93
97
|
const subComponentInitialValue = useRef<string | null>(null);
|
|
94
98
|
const [subSelectedValue, setSubSelectedValue] = useState<any>(null);
|
|
@@ -101,8 +105,8 @@ export const GridFormDropDown = <TData extends GridBaseRow, TOptionValue>(
|
|
|
101
105
|
selectedRows.some((row) => row[field] !== value) ||
|
|
102
106
|
(subComponentValue !== undefined && subComponentInitialValue.current !== JSON.stringify(subComponentValue));
|
|
103
107
|
if (hasChanged) {
|
|
104
|
-
if (
|
|
105
|
-
await
|
|
108
|
+
if (onSelectedItem) {
|
|
109
|
+
await onSelectedItem({
|
|
106
110
|
selectedRows,
|
|
107
111
|
selectedRowIds: selectedRows.map((row) => row.id),
|
|
108
112
|
value,
|
|
@@ -114,70 +118,20 @@ export const GridFormDropDown = <TData extends GridBaseRow, TOptionValue>(
|
|
|
114
118
|
}
|
|
115
119
|
return true;
|
|
116
120
|
},
|
|
117
|
-
[field,
|
|
121
|
+
[field, onSelectedItem, selectedRows],
|
|
118
122
|
);
|
|
119
123
|
|
|
120
|
-
// Load up options list if it's async function
|
|
121
|
-
useEffect(() => {
|
|
122
|
-
if (options) return;
|
|
123
|
-
let optionsConf = props.options;
|
|
124
|
-
|
|
125
|
-
void (async () => {
|
|
126
|
-
if (typeof optionsConf === 'function') {
|
|
127
|
-
optionsConf = await optionsConf(selectedRows, filter);
|
|
128
|
-
}
|
|
129
|
-
if (optionsConf !== undefined) {
|
|
130
|
-
setOptions(optionsConf);
|
|
131
|
-
}
|
|
132
|
-
})();
|
|
133
|
-
}, [filter, options, props, selectedRows]);
|
|
134
|
-
|
|
135
|
-
// Local filtering.
|
|
136
|
-
useEffect(() => {
|
|
137
|
-
if (props.filtered == 'local') {
|
|
138
|
-
if (options == null) return;
|
|
139
|
-
setFilteredValues(
|
|
140
|
-
options
|
|
141
|
-
.map((option) => {
|
|
142
|
-
if (option.label != null && typeof option.label !== 'string') {
|
|
143
|
-
console.error('Cannot filter non-string labels', option);
|
|
144
|
-
return undefined;
|
|
145
|
-
}
|
|
146
|
-
return textMatch((option.label as string) || '', filter) ? option : undefined;
|
|
147
|
-
})
|
|
148
|
-
.filter((r) => r !== undefined),
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
}, [props.filtered, filter, options]);
|
|
152
|
-
|
|
153
|
-
const reSearchOnFilterChange = useMemo(
|
|
154
|
-
() =>
|
|
155
|
-
debounce(() => {
|
|
156
|
-
setOptions(null);
|
|
157
|
-
}, 500),
|
|
158
|
-
[],
|
|
159
|
-
);
|
|
160
|
-
|
|
161
|
-
const previousFilter = useRef<string>(filter);
|
|
162
|
-
|
|
163
|
-
// Reload filtering.
|
|
164
|
-
useEffect(() => {
|
|
165
|
-
if (previousFilter.current != filter && props.filtered == 'reload') {
|
|
166
|
-
previousFilter.current = filter;
|
|
167
|
-
void reSearchOnFilterChange();
|
|
168
|
-
}
|
|
169
|
-
}, [filter, props, reSearchOnFilterChange]);
|
|
170
|
-
|
|
171
124
|
/**
|
|
172
125
|
* Saves are wrapped in updateValue and triggered by blur events
|
|
173
126
|
*/
|
|
174
127
|
const save = useCallback(async () => {
|
|
175
|
-
if (!options)
|
|
128
|
+
if (!options) {
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
176
131
|
|
|
177
132
|
// Filter saved
|
|
178
133
|
if (selectedItem === null) {
|
|
179
|
-
if (
|
|
180
|
-
const { onSelectFilter } = props;
|
|
134
|
+
if (onSelectFilter) {
|
|
181
135
|
if (!isEmpty(filter)) {
|
|
182
136
|
await onSelectFilter({
|
|
183
137
|
selectedRows,
|
|
@@ -195,11 +149,22 @@ export const GridFormDropDown = <TData extends GridBaseRow, TOptionValue>(
|
|
|
195
149
|
}
|
|
196
150
|
return false;
|
|
197
151
|
}
|
|
198
|
-
if (selectedItem.subComponent && !subComponentIsValid.current)
|
|
152
|
+
if (selectedItem.subComponent && !subComponentIsValid.current) {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
199
155
|
await selectItemHandler(selectedItem.value, subSelectedValue);
|
|
200
156
|
|
|
201
157
|
return true;
|
|
202
|
-
}, [
|
|
158
|
+
}, [
|
|
159
|
+
filter,
|
|
160
|
+
filteredValues,
|
|
161
|
+
onSelectFilter,
|
|
162
|
+
options,
|
|
163
|
+
selectItemHandler,
|
|
164
|
+
selectedItem,
|
|
165
|
+
selectedRows,
|
|
166
|
+
subSelectedValue,
|
|
167
|
+
]);
|
|
203
168
|
|
|
204
169
|
const { popoverWrapper } = useGridPopoverHook({
|
|
205
170
|
className: props.className,
|
|
@@ -208,6 +173,67 @@ export const GridFormDropDown = <TData extends GridBaseRow, TOptionValue>(
|
|
|
208
173
|
dontSaveOnExternalClick: true,
|
|
209
174
|
});
|
|
210
175
|
|
|
176
|
+
// Load up options list if it's async function
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
// If options is null then we need to load/reload
|
|
179
|
+
// Options will be set to null during a reload based filter, or on open popup
|
|
180
|
+
if (options !== null) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// propOptions is a const list
|
|
185
|
+
if (typeof propOptions !== 'function') {
|
|
186
|
+
if (propOptions) {
|
|
187
|
+
setOptions(propOptions);
|
|
188
|
+
}
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// propOptions is function, probably loading from web
|
|
193
|
+
void (async () => {
|
|
194
|
+
const r = await propOptions(selectedRows, filter);
|
|
195
|
+
setOptions(r ?? []);
|
|
196
|
+
})();
|
|
197
|
+
}, [filter, options, propOptions, selectedRows]);
|
|
198
|
+
|
|
199
|
+
// Local filtering.
|
|
200
|
+
useEffect(() => {
|
|
201
|
+
if (props.filtered !== 'local') {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (options == null) {
|
|
205
|
+
setFilteredValues([]);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
setFilteredValues(
|
|
210
|
+
compact(
|
|
211
|
+
options.map((option) => {
|
|
212
|
+
if (option.label != null && typeof option.label !== 'string') {
|
|
213
|
+
console.warn('GridFormDropDown: Cannot filter non-string labels', option);
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
return textMatch((option.label as string) || '', filter) ? option : undefined;
|
|
217
|
+
}),
|
|
218
|
+
),
|
|
219
|
+
);
|
|
220
|
+
}, [props.filtered, filter, options]);
|
|
221
|
+
|
|
222
|
+
const reSearchOnFilterChange = useMemo(
|
|
223
|
+
() =>
|
|
224
|
+
debounce(() => {
|
|
225
|
+
setOptions(null);
|
|
226
|
+
}, 500),
|
|
227
|
+
[],
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
const previousFilter = usePrevious(filter);
|
|
231
|
+
useEffect(() => {
|
|
232
|
+
if (previousFilter != null && previousFilter != filter && props.filtered === 'reload') {
|
|
233
|
+
void reSearchOnFilterChange();
|
|
234
|
+
}
|
|
235
|
+
}, [filter, previousFilter, props.filtered, reSearchOnFilterChange]);
|
|
236
|
+
|
|
211
237
|
let lastHeader: ReactElement | null = null;
|
|
212
238
|
let showHeader: ReactElement | null = null;
|
|
213
239
|
|