@controleonline/ui-common 1.2.71 → 1.2.75

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.
Files changed (150) hide show
  1. package/.github/actions/workers/manager/action.yml +147 -0
  2. package/.github/actions/workers/qa/action.yml +44 -0
  3. package/.github/actions/workers/security/action.yml +44 -0
  4. package/.github/actions/workers/technical-documenter/action.yml +51 -0
  5. package/.github/workflows/manager-worker.yml +168 -0
  6. package/.github/workflows/publish-npm.yml +45 -0
  7. package/.gitmodules +3 -0
  8. package/AGENTS.md +6 -0
  9. package/README.md +14 -0
  10. package/package.json +3 -2
  11. package/src/api/fetch.js +1 -1
  12. package/src/api/index.js +92 -22
  13. package/src/react/components/AddImportModal.js +94 -110
  14. package/src/react/components/BottomNavigationBar.config.js +211 -231
  15. package/src/react/components/CategoryForm.js +52 -35
  16. package/src/react/components/DefaultProvider.native.js +131 -95
  17. package/src/react/components/DefaultProvider.web.js +148 -74
  18. package/src/react/components/NetworkPrinterPreviewModal.js +249 -0
  19. package/src/react/components/NetworkPrinterPreviewModal.styles.js +159 -0
  20. package/src/react/components/RuntimeInfoFooter.js +100 -36
  21. package/src/react/components/RuntimeInfoFooter.styles.js +3 -0
  22. package/src/react/components/UnifiedPaymentBar.js +7 -4
  23. package/src/react/components/UserAvatar.js +160 -0
  24. package/src/react/components/integrations/IntegrationHero/index.js +48 -0
  25. package/src/react/components/integrations/IntegrationHero/styles.js +57 -0
  26. package/src/react/components/integrations/IntegrationTabs/index.js +89 -0
  27. package/src/react/components/integrations/IntegrationTabs/styles.js +44 -0
  28. package/src/react/config/deviceConfigBootstrap.js +5 -3
  29. package/src/react/pages/Connections.js +229 -0
  30. package/src/react/pages/Connections.styles.js +222 -0
  31. package/src/react/pages/DeviceDetailPage.js +2814 -0
  32. package/src/react/pages/DeviceDetailPage.styles.js +308 -0
  33. package/src/react/pages/Devices/currentDevice.js +194 -0
  34. package/src/react/pages/Devices/deviceTypes/DeviceGroupCard.js +257 -0
  35. package/src/react/pages/Devices/deviceTypes/all.js +23 -0
  36. package/src/react/pages/Devices/deviceTypes/device.js +25 -0
  37. package/src/react/pages/Devices/deviceTypes/deviceListHelpers.js +178 -0
  38. package/src/react/pages/Devices/deviceTypes/display.js +26 -0
  39. package/src/react/pages/Devices/deviceTypes/index.js +145 -0
  40. package/src/react/pages/Devices/deviceTypes/ipCamera.js +35 -0
  41. package/src/react/pages/Devices/deviceTypes/pdv.js +88 -0
  42. package/src/react/pages/Devices/deviceTypes/printer.js +37 -0
  43. package/src/react/pages/Devices/deviceTypes/shared.js +453 -0
  44. package/src/react/pages/Devices/deviceTypes/useDeviceNetworkConnectivity.js +145 -0
  45. package/src/react/pages/Devices.js +183 -0
  46. package/src/react/pages/Devices.styles.js +353 -0
  47. package/src/react/pages/Food99IntegrationPage/components/Food99CatalogTab.js +219 -0
  48. package/src/react/pages/Food99IntegrationPage/components/Food99OverviewTab.js +134 -0
  49. package/src/react/pages/Food99IntegrationPage/components/Food99PreviewModal.js +173 -0
  50. package/src/react/pages/Food99IntegrationPage/components/Food99ProductCard.js +1 -0
  51. package/src/react/pages/Food99IntegrationPage/components/Food99QuickWalletModal.js +181 -0
  52. package/src/react/pages/Food99IntegrationPage/components/Food99SettingsTab.js +306 -0
  53. package/src/react/pages/Food99IntegrationPage/components/Food99StoreTab.js +417 -0
  54. package/src/react/pages/Food99IntegrationPage/index.js +1530 -0
  55. package/src/react/pages/Food99IntegrationPage/styles.js +792 -0
  56. package/src/react/pages/Food99IntegrationPage/utils.js +155 -0
  57. package/src/react/pages/Food99IntegrationPage.js +1 -0
  58. package/src/react/pages/Food99IntegrationPage.styles.js +1 -0
  59. package/src/react/pages/GenericLogPage.js +42 -167
  60. package/src/react/pages/IFoodIntegrationPage/components/IFoodCatalogTab.js +8 -0
  61. package/src/react/pages/IFoodIntegrationPage/components/IFoodOperationsTab.js +420 -0
  62. package/src/react/pages/IFoodIntegrationPage/components/IFoodOverviewTab.js +118 -0
  63. package/src/react/pages/IFoodIntegrationPage/components/IFoodPreviewModal.js +103 -0
  64. package/src/react/pages/IFoodIntegrationPage/components/IFoodProductCard.js +1 -0
  65. package/src/react/pages/IFoodIntegrationPage/components/IFoodStoreTab.js +150 -0
  66. package/src/react/pages/IFoodIntegrationPage/index.js +1298 -0
  67. package/src/react/pages/IFoodIntegrationPage/styles.js +764 -0
  68. package/src/react/pages/IFoodIntegrationPage/utils.js +91 -0
  69. package/src/react/pages/IFoodIntegrationPage.js +1 -0
  70. package/src/react/pages/IFoodIntegrationPage.styles.js +1 -0
  71. package/src/react/pages/Imports.js +214 -166
  72. package/src/react/pages/IntegrationConfigPage.js +744 -0
  73. package/src/react/pages/IntegrationConfigPage.styles.js +269 -0
  74. package/src/react/pages/Integrations.js +299 -0
  75. package/src/react/pages/Integrations.styles.js +130 -0
  76. package/src/react/pages/ManagerOrderNotificationsPage.js +642 -0
  77. package/src/react/pages/MarketplaceIntegrationPage/components/MarketplaceProductCard.js +205 -0
  78. package/src/react/pages/MarketplaceIntegrationPage/components/RemoteMarketplaceMenuTab.js +335 -0
  79. package/src/react/pages/MarketplaceIntegrationPage/index.js +60 -0
  80. package/src/react/pages/MarketplaceIntegrationPage/utils.js +137 -0
  81. package/src/react/pages/MercadoLivreIntegrationPage.js +538 -0
  82. package/src/react/pages/PrinterDeviceDetailPage.js +1916 -0
  83. package/src/react/pages/PrinterDeviceDetailPage.styles.js +223 -0
  84. package/src/react/pages/PrinterDeviceFormPage.js +521 -0
  85. package/src/react/pages/PrinterDeviceFormPage.styles.js +159 -0
  86. package/src/react/pages/WhatsAppConnectionPage.js +459 -0
  87. package/src/react/pages/WhatsAppConnectionPage.styles.js +284 -0
  88. package/src/react/pages/integrationsCatalog.js +399 -0
  89. package/src/react/services/Cielo/Cielo.js +193 -193
  90. package/src/react/utils/categoryContexts.js +46 -0
  91. package/src/react/utils/entityDisplay.js +222 -217
  92. package/src/react/utils/fileUrl.js +39 -20
  93. package/src/react/utils/integrationPage.js +16 -0
  94. package/src/react/utils/runtimeFooter.js +40 -22
  95. package/src/react/utils/runtimeLanguage.js +50 -9
  96. package/src/react/utils/runtimeMenu.js +191 -131
  97. package/src/react/utils/runtimeZoom.js +43 -0
  98. package/src/react/utils/shopConfig.js +27 -15
  99. package/src/react/utils/shopFranchises.js +126 -1
  100. package/src/react/utils/storeColumns.js +23 -4
  101. package/src/react/utils/userAvatar.js +104 -0
  102. package/src/store/categories/index.js +48 -20
  103. package/src/store/device_config/index.js +62 -21
  104. package/src/store/entity_log/index.js +22 -1
  105. package/src/store/imports/customActions.js +51 -0
  106. package/src/store/imports/index.js +89 -88
  107. package/src/store/status/index.js +11 -11
  108. package/src/store/themes/index.js +22 -0
  109. package/src/store/timezones/index.js +3 -1
  110. package/src/tests/browser/manager/connections.spec.js +143 -0
  111. package/src/tests/browser/manager/devices-current.spec.js +343 -0
  112. package/src/tests/browser/manager/mercado-livre-integration.spec.js +268 -0
  113. package/src/tests/react/api/deviceHeaders.test.js +114 -0
  114. package/src/tests/react/components/AddImportModal.test.js +166 -0
  115. package/src/tests/react/components/BottomNavigationBar.config.test.js +20 -0
  116. package/src/tests/react/components/UserAvatar.test.js +52 -0
  117. package/src/tests/react/pages/DevicePickerStyles.test.js +47 -0
  118. package/src/tests/react/pages/Devices/deviceListHelpers.test.js +39 -0
  119. package/src/tests/react/pages/DevicesCurrentDevice.test.js +198 -0
  120. package/src/tests/react/pages/connectionsHelpers.test.js +34 -0
  121. package/src/tests/react/pages/mercadoLivreIntegrationPageContract.test.mjs +16 -0
  122. package/src/tests/react/services/Cielo.test.js +190 -190
  123. package/src/tests/react/store/categoriesOrdering.test.js +26 -0
  124. package/src/tests/react/utils/appDomain.test.js +62 -0
  125. package/src/tests/react/utils/entityDisplay.test.js +2 -2
  126. package/src/tests/react/utils/fileUrl.test.js +3 -3
  127. package/src/tests/react/utils/formatter.test.mjs +33 -0
  128. package/src/tests/react/utils/runtimeFooter.test.js +29 -4
  129. package/src/tests/react/utils/runtimeLanguage.test.js +79 -9
  130. package/src/tests/react/utils/runtimeMenu.test.js +198 -134
  131. package/src/tests/react/utils/runtimeZoom.test.js +38 -0
  132. package/src/tests/react/utils/shopConfig.test.js +10 -9
  133. package/src/tests/react/utils/shopFranchises.test.js +43 -0
  134. package/src/tests/react/utils/translate.discovery.test.mjs +170 -0
  135. package/src/tests/react/utils/translate.test.helpers.mjs +152 -0
  136. package/src/tests/react/utils/translate.test.mjs +141 -349
  137. package/src/tests/react/utils/userAvatar.test.js +63 -0
  138. package/src/utils/appDomain.js +15 -4
  139. package/src/utils/formatter.js +104 -16
  140. package/src/utils/integrationConfigs.js +80 -80
  141. package/src/utils/translate.js +222 -438
  142. package/src/utils/translateDiscovery.js +96 -0
  143. package/src/utils/translateNormalize.js +33 -0
  144. package/src/utils/translatePending.js +92 -0
  145. package/src/utils/translateStorage.js +142 -0
  146. package/.github/agents/developer.agent.md +0 -30
  147. package/.github/agents/devops.agent.md +0 -30
  148. package/.github/agents/qa.agent.md +0 -30
  149. package/.github/agents/security.agent.md +0 -30
  150. package/.github/workflows/npmjs.yml +0 -35
@@ -1,10 +1,62 @@
1
- export default class Formatter {
1
+ /* global Intl */
2
+
3
+ const MOJIBAKE_REPLACEMENTS = [
4
+ ['À', 'À'],
5
+ ['\u00C3\u0081', 'Á'],
6
+ ['Â', 'Â'],
7
+ ['Ã', 'Ã'],
8
+ ['É', 'É'],
9
+ ['Ê', 'Ê'],
10
+ ['Ó', 'Ó'],
11
+ ['Ô', 'Ô'],
12
+ ['Õ', 'Õ'],
13
+ ['Ú', 'Ú'],
14
+ ['á', 'á'],
15
+ ['à', 'à'],
16
+ ['Ã\u00A0', 'à'],
17
+ ['â', 'â'],
18
+ ['ã', 'ã'],
19
+ ['é', 'é'],
20
+ ['ê', 'ê'],
21
+ ['í', 'í'],
22
+ ['ó', 'ó'],
23
+ ['ô', 'ô'],
24
+ ['õ', 'õ'],
25
+ ['ú', 'ú'],
26
+ ['Ç', 'Ç'],
27
+ ['ç', 'ç'],
28
+ ['º', 'º'],
29
+ ['ª', 'ª'],
30
+ ['·', '·'],
31
+ ['→', '→'],
32
+ ['–', '–'],
33
+ ['—', '—'],
34
+ ['‘', "'"],
35
+ ['’', "'"],
36
+ ['“', '"'],
37
+ ['\u00E2\u20AC\u009D', '"'],
38
+ ['Â', ''],
39
+ ];
40
+
41
+ export default class Formatter {
2
42
 
3
43
  /* ================= UTIL ================= */
4
44
 
5
- static onlyNumbers(value) {
6
- return String(value || '').replace(/\D/g, '');
7
- }
45
+ static onlyNumbers(value) {
46
+ return String(value || '').replace(/\D/g, '');
47
+ }
48
+
49
+ static repairMojibake(value) {
50
+ let text = String(value || '');
51
+
52
+ for (let pass = 0; pass < 2; pass += 1) {
53
+ MOJIBAKE_REPLACEMENTS.forEach(([broken, fixed]) => {
54
+ text = text.split(broken).join(fixed);
55
+ });
56
+ }
57
+
58
+ return text;
59
+ }
8
60
 
9
61
  /* ================= DOCUMENTOS ================= */
10
62
 
@@ -402,14 +454,18 @@ export default class Formatter {
402
454
  return `${year}-${month}-${day}`;
403
455
  }
404
456
 
405
- static formatDateYmdTodmY(value, withTime = false) {
406
-
407
- if (!value) return '';
408
-
409
- const date = new Date(value);
410
-
411
- if (isNaN(date.getTime()))
412
- return value;
457
+ static formatDateYmdTodmY(value, withTime = false) {
458
+
459
+ if (!value) return '';
460
+
461
+ const isoOffsetParts = Formatter.parseIsoDateWithNumericOffset(value);
462
+ if (isoOffsetParts)
463
+ return Formatter.formatDatePartsToBR(isoOffsetParts, withTime);
464
+
465
+ const date = new Date(value);
466
+
467
+ if (isNaN(date.getTime()))
468
+ return value;
413
469
 
414
470
  const clientTimeZoneOffset = new Date().getTimezoneOffset();
415
471
 
@@ -430,8 +486,40 @@ export default class Formatter {
430
486
  options.minute = '2-digit';
431
487
  options.second = '2-digit';
432
488
  }
433
-
434
- return date.toLocaleString('pt-BR', options);
435
- }
436
-
489
+
490
+ return date.toLocaleString('pt-BR', options);
491
+ }
492
+
493
+ static parseIsoDateWithNumericOffset(value) {
494
+
495
+ if (typeof value !== 'string')
496
+ return null;
497
+
498
+ const matches = value.match(
499
+ /^(\d{4})-(\d{2})-(\d{2})[T\s](\d{2}):(\d{2})(?::(\d{2})(?:\.\d+)?)?[+-]\d{2}:?\d{2}$/
500
+ );
501
+
502
+ if (!matches)
503
+ return null;
504
+
505
+ return {
506
+ year: matches[1],
507
+ month: matches[2],
508
+ day: matches[3],
509
+ hour: matches[4],
510
+ minute: matches[5],
511
+ second: matches[6] || '00',
512
+ };
513
+ }
514
+
515
+ static formatDatePartsToBR(parts, withTime = false) {
516
+
517
+ const date = `${parts.day}/${parts.month}/${parts.year}`;
518
+
519
+ if (!withTime)
520
+ return date;
521
+
522
+ return `${date}, ${parts.hour}:${parts.minute}:${parts.second}`;
523
+ }
524
+
437
525
  }
@@ -1,80 +1,80 @@
1
- export const CIELO_CONFIG_KEY = 'CIELO';
2
- export const NEW_RELIC_CONFIG_KEY = 'NEW_RELIC';
3
- export const SPOTIFY_CONFIG_KEY = 'SPOTIFY';
4
-
5
- export const DEFAULT_CIELO_CONFIG = {
6
- ACCESS_TOKEN: '',
7
- CLIENT_ID: '',
8
- EMAIL: '',
9
- MERCHANT_CODE: '',
10
- };
11
-
12
- export const DEFAULT_NEW_RELIC_CONFIG = {
13
- LICENSE_KEY: '',
14
- APPLICATION_ID: '',
15
- ACCOUNT_ID: '',
16
- TRUST_KEY: '',
17
- BEACON: 'bam.nr-data.net',
18
- ERROR_BEACON: 'bam.nr-data.net',
19
- };
20
-
21
- export const DEFAULT_SPOTIFY_CONFIG = {
22
- CLIENT_ID: '',
23
- CLIENT_SECRET: '',
24
- };
25
-
26
- const isConfigMap = value =>
27
- value && typeof value === 'object' && !Array.isArray(value);
28
-
29
- const parseJsonValue = (value, fallback) => {
30
- if (value === null || value === undefined || value === '') {
31
- return fallback;
32
- }
33
-
34
- if (typeof value === 'string') {
35
- try {
36
- return JSON.parse(value);
37
- } catch {
38
- return fallback;
39
- }
40
- }
41
-
42
- return value;
43
- };
44
-
45
- const normalizeTextValue = value => String(value || '').trim();
46
-
47
- export const resolveIntegrationConfig = (configs, configKey, defaults) => {
48
- if (!isConfigMap(defaults)) {
49
- return {};
50
- }
51
-
52
- const rawConfig = isConfigMap(configs)
53
- ? parseJsonValue(configs[configKey], {})
54
- : {};
55
- const source = isConfigMap(rawConfig) ? rawConfig : {};
56
-
57
- return Object.keys(defaults).reduce((accumulator, fieldKey) => {
58
- accumulator[fieldKey] = normalizeTextValue(
59
- source[fieldKey] !== undefined ? source[fieldKey] : defaults[fieldKey],
60
- );
61
- return accumulator;
62
- }, {});
63
- };
64
-
65
- export const resolveCieloConfig = configs =>
66
- resolveIntegrationConfig(configs, CIELO_CONFIG_KEY, DEFAULT_CIELO_CONFIG);
67
-
68
- export const resolveNewRelicConfig = configs =>
69
- resolveIntegrationConfig(
70
- configs,
71
- NEW_RELIC_CONFIG_KEY,
72
- DEFAULT_NEW_RELIC_CONFIG,
73
- );
74
-
75
- export const resolveSpotifyConfig = configs =>
76
- resolveIntegrationConfig(
77
- configs,
78
- SPOTIFY_CONFIG_KEY,
79
- DEFAULT_SPOTIFY_CONFIG,
80
- );
1
+ export const CIELO_CONFIG_KEY = 'CIELO';
2
+ export const NEW_RELIC_CONFIG_KEY = 'NEW_RELIC';
3
+ export const SPOTIFY_CONFIG_KEY = 'SPOTIFY';
4
+
5
+ export const DEFAULT_CIELO_CONFIG = {
6
+ ACCESS_TOKEN: '',
7
+ CLIENT_ID: '',
8
+ EMAIL: '',
9
+ MERCHANT_CODE: '',
10
+ };
11
+
12
+ export const DEFAULT_NEW_RELIC_CONFIG = {
13
+ LICENSE_KEY: '',
14
+ APPLICATION_ID: '',
15
+ ACCOUNT_ID: '',
16
+ TRUST_KEY: '',
17
+ BEACON: 'bam.nr-data.net',
18
+ ERROR_BEACON: 'bam.nr-data.net',
19
+ };
20
+
21
+ export const DEFAULT_SPOTIFY_CONFIG = {
22
+ CLIENT_ID: '',
23
+ CLIENT_SECRET: '',
24
+ };
25
+
26
+ const isConfigMap = value =>
27
+ value && typeof value === 'object' && !Array.isArray(value);
28
+
29
+ const parseJsonValue = (value, fallback) => {
30
+ if (value === null || value === undefined || value === '') {
31
+ return fallback;
32
+ }
33
+
34
+ if (typeof value === 'string') {
35
+ try {
36
+ return JSON.parse(value);
37
+ } catch {
38
+ return fallback;
39
+ }
40
+ }
41
+
42
+ return value;
43
+ };
44
+
45
+ const normalizeTextValue = value => String(value || '').trim();
46
+
47
+ export const resolveIntegrationConfig = (configs, configKey, defaults) => {
48
+ if (!isConfigMap(defaults)) {
49
+ return {};
50
+ }
51
+
52
+ const rawConfig = isConfigMap(configs)
53
+ ? parseJsonValue(configs[configKey], {})
54
+ : {};
55
+ const source = isConfigMap(rawConfig) ? rawConfig : {};
56
+
57
+ return Object.keys(defaults).reduce((accumulator, fieldKey) => {
58
+ accumulator[fieldKey] = normalizeTextValue(
59
+ source[fieldKey] !== undefined ? source[fieldKey] : defaults[fieldKey],
60
+ );
61
+ return accumulator;
62
+ }, {});
63
+ };
64
+
65
+ export const resolveCieloConfig = configs =>
66
+ resolveIntegrationConfig(configs, CIELO_CONFIG_KEY, DEFAULT_CIELO_CONFIG);
67
+
68
+ export const resolveNewRelicConfig = configs =>
69
+ resolveIntegrationConfig(
70
+ configs,
71
+ NEW_RELIC_CONFIG_KEY,
72
+ DEFAULT_NEW_RELIC_CONFIG,
73
+ );
74
+
75
+ export const resolveSpotifyConfig = configs =>
76
+ resolveIntegrationConfig(
77
+ configs,
78
+ SPOTIFY_CONFIG_KEY,
79
+ DEFAULT_SPOTIFY_CONFIG,
80
+ );