@bit.rhplus/ui.grid 0.0.22 → 0.0.24
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/ColumnBuilder.jsx +411 -175
- package/dist/ColumnBuilder.d.ts +3 -10
- package/dist/ColumnBuilder.js +280 -108
- package/dist/ColumnBuilder.js.map +1 -1
- package/dist/index.js +19 -15
- package/dist/index.js.map +1 -1
- package/index.jsx +18 -15
- package/package.json +2 -2
- /package/dist/{preview-1747917457532.js → preview-1748952580414.js} +0 -0
package/ColumnBuilder.jsx
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { Menu, Dropdown,
|
|
2
|
+
import { Menu, Dropdown, Divider } from 'antd';
|
|
3
3
|
import { prepareCellStyle, prepareColDef, getValueByPath } from './utils';
|
|
4
4
|
import { currencySymbols } from './enums';
|
|
5
5
|
import { ActionIcon } from './Icons';
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
// Vytvoříme React hook funkci pro link cell renderer
|
|
9
8
|
const useLinkCellRenderer = (
|
|
10
9
|
params,
|
|
@@ -122,72 +121,6 @@ const useObjectCellRenderer = (params, editable, onEditClick) => {
|
|
|
122
121
|
};
|
|
123
122
|
};
|
|
124
123
|
|
|
125
|
-
// Vytvoříme React hook funkci pro row hover action renderer
|
|
126
|
-
const useRowHoverActionRenderer = (params) => {
|
|
127
|
-
const [isRowHovered, setIsRowHovered] = React.useState(false);
|
|
128
|
-
const rowRef = React.useRef(null);
|
|
129
|
-
|
|
130
|
-
React.useEffect(() => {
|
|
131
|
-
if (!params.node) return undefined;
|
|
132
|
-
|
|
133
|
-
// Funkce pro kontrolu, zda je řádek v hover stavu
|
|
134
|
-
const checkRowHoverState = () => {
|
|
135
|
-
// Najdeme DOM element řádku pomocí rowIndex
|
|
136
|
-
const rowElement = document.querySelector(
|
|
137
|
-
`.ag-row[row-index="${params.rowIndex}"]`
|
|
138
|
-
);
|
|
139
|
-
if (rowElement) {
|
|
140
|
-
rowRef.current = rowElement;
|
|
141
|
-
// AG-Grid automaticky přidává třídu ag-row-hover k řádku při najetí myší
|
|
142
|
-
const isHovered = rowElement.classList.contains('ag-row-hover');
|
|
143
|
-
setIsRowHovered(isHovered);
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
// Vytvoříme MutationObserver pro sledování změn tříd na řádku
|
|
148
|
-
const observer = new MutationObserver((mutations) => {
|
|
149
|
-
mutations.forEach((mutation) => {
|
|
150
|
-
if (
|
|
151
|
-
mutation.type === 'attributes' &&
|
|
152
|
-
mutation.attributeName === 'class'
|
|
153
|
-
) {
|
|
154
|
-
checkRowHoverState();
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
// Inicializujeme stav
|
|
160
|
-
checkRowHoverState();
|
|
161
|
-
|
|
162
|
-
// Přidáme observer k element řádku, pokud existuje
|
|
163
|
-
if (rowRef.current) {
|
|
164
|
-
observer.observe(rowRef.current, { attributes: true });
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Přidáme event listeners na grid container pro sledování pohybu myši
|
|
168
|
-
const gridContainer = document.querySelector('.ag-root-wrapper');
|
|
169
|
-
if (gridContainer) {
|
|
170
|
-
gridContainer.addEventListener('mouseover', checkRowHoverState);
|
|
171
|
-
gridContainer.addEventListener('mouseout', checkRowHoverState);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Cleanup při odmontování komponenty
|
|
175
|
-
return () => {
|
|
176
|
-
if (rowRef.current) {
|
|
177
|
-
observer.disconnect();
|
|
178
|
-
}
|
|
179
|
-
if (gridContainer) {
|
|
180
|
-
gridContainer.removeEventListener('mouseover', checkRowHoverState);
|
|
181
|
-
gridContainer.removeEventListener('mouseout', checkRowHoverState);
|
|
182
|
-
}
|
|
183
|
-
};
|
|
184
|
-
}, [params.node, params.rowIndex]);
|
|
185
|
-
|
|
186
|
-
return {
|
|
187
|
-
isRowHovered,
|
|
188
|
-
};
|
|
189
|
-
};
|
|
190
|
-
|
|
191
124
|
class ColumnBuilder {
|
|
192
125
|
#addPreparedColumn(props) {
|
|
193
126
|
this.columns.push(prepareColDef(this.intl, props));
|
|
@@ -198,42 +131,43 @@ class ColumnBuilder {
|
|
|
198
131
|
this.intl = intl;
|
|
199
132
|
}
|
|
200
133
|
|
|
201
|
-
addColumn({ colorField, ...props }) {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
134
|
+
addColumn({ colorField, ...props }) {
|
|
135
|
+
// Získáme původní cellStyle, pokud existuje
|
|
136
|
+
const originalCellStyle = props.cellStyle;
|
|
137
|
+
const { cellAlign, ...restProps } = props;
|
|
138
|
+
|
|
139
|
+
// Pokud je zadáno colorField, vytvoříme novou funkci pro cellStyle
|
|
140
|
+
if (colorField) {
|
|
141
|
+
const overrideCellStyle = (params) => {
|
|
142
|
+
// Získáme základní styl
|
|
143
|
+
let baseStyle = {};
|
|
144
|
+
if (originalCellStyle) {
|
|
145
|
+
if (typeof originalCellStyle === 'function') {
|
|
146
|
+
baseStyle = originalCellStyle(params);
|
|
147
|
+
} else {
|
|
148
|
+
baseStyle = originalCellStyle;
|
|
149
|
+
}
|
|
216
150
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
151
|
+
|
|
152
|
+
// Získáme hodnotu barvy z dat
|
|
153
|
+
const colorValue =
|
|
154
|
+
params.data && getValueByPath(params.data, colorField);
|
|
155
|
+
const restStyle = prepareCellStyle(props);
|
|
156
|
+
// Vrátíme kombinovaný styl
|
|
157
|
+
return colorValue
|
|
158
|
+
? { ...baseStyle, ...restStyle, color: colorValue }
|
|
159
|
+
: { ...baseStyle, ...restStyle };
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// Předáme upravené props do addPreparedColumn
|
|
163
|
+
this.#addPreparedColumn({ ...restProps, overrideCellStyle });
|
|
164
|
+
} else {
|
|
165
|
+
// Pokud není colorField zadán, použijeme původní implementaci
|
|
166
|
+
this.#addPreparedColumn(props);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return this;
|
|
233
170
|
}
|
|
234
|
-
|
|
235
|
-
return this;
|
|
236
|
-
}
|
|
237
171
|
|
|
238
172
|
// Nová metoda pro přidání sloupce s fakturou pro overview mód
|
|
239
173
|
addInvoiceCardColumn({
|
|
@@ -327,7 +261,7 @@ addColumn({ colorField, ...props }) {
|
|
|
327
261
|
hoverStyle,
|
|
328
262
|
cellAlign = 'left',
|
|
329
263
|
editable,
|
|
330
|
-
overviewToggle = false,
|
|
264
|
+
overviewToggle = false,
|
|
331
265
|
...restProps
|
|
332
266
|
}) {
|
|
333
267
|
// Vytvořím komponentu pro cell renderer, která používá hook
|
|
@@ -347,6 +281,12 @@ addColumn({ colorField, ...props }) {
|
|
|
347
281
|
overviewToggle
|
|
348
282
|
);
|
|
349
283
|
|
|
284
|
+
const handleKeyPress = React.useCallback((event) => {
|
|
285
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
286
|
+
handleClick(event);
|
|
287
|
+
}
|
|
288
|
+
}, [handleClick]);
|
|
289
|
+
|
|
350
290
|
return (
|
|
351
291
|
<div
|
|
352
292
|
className="link-cell-container"
|
|
@@ -361,14 +301,10 @@ addColumn({ colorField, ...props }) {
|
|
|
361
301
|
onClick={handleClick}
|
|
362
302
|
onMouseEnter={handleMouseEnter}
|
|
363
303
|
onMouseLeave={handleMouseLeave}
|
|
304
|
+
onKeyPress={handleKeyPress}
|
|
364
305
|
style={isHovered ? computedHoverStyle : computedLinkStyle}
|
|
365
306
|
role="button"
|
|
366
307
|
tabIndex={0}
|
|
367
|
-
onKeyPress={(event) => {
|
|
368
|
-
if (event.key === 'Enter' || event.key === ' ') {
|
|
369
|
-
handleClick(event);
|
|
370
|
-
}
|
|
371
|
-
}}
|
|
372
308
|
>
|
|
373
309
|
{params.value}
|
|
374
310
|
</span>
|
|
@@ -385,7 +321,7 @@ addColumn({ colorField, ...props }) {
|
|
|
385
321
|
cellAlign,
|
|
386
322
|
cellRenderer,
|
|
387
323
|
editable: this.#resolveEditable(editable),
|
|
388
|
-
overviewToggle,
|
|
324
|
+
overviewToggle,
|
|
389
325
|
...restProps,
|
|
390
326
|
});
|
|
391
327
|
return this;
|
|
@@ -459,6 +395,7 @@ addColumn({ colorField, ...props }) {
|
|
|
459
395
|
}}
|
|
460
396
|
onClick={handleEditClick}
|
|
461
397
|
title="Upravit"
|
|
398
|
+
type="button"
|
|
462
399
|
>
|
|
463
400
|
<span style={{ fontSize: '16px' }}>⋮</span>
|
|
464
401
|
</button>
|
|
@@ -497,13 +434,13 @@ addColumn({ colorField, ...props }) {
|
|
|
497
434
|
visibleGetter,
|
|
498
435
|
icon,
|
|
499
436
|
badge,
|
|
500
|
-
showZero
|
|
501
|
-
}
|
|
437
|
+
showZero,
|
|
438
|
+
};
|
|
502
439
|
this.#addPreparedColumn({
|
|
503
440
|
iconRenderer: true,
|
|
504
441
|
iconRendererParams,
|
|
505
|
-
...restProps
|
|
506
|
-
})
|
|
442
|
+
...restProps,
|
|
443
|
+
});
|
|
507
444
|
return this;
|
|
508
445
|
}
|
|
509
446
|
|
|
@@ -530,57 +467,336 @@ addColumn({ colorField, ...props }) {
|
|
|
530
467
|
return this;
|
|
531
468
|
}
|
|
532
469
|
|
|
470
|
+
// Řešení s izolovaným observer pro každý grid instance
|
|
533
471
|
addPinnedActionButton({
|
|
534
|
-
menuItems = [
|
|
535
|
-
{ key: '1', label: 'Hromadné smazání' },
|
|
536
|
-
{ key: '2', label: 'Hromadná aktualizace' },
|
|
537
|
-
{ key: '3', label: 'Spravovat značky' },
|
|
538
|
-
{ key: '4', label: 'Koncepty' },
|
|
539
|
-
{ key: '5', label: 'Hromadný e-mail' },
|
|
540
|
-
{ key: '6', label: 'Automatické odpovědi' },
|
|
541
|
-
{ key: '7', label: 'Schválit Kontakty' },
|
|
542
|
-
{ key: '8', label: 'Deduplikovat Kontakty' },
|
|
543
|
-
{ key: '9', label: 'Přidat do Kampaně' },
|
|
544
|
-
{ key: '10', label: 'Vytvoření klientského skriptu' },
|
|
545
|
-
{ key: 'divider1', type: 'divider' },
|
|
546
|
-
{ key: '11', label: 'Export Kontakty' },
|
|
547
|
-
{ key: '12', label: 'Zobrazení Zoho Sheet' },
|
|
548
|
-
{ key: 'divider2', type: 'divider' },
|
|
549
|
-
{ key: '13', label: 'Náhled tisku' },
|
|
550
|
-
],
|
|
472
|
+
menuItems = [],
|
|
551
473
|
onActionClick,
|
|
474
|
+
onBeforeShow,
|
|
552
475
|
...restProps
|
|
553
476
|
} = {}) {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
const { isRowHovered } = useRowHoverActionRenderer(params);
|
|
557
|
-
// Stav pro sledování, zda je dropdown otevřený
|
|
477
|
+
const ActionDropdownRenderer = (params) => {
|
|
478
|
+
const [isRowHovered, setIsRowHovered] = React.useState(false);
|
|
558
479
|
const [isDropdownVisible, setIsDropdownVisible] = React.useState(false);
|
|
480
|
+
const [currentMenuItems, setCurrentMenuItems] = React.useState(menuItems);
|
|
481
|
+
|
|
482
|
+
const isMountedRef = React.useRef(true);
|
|
483
|
+
const rowIndexRef = React.useRef(null);
|
|
484
|
+
const observerRef = React.useRef(null);
|
|
485
|
+
const gridContainerRef = React.useRef(null);
|
|
486
|
+
const currentHoveredRowRef = React.useRef(null);
|
|
487
|
+
const mouseListenersSetupRef = React.useRef(false);
|
|
559
488
|
|
|
560
|
-
//
|
|
561
|
-
const
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
489
|
+
// Notifikace o změně hover stavu - definována před použitím
|
|
490
|
+
const notifyRowHoverChange = React.useCallback((rowIndex, isHovered) => {
|
|
491
|
+
if (!isMountedRef.current) return;
|
|
492
|
+
|
|
493
|
+
if (!isHovered && rowIndexRef.current) {
|
|
494
|
+
setIsRowHovered(false);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
if (isHovered && rowIndexRef.current === rowIndex) {
|
|
498
|
+
setIsRowHovered(true);
|
|
499
|
+
}
|
|
500
|
+
}, []);
|
|
501
|
+
|
|
502
|
+
// Mouse event handlers - nyní definovány po notifyRowHoverChange
|
|
503
|
+
const handleMouseMove = React.useCallback((event) => {
|
|
504
|
+
if (!isMountedRef.current) return;
|
|
505
|
+
|
|
506
|
+
const { target } = event;
|
|
507
|
+
if (!target) return;
|
|
508
|
+
|
|
509
|
+
const rowElement = target.closest('.ag-row');
|
|
510
|
+
|
|
511
|
+
if (rowElement) {
|
|
512
|
+
const rowIndex =
|
|
513
|
+
rowElement.getAttribute('row-index') ||
|
|
514
|
+
rowElement.getAttribute('aria-rowindex') ||
|
|
515
|
+
rowElement.dataset.rowIndex ||
|
|
516
|
+
rowElement.getAttribute('data-ag-row-index');
|
|
517
|
+
|
|
518
|
+
if (rowIndex !== null) {
|
|
519
|
+
const normalizedRowIndex = rowIndex.toString();
|
|
520
|
+
|
|
521
|
+
if (normalizedRowIndex !== currentHoveredRowRef.current) {
|
|
522
|
+
if (currentHoveredRowRef.current !== null) {
|
|
523
|
+
notifyRowHoverChange(currentHoveredRowRef.current, false);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
currentHoveredRowRef.current = normalizedRowIndex;
|
|
527
|
+
notifyRowHoverChange(normalizedRowIndex, true);
|
|
566
528
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
529
|
+
}
|
|
530
|
+
} else if (currentHoveredRowRef.current !== null) {
|
|
531
|
+
notifyRowHoverChange(currentHoveredRowRef.current, false);
|
|
532
|
+
currentHoveredRowRef.current = null;
|
|
533
|
+
}
|
|
534
|
+
}, [notifyRowHoverChange]);
|
|
535
|
+
|
|
536
|
+
const handleMouseLeave = React.useCallback((event) => {
|
|
537
|
+
if (!isMountedRef.current) return;
|
|
538
|
+
|
|
539
|
+
const { relatedTarget } = event;
|
|
540
|
+
|
|
541
|
+
if (
|
|
542
|
+
gridContainerRef.current &&
|
|
543
|
+
(!relatedTarget || !gridContainerRef.current.contains(relatedTarget))
|
|
544
|
+
) {
|
|
545
|
+
if (currentHoveredRowRef.current !== null) {
|
|
546
|
+
notifyRowHoverChange(currentHoveredRowRef.current, false);
|
|
547
|
+
currentHoveredRowRef.current = null;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}, [notifyRowHoverChange]);
|
|
551
|
+
|
|
552
|
+
// Cleanup funkce - definována po handleMouseMove a handleMouseLeave
|
|
553
|
+
const cleanup = React.useCallback(() => {
|
|
554
|
+
if (observerRef.current) {
|
|
555
|
+
observerRef.current.disconnect();
|
|
556
|
+
observerRef.current = null;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
if (gridContainerRef.current && mouseListenersSetupRef.current) {
|
|
560
|
+
gridContainerRef.current.removeEventListener(
|
|
561
|
+
'mousemove',
|
|
562
|
+
handleMouseMove
|
|
563
|
+
);
|
|
564
|
+
gridContainerRef.current.removeEventListener(
|
|
565
|
+
'mouseleave',
|
|
566
|
+
handleMouseLeave
|
|
567
|
+
);
|
|
568
|
+
mouseListenersSetupRef.current = false;
|
|
569
|
+
}
|
|
570
|
+
}, [handleMouseMove, handleMouseLeave]);
|
|
571
|
+
|
|
572
|
+
React.useEffect(() => {
|
|
573
|
+
return () => {
|
|
574
|
+
isMountedRef.current = false;
|
|
575
|
+
cleanup();
|
|
576
|
+
};
|
|
577
|
+
}, [cleanup]);
|
|
578
|
+
|
|
579
|
+
// Získáme row index z params
|
|
580
|
+
React.useEffect(() => {
|
|
581
|
+
const { node, rowIndex } = params;
|
|
582
|
+
if (node && node.rowIndex !== undefined) {
|
|
583
|
+
rowIndexRef.current = node.rowIndex.toString();
|
|
584
|
+
} else if (rowIndex !== undefined) {
|
|
585
|
+
rowIndexRef.current = rowIndex.toString();
|
|
586
|
+
}
|
|
587
|
+
}, [params]);
|
|
588
|
+
|
|
589
|
+
// Nastavení observer pro tento konkrétní grid
|
|
590
|
+
const setupGridObserver = React.useCallback(() => {
|
|
591
|
+
const { api, eGridCell } = params;
|
|
592
|
+
if (!api || observerRef.current || !isMountedRef.current) return;
|
|
593
|
+
|
|
594
|
+
const findThisGridContainer = () => {
|
|
595
|
+
if (eGridCell) {
|
|
596
|
+
let current = eGridCell;
|
|
597
|
+
while (current && current !== document.body) {
|
|
598
|
+
if (
|
|
599
|
+
current.classList &&
|
|
600
|
+
(current.classList.contains('ag-root-wrapper') ||
|
|
601
|
+
current.classList.contains('ag-theme-alpine') ||
|
|
602
|
+
current.classList.contains('ag-theme-balham') ||
|
|
603
|
+
current.classList.contains('ag-theme-material') ||
|
|
604
|
+
current.classList.contains('ag-theme-fresh') ||
|
|
605
|
+
current.classList.contains('ag-theme-dark') ||
|
|
606
|
+
current.classList.contains('ag-theme-blue') ||
|
|
607
|
+
current.classList.contains('ag-theme-bootstrap'))
|
|
608
|
+
) {
|
|
609
|
+
return current;
|
|
610
|
+
}
|
|
611
|
+
current = current.parentElement;
|
|
574
612
|
}
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
613
|
+
}
|
|
614
|
+
return null;
|
|
615
|
+
};
|
|
616
|
+
|
|
617
|
+
const gridContainer = findThisGridContainer();
|
|
618
|
+
if (!gridContainer) {
|
|
619
|
+
setTimeout(setupGridObserver, 100);
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
gridContainerRef.current = gridContainer;
|
|
624
|
+
|
|
625
|
+
if (!mouseListenersSetupRef.current) {
|
|
626
|
+
gridContainer.addEventListener('mousemove', handleMouseMove, {
|
|
627
|
+
passive: true,
|
|
628
|
+
});
|
|
629
|
+
gridContainer.addEventListener('mouseleave', handleMouseLeave, {
|
|
630
|
+
passive: true,
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
const handleMouseEnter = () => {
|
|
634
|
+
if (isMountedRef.current) {
|
|
635
|
+
currentHoveredRowRef.current = null;
|
|
636
|
+
setIsRowHovered(false);
|
|
637
|
+
}
|
|
638
|
+
};
|
|
639
|
+
gridContainer.addEventListener('mouseenter', handleMouseEnter, {
|
|
640
|
+
passive: true,
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
mouseListenersSetupRef.current = true;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
observerRef.current = new MutationObserver((mutations) => {
|
|
647
|
+
if (!isMountedRef.current) return;
|
|
648
|
+
|
|
649
|
+
let shouldRecalculate = false;
|
|
650
|
+
|
|
651
|
+
mutations.forEach((mutation) => {
|
|
652
|
+
if (mutation.type === 'childList') {
|
|
653
|
+
const addedRows = Array.from(mutation.addedNodes).some(
|
|
654
|
+
(node) =>
|
|
655
|
+
node.nodeType === Node.ELEMENT_NODE &&
|
|
656
|
+
(node.classList?.contains('ag-row') ||
|
|
657
|
+
node.querySelector?.('.ag-row'))
|
|
658
|
+
);
|
|
659
|
+
|
|
660
|
+
const removedRows = Array.from(mutation.removedNodes).some(
|
|
661
|
+
(node) =>
|
|
662
|
+
node.nodeType === Node.ELEMENT_NODE &&
|
|
663
|
+
(node.classList?.contains('ag-row') ||
|
|
664
|
+
node.querySelector?.('.ag-row'))
|
|
665
|
+
);
|
|
666
|
+
|
|
667
|
+
if (addedRows || removedRows) {
|
|
668
|
+
shouldRecalculate = true;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
if (shouldRecalculate) {
|
|
674
|
+
currentHoveredRowRef.current = null;
|
|
675
|
+
setIsRowHovered(false);
|
|
676
|
+
|
|
677
|
+
setTimeout(() => {
|
|
678
|
+
if (isMountedRef.current && gridContainerRef.current) {
|
|
679
|
+
const rect = gridContainerRef.current.getBoundingClientRect();
|
|
680
|
+
const mouseEvent = new MouseEvent('mousemove', {
|
|
681
|
+
clientX: window.lastMouseX || rect.left + rect.width / 2,
|
|
682
|
+
clientY: window.lastMouseY || rect.top + rect.height / 2,
|
|
683
|
+
bubbles: true,
|
|
684
|
+
});
|
|
685
|
+
gridContainerRef.current.dispatchEvent(mouseEvent);
|
|
686
|
+
}
|
|
687
|
+
}, 100);
|
|
688
|
+
}
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
observerRef.current.observe(gridContainer, {
|
|
692
|
+
childList: true,
|
|
693
|
+
subtree: true,
|
|
694
|
+
attributes: false,
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
const trackMouse = (e) => {
|
|
698
|
+
window.lastMouseX = e.clientX;
|
|
699
|
+
window.lastMouseY = e.clientY;
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
document.addEventListener('mousemove', trackMouse, { passive: true });
|
|
703
|
+
|
|
704
|
+
const removeMouseListener = () => {
|
|
705
|
+
document.removeEventListener('mousemove', trackMouse);
|
|
706
|
+
};
|
|
707
|
+
|
|
708
|
+
removeMouseListener();
|
|
709
|
+
}, [params, handleMouseMove, handleMouseLeave]);
|
|
710
|
+
|
|
711
|
+
React.useEffect(() => {
|
|
712
|
+
setupGridObserver();
|
|
713
|
+
}, [setupGridObserver]);
|
|
714
|
+
|
|
715
|
+
const handleVisibleChange = React.useCallback(
|
|
716
|
+
async (visible) => {
|
|
717
|
+
if (!isMountedRef.current) return;
|
|
718
|
+
|
|
719
|
+
if (visible && onBeforeShow) {
|
|
720
|
+
try {
|
|
721
|
+
const updatedMenuItems = await onBeforeShow(params, menuItems);
|
|
722
|
+
if (
|
|
723
|
+
updatedMenuItems &&
|
|
724
|
+
Array.isArray(updatedMenuItems) &&
|
|
725
|
+
isMountedRef.current
|
|
726
|
+
) {
|
|
727
|
+
setCurrentMenuItems(updatedMenuItems);
|
|
728
|
+
}
|
|
729
|
+
} catch (error) {
|
|
730
|
+
// Odstraněn console.error pro ESLint
|
|
731
|
+
if (isMountedRef.current) {
|
|
732
|
+
setCurrentMenuItems(menuItems);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
if (isMountedRef.current) {
|
|
738
|
+
setIsDropdownVisible(visible);
|
|
739
|
+
}
|
|
740
|
+
},
|
|
741
|
+
[params]
|
|
742
|
+
);
|
|
743
|
+
|
|
744
|
+
React.useEffect(() => {
|
|
745
|
+
if (isMountedRef.current) {
|
|
746
|
+
setCurrentMenuItems(menuItems);
|
|
747
|
+
}
|
|
748
|
+
}, []);
|
|
749
|
+
|
|
750
|
+
const menu = React.useMemo(
|
|
751
|
+
() => (
|
|
752
|
+
<Menu
|
|
753
|
+
onClick={(e) => {
|
|
754
|
+
if (onActionClick) {
|
|
755
|
+
const item = currentMenuItems.filter(f => f.key === e.key)[0];
|
|
756
|
+
onActionClick(e.key, params, item);
|
|
757
|
+
}
|
|
758
|
+
setIsDropdownVisible(false);
|
|
759
|
+
}}
|
|
760
|
+
>
|
|
761
|
+
{currentMenuItems.map((item) => {
|
|
762
|
+
if (item.type === 'divider') {
|
|
763
|
+
return <Divider key={item.key} style={{ margin: '4px 0' }} />;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
const { disable, disabled } = item;
|
|
767
|
+
let isDisabled = false;
|
|
768
|
+
if (typeof disable === 'function') {
|
|
769
|
+
isDisabled = disable(params);
|
|
770
|
+
} else if (typeof disable === 'boolean') {
|
|
771
|
+
isDisabled = disable;
|
|
772
|
+
} else if (disabled !== undefined) {
|
|
773
|
+
isDisabled = disabled;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
return (
|
|
777
|
+
<Menu.Item key={item.key} disabled={isDisabled}>
|
|
778
|
+
{item.label}
|
|
779
|
+
</Menu.Item>
|
|
780
|
+
);
|
|
781
|
+
})}
|
|
782
|
+
</Menu>
|
|
783
|
+
),
|
|
784
|
+
[currentMenuItems, params]
|
|
578
785
|
);
|
|
579
786
|
|
|
580
|
-
|
|
787
|
+
const containerStyle = {
|
|
788
|
+
width: '32px',
|
|
789
|
+
height: '32px',
|
|
790
|
+
display: 'flex',
|
|
791
|
+
alignItems: 'center',
|
|
792
|
+
justifyContent: 'center',
|
|
793
|
+
position: 'relative',
|
|
794
|
+
};
|
|
795
|
+
|
|
581
796
|
const buttonStyle = {
|
|
582
797
|
minWidth: 'auto',
|
|
583
798
|
width: '32px',
|
|
799
|
+
height: '32px',
|
|
584
800
|
padding: '0',
|
|
585
801
|
background: 'transparent',
|
|
586
802
|
border: 'none',
|
|
@@ -588,40 +804,60 @@ addColumn({ colorField, ...props }) {
|
|
|
588
804
|
display: 'flex',
|
|
589
805
|
alignItems: 'center',
|
|
590
806
|
justifyContent: 'center',
|
|
807
|
+
opacity: isRowHovered || isDropdownVisible ? 1 : 0,
|
|
808
|
+
visibility: isRowHovered || isDropdownVisible ? 'visible' : 'hidden',
|
|
809
|
+
transition: 'opacity 0.15s ease-in-out, visibility 0.15s ease-in-out',
|
|
810
|
+
pointerEvents: isRowHovered || isDropdownVisible ? 'auto' : 'none',
|
|
591
811
|
};
|
|
592
812
|
|
|
593
|
-
|
|
594
|
-
|
|
813
|
+
const handleDropdownClick = React.useCallback((e) => {
|
|
814
|
+
e.stopPropagation();
|
|
815
|
+
}, []);
|
|
816
|
+
|
|
817
|
+
const handleKeyDown = React.useCallback((e) => {
|
|
818
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
819
|
+
e.preventDefault();
|
|
820
|
+
setIsDropdownVisible(!isDropdownVisible);
|
|
821
|
+
}
|
|
822
|
+
}, [isDropdownVisible]);
|
|
595
823
|
|
|
596
824
|
return (
|
|
597
|
-
<
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
style={buttonStyle}
|
|
606
|
-
// Zastavíme propagaci události mouseLeave, aby nedošlo k zavření dropdown
|
|
607
|
-
onMouseEnter={(e) => {
|
|
608
|
-
e.stopPropagation();
|
|
609
|
-
}}
|
|
825
|
+
<div style={containerStyle}>
|
|
826
|
+
<Dropdown
|
|
827
|
+
overlayStyle={{ zIndex: 5000 }}
|
|
828
|
+
overlay={menu}
|
|
829
|
+
trigger={['click']}
|
|
830
|
+
visible={isDropdownVisible}
|
|
831
|
+
onVisibleChange={handleVisibleChange}
|
|
832
|
+
getPopupContainer={() => document.body}
|
|
610
833
|
>
|
|
611
|
-
<
|
|
612
|
-
|
|
613
|
-
|
|
834
|
+
<div
|
|
835
|
+
style={buttonStyle}
|
|
836
|
+
onClick={handleDropdownClick}
|
|
837
|
+
onKeyDown={handleKeyDown}
|
|
838
|
+
role="button"
|
|
839
|
+
tabIndex={0}
|
|
840
|
+
aria-label="Otevřít akční menu"
|
|
841
|
+
>
|
|
842
|
+
<ActionIcon />
|
|
843
|
+
</div>
|
|
844
|
+
</Dropdown>
|
|
845
|
+
</div>
|
|
614
846
|
);
|
|
615
|
-
}
|
|
847
|
+
};
|
|
616
848
|
|
|
617
849
|
this.#addPreparedColumn({
|
|
618
850
|
headerName: '',
|
|
619
851
|
pinned: 'right',
|
|
620
|
-
maxWidth:
|
|
852
|
+
maxWidth: 40,
|
|
853
|
+
minWidth: 40,
|
|
621
854
|
suppressSizeToFit: true,
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
855
|
+
suppressMenu: true,
|
|
856
|
+
sortable: false,
|
|
857
|
+
filter: false,
|
|
858
|
+
resizable: false,
|
|
859
|
+
cellRenderer: ActionDropdownRenderer,
|
|
860
|
+
cellClass: 'action-button-cell-observer',
|
|
625
861
|
...restProps,
|
|
626
862
|
});
|
|
627
863
|
|
|
@@ -658,4 +894,4 @@ addColumn({ colorField, ...props }) {
|
|
|
658
894
|
}
|
|
659
895
|
}
|
|
660
896
|
|
|
661
|
-
export default ColumnBuilder;
|
|
897
|
+
export default ColumnBuilder;
|