@bit.rhplus/ag-grid 0.0.49 → 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 +18 -7
- package/BulkEdit/useBulkCellEdit.js +230 -54
- package/BulkEdit/utils.js +33 -31
- package/dist/BulkEdit/BulkEditButton.d.ts +1 -1
- package/dist/BulkEdit/BulkEditButton.js +19 -8
- 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 +32 -31
- package/dist/BulkEdit/utils.js.map +1 -1
- package/dist/index.js +6 -14
- package/dist/index.js.map +1 -1
- package/index.jsx +6 -15
- package/package.json +4 -4
- /package/dist/{preview-1761214842578.js → preview-1761316095439.js} +0 -0
|
@@ -25,6 +25,7 @@ const BulkEditButton = ({
|
|
|
25
25
|
range,
|
|
26
26
|
column,
|
|
27
27
|
cellCount,
|
|
28
|
+
rowsContainer, // ✅ Container specifický pro tento grid
|
|
28
29
|
editPopover,
|
|
29
30
|
onOpenPopover,
|
|
30
31
|
onValueChange,
|
|
@@ -121,15 +122,25 @@ const BulkEditButton = ({
|
|
|
121
122
|
cellCount === 1 ? 'buňku' : cellCount < 5 ? 'buňky' : 'buněk'
|
|
122
123
|
} v "${fieldName}"`;
|
|
123
124
|
|
|
124
|
-
|
|
125
|
-
|
|
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)
|
|
126
137
|
const content = (
|
|
127
138
|
<>
|
|
128
139
|
{/* Floating Button */}
|
|
129
140
|
<div
|
|
130
141
|
ref={buttonRef}
|
|
131
142
|
style={{
|
|
132
|
-
position: '
|
|
143
|
+
position: 'absolute',
|
|
133
144
|
top: position?.y || 0,
|
|
134
145
|
left: position?.x || 0,
|
|
135
146
|
zIndex: 9999,
|
|
@@ -160,7 +171,7 @@ const BulkEditButton = ({
|
|
|
160
171
|
<div
|
|
161
172
|
ref={popoverRef}
|
|
162
173
|
style={{
|
|
163
|
-
position: '
|
|
174
|
+
position: 'absolute',
|
|
164
175
|
top: popoverPosition?.top ?? (position?.y || 0) + 35,
|
|
165
176
|
left: popoverPosition?.left ?? (position?.x || 0),
|
|
166
177
|
zIndex: 10000,
|
|
@@ -186,9 +197,9 @@ const BulkEditButton = ({
|
|
|
186
197
|
</>
|
|
187
198
|
);
|
|
188
199
|
|
|
189
|
-
//
|
|
190
|
-
//
|
|
191
|
-
return ReactDOM.createPortal(content,
|
|
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);
|
|
192
203
|
};
|
|
193
204
|
|
|
194
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]
|
|
146
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
|
|
147
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;
|
|
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;
|
|
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,58 +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
106
|
if (!rowElement) {
|
|
105
|
-
console.warn('🔍 BulkEdit: Row element not found', { endRowIndex });
|
|
106
107
|
return null;
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
const cellElement = rowElement.querySelector(`[col-id="${colId}"]`);
|
|
110
111
|
if (!cellElement) {
|
|
111
|
-
console.warn('🔍 BulkEdit: Cell element not found', { colId });
|
|
112
112
|
return null;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
const
|
|
115
|
+
const cellRect = cellElement.getBoundingClientRect();
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
+
}
|
|
133
134
|
|
|
135
|
+
// Fallback: absolute pozice (window-relative) pokud container není dostupný
|
|
134
136
|
return {
|
|
135
|
-
x:
|
|
136
|
-
y:
|
|
137
|
-
width:
|
|
138
|
-
height:
|
|
139
|
-
top:
|
|
140
|
-
left:
|
|
141
|
-
right:
|
|
142
|
-
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
|
|
143
145
|
};
|
|
144
146
|
} catch (error) {
|
|
145
|
-
|
|
147
|
+
// Tiché selhání - vrátit null
|
|
146
148
|
return null;
|
|
147
149
|
}
|
|
148
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;
|
|
@@ -19,7 +19,8 @@ import BulkEditPopover from './BulkEditPopover';
|
|
|
19
19
|
* @param {Function} props.onSubmit - Handler pro submit
|
|
20
20
|
* @param {Function} props.onCancel - Handler pro cancel
|
|
21
21
|
*/
|
|
22
|
-
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, }) => {
|
|
23
24
|
const [popoverVisible, setPopoverVisible] = useState(false);
|
|
24
25
|
const [popoverPosition, setPopoverPosition] = useState(null);
|
|
25
26
|
const buttonRef = useRef(null);
|
|
@@ -93,10 +94,20 @@ const BulkEditButton = ({ visible, position, range, column, cellCount, editPopov
|
|
|
93
94
|
}
|
|
94
95
|
}, [popoverVisible]);
|
|
95
96
|
const tooltipTitle = `Hromadně změnit ${cellCount} ${cellCount === 1 ? 'buňku' : cellCount < 5 ? 'buňky' : 'buněk'} v "${fieldName}"`;
|
|
96
|
-
|
|
97
|
-
|
|
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)
|
|
98
109
|
const content = (_jsxs(_Fragment, { children: [_jsx("div", { ref: buttonRef, style: {
|
|
99
|
-
position: '
|
|
110
|
+
position: 'absolute',
|
|
100
111
|
top: position?.y || 0,
|
|
101
112
|
left: position?.x || 0,
|
|
102
113
|
zIndex: 9999,
|
|
@@ -104,7 +115,7 @@ const BulkEditButton = ({ visible, position, range, column, cellCount, editPopov
|
|
|
104
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: {
|
|
105
116
|
boxShadow: '0 2px 8px rgba(0,0,0,0.15)',
|
|
106
117
|
} }) }) }), popoverVisible && (_jsx("div", { ref: popoverRef, style: {
|
|
107
|
-
position: '
|
|
118
|
+
position: 'absolute',
|
|
108
119
|
top: popoverPosition?.top ?? (position?.y || 0) + 35,
|
|
109
120
|
left: popoverPosition?.left ?? (position?.x || 0),
|
|
110
121
|
zIndex: 10000,
|
|
@@ -112,9 +123,9 @@ const BulkEditButton = ({ visible, position, range, column, cellCount, editPopov
|
|
|
112
123
|
opacity: popoverPosition ? 1 : 0,
|
|
113
124
|
transition: 'opacity 0.1s ease-in-out',
|
|
114
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 }) }))] }));
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
return ReactDOM.createPortal(content,
|
|
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);
|
|
118
129
|
};
|
|
119
130
|
export default BulkEditButton;
|
|
120
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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"}
|