@linzjs/step-ag-grid 29.16.0 → 29.19.0
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/README.md +1 -1
- package/dist/index.css +27 -0
- package/dist/src/components/Grid.d.ts +3 -2
- package/dist/src/components/gridForm/GridFormInlineTextInput.d.ts +15 -0
- package/dist/src/components/gridForm/index.d.ts +1 -0
- package/dist/src/components/gridHook/useGridRangeSelection.d.ts +1 -1
- package/dist/src/components/gridPopoverEdit/GridInlineTextInput.d.ts +5 -0
- package/dist/src/components/gridPopoverEdit/index.d.ts +1 -0
- package/dist/src/contexts/GridContext.d.ts +1 -1
- package/dist/src/utils/__tests__/storybookTestUtil.ts +5 -1
- package/dist/step-ag-grid.cjs +212 -84
- package/dist/step-ag-grid.cjs.map +1 -1
- package/dist/step-ag-grid.esm.js +211 -85
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +14 -12
- package/src/components/Grid.tsx +33 -10
- package/src/components/GridPopoverHook.tsx +5 -2
- package/src/components/gridForm/GridFormInlineTextInput.tsx +119 -0
- package/src/components/gridForm/index.ts +1 -0
- package/src/components/gridHook/useGridContextMenu.tsx +3 -1
- package/src/components/gridHook/useGridCopy.ts +5 -2
- package/src/components/gridHook/useGridRangeSelection.ts +25 -4
- package/src/components/gridPopoverEdit/GridInlineTextInput.ts +13 -0
- package/src/components/gridPopoverEdit/index.ts +1 -0
- package/src/contexts/GridContext.tsx +6 -1
- package/src/contexts/GridContextProvider.tsx +30 -13
- package/src/stories/grid/GridFilterColumnsMultiSelect.stories.tsx +43 -2
- package/src/stories/grid/GridInlineText.stories.tsx +185 -0
- package/src/stories/grid/interactions/GridKeyboardInteractions.stories.tsx +3 -3
- package/src/styles/Grid.scss +5 -0
- package/src/styles/GridFormInlineTextInput.scss +23 -0
- package/src/styles/index.scss +1 -1
- package/src/utils/__tests__/storybookTestUtil.ts +5 -1
package/dist/step-ag-grid.esm.js
CHANGED
|
@@ -2632,8 +2632,9 @@ const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, co
|
|
|
2632
2632
|
const clickedRowRef = useRef(null);
|
|
2633
2633
|
const eventRef = useRef(undefined);
|
|
2634
2634
|
const openMenu = useCallback((e) => {
|
|
2635
|
-
if (!e)
|
|
2635
|
+
if (!e) {
|
|
2636
2636
|
return;
|
|
2637
|
+
}
|
|
2637
2638
|
prePopupOps();
|
|
2638
2639
|
setAnchorPoint({ x: e.clientX, y: e.clientY });
|
|
2639
2640
|
setOpen(true);
|
|
@@ -2903,7 +2904,11 @@ const useGridCopy = ({ ranges, rangeStartRef, rangeEndRef, hasSelectedMoreThanOn
|
|
|
2903
2904
|
contextMenu: (GridRangeSelectContextMenu),
|
|
2904
2905
|
context: { onCopy, copyType, setCopyType },
|
|
2905
2906
|
});
|
|
2906
|
-
const rangeSelectInterceptContextMenu = useCallback((event) =>
|
|
2907
|
+
const rangeSelectInterceptContextMenu = useCallback((event) => {
|
|
2908
|
+
return hasSelectedMoreThanOneCellRef.current && rangeStartRef.current !== null
|
|
2909
|
+
? rangeSelectContextMenu(event)
|
|
2910
|
+
: cellContextMenu(event);
|
|
2911
|
+
}, [cellContextMenu, rangeSelectContextMenu]);
|
|
2907
2912
|
return {
|
|
2908
2913
|
onCopyEvent,
|
|
2909
2914
|
rangeSelectInterceptContextMenu,
|
|
@@ -3027,6 +3032,23 @@ const useGridRangeSelection = ({ enableRangeSelection, gridDivRef, rangeStartRef
|
|
|
3027
3032
|
rangeEndRef.current = null;
|
|
3028
3033
|
updateRangeSelectionCellClasses();
|
|
3029
3034
|
}, [updateRangeSelectionCellClasses]);
|
|
3035
|
+
const mouseDownRef = useRef([0, 0]);
|
|
3036
|
+
const trackMouseDown = useCallback((e) => {
|
|
3037
|
+
mouseDownRef.current = [e.screenX, e.screenY];
|
|
3038
|
+
}, []);
|
|
3039
|
+
const trackMouseUp = useCallback((e) => {
|
|
3040
|
+
if (rangeEndRef.current) {
|
|
3041
|
+
rangeEndRef.current.clickLocation = [e.screenX, e.screenY];
|
|
3042
|
+
}
|
|
3043
|
+
}, []);
|
|
3044
|
+
useEffect(() => {
|
|
3045
|
+
document.addEventListener('mousedown', trackMouseDown, { capture: true });
|
|
3046
|
+
document.addEventListener('mouseup', trackMouseUp, { capture: true });
|
|
3047
|
+
return () => {
|
|
3048
|
+
document.removeEventListener('mousemove', trackMouseDown, { capture: true });
|
|
3049
|
+
document.removeEventListener('mouseup', trackMouseUp, { capture: true });
|
|
3050
|
+
};
|
|
3051
|
+
}, []);
|
|
3030
3052
|
const onCellMouseOver = useCallback((e, mouseDown) => {
|
|
3031
3053
|
if (!enableRangeSelection) {
|
|
3032
3054
|
return;
|
|
@@ -3040,19 +3062,20 @@ const useGridRangeSelection = ({ enableRangeSelection, gridDivRef, rangeStartRef
|
|
|
3040
3062
|
rangeEndRef.current = {
|
|
3041
3063
|
rowId: e.node.data.id,
|
|
3042
3064
|
colId: e.column.getColId(),
|
|
3043
|
-
|
|
3065
|
+
clickLocation: [0, 0],
|
|
3044
3066
|
};
|
|
3045
3067
|
if (mouseDown) {
|
|
3046
3068
|
const sortedNodes = [];
|
|
3047
3069
|
e.api.forEachNodeAfterFilterAndSort((node) => sortedNodes.push(node));
|
|
3048
3070
|
rangeSortedNodesRef.current = sortedNodes;
|
|
3049
3071
|
setRefreshIntervalEnabled(true);
|
|
3050
|
-
rangeStartRef.current = { ...rangeEndRef.current };
|
|
3072
|
+
rangeStartRef.current = { ...rangeEndRef.current, clickLocation: mouseDownRef.current };
|
|
3051
3073
|
}
|
|
3052
3074
|
if (rangeStartRef.current &&
|
|
3053
3075
|
rangeEndRef.current &&
|
|
3054
3076
|
(rangeStartRef.current.rowId !== rangeEndRef.current.rowId ||
|
|
3055
3077
|
rangeStartRef.current.colId !== rangeEndRef.current.colId)) {
|
|
3078
|
+
e.api.stopEditing();
|
|
3056
3079
|
hasSelectedMoreThanOneCellRef.current = true;
|
|
3057
3080
|
window.getSelection()?.removeAllRanges();
|
|
3058
3081
|
}
|
|
@@ -3257,7 +3280,7 @@ defaultPostSort = true, rowData, rowHeight = theme === 'ag-theme-step-default' ?
|
|
|
3257
3280
|
// ─── Selection ────────────────────────────────
|
|
3258
3281
|
autoSelectFirstRow, enableRangeSelection = false, externalSelectedIds, externalSelectedItems, selectColumnPinned = 'left', selectable, setExternalSelectedIds, setExternalSelectedItems,
|
|
3259
3282
|
// ─── Editing ──────────────────────────────────
|
|
3260
|
-
singleClickEdit = false,
|
|
3283
|
+
singleClickEdit = false, enableMultilineBulkEdit = false,
|
|
3261
3284
|
// ─── Context Menu ─────────────────────────────
|
|
3262
3285
|
contextMenuSelectRow = false, contextMenu,
|
|
3263
3286
|
// ─── Callbacks / Events ───────────────────────
|
|
@@ -3539,10 +3562,16 @@ maxInitialWidth,
|
|
|
3539
3562
|
* When grid is ready set the apis to the grid context and sync selected items to grid.
|
|
3540
3563
|
*/
|
|
3541
3564
|
const onGridReady = useCallback((event) => {
|
|
3542
|
-
setApis(event.api, hasExternallySelectedItems, dataTestId);
|
|
3565
|
+
setApis(event.api, hasExternallySelectedItems, enableMultilineBulkEdit, dataTestId);
|
|
3543
3566
|
event.api.showNoRowsOverlay();
|
|
3544
3567
|
synchroniseExternallySelectedItemsToGrid();
|
|
3545
|
-
}, [
|
|
3568
|
+
}, [
|
|
3569
|
+
dataTestId,
|
|
3570
|
+
enableMultilineBulkEdit,
|
|
3571
|
+
hasExternallySelectedItems,
|
|
3572
|
+
setApis,
|
|
3573
|
+
synchroniseExternallySelectedItemsToGrid,
|
|
3574
|
+
]);
|
|
3546
3575
|
/**
|
|
3547
3576
|
* When the grid is being initialized the data may be empty.
|
|
3548
3577
|
* This will resize columns when we have at least one row.
|
|
@@ -3585,6 +3614,11 @@ maxInitialWidth,
|
|
|
3585
3614
|
* Handle double click edit
|
|
3586
3615
|
*/
|
|
3587
3616
|
const onCellDoubleClick = useCallback((event) => {
|
|
3617
|
+
const cellEditing = event.api.getEditingCells()?.[0];
|
|
3618
|
+
if (cellEditing && cellEditing.colId === event.column.getColId() && cellEditing.rowIndex === event.rowIndex) {
|
|
3619
|
+
// Ignore double click in already editing cell
|
|
3620
|
+
return;
|
|
3621
|
+
}
|
|
3588
3622
|
const editable = fnOrVar(event.colDef?.editable, event);
|
|
3589
3623
|
if (editable && !invokeEditAction(event)) {
|
|
3590
3624
|
void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
|
|
@@ -3669,18 +3703,25 @@ maxInitialWidth,
|
|
|
3669
3703
|
* Handle single click edits
|
|
3670
3704
|
*/
|
|
3671
3705
|
const onCellClicked = useCallback((event) => {
|
|
3672
|
-
if (rangeStartRef.current && rangeEndRef.current) {
|
|
3706
|
+
if (enableRangeSelection && rangeStartRef.current && rangeEndRef.current) {
|
|
3673
3707
|
// This is to detect difference between a single click and a click drag return to cell.
|
|
3674
|
-
|
|
3675
|
-
|
|
3708
|
+
const maxDistanceBetweenC = Math.max(Math.abs(rangeEndRef.current.clickLocation[0] - rangeStartRef.current.clickLocation[0]), Math.abs(rangeEndRef.current.clickLocation[1] - rangeStartRef.current.clickLocation[1]));
|
|
3709
|
+
if (maxDistanceBetweenC > 8) {
|
|
3710
|
+
return;
|
|
3676
3711
|
}
|
|
3677
|
-
|
|
3712
|
+
clearRangeSelection();
|
|
3678
3713
|
}
|
|
3679
3714
|
const editable = fnOrVar(event.colDef?.editable, event);
|
|
3680
3715
|
if ((editable && event.colDef.singleClickEdit) ?? singleClickEdit) {
|
|
3716
|
+
const editingCell = event.api.getEditingCells()[0];
|
|
3717
|
+
// If we are editing and single click we don't want the editing to stop
|
|
3718
|
+
if (editingCell && editingCell.colId === event.column.getColId() && editingCell.rowIndex === event.rowIndex) {
|
|
3719
|
+
return;
|
|
3720
|
+
}
|
|
3721
|
+
event.api.setFocusedCell(event.rowIndex ?? 0, event.column.getColId(), event.rowPinned);
|
|
3681
3722
|
void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
|
|
3682
3723
|
}
|
|
3683
|
-
}, [clearRangeSelection, singleClickEdit, startCellEditing]);
|
|
3724
|
+
}, [clearRangeSelection, enableRangeSelection, singleClickEdit, startCellEditing]);
|
|
3684
3725
|
/**
|
|
3685
3726
|
* Set of column I'd's that are prevented from auto-sizing as they are user set
|
|
3686
3727
|
*/
|
|
@@ -3961,7 +4002,7 @@ maxInitialWidth,
|
|
|
3961
4002
|
event.api.sizeColumnsToFit();
|
|
3962
4003
|
}
|
|
3963
4004
|
}, [sizeColumns]);
|
|
3964
|
-
return (jsxs("div", { "data-testid": dataTestId, className: clsx('Grid-container', theme, 'theme-specific', staleGrid && 'Grid-sortIsStale', gridReady && rowData && autoSized && 'Grid-ready'), children: [contextMenuComponent, rangeSelectContextMenuComponent, jsx("div", { style: { flex: 1 }, ref: gridDivRef, onCopy: onCopyEvent, children: jsx(AgGridReact, { theme: 'legacy', domLayout: params.domLayout, defaultColDef: defaultColDef, columnDefs: columnDefsAdjusted, getRowId: getRowId, rowData: rowData, alwaysShowVerticalScroll: params.alwaysShowVerticalScroll, animateRows: params.animateRows ?? false, doesExternalFilterPass: doesExternalFilterPass, isExternalFilterPresent: isExternalFilterPresent, maintainColumnOrder: true, noRowsOverlayComponent: noRowsOverlayComponent, onCellClicked: onCellClicked, onCellContextMenu: rangeSelectInterceptContextMenu, onCellDoubleClicked: onCellDoubleClick, onCellEditingStopped: onCellEditingStopped, onCellFocused: onCellFocused, onCellKeyDown: onCellKeyPress, onCellMouseDown: onCellMouseDown, onCellMouseOver: onCellMouseOver, onColumnMoved: columnMoved, onColumnResized: onColumnResized, onColumnVisible: () => void setInitialContentSize(), onGridReady: onGridReady, onGridSizeChanged: onGridSizeChanged, onModelUpdated: onModelUpdated, onRowClicked: params.onRowClicked, onRowDataUpdated: onRowDataUpdated, onRowDoubleClicked: params.onRowDoubleClicked, onRowDragCancel: clearHighlightRowClasses, onRowDragEnd: onRowDragEnd, onRowDragMove: onRowDragMove, onSelectionChanged: synchroniseExternalStateToGridSelection, onSortChanged: onSortChanged, pinnedBottomRowData: params.pinnedBottomRowData, pinnedTopRowData: params.pinnedTopRowData, postSortRows: params.onRowDragEnd || !defaultPostSort ? undefined : postSortRows, preventDefaultOnContextMenu: true, quickFilterParser: quickFilterParser, rowClassRules: params.rowClassRules, rowDragText: params.rowDragText, rowHeight: rowHeight, rowSelection: selectable
|
|
4005
|
+
return (jsxs("div", { "data-testid": dataTestId, className: clsx('Grid-container', theme, 'theme-specific', staleGrid && 'Grid-sortIsStale', gridReady && rowData && autoSized && 'Grid-ready', params.hideSelectedRow && 'Grid-hideSelectedRow'), children: [contextMenuComponent, rangeSelectContextMenuComponent, jsx("div", { style: { flex: 1 }, ref: gridDivRef, onCopy: onCopyEvent, children: jsx(AgGridReact, { theme: 'legacy', domLayout: params.domLayout, defaultColDef: defaultColDef, columnDefs: columnDefsAdjusted, getRowId: getRowId, rowData: rowData, alwaysShowVerticalScroll: params.alwaysShowVerticalScroll, animateRows: params.animateRows ?? false, doesExternalFilterPass: doesExternalFilterPass, isExternalFilterPresent: isExternalFilterPresent, maintainColumnOrder: true, noRowsOverlayComponent: noRowsOverlayComponent, onCellClicked: onCellClicked, onCellContextMenu: rangeSelectInterceptContextMenu, onCellDoubleClicked: onCellDoubleClick, onCellEditingStopped: onCellEditingStopped, onCellFocused: onCellFocused, onCellKeyDown: onCellKeyPress, onCellMouseDown: onCellMouseDown, onCellMouseOver: onCellMouseOver, onColumnMoved: columnMoved, onColumnResized: onColumnResized, onColumnVisible: () => void setInitialContentSize(), onGridReady: onGridReady, onGridSizeChanged: onGridSizeChanged, onModelUpdated: onModelUpdated, onRowClicked: params.onRowClicked, onRowDataUpdated: onRowDataUpdated, onRowDoubleClicked: params.onRowDoubleClicked, onRowDragCancel: clearHighlightRowClasses, onRowDragEnd: onRowDragEnd, onRowDragMove: onRowDragMove, onSelectionChanged: synchroniseExternalStateToGridSelection, onSortChanged: onSortChanged, pinnedBottomRowData: params.pinnedBottomRowData, pinnedTopRowData: params.pinnedTopRowData, postSortRows: params.onRowDragEnd || !defaultPostSort ? undefined : postSortRows, preventDefaultOnContextMenu: true, quickFilterParser: quickFilterParser, rowClassRules: params.rowClassRules, rowDragText: params.rowDragText, rowHeight: rowHeight, rowSelection: selectable
|
|
3965
4006
|
? {
|
|
3966
4007
|
enableSelectionWithoutKeys: params.enableSelectionWithoutKeys ?? false,
|
|
3967
4008
|
enableClickSelection: params.enableClickSelection ?? false,
|
|
@@ -3971,7 +4012,7 @@ maxInitialWidth,
|
|
|
3971
4012
|
headerCheckbox: false,
|
|
3972
4013
|
}),
|
|
3973
4014
|
}
|
|
3974
|
-
: undefined,
|
|
4015
|
+
: undefined, selectionColumnDef: selectionColumnDef, suppressCellFocus: params.suppressCellFocus, suppressClickEdit: true, suppressColumnVirtualisation: suppressColumnVirtualization, suppressStartEditOnTab: true }) })] }));
|
|
3975
4016
|
};
|
|
3976
4017
|
const quickFilterParser = (filterStr) => {
|
|
3977
4018
|
// filter is exact matches exactly groups separated by commas
|
|
@@ -4786,6 +4827,7 @@ const textMatch = (text, filter) => {
|
|
|
4786
4827
|
|
|
4787
4828
|
const CancelPromise = () => Promise.resolve(true);
|
|
4788
4829
|
const useGridPopoverHook = ({ className, save, invalid, dontSaveOnExternalClick, }) => {
|
|
4830
|
+
const { resetFocusedCellAfterCellEditing } = useGridContext();
|
|
4789
4831
|
const { anchorRef, saving, updateValue, stopEditing } = useGridPopoverContext();
|
|
4790
4832
|
const saveButtonRef = useRef(null);
|
|
4791
4833
|
const [isOpen, setOpen] = useState(false);
|
|
@@ -4796,6 +4838,7 @@ const useGridPopoverHook = ({ className, save, invalid, dontSaveOnExternalClick,
|
|
|
4796
4838
|
if (reason == CloseReason.CANCEL) {
|
|
4797
4839
|
await updateValue(CancelPromise, 0);
|
|
4798
4840
|
stopEditing();
|
|
4841
|
+
resetFocusedCellAfterCellEditing();
|
|
4799
4842
|
return;
|
|
4800
4843
|
}
|
|
4801
4844
|
if (invalid?.()) {
|
|
@@ -4804,8 +4847,9 @@ const useGridPopoverHook = ({ className, save, invalid, dontSaveOnExternalClick,
|
|
|
4804
4847
|
}
|
|
4805
4848
|
if (await updateValue(save ?? (() => Promise.resolve(true)), reason === CloseReason.TAB_FORWARD ? 1 : reason === CloseReason.TAB_BACKWARD ? -1 : 0)) {
|
|
4806
4849
|
stopEditing();
|
|
4850
|
+
resetFocusedCellAfterCellEditing();
|
|
4807
4851
|
}
|
|
4808
|
-
}, [invalid, save, stopEditing, updateValue]);
|
|
4852
|
+
}, [invalid, resetFocusedCellAfterCellEditing, save, stopEditing, updateValue]);
|
|
4809
4853
|
const popoverWrapper = useCallback((children) => {
|
|
4810
4854
|
return (jsx(Fragment, { children: anchorRef.current && (jsxs(ControlledMenu, { state: isOpen ? 'open' : 'closed', portal: true, unmountOnClose: true, anchorRef: anchorRef, saveButtonRef: saveButtonRef, menuClassName: 'step-ag-grid-react-menu', onClose: (event) => {
|
|
4811
4855
|
// Prevent menu from closing when modals are invoked
|
|
@@ -5174,6 +5218,128 @@ const GridFormEditBearing = (props) => {
|
|
|
5174
5218
|
: props.formatValue(bearingNumberParser(value)), error: bearingStringValidator(value, props.range), helpText: 'Press enter or tab to save' }) }));
|
|
5175
5219
|
};
|
|
5176
5220
|
|
|
5221
|
+
const TextInputValidator = (props, value, data, context) => {
|
|
5222
|
+
if (value == null)
|
|
5223
|
+
return null;
|
|
5224
|
+
// This can happen because subcomponent is invoked without type safety
|
|
5225
|
+
if (typeof value !== 'string') {
|
|
5226
|
+
return 'Value is not a string';
|
|
5227
|
+
}
|
|
5228
|
+
if (props.required && value.trim() == '') {
|
|
5229
|
+
return 'Must not be empty';
|
|
5230
|
+
}
|
|
5231
|
+
if (props.maxLength && value.length > props.maxLength) {
|
|
5232
|
+
return `Must be no longer than ${props.maxLength} characters`;
|
|
5233
|
+
}
|
|
5234
|
+
if (props.maxBytes && stringByteLengthIsInvalid(value, props.maxBytes)) {
|
|
5235
|
+
return `Must be no longer than ${props.maxBytes} bytes`;
|
|
5236
|
+
}
|
|
5237
|
+
const nf = props.numberFormat;
|
|
5238
|
+
if (nf) {
|
|
5239
|
+
if (value != '' && !isFloat(value)) {
|
|
5240
|
+
return `Must be a valid number`;
|
|
5241
|
+
}
|
|
5242
|
+
if (value != '') {
|
|
5243
|
+
const number = parseFloat(value);
|
|
5244
|
+
if (nf.notZero && number === 0) {
|
|
5245
|
+
return `Must not be 0`;
|
|
5246
|
+
}
|
|
5247
|
+
if (nf.gtMin != null && number <= nf.gtMin) {
|
|
5248
|
+
return `Must be greater than ${nf.gtMin.toLocaleString()}`;
|
|
5249
|
+
}
|
|
5250
|
+
if (nf.geMin != null && number < nf.geMin) {
|
|
5251
|
+
return `Must not be less than ${nf.geMin.toLocaleString()}`;
|
|
5252
|
+
}
|
|
5253
|
+
if (nf.ltMax != null && number >= nf.ltMax) {
|
|
5254
|
+
return `Must be less than ${nf.ltMax.toLocaleString()}`;
|
|
5255
|
+
}
|
|
5256
|
+
if (nf.leMax != null && number > nf.leMax) {
|
|
5257
|
+
return `Must not be greater than ${nf.leMax.toLocaleString()}`;
|
|
5258
|
+
}
|
|
5259
|
+
if (nf.precision != null && value != '') {
|
|
5260
|
+
if (parseFloat(number.toPrecision(nf.precision)) != number) {
|
|
5261
|
+
return `Must have no more than ${nf.precision} digits precision`;
|
|
5262
|
+
}
|
|
5263
|
+
}
|
|
5264
|
+
if (nf.scale != null && value != '') {
|
|
5265
|
+
if (parseFloat(number.toFixed(nf.scale)) != number) {
|
|
5266
|
+
return nf.scale == 0 ? `Must be a whole number` : `Must have no more than ${nf.scale} decimal places`;
|
|
5267
|
+
}
|
|
5268
|
+
}
|
|
5269
|
+
}
|
|
5270
|
+
}
|
|
5271
|
+
if (props.invalid) {
|
|
5272
|
+
return props.invalid(value, data, context);
|
|
5273
|
+
}
|
|
5274
|
+
return null;
|
|
5275
|
+
};
|
|
5276
|
+
|
|
5277
|
+
const GridFormInlineTextInput = (props) => {
|
|
5278
|
+
const { onSave } = props;
|
|
5279
|
+
const { getSelectedRows, prePopupOps } = useGridContext();
|
|
5280
|
+
const { field, value: initialVale, data } = useGridPopoverContext();
|
|
5281
|
+
const initValue = useMemo(() => (initialVale == null ? '' : `${initialVale}`), [initialVale]);
|
|
5282
|
+
const [value, setValue] = useState(initValue);
|
|
5283
|
+
const invalid = useCallback(() => TextInputValidator(props, value, data, {}), [data, props, value]);
|
|
5284
|
+
useEffect(() => {
|
|
5285
|
+
prePopupOps();
|
|
5286
|
+
}, [prePopupOps]);
|
|
5287
|
+
const save = useCallback(async () => {
|
|
5288
|
+
if (invalid()) {
|
|
5289
|
+
return false;
|
|
5290
|
+
}
|
|
5291
|
+
const trimmedValue = value.trim();
|
|
5292
|
+
// No change, so don't save
|
|
5293
|
+
if (initValue === trimmedValue) {
|
|
5294
|
+
return true;
|
|
5295
|
+
}
|
|
5296
|
+
if (!onSave) {
|
|
5297
|
+
console.error(`No onSave handler for GridFormInlineTextInput "${String(field)}`);
|
|
5298
|
+
return false;
|
|
5299
|
+
}
|
|
5300
|
+
const selectedRows = getSelectedRows();
|
|
5301
|
+
const selectedRowIds = selectedRows.map((data) => data.id);
|
|
5302
|
+
return onSave({
|
|
5303
|
+
selectedRowIds,
|
|
5304
|
+
selectedRows,
|
|
5305
|
+
value: trimmedValue,
|
|
5306
|
+
});
|
|
5307
|
+
}, [invalid, value, initValue, onSave, getSelectedRows, field]);
|
|
5308
|
+
const inputRef = useRef(null);
|
|
5309
|
+
useEffect(() => {
|
|
5310
|
+
inputRef.current?.focus();
|
|
5311
|
+
inputRef.current?.select();
|
|
5312
|
+
}, []);
|
|
5313
|
+
const { triggerSave } = useGridPopoverHook({
|
|
5314
|
+
className: props.className,
|
|
5315
|
+
invalid,
|
|
5316
|
+
save,
|
|
5317
|
+
});
|
|
5318
|
+
const tabDirectionRef = useRef(CloseReason.BLUR);
|
|
5319
|
+
const tabRecorder = useCallback((e) => {
|
|
5320
|
+
if (e.key === 'Tab') {
|
|
5321
|
+
tabDirectionRef.current = e.shiftKey ? CloseReason.TAB_BACKWARD : CloseReason.TAB_FORWARD;
|
|
5322
|
+
e.preventDefault();
|
|
5323
|
+
e.stopPropagation();
|
|
5324
|
+
void triggerSave(tabDirectionRef.current);
|
|
5325
|
+
}
|
|
5326
|
+
}, [triggerSave]);
|
|
5327
|
+
useEffect(() => {
|
|
5328
|
+
const input = inputRef.current;
|
|
5329
|
+
input?.addEventListener('keydown', tabRecorder, { capture: true });
|
|
5330
|
+
return () => {
|
|
5331
|
+
input?.removeEventListener('keydown', tabRecorder, { capture: true });
|
|
5332
|
+
};
|
|
5333
|
+
}, [tabRecorder]);
|
|
5334
|
+
return (jsx("div", { className: clsx('GridFormInlineTextInput', invalid() && 'GridFormInlineTextInput-error'), title: String(invalid() ?? ''), children: jsx("input", { ref: inputRef, type: 'text', value: value, onChange: (e) => setValue(e.target.value), placeholder: props.placeholder ?? 'Type here', onBlur: () => {
|
|
5335
|
+
void triggerSave(CloseReason.BLUR);
|
|
5336
|
+
}, onKeyUp: (e) => {
|
|
5337
|
+
if (e.key === 'Enter') {
|
|
5338
|
+
void triggerSave(CloseReason.BLUR);
|
|
5339
|
+
}
|
|
5340
|
+
} }) }));
|
|
5341
|
+
};
|
|
5342
|
+
|
|
5177
5343
|
const GridFormMessage = (props) => {
|
|
5178
5344
|
const { selectedRows } = useGridPopoverContext();
|
|
5179
5345
|
const [message, setMessage] = useState(null);
|
|
@@ -5585,62 +5751,6 @@ const TextAreaInput = (props) => {
|
|
|
5585
5751
|
}, "data-allowtabtosave": props.allowTabToSave, children: props.value }) })] }), jsx(FormError, { error: props.error, helpText: props.helpText })] }));
|
|
5586
5752
|
};
|
|
5587
5753
|
|
|
5588
|
-
const TextInputValidator = (props, value, data, context) => {
|
|
5589
|
-
if (value == null)
|
|
5590
|
-
return null;
|
|
5591
|
-
// This can happen because subcomponent is invoked without type safety
|
|
5592
|
-
if (typeof value !== 'string') {
|
|
5593
|
-
return 'Value is not a string';
|
|
5594
|
-
}
|
|
5595
|
-
if (props.required && value.trim() == '') {
|
|
5596
|
-
return 'Must not be empty';
|
|
5597
|
-
}
|
|
5598
|
-
if (props.maxLength && value.length > props.maxLength) {
|
|
5599
|
-
return `Must be no longer than ${props.maxLength} characters`;
|
|
5600
|
-
}
|
|
5601
|
-
if (props.maxBytes && stringByteLengthIsInvalid(value, props.maxBytes)) {
|
|
5602
|
-
return `Must be no longer than ${props.maxBytes} bytes`;
|
|
5603
|
-
}
|
|
5604
|
-
const nf = props.numberFormat;
|
|
5605
|
-
if (nf) {
|
|
5606
|
-
if (value != '' && !isFloat(value)) {
|
|
5607
|
-
return `Must be a valid number`;
|
|
5608
|
-
}
|
|
5609
|
-
if (value != '') {
|
|
5610
|
-
const number = parseFloat(value);
|
|
5611
|
-
if (nf.notZero && number === 0) {
|
|
5612
|
-
return `Must not be 0`;
|
|
5613
|
-
}
|
|
5614
|
-
if (nf.gtMin != null && number <= nf.gtMin) {
|
|
5615
|
-
return `Must be greater than ${nf.gtMin.toLocaleString()}`;
|
|
5616
|
-
}
|
|
5617
|
-
if (nf.geMin != null && number < nf.geMin) {
|
|
5618
|
-
return `Must not be less than ${nf.geMin.toLocaleString()}`;
|
|
5619
|
-
}
|
|
5620
|
-
if (nf.ltMax != null && number >= nf.ltMax) {
|
|
5621
|
-
return `Must be less than ${nf.ltMax.toLocaleString()}`;
|
|
5622
|
-
}
|
|
5623
|
-
if (nf.leMax != null && number > nf.leMax) {
|
|
5624
|
-
return `Must not be greater than ${nf.leMax.toLocaleString()}`;
|
|
5625
|
-
}
|
|
5626
|
-
if (nf.precision != null && value != '') {
|
|
5627
|
-
if (parseFloat(number.toPrecision(nf.precision)) != number) {
|
|
5628
|
-
return `Must have no more than ${nf.precision} digits precision`;
|
|
5629
|
-
}
|
|
5630
|
-
}
|
|
5631
|
-
if (nf.scale != null && value != '') {
|
|
5632
|
-
if (parseFloat(number.toFixed(nf.scale)) != number) {
|
|
5633
|
-
return nf.scale == 0 ? `Must be a whole number` : `Must have no more than ${nf.scale} decimal places`;
|
|
5634
|
-
}
|
|
5635
|
-
}
|
|
5636
|
-
}
|
|
5637
|
-
}
|
|
5638
|
-
if (props.invalid) {
|
|
5639
|
-
return props.invalid(value, data, context);
|
|
5640
|
-
}
|
|
5641
|
-
return null;
|
|
5642
|
-
};
|
|
5643
|
-
|
|
5644
5754
|
const GridFormSubComponentTextArea = (props) => {
|
|
5645
5755
|
const { value, data, setValue, setValid, context } = useContext(GridSubComponentContext);
|
|
5646
5756
|
const helpText = props.helpText ?? 'Press tab to save';
|
|
@@ -5819,6 +5929,11 @@ const GridEditBoolean = (colDef, editorProps) => {
|
|
|
5819
5929
|
});
|
|
5820
5930
|
};
|
|
5821
5931
|
|
|
5932
|
+
const GridInlineTextInput = (colDef, params) => GridCell(colDef, {
|
|
5933
|
+
editor: GridFormInlineTextInput,
|
|
5934
|
+
...params,
|
|
5935
|
+
});
|
|
5936
|
+
|
|
5822
5937
|
const GridPopoutEditMultiSelect = (colDef, props) => GridCell(colDef, {
|
|
5823
5938
|
editor: GridFormMultiSelect,
|
|
5824
5939
|
...props,
|
|
@@ -5959,6 +6074,7 @@ const GridContextProvider = (props) => {
|
|
|
5959
6074
|
const [invisibleColumnIds, _setInvisibleColumnIds] = useState();
|
|
5960
6075
|
const testId = useRef();
|
|
5961
6076
|
const hasExternallySelectedItemsRef = useRef(false);
|
|
6077
|
+
const enableMultilineBulkEditRef = useRef(false);
|
|
5962
6078
|
const idsBeforeUpdate = useRef([]);
|
|
5963
6079
|
const prePopupFocusedCell = useRef();
|
|
5964
6080
|
const [externallySelectedItemsAreInSync, setExternallySelectedItemsAreInSync] = useState(false);
|
|
@@ -6023,8 +6139,9 @@ const GridContextProvider = (props) => {
|
|
|
6023
6139
|
/**
|
|
6024
6140
|
* Set the grid api when the grid is ready.
|
|
6025
6141
|
*/
|
|
6026
|
-
const setApis = useCallback((gridApi, hasExternallySelectedItems, dataTestId) => {
|
|
6142
|
+
const setApis = useCallback((gridApi, hasExternallySelectedItems, enableMultilineBulkEdit, dataTestId) => {
|
|
6027
6143
|
hasExternallySelectedItemsRef.current = hasExternallySelectedItems;
|
|
6144
|
+
enableMultilineBulkEditRef.current = enableMultilineBulkEdit;
|
|
6028
6145
|
testId.current = dataTestId;
|
|
6029
6146
|
setGridApi(gridApi);
|
|
6030
6147
|
gridApi?.setGridOption('quickFilterText', quickFilter);
|
|
@@ -6169,7 +6286,7 @@ const GridContextProvider = (props) => {
|
|
|
6169
6286
|
if (flash) {
|
|
6170
6287
|
delay(() => {
|
|
6171
6288
|
try {
|
|
6172
|
-
!gridApi.isDestroyed && gridApi.flashCells({ rowNodes });
|
|
6289
|
+
!gridApi.isDestroyed() && gridApi.flashCells({ rowNodes });
|
|
6173
6290
|
}
|
|
6174
6291
|
catch {
|
|
6175
6292
|
// ignore, flash cells sometimes throws errors as nodes have gone out of scope
|
|
@@ -6235,13 +6352,13 @@ const GridContextProvider = (props) => {
|
|
|
6235
6352
|
* Then we size the flexed columns.
|
|
6236
6353
|
*/
|
|
6237
6354
|
const autoSizeColumns = useCallback(async ({ skipHeader, colIds, userSizedColIds } = {}) => {
|
|
6238
|
-
if (!gridApi || !gridApi.getColumnState()) {
|
|
6355
|
+
if (!gridApi || gridApi.isDestroyed() || !gridApi.getColumnState()) {
|
|
6239
6356
|
return null;
|
|
6240
6357
|
}
|
|
6241
6358
|
try {
|
|
6242
6359
|
const colIdsSet = colIds instanceof Set ? colIds : new Set(colIds);
|
|
6243
6360
|
const getVisibleColStates = () => {
|
|
6244
|
-
const colStates = gridApi.getColumnState();
|
|
6361
|
+
const colStates = gridApi.getColumnState() ?? [];
|
|
6245
6362
|
return colStates.filter((colState) => {
|
|
6246
6363
|
const colId = colState.colId;
|
|
6247
6364
|
return (isEmpty(colIdsSet) || colIdsSet.has(colId)) && !userSizedColIds?.has(colId);
|
|
@@ -6301,9 +6418,11 @@ const GridContextProvider = (props) => {
|
|
|
6301
6418
|
if (!gridApi || gridApi.isDestroyed() || startCellEditingInProgressRef.current) {
|
|
6302
6419
|
return;
|
|
6303
6420
|
}
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
|
|
6421
|
+
const cellToFocus = prePopupFocusedCell.current;
|
|
6422
|
+
if (cellToFocus) {
|
|
6423
|
+
defer(() => {
|
|
6424
|
+
gridApi.setFocusedCell(cellToFocus.rowIndex, cellToFocus.column);
|
|
6425
|
+
});
|
|
6307
6426
|
}
|
|
6308
6427
|
}, [gridApi]);
|
|
6309
6428
|
// waitForExternallySelectedItemsToBeInSync can't use the state as it won't be updated during function execution
|
|
@@ -6369,9 +6488,8 @@ const GridContextProvider = (props) => {
|
|
|
6369
6488
|
}, [anyUpdating, gridApi, prePopupOps, waitForExternallySelectedItemsToBeInSync]);
|
|
6370
6489
|
const bulkEditingCompleteCallbackRef = useRef();
|
|
6371
6490
|
const onBulkEditingComplete = useCallback(async () => {
|
|
6372
|
-
resetFocusedCellAfterCellEditing();
|
|
6373
6491
|
await bulkEditingCompleteCallbackRef.current?.();
|
|
6374
|
-
}, [
|
|
6492
|
+
}, []);
|
|
6375
6493
|
const setOnBulkEditingComplete = useCallback((cellEditingCompleteCallback) => {
|
|
6376
6494
|
bulkEditingCompleteCallbackRef.current = cellEditingCompleteCallback;
|
|
6377
6495
|
}, []);
|
|
@@ -6411,10 +6529,18 @@ const GridContextProvider = (props) => {
|
|
|
6411
6529
|
return true;
|
|
6412
6530
|
}
|
|
6413
6531
|
const postRow = gridApi.getFocusedCell();
|
|
6414
|
-
if (
|
|
6415
|
-
//
|
|
6416
|
-
|
|
6417
|
-
|
|
6532
|
+
if (enableMultilineBulkEditRef.current) {
|
|
6533
|
+
// Last cell in grid, nowhere to tab
|
|
6534
|
+
if (preRow?.rowIndex === postRow?.rowIndex && preRow?.column === postRow?.column) {
|
|
6535
|
+
break;
|
|
6536
|
+
}
|
|
6537
|
+
}
|
|
6538
|
+
else {
|
|
6539
|
+
if (preRow?.rowIndex !== postRow?.rowIndex || preRow?.column === postRow?.column) {
|
|
6540
|
+
// We didn't find an editable cell in the same row, or the cell column didn't change
|
|
6541
|
+
// implying it was start/end of grid
|
|
6542
|
+
break;
|
|
6543
|
+
}
|
|
6418
6544
|
}
|
|
6419
6545
|
if (focusedCellIsEditable()) {
|
|
6420
6546
|
const focusedCell = gridApi.getFocusedCell();
|
|
@@ -6769,5 +6895,5 @@ const useDeferredPromise = () => {
|
|
|
6769
6895
|
};
|
|
6770
6896
|
};
|
|
6771
6897
|
|
|
6772
|
-
export { ActionButton, CancelPromise, ComponentLoadingWrapper, ControlledMenu, Editor, FocusableItem, FormError, GenericCellEditorComponentWrapper, Grid, GridButton, GridCell, GridCellBearingValueFormatter, GridCellFiller, GridCellFillerColId, GridCellMultiEditor, GridCellMultiSelectClassRules, GridCellRenderer, GridContext, GridContextProvider, GridEditBoolean, GridFilterButtons, GridFilterColumnsMultiSelect, GridFilterColumnsToggle, GridFilterDownloadCsvButton, GridFilterHeaderIconButton, GridFilterQuick, GridFilters, GridFormDropDown, GridFormEditBearing, GridFormMessage, GridFormMultiSelect, GridFormMultiSelectGrid, GridFormPopoverMenu, GridFormSubComponentTextArea, GridFormSubComponentTextInput, GridFormTextArea, GridFormTextInput, GridIcon, GridLoadableCell, GridNoRowsOverlay, GridNoRowsOverlayFr, GridPopoutEditMultiSelect, GridPopoutEditMultiSelectGrid, GridPopoverContext, GridPopoverContextProvider, GridPopoverEditBearing, GridPopoverEditBearingCorrection, GridPopoverEditBearingCorrectionEditorParams, GridPopoverEditBearingEditorParams, GridPopoverEditDropDown, GridPopoverMenu, GridPopoverMessage, GridPopoverTextArea, GridPopoverTextInput, GridRenderPopoutMenuCell, GridSubComponentContext, GridUpdatingContext, GridUpdatingContextProvider, GridWrapper, Menu, MenuButton, MenuDivider, MenuGroup, MenuHeader, MenuHeaderItem, MenuHeaderString, MenuItem, MenuRadioGroup, MenuSeparator, MenuSeparatorString, PopoutMenuSeparator, SubMenu, TextAreaInput, TextInputFormatted, TextInputValidator, agGridSelectRowColId, bearingCorrectionRangeValidator, bearingCorrectionValueFormatter, bearingNumberParser, bearingRangeValidator, bearingStringValidator, bearingValueFormatter, colStateFlexed, colStateId, colStateNotFlexed, compareNaturalInsensitive, convertDDToDMS, createCheckboxMultiFilterParams, defaultValueFormatter, downloadCsvUseValueFormattersProcessCellCallback, findParentWithClass, fnOrVar, generateFilterGetter, hasParentClass, isFloat, isGridCellFiller, isNotEmpty, primitiveToSelectOption, sanitiseFileName, stringByteLengthIsInvalid, suppressCellKeyboardEvents, textMatch, useDeferredPromise, useGridContext, useGridContextMenu, useGridFilter, useGridPopoverContext, useGridPopoverHook, useMenuState, usePostSortRowsHook, wait, waitForCondition };
|
|
6898
|
+
export { ActionButton, CancelPromise, ComponentLoadingWrapper, ControlledMenu, Editor, FocusableItem, FormError, GenericCellEditorComponentWrapper, Grid, GridButton, GridCell, GridCellBearingValueFormatter, GridCellFiller, GridCellFillerColId, GridCellMultiEditor, GridCellMultiSelectClassRules, GridCellRenderer, GridContext, GridContextProvider, GridEditBoolean, GridFilterButtons, GridFilterColumnsMultiSelect, GridFilterColumnsToggle, GridFilterDownloadCsvButton, GridFilterHeaderIconButton, GridFilterQuick, GridFilters, GridFormDropDown, GridFormEditBearing, GridFormInlineTextInput, GridFormMessage, GridFormMultiSelect, GridFormMultiSelectGrid, GridFormPopoverMenu, GridFormSubComponentTextArea, GridFormSubComponentTextInput, GridFormTextArea, GridFormTextInput, GridIcon, GridInlineTextInput, GridLoadableCell, GridNoRowsOverlay, GridNoRowsOverlayFr, GridPopoutEditMultiSelect, GridPopoutEditMultiSelectGrid, GridPopoverContext, GridPopoverContextProvider, GridPopoverEditBearing, GridPopoverEditBearingCorrection, GridPopoverEditBearingCorrectionEditorParams, GridPopoverEditBearingEditorParams, GridPopoverEditDropDown, GridPopoverMenu, GridPopoverMessage, GridPopoverTextArea, GridPopoverTextInput, GridRenderPopoutMenuCell, GridSubComponentContext, GridUpdatingContext, GridUpdatingContextProvider, GridWrapper, Menu, MenuButton, MenuDivider, MenuGroup, MenuHeader, MenuHeaderItem, MenuHeaderString, MenuItem, MenuRadioGroup, MenuSeparator, MenuSeparatorString, PopoutMenuSeparator, SubMenu, TextAreaInput, TextInputFormatted, TextInputValidator, agGridSelectRowColId, bearingCorrectionRangeValidator, bearingCorrectionValueFormatter, bearingNumberParser, bearingRangeValidator, bearingStringValidator, bearingValueFormatter, colStateFlexed, colStateId, colStateNotFlexed, compareNaturalInsensitive, convertDDToDMS, createCheckboxMultiFilterParams, defaultValueFormatter, downloadCsvUseValueFormattersProcessCellCallback, findParentWithClass, fnOrVar, generateFilterGetter, hasParentClass, isFloat, isGridCellFiller, isNotEmpty, primitiveToSelectOption, sanitiseFileName, stringByteLengthIsInvalid, suppressCellKeyboardEvents, textMatch, useDeferredPromise, useGridContext, useGridContextMenu, useGridFilter, useGridPopoverContext, useGridPopoverHook, useMenuState, usePostSortRowsHook, wait, waitForCondition };
|
|
6773
6899
|
//# sourceMappingURL=step-ag-grid.esm.js.map
|