@bit.rhplus/ag-grid 0.0.77 → 0.0.79

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.
Files changed (62) hide show
  1. package/BulkEdit/BulkEditButton.jsx +11 -1
  2. package/BulkEdit/BulkEditDatePicker.jsx +11 -1
  3. package/BulkEdit/BulkEditInput.jsx +11 -1
  4. package/BulkEdit/BulkEditModule.jsx +11 -1
  5. package/BulkEdit/BulkEditPopover.jsx +10 -1
  6. package/BulkEdit/BulkEditSelect.jsx +11 -1
  7. package/Renderers/BooleanRenderer.jsx +14 -1
  8. package/Renderers/ButtonRenderer.jsx +16 -2
  9. package/Renderers/IconRenderer.jsx +11 -1
  10. package/Renderers/ImageRenderer.jsx +12 -2
  11. package/Renderers/LinkRenderer.jsx +11 -1
  12. package/Renderers/ObjectRenderer.jsx +11 -1
  13. package/Renderers/SelectRenderer.jsx +12 -1
  14. package/Renderers/StateRenderer.jsx +11 -1
  15. package/dist/BulkEdit/BulkEditButton.d.ts +4 -17
  16. package/dist/BulkEdit/BulkEditButton.js +5 -1
  17. package/dist/BulkEdit/BulkEditButton.js.map +1 -1
  18. package/dist/BulkEdit/BulkEditDatePicker.d.ts +4 -3
  19. package/dist/BulkEdit/BulkEditDatePicker.js +7 -1
  20. package/dist/BulkEdit/BulkEditDatePicker.js.map +1 -1
  21. package/dist/BulkEdit/BulkEditInput.d.ts +4 -3
  22. package/dist/BulkEdit/BulkEditInput.js +7 -1
  23. package/dist/BulkEdit/BulkEditInput.js.map +1 -1
  24. package/dist/BulkEdit/BulkEditModule.d.ts +4 -3
  25. package/dist/BulkEdit/BulkEditModule.js +7 -1
  26. package/dist/BulkEdit/BulkEditModule.js.map +1 -1
  27. package/dist/BulkEdit/BulkEditPopover.d.ts +4 -17
  28. package/dist/BulkEdit/BulkEditPopover.js +4 -1
  29. package/dist/BulkEdit/BulkEditPopover.js.map +1 -1
  30. package/dist/BulkEdit/BulkEditSelect.d.ts +4 -3
  31. package/dist/BulkEdit/BulkEditSelect.js +7 -1
  32. package/dist/BulkEdit/BulkEditSelect.js.map +1 -1
  33. package/dist/Renderers/BooleanRenderer.d.ts +1 -2
  34. package/dist/Renderers/BooleanRenderer.js +10 -1
  35. package/dist/Renderers/BooleanRenderer.js.map +1 -1
  36. package/dist/Renderers/ButtonRenderer.d.ts +1 -5
  37. package/dist/Renderers/ButtonRenderer.js +10 -2
  38. package/dist/Renderers/ButtonRenderer.js.map +1 -1
  39. package/dist/Renderers/IconRenderer.d.ts +1 -2
  40. package/dist/Renderers/IconRenderer.js +5 -1
  41. package/dist/Renderers/IconRenderer.js.map +1 -1
  42. package/dist/Renderers/ImageRenderer.d.ts +1 -5
  43. package/dist/Renderers/ImageRenderer.js +5 -1
  44. package/dist/Renderers/ImageRenderer.js.map +1 -1
  45. package/dist/Renderers/LinkRenderer.d.ts +1 -5
  46. package/dist/Renderers/LinkRenderer.js +5 -1
  47. package/dist/Renderers/LinkRenderer.js.map +1 -1
  48. package/dist/Renderers/ObjectRenderer.d.ts +1 -5
  49. package/dist/Renderers/ObjectRenderer.js +5 -1
  50. package/dist/Renderers/ObjectRenderer.js.map +1 -1
  51. package/dist/Renderers/SelectRenderer.d.ts +1 -5
  52. package/dist/Renderers/SelectRenderer.js +6 -1
  53. package/dist/Renderers/SelectRenderer.js.map +1 -1
  54. package/dist/Renderers/StateRenderer.d.ts +1 -2
  55. package/dist/Renderers/StateRenderer.js +5 -1
  56. package/dist/Renderers/StateRenderer.js.map +1 -1
  57. package/dist/index.d.ts +2 -2
  58. package/dist/index.js +203 -66
  59. package/dist/index.js.map +1 -1
  60. package/index.jsx +227 -66
  61. package/package.json +6 -5
  62. /package/dist/{preview-1768366534788.js → preview-1768391238964.js} +0 -0
package/index.jsx CHANGED
@@ -10,6 +10,7 @@ import { AgGridOnRowDataChanged } from './AgGridOnRowDataChanged';
10
10
  import { AgGridOnRowDataUpdated } from './AgGridOnRowDataUpdated';
11
11
  import CheckboxRenderer from './Renderers/CheckboxRenderer';
12
12
  import BooleanRenderer from './Renderers/BooleanRenderer';
13
+ import { createGridComparison } from '@bit.rhplus/react-memo';
13
14
 
14
15
  import IconRenderer from './Renderers/IconRenderer';
15
16
  import ImageRenderer from './Renderers/ImageRenderer';
@@ -51,6 +52,19 @@ const themes = [
51
52
  ];
52
53
 
53
54
  const AgGrid = React.forwardRef((props, ref) => {
55
+ // ========== DIAGNOSTIC LOGGING ==========
56
+ const renderCountRef = React.useRef(0);
57
+ renderCountRef.current++;
58
+
59
+ if (process.env.NODE_ENV !== 'production') {
60
+ console.log(`🔄 [AG Grid ${props.gridName || 'unknown'}] Render #${renderCountRef.current}`, {
61
+ rowDataLength: props.rowData?.length,
62
+ columnDefsLength: props.columnDefs?.length,
63
+ quickFilterText: props.quickFilterText,
64
+ });
65
+ }
66
+ // ==========================================
67
+
54
68
  const internalRef = React.useRef();
55
69
  const {
56
70
  theme = "themeAlpine", // Default theme
@@ -237,11 +251,49 @@ const AgGrid = React.forwardRef((props, ref) => {
237
251
  setActiveNotificationMode('full');
238
252
  }, [aggregationData, props, notificationHead, createNotificationDescription, style, placement]);
239
253
 
254
+ // ========== PERFORMANCE FIX: Stabilní refs pro updateAggregationNotification ==========
255
+ const activeNotificationModeRef = React.useRef(activeNotificationMode);
256
+ const isSelectingRef = React.useRef(isSelecting);
257
+ const notificationHeadRef = React.useRef(notificationHead);
258
+ const createNotificationDescriptionRef = React.useRef(createNotificationDescription);
259
+ const styleRef = React.useRef(style);
260
+ const placementRef = React.useRef(placement);
261
+ const propsRef = React.useRef(props);
262
+
263
+ React.useEffect(() => {
264
+ activeNotificationModeRef.current = activeNotificationMode;
265
+ }, [activeNotificationMode]);
266
+
267
+ React.useEffect(() => {
268
+ isSelectingRef.current = isSelecting;
269
+ }, [isSelecting]);
270
+
271
+ React.useEffect(() => {
272
+ notificationHeadRef.current = notificationHead;
273
+ }, [notificationHead]);
274
+
275
+ React.useEffect(() => {
276
+ createNotificationDescriptionRef.current = createNotificationDescription;
277
+ }, [createNotificationDescription]);
278
+
279
+ React.useEffect(() => {
280
+ styleRef.current = style;
281
+ }, [style]);
282
+
283
+ React.useEffect(() => {
284
+ placementRef.current = placement;
285
+ }, [placement]);
286
+
287
+ React.useEffect(() => {
288
+ propsRef.current = props;
289
+ }, [props]);
290
+
240
291
  // ✅ OPTIMALIZACE: Helper funkce pro aktualizaci aggregace notifikace s cache check
241
292
  // Volá se BĚHEM označování s 100ms throttle pro real-time feedback
293
+ // STABILNÍ callback - používá pouze refs!
242
294
  const updateAggregationNotification = React.useCallback((event) => {
243
295
  // Pokud je notificationMode 'none', nedělat nic
244
- if (notificationMode === 'none') {
296
+ if (notificationModeRef.current === 'none') {
245
297
  return;
246
298
  }
247
299
 
@@ -254,14 +306,14 @@ const AgGrid = React.forwardRef((props, ref) => {
254
306
  lastRangeHashRef.current = null;
255
307
 
256
308
  // V 'full' módu zavřít notifikaci
257
- if (activeNotificationMode === 'full') {
258
- const gridId = props.gridName || props.id || 'default';
309
+ if (activeNotificationModeRef.current === 'full') {
310
+ const gridId = propsRef.current.gridName || propsRef.current.id || 'default';
259
311
  const key = `aggregation-grid-${gridId}`;
260
312
  notification.destroy(key);
261
313
  }
262
314
 
263
315
  // V 'simple' módu vyčistit aggregationData
264
- if (activeNotificationMode === 'simple') {
316
+ if (activeNotificationModeRef.current === 'simple') {
265
317
  setAggregationData(null);
266
318
  }
267
319
 
@@ -281,30 +333,30 @@ const AgGrid = React.forwardRef((props, ref) => {
281
333
  lastRangeHashRef.current = currentRangeHash;
282
334
 
283
335
  // Zavolat onAggregationChanged callback pokud existuje
284
- if (props.onAggregationChanged) {
285
- props.onAggregationChanged(messageInfo);
336
+ if (propsRef.current.onAggregationChanged) {
337
+ propsRef.current.onAggregationChanged(messageInfo);
286
338
  }
287
339
 
288
340
  // Podle aktivního módu zobrazit buď notifikaci nebo aktualizovat status bar
289
- if (activeNotificationMode === 'full') {
341
+ if (activeNotificationModeRef.current === 'full') {
290
342
  // FULL mód - zobrazit plovoucí notifikaci s tlačítkem pro přepnutí na simple
291
- const gridId = props.gridName || props.id || 'default';
343
+ const gridId = propsRef.current.gridName || propsRef.current.id || 'default';
292
344
  const key = `aggregation-grid-${gridId}`;
293
345
 
294
346
  const dynamicStyle = {
295
- ...style,
296
- pointerEvents: isSelecting ? 'none' : 'auto'
347
+ ...styleRef.current,
348
+ pointerEvents: isSelectingRef.current ? 'none' : 'auto'
297
349
  };
298
350
 
299
351
  notification.info({
300
352
  key,
301
- message: notificationHead(messageInfo),
302
- description: createNotificationDescription(messageInfo, true),
353
+ message: notificationHeadRef.current(messageInfo),
354
+ description: createNotificationDescriptionRef.current(messageInfo, true),
303
355
  duration: 0,
304
356
  style: dynamicStyle,
305
- placement,
357
+ placement: placementRef.current,
306
358
  });
307
- } else if (activeNotificationMode === 'simple') {
359
+ } else if (activeNotificationModeRef.current === 'simple') {
308
360
  // SIMPLE mód - aktualizovat state pro status bar
309
361
  setAggregationData(messageInfo);
310
362
  }
@@ -312,17 +364,17 @@ const AgGrid = React.forwardRef((props, ref) => {
312
364
  // Jen jedna buňka - zavřít/vyčistit vše
313
365
  lastRangeHashRef.current = null;
314
366
 
315
- if (activeNotificationMode === 'full') {
316
- const gridId = props.gridName || props.id || 'default';
367
+ if (activeNotificationModeRef.current === 'full') {
368
+ const gridId = propsRef.current.gridName || propsRef.current.id || 'default';
317
369
  const key = `aggregation-grid-${gridId}`;
318
370
  notification.destroy(key);
319
371
  }
320
372
 
321
- if (activeNotificationMode === 'simple') {
373
+ if (activeNotificationModeRef.current === 'simple') {
322
374
  setAggregationData(null);
323
375
  }
324
376
  }
325
- }, [notificationMode, activeNotificationMode, internalRef, props, notificationHead, createNotificationDescription, style, placement, isSelecting]);
377
+ }, [internalRef]); // Pouze internalRef v dependencies!
326
378
 
327
379
  // Detekce konce označování pomocí mouseup event
328
380
  React.useEffect(() => {
@@ -539,6 +591,36 @@ const AgGrid = React.forwardRef((props, ref) => {
539
591
  previousRowDataRef.current = rowData;
540
592
  }, [rowData, newRowFlash, updatedRowFlash]);
541
593
 
594
+ // ========== PERFORMANCE FIX: Stabilní ref pattern pro callbacks ==========
595
+ // Refs pro aktuální hodnoty - zabraňuje re-creation RhPlusRangeSelectionChanged při změně stavu
596
+ const notificationModeRef = React.useRef(notificationMode);
597
+ const enableBulkEditRef = React.useRef(enableBulkEdit);
598
+ const handleRangeChangeRef = React.useRef(handleRangeChange);
599
+ const onRangeSelectionChangedRef = React.useRef(props.onRangeSelectionChanged);
600
+ const updateAggregationNotificationRef = React.useRef(updateAggregationNotification);
601
+
602
+ // Aktualizovat refs při změně hodnot
603
+ React.useEffect(() => {
604
+ notificationModeRef.current = notificationMode;
605
+ }, [notificationMode]);
606
+
607
+ React.useEffect(() => {
608
+ enableBulkEditRef.current = enableBulkEdit;
609
+ }, [enableBulkEdit]);
610
+
611
+ React.useEffect(() => {
612
+ handleRangeChangeRef.current = handleRangeChange;
613
+ }, [handleRangeChange]);
614
+
615
+ React.useEffect(() => {
616
+ onRangeSelectionChangedRef.current = props.onRangeSelectionChanged;
617
+ }, [props.onRangeSelectionChanged]);
618
+
619
+ React.useEffect(() => {
620
+ updateAggregationNotificationRef.current = updateAggregationNotification;
621
+ }, [updateAggregationNotification]);
622
+
623
+ // Stabilní callback s prázdnými dependencies - používá pouze refs
542
624
  const RhPlusRangeSelectionChanged = React.useCallback(
543
625
  (event) => {
544
626
  // Detekovat začátek označování - nastavit isSelecting na true
@@ -547,8 +629,8 @@ const AgGrid = React.forwardRef((props, ref) => {
547
629
  // 1. ✅ OPTIMALIZACE: Zobrazení notifikace BĚHEM označování s THROTTLE
548
630
  // Simple mode: 300ms throttle (méně častá aktualizace, lepší výkon)
549
631
  // Full mode: 100ms throttle (rychlejší feedback, plovoucí notifikace je levná)
550
- if (notificationMode !== 'none') {
551
- const throttleInterval = notificationMode === 'simple' ? 300 : 100;
632
+ if (notificationModeRef.current !== 'none') {
633
+ const throttleInterval = notificationModeRef.current === 'simple' ? 300 : 100;
552
634
  const now = Date.now();
553
635
  const timeSinceLastCall = now - notificationLastCallRef.current;
554
636
 
@@ -557,7 +639,7 @@ const AgGrid = React.forwardRef((props, ref) => {
557
639
  // Okamžité volání
558
640
  notificationLastCallRef.current = now;
559
641
  if (internalRef?.current) {
560
- updateAggregationNotification(event);
642
+ updateAggregationNotificationRef.current(event);
561
643
  }
562
644
  } else {
563
645
  // Naplánovat volání za zbývající čas (trailing edge)
@@ -568,7 +650,7 @@ const AgGrid = React.forwardRef((props, ref) => {
568
650
  notificationThrottleRef.current = setTimeout(() => {
569
651
  notificationLastCallRef.current = Date.now();
570
652
  if (internalRef?.current) {
571
- updateAggregationNotification(event);
653
+ updateAggregationNotificationRef.current(event);
572
654
  }
573
655
  }, throttleInterval - timeSinceLastCall);
574
656
  }
@@ -577,14 +659,16 @@ const AgGrid = React.forwardRef((props, ref) => {
577
659
  // 2. ✅ OPTIMALIZACE: Bulk edit handler BEZ debounce - okamžité zobrazení ikony
578
660
  // Lightweight validace v useBulkCellEdit zajistí okamžité zobrazení
579
661
  // Těžká validace proběhne s 15ms debounce uvnitř useBulkCellEdit
580
- if (enableBulkEdit) {
581
- handleRangeChange(event);
662
+ if (enableBulkEditRef.current) {
663
+ handleRangeChangeRef.current(event);
582
664
  }
583
665
 
584
666
  // 3. Custom onRangeSelectionChanged callback - bez debounce
585
- if (props.onRangeSelectionChanged) props.onRangeSelectionChanged(event);
667
+ if (onRangeSelectionChangedRef.current) {
668
+ onRangeSelectionChangedRef.current(event);
669
+ }
586
670
  },
587
- [notificationMode, enableBulkEdit, handleRangeChange, props.onRangeSelectionChanged, updateAggregationNotification]
671
+ [] // PRÁZDNÉ dependencies - stabilní reference!
588
672
  );
589
673
 
590
674
  const AgGridOnGridReady = (event, options) => {
@@ -737,8 +821,9 @@ const AgGrid = React.forwardRef((props, ref) => {
737
821
  );
738
822
 
739
823
  // Memoizovaný context object
824
+ // ✅ OPTIMALIZACE: Použít pouze relevantní props pro context - neměnit při změně props
740
825
  const memoizedContext = React.useMemo(() => ({
741
- componentParent: { ...props }
826
+ componentParent: props
742
827
  }), [props.context, props.gridName, props.id]);
743
828
 
744
829
  // Memoizovaný defaultColDef
@@ -747,44 +832,111 @@ const AgGrid = React.forwardRef((props, ref) => {
747
832
  suppressHeaderMenuButton: true,
748
833
  suppressHeaderFilterButton: true,
749
834
  suppressMenu: true,
835
+ // ✅ FIX AG-Grid v35: Bezpečné zpracování null hodnot v Quick Filter
836
+ // AG-Grid v35 změnil implementaci Quick Filter - nyní volá .toString() na hodnotách buněk bez null check
837
+ // Tento callback zajistí že nikdy nedojde k chybě "Cannot read properties of null (reading 'toString')"
838
+ getQuickFilterText: (params) => {
839
+ const value = params.value;
840
+ // Null/undefined → prázdný string (bez chyby)
841
+ if (value == null) return '';
842
+ // Objekty a pole → JSON string
843
+ if (typeof value === 'object') {
844
+ try {
845
+ return JSON.stringify(value);
846
+ } catch {
847
+ // Cirkulární reference nebo jiná chyba při serializaci → prázdný string
848
+ return '';
849
+ }
850
+ }
851
+ // Primitivní typy → toString
852
+ return value.toString();
853
+ },
750
854
  }), [props.defaultColDef]);
751
855
 
752
- // ========== PERFORMANCE OPTIMIZATION: Memoizovaný allGridProps ==========
753
- const allGridProps = React.useMemo(() => ({
754
- ref: internalRef,
755
- ...props,
756
- theme: themeObject,
757
- columnDefs: AgGridColumns(props.columnDefs, props),
758
- defaultColDef: memoizedDefaultColDef,
759
- onCellEditingStarted: memoizedOnCellEditingStarted,
760
- onCellDoubleClicked: memoizedOnCellDoubleClicked,
761
- onCellValueChanged: memoizedOnCellValueChanged,
762
- postSort: memoizedPostSort,
763
- onGridReady: memoizedOnGridReady,
764
- onRowDataChanged: memoizedOnRowDataChanged,
765
- onRowDataUpdated: memoizedOnRowDataUpdated,
766
- onRangeSelectionChanged: RhPlusRangeSelectionChanged,
767
- context: memoizedContext,
768
- components,
769
- // Explicitně zajistit že enableRangeSelection je propagováno
770
- enableRangeSelection: props.enableRangeSelection,
771
- }), [
772
- internalRef,
773
- themeObject,
774
- props.columnDefs,
775
- props.enableRangeSelection,
776
- memoizedDefaultColDef,
777
- memoizedOnCellEditingStarted,
778
- memoizedOnCellDoubleClicked,
779
- memoizedOnCellValueChanged,
780
- memoizedPostSort,
781
- memoizedOnGridReady,
782
- memoizedOnRowDataChanged,
783
- memoizedOnRowDataUpdated,
784
- RhPlusRangeSelectionChanged,
785
- memoizedContext,
786
- components,
787
- ]);
856
+ // ========== PERFORMANCE FIX: Memoizovat columnDefs ==========
857
+ // AgGridColumns vrací nový array při každém volání, i když jsou vstupy stejné
858
+ const memoizedColumnDefs = React.useMemo(() => {
859
+ return AgGridColumns(props.columnDefs, props);
860
+ }, [props.columnDefs, props.getRowId, props.frameworkComponents]);
861
+
862
+ // ========== CRITICAL FIX: Stabilní allGridProps objekt pomocí ref a forceUpdate ==========
863
+ // Problém: Jakékoli použití useMemo vytváří nový objekt při změně dependencies
864
+ // Řešení: Použít ref pro VŽDY stejný objekt a forceUpdate pro kontrolované re-rendery
865
+
866
+ const allGridPropsRef = React.useRef(null);
867
+ const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
868
+
869
+ // Sledovat klíčové props pro detekci kdy je potřeba forceUpdate
870
+ const prevRowDataRef = React.useRef(props.rowData);
871
+ const prevColumnDefsRef = React.useRef(memoizedColumnDefs);
872
+
873
+ // Inicializace objektu
874
+ if (!allGridPropsRef.current) {
875
+ allGridPropsRef.current = {};
876
+ }
877
+
878
+ // ✅ Aktualizovat props v EXISTUJÍCÍM objektu (mutace)
879
+ // AG Grid interně detekuje změny props, nepotřebuje nový objekt
880
+ allGridPropsRef.current.ref = internalRef;
881
+ allGridPropsRef.current.rowData = props.rowData;
882
+ allGridPropsRef.current.getRowId = props.getRowId;
883
+ allGridPropsRef.current.theme = themeObject;
884
+ allGridPropsRef.current.columnDefs = memoizedColumnDefs;
885
+ allGridPropsRef.current.defaultColDef = memoizedDefaultColDef;
886
+ allGridPropsRef.current.onCellEditingStarted = memoizedOnCellEditingStarted;
887
+ allGridPropsRef.current.onCellDoubleClicked = memoizedOnCellDoubleClicked;
888
+ // allGridPropsRef.current.onCellValueChanged = memoizedOnCellValueChanged;
889
+ allGridPropsRef.current.postSort = memoizedPostSort;
890
+ allGridPropsRef.current.onGridReady = memoizedOnGridReady;
891
+ allGridPropsRef.current.onRowDataChanged = memoizedOnRowDataChanged;
892
+ allGridPropsRef.current.onRowDataUpdated = memoizedOnRowDataUpdated;
893
+ allGridPropsRef.current.onRangeSelectionChanged = RhPlusRangeSelectionChanged;
894
+ allGridPropsRef.current.context = memoizedContext;
895
+ allGridPropsRef.current.components = components;
896
+
897
+ // Další AG Grid props
898
+ allGridPropsRef.current.rowModelType = props.rowModelType;
899
+ allGridPropsRef.current.rowSelection = props.rowSelection;
900
+ allGridPropsRef.current.enableRangeSelection = props.enableRangeSelection;
901
+ allGridPropsRef.current.enableRangeHandle = props.enableRangeHandle;
902
+ allGridPropsRef.current.enableFillHandle = props.enableFillHandle;
903
+ allGridPropsRef.current.suppressRowClickSelection = props.suppressRowClickSelection;
904
+ allGridPropsRef.current.singleClickEdit = props.singleClickEdit;
905
+ allGridPropsRef.current.stopEditingWhenCellsLoseFocus = props.stopEditingWhenCellsLoseFocus;
906
+ allGridPropsRef.current.rowClass = props.rowClass;
907
+ allGridPropsRef.current.rowStyle = props.rowStyle;
908
+ allGridPropsRef.current.getRowClass = props.getRowClass;
909
+ allGridPropsRef.current.getRowStyle = props.getRowStyle;
910
+ allGridPropsRef.current.animateRows = props.animateRows;
911
+ allGridPropsRef.current.suppressCellFocus = props.suppressCellFocus;
912
+ allGridPropsRef.current.suppressMenuHide = props.suppressMenuHide;
913
+ allGridPropsRef.current.enableCellTextSelection = props.enableCellTextSelection;
914
+ allGridPropsRef.current.ensureDomOrder = props.ensureDomOrder;
915
+ allGridPropsRef.current.suppressRowTransform = props.suppressRowTransform;
916
+ allGridPropsRef.current.suppressColumnVirtualisation = props.suppressColumnVirtualisation;
917
+ allGridPropsRef.current.suppressRowVirtualisation = props.suppressRowVirtualisation;
918
+ allGridPropsRef.current.tooltipShowDelay = props.tooltipShowDelay;
919
+ allGridPropsRef.current.tooltipHideDelay = props.tooltipHideDelay;
920
+ allGridPropsRef.current.tooltipMouseTrack = props.tooltipMouseTrack;
921
+ allGridPropsRef.current.gridId = props.gridId;
922
+ allGridPropsRef.current.id = props.id;
923
+ allGridPropsRef.current.gridName = props.gridName;
924
+
925
+ // ✅ Detekovat změny které VYŽADUJÍ re-render AG Gridu
926
+ React.useEffect(() => {
927
+ const rowDataChanged = prevRowDataRef.current !== props.rowData;
928
+ const columnDefsChanged = prevColumnDefsRef.current !== memoizedColumnDefs;
929
+
930
+ if (rowDataChanged || columnDefsChanged) {
931
+ prevRowDataRef.current = props.rowData;
932
+ prevColumnDefsRef.current = memoizedColumnDefs;
933
+ // Vynutit re-render pouze když se data nebo sloupce změní
934
+ forceUpdate();
935
+ }
936
+ }, [props.rowData, memoizedColumnDefs]);
937
+
938
+ // ✅ Vracíme VŽDY stejný objekt (stabilní reference)
939
+ const allGridProps = allGridPropsRef.current;
788
940
 
789
941
  // State pro sledování, kdy je API ready
790
942
  const [isApiReady, setIsApiReady] = React.useState(false);
@@ -793,7 +945,10 @@ const AgGrid = React.forwardRef((props, ref) => {
793
945
  // Tento useEffect se volá při změně quickFilterText NEBO když API je ready
794
946
  React.useEffect(() => {
795
947
  if (internalRef.current?.api && !internalRef.current.api.isDestroyed?.()) {
796
- internalRef.current.api.setGridOption("quickFilterText", quickFilterText);
948
+ // ✅ FIX AG-Grid v35: Zajistit že quickFilterText není null/undefined
949
+ // AG-Grid v35 interně volá .toString() na této hodnotě bez null checku
950
+ const safeQuickFilterText = quickFilterText ?? '';
951
+ internalRef.current.api.setGridOption("quickFilterText", safeQuickFilterText);
797
952
  }
798
953
  }, [quickFilterText, isApiReady]);
799
954
 
@@ -859,7 +1014,13 @@ const AgGrid = React.forwardRef((props, ref) => {
859
1014
  );
860
1015
  });
861
1016
 
862
- export default AgGrid;
1017
+ // ========== PERFORMANCE OPTIMIZATION: React.memo ==========
1018
+ // Refactored: Používá createGridComparison utility místo manuálního deep comparison
1019
+ // Eliminováno ~120 řádků duplicitního kódu, zachována stejná funkcionalita
1020
+ // Diagnostic mode: zapnutý pouze ve development módu
1021
+ export default React.memo(AgGrid, createGridComparison(
1022
+ process.env.NODE_ENV !== 'production' // Diagnostic mode pouze ve development
1023
+ ));
863
1024
 
864
1025
  export {
865
1026
  useBulkCellEdit,
@@ -873,4 +1034,4 @@ export {
873
1034
 
874
1035
  export {
875
1036
  default as CheckboxRenderer
876
- } from './Renderers/CheckboxRenderer'
1037
+ } from './Renderers/CheckboxRenderer';
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bit.rhplus/ag-grid",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "homepage": "https://bit.cloud/remote-scope/ag-grid",
5
5
  "main": "dist/index.js",
6
6
  "componentId": {
7
7
  "scope": "remote-scope",
8
8
  "name": "ag-grid",
9
- "version": "0.0.77"
9
+ "version": "0.0.79"
10
10
  },
11
11
  "dependencies": {
12
12
  "moment": "^2.30.1",
@@ -20,10 +20,11 @@
20
20
  "styled-components": "^6.1.19",
21
21
  "lucide-react": "^0.503.0",
22
22
  "linq": "^4.0.3",
23
- "@bit.rhplus/ui.grid": "0.0.95",
23
+ "@bit.rhplus/ui.grid": "0.0.97",
24
+ "@bit.rhplus/react-memo": "0.0.2",
24
25
  "@bit.rhplus/linq": "0.0.8",
25
- "@bit.rhplus/ui2.module-dropdown-list": "0.1.71",
26
- "@bit.rhplus/data": "0.0.73"
26
+ "@bit.rhplus/ui2.module-dropdown-list": "0.1.73",
27
+ "@bit.rhplus/data": "0.0.75"
27
28
  },
28
29
  "devDependencies": {
29
30
  "@teambit/react.react-env": "1.0.132"