@bit.rhplus/ui.grid-layout 0.0.1

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.
@@ -0,0 +1,296 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * Hook pro komunikaci s Grid Layout API službou
4
+ * Poskytuje funkcionalitu pro načítání a ukládání personalizovaných nastavení gridů
5
+ */
6
+
7
+ import { useCallback, useMemo } from 'react';
8
+ import { useQueryClient } from '@tanstack/react-query';
9
+ import { useApiQuery, useApiQuerySilence } from '@bit.rhplus/data';
10
+ import {
11
+ userFieldsApi,
12
+ getSingleGridApi,
13
+ getUserGridsApi,
14
+ saveGridLayoutApi
15
+ } from './gridLayout';
16
+ import useData from '@bit.rhplus/data';
17
+
18
+ /**
19
+ * Hook pro práci s Grid Layout API
20
+ * @param {Object} config - Konfigurace gridu
21
+ * @param {string} config.userKey - Klíč uživatele
22
+ * @param {string} config.applicationName - Název aplikace
23
+ * @param {string} config.gridName - Název gridu
24
+ * @param {string} [config.filterName] - Název filtru (volitelné)
25
+ * @param {string} [config.accessToken] - Přístupový token
26
+ * @returns {Object} API methods pro grid layout
27
+ */
28
+ export const useGridLayoutApi = ({
29
+ userKey,
30
+ applicationName,
31
+ gridName,
32
+ filterName = null,
33
+ accessToken = null
34
+ }) => {
35
+ const { fetchDataUIAsync } = useData();
36
+ const queryClient = useQueryClient();
37
+
38
+ // Základní identifikace pro API volání
39
+ const baseParams = useMemo(() => ({
40
+ userKey,
41
+ applicationName,
42
+ gridName,
43
+ ...(filterName && { filterName })
44
+ }), [userKey, applicationName, gridName, filterName]);
45
+
46
+ // Query key pro caching
47
+ const gridQueryKey = useMemo(() =>
48
+ `grid_layout_${userKey}_${applicationName}_${gridName}_${filterName || 'default'}`,
49
+ [userKey, applicationName, gridName, filterName]
50
+ );
51
+
52
+ /**
53
+ * Načte seznam polí pro konkrétní grid s personalizací uživatele
54
+ * @param {Array} fields - Definice polí gridu
55
+ * @param {Object} options - React Query options
56
+ */
57
+ const useUserFields = (fields = [], options = {}) => {
58
+ const params = useMemo(() => ({
59
+ ...baseParams,
60
+ fields
61
+ }), [baseParams, fields]);
62
+
63
+ return useApiQuery(
64
+ `${gridQueryKey}_fields`,
65
+ userFieldsApi,
66
+ params,
67
+ accessToken,
68
+ null,
69
+ options?.enabled ?? true,
70
+ 5, // 5 minut stale time
71
+ options
72
+ );
73
+ };
74
+
75
+ /**
76
+ * Načte konkrétní jeden grid pro uživatele
77
+ * @param {Object} options - React Query options
78
+ */
79
+ const useSingleGrid = (options = {}) => {
80
+ return useApiQuery(
81
+ gridQueryKey,
82
+ getSingleGridApi,
83
+ baseParams,
84
+ accessToken,
85
+ null,
86
+ true,
87
+ 5 // 5 minut stale time
88
+ );
89
+ };
90
+
91
+ /**
92
+ * Načte seznam všech gridů uživatele v aplikaci
93
+ * @param {Object} options - React Query options
94
+ */
95
+ const useUserGrids = (options = {}) => {
96
+ const params = useMemo(() => ({
97
+ userKey,
98
+ applicationName
99
+ }), [userKey, applicationName]);
100
+
101
+ return useApiQuery(
102
+ `user_grids_${userKey}_${applicationName}`,
103
+ getUserGridsApi,
104
+ params,
105
+ accessToken,
106
+ null,
107
+ true,
108
+ 10 // 10 minut stale time
109
+ );
110
+ };
111
+
112
+ /**
113
+ * Uloží personalizované nastavení gridu pomocí SaveUserFields endpoint
114
+ * @param {Array} userFields - UserFieldModel array pro uložení
115
+ * @returns {Promise} Promise s výsledkem
116
+ */
117
+ const saveGridLayout = useCallback(async (userFields) => {
118
+ try {
119
+ const params = {
120
+ ...baseParams,
121
+ userFields // Nová struktura pro SaveUserFieldsCommand
122
+ };
123
+
124
+ const result = await fetchDataUIAsync(saveGridLayoutApi, params, accessToken);
125
+
126
+ if (result.success) {
127
+ // Invalidujeme cache pro načtení čerstvých dat z API - všechny queries související s tímto gridem
128
+ await queryClient.invalidateQueries({
129
+ predicate: (query) => {
130
+ // Invalidujeme všechny queries které začínají našim gridQueryKey
131
+ const queryKey = query.queryKey?.[0];
132
+ return queryKey && typeof queryKey === 'string' && queryKey.startsWith(gridQueryKey);
133
+ }
134
+ });
135
+
136
+ console.log("✅ Grid layout uložen a cache invalidován pro pattern:", gridQueryKey);
137
+
138
+ return {
139
+ success: true,
140
+ data: result.data,
141
+ message: result.message
142
+ };
143
+ } else {
144
+ throw new Error(result.message || result.error?.message || 'Chyba při ukládání grid layoutu');
145
+ }
146
+ } catch (error) {
147
+ console.error('Chyba při ukládání grid layout:', error);
148
+ throw error;
149
+ }
150
+ }, [baseParams, fetchDataUIAsync, accessToken, queryClient, gridQueryKey]);
151
+
152
+ /**
153
+ * Transformuje AG-Grid column state na UserFieldModel format
154
+ * @param {Array} columnState - AG-Grid column state
155
+ * @param {Array} columnDefs - Původní column definitions
156
+ * @returns {Array} UserFieldModel array pro SaveUserFields API
157
+ */
158
+ const transformColumnStateToFields = useCallback((columnState, columnDefs) => {
159
+ if (!columnState || !columnDefs) return [];
160
+ if (!Array.isArray(columnDefs)) {
161
+ console.error('transformColumnStateToFields: columnDefs musí být array, získán:', typeof columnDefs);
162
+ return [];
163
+ }
164
+
165
+ return columnState.map((columnStateItem, index) => {
166
+ // Najdeme odpovídající column definition podle colId
167
+ const colDef = columnDefs.find(cd => cd.field === columnStateItem.colId) || {};
168
+
169
+ return {
170
+ // Mapování na UserFieldModel strukturu
171
+ Id: 0, // Nové pole má ID = 0, existující budou mít správné ID z API
172
+ UserKey: baseParams.userKey,
173
+ ApplicationName: baseParams.applicationName,
174
+ GridName: baseParams.gridName,
175
+ FilterName: baseParams.filterName || null,
176
+ FieldName: columnStateItem.colId,
177
+ HeaderName: colDef.headerName || columnStateItem.colId || `Column ${index + 1}`,
178
+ Order: index, // Pořadí podle pozice v column state
179
+ Show: columnStateItem.hide !== true,
180
+ Width: columnStateItem.width || colDef.width || null,
181
+ System: colDef.system || false // Systémové sloupce nejde skrývat/editovat
182
+ };
183
+ });
184
+ }, [baseParams]);
185
+
186
+ /**
187
+ * Transformuje UserFieldModel array na AG-Grid column state
188
+ * Používá columnDefs jako primární zdroj a userFields jen pro úpravy
189
+ * @param {Array} userFields - UserFieldModel array z API (pro úpravy)
190
+ * @param {Array} columnDefs - Původní column definitions (primární)
191
+ * @returns {Array} Column state pro AG-Grid
192
+ */
193
+ const transformFieldsToColumnState = useCallback((userFields, columnDefs) => {
194
+ if (!columnDefs || !Array.isArray(columnDefs)) {
195
+ return [];
196
+ }
197
+
198
+ // Pokud nemáme userFields, vrátíme default column state z columnDefs
199
+ if (!userFields || !Array.isArray(userFields)) {
200
+ return columnDefs.map((colDef, index) => ({
201
+ colId: colDef.field,
202
+ width: colDef.width || 100,
203
+ hide: colDef.hide || false,
204
+ pinned: colDef.pinned || null,
205
+ sort: null,
206
+ sortIndex: null
207
+ }));
208
+ }
209
+
210
+ // Vytvoříme mapu userFields pro rychlé vyhledávání
211
+ const userFieldsMap = new Map();
212
+ userFields.forEach(userField => {
213
+ // API používá lowercase názvy (fieldName, order, show) místo uppercase (FieldName, Order, Show)
214
+ const fieldName = userField.fieldName || userField.FieldName;
215
+ userFieldsMap.set(fieldName, userField);
216
+ });
217
+
218
+ console.log("🔍 transformFieldsToColumnState debug:", {
219
+ userFields: userFields.map(uf => ({
220
+ fieldName: uf.fieldName || uf.FieldName,
221
+ order: uf.order ?? uf.Order,
222
+ show: uf.show ?? uf.Show,
223
+ width: uf.width ?? uf.Width
224
+ })),
225
+ columnDefs: columnDefs.map(cd => ({ field: cd.field, headerName: cd.headerName })),
226
+ userFieldsMapKeys: Array.from(userFieldsMap.keys())
227
+ });
228
+
229
+ // Vytvoříme column state POUZE pro sloupce, které mají záznam v userFields
230
+ const columnStateWithUserFields = columnDefs
231
+ .map((colDef, defaultIndex) => {
232
+ const userField = userFieldsMap.get(colDef.field);
233
+
234
+ // Pokud pro tento sloupec není userField, vracíme null (bude odfiltrován)
235
+ if (!userField) {
236
+ console.log(`🔍 No userField for ${colDef.field} - skipping`);
237
+ return null;
238
+ }
239
+
240
+ const result = {
241
+ colId: colDef.field,
242
+ // API používá lowercase názvy polí
243
+ width: userField.width ?? userField.Width ?? colDef.width ?? 100,
244
+ hide: !(userField.show ?? userField.Show ?? true),
245
+ pinned: colDef.pinned || null, // Pinning z columnDefs, userFields to zatím nepodporuje
246
+ sort: null, // Sorting není součástí layout managementu
247
+ sortIndex: null,
248
+ // Pořadí z userFields (lowercase/uppercase)
249
+ __order: userField.order ?? userField.Order ?? defaultIndex
250
+ };
251
+
252
+ console.log(`🔍 Column mapping for ${colDef.field}:`, {
253
+ colDefField: colDef.field,
254
+ foundUserField: true,
255
+ userFieldOrder: userField.order ?? userField.Order,
256
+ defaultIndex,
257
+ finalOrder: result.__order,
258
+ userFieldData: userField
259
+ });
260
+
261
+ return result;
262
+ })
263
+ .filter(Boolean); // Odfiltrujeme null hodnoty
264
+
265
+ // Seřadíme podle pořadí z userFields
266
+ const sortedColumnState = columnStateWithUserFields.sort((a, b) => (a.__order || 0) - (b.__order || 0));
267
+
268
+ console.log("🔍 Sorting result:", {
269
+ beforeSort: columnStateWithUserFields.map(c => ({ colId: c.colId, order: c.__order })),
270
+ afterSort: sortedColumnState.map(c => ({ colId: c.colId, order: c.__order }))
271
+ });
272
+
273
+ const finalResult = sortedColumnState.map(({ __order, ...columnState }) => columnState);
274
+
275
+ console.log("🔍 Final column state:", finalResult.map(c => c.colId));
276
+
277
+ return finalResult;
278
+ }, []);
279
+
280
+ return {
281
+ // Query hooks
282
+ useUserFields,
283
+ useSingleGrid,
284
+ useUserGrids,
285
+ // Mutation methods
286
+ saveGridLayout,
287
+ // Transform utilities
288
+ transformColumnStateToFields,
289
+ transformFieldsToColumnState,
290
+ // Config
291
+ gridQueryKey,
292
+ baseParams
293
+ };
294
+ };
295
+
296
+ export default useGridLayoutApi;