@bit.rhplus/ui.grid-layout 0.0.5 → 0.0.7
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/dist/useGridLayout.js +123 -410
- package/dist/useGridLayout.js.map +1 -1
- package/dist/useGridLayoutApi.js +6 -3
- package/dist/useGridLayoutApi.js.map +1 -1
- package/package.json +2 -2
- package/useGridLayout.js +132 -456
- package/useGridLayoutApi.js +7 -3
- /package/dist/{preview-1756735815679.js → preview-1756909601955.js} +0 -0
package/dist/useGridLayout.js
CHANGED
|
@@ -17,7 +17,7 @@ import { debounce } from 'lodash';
|
|
|
17
17
|
* @param {string} [config.filterName] - Název filtru (volitelné)
|
|
18
18
|
* @param {boolean} [config.enabled=true] - Zapnout/vypnout layout management
|
|
19
19
|
* @param {boolean} [config.autoSave=true] - Automatické ukládání při změnách
|
|
20
|
-
* @param {number} [config.autoSaveDelay=
|
|
20
|
+
* @param {number} [config.autoSaveDelay=500] - Zpoždění auto-save v ms
|
|
21
21
|
* @param {Array} config.columnDefs - AG-Grid column definitions
|
|
22
22
|
* @param {string} [config.accessToken] - Přístupový token
|
|
23
23
|
* @param {boolean} [config.waitForSavedFields=false] - Skrýt columnDefs dokud nejsou načtena savedFields
|
|
@@ -26,7 +26,7 @@ import { debounce } from 'lodash';
|
|
|
26
26
|
* @param {Function} [config.onError] - Callback při chybě
|
|
27
27
|
* @returns {Object} Grid layout management interface
|
|
28
28
|
*/
|
|
29
|
-
export const useGridLayout = ({ userKey, applicationName, gridName, filterName, enabled = true, autoSave = true, autoSaveDelay =
|
|
29
|
+
export const useGridLayout = ({ userKey, applicationName, gridName, filterName, enabled = true, autoSave = true, autoSaveDelay = 500, columnDefs = [], accessToken, waitForSavedFields = false, // Nový prop pro odložené zobrazení columnDefs
|
|
30
30
|
onLayoutLoaded, onLayoutSaved, onError, }) => {
|
|
31
31
|
// Validace columnDefs - musí být array
|
|
32
32
|
if (columnDefs !== undefined &&
|
|
@@ -38,6 +38,8 @@ onLayoutLoaded, onLayoutSaved, onError, }) => {
|
|
|
38
38
|
// Refs pro AG-Grid API
|
|
39
39
|
const gridApiRef = useRef(null);
|
|
40
40
|
const columnApiRef = useRef(null);
|
|
41
|
+
// Ref mapa pro ukládání aktuálních šířek sloupců (fieldId -> šířka)
|
|
42
|
+
const columnWidthRefsMap = useRef(new Map());
|
|
41
43
|
// State
|
|
42
44
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
43
45
|
const [isGridReady, setIsGridReady] = useState(false);
|
|
@@ -48,15 +50,7 @@ onLayoutLoaded, onLayoutSaved, onError, }) => {
|
|
|
48
50
|
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
|
|
49
51
|
const [isColumnEditorOpen, setIsColumnEditorOpen] = useState(false);
|
|
50
52
|
const [lastKnownColumnState, setLastKnownColumnState] = useState(null);
|
|
51
|
-
|
|
52
|
-
const [lastColumnDefsHash, setLastColumnDefsHash] = useState('');
|
|
53
|
-
// Utility funkce pro generování hash z columnDefs
|
|
54
|
-
const generateColumnDefsHash = useCallback((colDefs) => {
|
|
55
|
-
if (!Array.isArray(colDefs))
|
|
56
|
-
return '';
|
|
57
|
-
// Vytvoříme hash z klíčových vlastností které ovlivňují rendering
|
|
58
|
-
return colDefs.map(col => `${col.field || col.colId}:${col.width || 'auto'}:${col.hide ? 'hidden' : 'visible'}:${col.headerName || ''}`).join('|');
|
|
59
|
-
}, []);
|
|
53
|
+
const [columnWidthsVersion, setColumnWidthsVersion] = useState(0); // Pro trigger preTransformedColumnDefs
|
|
60
54
|
// Grid Layout API hook
|
|
61
55
|
const gridLayoutApi = useGridLayoutApi({
|
|
62
56
|
userKey,
|
|
@@ -83,110 +77,6 @@ onLayoutLoaded, onLayoutSaved, onError, }) => {
|
|
|
83
77
|
Array.isArray(columnDefs) &&
|
|
84
78
|
columnDefs.length > 0,
|
|
85
79
|
});
|
|
86
|
-
// // Bezpečné aktualizování lastKnownColumnState při otevření editoru
|
|
87
|
-
// useEffect(() => {
|
|
88
|
-
// if (isColumnEditorOpen && columnApiRef.current && typeof columnApiRef.current.getColumnState === 'function') {
|
|
89
|
-
// try {
|
|
90
|
-
// const currentState = columnApiRef.current.getColumnState();
|
|
91
|
-
// if (Array.isArray(currentState) && currentState.length > 0) {
|
|
92
|
-
// // Aktualizujeme lastKnownColumnState po otevření editoru
|
|
93
|
-
// const validColumnDefs = Array.isArray(columnDefs) ? columnDefs : [];
|
|
94
|
-
// const formattedState = currentState.map((columnStateItem, index) => {
|
|
95
|
-
// const colDef = validColumnDefs.find(cd => cd.field === columnStateItem.colId) || {};
|
|
96
|
-
// const savedField = savedFields?.records?.find(sf => sf.fieldName === columnStateItem.colId);
|
|
97
|
-
// return {
|
|
98
|
-
// id: columnStateItem.colId,
|
|
99
|
-
// field: columnStateItem.colId,
|
|
100
|
-
// headerName: savedField?.headerName || colDef.headerName || columnStateItem.colId,
|
|
101
|
-
// originalHeaderName: colDef.headerName || columnStateItem.colId,
|
|
102
|
-
// width: columnStateItem.width || colDef.width || 100,
|
|
103
|
-
// originalWidth: colDef.width || 100,
|
|
104
|
-
// visible: !columnStateItem.hide,
|
|
105
|
-
// order: index
|
|
106
|
-
// };
|
|
107
|
-
// });
|
|
108
|
-
// setLastKnownColumnState(formattedState);
|
|
109
|
-
// console.log('[GridLayout] Updated lastKnownColumnState after opening editor');
|
|
110
|
-
// }
|
|
111
|
-
// } catch (error) {
|
|
112
|
-
// console.error('[GridLayout] Error updating column state after opening editor:', error);
|
|
113
|
-
// }
|
|
114
|
-
// }
|
|
115
|
-
// }, [isColumnEditorOpen, columnDefs, savedFields, columnApiRef]);
|
|
116
|
-
// MutationObserver pro sledování změn v DOM a okamžitou aktualizaci headerName
|
|
117
|
-
// useEffect(() => {
|
|
118
|
-
// if (!savedFields?.records || !isInitialized || !enabled) return;
|
|
119
|
-
// // Reference na observer pro cleanup
|
|
120
|
-
// let observer = null;
|
|
121
|
-
// try {
|
|
122
|
-
// console.log('[GridLayout] Setting up MutationObserver for header changes');
|
|
123
|
-
// // Funkce pro aktualizaci headerName
|
|
124
|
-
// const updateHeaderNames = () => {
|
|
125
|
-
// try {
|
|
126
|
-
// // Vytvoříme mapu fieldName -> headerName z API dat
|
|
127
|
-
// const headerNameMap = new Map();
|
|
128
|
-
// savedFields.records.forEach(field => {
|
|
129
|
-
// if (field.fieldName && field.headerName) {
|
|
130
|
-
// headerNameMap.set(field.fieldName, field.headerName);
|
|
131
|
-
// }
|
|
132
|
-
// });
|
|
133
|
-
// // Najdeme všechny hlavičky sloupců v DOM
|
|
134
|
-
// const headerCells = document.querySelectorAll('.ag-header-cell');
|
|
135
|
-
// // Aktualizujeme texty hlaviček
|
|
136
|
-
// headerCells.forEach(headerCell => {
|
|
137
|
-
// try {
|
|
138
|
-
// // Získáme ID sloupce z DOM atributů
|
|
139
|
-
// const colId = headerCell.getAttribute('col-id');
|
|
140
|
-
// if (colId && headerNameMap.has(colId)) {
|
|
141
|
-
// // Najdeme element s textem hlavičky
|
|
142
|
-
// const headerTextEl = headerCell.querySelector('.ag-header-cell-text');
|
|
143
|
-
// if (headerTextEl) {
|
|
144
|
-
// const newHeaderName = headerNameMap.get(colId);
|
|
145
|
-
// const currentText = headerTextEl.textContent;
|
|
146
|
-
// if (currentText !== newHeaderName) {
|
|
147
|
-
// console.log(`[GridLayout] MutationObserver update: Column '${colId}' header from '${currentText}' to '${newHeaderName}'`);
|
|
148
|
-
// headerTextEl.textContent = newHeaderName;
|
|
149
|
-
// }
|
|
150
|
-
// }
|
|
151
|
-
// }
|
|
152
|
-
// } catch (cellError) {
|
|
153
|
-
// // Tiché selhání - nechceme, aby MutationObserver padal
|
|
154
|
-
// }
|
|
155
|
-
// });
|
|
156
|
-
// } catch (error) {
|
|
157
|
-
// // Tiché selhání - nechceme, aby MutationObserver padal
|
|
158
|
-
// }
|
|
159
|
-
// };
|
|
160
|
-
// // Najdeme element hlavičky
|
|
161
|
-
// const headerElement = document.querySelector('.ag-header');
|
|
162
|
-
// if (headerElement) {
|
|
163
|
-
// // Vytvoříme observer, který bude sledovat změny v hlavičce
|
|
164
|
-
// observer = new MutationObserver((mutations) => {
|
|
165
|
-
// // Detekovali jsme změnu v DOM hlavičky, aktualizujeme headerName
|
|
166
|
-
// updateHeaderNames();
|
|
167
|
-
// });
|
|
168
|
-
// // Začneme sledovat změny v hlavičce
|
|
169
|
-
// observer.observe(headerElement, {
|
|
170
|
-
// childList: true, // sledujeme přidání/odebírání elementů
|
|
171
|
-
// subtree: true, // sledujeme změny i v potomcích
|
|
172
|
-
// characterData: true, // sledujeme změny textu
|
|
173
|
-
// attributeFilter: ['col-id', 'class'] // sledujeme změny těchto atributů
|
|
174
|
-
// });
|
|
175
|
-
// console.log('[GridLayout] MutationObserver set up successfully');
|
|
176
|
-
// } else {
|
|
177
|
-
// console.log('[GridLayout] Header element not found for MutationObserver');
|
|
178
|
-
// }
|
|
179
|
-
// } catch (error) {
|
|
180
|
-
// console.error('[GridLayout] Error setting up MutationObserver:', error);
|
|
181
|
-
// }
|
|
182
|
-
// // Cleanup - odpojit observer při unmount
|
|
183
|
-
// return () => {
|
|
184
|
-
// if (observer) {
|
|
185
|
-
// observer.disconnect();
|
|
186
|
-
// console.log('[GridLayout] MutationObserver disconnected');
|
|
187
|
-
// }
|
|
188
|
-
// };
|
|
189
|
-
// }, [savedFields, isInitialized, enabled]);
|
|
190
80
|
/**
|
|
191
81
|
* Error handler
|
|
192
82
|
*/
|
|
@@ -204,41 +94,36 @@ onLayoutLoaded, onLayoutSaved, onError, }) => {
|
|
|
204
94
|
const stableHandleErrorRef = useRef(handleError);
|
|
205
95
|
// Reference pro ukládání stavu sloupců bez state update v render cyklu
|
|
206
96
|
const stableCurrentColumnsRef = useRef(null);
|
|
207
|
-
//
|
|
97
|
+
// Jednoduchá aktualizace ref hodnot - BEZ aktualizace columnDefs
|
|
208
98
|
useEffect(() => {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
//
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
232
|
-
// Zkontrolujeme zda se columnDefs skutečně změnily pomocí hash
|
|
233
|
-
const newHash = generateColumnDefsHash(updatedColumnDefs);
|
|
234
|
-
if (newHash !== lastColumnDefsHash) {
|
|
235
|
-
stableColumnDefsRef.current = updatedColumnDefs;
|
|
236
|
-
setLastColumnDefsHash(newHash);
|
|
99
|
+
// Při změně columnDefs vyčistíme columnWidthRefsMap a přeneseme existující šířky
|
|
100
|
+
if (columnDefs !== stableColumnDefsRef.current) {
|
|
101
|
+
const newWidthMap = new Map();
|
|
102
|
+
// Zachováme šířky pro sloupce, které stále existují
|
|
103
|
+
if (Array.isArray(columnDefs)) {
|
|
104
|
+
columnDefs.forEach(colDef => {
|
|
105
|
+
const fieldId = colDef.field || colDef.colId;
|
|
106
|
+
if (fieldId) {
|
|
107
|
+
// Zkusíme najít existující šířku v ref map
|
|
108
|
+
const existingWidth = columnWidthRefsMap.current.get(fieldId);
|
|
109
|
+
if (existingWidth !== undefined) {
|
|
110
|
+
newWidthMap.set(fieldId, existingWidth);
|
|
111
|
+
}
|
|
112
|
+
else if (colDef.width) {
|
|
113
|
+
// Použijeme šířku z nového columnDef
|
|
114
|
+
newWidthMap.set(fieldId, colDef.width);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
columnWidthRefsMap.current = newWidthMap;
|
|
120
|
+
setColumnWidthsVersion(prev => prev + 1); // Trigger preTransformedColumnDefs přepočet
|
|
237
121
|
}
|
|
122
|
+
stableColumnDefsRef.current = columnDefs;
|
|
238
123
|
stableGridLayoutApiRef.current = gridLayoutApi;
|
|
239
124
|
stableOnLayoutSavedRef.current = onLayoutSaved;
|
|
240
125
|
stableHandleErrorRef.current = handleError;
|
|
241
|
-
});
|
|
126
|
+
}, [columnDefs, gridLayoutApi, onLayoutSaved, handleError]);
|
|
242
127
|
// Efekt pro bezpečnou aktualizaci lastKnownColumnState z ref
|
|
243
128
|
// useEffect(() => {
|
|
244
129
|
// if (stableCurrentColumnsRef.current) {
|
|
@@ -495,6 +380,14 @@ onLayoutLoaded, onLayoutSaved, onError, }) => {
|
|
|
495
380
|
const columnDefsToUse = stableColumnDefsRef.current || columnDefs;
|
|
496
381
|
const columnState = gridLayoutApi.transformFieldsToColumnState(savedFields.records, columnDefsToUse);
|
|
497
382
|
if (columnState && columnState.length > 0) {
|
|
383
|
+
// Při prvotním načítání inicializujeme ref mapu s API šířkami
|
|
384
|
+
if (!isInitialized) {
|
|
385
|
+
columnState.forEach(colState => {
|
|
386
|
+
if (colState.colId && colState.width) {
|
|
387
|
+
columnWidthRefsMap.current.set(colState.colId, colState.width);
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
}
|
|
498
391
|
// Pokud je waitForSavedFields true, columnDefs jsou už pre-transformované,
|
|
499
392
|
// takže aplikujeme jen width a hide vlastnosti bez delay pro pořadí
|
|
500
393
|
const applyFunction = () => {
|
|
@@ -503,30 +396,22 @@ onLayoutLoaded, onLayoutSaved, onError, }) => {
|
|
|
503
396
|
let result;
|
|
504
397
|
try {
|
|
505
398
|
const applyOrderEnabled = !waitForSavedFields; // Při waitForSavedFields už je pořadí v columnDefs
|
|
506
|
-
//
|
|
507
|
-
//
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
//
|
|
511
|
-
const
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
return {
|
|
523
|
-
...colState,
|
|
524
|
-
width: currentWidth
|
|
525
|
-
};
|
|
526
|
-
}
|
|
527
|
-
return colState;
|
|
528
|
-
});
|
|
529
|
-
}
|
|
399
|
+
// Upravíme columnState s aktuálními šířkami z ref map
|
|
400
|
+
// POUZE pokud ref mapa obsahuje hodnoty (tj. uživatel už manipuloval s šířkami)
|
|
401
|
+
// Při prvotním načítání z API zachováme API šířky
|
|
402
|
+
let adjustedColumnState = columnState.map(colState => {
|
|
403
|
+
// Zkontrolujeme, zda máme ref hodnotu pro tento sloupec
|
|
404
|
+
const refWidth = columnWidthRefsMap.current.get(colState.colId);
|
|
405
|
+
// Použijeme ref hodnotu POUZE pokud existuje A není to prvotní načítání
|
|
406
|
+
if (refWidth !== undefined && isInitialized) {
|
|
407
|
+
return {
|
|
408
|
+
...colState,
|
|
409
|
+
width: refWidth
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
// Při prvotním načítání nebo pokud nemáme ref hodnotu, zachováme API šířku
|
|
413
|
+
return colState;
|
|
414
|
+
});
|
|
530
415
|
result = applyColumnStateApi.applyColumnState({
|
|
531
416
|
state: adjustedColumnState,
|
|
532
417
|
applyOrder: applyOrderEnabled, // Pořadí jen když není waitForSavedFields
|
|
@@ -591,6 +476,7 @@ onLayoutLoaded, onLayoutSaved, onError, }) => {
|
|
|
591
476
|
setTimeout(() => {
|
|
592
477
|
try {
|
|
593
478
|
const afterUpdateColDefs = gridApiRef.current.getColumnDefs();
|
|
479
|
+
const afterUpdateColumnState = gridApiRef.current.getColumnState?.() || [];
|
|
594
480
|
// DOM operace dokončeny, můžeme ukončit loading
|
|
595
481
|
setIsApplyingLayout(false);
|
|
596
482
|
}
|
|
@@ -733,38 +619,23 @@ onLayoutLoaded, onLayoutSaved, onError, }) => {
|
|
|
733
619
|
return;
|
|
734
620
|
}
|
|
735
621
|
setHasUnsavedChanges(true);
|
|
736
|
-
//
|
|
622
|
+
// Okamžitě uložit aktuální šířky sloupců do ref map (podobně jako v handleColumnResized)
|
|
737
623
|
try {
|
|
738
624
|
if (gridApiRef.current && typeof gridApiRef.current.getColumnState === 'function') {
|
|
739
625
|
const currentColumnState = gridApiRef.current.getColumnState();
|
|
740
626
|
if (currentColumnState && Array.isArray(currentColumnState)) {
|
|
741
|
-
//
|
|
742
|
-
const widthUpdatesMap = new Map();
|
|
627
|
+
// Uložit šířky do ref map pro každý sloupec
|
|
743
628
|
currentColumnState.forEach(colState => {
|
|
744
629
|
if (colState.colId && colState.width) {
|
|
745
|
-
|
|
630
|
+
columnWidthRefsMap.current.set(colState.colId, colState.width);
|
|
746
631
|
}
|
|
747
632
|
});
|
|
748
|
-
|
|
749
|
-
if (stableColumnDefsRef.current && Array.isArray(stableColumnDefsRef.current)) {
|
|
750
|
-
const updatedColumnDefs = stableColumnDefsRef.current.map(colDef => {
|
|
751
|
-
const fieldId = colDef.field || colDef.colId;
|
|
752
|
-
if (fieldId && widthUpdatesMap.has(fieldId)) {
|
|
753
|
-
return {
|
|
754
|
-
...colDef,
|
|
755
|
-
width: widthUpdatesMap.get(fieldId)
|
|
756
|
-
};
|
|
757
|
-
}
|
|
758
|
-
return colDef;
|
|
759
|
-
});
|
|
760
|
-
stableColumnDefsRef.current = updatedColumnDefs;
|
|
761
|
-
// Hash se aktualizuje automaticky v hlavním useEffect
|
|
762
|
-
}
|
|
633
|
+
setColumnWidthsVersion(prev => prev + 1); // Trigger preTransformedColumnDefs přepočet
|
|
763
634
|
}
|
|
764
635
|
}
|
|
765
636
|
}
|
|
766
637
|
catch (error) {
|
|
767
|
-
console.error('[GridLayout] Error updating
|
|
638
|
+
console.error('[GridLayout] Error updating columnWidthRefsMap in handleDragStopped:', error);
|
|
768
639
|
}
|
|
769
640
|
// Pokud ještě není inicializované, přidáme akci do pending
|
|
770
641
|
if (!isInitialized && autoSave) {
|
|
@@ -774,49 +645,56 @@ onLayoutLoaded, onLayoutSaved, onError, }) => {
|
|
|
774
645
|
]);
|
|
775
646
|
return;
|
|
776
647
|
}
|
|
777
|
-
// Normální proces pokud je vše inicializované
|
|
778
648
|
if (autoSave && debouncedSave) {
|
|
779
649
|
debouncedSave();
|
|
780
650
|
}
|
|
781
|
-
else {
|
|
782
|
-
}
|
|
783
651
|
}, [enabled, isGridReady, isInitialized, autoSave, debouncedSave]);
|
|
652
|
+
// Handler pro PRŮBĚŽNÉ resize - ukládá šířky během resize operace
|
|
653
|
+
const handleColumnResizing = useCallback(() => {
|
|
654
|
+
if (!enabled || !isGridReady)
|
|
655
|
+
return;
|
|
656
|
+
// Okamžitě uložit aktuální šířky sloupců do ref map BĚHEM resize operace
|
|
657
|
+
try {
|
|
658
|
+
if (gridApiRef.current && typeof gridApiRef.current.getColumnState === 'function') {
|
|
659
|
+
const currentColumnState = gridApiRef.current.getColumnState();
|
|
660
|
+
if (currentColumnState && Array.isArray(currentColumnState)) {
|
|
661
|
+
// Uložit šířky do ref map pro každý sloupec
|
|
662
|
+
currentColumnState.forEach(colState => {
|
|
663
|
+
if (colState.colId && colState.width) {
|
|
664
|
+
columnWidthRefsMap.current.set(colState.colId, colState.width);
|
|
665
|
+
}
|
|
666
|
+
});
|
|
667
|
+
setColumnWidthsVersion(prev => prev + 1); // Trigger preTransformedColumnDefs přepočet
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
catch (error) {
|
|
672
|
+
console.error('[GridLayout] Error updating columnWidthRefsMap in handleColumnResizing:', error);
|
|
673
|
+
}
|
|
674
|
+
// NEPOUŽÍVÁME setHasUnsavedChanges zde - to až v handleColumnResized
|
|
675
|
+
}, [enabled, isGridReady]);
|
|
676
|
+
// Handler pro DOKONČENÍ resize - spouští auto-save
|
|
784
677
|
const handleColumnResized = useCallback(() => {
|
|
785
678
|
if (!enabled || !isGridReady)
|
|
786
679
|
return;
|
|
787
680
|
setHasUnsavedChanges(true);
|
|
788
|
-
//
|
|
681
|
+
// Ještě jednou uložit aktuální šířky sloupců do ref map (pro jistotu)
|
|
789
682
|
try {
|
|
790
683
|
if (gridApiRef.current && typeof gridApiRef.current.getColumnState === 'function') {
|
|
791
684
|
const currentColumnState = gridApiRef.current.getColumnState();
|
|
792
685
|
if (currentColumnState && Array.isArray(currentColumnState)) {
|
|
793
|
-
//
|
|
794
|
-
const widthUpdatesMap = new Map();
|
|
686
|
+
// Uložit šířky do ref map pro každý sloupec
|
|
795
687
|
currentColumnState.forEach(colState => {
|
|
796
688
|
if (colState.colId && colState.width) {
|
|
797
|
-
|
|
689
|
+
columnWidthRefsMap.current.set(colState.colId, colState.width);
|
|
798
690
|
}
|
|
799
691
|
});
|
|
800
|
-
|
|
801
|
-
if (stableColumnDefsRef.current && Array.isArray(stableColumnDefsRef.current)) {
|
|
802
|
-
const updatedColumnDefs = stableColumnDefsRef.current.map(colDef => {
|
|
803
|
-
const fieldId = colDef.field || colDef.colId;
|
|
804
|
-
if (fieldId && widthUpdatesMap.has(fieldId)) {
|
|
805
|
-
return {
|
|
806
|
-
...colDef,
|
|
807
|
-
width: widthUpdatesMap.get(fieldId)
|
|
808
|
-
};
|
|
809
|
-
}
|
|
810
|
-
return colDef;
|
|
811
|
-
});
|
|
812
|
-
stableColumnDefsRef.current = updatedColumnDefs;
|
|
813
|
-
// Hash se aktualizuje automaticky v hlavním useEffect
|
|
814
|
-
}
|
|
692
|
+
setColumnWidthsVersion(prev => prev + 1); // Trigger preTransformedColumnDefs přepočet
|
|
815
693
|
}
|
|
816
694
|
}
|
|
817
695
|
}
|
|
818
696
|
catch (error) {
|
|
819
|
-
console.error('[GridLayout] Error updating
|
|
697
|
+
console.error('[GridLayout] Error updating columnWidthRefsMap in handleColumnResized:', error);
|
|
820
698
|
}
|
|
821
699
|
if (autoSave && isInitialized && debouncedSave) {
|
|
822
700
|
debouncedSave();
|
|
@@ -859,151 +737,20 @@ onLayoutLoaded, onLayoutSaved, onError, }) => {
|
|
|
859
737
|
*/
|
|
860
738
|
useEffect(() => {
|
|
861
739
|
// Aplikujeme layout pokud:
|
|
862
|
-
// 1. Máme savedFields z API
|
|
863
|
-
// 2. Grid je ready (má API
|
|
740
|
+
// 1. Máme savedFields z API (i když prázdné - první zobrazení modulu)
|
|
741
|
+
// 2. Grid je ready (má API references)
|
|
864
742
|
// 3. Ještě jsme neinicializovali layout
|
|
865
|
-
if (savedFields?.records
|
|
866
|
-
|
|
743
|
+
if (savedFields?.records !== undefined && gridApiRef.current && !isInitialized) {
|
|
744
|
+
if (savedFields.records.length > 0) {
|
|
745
|
+
applySavedLayout();
|
|
746
|
+
}
|
|
747
|
+
else {
|
|
748
|
+
// Pro prázdné savedFields jen nastavíme inicializaci
|
|
749
|
+
setIsInitialized(true);
|
|
750
|
+
setIsGridReady(true);
|
|
751
|
+
}
|
|
867
752
|
}
|
|
868
753
|
}, [savedFields?.records, isInitialized, applySavedLayout]);
|
|
869
|
-
/**
|
|
870
|
-
* Původní zakomentovaný effect pro aplikování layoutu když se načtou data
|
|
871
|
-
*/
|
|
872
|
-
// useEffect(() => {
|
|
873
|
-
// if (savedFields?.records && columnApiRef.current && !isInitialized) {
|
|
874
|
-
// console.log('[GridLayout] Layout will be applied from effect');
|
|
875
|
-
// applySavedLayout();
|
|
876
|
-
// } else if (savedFields?.records && columnApiRef.current && isInitialized) {
|
|
877
|
-
// // Pokud je již inicializován, ale přišla nová data, aktualizujeme jen DOM (ne celý layout)
|
|
878
|
-
// console.log('[GridLayout] Already initialized, but received new data - updating headers directly');
|
|
879
|
-
// // Počkáme moment, než se nová data zpracují, a pak aktualizujeme headerName
|
|
880
|
-
// setTimeout(() => {
|
|
881
|
-
// try {
|
|
882
|
-
// // Vytvoříme mapu fieldName -> headerName z API dat
|
|
883
|
-
// const headerNameMap = new Map();
|
|
884
|
-
// savedFields.records.forEach(field => {
|
|
885
|
-
// if (field.fieldName && field.headerName) {
|
|
886
|
-
// headerNameMap.set(field.fieldName, field.headerName);
|
|
887
|
-
// console.log(`[GridLayout] Update after reload: '${field.fieldName}' -> '${field.headerName}'`);
|
|
888
|
-
// }
|
|
889
|
-
// });
|
|
890
|
-
// // Najdeme všechny hlavičky sloupců v DOM
|
|
891
|
-
// const headerCells = document.querySelectorAll('.ag-header-cell');
|
|
892
|
-
// console.log('[GridLayout] Found header cells after reload:', headerCells.length);
|
|
893
|
-
// // Aktualizujeme texty hlaviček
|
|
894
|
-
// headerCells.forEach(headerCell => {
|
|
895
|
-
// try {
|
|
896
|
-
// // Získáme ID sloupce z DOM atributů
|
|
897
|
-
// const colId = headerCell.getAttribute('col-id');
|
|
898
|
-
// if (colId && headerNameMap.has(colId)) {
|
|
899
|
-
// // Najdeme element s textem hlavičky
|
|
900
|
-
// const headerTextEl = headerCell.querySelector('.ag-header-cell-text');
|
|
901
|
-
// if (headerTextEl) {
|
|
902
|
-
// const newHeaderName = headerNameMap.get(colId);
|
|
903
|
-
// const currentText = headerTextEl.textContent;
|
|
904
|
-
// console.log(`[GridLayout] DOM update after reload: Column '${colId}' header from '${currentText}' to '${newHeaderName}'`);
|
|
905
|
-
// headerTextEl.textContent = newHeaderName;
|
|
906
|
-
// }
|
|
907
|
-
// }
|
|
908
|
-
// } catch (cellError) {
|
|
909
|
-
// console.error('[GridLayout] Error updating header cell after reload:', cellError);
|
|
910
|
-
// }
|
|
911
|
-
// });
|
|
912
|
-
// // Zkusíme vynutit překreslení hlavičky
|
|
913
|
-
// if (typeof gridApiRef.current.refreshHeader === 'function') {
|
|
914
|
-
// console.log('[GridLayout] Forcing header refresh after reload');
|
|
915
|
-
// gridApiRef.current.refreshHeader();
|
|
916
|
-
// }
|
|
917
|
-
// } catch (error) {
|
|
918
|
-
// console.error('[GridLayout] Error updating headers after reload:', error);
|
|
919
|
-
// }
|
|
920
|
-
// }, 200);
|
|
921
|
-
// }
|
|
922
|
-
// }, [savedFields, applySavedLayout, isInitialized, columnApiRef]);
|
|
923
|
-
/**
|
|
924
|
-
* Alternativní metoda pro aktualizaci headerName po inicializaci gridu
|
|
925
|
-
*/
|
|
926
|
-
// useEffect(() => {
|
|
927
|
-
// // Pokud již proběhla inicializace a máme uložená data z API
|
|
928
|
-
// if (isInitialized && savedFields?.records && gridApiRef.current) {
|
|
929
|
-
// console.log('[GridLayout] Attempting alternative header update after initialization');
|
|
930
|
-
// // Zkusíme použít metodu columnDefHeaderNameChanged, pokud je dostupná
|
|
931
|
-
// try {
|
|
932
|
-
// if (typeof gridApiRef.current.columnDefHeaderNameChanged === 'function') {
|
|
933
|
-
// console.log('[GridLayout] Trying columnDefHeaderNameChanged method');
|
|
934
|
-
// // Vytvoříme mapu fieldName -> headerName z API dat
|
|
935
|
-
// const headerNameMap = new Map();
|
|
936
|
-
// savedFields.records.forEach(field => {
|
|
937
|
-
// if (field.fieldName && field.headerName) {
|
|
938
|
-
// headerNameMap.set(field.fieldName, field.headerName);
|
|
939
|
-
// }
|
|
940
|
-
// });
|
|
941
|
-
// // Získáme aktuální definice sloupců
|
|
942
|
-
// const currentColumnDefs = gridApiRef.current.getColumnDefs();
|
|
943
|
-
// if (currentColumnDefs && Array.isArray(currentColumnDefs)) {
|
|
944
|
-
// currentColumnDefs.forEach(colDef => {
|
|
945
|
-
// if (colDef.field && headerNameMap.has(colDef.field)) {
|
|
946
|
-
// const newHeaderName = headerNameMap.get(colDef.field);
|
|
947
|
-
// if (colDef.headerName !== newHeaderName) {
|
|
948
|
-
// console.log(`[GridLayout] Using columnDefHeaderNameChanged for '${colDef.field}': '${colDef.headerName}' -> '${newHeaderName}'`);
|
|
949
|
-
// colDef.headerName = newHeaderName;
|
|
950
|
-
// gridApiRef.current.columnDefHeaderNameChanged(colDef);
|
|
951
|
-
// }
|
|
952
|
-
// }
|
|
953
|
-
// });
|
|
954
|
-
// }
|
|
955
|
-
// }
|
|
956
|
-
// } catch (error) {
|
|
957
|
-
// console.error('[GridLayout] Error using columnDefHeaderNameChanged:', error);
|
|
958
|
-
// }
|
|
959
|
-
// // Počkáme chvíli, aby se grid stihl plně vyrenderovat
|
|
960
|
-
// setTimeout(() => {
|
|
961
|
-
// try {
|
|
962
|
-
// // Získáme aktuální definice sloupců z gridu
|
|
963
|
-
// const currentColDefs = gridApiRef.current.getColumnDefs ? gridApiRef.current.getColumnDefs() : null;
|
|
964
|
-
// if (currentColDefs && Array.isArray(currentColDefs)) {
|
|
965
|
-
// // Vytvoříme mapu fieldName -> headerName z API dat
|
|
966
|
-
// const headerNameMap = new Map();
|
|
967
|
-
// savedFields.records.forEach(field => {
|
|
968
|
-
// if (field.fieldName && field.headerName) {
|
|
969
|
-
// headerNameMap.set(field.fieldName, field.headerName);
|
|
970
|
-
// }
|
|
971
|
-
// });
|
|
972
|
-
// // Zkontrolujeme, zda je třeba aktualizovat nějaké headery
|
|
973
|
-
// let needsUpdate = false;
|
|
974
|
-
// const updatedColDefs = currentColDefs.map(colDef => {
|
|
975
|
-
// const fieldName = colDef.field;
|
|
976
|
-
// if (fieldName && headerNameMap.has(fieldName)) {
|
|
977
|
-
// const newHeaderName = headerNameMap.get(fieldName);
|
|
978
|
-
// if (colDef.headerName !== newHeaderName) {
|
|
979
|
-
// needsUpdate = true;
|
|
980
|
-
// console.log(`[GridLayout] Alternative update: Column '${fieldName}' header from '${colDef.headerName}' to '${newHeaderName}'`);
|
|
981
|
-
// return {
|
|
982
|
-
// ...colDef,
|
|
983
|
-
// headerName: newHeaderName
|
|
984
|
-
// };
|
|
985
|
-
// }
|
|
986
|
-
// }
|
|
987
|
-
// return colDef;
|
|
988
|
-
// });
|
|
989
|
-
// if (needsUpdate && typeof gridApiRef.current.setColumnDefs === 'function') {
|
|
990
|
-
// console.log('[GridLayout] Applying alternative column header update');
|
|
991
|
-
// gridApiRef.current.setColumnDefs(updatedColDefs);
|
|
992
|
-
// // Zkusíme vynutit překreslení hlavičky
|
|
993
|
-
// setTimeout(() => {
|
|
994
|
-
// if (typeof gridApiRef.current.refreshHeader === 'function') {
|
|
995
|
-
// console.log('[GridLayout] Forcing header refresh');
|
|
996
|
-
// gridApiRef.current.refreshHeader();
|
|
997
|
-
// }
|
|
998
|
-
// }, 50);
|
|
999
|
-
// }
|
|
1000
|
-
// }
|
|
1001
|
-
// } catch (error) {
|
|
1002
|
-
// console.error('[GridLayout] Error in alternative header update:', error);
|
|
1003
|
-
// }
|
|
1004
|
-
// }, 300);
|
|
1005
|
-
// }
|
|
1006
|
-
// }, [isInitialized, savedFields, gridApiRef]);
|
|
1007
754
|
/**
|
|
1008
755
|
* Effect pro error handling
|
|
1009
756
|
*/
|
|
@@ -1332,7 +1079,7 @@ onLayoutLoaded, onLayoutSaved, onError, }) => {
|
|
|
1332
1079
|
// DŮLEŽITÉ: Toto useMemo nyní obsahuje i AgGridColumns transformaci pro eliminaci circular dependency
|
|
1333
1080
|
const preTransformedColumnDefs = useMemo(() => {
|
|
1334
1081
|
// Použijeme aktualizované columnDefs ze stableColumnDefsRef pokud existují
|
|
1335
|
-
const columnDefsToUse = stableColumnDefsRef.current || columnDefs;
|
|
1082
|
+
const columnDefsToUse = stableColumnDefsRef.current; // || columnDefs; //HLO
|
|
1336
1083
|
let baseColumnDefs = columnDefsToUse;
|
|
1337
1084
|
// Pro waitForSavedFields aplikujeme grid layout transformace
|
|
1338
1085
|
if (waitForSavedFields &&
|
|
@@ -1367,7 +1114,7 @@ onLayoutLoaded, onLayoutSaved, onError, }) => {
|
|
|
1367
1114
|
.map((colDef) => {
|
|
1368
1115
|
const fieldId = colDef.field || colDef.colId;
|
|
1369
1116
|
const columnStateItem = columnStateMap.get(fieldId);
|
|
1370
|
-
// Aplikujeme
|
|
1117
|
+
// Aplikujeme headerName, hide i width z API pro waitForSavedFields režim
|
|
1371
1118
|
if (fieldId && (headerNameMap.has(fieldId) || columnStateItem)) {
|
|
1372
1119
|
return {
|
|
1373
1120
|
...colDef,
|
|
@@ -1375,7 +1122,8 @@ onLayoutLoaded, onLayoutSaved, onError, }) => {
|
|
|
1375
1122
|
...(headerNameMap.has(fieldId) && { headerName: headerNameMap.get(fieldId) }),
|
|
1376
1123
|
// Aplikujeme hide hodnotu z columnState (z API show hodnoty)
|
|
1377
1124
|
...(columnStateItem && { hide: columnStateItem.hide }),
|
|
1378
|
-
//
|
|
1125
|
+
// Aplikujeme také width pro konzistentní zobrazení
|
|
1126
|
+
...(columnStateItem && columnStateItem.width && { width: columnStateItem.width }),
|
|
1379
1127
|
};
|
|
1380
1128
|
}
|
|
1381
1129
|
return colDef;
|
|
@@ -1393,7 +1141,21 @@ onLayoutLoaded, onLayoutSaved, onError, }) => {
|
|
|
1393
1141
|
return [];
|
|
1394
1142
|
}
|
|
1395
1143
|
}
|
|
1396
|
-
|
|
1144
|
+
// Aplikujeme ref šířky jako poslední krok POUZE pokud už byla provedena inicializace
|
|
1145
|
+
// Při prvotním načítání zachováváme API šířky (které jsou už v baseColumnDefs pro waitForSavedFields)
|
|
1146
|
+
const finalColumnDefs = baseColumnDefs.map(colDef => {
|
|
1147
|
+
const fieldId = colDef.field || colDef.colId;
|
|
1148
|
+
const refWidth = columnWidthRefsMap.current.get(fieldId);
|
|
1149
|
+
// Použijeme ref šířku POUZE pokud už je grid inicializovaný (uživatel manipuloval s šířkami)
|
|
1150
|
+
if (refWidth !== undefined && isInitialized) {
|
|
1151
|
+
return {
|
|
1152
|
+
...colDef,
|
|
1153
|
+
width: refWidth
|
|
1154
|
+
};
|
|
1155
|
+
}
|
|
1156
|
+
return colDef;
|
|
1157
|
+
});
|
|
1158
|
+
return finalColumnDefs;
|
|
1397
1159
|
// // Replikujeme AgGridColumns logiku pro všechny column definitions:
|
|
1398
1160
|
// const processedColumns = baseColumnDefs?.map((column) => {
|
|
1399
1161
|
// // Zkopírujeme column aby se předešlo mutacím
|
|
@@ -1412,57 +1174,7 @@ onLayoutLoaded, onLayoutSaved, onError, }) => {
|
|
|
1412
1174
|
// return processedColumn;
|
|
1413
1175
|
// }) || [];
|
|
1414
1176
|
// return processedColumns;
|
|
1415
|
-
}, [waitForSavedFields, savedFields?.records, columnDefs, gridLayoutApi,
|
|
1416
|
-
/**
|
|
1417
|
-
* Handler pro změnu zobrazených dat - aktualizace headerName
|
|
1418
|
-
*/
|
|
1419
|
-
const handleRowDataChanged = useCallback((params) => {
|
|
1420
|
-
// if (!enabled || !savedFields?.records || !isInitialized) return;
|
|
1421
|
-
// console.log('[GridLayout] Row data changed - ensuring header names stay updated');
|
|
1422
|
-
// // Počkáme chvíli, až se vše vyrenderuje, a pak aktualizujeme headerName
|
|
1423
|
-
// setTimeout(() => {
|
|
1424
|
-
// try {
|
|
1425
|
-
// // Vytvoříme mapu fieldName -> headerName z API dat
|
|
1426
|
-
// const headerNameMap = new Map();
|
|
1427
|
-
// savedFields.records.forEach(field => {
|
|
1428
|
-
// if (field.fieldName && field.headerName) {
|
|
1429
|
-
// headerNameMap.set(field.fieldName, field.headerName);
|
|
1430
|
-
// }
|
|
1431
|
-
// });
|
|
1432
|
-
// // Najdeme všechny hlavičky sloupců v DOM
|
|
1433
|
-
// const headerCells = document.querySelectorAll('.ag-header-cell');
|
|
1434
|
-
// console.log('[GridLayout] Found header cells after data change:', headerCells.length);
|
|
1435
|
-
// // Aktualizujeme texty hlaviček
|
|
1436
|
-
// headerCells.forEach(headerCell => {
|
|
1437
|
-
// try {
|
|
1438
|
-
// // Získáme ID sloupce z DOM atributů
|
|
1439
|
-
// const colId = headerCell.getAttribute('col-id');
|
|
1440
|
-
// if (colId && headerNameMap.has(colId)) {
|
|
1441
|
-
// // Najdeme element s textem hlavičky
|
|
1442
|
-
// const headerTextEl = headerCell.querySelector('.ag-header-cell-text');
|
|
1443
|
-
// if (headerTextEl) {
|
|
1444
|
-
// const newHeaderName = headerNameMap.get(colId);
|
|
1445
|
-
// const currentText = headerTextEl.textContent;
|
|
1446
|
-
// if (currentText !== newHeaderName) {
|
|
1447
|
-
// console.log(`[GridLayout] Data change update: Column '${colId}' header from '${currentText}' to '${newHeaderName}'`);
|
|
1448
|
-
// headerTextEl.textContent = newHeaderName;
|
|
1449
|
-
// }
|
|
1450
|
-
// }
|
|
1451
|
-
// }
|
|
1452
|
-
// } catch (cellError) {
|
|
1453
|
-
// console.error('[GridLayout] Error updating header cell after data change:', cellError);
|
|
1454
|
-
// }
|
|
1455
|
-
// });
|
|
1456
|
-
// // Zkusíme vynutit překreslení hlavičky
|
|
1457
|
-
// if (typeof gridApiRef.current.refreshHeader === 'function') {
|
|
1458
|
-
// console.log('[GridLayout] Forcing header refresh after data change');
|
|
1459
|
-
// gridApiRef.current.refreshHeader();
|
|
1460
|
-
// }
|
|
1461
|
-
// } catch (error) {
|
|
1462
|
-
// console.error('[GridLayout] Error updating headers after data change:', error);
|
|
1463
|
-
// }
|
|
1464
|
-
// }, 100);
|
|
1465
|
-
}, [enabled, savedFields, isInitialized]);
|
|
1177
|
+
}, [waitForSavedFields, savedFields?.records, columnDefs, gridLayoutApi, columnWidthsVersion, isInitialized]);
|
|
1466
1178
|
return {
|
|
1467
1179
|
// State
|
|
1468
1180
|
isLoading: isLoading || isFieldsLoading,
|
|
@@ -1478,10 +1190,11 @@ onLayoutLoaded, onLayoutSaved, onError, }) => {
|
|
|
1478
1190
|
onGridReady: handleGridReady,
|
|
1479
1191
|
onColumnMoved: handleColumnMoved,
|
|
1480
1192
|
onDragStopped: handleDragStopped, // Nový handler pro konec drag operace
|
|
1193
|
+
onColumnResizing: handleColumnResizing, // NOVÝ handler pro průběžné resize
|
|
1481
1194
|
onColumnResized: handleColumnResized,
|
|
1482
1195
|
onColumnVisible: handleColumnVisible,
|
|
1483
1196
|
onColumnPinned: handleColumnPinned,
|
|
1484
|
-
onRowDataChanged: handleRowDataChanged, // Nový handler pro změnu dat
|
|
1197
|
+
// onRowDataChanged: handleRowDataChanged, // Nový handler pro změnu dat
|
|
1485
1198
|
// Manual actions
|
|
1486
1199
|
saveLayout,
|
|
1487
1200
|
resetToDefault,
|