@bit.rhplus/ui.grid 0.0.37 → 0.0.39

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/index.jsx CHANGED
@@ -1,339 +1,339 @@
1
- /* eslint-disable */
2
- import React, { useCallback, useEffect, useState, useMemo, useImperativeHandle, forwardRef } from 'react';
3
- import AgGrid from '@bit.rhplus/ag-grid';
4
- // import { AgGridReact } from 'ag-grid-react';
5
- import classnames from 'classnames';
6
- import { OperationType, useSharedGrid } from '@bit.rhplus/shared-grid-form';
7
- import { AgGridColumns } from './AgGridColumns';
8
- import { useGridLayout, ColumnEditorModal } from '@bit.rhplus/ui.grid-layout';
9
- import { useOidcAccessToken } from "@axa-fr/react-oidc";
10
-
11
- const Grid = React.forwardRef((props, ref) => {
12
- const gridRef = React.useRef(null);
13
- const {
14
- appearance = 'ag-theme-alpine',
15
- columnDefs,
16
- height = '100%',
17
- defaultColDef,
18
- gridOptions,
19
- rowClassRules,
20
- editableDefault = true,
21
- onRowDoubleClicked,
22
- // Grid Layout props
23
- gridName,
24
- applicationName = 'Portal.App',
25
- userKey,
26
- filterName,
27
- layoutEnabled = true,
28
- autoSave = true,
29
- autoSaveDelay = 2000,
30
- accessToken,
31
- waitForSavedFields = false, // Nový prop pro odložené zobrazení columnDefs
32
- onLayoutLoaded,
33
- onLayoutSaved,
34
- onLayoutError,
35
- } = props;
36
-
37
-
38
- const {
39
- items,
40
- onGridReady,
41
- addItem,
42
- updateItem,
43
- deleteItem,
44
- pendingChanges = [],
45
- isCellEditable,
46
- } = useSharedGrid();
47
-
48
- const [gridApi, setGridApi] = useState(null);
49
- const [gridLayoutActivated, setGridLayoutActivated] = useState(false);
50
-
51
- // Konverze columnDefs na array pro Grid Layout - memoizace pro prevenci nekonečné smyčky
52
- const columnDefsArray = useMemo(() => {
53
- if (Array.isArray(columnDefs)) {
54
- return columnDefs;
55
- }
56
- // Pokud má build() metodu, je to pravděpodobně ColumnBuilder
57
- if (columnDefs && typeof columnDefs.build === 'function') {
58
- return columnDefs.build();
59
- }
60
- return [];
61
- }, [columnDefs]);
62
-
63
- // Grid Layout Management
64
- const gridLayout = useGridLayout({
65
- userKey,
66
- applicationName,
67
- gridName,
68
- filterName,
69
- enabled: layoutEnabled && !!userKey && !!gridName,
70
- autoSave,
71
- autoSaveDelay,
72
- columnDefs: columnDefsArray,
73
- accessToken,
74
- waitForSavedFields, // Nový parametr pro odložené zobrazení
75
- onLayoutLoaded,
76
- onLayoutSaved,
77
- onError: onLayoutError
78
- });
79
-
80
- // Handler pro připravení gridu
81
- const handleGridReady = useCallback(
82
- (event, options) => {
83
- setGridApi(event.api);
84
-
85
- // Modern AG-Grid (33+) fix: columnApi was moved to main api object
86
- const normalizedEvent = {
87
- ...event,
88
- api: event.api,
89
- columnApi: event.columnApi || event.api // fallback for modern AG-Grid versions
90
- };
91
-
92
- // Grid Layout initialization
93
- if (layoutEnabled && gridLayout.onGridReady && !gridLayoutActivated) {
94
- gridLayout.onGridReady(normalizedEvent);
95
- setGridLayoutActivated(true);
96
- }
97
-
98
- if (onGridReady) {
99
- onGridReady(event);
100
- }
101
- },
102
- [onGridReady, layoutEnabled, gridLayout, userKey, gridName]
103
- );
104
-
105
- // Effect pro delayed grid layout activation když se layoutEnabled změní na true
106
- useEffect(() => {
107
- // Pokud se layoutEnabled změnilo na true a máme již gridApi, aktivujeme grid layout
108
- if (layoutEnabled && gridApi && gridLayout.onGridReady && !gridLayoutActivated) {
109
- // Simulujeme onGridReady event pro grid layout
110
- // Modern AG-Grid (33+) fix: columnApi functionality is in main api
111
- const mockGridReadyParams = {
112
- api: gridApi,
113
- columnApi: gridApi.columnApi || gridApi // fallback for modern AG-Grid versions
114
- };
115
-
116
- try {
117
- gridLayout.onGridReady(mockGridReadyParams);
118
- setGridLayoutActivated(true);
119
- } catch (error) {
120
- console.error('❌ UI/Grid: Error in delayed grid layout activation:', error);
121
- }
122
- }
123
- }, [layoutEnabled, gridApi, gridLayout, userKey, gridName, gridLayoutActivated]);
124
-
125
- // Handler pro změnu hodnoty buňky
126
- const handleCellValueChanged = useCallback(
127
- (params) => {
128
- const { data, colDef, newValue } = params;
129
- // Extrahujeme pouze změněné pole
130
- const changes = { [colDef.field]: newValue };
131
- updateItem(data.id, changes);
132
- },
133
- [updateItem]
134
- );
135
-
136
- // Handler pro dvojklik na buňku
137
- // const handleCellDoubleClicked = useCallback((params) => {
138
- // const { colDef } = params;
139
-
140
- // // Pokud je buňka needitovatelná, vyvoláme událost onRowDoubleClicked
141
- // let isEditable = true;
142
- // if (typeof colDef.editable === 'function') {
143
- // isEditable = colDef.editable(params);
144
- // } else if (typeof colDef.editable === 'boolean') {
145
- // isEditable = colDef.editable;
146
- // } else {
147
- // isEditable = editableDefault;
148
- // }
149
-
150
- // // Pokud buňka není editovatelná a máme definován callback pro dvojklik na řádek
151
- // if (!isEditable && onRowDoubleClicked) {
152
- // // Simulujeme událost dvojkliku na řádek
153
- // onRowDoubleClicked({
154
- // ...params,
155
- // // Přidáme data, která by normálně obsahovala událost onRowDoubleClicked
156
- // api: params.api,
157
- // node: params.node,
158
- // rowIndex: params.rowIndex,
159
- // data: params.data,
160
- // event: params.event
161
- // });
162
-
163
- // // Zastavíme výchozí zpracování událostí, aby se nezobrazil editor buňky
164
- // if (params.event) {
165
- // params.event.preventDefault();
166
- // }
167
- // }
168
- // }, [onRowDoubleClicked, editableDefault]);
169
-
170
- // Handler pro přidání nového řádku
171
- const handleAddRow = useCallback(
172
- (rowData = {}) => {
173
- const newItemId = addItem(rowData);
174
-
175
- // Může být potřeba aktualizovat grid pro zobrazení nového řádku
176
- if (gridApi) {
177
- gridApi.setRowData(items);
178
-
179
- // Volitelně: přejít na nově přidanou položku
180
- setTimeout(() => {
181
- const rowNode = gridApi.getRowNode(newItemId);
182
- if (rowNode) {
183
- gridApi.ensureNodeVisible(rowNode);
184
- }
185
- }, 100);
186
- }
187
-
188
- return newItemId;
189
- },
190
- [addItem, gridApi, items]
191
- );
192
-
193
- // Handler pro odstranění řádku
194
- const handleDeleteRow = useCallback(
195
- (id) => {
196
- deleteItem(id);
197
-
198
- // Může být potřeba aktualizovat grid
199
- if (gridApi) {
200
- gridApi.setRowData(items);
201
- }
202
- },
203
- [deleteItem, gridApi, items]
204
- );
205
-
206
- // Vlastní CSS třídy pro řádky s čekajícími změnami
207
- const defaultRowClassRules = {
208
- 'row-pending-add': (params) => {
209
- return (
210
- pendingChanges[params.data.id] &&
211
- pendingChanges[params.data.id].operation === OperationType.ADD
212
- );
213
- },
214
- 'row-pending-update': (params) => {
215
- return (
216
- pendingChanges[params.data.id] &&
217
- pendingChanges[params.data.id].operation === OperationType.UPDATE
218
- );
219
- },
220
- 'row-pending-delete': (params) => {
221
- return (
222
- pendingChanges[params.data.id] &&
223
- pendingChanges[params.data.id].operation === OperationType.DELETE
224
- );
225
- },
226
- };
227
-
228
- // Kombinované rowClassRules
229
- const combinedRowClassRules = { ...defaultRowClassRules, ...rowClassRules };
230
-
231
- // Exportovat metody pro přidání/odstranění řádků
232
- useEffect(() => {
233
- if (gridApi) {
234
- // Metody můžeme přidat přímo do gridApi pro použití z vnějšku
235
- gridApi.addRow = handleAddRow;
236
- gridApi.deleteRow = handleDeleteRow;
237
- }
238
- }, [gridApi, handleAddRow, handleDeleteRow]);
239
-
240
- const allGridProps = {
241
- rowData: items,
242
- defaultColDef: {
243
- enableCellChangeFlash: true,
244
- editable: editableDefault,
245
- resizable: true,
246
- ...defaultColDef,
247
- },
248
- isRowSelectable: (params) => {
249
- return (
250
- !pendingChanges[params.data.id] ||
251
- pendingChanges[params.data.id].operation !== OperationType.DELETE
252
- );
253
- },
254
- isEditable: isCellEditable,
255
- onGridReady: handleGridReady,
256
- onCellValueChanged: handleCellValueChanged,
257
- // Grid Layout event handlers - always attached, but with internal enabled check
258
- onColumnMoved: gridLayout.onColumnMoved,
259
- onDragStopped: gridLayout.onDragStopped, // Handler pro konec drag operace
260
- onColumnResized: gridLayout.onColumnResized,
261
- onColumnVisible: gridLayout.onColumnVisible,
262
- onColumnPinned: gridLayout.onColumnPinned,
263
- getRowId: (params) => params.data.id,
264
- // Grid Layout: maintain column order for proper column reordering
265
- maintainColumnOrder: true,
266
- ...gridOptions,
267
- context: {
268
- componentParent: this,
269
- // Grid Layout context
270
- ...(layoutEnabled && {
271
- gridLayout: {
272
- isLoading: gridLayout.isLoading,
273
- isSaving: gridLayout.isSaving,
274
- hasUnsavedChanges: gridLayout.hasUnsavedChanges,
275
- saveLayout: gridLayout.saveLayout,
276
- resetToDefault: gridLayout.resetToDefault,
277
- reloadLayout: gridLayout.reloadLayout,
278
- openColumnEditor: gridLayout.openColumnEditor // Pro přístup z AG-Grid kontextu
279
- }
280
- })
281
- },
282
- ...props,
283
- ref: gridRef,
284
- // Použijeme pre-transformované columnDefs pro waitForSavedFields mode
285
- columnDefs: AgGridColumns(gridLayout.preTransformedColumnDefs || columnDefs, props),
286
- };
287
-
288
- useImperativeHandle(ref, () => ({
289
- showColumnEditor: () => {
290
- gridLayout.openColumnEditor();
291
- }
292
- }));
293
-
294
- console.log('gridLayout.isColumnEditorOpen', gridLayout.isColumnEditorOpen);
295
- return (
296
- <>
297
- <div className={classnames(appearance)} style={{ height }}>
298
- {gridLayout.shouldShowColumns ? (
299
- <AgGrid
300
- {...allGridProps}
301
- onGridReady={handleGridReady}
302
- />
303
- ) : (
304
- <div style={{
305
- display: 'flex',
306
- justifyContent: 'center',
307
- alignItems: 'center',
308
- height: '100%',
309
- background: '#f5f5f5'
310
- }}>
311
- <div>Načítání sloupců...</div>
312
- </div>
313
- )}
314
- </div>
315
-
316
- {/* Column Editor Modal */}
317
- {gridLayout.isColumnEditorOpen && (
318
- <ColumnEditorModal
319
- open={gridLayout.isColumnEditorOpen}
320
- onCancel={gridLayout.closeColumnEditor}
321
- onSave={gridLayout.saveColumnEditorChanges}
322
- columns={gridLayout.getCurrentColumnsForEditor()}
323
- getContainer={() => document.getElementById('root') || document.body}
324
- zIndex={10000}
325
- />
326
- )}
327
- </>
328
- );
329
- });
330
-
331
- export default Grid;
332
- export * from './enums';
333
- export { default as ColumnBuilder } from './ColumnBuilder';
334
- export { default as ContextBuilder } from './ContextBuilder';
335
- export * as utils from './utils';
336
- export * from './tooltips';
337
- // Grid Layout exports
338
-
339
- /* eslint-enable */
1
+ /* eslint-disable */
2
+ import React, { useCallback, useEffect, useState, useMemo, useImperativeHandle, forwardRef } from 'react';
3
+ import AgGrid from '@bit.rhplus/ag-grid';
4
+ // import { AgGridReact } from 'ag-grid-react';
5
+ import classnames from 'classnames';
6
+ import { OperationType, useSharedGrid } from '@bit.rhplus/shared-grid-form';
7
+ import { AgGridColumns } from './AgGridColumns';
8
+ import { useGridLayout, ColumnEditorModal } from '@bit.rhplus/ui.grid-layout';
9
+ import { useOidcAccessToken } from "@axa-fr/react-oidc";
10
+
11
+ const Grid = React.forwardRef((props, ref) => {
12
+ const gridRef = React.useRef(null);
13
+ const {
14
+ appearance = 'ag-theme-alpine',
15
+ columnDefs,
16
+ height = '100%',
17
+ defaultColDef,
18
+ gridOptions,
19
+ rowClassRules,
20
+ editableDefault = true,
21
+ onRowDoubleClicked,
22
+ // Grid Layout props
23
+ gridName,
24
+ applicationName = 'Portal.App',
25
+ userKey,
26
+ filterName,
27
+ layoutEnabled = true,
28
+ autoSave = true,
29
+ autoSaveDelay = 2000,
30
+ accessToken,
31
+ waitForSavedFields = false, // Nový prop pro odložené zobrazení columnDefs
32
+ onLayoutLoaded,
33
+ onLayoutSaved,
34
+ onLayoutError,
35
+ } = props;
36
+
37
+
38
+ const {
39
+ items,
40
+ onGridReady,
41
+ addItem,
42
+ updateItem,
43
+ deleteItem,
44
+ pendingChanges = [],
45
+ isCellEditable,
46
+ } = useSharedGrid();
47
+
48
+ const [gridApi, setGridApi] = useState(null);
49
+ const [gridLayoutActivated, setGridLayoutActivated] = useState(false);
50
+
51
+ // Konverze columnDefs na array pro Grid Layout - memoizace pro prevenci nekonečné smyčky
52
+ const columnDefsArray = useMemo(() => {
53
+ if (Array.isArray(columnDefs)) {
54
+ return columnDefs;
55
+ }
56
+ // Pokud má build() metodu, je to pravděpodobně ColumnBuilder
57
+ if (columnDefs && typeof columnDefs.build === 'function') {
58
+ return columnDefs.build();
59
+ }
60
+ return [];
61
+ }, [columnDefs]);
62
+
63
+ // Grid Layout Management
64
+ const gridLayout = useGridLayout({
65
+ userKey,
66
+ applicationName,
67
+ gridName,
68
+ filterName,
69
+ enabled: layoutEnabled && !!userKey && !!gridName,
70
+ autoSave,
71
+ autoSaveDelay,
72
+ columnDefs: columnDefsArray,
73
+ accessToken,
74
+ waitForSavedFields, // Nový parametr pro odložené zobrazení
75
+ onLayoutLoaded,
76
+ onLayoutSaved,
77
+ onError: onLayoutError
78
+ });
79
+
80
+ // Handler pro připravení gridu
81
+ const handleGridReady = useCallback(
82
+ (event, options) => {
83
+ setGridApi(event.api);
84
+
85
+ // Modern AG-Grid (33+) fix: columnApi was moved to main api object
86
+ const normalizedEvent = {
87
+ ...event,
88
+ api: event.api,
89
+ columnApi: event.columnApi || event.api // fallback for modern AG-Grid versions
90
+ };
91
+
92
+ // Grid Layout initialization
93
+ if (layoutEnabled && gridLayout.onGridReady && !gridLayoutActivated) {
94
+ gridLayout.onGridReady(normalizedEvent);
95
+ setGridLayoutActivated(true);
96
+ }
97
+
98
+ if (onGridReady) {
99
+ onGridReady(event);
100
+ }
101
+ },
102
+ [onGridReady, layoutEnabled, gridLayout, userKey, gridName]
103
+ );
104
+
105
+ // Effect pro delayed grid layout activation když se layoutEnabled změní na true
106
+ useEffect(() => {
107
+ // Pokud se layoutEnabled změnilo na true a máme již gridApi, aktivujeme grid layout
108
+ if (layoutEnabled && gridApi && gridLayout.onGridReady && !gridLayoutActivated) {
109
+ // Simulujeme onGridReady event pro grid layout
110
+ // Modern AG-Grid (33+) fix: columnApi functionality is in main api
111
+ const mockGridReadyParams = {
112
+ api: gridApi,
113
+ columnApi: gridApi.columnApi || gridApi // fallback for modern AG-Grid versions
114
+ };
115
+
116
+ try {
117
+ gridLayout.onGridReady(mockGridReadyParams);
118
+ setGridLayoutActivated(true);
119
+ } catch (error) {
120
+ // Removed console.error for production
121
+ }
122
+ }
123
+ }, [layoutEnabled, gridApi, gridLayout, userKey, gridName, gridLayoutActivated]);
124
+
125
+ // Handler pro změnu hodnoty buňky
126
+ const handleCellValueChanged = useCallback(
127
+ (params) => {
128
+ const { data, colDef, newValue } = params;
129
+ // Extrahujeme pouze změněné pole
130
+ const changes = { [colDef.field]: newValue };
131
+ updateItem(data.id, changes);
132
+ },
133
+ [updateItem]
134
+ );
135
+
136
+ // Handler pro dvojklik na buňku
137
+ // const handleCellDoubleClicked = useCallback((params) => {
138
+ // const { colDef } = params;
139
+
140
+ // // Pokud je buňka needitovatelná, vyvoláme událost onRowDoubleClicked
141
+ // let isEditable = true;
142
+ // if (typeof colDef.editable === 'function') {
143
+ // isEditable = colDef.editable(params);
144
+ // } else if (typeof colDef.editable === 'boolean') {
145
+ // isEditable = colDef.editable;
146
+ // } else {
147
+ // isEditable = editableDefault;
148
+ // }
149
+
150
+ // // Pokud buňka není editovatelná a máme definován callback pro dvojklik na řádek
151
+ // if (!isEditable && onRowDoubleClicked) {
152
+ // // Simulujeme událost dvojkliku na řádek
153
+ // onRowDoubleClicked({
154
+ // ...params,
155
+ // // Přidáme data, která by normálně obsahovala událost onRowDoubleClicked
156
+ // api: params.api,
157
+ // node: params.node,
158
+ // rowIndex: params.rowIndex,
159
+ // data: params.data,
160
+ // event: params.event
161
+ // });
162
+
163
+ // // Zastavíme výchozí zpracování událostí, aby se nezobrazil editor buňky
164
+ // if (params.event) {
165
+ // params.event.preventDefault();
166
+ // }
167
+ // }
168
+ // }, [onRowDoubleClicked, editableDefault]);
169
+
170
+ // Handler pro přidání nového řádku
171
+ const handleAddRow = useCallback(
172
+ (rowData = {}) => {
173
+ const newItemId = addItem(rowData);
174
+
175
+ // Může být potřeba aktualizovat grid pro zobrazení nového řádku
176
+ if (gridApi) {
177
+ gridApi.setRowData(items);
178
+
179
+ // Volitelně: přejít na nově přidanou položku
180
+ setTimeout(() => {
181
+ const rowNode = gridApi.getRowNode(newItemId);
182
+ if (rowNode) {
183
+ gridApi.ensureNodeVisible(rowNode);
184
+ }
185
+ }, 100);
186
+ }
187
+
188
+ return newItemId;
189
+ },
190
+ [addItem, gridApi, items]
191
+ );
192
+
193
+ // Handler pro odstranění řádku
194
+ const handleDeleteRow = useCallback(
195
+ (id) => {
196
+ deleteItem(id);
197
+
198
+ // Může být potřeba aktualizovat grid
199
+ if (gridApi) {
200
+ gridApi.setRowData(items);
201
+ }
202
+ },
203
+ [deleteItem, gridApi, items]
204
+ );
205
+
206
+ // Vlastní CSS třídy pro řádky s čekajícími změnami
207
+ const defaultRowClassRules = {
208
+ 'row-pending-add': (params) => {
209
+ return (
210
+ pendingChanges[params.data.id] &&
211
+ pendingChanges[params.data.id].operation === OperationType.ADD
212
+ );
213
+ },
214
+ 'row-pending-update': (params) => {
215
+ return (
216
+ pendingChanges[params.data.id] &&
217
+ pendingChanges[params.data.id].operation === OperationType.UPDATE
218
+ );
219
+ },
220
+ 'row-pending-delete': (params) => {
221
+ return (
222
+ pendingChanges[params.data.id] &&
223
+ pendingChanges[params.data.id].operation === OperationType.DELETE
224
+ );
225
+ },
226
+ };
227
+
228
+ // Kombinované rowClassRules
229
+ const combinedRowClassRules = { ...defaultRowClassRules, ...rowClassRules };
230
+
231
+ // Exportovat metody pro přidání/odstranění řádků
232
+ useEffect(() => {
233
+ if (gridApi) {
234
+ // Metody můžeme přidat přímo do gridApi pro použití z vnějšku
235
+ gridApi.addRow = handleAddRow;
236
+ gridApi.deleteRow = handleDeleteRow;
237
+ }
238
+ }, [gridApi, handleAddRow, handleDeleteRow]);
239
+
240
+ const allGridProps = {
241
+ rowData: items,
242
+ defaultColDef: {
243
+ enableCellChangeFlash: true,
244
+ editable: editableDefault,
245
+ resizable: true,
246
+ ...defaultColDef,
247
+ },
248
+ isRowSelectable: (params) => {
249
+ return (
250
+ !pendingChanges[params.data.id] ||
251
+ pendingChanges[params.data.id].operation !== OperationType.DELETE
252
+ );
253
+ },
254
+ isEditable: isCellEditable,
255
+ onGridReady: handleGridReady,
256
+ onCellValueChanged: handleCellValueChanged,
257
+ // Grid Layout event handlers - always attached, but with internal enabled check
258
+ onColumnMoved: gridLayout.onColumnMoved,
259
+ onDragStopped: gridLayout.onDragStopped, // Handler pro konec drag operace
260
+ onColumnResized: gridLayout.onColumnResized,
261
+ onColumnVisible: gridLayout.onColumnVisible,
262
+ onColumnPinned: gridLayout.onColumnPinned,
263
+ getRowId: (params) => params.data.id,
264
+ // Grid Layout: maintain column order for proper column reordering
265
+ maintainColumnOrder: true,
266
+ ...gridOptions,
267
+ context: {
268
+ componentParent: this,
269
+ // Grid Layout context
270
+ ...(layoutEnabled && {
271
+ gridLayout: {
272
+ isLoading: gridLayout.isLoading,
273
+ isSaving: gridLayout.isSaving,
274
+ hasUnsavedChanges: gridLayout.hasUnsavedChanges,
275
+ saveLayout: gridLayout.saveLayout,
276
+ resetToDefault: gridLayout.resetToDefault,
277
+ reloadLayout: gridLayout.reloadLayout,
278
+ openColumnEditor: gridLayout.openColumnEditor // Pro přístup z AG-Grid kontextu
279
+ }
280
+ })
281
+ },
282
+ ...props,
283
+ ref: gridRef,
284
+ // Použijeme pre-transformované columnDefs pro waitForSavedFields mode
285
+ columnDefs: AgGridColumns(gridLayout.preTransformedColumnDefs || columnDefs, props),
286
+ };
287
+
288
+ useImperativeHandle(ref, () => ({
289
+ showColumnEditor: () => {
290
+ gridLayout.openColumnEditor();
291
+ }
292
+ }));
293
+
294
+ // Removed console.log for production
295
+ return (
296
+ <>
297
+ <div className={classnames(appearance)} style={{ height }}>
298
+ {gridLayout.shouldShowColumns ? (
299
+ <AgGrid
300
+ {...allGridProps}
301
+ onGridReady={handleGridReady}
302
+ />
303
+ ) : (
304
+ <div style={{
305
+ display: 'flex',
306
+ justifyContent: 'center',
307
+ alignItems: 'center',
308
+ height: '100%',
309
+ background: '#f5f5f5'
310
+ }}>
311
+ <div>Načítání sloupců...</div>
312
+ </div>
313
+ )}
314
+ </div>
315
+
316
+ {/* Column Editor Modal */}
317
+ {gridLayout.isColumnEditorOpen && (
318
+ <ColumnEditorModal
319
+ open={gridLayout.isColumnEditorOpen}
320
+ onCancel={gridLayout.closeColumnEditor}
321
+ onSave={gridLayout.saveColumnEditorChanges}
322
+ columns={gridLayout.getCurrentColumnsForEditor()}
323
+ getContainer={() => document.getElementById('root') || document.body}
324
+ zIndex={10000}
325
+ />
326
+ )}
327
+ </>
328
+ );
329
+ });
330
+
331
+ export default Grid;
332
+ export * from './enums';
333
+ export { default as ColumnBuilder } from './ColumnBuilder';
334
+ export { default as ContextBuilder } from './ContextBuilder';
335
+ export * as utils from './utils';
336
+ export * from './tooltips';
337
+ // Grid Layout exports
338
+
339
+ /* eslint-enable */