@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 CHANGED
@@ -875,7 +875,7 @@ class ColumnBuilder {
875
875
  setCurrentMenuItems(updatedMenuItems);
876
876
  }
877
877
  } catch (error) {
878
- console.error('Chyba při volání onBeforeShow:', error);
878
+ // Removed console.error for production
879
879
  if (isMountedRef.current) {
880
880
  setCurrentMenuItems(menuItems);
881
881
  }
@@ -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
- 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
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)
@@ -604,7 +604,7 @@ class ColumnBuilder {
604
604
  }
605
605
  }
606
606
  catch (error) {
607
- console.error('Chyba při volání onBeforeShow:', error);
607
+ // Removed console.error for production
608
608
  if (isMountedRef.current) {
609
609
  setCurrentMenuItems(menuItems);
610
610
  }