@bit.rhplus/ag-grid 0.0.48 → 0.0.50
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/BulkEdit/BulkEditButton.jsx +23 -5
- package/BulkEdit/useBulkCellEdit.js +230 -54
- package/BulkEdit/utils.js +44 -18
- package/dist/BulkEdit/BulkEditButton.d.ts +3 -2
- package/dist/BulkEdit/BulkEditButton.js +21 -4
- package/dist/BulkEdit/BulkEditButton.js.map +1 -1
- package/dist/BulkEdit/useBulkCellEdit.js +195 -46
- package/dist/BulkEdit/useBulkCellEdit.js.map +1 -1
- package/dist/BulkEdit/utils.d.ts +1 -1
- package/dist/BulkEdit/utils.js +36 -14
- package/dist/BulkEdit/utils.js.map +1 -1
- package/dist/index.js +113 -58
- package/dist/index.js.map +1 -1
- package/index.jsx +147 -63
- package/package.json +6 -5
- /package/dist/{preview-1761053796620.js → preview-1761316095439.js} +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
2
|
import React, { useState, useRef, useEffect } from 'react';
|
|
3
|
+
import ReactDOM from 'react-dom';
|
|
3
4
|
import { Button, Tooltip } from 'antd';
|
|
4
5
|
import { EditOutlined } from '@ant-design/icons';
|
|
5
6
|
import BulkEditPopover from './BulkEditPopover';
|
|
@@ -24,6 +25,7 @@ const BulkEditButton = ({
|
|
|
24
25
|
range,
|
|
25
26
|
column,
|
|
26
27
|
cellCount,
|
|
28
|
+
rowsContainer, // ✅ Container specifický pro tento grid
|
|
27
29
|
editPopover,
|
|
28
30
|
onOpenPopover,
|
|
29
31
|
onValueChange,
|
|
@@ -120,21 +122,33 @@ const BulkEditButton = ({
|
|
|
120
122
|
cellCount === 1 ? 'buňku' : cellCount < 5 ? 'buňky' : 'buněk'
|
|
121
123
|
} v "${fieldName}"`;
|
|
122
124
|
|
|
123
|
-
|
|
125
|
+
/**
|
|
126
|
+
* ✅ OPTIMALIZACE: Použít container specifický pro tento grid (předaný jako prop)
|
|
127
|
+
* Toto zajistí, že button se renderuje do správného gridu i když je v DOM více gridů
|
|
128
|
+
* → Funguje správně při přepínání mezi moduly (každý modul má svůj vlastní container)
|
|
129
|
+
*/
|
|
130
|
+
const portalContainer = React.useMemo(() => {
|
|
131
|
+
if (!visible || !rowsContainer) return document.body;
|
|
132
|
+
return rowsContainer;
|
|
133
|
+
}, [visible, rowsContainer]);
|
|
134
|
+
|
|
135
|
+
// Renderujeme pomocí React Portal do ag-center-cols-container
|
|
136
|
+
// Button se automaticky scrolluje s gridem (součástí transformed containeru)
|
|
137
|
+
const content = (
|
|
124
138
|
<>
|
|
125
139
|
{/* Floating Button */}
|
|
126
140
|
<div
|
|
127
141
|
ref={buttonRef}
|
|
128
142
|
style={{
|
|
129
|
-
position: '
|
|
143
|
+
position: 'absolute',
|
|
130
144
|
top: position?.y || 0,
|
|
131
145
|
left: position?.x || 0,
|
|
132
146
|
zIndex: 9999,
|
|
133
147
|
pointerEvents: 'auto',
|
|
134
148
|
}}
|
|
135
149
|
>
|
|
136
|
-
<Tooltip
|
|
137
|
-
title={tooltipTitle}
|
|
150
|
+
<Tooltip
|
|
151
|
+
title={tooltipTitle}
|
|
138
152
|
placement="top"
|
|
139
153
|
getPopupContainer={() => document.body}
|
|
140
154
|
zIndex={10001}
|
|
@@ -157,7 +171,7 @@ const BulkEditButton = ({
|
|
|
157
171
|
<div
|
|
158
172
|
ref={popoverRef}
|
|
159
173
|
style={{
|
|
160
|
-
position: '
|
|
174
|
+
position: 'absolute',
|
|
161
175
|
top: popoverPosition?.top ?? (position?.y || 0) + 35,
|
|
162
176
|
left: popoverPosition?.left ?? (position?.x || 0),
|
|
163
177
|
zIndex: 10000,
|
|
@@ -182,6 +196,10 @@ const BulkEditButton = ({
|
|
|
182
196
|
)}
|
|
183
197
|
</>
|
|
184
198
|
);
|
|
199
|
+
|
|
200
|
+
// ✅ OPTIMALIZACE: React Portal do ag-center-cols-container
|
|
201
|
+
// portalContainer se aktualizuje při každém zobrazení → funguje i po route change
|
|
202
|
+
return ReactDOM.createPortal(content, portalContainer);
|
|
185
203
|
};
|
|
186
204
|
|
|
187
205
|
export default BulkEditButton;
|
|
@@ -34,6 +34,7 @@ export const useBulkCellEdit = (gridRef, options = {}) => {
|
|
|
34
34
|
range: null,
|
|
35
35
|
column: null,
|
|
36
36
|
cellCount: 0,
|
|
37
|
+
rowsContainer: null, // ✅ Container specifický pro tento grid
|
|
37
38
|
});
|
|
38
39
|
|
|
39
40
|
const [editPopover, setEditPopover] = useState({
|
|
@@ -47,20 +48,16 @@ export const useBulkCellEdit = (gridRef, options = {}) => {
|
|
|
47
48
|
const debounceTimeoutRef = useRef(null);
|
|
48
49
|
const pendingEventRef = useRef(null);
|
|
49
50
|
|
|
51
|
+
// ✅ OPTIMALIZACE: Cache pro pozice buněk - eliminuje opakované getBoundingClientRect
|
|
52
|
+
const positionCacheRef = useRef({ endRowIndex: null, colId: null, position: null });
|
|
53
|
+
|
|
50
54
|
/**
|
|
51
|
-
* Helper funkce pro výpočet pozice buttonu
|
|
55
|
+
* Helper funkce pro výpočet pozice buttonu (relativní k rows container)
|
|
56
|
+
* ✅ OPTIMALIZACE: Žádné viewport adjustments - button je position: absolute v containeru
|
|
52
57
|
*/
|
|
53
58
|
const calculateButtonPosition = useCallback((cellPosition) => {
|
|
54
|
-
|
|
55
|
-
const POPOVER_WIDTH = 30;
|
|
56
|
-
const POPOVER_HEIGHT = 30;
|
|
57
|
-
const VIEWPORT_MARGIN = 10;
|
|
58
|
-
|
|
59
|
-
const viewportWidth = window.innerWidth;
|
|
60
|
-
const viewportHeight = window.innerHeight;
|
|
61
|
-
|
|
59
|
+
// Jednoduše použij pozici z cellPosition + offset podle buttonPosition
|
|
62
60
|
let buttonX, buttonY;
|
|
63
|
-
let adjustedPosition = buttonPosition;
|
|
64
61
|
|
|
65
62
|
switch (buttonPosition) {
|
|
66
63
|
case 'bottom-right':
|
|
@@ -68,39 +65,22 @@ export const useBulkCellEdit = (gridRef, options = {}) => {
|
|
|
68
65
|
buttonY = cellPosition.bottom + buttonOffset.y;
|
|
69
66
|
break;
|
|
70
67
|
case 'bottom-left':
|
|
71
|
-
buttonX = cellPosition.left - buttonOffset.x;
|
|
68
|
+
buttonX = cellPosition.left - buttonOffset.x - 32; // 32 = button size
|
|
72
69
|
buttonY = cellPosition.bottom + buttonOffset.y;
|
|
73
70
|
break;
|
|
74
71
|
case 'top-right':
|
|
75
72
|
buttonX = cellPosition.right + buttonOffset.x;
|
|
76
|
-
buttonY = cellPosition.top - buttonOffset.y;
|
|
73
|
+
buttonY = cellPosition.top - buttonOffset.y - 32;
|
|
77
74
|
break;
|
|
78
75
|
case 'top-left':
|
|
79
|
-
buttonX = cellPosition.left - buttonOffset.x;
|
|
80
|
-
buttonY = cellPosition.top - buttonOffset.y;
|
|
76
|
+
buttonX = cellPosition.left - buttonOffset.x - 32;
|
|
77
|
+
buttonY = cellPosition.top - buttonOffset.y - 32;
|
|
81
78
|
break;
|
|
82
79
|
default:
|
|
83
80
|
buttonX = cellPosition.right + buttonOffset.x;
|
|
84
81
|
buttonY = cellPosition.bottom + buttonOffset.y;
|
|
85
82
|
}
|
|
86
83
|
|
|
87
|
-
const buttonRight = buttonX + BUTTON_SIZE;
|
|
88
|
-
const popoverRight = buttonX + POPOVER_WIDTH;
|
|
89
|
-
const popoverBottom = buttonY + BUTTON_SIZE + POPOVER_HEIGHT;
|
|
90
|
-
|
|
91
|
-
if (popoverRight > viewportWidth - VIEWPORT_MARGIN) {
|
|
92
|
-
buttonX = cellPosition.left - buttonOffset.x - BUTTON_SIZE;
|
|
93
|
-
buttonX = Math.max(VIEWPORT_MARGIN, buttonX);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (popoverBottom > viewportHeight - VIEWPORT_MARGIN) {
|
|
97
|
-
buttonY = cellPosition.top - buttonOffset.y - BUTTON_SIZE;
|
|
98
|
-
buttonY = Math.max(VIEWPORT_MARGIN, buttonY);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
buttonX = Math.max(VIEWPORT_MARGIN, Math.min(buttonX, viewportWidth - BUTTON_SIZE - VIEWPORT_MARGIN));
|
|
102
|
-
buttonY = Math.max(VIEWPORT_MARGIN, Math.min(buttonY, viewportHeight - BUTTON_SIZE - VIEWPORT_MARGIN));
|
|
103
|
-
|
|
104
84
|
return { x: buttonX, y: buttonY };
|
|
105
85
|
}, [buttonPosition, buttonOffset]);
|
|
106
86
|
|
|
@@ -126,25 +106,110 @@ export const useBulkCellEdit = (gridRef, options = {}) => {
|
|
|
126
106
|
// ✨ OKAŽITÁ lightweight validace - zobraz button HNED
|
|
127
107
|
if (allowMultiColumn || range.columns.length === 1) {
|
|
128
108
|
const cellCount = Math.abs(range.endRow.rowIndex - range.startRow.rowIndex) + 1;
|
|
129
|
-
|
|
109
|
+
|
|
130
110
|
if (cellCount >= minCells) {
|
|
131
111
|
// Kontrola zda má sloupec bulkEditApi (rychlá kontrola)
|
|
132
112
|
const column = range.columns[0];
|
|
133
113
|
const colDef = column?.getColDef();
|
|
134
114
|
const hasBulkEditApi = colDef?.bulkEditApi || colDef?.bulkEditPopover;
|
|
135
|
-
|
|
115
|
+
|
|
136
116
|
// Zobraz button jen pokud má bulkEditApi nebo bulkEditPopover
|
|
137
117
|
if (hasBulkEditApi) {
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
118
|
+
const endRowIndex = Math.max(range.startRow.rowIndex, range.endRow.rowIndex);
|
|
119
|
+
const colId = column.getColId();
|
|
120
|
+
|
|
121
|
+
// ✅ KLÍČOVÉ ŘEŠENÍ: Najít container relativně od OZNAČENÉ BUŇKY
|
|
122
|
+
// Když jsou v DOM více gridů (shared/master), querySelector najde první
|
|
123
|
+
// Ale my potřebujeme container od AKTUÁLNĚ AKTIVNÍHO gridu
|
|
124
|
+
|
|
125
|
+
// ✅ KLÍČOVÉ ŘEŠENÍ: Najít POSLEDNÍ buňku v range (endRow) pro správné umístění
|
|
126
|
+
// API ví přesně, která buňka patří do kterého gridu (řeší multi-grid problém!)
|
|
127
|
+
// DŮLEŽITÉ: Používáme endRow (ne startRow), aby pozice byla stejná jako v heavy validaci
|
|
128
|
+
const endRowForCalc = Math.max(range.startRow.rowIndex, range.endRow.rowIndex) === range.startRow.rowIndex ? range.startRow : range.endRow;
|
|
129
|
+
let targetCell = null;
|
|
130
|
+
|
|
131
|
+
// Metoda 1: Použít getCellRendererInstances (nejspolehlivější)
|
|
132
|
+
try {
|
|
133
|
+
const cellRenderers = event.api.getCellRendererInstances({
|
|
134
|
+
rowNodes: [endRowForCalc],
|
|
135
|
+
columns: [column]
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
if (cellRenderers && cellRenderers.length > 0) {
|
|
139
|
+
targetCell = cellRenderers[0].eGui || cellRenderers[0].getGui?.();
|
|
140
|
+
}
|
|
141
|
+
} catch (e) {
|
|
142
|
+
// Tiché selhání, fallback
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Metoda 2: Fallback - najít aktivní grid container a pak hledat row
|
|
146
|
+
if (!targetCell) {
|
|
147
|
+
// Nejprve najdeme jakoukoliv viditelnou buňku z TOHOTO gridu
|
|
148
|
+
const allCellsWithColId = Array.from(document.querySelectorAll(`[col-id="${colId}"].ag-cell`));
|
|
149
|
+
const visibleCell = allCellsWithColId.find(cell => {
|
|
150
|
+
const rect = cell.getBoundingClientRect();
|
|
151
|
+
return rect.width > 0 && rect.height > 0;
|
|
146
152
|
});
|
|
153
|
+
|
|
154
|
+
if (visibleCell) {
|
|
155
|
+
// Od viditelné buňky najdeme její grid container
|
|
156
|
+
const activeGridContainer = visibleCell.closest('.ag-center-cols-container');
|
|
157
|
+
|
|
158
|
+
if (activeGridContainer) {
|
|
159
|
+
// V aktivním containeru hledáme row podle row-index
|
|
160
|
+
const rowId = endRowForCalc.id || endRowForCalc.data?.id;
|
|
161
|
+
const endRowIndex = Math.max(range.startRow.rowIndex, range.endRow.rowIndex);
|
|
162
|
+
const rowsInActiveGrid = Array.from(activeGridContainer.querySelectorAll('.ag-row'));
|
|
163
|
+
|
|
164
|
+
let targetRow = rowsInActiveGrid.find(row => row.getAttribute('row-id') === rowId);
|
|
165
|
+
|
|
166
|
+
if (!targetRow) {
|
|
167
|
+
targetRow = rowsInActiveGrid.find(row => row.getAttribute('row-index') === String(endRowIndex));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (targetRow) {
|
|
171
|
+
targetCell = targetRow.querySelector(`[col-id="${colId}"]`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (!targetCell) {
|
|
178
|
+
setFloatingButton({ visible: false });
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Od buňky najdeme její .ag-center-cols-container (specifický pro tento grid)
|
|
183
|
+
const rowsContainer = targetCell.closest('.ag-center-cols-container');
|
|
184
|
+
if (!rowsContainer) {
|
|
185
|
+
setFloatingButton({ visible: false });
|
|
186
|
+
return;
|
|
147
187
|
}
|
|
188
|
+
|
|
189
|
+
// ✅ OPTIMALIZACE: Vypočítat pozici z POSLEDNÍ buňky (stejně jako heavy validace)
|
|
190
|
+
// Tím eliminujeme přeblikávání mezi firstCell a lastCell
|
|
191
|
+
const cellRect = targetCell.getBoundingClientRect();
|
|
192
|
+
const containerRect = rowsContainer.getBoundingClientRect();
|
|
193
|
+
|
|
194
|
+
const cellPosition = {
|
|
195
|
+
x: cellRect.right - containerRect.left,
|
|
196
|
+
y: cellRect.bottom - containerRect.top,
|
|
197
|
+
width: cellRect.width,
|
|
198
|
+
height: cellRect.height,
|
|
199
|
+
top: cellRect.top - containerRect.top,
|
|
200
|
+
left: cellRect.left - containerRect.left,
|
|
201
|
+
right: cellRect.right - containerRect.left,
|
|
202
|
+
bottom: cellRect.bottom - containerRect.top
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
setFloatingButton({
|
|
206
|
+
visible: true,
|
|
207
|
+
position: calculateButtonPosition(cellPosition),
|
|
208
|
+
range,
|
|
209
|
+
column: column,
|
|
210
|
+
cellCount,
|
|
211
|
+
rowsContainer, // ✅ Předat container specifický pro tento grid
|
|
212
|
+
});
|
|
148
213
|
} else {
|
|
149
214
|
// Skryj button pokud sloupec nemá bulk edit podporu
|
|
150
215
|
setFloatingButton({ visible: false });
|
|
@@ -164,7 +229,7 @@ export const useBulkCellEdit = (gridRef, options = {}) => {
|
|
|
164
229
|
if (pendingEventRef.current) {
|
|
165
230
|
executeRangeValidation(pendingEventRef.current);
|
|
166
231
|
}
|
|
167
|
-
},
|
|
232
|
+
}, 15);
|
|
168
233
|
},
|
|
169
234
|
[enabled, allowMultiColumn, minCells, calculateButtonPosition]
|
|
170
235
|
);
|
|
@@ -204,22 +269,133 @@ export const useBulkCellEdit = (gridRef, options = {}) => {
|
|
|
204
269
|
return;
|
|
205
270
|
}
|
|
206
271
|
|
|
207
|
-
//
|
|
208
|
-
const
|
|
209
|
-
|
|
272
|
+
// ✅ KLÍČOVÉ ŘEŠENÍ: Použít AG-Grid API k získání cell elementu (STEJNĚ jako v lightweight validaci)
|
|
273
|
+
const column = range.columns[0];
|
|
274
|
+
const colId = column.getColId();
|
|
275
|
+
let firstCell = null;
|
|
276
|
+
|
|
277
|
+
// Metoda 1: Použít getCellRendererInstances (nejspolehlivější)
|
|
278
|
+
try {
|
|
279
|
+
const cellRenderers = event.api.getCellRendererInstances({
|
|
280
|
+
rowNodes: [range.startRow],
|
|
281
|
+
columns: [column]
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
if (cellRenderers && cellRenderers.length > 0) {
|
|
285
|
+
firstCell = cellRenderers[0].eGui || cellRenderers[0].getGui?.();
|
|
286
|
+
}
|
|
287
|
+
} catch (e) {
|
|
288
|
+
// Tiché selhání, fallback
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Metoda 2: Fallback - najít aktivní grid container a pak hledat row (STEJNĚ jako v lightweight)
|
|
292
|
+
if (!firstCell) {
|
|
293
|
+
// Nejprve najdeme jakoukoliv viditelnou buňku z TOHOTO gridu
|
|
294
|
+
const allCellsWithColId = Array.from(document.querySelectorAll(`[col-id="${colId}"].ag-cell`));
|
|
295
|
+
const visibleCell = allCellsWithColId.find(cell => {
|
|
296
|
+
const rect = cell.getBoundingClientRect();
|
|
297
|
+
return rect.width > 0 && rect.height > 0;
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
if (visibleCell) {
|
|
301
|
+
// Od viditelné buňky najdeme její grid container
|
|
302
|
+
const activeGridContainer = visibleCell.closest('.ag-center-cols-container');
|
|
303
|
+
|
|
304
|
+
if (activeGridContainer) {
|
|
305
|
+
// V aktivním containeru hledáme row podle row-index
|
|
306
|
+
const rowId = range.startRow.id || range.startRow.data?.id;
|
|
307
|
+
const rowsInActiveGrid = Array.from(activeGridContainer.querySelectorAll('.ag-row'));
|
|
308
|
+
|
|
309
|
+
let targetRow = rowsInActiveGrid.find(row => row.getAttribute('row-id') === rowId);
|
|
310
|
+
|
|
311
|
+
if (!targetRow) {
|
|
312
|
+
targetRow = rowsInActiveGrid.find(row => row.getAttribute('row-index') === String(range.startRow.rowIndex));
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (targetRow) {
|
|
316
|
+
firstCell = targetRow.querySelector(`[col-id="${colId}"]`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (!firstCell) {
|
|
323
|
+
setFloatingButton({ visible: false });
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Od buňky najdeme její .ag-center-cols-container (specifický pro tento grid)
|
|
328
|
+
const rowsContainer = firstCell.closest('.ag-center-cols-container');
|
|
329
|
+
if (!rowsContainer) {
|
|
210
330
|
setFloatingButton({ visible: false });
|
|
211
331
|
return;
|
|
212
332
|
}
|
|
213
333
|
|
|
334
|
+
// Těžký výpočet - najít POSLEDNÍ buňku v range (pro přesné umístění buttonu)
|
|
335
|
+
// Najdeme buňku na endRow pozici
|
|
336
|
+
const endRowIndex = Math.max(range.startRow.rowIndex, range.endRow.rowIndex);
|
|
337
|
+
let lastCell = null;
|
|
338
|
+
|
|
339
|
+
// Metoda 1: getCellRendererInstances pro endRow
|
|
340
|
+
try {
|
|
341
|
+
const cellRenderers = event.api.getCellRendererInstances({
|
|
342
|
+
rowNodes: [range.endRow],
|
|
343
|
+
columns: [column]
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
if (cellRenderers && cellRenderers.length > 0) {
|
|
347
|
+
lastCell = cellRenderers[0].eGui || cellRenderers[0].getGui?.();
|
|
348
|
+
}
|
|
349
|
+
} catch (e) {
|
|
350
|
+
// Fallback
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Metoda 2: Fallback - hledat row v AKTIVNÍM containeru (použít rowsContainer který už máme!)
|
|
354
|
+
if (!lastCell) {
|
|
355
|
+
const rowId = range.endRow.id || range.endRow.data?.id;
|
|
356
|
+
const rowsInActiveGrid = Array.from(rowsContainer.querySelectorAll('.ag-row'));
|
|
357
|
+
|
|
358
|
+
let targetRow = rowsInActiveGrid.find(row => row.getAttribute('row-id') === rowId);
|
|
359
|
+
|
|
360
|
+
if (!targetRow) {
|
|
361
|
+
targetRow = rowsInActiveGrid.find(row => row.getAttribute('row-index') === String(endRowIndex));
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
if (targetRow) {
|
|
365
|
+
lastCell = targetRow.querySelector(`[col-id="${colId}"]`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Metoda 3: Fallback na firstCell pokud endRow buňku nenajdeme
|
|
370
|
+
if (!lastCell) {
|
|
371
|
+
lastCell = firstCell;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Spočítej pozici z lastCell
|
|
375
|
+
const cellRect = lastCell.getBoundingClientRect();
|
|
376
|
+
const containerRect = rowsContainer.getBoundingClientRect();
|
|
377
|
+
|
|
378
|
+
const cellPosition = {
|
|
379
|
+
x: cellRect.right - containerRect.left,
|
|
380
|
+
y: cellRect.bottom - containerRect.top,
|
|
381
|
+
width: cellRect.width,
|
|
382
|
+
height: cellRect.height,
|
|
383
|
+
top: cellRect.top - containerRect.top,
|
|
384
|
+
left: cellRect.left - containerRect.left,
|
|
385
|
+
right: cellRect.right - containerRect.left,
|
|
386
|
+
bottom: cellRect.bottom - containerRect.top
|
|
387
|
+
};
|
|
388
|
+
|
|
214
389
|
setFloatingButton({
|
|
215
390
|
visible: true,
|
|
216
391
|
position: calculateButtonPosition(cellPosition),
|
|
217
392
|
range,
|
|
218
393
|
column: range.columns[0],
|
|
219
394
|
cellCount,
|
|
395
|
+
rowsContainer, // ✅ Předat container specifický pro tento grid
|
|
220
396
|
});
|
|
221
397
|
},
|
|
222
|
-
[minCells, allowMultiColumn, buttonPosition, buttonOffset]
|
|
398
|
+
[minCells, allowMultiColumn, buttonPosition, buttonOffset, calculateButtonPosition, gridRef]
|
|
223
399
|
);
|
|
224
400
|
|
|
225
401
|
/**
|
|
@@ -352,21 +528,21 @@ export const useBulkCellEdit = (gridRef, options = {}) => {
|
|
|
352
528
|
useEffect(() => {
|
|
353
529
|
if (!enabled || !gridRef.current) return;
|
|
354
530
|
|
|
355
|
-
const
|
|
356
|
-
if (!
|
|
531
|
+
const gridViewport = gridRef.current.api?.gridBodyCtrl?.eBodyViewport;
|
|
532
|
+
if (!gridViewport) return;
|
|
357
533
|
|
|
358
534
|
const handleScroll = () => {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
535
|
+
// ✅ OPTIMALIZACE: Button se nyní scrolluje automaticky s gridem (position: absolute v viewport)
|
|
536
|
+
// Není potřeba skrývat button ani invalidovat cache - button zůstává přilepený k buňce
|
|
537
|
+
// Cache zůstává validní, protože relativní pozice se nemění při scrollu
|
|
362
538
|
};
|
|
363
539
|
|
|
364
540
|
scrollListenerRef.current = handleScroll;
|
|
365
|
-
|
|
541
|
+
gridViewport.addEventListener('scroll', handleScroll);
|
|
366
542
|
|
|
367
543
|
return () => {
|
|
368
|
-
if (
|
|
369
|
-
|
|
544
|
+
if (gridViewport && scrollListenerRef.current) {
|
|
545
|
+
gridViewport.removeEventListener('scroll', scrollListenerRef.current);
|
|
370
546
|
}
|
|
371
547
|
};
|
|
372
548
|
}, [enabled, gridRef, floatingButton.visible]);
|
package/BulkEdit/utils.js
CHANGED
|
@@ -91,34 +91,60 @@ export const validateRangeEditable = (range, gridApi) => {
|
|
|
91
91
|
* Získá pozici poslední buňky v range pro umístění floating buttonu
|
|
92
92
|
* @param {Object} range - AG Grid cell range
|
|
93
93
|
* @param {Object} gridApi - AG Grid API
|
|
94
|
-
* @
|
|
94
|
+
* @param {HTMLElement} rowsContainer - AG Grid rows container (.ag-center-cols-container)
|
|
95
|
+
* @returns {Object} - {x, y, width, height} pozice RELATIVNÍ k rows container
|
|
95
96
|
*/
|
|
96
|
-
export const getLastCellPosition = (range, gridApi) => {
|
|
97
|
+
export const getLastCellPosition = (range, gridApi, rowsContainer) => {
|
|
97
98
|
try {
|
|
98
99
|
const endRowIndex = Math.max(range.startRow.rowIndex, range.endRow.rowIndex);
|
|
99
100
|
const column = range.columns[0];
|
|
100
101
|
const colId = column.getColId();
|
|
101
|
-
|
|
102
|
-
//
|
|
102
|
+
|
|
103
|
+
// ✅ OPTIMALIZACE: querySelector je sice pomalejší, ale díky cache v useBulkCellEdit
|
|
104
|
+
// se volá pouze při změně pozice (cache hit = 0ms overhead)
|
|
103
105
|
const rowElement = document.querySelector(`[row-index="${endRowIndex}"]`);
|
|
104
|
-
if (!rowElement)
|
|
105
|
-
|
|
106
|
+
if (!rowElement) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
|
|
106
110
|
const cellElement = rowElement.querySelector(`[col-id="${colId}"]`);
|
|
107
|
-
if (!cellElement)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
+
if (!cellElement) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const cellRect = cellElement.getBoundingClientRect();
|
|
116
|
+
|
|
117
|
+
// ✅ OPTIMALIZACE: Výpočet pozice RELATIVNÍ k rows container
|
|
118
|
+
// Button je position: absolute uvnitř .ag-center-cols-container
|
|
119
|
+
// Tento container má transform: translateY() při scrollu → button scrolluje automaticky
|
|
120
|
+
if (rowsContainer) {
|
|
121
|
+
const containerRect = rowsContainer.getBoundingClientRect();
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
x: cellRect.right - containerRect.left,
|
|
125
|
+
y: cellRect.bottom - containerRect.top,
|
|
126
|
+
width: cellRect.width,
|
|
127
|
+
height: cellRect.height,
|
|
128
|
+
top: cellRect.top - containerRect.top,
|
|
129
|
+
left: cellRect.left - containerRect.left,
|
|
130
|
+
right: cellRect.right - containerRect.left,
|
|
131
|
+
bottom: cellRect.bottom - containerRect.top
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Fallback: absolute pozice (window-relative) pokud container není dostupný
|
|
111
136
|
return {
|
|
112
|
-
x:
|
|
113
|
-
y:
|
|
114
|
-
width:
|
|
115
|
-
height:
|
|
116
|
-
top:
|
|
117
|
-
left:
|
|
118
|
-
right:
|
|
119
|
-
bottom:
|
|
137
|
+
x: cellRect.right,
|
|
138
|
+
y: cellRect.bottom,
|
|
139
|
+
width: cellRect.width,
|
|
140
|
+
height: cellRect.height,
|
|
141
|
+
top: cellRect.top,
|
|
142
|
+
left: cellRect.left,
|
|
143
|
+
right: cellRect.right,
|
|
144
|
+
bottom: cellRect.bottom
|
|
120
145
|
};
|
|
121
146
|
} catch (error) {
|
|
147
|
+
// Tiché selhání - vrátit null
|
|
122
148
|
return null;
|
|
123
149
|
}
|
|
124
150
|
};
|
|
@@ -13,7 +13,7 @@ export default BulkEditButton;
|
|
|
13
13
|
* @param {Function} props.onSubmit - Handler pro submit
|
|
14
14
|
* @param {Function} props.onCancel - Handler pro cancel
|
|
15
15
|
*/
|
|
16
|
-
declare function BulkEditButton({ visible, position, range, column, cellCount, editPopover, onOpenPopover, onValueChange, onSubmit, onCancel, }: {
|
|
16
|
+
declare function BulkEditButton({ visible, position, range, column, cellCount, rowsContainer, editPopover, onOpenPopover, onValueChange, onSubmit, onCancel, }: {
|
|
17
17
|
visible: boolean;
|
|
18
18
|
position: Object;
|
|
19
19
|
range: Object;
|
|
@@ -24,4 +24,5 @@ declare function BulkEditButton({ visible, position, range, column, cellCount, e
|
|
|
24
24
|
onValueChange: Function;
|
|
25
25
|
onSubmit: Function;
|
|
26
26
|
onCancel: Function;
|
|
27
|
-
}):
|
|
27
|
+
}): React.ReactPortal | null;
|
|
28
|
+
import React from 'react';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/* eslint-disable */
|
|
3
3
|
import React, { useState, useRef, useEffect } from 'react';
|
|
4
|
+
import ReactDOM from 'react-dom';
|
|
4
5
|
import { Button, Tooltip } from 'antd';
|
|
5
6
|
import { EditOutlined } from '@ant-design/icons';
|
|
6
7
|
import BulkEditPopover from './BulkEditPopover';
|
|
@@ -18,7 +19,8 @@ import BulkEditPopover from './BulkEditPopover';
|
|
|
18
19
|
* @param {Function} props.onSubmit - Handler pro submit
|
|
19
20
|
* @param {Function} props.onCancel - Handler pro cancel
|
|
20
21
|
*/
|
|
21
|
-
const BulkEditButton = ({ visible, position, range, column, cellCount,
|
|
22
|
+
const BulkEditButton = ({ visible, position, range, column, cellCount, rowsContainer, // ✅ Container specifický pro tento grid
|
|
23
|
+
editPopover, onOpenPopover, onValueChange, onSubmit, onCancel, }) => {
|
|
22
24
|
const [popoverVisible, setPopoverVisible] = useState(false);
|
|
23
25
|
const [popoverPosition, setPopoverPosition] = useState(null);
|
|
24
26
|
const buttonRef = useRef(null);
|
|
@@ -92,8 +94,20 @@ const BulkEditButton = ({ visible, position, range, column, cellCount, editPopov
|
|
|
92
94
|
}
|
|
93
95
|
}, [popoverVisible]);
|
|
94
96
|
const tooltipTitle = `Hromadně změnit ${cellCount} ${cellCount === 1 ? 'buňku' : cellCount < 5 ? 'buňky' : 'buněk'} v "${fieldName}"`;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
+
/**
|
|
98
|
+
* ✅ OPTIMALIZACE: Použít container specifický pro tento grid (předaný jako prop)
|
|
99
|
+
* Toto zajistí, že button se renderuje do správného gridu i když je v DOM více gridů
|
|
100
|
+
* → Funguje správně při přepínání mezi moduly (každý modul má svůj vlastní container)
|
|
101
|
+
*/
|
|
102
|
+
const portalContainer = React.useMemo(() => {
|
|
103
|
+
if (!visible || !rowsContainer)
|
|
104
|
+
return document.body;
|
|
105
|
+
return rowsContainer;
|
|
106
|
+
}, [visible, rowsContainer]);
|
|
107
|
+
// Renderujeme pomocí React Portal do ag-center-cols-container
|
|
108
|
+
// Button se automaticky scrolluje s gridem (součástí transformed containeru)
|
|
109
|
+
const content = (_jsxs(_Fragment, { children: [_jsx("div", { ref: buttonRef, style: {
|
|
110
|
+
position: 'absolute',
|
|
97
111
|
top: position?.y || 0,
|
|
98
112
|
left: position?.x || 0,
|
|
99
113
|
zIndex: 9999,
|
|
@@ -101,7 +115,7 @@ const BulkEditButton = ({ visible, position, range, column, cellCount, editPopov
|
|
|
101
115
|
}, children: _jsx(Tooltip, { title: tooltipTitle, placement: "top", getPopupContainer: () => document.body, zIndex: 10001, children: _jsx(Button, { type: "primary", shape: "circle", icon: _jsx(EditOutlined, {}), size: "small", onClick: handleButtonClick, style: {
|
|
102
116
|
boxShadow: '0 2px 8px rgba(0,0,0,0.15)',
|
|
103
117
|
} }) }) }), popoverVisible && (_jsx("div", { ref: popoverRef, style: {
|
|
104
|
-
position: '
|
|
118
|
+
position: 'absolute',
|
|
105
119
|
top: popoverPosition?.top ?? (position?.y || 0) + 35,
|
|
106
120
|
left: popoverPosition?.left ?? (position?.x || 0),
|
|
107
121
|
zIndex: 10000,
|
|
@@ -109,6 +123,9 @@ const BulkEditButton = ({ visible, position, range, column, cellCount, editPopov
|
|
|
109
123
|
opacity: popoverPosition ? 1 : 0,
|
|
110
124
|
transition: 'opacity 0.1s ease-in-out',
|
|
111
125
|
}, children: _jsx(BulkEditPopover, { visible: editPopover.visible, value: editPopover.value, loading: editPopover.loading, error: editPopover.error, column: column, range: range, cellCount: cellCount, onValueChange: onValueChange, onSubmit: onSubmit, onCancel: onCancel }) }))] }));
|
|
126
|
+
// ✅ OPTIMALIZACE: React Portal do ag-center-cols-container
|
|
127
|
+
// portalContainer se aktualizuje při každém zobrazení → funguje i po route change
|
|
128
|
+
return ReactDOM.createPortal(content, portalContainer);
|
|
112
129
|
};
|
|
113
130
|
export default BulkEditButton;
|
|
114
131
|
//# sourceMappingURL=BulkEditButton.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BulkEditButton.js","sourceRoot":"","sources":["../../BulkEdit/BulkEditButton.jsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"BulkEditButton.js","sourceRoot":"","sources":["../../BulkEdit/BulkEditButton.jsx"],"names":[],"mappings":"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"}
|