@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/dist/step-ag-grid.esm.js
CHANGED
|
@@ -2,7 +2,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
2
2
|
import { LuiMiniSpinner, LuiStatusSpinner, LuiIcon, LuiButtonGroup, LuiButton, LuiCheckboxInput } from '@linzjs/lui';
|
|
3
3
|
import { ModuleRegistry, AllCommunityModule } from 'ag-grid-community';
|
|
4
4
|
import { AgGridReact } from 'ag-grid-react';
|
|
5
|
-
import { negate, isEmpty, findIndex, defer, debounce as debounce$1, xorBy, last, difference, omit, sortBy, delay, partition, pick, groupBy, fromPairs, toPairs, isEqual, pull,
|
|
5
|
+
import { negate, isEmpty, findIndex, defer, debounce as debounce$1, xorBy, last, difference, omit, sortBy, delay, partition, compact, pick, groupBy, fromPairs, toPairs, isEqual, pull, filter, sumBy, remove, flatten, castArray } from 'lodash-es';
|
|
6
6
|
import React, { useRef, useLayoutEffect, useEffect, createContext, useContext, useState, useMemo, memo, forwardRef, useCallback, useReducer, cloneElement, useImperativeHandle, Fragment as Fragment$1, useId } from 'react';
|
|
7
7
|
import { unstable_batchedUpdates, flushSync, createPortal } from 'react-dom';
|
|
8
8
|
|
|
@@ -3799,6 +3799,19 @@ const FormError = (props) => {
|
|
|
3799
3799
|
return (jsxs(Fragment, { children: [props.error && (jsxs("div", { className: "FormError", children: [jsx(LuiIcon, { alt: "error", name: "ic_error", className: "FormError-text-icon", size: "sm", status: "error" }), jsx("span", { className: "FormError-error", children: props.error })] })), props.helpText && !props.error && jsx("span", { className: 'FormError-helpText', children: props.helpText })] }));
|
|
3800
3800
|
};
|
|
3801
3801
|
|
|
3802
|
+
/**
|
|
3803
|
+
* Track previous values of states.
|
|
3804
|
+
*
|
|
3805
|
+
* @param value Value to track.
|
|
3806
|
+
*/
|
|
3807
|
+
const usePrevious = (value) => {
|
|
3808
|
+
const ref = useRef();
|
|
3809
|
+
useEffect(() => {
|
|
3810
|
+
ref.current = value;
|
|
3811
|
+
}, [value]);
|
|
3812
|
+
return ref.current;
|
|
3813
|
+
};
|
|
3814
|
+
|
|
3802
3815
|
function escapeStringRegexp(string) {
|
|
3803
3816
|
if (typeof string !== 'string') {
|
|
3804
3817
|
throw new TypeError('Expected a string');
|
|
@@ -4015,10 +4028,11 @@ const fieldToString = (field) => {
|
|
|
4015
4028
|
};
|
|
4016
4029
|
const GridFormDropDown = (props) => {
|
|
4017
4030
|
const { selectedRows, field, data } = useGridPopoverContext();
|
|
4031
|
+
const { onSelectFilter, options: propOptions, onSelectedItem } = props;
|
|
4018
4032
|
// Save triggers during async action processing which triggers another selectItem(), this ref blocks that
|
|
4019
4033
|
const [filter, setFilter] = useState(props.filterDefaultValue ?? '');
|
|
4020
4034
|
const [filteredValues, setFilteredValues] = useState();
|
|
4021
|
-
const [options, setOptions] = useState(null);
|
|
4035
|
+
const [options, setOptions] = useState(!!propOptions && typeof propOptions !== 'function' ? propOptions : null);
|
|
4022
4036
|
const subComponentIsValid = useRef(false);
|
|
4023
4037
|
const subComponentInitialValue = useRef(null);
|
|
4024
4038
|
const [subSelectedValue, setSubSelectedValue] = useState(null);
|
|
@@ -4028,8 +4042,8 @@ const GridFormDropDown = (props) => {
|
|
|
4028
4042
|
const hasChanged = selectedRows.some((row) => row[field] !== value) ||
|
|
4029
4043
|
(subComponentValue !== undefined && subComponentInitialValue.current !== JSON.stringify(subComponentValue));
|
|
4030
4044
|
if (hasChanged) {
|
|
4031
|
-
if (
|
|
4032
|
-
await
|
|
4045
|
+
if (onSelectedItem) {
|
|
4046
|
+
await onSelectedItem({
|
|
4033
4047
|
selectedRows,
|
|
4034
4048
|
selectedRowIds: selectedRows.map((row) => row.id),
|
|
4035
4049
|
value,
|
|
@@ -4041,58 +4055,17 @@ const GridFormDropDown = (props) => {
|
|
|
4041
4055
|
}
|
|
4042
4056
|
}
|
|
4043
4057
|
return true;
|
|
4044
|
-
}, [field,
|
|
4045
|
-
// Load up options list if it's async function
|
|
4046
|
-
useEffect(() => {
|
|
4047
|
-
if (options)
|
|
4048
|
-
return;
|
|
4049
|
-
let optionsConf = props.options;
|
|
4050
|
-
void (async () => {
|
|
4051
|
-
if (typeof optionsConf === 'function') {
|
|
4052
|
-
optionsConf = await optionsConf(selectedRows, filter);
|
|
4053
|
-
}
|
|
4054
|
-
if (optionsConf !== undefined) {
|
|
4055
|
-
setOptions(optionsConf);
|
|
4056
|
-
}
|
|
4057
|
-
})();
|
|
4058
|
-
}, [filter, options, props, selectedRows]);
|
|
4059
|
-
// Local filtering.
|
|
4060
|
-
useEffect(() => {
|
|
4061
|
-
if (props.filtered == 'local') {
|
|
4062
|
-
if (options == null)
|
|
4063
|
-
return;
|
|
4064
|
-
setFilteredValues(options
|
|
4065
|
-
.map((option) => {
|
|
4066
|
-
if (option.label != null && typeof option.label !== 'string') {
|
|
4067
|
-
console.error('Cannot filter non-string labels', option);
|
|
4068
|
-
return undefined;
|
|
4069
|
-
}
|
|
4070
|
-
return textMatch(option.label || '', filter) ? option : undefined;
|
|
4071
|
-
})
|
|
4072
|
-
.filter((r) => r !== undefined));
|
|
4073
|
-
}
|
|
4074
|
-
}, [props.filtered, filter, options]);
|
|
4075
|
-
const reSearchOnFilterChange = useMemo(() => debounce(() => {
|
|
4076
|
-
setOptions(null);
|
|
4077
|
-
}, 500), []);
|
|
4078
|
-
const previousFilter = useRef(filter);
|
|
4079
|
-
// Reload filtering.
|
|
4080
|
-
useEffect(() => {
|
|
4081
|
-
if (previousFilter.current != filter && props.filtered == 'reload') {
|
|
4082
|
-
previousFilter.current = filter;
|
|
4083
|
-
void reSearchOnFilterChange();
|
|
4084
|
-
}
|
|
4085
|
-
}, [filter, props, reSearchOnFilterChange]);
|
|
4058
|
+
}, [field, onSelectedItem, selectedRows]);
|
|
4086
4059
|
/**
|
|
4087
4060
|
* Saves are wrapped in updateValue and triggered by blur events
|
|
4088
4061
|
*/
|
|
4089
4062
|
const save = useCallback(async () => {
|
|
4090
|
-
if (!options)
|
|
4063
|
+
if (!options) {
|
|
4091
4064
|
return true;
|
|
4065
|
+
}
|
|
4092
4066
|
// Filter saved
|
|
4093
4067
|
if (selectedItem === null) {
|
|
4094
|
-
if (
|
|
4095
|
-
const { onSelectFilter } = props;
|
|
4068
|
+
if (onSelectFilter) {
|
|
4096
4069
|
if (!isEmpty(filter)) {
|
|
4097
4070
|
await onSelectFilter({
|
|
4098
4071
|
selectedRows,
|
|
@@ -4111,17 +4084,73 @@ const GridFormDropDown = (props) => {
|
|
|
4111
4084
|
}
|
|
4112
4085
|
return false;
|
|
4113
4086
|
}
|
|
4114
|
-
if (selectedItem.subComponent && !subComponentIsValid.current)
|
|
4087
|
+
if (selectedItem.subComponent && !subComponentIsValid.current) {
|
|
4115
4088
|
return false;
|
|
4089
|
+
}
|
|
4116
4090
|
await selectItemHandler(selectedItem.value, subSelectedValue);
|
|
4117
4091
|
return true;
|
|
4118
|
-
}, [
|
|
4092
|
+
}, [
|
|
4093
|
+
filter,
|
|
4094
|
+
filteredValues,
|
|
4095
|
+
onSelectFilter,
|
|
4096
|
+
options,
|
|
4097
|
+
selectItemHandler,
|
|
4098
|
+
selectedItem,
|
|
4099
|
+
selectedRows,
|
|
4100
|
+
subSelectedValue,
|
|
4101
|
+
]);
|
|
4119
4102
|
const { popoverWrapper } = useGridPopoverHook({
|
|
4120
4103
|
className: props.className,
|
|
4121
4104
|
invalid: () => !options || !!(selectedItem && !subComponentIsValid.current),
|
|
4122
4105
|
save,
|
|
4123
4106
|
dontSaveOnExternalClick: true,
|
|
4124
4107
|
});
|
|
4108
|
+
// Load up options list if it's async function
|
|
4109
|
+
useEffect(() => {
|
|
4110
|
+
// If options is null then we need to load/reload
|
|
4111
|
+
// Options will be set to null during a reload based filter, or on open popup
|
|
4112
|
+
if (options !== null) {
|
|
4113
|
+
return;
|
|
4114
|
+
}
|
|
4115
|
+
// propOptions is a const list
|
|
4116
|
+
if (typeof propOptions !== 'function') {
|
|
4117
|
+
if (propOptions) {
|
|
4118
|
+
setOptions(propOptions);
|
|
4119
|
+
}
|
|
4120
|
+
return;
|
|
4121
|
+
}
|
|
4122
|
+
// propOptions is function, probably loading from web
|
|
4123
|
+
void (async () => {
|
|
4124
|
+
const r = await propOptions(selectedRows, filter);
|
|
4125
|
+
setOptions(r ?? []);
|
|
4126
|
+
})();
|
|
4127
|
+
}, [filter, options, propOptions, selectedRows]);
|
|
4128
|
+
// Local filtering.
|
|
4129
|
+
useEffect(() => {
|
|
4130
|
+
if (props.filtered !== 'local') {
|
|
4131
|
+
return;
|
|
4132
|
+
}
|
|
4133
|
+
if (options == null) {
|
|
4134
|
+
setFilteredValues([]);
|
|
4135
|
+
return;
|
|
4136
|
+
}
|
|
4137
|
+
setFilteredValues(compact(options.map((option) => {
|
|
4138
|
+
if (option.label != null && typeof option.label !== 'string') {
|
|
4139
|
+
console.warn('GridFormDropDown: Cannot filter non-string labels', option);
|
|
4140
|
+
return undefined;
|
|
4141
|
+
}
|
|
4142
|
+
return textMatch(option.label || '', filter) ? option : undefined;
|
|
4143
|
+
})));
|
|
4144
|
+
}, [props.filtered, filter, options]);
|
|
4145
|
+
const reSearchOnFilterChange = useMemo(() => debounce(() => {
|
|
4146
|
+
setOptions(null);
|
|
4147
|
+
}, 500), []);
|
|
4148
|
+
const previousFilter = usePrevious(filter);
|
|
4149
|
+
useEffect(() => {
|
|
4150
|
+
if (previousFilter != null && previousFilter != filter && props.filtered === 'reload') {
|
|
4151
|
+
void reSearchOnFilterChange();
|
|
4152
|
+
}
|
|
4153
|
+
}, [filter, previousFilter, props.filtered, reSearchOnFilterChange]);
|
|
4125
4154
|
let lastHeader = null;
|
|
4126
4155
|
let showHeader = null;
|
|
4127
4156
|
return popoverWrapper(jsxs(Fragment, { children: [props.filtered && (jsxs("div", { className: 'GridFormDropDown-filter', children: [jsx(FocusableItem, { className: 'filter-item', onFocus: () => {
|
|
@@ -5805,19 +5834,6 @@ const GridUpdatingContextProvider = (props) => {
|
|
|
5805
5834
|
var css_248z = ".ActionButton{align-items:center;display:flex}.ActionButton-inProgress .LuiIcon{visibility:hidden}.ActionButton-minimal.lui-button-lg.lui-button-icon-right{padding-right:38px}.ActionButton.lui-button-lg.lui-button-icon-right:not(.ActionButton-tight) .LuiIcon{margin:0 4px}.ActionButton.ActionButton-tight.lui-button-lg.lui-button-icon-right .LuiIcon{margin:0}.ActionButton-iconOnly.lui-button-lg.lui-button-icon-right:not(.ActionButton-tight){padding:8px 5px}.ActionButton-iconOnly.lui-button-lg.lui-button-icon-right.ActionButton-tight{padding:0}.ActionButton-minimalArea{position:relative}.ActionButton-minimalAreaDisplay{position:absolute}.ActionButton-minimalAreaExpand{visibility:hidden}.ActionButton-inProgress.lui-button-lg.lui-button-icon-right{background-color:#e2f3f7;color:#007198;cursor:progress}.ActionButton-fill{justify-content:center;width:100%}";
|
|
5806
5835
|
styleInject(css_248z);
|
|
5807
5836
|
|
|
5808
|
-
/**
|
|
5809
|
-
* Track previous values of states.
|
|
5810
|
-
*
|
|
5811
|
-
* @param value Value to track.
|
|
5812
|
-
*/
|
|
5813
|
-
const usePrevious = (value) => {
|
|
5814
|
-
const ref = useRef();
|
|
5815
|
-
useEffect(() => {
|
|
5816
|
-
ref.current = value;
|
|
5817
|
-
}, [value]);
|
|
5818
|
-
return ref.current;
|
|
5819
|
-
};
|
|
5820
|
-
|
|
5821
5837
|
// Kept this less than one second, so I don't have issues with waitFor as it defaults to 1s
|
|
5822
5838
|
const minimumInProgressTimeMs = 950;
|
|
5823
5839
|
const ActionButton = ({ icon, name, inProgressName, disabled, dataTestId, style, className, title, onClick, size = 'sm', iconPosition = 'left', level = 'tertiary', 'aria-label': ariaLabel, }) => {
|