@bit.rhplus/ui.grid 0.0.38 → 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/ColumnBuilder.jsx +1 -1
- package/README-GridLayout.md +270 -272
- package/dist/ColumnBuilder.js +1 -1
- package/dist/ColumnBuilder.js.map +1 -1
- package/dist/README-GridLayout.md +270 -272
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/index.jsx +339 -339
- package/package.json +4 -4
- /package/dist/{preview-1755033542068.js → preview-1755777309104.js} +0 -0
package/ColumnBuilder.jsx
CHANGED
|
@@ -875,7 +875,7 @@ class ColumnBuilder {
|
|
|
875
875
|
setCurrentMenuItems(updatedMenuItems);
|
|
876
876
|
}
|
|
877
877
|
} catch (error) {
|
|
878
|
-
console.error
|
|
878
|
+
// Removed console.error for production
|
|
879
879
|
if (isMountedRef.current) {
|
|
880
880
|
setCurrentMenuItems(menuItems);
|
|
881
881
|
}
|
package/README-GridLayout.md
CHANGED
|
@@ -1,273 +1,271 @@
|
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
notification.
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
notification.
|
|
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
|
-
// AG-Grid
|
|
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
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
- Zkontroluj
|
|
253
|
-
|
|
254
|
-
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
- ✅
|
|
270
|
-
- ✅
|
|
271
|
-
- ✅ Integration s Grid API službou
|
|
272
|
-
- ✅ Error handling a recovery
|
|
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
|
+
}}
|
|
43
|
+
onLayoutSaved={(fields, columnState) => {
|
|
44
|
+
}}
|
|
45
|
+
onLayoutError={(error, context) => {
|
|
46
|
+
console.error('Grid layout chyba:', error, context);
|
|
47
|
+
}}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Pokročilé použití s manuálními ovládacími prvky
|
|
54
|
+
|
|
55
|
+
```jsx
|
|
56
|
+
import Grid, { useGridLayout } from '@bit.rhplus/ui.grid';
|
|
57
|
+
|
|
58
|
+
const AdvancedGridComponent = () => {
|
|
59
|
+
const { accessToken } = useOidcAccessToken();
|
|
60
|
+
const [gridApi, setGridApi] = useState(null);
|
|
61
|
+
|
|
62
|
+
// Přímé použití useGridLayout hook
|
|
63
|
+
// POZOR: columnDefs musí být array! Pokud používáte ColumnBuilder, zavolejte .build()
|
|
64
|
+
const columnDefsArray = columnDefs.build ? columnDefs.build() : columnDefs;
|
|
65
|
+
|
|
66
|
+
const gridLayout = useGridLayout({
|
|
67
|
+
userKey: currentUser.id,
|
|
68
|
+
applicationName: 'Portal.App',
|
|
69
|
+
gridName: 'advanced-grid',
|
|
70
|
+
enabled: true,
|
|
71
|
+
autoSave: false, // Manuální ukládání
|
|
72
|
+
columnDefs: columnDefsArray,
|
|
73
|
+
accessToken: accessToken
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const handleSaveLayout = async () => {
|
|
77
|
+
try {
|
|
78
|
+
await gridLayout.saveLayout();
|
|
79
|
+
notification.success('Layout uložen');
|
|
80
|
+
} catch (error) {
|
|
81
|
+
notification.error('Chyba při ukládání layoutu');
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const handleResetLayout = async () => {
|
|
86
|
+
try {
|
|
87
|
+
await gridLayout.resetToDefault();
|
|
88
|
+
notification.info('Layout resetován na výchozí');
|
|
89
|
+
} catch (error) {
|
|
90
|
+
notification.error('Chyba při resetování layoutu');
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<div>
|
|
96
|
+
{/* Ovládací panel */}
|
|
97
|
+
<div style={{ marginBottom: 16 }}>
|
|
98
|
+
<Button
|
|
99
|
+
onClick={handleSaveLayout}
|
|
100
|
+
loading={gridLayout.isSaving}
|
|
101
|
+
disabled={!gridLayout.hasUnsavedChanges}
|
|
102
|
+
>
|
|
103
|
+
Uložit layout
|
|
104
|
+
</Button>
|
|
105
|
+
<Button onClick={handleResetLayout}>
|
|
106
|
+
Resetovat layout
|
|
107
|
+
</Button>
|
|
108
|
+
{gridLayout.hasUnsavedChanges && (
|
|
109
|
+
<span style={{ color: 'orange', marginLeft: 8 }}>
|
|
110
|
+
Neuložené změny
|
|
111
|
+
</span>
|
|
112
|
+
)}
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
{/* Grid s manuálním layoutem */}
|
|
116
|
+
<Grid
|
|
117
|
+
columnDefs={columnDefs}
|
|
118
|
+
rowData={rowData}
|
|
119
|
+
|
|
120
|
+
layoutEnabled={true}
|
|
121
|
+
gridName="advanced-grid"
|
|
122
|
+
userKey={currentUser.id}
|
|
123
|
+
autoSave={false}
|
|
124
|
+
accessToken={accessToken}
|
|
125
|
+
|
|
126
|
+
onGridReady={(params) => {
|
|
127
|
+
setGridApi(params.api);
|
|
128
|
+
gridLayout.onGridReady(params);
|
|
129
|
+
}}
|
|
130
|
+
onColumnMoved={gridLayout.onColumnMoved}
|
|
131
|
+
onColumnResized={gridLayout.onColumnResized}
|
|
132
|
+
onColumnVisible={gridLayout.onColumnVisible}
|
|
133
|
+
onColumnPinned={gridLayout.onColumnPinned}
|
|
134
|
+
/>
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
137
|
+
};
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## ⚙️ Konfigurace Props
|
|
141
|
+
|
|
142
|
+
| Prop | Type | Default | Popis |
|
|
143
|
+
|------|------|---------|--------|
|
|
144
|
+
| `layoutEnabled` | `boolean` | `false` | Zapnout/vypnout layout management |
|
|
145
|
+
| `gridName` | `string` | **povinné** | Unikátní název gridu pro identifikaci |
|
|
146
|
+
| `applicationName` | `string` | `'Portal.App'` | Název aplikace |
|
|
147
|
+
| `userKey` | `string` | **povinné** | Identifikátor uživatele |
|
|
148
|
+
| `filterName` | `string` | `null` | Volitelný název filtru pro více layoutů |
|
|
149
|
+
| `autoSave` | `boolean` | `true` | Automatické ukládání při změnách |
|
|
150
|
+
| `autoSaveDelay` | `number` | `2000` | Zpoždění auto-save v milisekundách |
|
|
151
|
+
| `accessToken` | `string` | `null` | Bearer token pro API autorizaci |
|
|
152
|
+
|
|
153
|
+
## 📞 Callback Props
|
|
154
|
+
|
|
155
|
+
| Callback | Parametry | Popis |
|
|
156
|
+
|----------|-----------|--------|
|
|
157
|
+
| `onLayoutLoaded` | `(fields, columnState)` | Voláno při úspěšném načtení layoutu |
|
|
158
|
+
| `onLayoutSaved` | `(fields, columnState)` | Voláno při úspěšném uložení layoutu |
|
|
159
|
+
| `onLayoutError` | `(error, context)` | Voláno při chybě v layout managementu |
|
|
160
|
+
|
|
161
|
+
## 🛠️ useGridLayout Hook API
|
|
162
|
+
|
|
163
|
+
```jsx
|
|
164
|
+
const {
|
|
165
|
+
// State
|
|
166
|
+
isLoading, // boolean - načítání dat
|
|
167
|
+
isSaving, // boolean - ukládání layoutu
|
|
168
|
+
error, // Error | null - poslední chyba
|
|
169
|
+
hasUnsavedChanges, // boolean - neuložené změny
|
|
170
|
+
isInitialized, // boolean - layout byl inicializován
|
|
171
|
+
|
|
172
|
+
// AG-Grid event handlers
|
|
173
|
+
onGridReady, // function - AG-Grid onGridReady handler
|
|
174
|
+
onColumnMoved, // function - AG-Grid onColumnMoved handler
|
|
175
|
+
onColumnResized, // function - AG-Grid onColumnResized handler
|
|
176
|
+
onColumnVisible, // function - AG-Grid onColumnVisible handler
|
|
177
|
+
onColumnPinned, // function - AG-Grid onColumnPinned handler
|
|
178
|
+
|
|
179
|
+
// Manual actions
|
|
180
|
+
saveLayout, // function - manuální uložení
|
|
181
|
+
resetToDefault, // function - reset na výchozí layout
|
|
182
|
+
reloadLayout, // function - znovunačtení z API
|
|
183
|
+
|
|
184
|
+
// Data
|
|
185
|
+
savedFields, // Array - uložená pole z API
|
|
186
|
+
|
|
187
|
+
// Utils
|
|
188
|
+
gridLayoutApi // Object - Grid Layout API utils
|
|
189
|
+
} = useGridLayout(config);
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## 🌍 Grid Context
|
|
193
|
+
|
|
194
|
+
Když je layout management zapnutý, Grid komponenta poskytuje context s layout informacemi:
|
|
195
|
+
|
|
196
|
+
```jsx
|
|
197
|
+
// V AG-Grid cell rendereru nebo custom komponentě
|
|
198
|
+
const MyCustomRenderer = (params) => {
|
|
199
|
+
const { gridLayout } = params.context || {};
|
|
200
|
+
|
|
201
|
+
if (gridLayout) {
|
|
202
|
+
const { isLoading, isSaving, hasUnsavedChanges, saveLayout } = gridLayout;
|
|
203
|
+
|
|
204
|
+
return (
|
|
205
|
+
<div>
|
|
206
|
+
{isSaving && <Spin size="small" />}
|
|
207
|
+
{hasUnsavedChanges && <Badge status="warning" />}
|
|
208
|
+
<Button size="small" onClick={saveLayout}>Save</Button>
|
|
209
|
+
</div>
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return <span>{params.value}</span>;
|
|
214
|
+
};
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## 📊 Datový model
|
|
218
|
+
|
|
219
|
+
### Grid API Field Structure
|
|
220
|
+
```javascript
|
|
221
|
+
{
|
|
222
|
+
name: "customerName", // Název pole
|
|
223
|
+
displayName: "Název zákazníka", // Zobrazovaný název
|
|
224
|
+
dataType: "string", // Datový typ
|
|
225
|
+
isVisible: true, // Viditelnost sloupce
|
|
226
|
+
width: 150, // Šířka sloupce
|
|
227
|
+
order: 0, // Pořadí sloupce
|
|
228
|
+
isPinned: null, // Připínání ('left', 'right', null)
|
|
229
|
+
userField: { // Personalizované nastavení
|
|
230
|
+
isVisible: true,
|
|
231
|
+
width: 200,
|
|
232
|
+
order: 1,
|
|
233
|
+
isPinned: "left"
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## 🎯 Best Practices
|
|
239
|
+
|
|
240
|
+
1. **Unikátní gridName**: Každý grid musí mít unikátní název v rámci aplikace
|
|
241
|
+
2. **UserKey konzistence**: Používej konzistentní identifikátor uživatele
|
|
242
|
+
3. **Error handling**: Vždy implementuj `onLayoutError` callback
|
|
243
|
+
4. **AccessToken**: Poskytni access token pro autorizaci API volání
|
|
244
|
+
5. **Debouncing**: Pro časté změny používej vyšší `autoSaveDelay`
|
|
245
|
+
6. **Testing**: Testuj s různými kombinacemi column definitions
|
|
246
|
+
|
|
247
|
+
## 🚨 Troubleshooting
|
|
248
|
+
|
|
249
|
+
### Layout se nenačítá
|
|
250
|
+
- Zkontroluj, že `layoutEnabled={true}`
|
|
251
|
+
- Ověř, že `userKey`, `gridName` a `accessToken` jsou správně nastaveny
|
|
252
|
+
- Zkontroluj network tab pro API chyby
|
|
253
|
+
|
|
254
|
+
### Auto-save nefunguje
|
|
255
|
+
- Ověř, že `autoSave={true}` (default)
|
|
256
|
+
- Zkontroluj, že se spouští AG-Grid eventy (onColumnMoved, onColumnResized)
|
|
257
|
+
- Zkontroluj console pro chyby
|
|
258
|
+
|
|
259
|
+
### Performance problémy
|
|
260
|
+
- Zvyš `autoSaveDelay` pro méně časté ukládání
|
|
261
|
+
- Použij `autoSave={false}` pro manuální kontrolu
|
|
262
|
+
- Implementuj vlastní debouncing v parent komponentě
|
|
263
|
+
|
|
264
|
+
## 📝 Changelog
|
|
265
|
+
|
|
266
|
+
### v1.0.0
|
|
267
|
+
- ✅ Základní grid layout management
|
|
268
|
+
- ✅ Auto-save funkcionalita
|
|
269
|
+
- ✅ Integration s Grid API službou
|
|
270
|
+
- ✅ Error handling a recovery
|
|
273
271
|
- ✅ Manual controls (save, reset, reload)
|
package/dist/ColumnBuilder.js
CHANGED