@controleonline/ui-common 1.2.80 → 1.2.81
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/AGENTS.md +8 -0
- package/package.json +9 -3
- package/src/api/fetch.js +7 -7
- package/src/react/components/AddImportModal.js +6 -2
- package/src/react/components/BackgroundRuntimeBridge.js +201 -215
- package/src/react/components/ConfirmModal.js +44 -9
- package/src/react/components/ConfirmModal.styles.js +55 -41
- package/src/react/components/CopyDeviceConfigModal.js +193 -0
- package/src/react/components/CopyDeviceConfigModal.styles.js +123 -0
- package/src/react/components/DefaultProvider.native.js +22 -0
- package/src/react/components/DefaultProvider.web.js +25 -1
- package/src/react/components/EntityLogBranch.js +482 -0
- package/src/react/components/EntityLogCards.js +369 -0
- package/src/react/components/EntityLogContent.js +113 -794
- package/src/react/components/LinkedOrderProductsTab.js +3 -3
- package/src/react/components/PrintService.js +130 -409
- package/src/react/components/RemoteCheckoutService.js +2 -2
- package/src/react/components/RuntimeBottomNavigationBar.js +141 -146
- package/src/react/components/RuntimeFooterMarqueeText.js +137 -0
- package/src/react/components/RuntimeInfoFooter.js +12 -15
- package/src/react/components/SystemErrorToast.js +49 -29
- package/src/react/components/SystemErrorToast.styles.js +43 -38
- package/src/react/components/UserAvatar.js +120 -28
- package/src/react/config/deviceConfigBootstrap.js +330 -304
- package/src/react/hooks/usePrintSpoolEffects.js +161 -0
- package/src/react/pages/DeviceDetailPage.js +6 -2882
- package/src/react/pages/Devices/detail/DeviceDetailAlertsCommandsSection.js +233 -0
- package/src/react/pages/Devices/detail/DeviceDetailHeader.js +138 -0
- package/src/react/pages/Devices/detail/DeviceDetailMovementSections.js +167 -0
- package/src/react/pages/Devices/detail/DeviceDetailOrdersPrintSection.js +216 -0
- package/src/react/pages/Devices/detail/DeviceDetailPaymentSection.js +40 -0
- package/src/react/pages/Devices/detail/DeviceDetailPdvConfigSection.js +390 -0
- package/src/react/pages/Devices/detail/DeviceDetailRenderers.js +135 -0
- package/src/react/pages/Devices/detail/DeviceDetailScreen.js +493 -0
- package/src/react/pages/Devices/detail/OptionButtonChip.js +65 -0
- package/src/react/pages/Devices/detail/deviceDetailConstants.js +36 -0
- package/src/react/pages/Devices/detail/deviceDetailHelpers.js +70 -0
- package/src/react/pages/Devices/detail/useDeviceDetailActions.js +483 -0
- package/src/react/pages/Devices/detail/useDeviceDetailCopyConfig.js +87 -0
- package/src/react/pages/Devices/detail/useDeviceDetailLoaders.js +327 -0
- package/src/react/pages/Devices/detail/useDeviceDetailSaves.js +429 -0
- package/src/react/pages/Devices/detail/useDeviceDetailStateA.js +484 -0
- package/src/react/pages/Devices/detail/useDeviceDetailStateB.js +71 -0
- package/src/react/pages/Devices/deviceTypes/index.js +2 -0
- package/src/react/pages/Devices/deviceTypes/pdv.js +11 -0
- package/src/react/pages/Imports.js +3 -2
- package/src/react/pages/IntegrationConfigFields.js +126 -0
- package/src/react/pages/IntegrationConfigPage.js +122 -591
- package/src/react/pages/IntegrationConfigPage.utils.js +95 -0
- package/src/react/print/usePrintButtonController.js +9 -1
- package/src/react/services/Getnet/Checkout.js +81 -0
- package/src/react/services/Getnet/Getnet.js +77 -0
- package/src/react/services/paymentGatewayExecution.js +20 -0
- package/src/react/utils/bottomNavigationToolbar.js +161 -0
- package/src/react/utils/commercialDocumentOrders.js +18 -6
- package/src/react/utils/copyDeviceConfigs.js +198 -0
- package/src/react/utils/fileUrl.js +43 -0
- package/src/react/utils/importStatus.js +19 -10
- package/src/react/utils/logSettings.js +7 -7
- package/src/react/utils/maintenanceSettings.js +16 -0
- package/src/react/utils/paymentDevices.js +6 -0
- package/src/react/utils/printManagedPrinter.js +45 -0
- package/src/react/utils/printRouting.js +63 -0
- package/src/react/utils/printSpoolUtils.js +119 -0
- package/src/react/utils/printerDevices.js +368 -368
- package/src/react/utils/runtimeFooter.js +10 -19
- package/src/react/utils/shopFranchises.js +186 -65
- package/src/react/utils/systemErrorMessage.js +71 -67
- package/src/store/device_config/customActions.js +119 -30
- package/src/tests/browser/manager/bottom-navigation-role-toolbar.spec.js +353 -0
- package/src/tests/browser/manager/device-detail-alias-save.spec.js +345 -0
- package/src/tests/browser/manager/device-detail-copy-config.spec.js +365 -0
- package/src/tests/browser/manager/runtime-footer-marquee.spec.js +262 -0
- package/src/tests/browser/manager/theme-confirm-toast.spec.js +236 -0
- package/src/tests/react/components/RuntimeFooterMarqueeText.test.js +171 -0
- package/src/tests/react/components/UserAvatar.test.js +6 -2
- package/src/tests/react/components/themeAwareModals.test.mjs +60 -0
- package/src/tests/react/config/deviceConfigBootstrap.test.js +104 -66
- package/src/tests/react/pages/deviceDetailDelete.test.js +78 -0
- package/src/tests/react/pages/receitaFederalIntegrationContract.test.mjs +48 -0
- package/src/tests/react/utils/bottomNavigationToolbar.test.js +222 -0
- package/src/tests/react/utils/copyDeviceConfigs.test.mjs +127 -0
- package/src/tests/react/utils/fileUrl.test.js +38 -0
- package/src/tests/react/utils/importStatus.test.js +26 -9
- package/src/tests/react/utils/passwordPolicy.test.js +27 -0
- package/src/tests/react/utils/printRouting.test.mjs +86 -0
- package/src/tests/react/utils/printSpoolUtils.test.mjs +52 -0
- package/src/tests/react/utils/runtimeFooter.test.js +7 -0
- package/src/tests/react/utils/shopFranchises.test.js +121 -115
- package/src/tests/react/utils/systemErrorMessage.test.js +32 -59
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { getDeviceTypeLabel } from '@controleonline/ui-common/src/react/utils/printerDevices';
|
|
2
|
+
|
|
1
3
|
const DEVICE_RUNTIME_FOOTER_TEXT_CONFIG_KEY = 'device-runtime-footer-text';
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
+
const RUNTIME_FOOTER_HIDDEN_ROUTES = new Set(['PaylistPage']);
|
|
5
|
+
|
|
6
|
+
const shouldShowRuntimeFooter = currentRouteName =>
|
|
7
|
+
!RUNTIME_FOOTER_HIDDEN_ROUTES.has(String(currentRouteName || '').trim());
|
|
4
8
|
|
|
5
9
|
const safeTrim = value => String(value || '').trim();
|
|
6
10
|
|
|
@@ -25,20 +29,6 @@ const normalizeComparableText = value =>
|
|
|
25
29
|
.normalize('NFD')
|
|
26
30
|
.replace(/[\u0300-\u036f]/g, '');
|
|
27
31
|
|
|
28
|
-
const getRuntimeFooterDeviceTypeLabel = type => {
|
|
29
|
-
const normalizedType = safeTrim(type).toUpperCase();
|
|
30
|
-
|
|
31
|
-
if (PRINTER_DEVICE_TYPES.has(normalizedType)) {
|
|
32
|
-
return 'Impressora';
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (normalizedType === IP_CAMERA_DEVICE_TYPE) {
|
|
36
|
-
return 'Camera IP';
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return normalizedType || 'DEVICE';
|
|
40
|
-
};
|
|
41
|
-
|
|
42
32
|
const getRuntimeFooterTranslation = (store, type, key) =>
|
|
43
33
|
safeTrim(globalThis?.t?.getMessageFromBuckets?.(store, type, key));
|
|
44
34
|
|
|
@@ -268,7 +258,7 @@ const getRuntimeFooterOperationalTypeLabel = ({device, deviceConfig} = {}) => {
|
|
|
268
258
|
});
|
|
269
259
|
|
|
270
260
|
return operationalTypeInfo.value
|
|
271
|
-
?
|
|
261
|
+
? getDeviceTypeLabel(operationalTypeInfo.value)
|
|
272
262
|
: '';
|
|
273
263
|
};
|
|
274
264
|
|
|
@@ -396,7 +386,7 @@ const getRuntimeFooterDebugInfo = ({device, appVersion, deviceConfig}) => {
|
|
|
396
386
|
deviceConfig,
|
|
397
387
|
});
|
|
398
388
|
const operationalTypeLabel = operationalTypeInfo.value
|
|
399
|
-
?
|
|
389
|
+
? getDeviceTypeLabel(operationalTypeInfo.value)
|
|
400
390
|
: '';
|
|
401
391
|
const operationModeLabel =
|
|
402
392
|
operationalTypeLabel === 'PDV'
|
|
@@ -503,5 +493,6 @@ module.exports = {
|
|
|
503
493
|
getRuntimeFooterWebIdentifierCandidates,
|
|
504
494
|
getRuntimeFooterText,
|
|
505
495
|
getRuntimeFooterWebHost,
|
|
506
|
-
normalizeRuntimeFooterText,
|
|
496
|
+
normalizeRuntimeFooterText,
|
|
497
|
+
shouldShowRuntimeFooter,
|
|
507
498
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {api} from '@controleonline/ui-common/src/api';
|
|
2
|
-
import {
|
|
3
|
-
extractCollectionItems,
|
|
4
|
-
toEntityIri,
|
|
5
|
-
} from '@controleonline/ui-common/src/react/utils/commercialDocumentOrders';
|
|
1
|
+
import {api} from '@controleonline/ui-common/src/api';
|
|
2
|
+
import {
|
|
3
|
+
extractCollectionItems,
|
|
4
|
+
toEntityIri,
|
|
5
|
+
} from '@controleonline/ui-common/src/react/utils/commercialDocumentOrders';
|
|
6
6
|
import {normalizeShopEntityId} from '@controleonline/ui-common/src/react/utils/shopConfig';
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
export const SHOP_FRANCHISE_LINK_TYPE = 'franchisee';
|
|
9
9
|
export const SHOP_FRANCHISE_PAGE_SIZE = 50;
|
|
10
10
|
|
|
@@ -150,39 +150,113 @@ export const filterShopFranchiseDirectory = ({
|
|
|
150
150
|
})
|
|
151
151
|
.filter(Boolean);
|
|
152
152
|
};
|
|
153
|
-
|
|
154
|
-
export const resolveFranchiseCompanyLabel = company =>
|
|
155
|
-
String(company?.alias || company?.name || '').trim() ||
|
|
156
|
-
`Franquia #${normalizeShopEntityId(company) || ''}`.trim();
|
|
157
|
-
|
|
158
|
-
|
|
153
|
+
|
|
154
|
+
export const resolveFranchiseCompanyLabel = company =>
|
|
155
|
+
String(company?.alias || company?.name || '').trim() ||
|
|
156
|
+
`Franquia #${normalizeShopEntityId(company) || ''}`.trim();
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Resolve the franchise company entity from a people_link relative to the
|
|
160
|
+
* viewed franchisor/company id. DB rows may store the viewed company as
|
|
161
|
+
* `company` or as `people` (inverted association).
|
|
162
|
+
*/
|
|
163
|
+
export const extractFranchiseCompanyFromLink = (link, viewerCompanyId) => {
|
|
164
|
+
const viewerId = normalizeShopEntityId(viewerCompanyId);
|
|
165
|
+
const companySide = link?.company;
|
|
166
|
+
const peopleSide = link?.people;
|
|
167
|
+
const companyId = normalizeShopEntityId(companySide);
|
|
168
|
+
const peopleId = normalizeShopEntityId(peopleSide);
|
|
169
|
+
|
|
170
|
+
if (viewerId && companyId === viewerId) {
|
|
171
|
+
return peopleSide;
|
|
172
|
+
}
|
|
173
|
+
if (viewerId && peopleId === viewerId) {
|
|
174
|
+
return companySide;
|
|
175
|
+
}
|
|
176
|
+
// Fallback: franchisee is typically the `people` side of linkType=franchisee.
|
|
177
|
+
return peopleSide || companySide || null;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const fetchFranchiseLinksPage = async ({
|
|
159
181
|
companyId,
|
|
160
|
-
|
|
182
|
+
side,
|
|
161
183
|
page = 1,
|
|
162
184
|
itemsPerPage = SHOP_FRANCHISE_PAGE_SIZE,
|
|
163
|
-
|
|
164
|
-
}
|
|
185
|
+
search = '',
|
|
186
|
+
}) => {
|
|
187
|
+
const id = normalizeShopEntityId(companyId);
|
|
188
|
+
if (!id) {
|
|
189
|
+
return [];
|
|
190
|
+
}
|
|
191
|
+
|
|
165
192
|
const params = {
|
|
166
193
|
page: Math.max(1, Number(page) || 1),
|
|
167
194
|
itemsPerPage: normalizeItemsPerPage(itemsPerPage),
|
|
195
|
+
linkType: SHOP_FRANCHISE_LINK_TYPE,
|
|
196
|
+
[side]: toEntityIri(id, 'people'),
|
|
168
197
|
};
|
|
169
198
|
|
|
170
199
|
if (String(search || '').trim()) {
|
|
171
200
|
params.search = String(search).trim();
|
|
172
201
|
}
|
|
173
202
|
|
|
174
|
-
const response =
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
203
|
+
const response = await api.fetch('people_links', {params});
|
|
204
|
+
return extractCollectionItems(response);
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Authenticated franchise directory via people_links (both sides).
|
|
209
|
+
* GET /people?link.company=… does not reliably return franchisee PJs.
|
|
210
|
+
*/
|
|
211
|
+
const fetchFranchiseCompaniesFromLinks = async ({
|
|
212
|
+
companyId,
|
|
213
|
+
search = '',
|
|
214
|
+
itemsPerPage = SHOP_FRANCHISE_PAGE_SIZE,
|
|
215
|
+
} = {}) => {
|
|
216
|
+
const viewerId = normalizeShopEntityId(companyId);
|
|
217
|
+
if (!viewerId) {
|
|
218
|
+
return [];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const pageSize = normalizeItemsPerPage(itemsPerPage);
|
|
222
|
+
const byId = new Map();
|
|
223
|
+
|
|
224
|
+
for (const side of ['company', 'people']) {
|
|
225
|
+
let page = 1;
|
|
226
|
+
while (true) {
|
|
227
|
+
const links = await fetchFranchiseLinksPage({
|
|
228
|
+
companyId: viewerId,
|
|
229
|
+
side,
|
|
230
|
+
page,
|
|
231
|
+
itemsPerPage: pageSize,
|
|
232
|
+
search,
|
|
233
|
+
});
|
|
234
|
+
const pageLinks = Array.isArray(links) ? links : [];
|
|
235
|
+
|
|
236
|
+
pageLinks.forEach(link => {
|
|
237
|
+
const franchise = extractFranchiseCompanyFromLink(link, viewerId);
|
|
238
|
+
const franchiseId = normalizeShopEntityId(franchise);
|
|
239
|
+
if (!franchiseId || franchiseId === viewerId) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (!byId.has(franchiseId)) {
|
|
243
|
+
byId.set(
|
|
244
|
+
franchiseId,
|
|
245
|
+
typeof franchise === 'object' && franchise
|
|
246
|
+
? franchise
|
|
247
|
+
: {id: franchiseId},
|
|
248
|
+
);
|
|
249
|
+
}
|
|
182
250
|
});
|
|
183
|
-
const items = extractCollectionItems(response);
|
|
184
251
|
|
|
185
|
-
|
|
252
|
+
if (pageLinks.length < pageSize) {
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
page += 1;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return Array.from(byId.values())
|
|
186
260
|
.map(normalizeFranchiseDirectoryItem)
|
|
187
261
|
.sort((left, right) =>
|
|
188
262
|
sortByLabel(
|
|
@@ -192,67 +266,113 @@ export const fetchShopFranchiseCompanies = async ({
|
|
|
192
266
|
);
|
|
193
267
|
};
|
|
194
268
|
|
|
195
|
-
export const
|
|
269
|
+
export const fetchShopFranchiseCompanies = async ({
|
|
196
270
|
companyId,
|
|
197
|
-
publicDirectory = false,
|
|
198
271
|
search = '',
|
|
272
|
+
page = 1,
|
|
199
273
|
itemsPerPage = SHOP_FRANCHISE_PAGE_SIZE,
|
|
274
|
+
publicDirectory = false,
|
|
200
275
|
} = {}) => {
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
while (true) {
|
|
206
|
-
const pageItems = await fetchShopFranchiseCompanies({
|
|
207
|
-
companyId,
|
|
208
|
-
publicDirectory,
|
|
209
|
-
search,
|
|
210
|
-
page,
|
|
211
|
-
itemsPerPage: normalizedItemsPerPage,
|
|
212
|
-
});
|
|
213
|
-
const normalizedPageItems = Array.isArray(pageItems) ? pageItems : [];
|
|
276
|
+
const params = {
|
|
277
|
+
page: Math.max(1, Number(page) || 1),
|
|
278
|
+
itemsPerPage: normalizeItemsPerPage(itemsPerPage),
|
|
279
|
+
};
|
|
214
280
|
|
|
215
|
-
|
|
281
|
+
if (String(search || '').trim()) {
|
|
282
|
+
params.search = String(search).trim();
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (publicDirectory) {
|
|
286
|
+
const response = await api.fetch('/shop/franchises', {params});
|
|
287
|
+
const items = extractCollectionItems(response);
|
|
288
|
+
return items
|
|
289
|
+
.map(normalizeFranchiseDirectoryItem)
|
|
290
|
+
.sort((left, right) =>
|
|
291
|
+
sortByLabel(
|
|
292
|
+
resolveFranchiseCompanyLabel(left),
|
|
293
|
+
resolveFranchiseCompanyLabel(right),
|
|
294
|
+
),
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Management path: people_links dual-side (company + people).
|
|
299
|
+
// Page param is ignored for dual aggregation; callers that need full list
|
|
300
|
+
// should use fetchAllShopFranchiseDirectory.
|
|
301
|
+
const all = await fetchFranchiseCompaniesFromLinks({
|
|
302
|
+
companyId,
|
|
303
|
+
search,
|
|
304
|
+
itemsPerPage,
|
|
305
|
+
});
|
|
306
|
+
const start = (Math.max(1, Number(page) || 1) - 1) * normalizeItemsPerPage(itemsPerPage);
|
|
307
|
+
return all.slice(start, start + normalizeItemsPerPage(itemsPerPage));
|
|
308
|
+
};
|
|
216
309
|
|
|
217
|
-
|
|
218
|
-
|
|
310
|
+
export const fetchAllShopFranchiseDirectory = async ({
|
|
311
|
+
companyId,
|
|
312
|
+
publicDirectory = false,
|
|
313
|
+
search = '',
|
|
314
|
+
itemsPerPage = SHOP_FRANCHISE_PAGE_SIZE,
|
|
315
|
+
} = {}) => {
|
|
316
|
+
if (publicDirectory) {
|
|
317
|
+
const normalizedItemsPerPage = normalizeItemsPerPage(itemsPerPage);
|
|
318
|
+
const items = [];
|
|
319
|
+
let page = 1;
|
|
320
|
+
|
|
321
|
+
while (true) {
|
|
322
|
+
const pageItems = await fetchShopFranchiseCompanies({
|
|
323
|
+
companyId,
|
|
324
|
+
publicDirectory: true,
|
|
325
|
+
search,
|
|
326
|
+
page,
|
|
327
|
+
itemsPerPage: normalizedItemsPerPage,
|
|
328
|
+
});
|
|
329
|
+
const normalizedPageItems = Array.isArray(pageItems) ? pageItems : [];
|
|
330
|
+
items.push(...normalizedPageItems);
|
|
331
|
+
if (normalizedPageItems.length < normalizedItemsPerPage) {
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
page += 1;
|
|
219
335
|
}
|
|
220
336
|
|
|
221
|
-
|
|
337
|
+
return items
|
|
338
|
+
.map(normalizeFranchiseDirectoryItem)
|
|
339
|
+
.sort((left, right) =>
|
|
340
|
+
sortByLabel(
|
|
341
|
+
resolveFranchiseCompanyLabel(left),
|
|
342
|
+
resolveFranchiseCompanyLabel(right),
|
|
343
|
+
),
|
|
344
|
+
);
|
|
222
345
|
}
|
|
223
346
|
|
|
224
|
-
return
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
resolveFranchiseCompanyLabel(right),
|
|
230
|
-
),
|
|
231
|
-
);
|
|
347
|
+
return fetchFranchiseCompaniesFromLinks({
|
|
348
|
+
companyId,
|
|
349
|
+
search,
|
|
350
|
+
itemsPerPage,
|
|
351
|
+
});
|
|
232
352
|
};
|
|
233
353
|
|
|
234
354
|
export const fetchShopFranchiseAddresses = async ({
|
|
235
355
|
peopleId,
|
|
236
356
|
search = '',
|
|
237
357
|
} = {}) => {
|
|
238
|
-
if (!peopleId) {
|
|
239
|
-
return [];
|
|
240
|
-
}
|
|
241
|
-
|
|
358
|
+
if (!peopleId) {
|
|
359
|
+
return [];
|
|
360
|
+
}
|
|
361
|
+
|
|
242
362
|
const params = {
|
|
243
363
|
people: toEntityIri(peopleId, 'people'),
|
|
244
364
|
itemsPerPage: SHOP_FRANCHISE_PAGE_SIZE,
|
|
245
365
|
page: 1,
|
|
246
366
|
};
|
|
247
|
-
|
|
248
|
-
if (String(search || '').trim()) {
|
|
249
|
-
params.search = String(search).trim();
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const response = await api.fetch('addresses', {params});
|
|
253
|
-
return extractCollectionItems(response);
|
|
254
|
-
};
|
|
255
|
-
|
|
367
|
+
|
|
368
|
+
if (String(search || '').trim()) {
|
|
369
|
+
params.search = String(search).trim();
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
const response = await api.fetch('addresses', {params});
|
|
373
|
+
return extractCollectionItems(response);
|
|
374
|
+
};
|
|
375
|
+
|
|
256
376
|
export const fetchShopFranchiseDirectory = async ({
|
|
257
377
|
companyId,
|
|
258
378
|
publicDirectory = false,
|
|
@@ -270,4 +390,5 @@ export const fetchShopFranchiseDirectory = async ({
|
|
|
270
390
|
|
|
271
391
|
return companies.map(normalizeFranchiseDirectoryItem);
|
|
272
392
|
};
|
|
393
|
+
|
|
273
394
|
// TODO(store-first): quando este arquivo for mexido, mover a leitura para stores, remover api.fetch e evitar repassar dados em objetos quando o store ja resolver isso.
|
|
@@ -1,67 +1,71 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
item?.title ||
|
|
11
|
-
item?.
|
|
12
|
-
item?.
|
|
13
|
-
item
|
|
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
|
-
error?.description ||
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
1
|
+
import { mapPasswordErrorMessage } from './passwordPolicy'
|
|
2
|
+
|
|
3
|
+
const normalizeText = value => String(value || '').trim()
|
|
4
|
+
|
|
5
|
+
const resolveMessageList = items =>
|
|
6
|
+
(Array.isArray(items) ? items : [])
|
|
7
|
+
.map(item =>
|
|
8
|
+
normalizeText(
|
|
9
|
+
item?.['hydra:description'] ||
|
|
10
|
+
item?.['hydra:title'] ||
|
|
11
|
+
item?.message ||
|
|
12
|
+
item?.title ||
|
|
13
|
+
item?.detail ||
|
|
14
|
+
item?.description ||
|
|
15
|
+
item,
|
|
16
|
+
),
|
|
17
|
+
)
|
|
18
|
+
.filter(Boolean)
|
|
19
|
+
.join('\n')
|
|
20
|
+
.trim()
|
|
21
|
+
|
|
22
|
+
export const resolveSystemErrorMessage = error => {
|
|
23
|
+
if (error === undefined || error === null) {
|
|
24
|
+
return ''
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (typeof error === 'string') {
|
|
28
|
+
return mapPasswordErrorMessage(error.trim())
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (Array.isArray(error)) {
|
|
32
|
+
return mapPasswordErrorMessage(resolveMessageList(error))
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (Array.isArray(error?.message)) {
|
|
36
|
+
return mapPasswordErrorMessage(resolveMessageList(error.message))
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (Array.isArray(error?.violations)) {
|
|
40
|
+
return mapPasswordErrorMessage(resolveMessageList(error.violations))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (error?.response?.data) {
|
|
44
|
+
const responseMessage = resolveSystemErrorMessage(error.response.data)
|
|
45
|
+
if (responseMessage) {
|
|
46
|
+
return responseMessage
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (error?.body) {
|
|
51
|
+
const bodyMessage = resolveSystemErrorMessage(error.body)
|
|
52
|
+
if (bodyMessage) {
|
|
53
|
+
return bodyMessage
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return mapPasswordErrorMessage(
|
|
58
|
+
normalizeText(
|
|
59
|
+
error?.['hydra:description'] ||
|
|
60
|
+
error?.['hydra:title'] ||
|
|
61
|
+
error?.detail ||
|
|
62
|
+
error?.description ||
|
|
63
|
+
error?.errmsg ||
|
|
64
|
+
error?.error ||
|
|
65
|
+
error?.message ||
|
|
66
|
+
error?.title,
|
|
67
|
+
),
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export default resolveSystemErrorMessage
|