@bit.rhplus/ag-grid 0.0.77 → 0.0.78

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 +10 -1
  3. package/BulkEdit/BulkEditInput.jsx +10 -1
  4. package/BulkEdit/BulkEditModule.jsx +10 -1
  5. package/BulkEdit/BulkEditPopover.jsx +10 -1
  6. package/BulkEdit/BulkEditSelect.jsx +10 -1
  7. package/Renderers/BooleanRenderer.jsx +10 -1
  8. package/Renderers/ButtonRenderer.jsx +14 -2
  9. package/Renderers/IconRenderer.jsx +10 -1
  10. package/Renderers/ImageRenderer.jsx +11 -2
  11. package/Renderers/LinkRenderer.jsx +10 -1
  12. package/Renderers/ObjectRenderer.jsx +10 -1
  13. package/Renderers/SelectRenderer.jsx +11 -1
  14. package/Renderers/StateRenderer.jsx +10 -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 +6 -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 +6 -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 +6 -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 +6 -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 +4 -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 +8 -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 +4 -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 +4 -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 +4 -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 +4 -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 +5 -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 +4 -1
  56. package/dist/Renderers/StateRenderer.js.map +1 -1
  57. package/dist/index.d.ts +2 -2
  58. package/dist/index.js +192 -66
  59. package/dist/index.js.map +1 -1
  60. package/index.jsx +214 -66
  61. package/package.json +6 -5
  62. /package/dist/{preview-1768366534788.js → preview-1768388646791.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';
@@ -237,11 +238,49 @@ const AgGrid = React.forwardRef((props, ref) => {
237
238
  setActiveNotificationMode('full');
238
239
  }, [aggregationData, props, notificationHead, createNotificationDescription, style, placement]);
239
240
 
241
+ // ========== PERFORMANCE FIX: Stabilní refs pro updateAggregationNotification ==========
242
+ const activeNotificationModeRef = React.useRef(activeNotificationMode);
243
+ const isSelectingRef = React.useRef(isSelecting);
244
+ const notificationHeadRef = React.useRef(notificationHead);
245
+ const createNotificationDescriptionRef = React.useRef(createNotificationDescription);
246
+ const styleRef = React.useRef(style);
247
+ const placementRef = React.useRef(placement);
248
+ const propsRef = React.useRef(props);
249
+
250
+ React.useEffect(() => {
251
+ activeNotificationModeRef.current = activeNotificationMode;
252
+ }, [activeNotificationMode]);
253
+
254
+ React.useEffect(() => {
255
+ isSelectingRef.current = isSelecting;
256
+ }, [isSelecting]);
257
+
258
+ React.useEffect(() => {
259
+ notificationHeadRef.current = notificationHead;
260
+ }, [notificationHead]);
261
+
262
+ React.useEffect(() => {
263
+ createNotificationDescriptionRef.current = createNotificationDescription;
264
+ }, [createNotificationDescription]);
265
+
266
+ React.useEffect(() => {
267
+ styleRef.current = style;
268
+ }, [style]);
269
+
270
+ React.useEffect(() => {
271
+ placementRef.current = placement;
272
+ }, [placement]);
273
+
274
+ React.useEffect(() => {
275
+ propsRef.current = props;
276
+ }, [props]);
277
+
240
278
  // ✅ OPTIMALIZACE: Helper funkce pro aktualizaci aggregace notifikace s cache check
241
279
  // Volá se BĚHEM označování s 100ms throttle pro real-time feedback
280
+ // STABILNÍ callback - používá pouze refs!
242
281
  const updateAggregationNotification = React.useCallback((event) => {
243
282
  // Pokud je notificationMode 'none', nedělat nic
244
- if (notificationMode === 'none') {
283
+ if (notificationModeRef.current === 'none') {
245
284
  return;
246
285
  }
247
286
 
@@ -254,14 +293,14 @@ const AgGrid = React.forwardRef((props, ref) => {
254
293
  lastRangeHashRef.current = null;
255
294
 
256
295
  // V 'full' módu zavřít notifikaci
257
- if (activeNotificationMode === 'full') {
258
- const gridId = props.gridName || props.id || 'default';
296
+ if (activeNotificationModeRef.current === 'full') {
297
+ const gridId = propsRef.current.gridName || propsRef.current.id || 'default';
259
298
  const key = `aggregation-grid-${gridId}`;
260
299
  notification.destroy(key);
261
300
  }
262
301
 
263
302
  // V 'simple' módu vyčistit aggregationData
264
- if (activeNotificationMode === 'simple') {
303
+ if (activeNotificationModeRef.current === 'simple') {
265
304
  setAggregationData(null);
266
305
  }
267
306
 
@@ -281,30 +320,30 @@ const AgGrid = React.forwardRef((props, ref) => {
281
320
  lastRangeHashRef.current = currentRangeHash;
282
321
 
283
322
  // Zavolat onAggregationChanged callback pokud existuje
284
- if (props.onAggregationChanged) {
285
- props.onAggregationChanged(messageInfo);
323
+ if (propsRef.current.onAggregationChanged) {
324
+ propsRef.current.onAggregationChanged(messageInfo);
286
325
  }
287
326
 
288
327
  // Podle aktivního módu zobrazit buď notifikaci nebo aktualizovat status bar
289
- if (activeNotificationMode === 'full') {
328
+ if (activeNotificationModeRef.current === 'full') {
290
329
  // FULL mód - zobrazit plovoucí notifikaci s tlačítkem pro přepnutí na simple
291
- const gridId = props.gridName || props.id || 'default';
330
+ const gridId = propsRef.current.gridName || propsRef.current.id || 'default';
292
331
  const key = `aggregation-grid-${gridId}`;
293
332
 
294
333
  const dynamicStyle = {
295
- ...style,
296
- pointerEvents: isSelecting ? 'none' : 'auto'
334
+ ...styleRef.current,
335
+ pointerEvents: isSelectingRef.current ? 'none' : 'auto'
297
336
  };
298
337
 
299
338
  notification.info({
300
339
  key,
301
- message: notificationHead(messageInfo),
302
- description: createNotificationDescription(messageInfo, true),
340
+ message: notificationHeadRef.current(messageInfo),
341
+ description: createNotificationDescriptionRef.current(messageInfo, true),
303
342
  duration: 0,
304
343
  style: dynamicStyle,
305
- placement,
344
+ placement: placementRef.current,
306
345
  });
307
- } else if (activeNotificationMode === 'simple') {
346
+ } else if (activeNotificationModeRef.current === 'simple') {
308
347
  // SIMPLE mód - aktualizovat state pro status bar
309
348
  setAggregationData(messageInfo);
310
349
  }
@@ -312,17 +351,17 @@ const AgGrid = React.forwardRef((props, ref) => {
312
351
  // Jen jedna buňka - zavřít/vyčistit vše
313
352
  lastRangeHashRef.current = null;
314
353
 
315
- if (activeNotificationMode === 'full') {
316
- const gridId = props.gridName || props.id || 'default';
354
+ if (activeNotificationModeRef.current === 'full') {
355
+ const gridId = propsRef.current.gridName || propsRef.current.id || 'default';
317
356
  const key = `aggregation-grid-${gridId}`;
318
357
  notification.destroy(key);
319
358
  }
320
359
 
321
- if (activeNotificationMode === 'simple') {
360
+ if (activeNotificationModeRef.current === 'simple') {
322
361
  setAggregationData(null);
323
362
  }
324
363
  }
325
- }, [notificationMode, activeNotificationMode, internalRef, props, notificationHead, createNotificationDescription, style, placement, isSelecting]);
364
+ }, [internalRef]); // Pouze internalRef v dependencies!
326
365
 
327
366
  // Detekce konce označování pomocí mouseup event
328
367
  React.useEffect(() => {
@@ -539,6 +578,36 @@ const AgGrid = React.forwardRef((props, ref) => {
539
578
  previousRowDataRef.current = rowData;
540
579
  }, [rowData, newRowFlash, updatedRowFlash]);
541
580
 
581
+ // ========== PERFORMANCE FIX: Stabilní ref pattern pro callbacks ==========
582
+ // Refs pro aktuální hodnoty - zabraňuje re-creation RhPlusRangeSelectionChanged při změně stavu
583
+ const notificationModeRef = React.useRef(notificationMode);
584
+ const enableBulkEditRef = React.useRef(enableBulkEdit);
585
+ const handleRangeChangeRef = React.useRef(handleRangeChange);
586
+ const onRangeSelectionChangedRef = React.useRef(props.onRangeSelectionChanged);
587
+ const updateAggregationNotificationRef = React.useRef(updateAggregationNotification);
588
+
589
+ // Aktualizovat refs při změně hodnot
590
+ React.useEffect(() => {
591
+ notificationModeRef.current = notificationMode;
592
+ }, [notificationMode]);
593
+
594
+ React.useEffect(() => {
595
+ enableBulkEditRef.current = enableBulkEdit;
596
+ }, [enableBulkEdit]);
597
+
598
+ React.useEffect(() => {
599
+ handleRangeChangeRef.current = handleRangeChange;
600
+ }, [handleRangeChange]);
601
+
602
+ React.useEffect(() => {
603
+ onRangeSelectionChangedRef.current = props.onRangeSelectionChanged;
604
+ }, [props.onRangeSelectionChanged]);
605
+
606
+ React.useEffect(() => {
607
+ updateAggregationNotificationRef.current = updateAggregationNotification;
608
+ }, [updateAggregationNotification]);
609
+
610
+ // Stabilní callback s prázdnými dependencies - používá pouze refs
542
611
  const RhPlusRangeSelectionChanged = React.useCallback(
543
612
  (event) => {
544
613
  // Detekovat začátek označování - nastavit isSelecting na true
@@ -547,8 +616,8 @@ const AgGrid = React.forwardRef((props, ref) => {
547
616
  // 1. ✅ OPTIMALIZACE: Zobrazení notifikace BĚHEM označování s THROTTLE
548
617
  // Simple mode: 300ms throttle (méně častá aktualizace, lepší výkon)
549
618
  // Full mode: 100ms throttle (rychlejší feedback, plovoucí notifikace je levná)
550
- if (notificationMode !== 'none') {
551
- const throttleInterval = notificationMode === 'simple' ? 300 : 100;
619
+ if (notificationModeRef.current !== 'none') {
620
+ const throttleInterval = notificationModeRef.current === 'simple' ? 300 : 100;
552
621
  const now = Date.now();
553
622
  const timeSinceLastCall = now - notificationLastCallRef.current;
554
623
 
@@ -557,7 +626,7 @@ const AgGrid = React.forwardRef((props, ref) => {
557
626
  // Okamžité volání
558
627
  notificationLastCallRef.current = now;
559
628
  if (internalRef?.current) {
560
- updateAggregationNotification(event);
629
+ updateAggregationNotificationRef.current(event);
561
630
  }
562
631
  } else {
563
632
  // Naplánovat volání za zbývající čas (trailing edge)
@@ -568,7 +637,7 @@ const AgGrid = React.forwardRef((props, ref) => {
568
637
  notificationThrottleRef.current = setTimeout(() => {
569
638
  notificationLastCallRef.current = Date.now();
570
639
  if (internalRef?.current) {
571
- updateAggregationNotification(event);
640
+ updateAggregationNotificationRef.current(event);
572
641
  }
573
642
  }, throttleInterval - timeSinceLastCall);
574
643
  }
@@ -577,14 +646,16 @@ const AgGrid = React.forwardRef((props, ref) => {
577
646
  // 2. ✅ OPTIMALIZACE: Bulk edit handler BEZ debounce - okamžité zobrazení ikony
578
647
  // Lightweight validace v useBulkCellEdit zajistí okamžité zobrazení
579
648
  // Těžká validace proběhne s 15ms debounce uvnitř useBulkCellEdit
580
- if (enableBulkEdit) {
581
- handleRangeChange(event);
649
+ if (enableBulkEditRef.current) {
650
+ handleRangeChangeRef.current(event);
582
651
  }
583
652
 
584
653
  // 3. Custom onRangeSelectionChanged callback - bez debounce
585
- if (props.onRangeSelectionChanged) props.onRangeSelectionChanged(event);
654
+ if (onRangeSelectionChangedRef.current) {
655
+ onRangeSelectionChangedRef.current(event);
656
+ }
586
657
  },
587
- [notificationMode, enableBulkEdit, handleRangeChange, props.onRangeSelectionChanged, updateAggregationNotification]
658
+ [] // PRÁZDNÉ dependencies - stabilní reference!
588
659
  );
589
660
 
590
661
  const AgGridOnGridReady = (event, options) => {
@@ -737,8 +808,9 @@ const AgGrid = React.forwardRef((props, ref) => {
737
808
  );
738
809
 
739
810
  // Memoizovaný context object
811
+ // ✅ OPTIMALIZACE: Použít pouze relevantní props pro context - neměnit při změně props
740
812
  const memoizedContext = React.useMemo(() => ({
741
- componentParent: { ...props }
813
+ componentParent: props
742
814
  }), [props.context, props.gridName, props.id]);
743
815
 
744
816
  // Memoizovaný defaultColDef
@@ -747,44 +819,111 @@ const AgGrid = React.forwardRef((props, ref) => {
747
819
  suppressHeaderMenuButton: true,
748
820
  suppressHeaderFilterButton: true,
749
821
  suppressMenu: true,
822
+ // ✅ FIX AG-Grid v35: Bezpečné zpracování null hodnot v Quick Filter
823
+ // AG-Grid v35 změnil implementaci Quick Filter - nyní volá .toString() na hodnotách buněk bez null check
824
+ // Tento callback zajistí že nikdy nedojde k chybě "Cannot read properties of null (reading 'toString')"
825
+ getQuickFilterText: (params) => {
826
+ const value = params.value;
827
+ // Null/undefined → prázdný string (bez chyby)
828
+ if (value == null) return '';
829
+ // Objekty a pole → JSON string
830
+ if (typeof value === 'object') {
831
+ try {
832
+ return JSON.stringify(value);
833
+ } catch {
834
+ // Cirkulární reference nebo jiná chyba při serializaci → prázdný string
835
+ return '';
836
+ }
837
+ }
838
+ // Primitivní typy → toString
839
+ return value.toString();
840
+ },
750
841
  }), [props.defaultColDef]);
751
842
 
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
- ]);
843
+ // ========== PERFORMANCE FIX: Memoizovat columnDefs ==========
844
+ // AgGridColumns vrací nový array při každém volání, i když jsou vstupy stejné
845
+ const memoizedColumnDefs = React.useMemo(() => {
846
+ return AgGridColumns(props.columnDefs, props);
847
+ }, [props.columnDefs, props.getRowId, props.frameworkComponents]);
848
+
849
+ // ========== CRITICAL FIX: Stabilní allGridProps objekt pomocí ref a forceUpdate ==========
850
+ // Problém: Jakékoli použití useMemo vytváří nový objekt při změně dependencies
851
+ // Řešení: Použít ref pro VŽDY stejný objekt a forceUpdate pro kontrolované re-rendery
852
+
853
+ const allGridPropsRef = React.useRef(null);
854
+ const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
855
+
856
+ // Sledovat klíčové props pro detekci kdy je potřeba forceUpdate
857
+ const prevRowDataRef = React.useRef(props.rowData);
858
+ const prevColumnDefsRef = React.useRef(memoizedColumnDefs);
859
+
860
+ // Inicializace objektu
861
+ if (!allGridPropsRef.current) {
862
+ allGridPropsRef.current = {};
863
+ }
864
+
865
+ // ✅ Aktualizovat props v EXISTUJÍCÍM objektu (mutace)
866
+ // AG Grid interně detekuje změny props, nepotřebuje nový objekt
867
+ allGridPropsRef.current.ref = internalRef;
868
+ allGridPropsRef.current.rowData = props.rowData;
869
+ allGridPropsRef.current.getRowId = props.getRowId;
870
+ allGridPropsRef.current.theme = themeObject;
871
+ allGridPropsRef.current.columnDefs = memoizedColumnDefs;
872
+ allGridPropsRef.current.defaultColDef = memoizedDefaultColDef;
873
+ allGridPropsRef.current.onCellEditingStarted = memoizedOnCellEditingStarted;
874
+ allGridPropsRef.current.onCellDoubleClicked = memoizedOnCellDoubleClicked;
875
+ // allGridPropsRef.current.onCellValueChanged = memoizedOnCellValueChanged;
876
+ allGridPropsRef.current.postSort = memoizedPostSort;
877
+ allGridPropsRef.current.onGridReady = memoizedOnGridReady;
878
+ allGridPropsRef.current.onRowDataChanged = memoizedOnRowDataChanged;
879
+ allGridPropsRef.current.onRowDataUpdated = memoizedOnRowDataUpdated;
880
+ allGridPropsRef.current.onRangeSelectionChanged = RhPlusRangeSelectionChanged;
881
+ allGridPropsRef.current.context = memoizedContext;
882
+ allGridPropsRef.current.components = components;
883
+
884
+ // Další AG Grid props
885
+ allGridPropsRef.current.rowModelType = props.rowModelType;
886
+ allGridPropsRef.current.rowSelection = props.rowSelection;
887
+ allGridPropsRef.current.enableRangeSelection = props.enableRangeSelection;
888
+ allGridPropsRef.current.enableRangeHandle = props.enableRangeHandle;
889
+ allGridPropsRef.current.enableFillHandle = props.enableFillHandle;
890
+ allGridPropsRef.current.suppressRowClickSelection = props.suppressRowClickSelection;
891
+ allGridPropsRef.current.singleClickEdit = props.singleClickEdit;
892
+ allGridPropsRef.current.stopEditingWhenCellsLoseFocus = props.stopEditingWhenCellsLoseFocus;
893
+ allGridPropsRef.current.rowClass = props.rowClass;
894
+ allGridPropsRef.current.rowStyle = props.rowStyle;
895
+ allGridPropsRef.current.getRowClass = props.getRowClass;
896
+ allGridPropsRef.current.getRowStyle = props.getRowStyle;
897
+ allGridPropsRef.current.animateRows = props.animateRows;
898
+ allGridPropsRef.current.suppressCellFocus = props.suppressCellFocus;
899
+ allGridPropsRef.current.suppressMenuHide = props.suppressMenuHide;
900
+ allGridPropsRef.current.enableCellTextSelection = props.enableCellTextSelection;
901
+ allGridPropsRef.current.ensureDomOrder = props.ensureDomOrder;
902
+ allGridPropsRef.current.suppressRowTransform = props.suppressRowTransform;
903
+ allGridPropsRef.current.suppressColumnVirtualisation = props.suppressColumnVirtualisation;
904
+ allGridPropsRef.current.suppressRowVirtualisation = props.suppressRowVirtualisation;
905
+ allGridPropsRef.current.tooltipShowDelay = props.tooltipShowDelay;
906
+ allGridPropsRef.current.tooltipHideDelay = props.tooltipHideDelay;
907
+ allGridPropsRef.current.tooltipMouseTrack = props.tooltipMouseTrack;
908
+ allGridPropsRef.current.gridId = props.gridId;
909
+ allGridPropsRef.current.id = props.id;
910
+ allGridPropsRef.current.gridName = props.gridName;
911
+
912
+ // ✅ Detekovat změny které VYŽADUJÍ re-render AG Gridu
913
+ React.useEffect(() => {
914
+ const rowDataChanged = prevRowDataRef.current !== props.rowData;
915
+ const columnDefsChanged = prevColumnDefsRef.current !== memoizedColumnDefs;
916
+
917
+ if (rowDataChanged || columnDefsChanged) {
918
+ prevRowDataRef.current = props.rowData;
919
+ prevColumnDefsRef.current = memoizedColumnDefs;
920
+ // Vynutit re-render pouze když se data nebo sloupce změní
921
+ forceUpdate();
922
+ }
923
+ }, [props.rowData, memoizedColumnDefs]);
924
+
925
+ // ✅ Vracíme VŽDY stejný objekt (stabilní reference)
926
+ const allGridProps = allGridPropsRef.current;
788
927
 
789
928
  // State pro sledování, kdy je API ready
790
929
  const [isApiReady, setIsApiReady] = React.useState(false);
@@ -793,7 +932,10 @@ const AgGrid = React.forwardRef((props, ref) => {
793
932
  // Tento useEffect se volá při změně quickFilterText NEBO když API je ready
794
933
  React.useEffect(() => {
795
934
  if (internalRef.current?.api && !internalRef.current.api.isDestroyed?.()) {
796
- internalRef.current.api.setGridOption("quickFilterText", quickFilterText);
935
+ // ✅ FIX AG-Grid v35: Zajistit že quickFilterText není null/undefined
936
+ // AG-Grid v35 interně volá .toString() na této hodnotě bez null checku
937
+ const safeQuickFilterText = quickFilterText ?? '';
938
+ internalRef.current.api.setGridOption("quickFilterText", safeQuickFilterText);
797
939
  }
798
940
  }, [quickFilterText, isApiReady]);
799
941
 
@@ -859,7 +1001,13 @@ const AgGrid = React.forwardRef((props, ref) => {
859
1001
  );
860
1002
  });
861
1003
 
862
- export default AgGrid;
1004
+ // ========== PERFORMANCE OPTIMIZATION: React.memo ==========
1005
+ // Refactored: Používá createGridComparison utility místo manuálního deep comparison
1006
+ // Eliminováno ~120 řádků duplicitního kódu, zachována stejná funkcionalita
1007
+ // Diagnostic mode: zapnutý pouze ve development módu
1008
+ export default React.memo(AgGrid, createGridComparison(
1009
+ process.env.NODE_ENV !== 'production' // Diagnostic mode pouze ve development
1010
+ ));
863
1011
 
864
1012
  export {
865
1013
  useBulkCellEdit,
@@ -873,4 +1021,4 @@ export {
873
1021
 
874
1022
  export {
875
1023
  default as CheckboxRenderer
876
- } from './Renderers/CheckboxRenderer'
1024
+ } 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.78",
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.78"
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.96",
24
+ "@bit.rhplus/react-memo": "0.0.1",
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.72",
27
+ "@bit.rhplus/data": "0.0.74"
27
28
  },
28
29
  "devDependencies": {
29
30
  "@teambit/react.react-env": "1.0.132"