@linzjs/step-ag-grid 29.1.2 → 29.1.4
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/src/components/Grid.d.ts +1 -1
- package/dist/src/components/GridPopoverHook.d.ts +2 -0
- package/dist/src/contexts/GridContext.d.ts +2 -2
- package/dist/src/utils/waitForCondition.d.ts +1 -1
- package/dist/step-ag-grid.cjs +147 -114
- package/dist/step-ag-grid.cjs.map +1 -1
- package/dist/step-ag-grid.esm.js +147 -115
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Grid.tsx +1 -1
- package/src/components/GridCell.tsx +34 -14
- package/src/components/GridPopoverHook.tsx +10 -15
- package/src/components/gridForm/GridFormDropDown.tsx +73 -49
- package/src/components/gridForm/GridFormMultiSelect.tsx +12 -4
- package/src/components/gridPopoverEdit/GridPopoverMessage.ts +1 -0
- package/src/contexts/GridContext.tsx +2 -2
- package/src/contexts/GridContextProvider.tsx +31 -23
- package/src/stories/grid/GridPopoutEditGeneric.stories.tsx +1 -1
- package/src/stories/grid/GridPopoverEditMultiSelect.stories.tsx +1 -1
- package/src/stories/grid/GridPopoverEditMultiSelectGrid.stories.tsx +1 -1
- package/src/stories/grid/gridFormInteraction/GridFormDropDownInteraction.stories.tsx +1 -1
- package/src/stories/grid/gridFormInteraction/GridFormEditBearingCorrectionInteraction.stories.tsx +2 -1
- package/src/stories/grid/gridFormInteraction/GridFormEditBearingInteraction.stories.tsx +1 -1
- package/src/stories/grid/gridFormInteraction/GridFormMultiSelectInteraction.stories.tsx +2 -1
- package/src/stories/grid/gridFormInteraction/GridFormPopoverMenuInteraction.stories.tsx +2 -2
- package/src/stories/grid/gridFormInteraction/GridFormTextAreaInteraction.stories.tsx +1 -1
- package/src/stories/grid/gridFormInteraction/GridFormTextInputInteraction.stories.tsx +1 -1
- package/src/stories/grid/interactions/GridKeyboardInteractions.stories.tsx +56 -13
- package/src/utils/waitForCondition.tsx +6 -2
|
@@ -65,7 +65,7 @@ export interface GridProps<TData extends GridBaseRow = GridBaseRow> {
|
|
|
65
65
|
* When pressing tab whilst editing the grid will select and edit the next cell if available.
|
|
66
66
|
* Once the last cell to edit closes this callback is called.
|
|
67
67
|
*/
|
|
68
|
-
onBulkEditingComplete?: () => void;
|
|
68
|
+
onBulkEditingComplete?: () => Promise<void> | void;
|
|
69
69
|
/**
|
|
70
70
|
* Context menu definition if required.
|
|
71
71
|
*/
|
|
@@ -6,7 +6,9 @@ export interface GridPopoverHookProps<TData> {
|
|
|
6
6
|
save?: (selectedRows: TData[]) => Promise<boolean>;
|
|
7
7
|
dontSaveOnExternalClick?: boolean;
|
|
8
8
|
}
|
|
9
|
+
export declare const CancelPromise: () => Promise<boolean>;
|
|
9
10
|
export declare const useGridPopoverHook: <TData extends GridBaseRow>({ className, save, invalid, dontSaveOnExternalClick, }: GridPopoverHookProps<TData>) => {
|
|
10
11
|
popoverWrapper: (children: ReactElement) => import("react/jsx-runtime").JSX.Element;
|
|
11
12
|
triggerSave: (reason?: string) => Promise<void>;
|
|
13
|
+
gridPopoverOpen: boolean;
|
|
12
14
|
};
|
|
@@ -57,8 +57,8 @@ export interface GridContextType<TData extends GridBaseRow> {
|
|
|
57
57
|
invisibleColumnIds: string[] | undefined;
|
|
58
58
|
setInvisibleColumnIds: (colIds: string[]) => void;
|
|
59
59
|
downloadCsv: (csvExportParams?: CsvExportParams) => void;
|
|
60
|
-
onBulkEditingComplete: () => void;
|
|
61
|
-
setOnBulkEditingComplete: (callback: (() => void) | undefined) => void;
|
|
60
|
+
onBulkEditingComplete: () => Promise<void> | void;
|
|
61
|
+
setOnBulkEditingComplete: (callback: (() => Promise<void> | void) | undefined) => void;
|
|
62
62
|
showNoRowsOverlay: () => void;
|
|
63
63
|
}
|
|
64
64
|
export declare const GridContext: import("react").Context<GridContextType<any>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const waitForCondition: (condition: () => boolean, timeoutMs: number) => Promise<boolean>;
|
|
1
|
+
export declare const waitForCondition: (error: string, condition: () => boolean, timeoutMs: number) => Promise<boolean>;
|
package/dist/step-ag-grid.cjs
CHANGED
|
@@ -3400,20 +3400,25 @@ const GridCell = (props, custom) => {
|
|
|
3400
3400
|
sortable: true,
|
|
3401
3401
|
resizable: true,
|
|
3402
3402
|
valueSetter: custom?.editor ? blockValueSetter : undefined,
|
|
3403
|
-
editable: props.editable ??
|
|
3404
|
-
...(custom?.editor
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3403
|
+
editable: props.editable ?? !!custom?.editor,
|
|
3404
|
+
...(custom?.editor
|
|
3405
|
+
? {
|
|
3406
|
+
cellClassRules: GridCellMultiSelectClassRules,
|
|
3407
|
+
cellEditor: GenericCellEditorComponentWrapper(custom?.editor),
|
|
3408
|
+
}
|
|
3409
|
+
: {
|
|
3410
|
+
cellEditor: CellEditorToBlockEditing,
|
|
3411
|
+
}),
|
|
3409
3412
|
suppressKeyboardEvent: suppressCellKeyboardEvents,
|
|
3410
|
-
...(custom?.editorParams
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3413
|
+
...(custom?.editorParams
|
|
3414
|
+
? {
|
|
3415
|
+
cellEditorParams: {
|
|
3416
|
+
...custom.editorParams,
|
|
3417
|
+
multiEdit: custom.multiEdit,
|
|
3418
|
+
preventAutoEdit: custom.preventAutoEdit ?? !custom?.editor,
|
|
3419
|
+
},
|
|
3420
|
+
}
|
|
3421
|
+
: { cellEditorParams: { preventAutoEdit: !custom?.editor } }),
|
|
3417
3422
|
// If there's a valueFormatter and no filterValueGetter then create a filterValueGetter
|
|
3418
3423
|
getQuickFilterText: filterValueGetter,
|
|
3419
3424
|
// Default value formatter, otherwise react freaks out on objects
|
|
@@ -3430,6 +3435,19 @@ const GridCell = (props, custom) => {
|
|
|
3430
3435
|
},
|
|
3431
3436
|
};
|
|
3432
3437
|
};
|
|
3438
|
+
/**
|
|
3439
|
+
* Ag-grid will start its own editor if editable is true and there is no cell editor
|
|
3440
|
+
* like in the case of a cell that is editable because it triggers a modal.
|
|
3441
|
+
* This will block that editor.
|
|
3442
|
+
*/
|
|
3443
|
+
const CellEditorToBlockEditing = ({ stopEditing }) => {
|
|
3444
|
+
React.useEffect(() => {
|
|
3445
|
+
lodashEs.defer(() => {
|
|
3446
|
+
stopEditing();
|
|
3447
|
+
});
|
|
3448
|
+
}, [stopEditing]);
|
|
3449
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
3450
|
+
};
|
|
3433
3451
|
const GenericCellEditorComponentWrapper = (editor) => {
|
|
3434
3452
|
const obj = { editor };
|
|
3435
3453
|
return React.forwardRef(function GenericCellEditorComponentFr(cellEditorParams, _) {
|
|
@@ -3783,6 +3801,19 @@ const FormError = (props) => {
|
|
|
3783
3801
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [props.error && (jsxRuntime.jsxs("div", { className: "FormError", children: [jsxRuntime.jsx(lui.LuiIcon, { alt: "error", name: "ic_error", className: "FormError-text-icon", size: "sm", status: "error" }), jsxRuntime.jsx("span", { className: "FormError-error", children: props.error })] })), props.helpText && !props.error && jsxRuntime.jsx("span", { className: 'FormError-helpText', children: props.helpText })] }));
|
|
3784
3802
|
};
|
|
3785
3803
|
|
|
3804
|
+
/**
|
|
3805
|
+
* Track previous values of states.
|
|
3806
|
+
*
|
|
3807
|
+
* @param value Value to track.
|
|
3808
|
+
*/
|
|
3809
|
+
const usePrevious = (value) => {
|
|
3810
|
+
const ref = React.useRef();
|
|
3811
|
+
React.useEffect(() => {
|
|
3812
|
+
ref.current = value;
|
|
3813
|
+
}, [value]);
|
|
3814
|
+
return ref.current;
|
|
3815
|
+
};
|
|
3816
|
+
|
|
3786
3817
|
function escapeStringRegexp(string) {
|
|
3787
3818
|
if (typeof string !== 'string') {
|
|
3788
3819
|
throw new TypeError('Expected a string');
|
|
@@ -3938,8 +3969,8 @@ const textMatch = (text, filter) => {
|
|
|
3938
3969
|
negativeFilters.every((superFilter) => values.every((value) => isMatch(value, superFilter)))));
|
|
3939
3970
|
};
|
|
3940
3971
|
|
|
3972
|
+
const CancelPromise = () => Promise.resolve(true);
|
|
3941
3973
|
const useGridPopoverHook = ({ className, save, invalid, dontSaveOnExternalClick, }) => {
|
|
3942
|
-
const { onBulkEditingComplete, redrawRows } = useGridContext();
|
|
3943
3974
|
const { anchorRef, saving, updateValue, stopEditing } = useGridPopoverContext();
|
|
3944
3975
|
const saveButtonRef = React.useRef(null);
|
|
3945
3976
|
const [isOpen, setOpen] = React.useState(false);
|
|
@@ -3948,27 +3979,18 @@ const useGridPopoverHook = ({ className, save, invalid, dontSaveOnExternalClick,
|
|
|
3948
3979
|
}, []);
|
|
3949
3980
|
const triggerSave = React.useCallback(async (reason) => {
|
|
3950
3981
|
if (reason == CloseReason.CANCEL) {
|
|
3982
|
+
await updateValue(CancelPromise, 0);
|
|
3951
3983
|
stopEditing();
|
|
3952
|
-
onBulkEditingComplete();
|
|
3953
|
-
redrawRows();
|
|
3954
3984
|
return;
|
|
3955
3985
|
}
|
|
3956
3986
|
if (invalid?.()) {
|
|
3957
3987
|
// Don't close, don't do anything it's invalid
|
|
3958
3988
|
return;
|
|
3959
3989
|
}
|
|
3960
|
-
if (
|
|
3961
|
-
// No save method so just close
|
|
3990
|
+
if (await updateValue(save ?? (() => Promise.resolve(true)), reason === CloseReason.TAB_FORWARD ? 1 : reason === CloseReason.TAB_BACKWARD ? -1 : 0)) {
|
|
3962
3991
|
stopEditing();
|
|
3963
|
-
onBulkEditingComplete();
|
|
3964
|
-
redrawRows();
|
|
3965
|
-
return;
|
|
3966
3992
|
}
|
|
3967
|
-
|
|
3968
|
-
stopEditing();
|
|
3969
|
-
redrawRows();
|
|
3970
|
-
}
|
|
3971
|
-
}, [invalid, onBulkEditingComplete, redrawRows, save, stopEditing, updateValue]);
|
|
3993
|
+
}, [invalid, save, stopEditing, updateValue]);
|
|
3972
3994
|
const popoverWrapper = React.useCallback((children) => {
|
|
3973
3995
|
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: anchorRef.current && (jsxRuntime.jsxs(ControlledMenu, { state: isOpen ? 'open' : 'closed', portal: true, unmountOnClose: true, anchorRef: anchorRef, saveButtonRef: saveButtonRef, menuClassName: 'step-ag-grid-react-menu', onClose: (event) => {
|
|
3974
3996
|
// Prevent menu from closing when modals are invoked
|
|
@@ -3988,13 +4010,14 @@ const useGridPopoverHook = ({ className, save, invalid, dontSaveOnExternalClick,
|
|
|
3988
4010
|
return {
|
|
3989
4011
|
popoverWrapper,
|
|
3990
4012
|
triggerSave,
|
|
4013
|
+
gridPopoverOpen: isOpen,
|
|
3991
4014
|
};
|
|
3992
4015
|
};
|
|
3993
4016
|
|
|
3994
4017
|
const primitiveToSelectOption = (value) => {
|
|
3995
4018
|
return {
|
|
3996
4019
|
value: value,
|
|
3997
|
-
label: value ? String(value) : '',
|
|
4020
|
+
label: value ? String(value) : '-',
|
|
3998
4021
|
};
|
|
3999
4022
|
};
|
|
4000
4023
|
const MenuSeparatorString = '_____MENU_SEPARATOR_____';
|
|
@@ -4008,6 +4031,7 @@ const fieldToString = (field) => {
|
|
|
4008
4031
|
};
|
|
4009
4032
|
const GridFormDropDown = (props) => {
|
|
4010
4033
|
const { selectedRows, field, data } = useGridPopoverContext();
|
|
4034
|
+
const { onSelectFilter, options: propOptions, onSelectedItem } = props;
|
|
4011
4035
|
// Save triggers during async action processing which triggers another selectItem(), this ref blocks that
|
|
4012
4036
|
const [filter, setFilter] = React.useState(props.filterDefaultValue ?? '');
|
|
4013
4037
|
const [filteredValues, setFilteredValues] = React.useState();
|
|
@@ -4021,8 +4045,8 @@ const GridFormDropDown = (props) => {
|
|
|
4021
4045
|
const hasChanged = selectedRows.some((row) => row[field] !== value) ||
|
|
4022
4046
|
(subComponentValue !== undefined && subComponentInitialValue.current !== JSON.stringify(subComponentValue));
|
|
4023
4047
|
if (hasChanged) {
|
|
4024
|
-
if (
|
|
4025
|
-
await
|
|
4048
|
+
if (onSelectedItem) {
|
|
4049
|
+
await onSelectedItem({
|
|
4026
4050
|
selectedRows,
|
|
4027
4051
|
selectedRowIds: selectedRows.map((row) => row.id),
|
|
4028
4052
|
value,
|
|
@@ -4034,21 +4058,72 @@ const GridFormDropDown = (props) => {
|
|
|
4034
4058
|
}
|
|
4035
4059
|
}
|
|
4036
4060
|
return true;
|
|
4037
|
-
}, [field,
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4061
|
+
}, [field, onSelectedItem, selectedRows]);
|
|
4062
|
+
/**
|
|
4063
|
+
* Saves are wrapped in updateValue and triggered by blur events
|
|
4064
|
+
*/
|
|
4065
|
+
const save = React.useCallback(async () => {
|
|
4066
|
+
if (!options) {
|
|
4067
|
+
return true;
|
|
4068
|
+
}
|
|
4069
|
+
// Filter saved
|
|
4070
|
+
if (selectedItem === null) {
|
|
4071
|
+
if (onSelectFilter) {
|
|
4072
|
+
if (!lodashEs.isEmpty(filter)) {
|
|
4073
|
+
await onSelectFilter({
|
|
4074
|
+
selectedRows,
|
|
4075
|
+
selectedRowIds: selectedRows.map((row) => row.id),
|
|
4076
|
+
value: filter,
|
|
4077
|
+
});
|
|
4078
|
+
}
|
|
4079
|
+
return true;
|
|
4046
4080
|
}
|
|
4047
|
-
|
|
4048
|
-
|
|
4081
|
+
else {
|
|
4082
|
+
if (filteredValues && filteredValues.length === 1) {
|
|
4083
|
+
if (filteredValues[0].subComponent)
|
|
4084
|
+
return false;
|
|
4085
|
+
return await selectItemHandler(filteredValues[0].value, null);
|
|
4086
|
+
}
|
|
4049
4087
|
}
|
|
4050
|
-
|
|
4051
|
-
|
|
4088
|
+
return false;
|
|
4089
|
+
}
|
|
4090
|
+
if (selectedItem.subComponent && !subComponentIsValid.current) {
|
|
4091
|
+
return false;
|
|
4092
|
+
}
|
|
4093
|
+
await selectItemHandler(selectedItem.value, subSelectedValue);
|
|
4094
|
+
return true;
|
|
4095
|
+
}, [
|
|
4096
|
+
filter,
|
|
4097
|
+
filteredValues,
|
|
4098
|
+
onSelectFilter,
|
|
4099
|
+
options,
|
|
4100
|
+
selectItemHandler,
|
|
4101
|
+
selectedItem,
|
|
4102
|
+
selectedRows,
|
|
4103
|
+
subSelectedValue,
|
|
4104
|
+
]);
|
|
4105
|
+
const { popoverWrapper, gridPopoverOpen } = useGridPopoverHook({
|
|
4106
|
+
className: props.className,
|
|
4107
|
+
invalid: () => !options || !!(selectedItem && !subComponentIsValid.current),
|
|
4108
|
+
save,
|
|
4109
|
+
dontSaveOnExternalClick: true,
|
|
4110
|
+
});
|
|
4111
|
+
// Load up options list if it's async function
|
|
4112
|
+
const prevIsOpen = usePrevious(gridPopoverOpen);
|
|
4113
|
+
const prevFilter = usePrevious(filter);
|
|
4114
|
+
React.useEffect(() => {
|
|
4115
|
+
if ((gridPopoverOpen !== prevIsOpen || filter !== prevFilter) && gridPopoverOpen) {
|
|
4116
|
+
let optionsConf = propOptions;
|
|
4117
|
+
void (async () => {
|
|
4118
|
+
if (typeof optionsConf === 'function') {
|
|
4119
|
+
optionsConf = await optionsConf(selectedRows, filter);
|
|
4120
|
+
}
|
|
4121
|
+
if (optionsConf !== undefined) {
|
|
4122
|
+
setOptions(optionsConf);
|
|
4123
|
+
}
|
|
4124
|
+
})();
|
|
4125
|
+
}
|
|
4126
|
+
}, [filter, gridPopoverOpen, options, prevFilter, prevIsOpen, propOptions, selectedRows]);
|
|
4052
4127
|
// Local filtering.
|
|
4053
4128
|
React.useEffect(() => {
|
|
4054
4129
|
if (props.filtered == 'local') {
|
|
@@ -4076,39 +4151,6 @@ const GridFormDropDown = (props) => {
|
|
|
4076
4151
|
void reSearchOnFilterChange();
|
|
4077
4152
|
}
|
|
4078
4153
|
}, [filter, props, reSearchOnFilterChange]);
|
|
4079
|
-
/**
|
|
4080
|
-
* Saves are wrapped in updateValue and triggered by blur events
|
|
4081
|
-
*/
|
|
4082
|
-
const save = React.useCallback(async () => {
|
|
4083
|
-
if (!options)
|
|
4084
|
-
return true;
|
|
4085
|
-
// Filter saved
|
|
4086
|
-
if (selectedItem === null) {
|
|
4087
|
-
if (props.onSelectFilter) {
|
|
4088
|
-
const { onSelectFilter } = props;
|
|
4089
|
-
await onSelectFilter({ selectedRows, selectedRowIds: selectedRows.map((row) => row.id), value: filter });
|
|
4090
|
-
return true;
|
|
4091
|
-
}
|
|
4092
|
-
else {
|
|
4093
|
-
if (filteredValues && filteredValues.length === 1) {
|
|
4094
|
-
if (filteredValues[0].subComponent)
|
|
4095
|
-
return false;
|
|
4096
|
-
return await selectItemHandler(filteredValues[0].value, null);
|
|
4097
|
-
}
|
|
4098
|
-
}
|
|
4099
|
-
return false;
|
|
4100
|
-
}
|
|
4101
|
-
if (selectedItem.subComponent && !subComponentIsValid.current)
|
|
4102
|
-
return false;
|
|
4103
|
-
await selectItemHandler(selectedItem.value, subSelectedValue);
|
|
4104
|
-
return true;
|
|
4105
|
-
}, [filter, filteredValues, options, props, selectItemHandler, selectedItem, selectedRows, subSelectedValue]);
|
|
4106
|
-
const { popoverWrapper } = useGridPopoverHook({
|
|
4107
|
-
className: props.className,
|
|
4108
|
-
invalid: () => !options || !!(selectedItem && !subComponentIsValid.current),
|
|
4109
|
-
save,
|
|
4110
|
-
dontSaveOnExternalClick: true,
|
|
4111
|
-
});
|
|
4112
4154
|
let lastHeader = null;
|
|
4113
4155
|
let showHeader = null;
|
|
4114
4156
|
return popoverWrapper(jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [props.filtered && (jsxRuntime.jsxs("div", { className: 'GridFormDropDown-filter', children: [jsxRuntime.jsx(FocusableItem, { className: 'filter-item', onFocus: () => {
|
|
@@ -4116,7 +4158,7 @@ const GridFormDropDown = (props) => {
|
|
|
4116
4158
|
setSubSelectedValue(null);
|
|
4117
4159
|
subComponentIsValid.current = true;
|
|
4118
4160
|
}, children: ({ ref }) => (jsxRuntime.jsxs("div", { style: { display: 'flex', flexDirection: 'column', width: '100%' }, children: [jsxRuntime.jsx("input", { className: 'LuiTextInput-input', ref: ref, type: "text", placeholder: props.filterPlaceholder ?? 'Filter...', "data-testid": 'filteredMenu-free-text-input', defaultValue: filter, "data-allowtabtosave": true, "data-disableenterautosave": !props.onSelectFilter &&
|
|
4119
|
-
!(filteredValues && filteredValues.length === 1 && !filteredValues[0].subComponent), onChange: (e) => setFilter(e.target.value) }), props.filterHelpText && isNotEmpty(filter) && (jsxRuntime.jsx(FormError, { error: null, helpText: props.filterHelpText }))] })) }), jsxRuntime.jsx(MenuDivider, {}, `$$divider_filter`)] })), jsxRuntime.jsx(ComponentLoadingWrapper, { loading: !options, className: 'GridFormDropDown-options', children: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [options && (lodashEs.isEmpty(options) || (filteredValues && lodashEs.isEmpty(filteredValues))) && (jsxRuntime.jsx(MenuItem, { className: 'GridPopoverEditDropDown-noOptions', disabled: true, children: props.noOptionsMessage ?? 'No Options' }, `${fieldToString(field)}-empty`)), options?.map((item, index) => {
|
|
4161
|
+
!(filteredValues && filteredValues.length === 1 && !filteredValues[0].subComponent), onChange: (e) => setFilter(e.target.value.trim()) }), props.filterHelpText && isNotEmpty(filter) && (jsxRuntime.jsx(FormError, { error: null, helpText: props.filterHelpText }))] })) }), jsxRuntime.jsx(MenuDivider, {}, `$$divider_filter`)] })), jsxRuntime.jsx(ComponentLoadingWrapper, { loading: !options, className: 'GridFormDropDown-options', children: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [options && (lodashEs.isEmpty(options) || (filteredValues && lodashEs.isEmpty(filteredValues))) && (jsxRuntime.jsx(MenuItem, { className: 'GridPopoverEditDropDown-noOptions', disabled: true, children: props.noOptionsMessage ?? 'No Options' }, `${fieldToString(field)}-empty`)), options?.map((item, index) => {
|
|
4120
4162
|
showHeader = null;
|
|
4121
4163
|
if (item.value === MenuSeparatorString) {
|
|
4122
4164
|
return jsxRuntime.jsx(MenuDivider, {}, `$$divider_${index}`);
|
|
@@ -4346,11 +4388,13 @@ const GridFormMultiSelect = (props) => {
|
|
|
4346
4388
|
props.invalid(selectedRows, options.filter((o) => o.checked)));
|
|
4347
4389
|
}, [options, props, selectedRows]);
|
|
4348
4390
|
const save = React.useCallback(async (selectedRows) => {
|
|
4349
|
-
if (!options || !props.onSave)
|
|
4391
|
+
if (!options || !props.onSave) {
|
|
4350
4392
|
return true;
|
|
4393
|
+
}
|
|
4351
4394
|
// Any changes to save?
|
|
4352
|
-
if (initialValues === JSON.stringify(options))
|
|
4395
|
+
if (initialValues === JSON.stringify(options)) {
|
|
4353
4396
|
return true;
|
|
4397
|
+
}
|
|
4354
4398
|
return props.onSave({
|
|
4355
4399
|
selectedRows,
|
|
4356
4400
|
selectedOptions: options.filter((o) => o.checked),
|
|
@@ -4443,8 +4487,9 @@ const FilterInput = (props) => {
|
|
|
4443
4487
|
setOptions([...options]);
|
|
4444
4488
|
}, [filter, headerGroups, options, setOptions]);
|
|
4445
4489
|
const addCustomFilterValue = React.useCallback(() => {
|
|
4446
|
-
if (!options || !onSelectFilter)
|
|
4490
|
+
if (!options || !onSelectFilter) {
|
|
4447
4491
|
return;
|
|
4492
|
+
}
|
|
4448
4493
|
const filterTrimmed = filter.trim();
|
|
4449
4494
|
if (lodashEs.isEmpty(filterTrimmed)) {
|
|
4450
4495
|
void triggerSave();
|
|
@@ -4453,8 +4498,9 @@ const FilterInput = (props) => {
|
|
|
4453
4498
|
const preFilterOptions = JSON.stringify(options);
|
|
4454
4499
|
onSelectFilter({ filter: filterTrimmed, options });
|
|
4455
4500
|
// Detect if options list changed and update
|
|
4456
|
-
if (preFilterOptions === JSON.stringify(options))
|
|
4501
|
+
if (preFilterOptions === JSON.stringify(options)) {
|
|
4457
4502
|
return;
|
|
4503
|
+
}
|
|
4458
4504
|
setOptions([...options]);
|
|
4459
4505
|
setFilter('');
|
|
4460
4506
|
}, [filter, onSelectFilter, options, setFilter, setOptions, triggerSave]);
|
|
@@ -5049,6 +5095,7 @@ const GridPopoverMessage = (colDef, props) => GridCell({
|
|
|
5049
5095
|
singleClickEdit: true,
|
|
5050
5096
|
}, {
|
|
5051
5097
|
editor: GridFormMessage,
|
|
5098
|
+
preventAutoEdit: true,
|
|
5052
5099
|
...props,
|
|
5053
5100
|
});
|
|
5054
5101
|
|
|
@@ -5064,7 +5111,7 @@ const GridWrapper = ({ children, maxHeight }) => (jsxRuntime.jsx("div", { classN
|
|
|
5064
5111
|
const getColId = (colDef) => colDef.colId ?? '';
|
|
5065
5112
|
const isFlexColumn = (colDef) => !!colDef.flex && !isGridCellFiller(colDef);
|
|
5066
5113
|
|
|
5067
|
-
const waitForCondition = async (condition, timeoutMs) => {
|
|
5114
|
+
const waitForCondition = async (error, condition, timeoutMs) => {
|
|
5068
5115
|
const endTime = Date.now() + timeoutMs;
|
|
5069
5116
|
while (Date.now() < endTime) {
|
|
5070
5117
|
if (condition()) {
|
|
@@ -5072,7 +5119,7 @@ const waitForCondition = async (condition, timeoutMs) => {
|
|
|
5072
5119
|
}
|
|
5073
5120
|
await wait(100);
|
|
5074
5121
|
}
|
|
5075
|
-
console.warn(
|
|
5122
|
+
console.warn(error);
|
|
5076
5123
|
return false;
|
|
5077
5124
|
};
|
|
5078
5125
|
|
|
@@ -5421,8 +5468,7 @@ const GridContextProvider = (props) => {
|
|
|
5421
5468
|
startCellEditingInProgressRef.current = true;
|
|
5422
5469
|
try {
|
|
5423
5470
|
// Edit in progress so don't edit until finished, timeout waiting after 5s
|
|
5424
|
-
if (!(await waitForCondition(() => !anyUpdating(),
|
|
5425
|
-
console.error("Could not start edit because previous edit hasn't finished after 5 seconds");
|
|
5471
|
+
if (!(await waitForCondition('startCellEditing failed as update still in progress, waited for 15 seconds', () => !anyUpdating(), 15000))) {
|
|
5426
5472
|
return;
|
|
5427
5473
|
}
|
|
5428
5474
|
const colDef = gridApi.getColumnDef(colId);
|
|
@@ -5444,11 +5490,12 @@ const GridContextProvider = (props) => {
|
|
|
5444
5490
|
const rowIndex = rowNode.rowIndex;
|
|
5445
5491
|
if (rowIndex != null) {
|
|
5446
5492
|
lodashEs.defer(() => {
|
|
5447
|
-
!gridApi.isDestroyed()
|
|
5493
|
+
if (!gridApi.isDestroyed()) {
|
|
5448
5494
|
gridApi.startEditingCell({
|
|
5449
5495
|
rowIndex,
|
|
5450
5496
|
colKey: colId,
|
|
5451
5497
|
});
|
|
5498
|
+
}
|
|
5452
5499
|
});
|
|
5453
5500
|
}
|
|
5454
5501
|
}
|
|
@@ -5457,9 +5504,9 @@ const GridContextProvider = (props) => {
|
|
|
5457
5504
|
}
|
|
5458
5505
|
}, [anyUpdating, gridApi, prePopupOps, waitForExternallySelectedItemsToBeInSync]);
|
|
5459
5506
|
const bulkEditingCompleteCallbackRef = React.useRef();
|
|
5460
|
-
const onBulkEditingComplete = React.useCallback(() => {
|
|
5507
|
+
const onBulkEditingComplete = React.useCallback(async () => {
|
|
5461
5508
|
resetFocusedCellAfterCellEditing();
|
|
5462
|
-
bulkEditingCompleteCallbackRef.current?.();
|
|
5509
|
+
await bulkEditingCompleteCallbackRef.current?.();
|
|
5463
5510
|
}, [resetFocusedCellAfterCellEditing]);
|
|
5464
5511
|
const setOnBulkEditingComplete = React.useCallback((cellEditingCompleteCallback) => {
|
|
5465
5512
|
bulkEditingCompleteCallbackRef.current = cellEditingCompleteCallback;
|
|
@@ -5490,8 +5537,10 @@ const GridContextProvider = (props) => {
|
|
|
5490
5537
|
// Prevent resetting focus to original editing cell
|
|
5491
5538
|
prePopupFocusedCell.current = undefined;
|
|
5492
5539
|
const preRow = gridApi.getFocusedCell();
|
|
5540
|
+
// If we don't do this ag-grid will do its own continuation of an edit on tab, we don't want that as
|
|
5541
|
+
// we are managing it ourselves
|
|
5542
|
+
gridApi.stopEditing();
|
|
5493
5543
|
if (tabDirection === 1) {
|
|
5494
|
-
gridApi.stopEditing();
|
|
5495
5544
|
gridApi.tabToNextCell();
|
|
5496
5545
|
}
|
|
5497
5546
|
else {
|
|
@@ -5528,29 +5577,25 @@ const GridContextProvider = (props) => {
|
|
|
5528
5577
|
const selectedRows = props.selectedRows;
|
|
5529
5578
|
let ok = false;
|
|
5530
5579
|
await modifyUpdating(props.field ?? '', selectedRows.map((data) => data.id), async () => {
|
|
5531
|
-
// MATT Disabled I don't believe these are needed anymore
|
|
5532
|
-
// I've left them here just in case they are
|
|
5533
5580
|
// Need to refresh to get spinners to work on all rows
|
|
5534
|
-
|
|
5581
|
+
gridApi.refreshCells({ rowNodes: props.selectedRows, force: true });
|
|
5535
5582
|
ok = await fnUpdate(selectedRows).catch((ex) => {
|
|
5536
5583
|
console.error('Exception during modifyUpdating', ex);
|
|
5537
5584
|
return false;
|
|
5538
5585
|
});
|
|
5539
5586
|
});
|
|
5540
|
-
// MATT Disabled I don't believe these are needed anymore
|
|
5541
|
-
// I've left them here just in case they are
|
|
5542
5587
|
// async processes need to refresh their own rows
|
|
5543
|
-
|
|
5588
|
+
gridApi.refreshCells({ rowNodes: selectedRows, force: true });
|
|
5544
5589
|
if (gridApi.isDestroyed()) {
|
|
5545
5590
|
return ok;
|
|
5546
5591
|
}
|
|
5547
5592
|
if (ok) {
|
|
5548
|
-
const cell = gridApi.getFocusedCell();
|
|
5549
|
-
if (cell && gridApi.getFocusedCell() == null) {
|
|
5550
|
-
|
|
5551
|
-
}
|
|
5593
|
+
//const cell = gridApi.getFocusedCell();
|
|
5594
|
+
//if (cell && gridApi.getFocusedCell() == null) {
|
|
5595
|
+
// !gridApi.isDestroyed && gridApi.setFocusedCell(cell.rowIndex, cell.column);
|
|
5596
|
+
// }
|
|
5552
5597
|
// This is needed to trigger postSortRowsHook
|
|
5553
|
-
gridApi.refreshClientSideRowModel();
|
|
5598
|
+
!gridApi.isDestroyed && gridApi.refreshClientSideRowModel();
|
|
5554
5599
|
}
|
|
5555
5600
|
void (async () => {
|
|
5556
5601
|
// Only focus next cell if user hasn't already manually changed focus
|
|
@@ -5560,11 +5605,11 @@ const GridContextProvider = (props) => {
|
|
|
5560
5605
|
prePopupFocusedCell.current.rowIndex == postPopupFocusedCell.rowIndex &&
|
|
5561
5606
|
prePopupFocusedCell.current.column.getColId() == postPopupFocusedCell.column.getColId()) {
|
|
5562
5607
|
if (!tabDirection || !(await selectNextEditableCell(tabDirection))) {
|
|
5563
|
-
onBulkEditingComplete();
|
|
5608
|
+
await onBulkEditingComplete();
|
|
5564
5609
|
}
|
|
5565
5610
|
}
|
|
5566
5611
|
else {
|
|
5567
|
-
onBulkEditingComplete();
|
|
5612
|
+
await onBulkEditingComplete();
|
|
5568
5613
|
}
|
|
5569
5614
|
})();
|
|
5570
5615
|
return ok;
|
|
@@ -5789,19 +5834,6 @@ const GridUpdatingContextProvider = (props) => {
|
|
|
5789
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%}";
|
|
5790
5835
|
styleInject(css_248z);
|
|
5791
5836
|
|
|
5792
|
-
/**
|
|
5793
|
-
* Track previous values of states.
|
|
5794
|
-
*
|
|
5795
|
-
* @param value Value to track.
|
|
5796
|
-
*/
|
|
5797
|
-
const usePrevious = (value) => {
|
|
5798
|
-
const ref = React.useRef();
|
|
5799
|
-
React.useEffect(() => {
|
|
5800
|
-
ref.current = value;
|
|
5801
|
-
}, [value]);
|
|
5802
|
-
return ref.current;
|
|
5803
|
-
};
|
|
5804
|
-
|
|
5805
5837
|
// Kept this less than one second, so I don't have issues with waitFor as it defaults to 1s
|
|
5806
5838
|
const minimumInProgressTimeMs = 950;
|
|
5807
5839
|
const ActionButton = ({ icon, name, inProgressName, disabled, dataTestId, style, className, title, onClick, size = 'sm', iconPosition = 'left', level = 'tertiary', 'aria-label': ariaLabel, }) => {
|
|
@@ -5876,6 +5908,7 @@ const useDeferredPromise = () => {
|
|
|
5876
5908
|
};
|
|
5877
5909
|
|
|
5878
5910
|
exports.ActionButton = ActionButton;
|
|
5911
|
+
exports.CancelPromise = CancelPromise;
|
|
5879
5912
|
exports.ComponentLoadingWrapper = ComponentLoadingWrapper;
|
|
5880
5913
|
exports.ControlledMenu = ControlledMenu;
|
|
5881
5914
|
exports.Editor = Editor;
|