@linzjs/step-ag-grid 31.1.1 → 31.2.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.
@@ -259,6 +259,10 @@ $grid-base-font-size: calc(#{lui.$base-font-size} - 1px);
259
259
  border-bottom: 2px dashed lui.$andrea;
260
260
  }
261
261
 
262
+ .ag-row-dragging {
263
+ opacity: 0.5;
264
+ }
265
+
262
266
  .ag-pinned-left-header,
263
267
  .ag-pinned-right-header,
264
268
  .ag-pinned-right-cols-container,
@@ -0,0 +1,10 @@
1
+ import { GridBaseRow } from './types';
2
+ /**
3
+ * Reorders rows by removing movedRows from the array and inserting them at the target position.
4
+ * @param rows - The current row array.
5
+ * @param movedRows - Rows to move, in desired insertion order (typically display order).
6
+ * @param targetRow - The row to insert relative to.
7
+ * @param direction - -1 inserts above targetRow, 1 inserts below targetRow.
8
+ * @returns A new array with the rows reordered, or the original array if the operation is a no-op.
9
+ */
10
+ export declare function reorderRows<T extends GridBaseRow>(rows: T[], movedRows: T[], targetRow: T, direction: -1 | 1): T[];
@@ -0,0 +1 @@
1
+ export {};
@@ -4,6 +4,7 @@ export * from './GridCell';
4
4
  export * from './GridCellFiller';
5
5
  export * from './GridCellMultiEditor';
6
6
  export * from './GridCellMultiSelectClassRules';
7
+ export * from './gridDragUtil';
7
8
  export * from './gridFilter';
8
9
  export * from './gridForm';
9
10
  export * from './gridHook';
@@ -5,8 +5,12 @@ export interface GridBaseRow {
5
5
  id: string | number;
6
6
  }
7
7
  export interface GridOnRowDragEndProps<TData extends GridBaseRow> {
8
+ /** The row the user physically grabbed by its drag handle. */
8
9
  movedRow: TData;
10
+ /** All rows being moved, ordered by display index. Single-element array when dragging an unselected row. */
11
+ movedRows: TData[];
9
12
  targetRow: TData;
13
+ /** -1 = dropped above target, 1 = dropped below target. */
10
14
  direction: -1 | 1;
11
15
  }
12
16
  export interface ColDefT<TData extends GridBaseRow, ValueType = any> extends ColDef<TData, ValueType> {
@@ -61748,10 +61748,36 @@ maxInitialWidth,
61748
61748
  el.classList.remove('ag-row-highlight-below');
61749
61749
  });
61750
61750
  }, []);
61751
+ const clearDragRowClasses = React13.useCallback(() => {
61752
+ document.querySelectorAll(`.ag-row-dragging`)?.forEach((el) => {
61753
+ el.classList.remove('ag-row-dragging');
61754
+ });
61755
+ }, []);
61751
61756
  const gridElementRef = React13.useRef(undefined);
61757
+ const multiDragAppliedRef = React13.useRef(false);
61758
+ const multiDragCountRef = React13.useRef(0);
61752
61759
  const onRowDragMove = React13.useCallback((event) => {
61753
61760
  if (startDragYRef.current === null) {
61754
61761
  startDragYRef.current = event.y;
61762
+ // On first move event, apply ag-row-dragging class to all selected rows for multi-drag
61763
+ if (rowSelection === 'multiple' && event.node.isSelected()) {
61764
+ const selectedNodes = event.api.getSelectedNodes().filter((n) => n.displayed && n.data != null);
61765
+ if (selectedNodes.length > 1) {
61766
+ multiDragAppliedRef.current = true;
61767
+ multiDragCountRef.current = selectedNodes.length;
61768
+ // Find the grid body element for scoped queries
61769
+ const targetEl = event.event.target;
61770
+ const gridElement = targetEl?.closest('.ag-body');
61771
+ if (gridElement) {
61772
+ gridElementRef.current = gridElement;
61773
+ for (const node of selectedNodes) {
61774
+ gridElement.querySelectorAll(`[row-id='${node.data.id}']`)?.forEach((el) => {
61775
+ el.classList.add('ag-row-dragging');
61776
+ });
61777
+ }
61778
+ }
61779
+ }
61780
+ }
61755
61781
  }
61756
61782
  const yDiff = event.y - startDragYRef.current;
61757
61783
  const data = event.overNode?.data;
@@ -61770,7 +61796,7 @@ maxInitialWidth,
61770
61796
  el.classList.add(yDiff < 0 ? 'ag-row-highlight-above' : 'ag-row-highlight-below');
61771
61797
  });
61772
61798
  }
61773
- }, [clearHighlightRowClasses]);
61799
+ }, [clearHighlightRowClasses, rowSelection]);
61774
61800
  const onCellFocused = React13.useCallback((event) => {
61775
61801
  if (event.rowIndex == null) {
61776
61802
  return;
@@ -61799,6 +61825,9 @@ maxInitialWidth,
61799
61825
  }, [paramsOnCellFocused]);
61800
61826
  const onRowDragEnd = React13.useCallback((event) => {
61801
61827
  clearHighlightRowClasses();
61828
+ clearDragRowClasses();
61829
+ multiDragAppliedRef.current = false;
61830
+ multiDragCountRef.current = 0;
61802
61831
  gridElementRef.current = undefined;
61803
61832
  if (!params.onRowDragEnd || startDragYRef.current === null) {
61804
61833
  return;
@@ -61811,9 +61840,26 @@ maxInitialWidth,
61811
61840
  if (!movedRow || !targetRow || movedRow === targetRow || yDiff === 0) {
61812
61841
  return;
61813
61842
  }
61814
- void params.onRowDragEnd({ movedRow, targetRow, direction: yDiff > 0 ? 1 : -1 });
61843
+ // Determine movedRows: if dragged row is part of a multi-selection, include all selected & displayed rows
61844
+ let movedRows;
61845
+ if (rowSelection === 'multiple' && event.node.isSelected()) {
61846
+ movedRows = event.api
61847
+ .getSelectedNodes()
61848
+ .filter((n) => n.displayed && n.data != null)
61849
+ .sort((a, b) => (a.rowIndex ?? 0) - (b.rowIndex ?? 0))
61850
+ .map((n) => n.data);
61851
+ }
61852
+ else {
61853
+ movedRows = [movedRow];
61854
+ }
61855
+ // If targetRow is one of the moved rows, no-op
61856
+ if (movedRows.some((r) => r.id === targetRow.id)) {
61857
+ return;
61858
+ }
61859
+ const direction = yDiff > 0 ? 1 : -1;
61860
+ void params.onRowDragEnd({ movedRow, movedRows, targetRow, direction });
61815
61861
  }
61816
- }, [params, clearHighlightRowClasses]);
61862
+ }, [params, clearHighlightRowClasses, clearDragRowClasses, rowSelection]);
61817
61863
  React13.useEffect(() => {
61818
61864
  if ((setExternalSelectedItems || setExternalSelectedIds) && selectable == null) {
61819
61865
  console.warn('<Grid/> has setExternalSelectedItems/setExternalSelectedIds parameter, but is missing selectable parameter,' +
@@ -61883,7 +61929,20 @@ maxInitialWidth,
61883
61929
  event.api.sizeColumnsToFit();
61884
61930
  }
61885
61931
  }, [sizeColumns]);
61886
- return (jsxRuntime.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, jsxRuntime.jsx("div", { style: { flex: 1 }, ref: gridDivRef, onCopy: onCopyEvent, children: jsxRuntime.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
61932
+ return (jsxRuntime.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, jsxRuntime.jsx("div", { style: { flex: 1 }, ref: gridDivRef, onCopy: onCopyEvent, children: jsxRuntime.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: () => {
61933
+ clearHighlightRowClasses();
61934
+ clearDragRowClasses();
61935
+ multiDragAppliedRef.current = false;
61936
+ multiDragCountRef.current = 0;
61937
+ }, 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 ??
61938
+ (rowSelection === 'multiple'
61939
+ ? () => {
61940
+ const count = multiDragCountRef.current;
61941
+ if (count > 1)
61942
+ return `Moving ${count} rows`;
61943
+ return '';
61944
+ }
61945
+ : undefined), rowHeight: rowHeight, rowSelection: selectable
61887
61946
  ? {
61888
61947
  enableSelectionWithoutKeys: params.enableSelectionWithoutKeys ?? false,
61889
61948
  enableClickSelection: params.enableClickSelection ?? false,
@@ -62115,6 +62174,34 @@ const GridCellMultiEditor = (props, cellEditorSelector) => GridCell({
62115
62174
  ...props,
62116
62175
  });
62117
62176
 
62177
+ /**
62178
+ * Reorders rows by removing movedRows from the array and inserting them at the target position.
62179
+ * @param rows - The current row array.
62180
+ * @param movedRows - Rows to move, in desired insertion order (typically display order).
62181
+ * @param targetRow - The row to insert relative to.
62182
+ * @param direction - -1 inserts above targetRow, 1 inserts below targetRow.
62183
+ * @returns A new array with the rows reordered, or the original array if the operation is a no-op.
62184
+ */
62185
+ function reorderRows(rows, movedRows, targetRow, direction) {
62186
+ if (movedRows.length === 0)
62187
+ return rows;
62188
+ const movedIds = new Set(movedRows.map((r) => r.id));
62189
+ // If targetRow is one of the moved rows, no-op
62190
+ if (movedIds.has(targetRow.id))
62191
+ return rows;
62192
+ // Remove moved rows from the array
62193
+ const remaining = rows.filter((r) => !movedIds.has(r.id));
62194
+ // Find where to insert relative to the target
62195
+ const targetIndex = remaining.findIndex((r) => r.id === targetRow.id);
62196
+ if (targetIndex === -1)
62197
+ return rows;
62198
+ const insertIndex = direction === 1 ? targetIndex + 1 : targetIndex;
62199
+ // Insert movedRows at the calculated position
62200
+ const result = [...remaining];
62201
+ result.splice(insertIndex, 0, ...movedRows);
62202
+ return result;
62203
+ }
62204
+
62118
62205
  const useGridFilter = (filter) => {
62119
62206
  const { addExternalFilter, removeExternalFilter } = useGridContext();
62120
62207
  React13.useEffect(() => {
@@ -64956,6 +65043,7 @@ exports.isFloat = isFloat;
64956
65043
  exports.isGridCellFiller = isGridCellFiller;
64957
65044
  exports.isNotEmpty = isNotEmpty;
64958
65045
  exports.primitiveToSelectOption = primitiveToSelectOption;
65046
+ exports.reorderRows = reorderRows;
64959
65047
  exports.sanitiseFileName = sanitiseFileName;
64960
65048
  exports.stringByteLengthIsInvalid = stringByteLengthIsInvalid;
64961
65049
  exports.suppressCellKeyboardEvents = suppressCellKeyboardEvents;