@bit.rhplus/ui.grid 0.0.35 → 0.0.36
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/README-GridLayout.md +273 -0
- package/dist/README-GridLayout.md +273 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +106 -11
- package/dist/index.js.map +1 -1
- package/index.jsx +334 -202
- package/package.json +6 -4
- /package/dist/{preview-1753963210027.js → preview-1754923422987.js} +0 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# 🎛️ Grid Layout Management
|
|
2
|
+
|
|
3
|
+
Automatické ukládání a načítání rozvržení sloupců gridu pomocí Grid API služby.
|
|
4
|
+
|
|
5
|
+
## 📋 Funkcionality
|
|
6
|
+
|
|
7
|
+
- ✅ **Automatické ukládání** rozložení sloupců (šířka, pořadí, viditelnost, připínání)
|
|
8
|
+
- ✅ **Persistence** nastavení napříč relacemi uživatele
|
|
9
|
+
- ✅ **Multi-aplikační podpora** s jasnou separací dat
|
|
10
|
+
- ✅ **Debounced auto-save** pro předcházení častým API voláním
|
|
11
|
+
- ✅ **Error handling** s fallback na default layout
|
|
12
|
+
- ✅ **Manual controls** pro uložení, reset a reload
|
|
13
|
+
|
|
14
|
+
## 🚀 Použití
|
|
15
|
+
|
|
16
|
+
### Základní konfigurace
|
|
17
|
+
|
|
18
|
+
```jsx
|
|
19
|
+
import Grid from '@bit.rhplus/ui.grid';
|
|
20
|
+
|
|
21
|
+
const MyGridComponent = () => {
|
|
22
|
+
const { accessToken } = useOidcAccessToken();
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Grid
|
|
26
|
+
// Standardní Grid props
|
|
27
|
+
columnDefs={columnDefs}
|
|
28
|
+
rowData={rowData}
|
|
29
|
+
|
|
30
|
+
// Grid Layout props
|
|
31
|
+
layoutEnabled={true} // Zapnout layout management
|
|
32
|
+
gridName="invoices-master" // Unikátní název gridu
|
|
33
|
+
applicationName="Portal.App" // Název aplikace (default)
|
|
34
|
+
userKey={currentUser.id} // ID uživatele
|
|
35
|
+
filterName="default" // Volitelný název filtru
|
|
36
|
+
autoSave={true} // Automatické ukládání (default)
|
|
37
|
+
autoSaveDelay={2000} // Zpoždění auto-save v ms
|
|
38
|
+
accessToken={accessToken} // Bearer token
|
|
39
|
+
|
|
40
|
+
// Callback funkce
|
|
41
|
+
onLayoutLoaded={(fields, columnState) => {
|
|
42
|
+
console.log('Layout načten:', fields);
|
|
43
|
+
}}
|
|
44
|
+
onLayoutSaved={(fields, columnState) => {
|
|
45
|
+
console.log('Layout uložen:', fields);
|
|
46
|
+
}}
|
|
47
|
+
onLayoutError={(error, context) => {
|
|
48
|
+
console.error('Grid layout chyba:', error, context);
|
|
49
|
+
}}
|
|
50
|
+
/>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Pokročilé použití s manuálními ovládacími prvky
|
|
56
|
+
|
|
57
|
+
```jsx
|
|
58
|
+
import Grid, { useGridLayout } from '@bit.rhplus/ui.grid';
|
|
59
|
+
|
|
60
|
+
const AdvancedGridComponent = () => {
|
|
61
|
+
const { accessToken } = useOidcAccessToken();
|
|
62
|
+
const [gridApi, setGridApi] = useState(null);
|
|
63
|
+
|
|
64
|
+
// Přímé použití useGridLayout hook
|
|
65
|
+
// POZOR: columnDefs musí být array! Pokud používáte ColumnBuilder, zavolejte .build()
|
|
66
|
+
const columnDefsArray = columnDefs.build ? columnDefs.build() : columnDefs;
|
|
67
|
+
|
|
68
|
+
const gridLayout = useGridLayout({
|
|
69
|
+
userKey: currentUser.id,
|
|
70
|
+
applicationName: 'Portal.App',
|
|
71
|
+
gridName: 'advanced-grid',
|
|
72
|
+
enabled: true,
|
|
73
|
+
autoSave: false, // Manuální ukládání
|
|
74
|
+
columnDefs: columnDefsArray,
|
|
75
|
+
accessToken: accessToken
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const handleSaveLayout = async () => {
|
|
79
|
+
try {
|
|
80
|
+
await gridLayout.saveLayout();
|
|
81
|
+
notification.success('Layout uložen');
|
|
82
|
+
} catch (error) {
|
|
83
|
+
notification.error('Chyba při ukládání layoutu');
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const handleResetLayout = async () => {
|
|
88
|
+
try {
|
|
89
|
+
await gridLayout.resetToDefault();
|
|
90
|
+
notification.info('Layout resetován na výchozí');
|
|
91
|
+
} catch (error) {
|
|
92
|
+
notification.error('Chyba při resetování layoutu');
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<div>
|
|
98
|
+
{/* Ovládací panel */}
|
|
99
|
+
<div style={{ marginBottom: 16 }}>
|
|
100
|
+
<Button
|
|
101
|
+
onClick={handleSaveLayout}
|
|
102
|
+
loading={gridLayout.isSaving}
|
|
103
|
+
disabled={!gridLayout.hasUnsavedChanges}
|
|
104
|
+
>
|
|
105
|
+
Uložit layout
|
|
106
|
+
</Button>
|
|
107
|
+
<Button onClick={handleResetLayout}>
|
|
108
|
+
Resetovat layout
|
|
109
|
+
</Button>
|
|
110
|
+
{gridLayout.hasUnsavedChanges && (
|
|
111
|
+
<span style={{ color: 'orange', marginLeft: 8 }}>
|
|
112
|
+
Neuložené změny
|
|
113
|
+
</span>
|
|
114
|
+
)}
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
{/* Grid s manuálním layoutem */}
|
|
118
|
+
<Grid
|
|
119
|
+
columnDefs={columnDefs}
|
|
120
|
+
rowData={rowData}
|
|
121
|
+
|
|
122
|
+
layoutEnabled={true}
|
|
123
|
+
gridName="advanced-grid"
|
|
124
|
+
userKey={currentUser.id}
|
|
125
|
+
autoSave={false}
|
|
126
|
+
accessToken={accessToken}
|
|
127
|
+
|
|
128
|
+
onGridReady={(params) => {
|
|
129
|
+
setGridApi(params.api);
|
|
130
|
+
gridLayout.onGridReady(params);
|
|
131
|
+
}}
|
|
132
|
+
onColumnMoved={gridLayout.onColumnMoved}
|
|
133
|
+
onColumnResized={gridLayout.onColumnResized}
|
|
134
|
+
onColumnVisible={gridLayout.onColumnVisible}
|
|
135
|
+
onColumnPinned={gridLayout.onColumnPinned}
|
|
136
|
+
/>
|
|
137
|
+
</div>
|
|
138
|
+
);
|
|
139
|
+
};
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## ⚙️ Konfigurace Props
|
|
143
|
+
|
|
144
|
+
| Prop | Type | Default | Popis |
|
|
145
|
+
|------|------|---------|--------|
|
|
146
|
+
| `layoutEnabled` | `boolean` | `false` | Zapnout/vypnout layout management |
|
|
147
|
+
| `gridName` | `string` | **povinné** | Unikátní název gridu pro identifikaci |
|
|
148
|
+
| `applicationName` | `string` | `'Portal.App'` | Název aplikace |
|
|
149
|
+
| `userKey` | `string` | **povinné** | Identifikátor uživatele |
|
|
150
|
+
| `filterName` | `string` | `null` | Volitelný název filtru pro více layoutů |
|
|
151
|
+
| `autoSave` | `boolean` | `true` | Automatické ukládání při změnách |
|
|
152
|
+
| `autoSaveDelay` | `number` | `2000` | Zpoždění auto-save v milisekundách |
|
|
153
|
+
| `accessToken` | `string` | `null` | Bearer token pro API autorizaci |
|
|
154
|
+
|
|
155
|
+
## 📞 Callback Props
|
|
156
|
+
|
|
157
|
+
| Callback | Parametry | Popis |
|
|
158
|
+
|----------|-----------|--------|
|
|
159
|
+
| `onLayoutLoaded` | `(fields, columnState)` | Voláno při úspěšném načtení layoutu |
|
|
160
|
+
| `onLayoutSaved` | `(fields, columnState)` | Voláno při úspěšném uložení layoutu |
|
|
161
|
+
| `onLayoutError` | `(error, context)` | Voláno při chybě v layout managementu |
|
|
162
|
+
|
|
163
|
+
## 🛠️ useGridLayout Hook API
|
|
164
|
+
|
|
165
|
+
```jsx
|
|
166
|
+
const {
|
|
167
|
+
// State
|
|
168
|
+
isLoading, // boolean - načítání dat
|
|
169
|
+
isSaving, // boolean - ukládání layoutu
|
|
170
|
+
error, // Error | null - poslední chyba
|
|
171
|
+
hasUnsavedChanges, // boolean - neuložené změny
|
|
172
|
+
isInitialized, // boolean - layout byl inicializován
|
|
173
|
+
|
|
174
|
+
// AG-Grid event handlers
|
|
175
|
+
onGridReady, // function - AG-Grid onGridReady handler
|
|
176
|
+
onColumnMoved, // function - AG-Grid onColumnMoved handler
|
|
177
|
+
onColumnResized, // function - AG-Grid onColumnResized handler
|
|
178
|
+
onColumnVisible, // function - AG-Grid onColumnVisible handler
|
|
179
|
+
onColumnPinned, // function - AG-Grid onColumnPinned handler
|
|
180
|
+
|
|
181
|
+
// Manual actions
|
|
182
|
+
saveLayout, // function - manuální uložení
|
|
183
|
+
resetToDefault, // function - reset na výchozí layout
|
|
184
|
+
reloadLayout, // function - znovunačtení z API
|
|
185
|
+
|
|
186
|
+
// Data
|
|
187
|
+
savedFields, // Array - uložená pole z API
|
|
188
|
+
|
|
189
|
+
// Utils
|
|
190
|
+
gridLayoutApi // Object - Grid Layout API utils
|
|
191
|
+
} = useGridLayout(config);
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## 🌍 Grid Context
|
|
195
|
+
|
|
196
|
+
Když je layout management zapnutý, Grid komponenta poskytuje context s layout informacemi:
|
|
197
|
+
|
|
198
|
+
```jsx
|
|
199
|
+
// V AG-Grid cell rendereru nebo custom komponentě
|
|
200
|
+
const MyCustomRenderer = (params) => {
|
|
201
|
+
const { gridLayout } = params.context || {};
|
|
202
|
+
|
|
203
|
+
if (gridLayout) {
|
|
204
|
+
const { isLoading, isSaving, hasUnsavedChanges, saveLayout } = gridLayout;
|
|
205
|
+
|
|
206
|
+
return (
|
|
207
|
+
<div>
|
|
208
|
+
{isSaving && <Spin size="small" />}
|
|
209
|
+
{hasUnsavedChanges && <Badge status="warning" />}
|
|
210
|
+
<Button size="small" onClick={saveLayout}>Save</Button>
|
|
211
|
+
</div>
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return <span>{params.value}</span>;
|
|
216
|
+
};
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## 📊 Datový model
|
|
220
|
+
|
|
221
|
+
### Grid API Field Structure
|
|
222
|
+
```javascript
|
|
223
|
+
{
|
|
224
|
+
name: "customerName", // Název pole
|
|
225
|
+
displayName: "Název zákazníka", // Zobrazovaný název
|
|
226
|
+
dataType: "string", // Datový typ
|
|
227
|
+
isVisible: true, // Viditelnost sloupce
|
|
228
|
+
width: 150, // Šířka sloupce
|
|
229
|
+
order: 0, // Pořadí sloupce
|
|
230
|
+
isPinned: null, // Připínání ('left', 'right', null)
|
|
231
|
+
userField: { // Personalizované nastavení
|
|
232
|
+
isVisible: true,
|
|
233
|
+
width: 200,
|
|
234
|
+
order: 1,
|
|
235
|
+
isPinned: "left"
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## 🎯 Best Practices
|
|
241
|
+
|
|
242
|
+
1. **Unikátní gridName**: Každý grid musí mít unikátní název v rámci aplikace
|
|
243
|
+
2. **UserKey konzistence**: Používej konzistentní identifikátor uživatele
|
|
244
|
+
3. **Error handling**: Vždy implementuj `onLayoutError` callback
|
|
245
|
+
4. **AccessToken**: Poskytni access token pro autorizaci API volání
|
|
246
|
+
5. **Debouncing**: Pro časté změny používej vyšší `autoSaveDelay`
|
|
247
|
+
6. **Testing**: Testuj s různými kombinacemi column definitions
|
|
248
|
+
|
|
249
|
+
## 🚨 Troubleshooting
|
|
250
|
+
|
|
251
|
+
### Layout se nenačítá
|
|
252
|
+
- Zkontroluj, že `layoutEnabled={true}`
|
|
253
|
+
- Ověř, že `userKey`, `gridName` a `accessToken` jsou správně nastaveny
|
|
254
|
+
- Zkontroluj network tab pro API chyby
|
|
255
|
+
|
|
256
|
+
### Auto-save nefunguje
|
|
257
|
+
- Ověř, že `autoSave={true}` (default)
|
|
258
|
+
- Zkontroluj, že se spouští AG-Grid eventy (onColumnMoved, onColumnResized)
|
|
259
|
+
- Zkontroluj console pro chyby
|
|
260
|
+
|
|
261
|
+
### Performance problémy
|
|
262
|
+
- Zvyš `autoSaveDelay` pro méně časté ukládání
|
|
263
|
+
- Použij `autoSave={false}` pro manuální kontrolu
|
|
264
|
+
- Implementuj vlastní debouncing v parent komponentě
|
|
265
|
+
|
|
266
|
+
## 📝 Changelog
|
|
267
|
+
|
|
268
|
+
### v1.0.0
|
|
269
|
+
- ✅ Základní grid layout management
|
|
270
|
+
- ✅ Auto-save funkcionalita
|
|
271
|
+
- ✅ Integration s Grid API službou
|
|
272
|
+
- ✅ Error handling a recovery
|
|
273
|
+
- ✅ Manual controls (save, reset, reload)
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# 🎛️ Grid Layout Management
|
|
2
|
+
|
|
3
|
+
Automatické ukládání a načítání rozvržení sloupců gridu pomocí Grid API služby.
|
|
4
|
+
|
|
5
|
+
## 📋 Funkcionality
|
|
6
|
+
|
|
7
|
+
- ✅ **Automatické ukládání** rozložení sloupců (šířka, pořadí, viditelnost, připínání)
|
|
8
|
+
- ✅ **Persistence** nastavení napříč relacemi uživatele
|
|
9
|
+
- ✅ **Multi-aplikační podpora** s jasnou separací dat
|
|
10
|
+
- ✅ **Debounced auto-save** pro předcházení častým API voláním
|
|
11
|
+
- ✅ **Error handling** s fallback na default layout
|
|
12
|
+
- ✅ **Manual controls** pro uložení, reset a reload
|
|
13
|
+
|
|
14
|
+
## 🚀 Použití
|
|
15
|
+
|
|
16
|
+
### Základní konfigurace
|
|
17
|
+
|
|
18
|
+
```jsx
|
|
19
|
+
import Grid from '@bit.rhplus/ui.grid';
|
|
20
|
+
|
|
21
|
+
const MyGridComponent = () => {
|
|
22
|
+
const { accessToken } = useOidcAccessToken();
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Grid
|
|
26
|
+
// Standardní Grid props
|
|
27
|
+
columnDefs={columnDefs}
|
|
28
|
+
rowData={rowData}
|
|
29
|
+
|
|
30
|
+
// Grid Layout props
|
|
31
|
+
layoutEnabled={true} // Zapnout layout management
|
|
32
|
+
gridName="invoices-master" // Unikátní název gridu
|
|
33
|
+
applicationName="Portal.App" // Název aplikace (default)
|
|
34
|
+
userKey={currentUser.id} // ID uživatele
|
|
35
|
+
filterName="default" // Volitelný název filtru
|
|
36
|
+
autoSave={true} // Automatické ukládání (default)
|
|
37
|
+
autoSaveDelay={2000} // Zpoždění auto-save v ms
|
|
38
|
+
accessToken={accessToken} // Bearer token
|
|
39
|
+
|
|
40
|
+
// Callback funkce
|
|
41
|
+
onLayoutLoaded={(fields, columnState) => {
|
|
42
|
+
console.log('Layout načten:', fields);
|
|
43
|
+
}}
|
|
44
|
+
onLayoutSaved={(fields, columnState) => {
|
|
45
|
+
console.log('Layout uložen:', fields);
|
|
46
|
+
}}
|
|
47
|
+
onLayoutError={(error, context) => {
|
|
48
|
+
console.error('Grid layout chyba:', error, context);
|
|
49
|
+
}}
|
|
50
|
+
/>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Pokročilé použití s manuálními ovládacími prvky
|
|
56
|
+
|
|
57
|
+
```jsx
|
|
58
|
+
import Grid, { useGridLayout } from '@bit.rhplus/ui.grid';
|
|
59
|
+
|
|
60
|
+
const AdvancedGridComponent = () => {
|
|
61
|
+
const { accessToken } = useOidcAccessToken();
|
|
62
|
+
const [gridApi, setGridApi] = useState(null);
|
|
63
|
+
|
|
64
|
+
// Přímé použití useGridLayout hook
|
|
65
|
+
// POZOR: columnDefs musí být array! Pokud používáte ColumnBuilder, zavolejte .build()
|
|
66
|
+
const columnDefsArray = columnDefs.build ? columnDefs.build() : columnDefs;
|
|
67
|
+
|
|
68
|
+
const gridLayout = useGridLayout({
|
|
69
|
+
userKey: currentUser.id,
|
|
70
|
+
applicationName: 'Portal.App',
|
|
71
|
+
gridName: 'advanced-grid',
|
|
72
|
+
enabled: true,
|
|
73
|
+
autoSave: false, // Manuální ukládání
|
|
74
|
+
columnDefs: columnDefsArray,
|
|
75
|
+
accessToken: accessToken
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const handleSaveLayout = async () => {
|
|
79
|
+
try {
|
|
80
|
+
await gridLayout.saveLayout();
|
|
81
|
+
notification.success('Layout uložen');
|
|
82
|
+
} catch (error) {
|
|
83
|
+
notification.error('Chyba při ukládání layoutu');
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const handleResetLayout = async () => {
|
|
88
|
+
try {
|
|
89
|
+
await gridLayout.resetToDefault();
|
|
90
|
+
notification.info('Layout resetován na výchozí');
|
|
91
|
+
} catch (error) {
|
|
92
|
+
notification.error('Chyba při resetování layoutu');
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<div>
|
|
98
|
+
{/* Ovládací panel */}
|
|
99
|
+
<div style={{ marginBottom: 16 }}>
|
|
100
|
+
<Button
|
|
101
|
+
onClick={handleSaveLayout}
|
|
102
|
+
loading={gridLayout.isSaving}
|
|
103
|
+
disabled={!gridLayout.hasUnsavedChanges}
|
|
104
|
+
>
|
|
105
|
+
Uložit layout
|
|
106
|
+
</Button>
|
|
107
|
+
<Button onClick={handleResetLayout}>
|
|
108
|
+
Resetovat layout
|
|
109
|
+
</Button>
|
|
110
|
+
{gridLayout.hasUnsavedChanges && (
|
|
111
|
+
<span style={{ color: 'orange', marginLeft: 8 }}>
|
|
112
|
+
Neuložené změny
|
|
113
|
+
</span>
|
|
114
|
+
)}
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
{/* Grid s manuálním layoutem */}
|
|
118
|
+
<Grid
|
|
119
|
+
columnDefs={columnDefs}
|
|
120
|
+
rowData={rowData}
|
|
121
|
+
|
|
122
|
+
layoutEnabled={true}
|
|
123
|
+
gridName="advanced-grid"
|
|
124
|
+
userKey={currentUser.id}
|
|
125
|
+
autoSave={false}
|
|
126
|
+
accessToken={accessToken}
|
|
127
|
+
|
|
128
|
+
onGridReady={(params) => {
|
|
129
|
+
setGridApi(params.api);
|
|
130
|
+
gridLayout.onGridReady(params);
|
|
131
|
+
}}
|
|
132
|
+
onColumnMoved={gridLayout.onColumnMoved}
|
|
133
|
+
onColumnResized={gridLayout.onColumnResized}
|
|
134
|
+
onColumnVisible={gridLayout.onColumnVisible}
|
|
135
|
+
onColumnPinned={gridLayout.onColumnPinned}
|
|
136
|
+
/>
|
|
137
|
+
</div>
|
|
138
|
+
);
|
|
139
|
+
};
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## ⚙️ Konfigurace Props
|
|
143
|
+
|
|
144
|
+
| Prop | Type | Default | Popis |
|
|
145
|
+
|------|------|---------|--------|
|
|
146
|
+
| `layoutEnabled` | `boolean` | `false` | Zapnout/vypnout layout management |
|
|
147
|
+
| `gridName` | `string` | **povinné** | Unikátní název gridu pro identifikaci |
|
|
148
|
+
| `applicationName` | `string` | `'Portal.App'` | Název aplikace |
|
|
149
|
+
| `userKey` | `string` | **povinné** | Identifikátor uživatele |
|
|
150
|
+
| `filterName` | `string` | `null` | Volitelný název filtru pro více layoutů |
|
|
151
|
+
| `autoSave` | `boolean` | `true` | Automatické ukládání při změnách |
|
|
152
|
+
| `autoSaveDelay` | `number` | `2000` | Zpoždění auto-save v milisekundách |
|
|
153
|
+
| `accessToken` | `string` | `null` | Bearer token pro API autorizaci |
|
|
154
|
+
|
|
155
|
+
## 📞 Callback Props
|
|
156
|
+
|
|
157
|
+
| Callback | Parametry | Popis |
|
|
158
|
+
|----------|-----------|--------|
|
|
159
|
+
| `onLayoutLoaded` | `(fields, columnState)` | Voláno při úspěšném načtení layoutu |
|
|
160
|
+
| `onLayoutSaved` | `(fields, columnState)` | Voláno při úspěšném uložení layoutu |
|
|
161
|
+
| `onLayoutError` | `(error, context)` | Voláno při chybě v layout managementu |
|
|
162
|
+
|
|
163
|
+
## 🛠️ useGridLayout Hook API
|
|
164
|
+
|
|
165
|
+
```jsx
|
|
166
|
+
const {
|
|
167
|
+
// State
|
|
168
|
+
isLoading, // boolean - načítání dat
|
|
169
|
+
isSaving, // boolean - ukládání layoutu
|
|
170
|
+
error, // Error | null - poslední chyba
|
|
171
|
+
hasUnsavedChanges, // boolean - neuložené změny
|
|
172
|
+
isInitialized, // boolean - layout byl inicializován
|
|
173
|
+
|
|
174
|
+
// AG-Grid event handlers
|
|
175
|
+
onGridReady, // function - AG-Grid onGridReady handler
|
|
176
|
+
onColumnMoved, // function - AG-Grid onColumnMoved handler
|
|
177
|
+
onColumnResized, // function - AG-Grid onColumnResized handler
|
|
178
|
+
onColumnVisible, // function - AG-Grid onColumnVisible handler
|
|
179
|
+
onColumnPinned, // function - AG-Grid onColumnPinned handler
|
|
180
|
+
|
|
181
|
+
// Manual actions
|
|
182
|
+
saveLayout, // function - manuální uložení
|
|
183
|
+
resetToDefault, // function - reset na výchozí layout
|
|
184
|
+
reloadLayout, // function - znovunačtení z API
|
|
185
|
+
|
|
186
|
+
// Data
|
|
187
|
+
savedFields, // Array - uložená pole z API
|
|
188
|
+
|
|
189
|
+
// Utils
|
|
190
|
+
gridLayoutApi // Object - Grid Layout API utils
|
|
191
|
+
} = useGridLayout(config);
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## 🌍 Grid Context
|
|
195
|
+
|
|
196
|
+
Když je layout management zapnutý, Grid komponenta poskytuje context s layout informacemi:
|
|
197
|
+
|
|
198
|
+
```jsx
|
|
199
|
+
// V AG-Grid cell rendereru nebo custom komponentě
|
|
200
|
+
const MyCustomRenderer = (params) => {
|
|
201
|
+
const { gridLayout } = params.context || {};
|
|
202
|
+
|
|
203
|
+
if (gridLayout) {
|
|
204
|
+
const { isLoading, isSaving, hasUnsavedChanges, saveLayout } = gridLayout;
|
|
205
|
+
|
|
206
|
+
return (
|
|
207
|
+
<div>
|
|
208
|
+
{isSaving && <Spin size="small" />}
|
|
209
|
+
{hasUnsavedChanges && <Badge status="warning" />}
|
|
210
|
+
<Button size="small" onClick={saveLayout}>Save</Button>
|
|
211
|
+
</div>
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return <span>{params.value}</span>;
|
|
216
|
+
};
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## 📊 Datový model
|
|
220
|
+
|
|
221
|
+
### Grid API Field Structure
|
|
222
|
+
```javascript
|
|
223
|
+
{
|
|
224
|
+
name: "customerName", // Název pole
|
|
225
|
+
displayName: "Název zákazníka", // Zobrazovaný název
|
|
226
|
+
dataType: "string", // Datový typ
|
|
227
|
+
isVisible: true, // Viditelnost sloupce
|
|
228
|
+
width: 150, // Šířka sloupce
|
|
229
|
+
order: 0, // Pořadí sloupce
|
|
230
|
+
isPinned: null, // Připínání ('left', 'right', null)
|
|
231
|
+
userField: { // Personalizované nastavení
|
|
232
|
+
isVisible: true,
|
|
233
|
+
width: 200,
|
|
234
|
+
order: 1,
|
|
235
|
+
isPinned: "left"
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## 🎯 Best Practices
|
|
241
|
+
|
|
242
|
+
1. **Unikátní gridName**: Každý grid musí mít unikátní název v rámci aplikace
|
|
243
|
+
2. **UserKey konzistence**: Používej konzistentní identifikátor uživatele
|
|
244
|
+
3. **Error handling**: Vždy implementuj `onLayoutError` callback
|
|
245
|
+
4. **AccessToken**: Poskytni access token pro autorizaci API volání
|
|
246
|
+
5. **Debouncing**: Pro časté změny používej vyšší `autoSaveDelay`
|
|
247
|
+
6. **Testing**: Testuj s různými kombinacemi column definitions
|
|
248
|
+
|
|
249
|
+
## 🚨 Troubleshooting
|
|
250
|
+
|
|
251
|
+
### Layout se nenačítá
|
|
252
|
+
- Zkontroluj, že `layoutEnabled={true}`
|
|
253
|
+
- Ověř, že `userKey`, `gridName` a `accessToken` jsou správně nastaveny
|
|
254
|
+
- Zkontroluj network tab pro API chyby
|
|
255
|
+
|
|
256
|
+
### Auto-save nefunguje
|
|
257
|
+
- Ověř, že `autoSave={true}` (default)
|
|
258
|
+
- Zkontroluj, že se spouští AG-Grid eventy (onColumnMoved, onColumnResized)
|
|
259
|
+
- Zkontroluj console pro chyby
|
|
260
|
+
|
|
261
|
+
### Performance problémy
|
|
262
|
+
- Zvyš `autoSaveDelay` pro méně časté ukládání
|
|
263
|
+
- Použij `autoSave={false}` pro manuální kontrolu
|
|
264
|
+
- Implementuj vlastní debouncing v parent komponentě
|
|
265
|
+
|
|
266
|
+
## 📝 Changelog
|
|
267
|
+
|
|
268
|
+
### v1.0.0
|
|
269
|
+
- ✅ Základní grid layout management
|
|
270
|
+
- ✅ Auto-save funkcionalita
|
|
271
|
+
- ✅ Integration s Grid API službou
|
|
272
|
+
- ✅ Error handling a recovery
|
|
273
|
+
- ✅ Manual controls (save, reset, reload)
|
package/dist/index.d.ts
CHANGED
|
@@ -4,4 +4,5 @@ export * from "./tooltips";
|
|
|
4
4
|
export { default as ColumnBuilder } from "./ColumnBuilder";
|
|
5
5
|
export { default as ContextBuilder } from "./ContextBuilder";
|
|
6
6
|
export * as utils from "./utils";
|
|
7
|
-
declare
|
|
7
|
+
declare const Grid: React.ForwardRefExoticComponent<React.RefAttributes<any>>;
|
|
8
|
+
import React from 'react';
|
package/dist/index.js
CHANGED
|
@@ -1,23 +1,86 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/* eslint-disable */
|
|
3
|
-
import React, { useCallback, useEffect, useState } from 'react';
|
|
3
|
+
import React, { useCallback, useEffect, useState, useMemo, useImperativeHandle, forwardRef } from 'react';
|
|
4
4
|
import AgGrid from '@bit.rhplus/ag-grid';
|
|
5
5
|
// import { AgGridReact } from 'ag-grid-react';
|
|
6
6
|
import classnames from 'classnames';
|
|
7
7
|
import { OperationType, useSharedGrid } from '@bit.rhplus/shared-grid-form';
|
|
8
8
|
import { AgGridColumns } from './AgGridColumns';
|
|
9
|
-
|
|
9
|
+
import { useGridLayout, ColumnEditorModal } from '@bit.rhplus/ui.grid-layout';
|
|
10
|
+
import { useOidcAccessToken } from "@axa-fr/react-oidc";
|
|
11
|
+
const Grid = React.forwardRef((props, ref) => {
|
|
10
12
|
const gridRef = React.useRef(null);
|
|
11
|
-
const { appearance = 'ag-theme-alpine', columnDefs, height = '100%', defaultColDef, gridOptions, rowClassRules, editableDefault = true, onRowDoubleClicked,
|
|
13
|
+
const { appearance = 'ag-theme-alpine', columnDefs, height = '100%', defaultColDef, gridOptions, rowClassRules, editableDefault = true, onRowDoubleClicked,
|
|
14
|
+
// Grid Layout props
|
|
15
|
+
gridName, applicationName = 'Portal.App', userKey, filterName, layoutEnabled = true, autoSave = true, autoSaveDelay = 2000, accessToken, waitForSavedFields = false, // Nový prop pro odložené zobrazení columnDefs
|
|
16
|
+
onLayoutLoaded, onLayoutSaved, onLayoutError, } = props;
|
|
12
17
|
const { items, onGridReady, addItem, updateItem, deleteItem, pendingChanges = [], isCellEditable, } = useSharedGrid();
|
|
13
18
|
const [gridApi, setGridApi] = useState(null);
|
|
19
|
+
const [gridLayoutActivated, setGridLayoutActivated] = useState(false);
|
|
20
|
+
// Konverze columnDefs na array pro Grid Layout - memoizace pro prevenci nekonečné smyčky
|
|
21
|
+
const columnDefsArray = useMemo(() => {
|
|
22
|
+
if (Array.isArray(columnDefs)) {
|
|
23
|
+
return columnDefs;
|
|
24
|
+
}
|
|
25
|
+
// Pokud má build() metodu, je to pravděpodobně ColumnBuilder
|
|
26
|
+
if (columnDefs && typeof columnDefs.build === 'function') {
|
|
27
|
+
return columnDefs.build();
|
|
28
|
+
}
|
|
29
|
+
return [];
|
|
30
|
+
}, [columnDefs]);
|
|
31
|
+
// Grid Layout Management
|
|
32
|
+
const gridLayout = useGridLayout({
|
|
33
|
+
userKey,
|
|
34
|
+
applicationName,
|
|
35
|
+
gridName,
|
|
36
|
+
filterName,
|
|
37
|
+
enabled: layoutEnabled && !!userKey && !!gridName,
|
|
38
|
+
autoSave,
|
|
39
|
+
autoSaveDelay,
|
|
40
|
+
columnDefs: columnDefsArray,
|
|
41
|
+
accessToken,
|
|
42
|
+
waitForSavedFields, // Nový parametr pro odložené zobrazení
|
|
43
|
+
onLayoutLoaded,
|
|
44
|
+
onLayoutSaved,
|
|
45
|
+
onError: onLayoutError
|
|
46
|
+
});
|
|
14
47
|
// Handler pro připravení gridu
|
|
15
|
-
const handleGridReady = useCallback((
|
|
16
|
-
setGridApi(
|
|
48
|
+
const handleGridReady = useCallback((event, options) => {
|
|
49
|
+
setGridApi(event.api);
|
|
50
|
+
// Modern AG-Grid (33+) fix: columnApi was moved to main api object
|
|
51
|
+
const normalizedEvent = {
|
|
52
|
+
...event,
|
|
53
|
+
api: event.api,
|
|
54
|
+
columnApi: event.columnApi || event.api // fallback for modern AG-Grid versions
|
|
55
|
+
};
|
|
56
|
+
// Grid Layout initialization
|
|
57
|
+
if (layoutEnabled && gridLayout.onGridReady && !gridLayoutActivated) {
|
|
58
|
+
gridLayout.onGridReady(normalizedEvent);
|
|
59
|
+
setGridLayoutActivated(true);
|
|
60
|
+
}
|
|
17
61
|
if (onGridReady) {
|
|
18
|
-
onGridReady(
|
|
62
|
+
onGridReady(event);
|
|
19
63
|
}
|
|
20
|
-
}, [onGridReady]);
|
|
64
|
+
}, [onGridReady, layoutEnabled, gridLayout, userKey, gridName]);
|
|
65
|
+
// Effect pro delayed grid layout activation když se layoutEnabled změní na true
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
// Pokud se layoutEnabled změnilo na true a máme již gridApi, aktivujeme grid layout
|
|
68
|
+
if (layoutEnabled && gridApi && gridLayout.onGridReady && !gridLayoutActivated) {
|
|
69
|
+
// Simulujeme onGridReady event pro grid layout
|
|
70
|
+
// Modern AG-Grid (33+) fix: columnApi functionality is in main api
|
|
71
|
+
const mockGridReadyParams = {
|
|
72
|
+
api: gridApi,
|
|
73
|
+
columnApi: gridApi.columnApi || gridApi // fallback for modern AG-Grid versions
|
|
74
|
+
};
|
|
75
|
+
try {
|
|
76
|
+
gridLayout.onGridReady(mockGridReadyParams);
|
|
77
|
+
setGridLayoutActivated(true);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
console.error('❌ UI/Grid: Error in delayed grid layout activation:', error);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}, [layoutEnabled, gridApi, gridLayout, userKey, gridName, gridLayoutActivated]);
|
|
21
84
|
// Handler pro změnu hodnoty buňky
|
|
22
85
|
const handleCellValueChanged = useCallback((params) => {
|
|
23
86
|
const { data, colDef, newValue } = params;
|
|
@@ -119,17 +182,49 @@ const Grid = (props) => {
|
|
|
119
182
|
isEditable: isCellEditable,
|
|
120
183
|
onGridReady: handleGridReady,
|
|
121
184
|
onCellValueChanged: handleCellValueChanged,
|
|
185
|
+
// Grid Layout event handlers - always attached, but with internal enabled check
|
|
186
|
+
onColumnMoved: gridLayout.onColumnMoved,
|
|
187
|
+
onDragStopped: gridLayout.onDragStopped, // Handler pro konec drag operace
|
|
188
|
+
onColumnResized: gridLayout.onColumnResized,
|
|
189
|
+
onColumnVisible: gridLayout.onColumnVisible,
|
|
190
|
+
onColumnPinned: gridLayout.onColumnPinned,
|
|
122
191
|
getRowId: (params) => params.data.id,
|
|
192
|
+
// Grid Layout: maintain column order for proper column reordering
|
|
193
|
+
maintainColumnOrder: true,
|
|
123
194
|
...gridOptions,
|
|
124
195
|
context: {
|
|
125
196
|
componentParent: this,
|
|
197
|
+
// Grid Layout context
|
|
198
|
+
...(layoutEnabled && {
|
|
199
|
+
gridLayout: {
|
|
200
|
+
isLoading: gridLayout.isLoading,
|
|
201
|
+
isSaving: gridLayout.isSaving,
|
|
202
|
+
hasUnsavedChanges: gridLayout.hasUnsavedChanges,
|
|
203
|
+
saveLayout: gridLayout.saveLayout,
|
|
204
|
+
resetToDefault: gridLayout.resetToDefault,
|
|
205
|
+
reloadLayout: gridLayout.reloadLayout,
|
|
206
|
+
openColumnEditor: gridLayout.openColumnEditor // Pro přístup z AG-Grid kontextu
|
|
207
|
+
}
|
|
208
|
+
})
|
|
126
209
|
},
|
|
127
210
|
...props,
|
|
128
211
|
ref: gridRef,
|
|
129
|
-
|
|
212
|
+
// Použijeme pre-transformované columnDefs pro waitForSavedFields mode
|
|
213
|
+
columnDefs: AgGridColumns(gridLayout.preTransformedColumnDefs || columnDefs, props),
|
|
130
214
|
};
|
|
131
|
-
|
|
132
|
-
|
|
215
|
+
useImperativeHandle(ref, () => ({
|
|
216
|
+
showColumnEditor: () => {
|
|
217
|
+
gridLayout.openColumnEditor();
|
|
218
|
+
}
|
|
219
|
+
}));
|
|
220
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: classnames(appearance), style: { height }, children: gridLayout.shouldShowColumns ? (_jsx(AgGrid, { ...allGridProps, onGridReady: handleGridReady })) : (_jsx("div", { style: {
|
|
221
|
+
display: 'flex',
|
|
222
|
+
justifyContent: 'center',
|
|
223
|
+
alignItems: 'center',
|
|
224
|
+
height: '100%',
|
|
225
|
+
background: '#f5f5f5'
|
|
226
|
+
}, children: _jsx("div", { children: "Na\u010D\u00EDt\u00E1n\u00ED sloupc\u016F..." }) })) }), _jsx(ColumnEditorModal, { open: gridLayout.isColumnEditorOpen, onCancel: gridLayout.closeColumnEditor, onSave: gridLayout.saveColumnEditorChanges, columns: gridLayout.columnDefs })] }));
|
|
227
|
+
});
|
|
133
228
|
export default Grid;
|
|
134
229
|
export * from './enums';
|
|
135
230
|
export { default as ColumnBuilder } from './ColumnBuilder';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.jsx"],"names":[],"mappings":";AAAA,oBAAoB;AACpB,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.jsx"],"names":[],"mappings":"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"}
|
package/index.jsx
CHANGED
|
@@ -1,202 +1,334 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
import React, { useCallback, useEffect, useState } 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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
//
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
);
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
+
return (
|
|
295
|
+
<>
|
|
296
|
+
<div className={classnames(appearance)} style={{ height }}>
|
|
297
|
+
{gridLayout.shouldShowColumns ? (
|
|
298
|
+
<AgGrid
|
|
299
|
+
{...allGridProps}
|
|
300
|
+
onGridReady={handleGridReady}
|
|
301
|
+
/>
|
|
302
|
+
) : (
|
|
303
|
+
<div style={{
|
|
304
|
+
display: 'flex',
|
|
305
|
+
justifyContent: 'center',
|
|
306
|
+
alignItems: 'center',
|
|
307
|
+
height: '100%',
|
|
308
|
+
background: '#f5f5f5'
|
|
309
|
+
}}>
|
|
310
|
+
<div>Načítání sloupců...</div>
|
|
311
|
+
</div>
|
|
312
|
+
)}
|
|
313
|
+
</div>
|
|
314
|
+
|
|
315
|
+
{/* Column Editor Modal */}
|
|
316
|
+
<ColumnEditorModal
|
|
317
|
+
open={gridLayout.isColumnEditorOpen}
|
|
318
|
+
onCancel={gridLayout.closeColumnEditor}
|
|
319
|
+
onSave={gridLayout.saveColumnEditorChanges}
|
|
320
|
+
columns={gridLayout.columnDefs}
|
|
321
|
+
/>
|
|
322
|
+
</>
|
|
323
|
+
);
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
export default Grid;
|
|
327
|
+
export * from './enums';
|
|
328
|
+
export { default as ColumnBuilder } from './ColumnBuilder';
|
|
329
|
+
export { default as ContextBuilder } from './ContextBuilder';
|
|
330
|
+
export * as utils from './utils';
|
|
331
|
+
export * from './tooltips';
|
|
332
|
+
// Grid Layout exports
|
|
333
|
+
|
|
334
|
+
/* eslint-enable */
|
package/package.json
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bit.rhplus/ui.grid",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.36",
|
|
4
4
|
"homepage": "https://bit.cloud/remote-scope/ui/grid",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"componentId": {
|
|
7
7
|
"scope": "remote-scope",
|
|
8
8
|
"name": "ui/grid",
|
|
9
|
-
"version": "0.0.
|
|
9
|
+
"version": "0.0.36"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"antd": "^5.20.6",
|
|
13
13
|
"lucide-react": "^0.503.0",
|
|
14
|
+
"@axa-fr/react-oidc": "7.25.13",
|
|
14
15
|
"classnames": "^2.5.1",
|
|
15
|
-
"@bit.rhplus/ag-grid": "0.0.
|
|
16
|
-
"@bit.rhplus/shared-grid-form": "0.0.7"
|
|
16
|
+
"@bit.rhplus/ag-grid": "0.0.31",
|
|
17
|
+
"@bit.rhplus/shared-grid-form": "0.0.7",
|
|
18
|
+
"@bit.rhplus/ui.grid-layout": "0.0.1"
|
|
17
19
|
},
|
|
18
20
|
"devDependencies": {
|
|
19
21
|
"@teambit/react.react-env": "1.0.132"
|
|
File without changes
|