@controleonline/ui-common 1.2.71 → 1.2.76

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 +164 -104
  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 +2865 -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
@@ -27,7 +27,7 @@ function resolveCompanyLanguageCode(company) {
27
27
  return ''
28
28
  }
29
29
 
30
- function resolveConfiguredLanguage({
30
+ function resolveConfiguredLanguage({
31
31
  currentCompany,
32
32
  defaultCompany,
33
33
  currentConfig,
@@ -40,11 +40,52 @@ function resolveConfiguredLanguage({
40
40
  normalizeLanguageCode(currentConfig?.language) ||
41
41
  normalizeLanguageCode(sessionData?.language) ||
42
42
  fallback
43
- )
44
- }
45
-
46
- module.exports = {
47
- normalizeLanguageCode,
48
- resolveCompanyLanguageCode,
49
- resolveConfiguredLanguage,
50
- }
43
+ )
44
+ }
45
+
46
+ function buildTranslationBootstrapKey({
47
+ language,
48
+ currentCompanyId,
49
+ defaultCompanyId,
50
+ } = {}) {
51
+ const normalizedLanguage = normalizeLanguageCode(language)
52
+ const normalizedCurrentCompanyId = String(currentCompanyId || '').trim()
53
+ const normalizedDefaultCompanyId = String(defaultCompanyId || '').trim()
54
+
55
+ if (!normalizedLanguage || !normalizedCurrentCompanyId) {
56
+ return ''
57
+ }
58
+
59
+ return [
60
+ normalizedLanguage,
61
+ normalizedCurrentCompanyId,
62
+ normalizedDefaultCompanyId,
63
+ ].join('::')
64
+ }
65
+
66
+ function isTranslationBootstrapReady({
67
+ activeKey,
68
+ expectedKey,
69
+ required,
70
+ ready,
71
+ translator,
72
+ } = {}) {
73
+ if (!required) {
74
+ return true
75
+ }
76
+
77
+ return Boolean(
78
+ expectedKey &&
79
+ activeKey === expectedKey &&
80
+ ready === true &&
81
+ typeof translator?.t === 'function',
82
+ )
83
+ }
84
+
85
+ module.exports = {
86
+ buildTranslationBootstrapKey,
87
+ isTranslationBootstrapReady,
88
+ normalizeLanguageCode,
89
+ resolveCompanyLanguageCode,
90
+ resolveConfiguredLanguage,
91
+ }
@@ -3,30 +3,30 @@ export const normalizeAppType = value => {
3
3
  return normalized || 'MANAGER';
4
4
  };
5
5
 
6
- const RUNTIME_MENU_ICON_ALIASES = {
7
- shopping_cart: 'shopping-cart',
8
- account_balance: 'dollar-sign',
9
- account_balance_wallet: 'credit-card',
10
- };
11
-
12
- export const normalizeRuntimeMenuType = (value, fallback = 'home') => {
13
- const normalized = String(value || '').trim().toLowerCase();
14
- return normalized || fallback;
15
- };
16
-
17
- const normalizeRuntimeMenuItem = (menu = {}) => ({
18
- ...menu,
19
- icon: normalizeRuntimeMenuIcon(menu?.icon),
20
- menuKey: String(menu?.menuKey || menu?.menu_key || '').trim(),
21
- menuType: normalizeRuntimeMenuType(menu?.menuType || menu?.menu_type),
22
- routeParams:
23
- menu?.routeParams && typeof menu.routeParams === 'object'
24
- ? menu.routeParams
25
- : {},
26
- sortOrder: Number(menu?.sortOrder ?? menu?.sort_order ?? 0),
27
- });
28
-
29
- const MANAGER_RUNTIME_MENU_FALLBACK = [
6
+ const RUNTIME_MENU_ICON_ALIASES = {
7
+ shopping_cart: 'shopping-cart',
8
+ account_balance: 'dollar-sign',
9
+ account_balance_wallet: 'credit-card',
10
+ };
11
+
12
+ export const normalizeRuntimeMenuType = (value, fallback = 'home') => {
13
+ const normalized = String(value || '').trim().toLowerCase();
14
+ return normalized || fallback;
15
+ };
16
+
17
+ const normalizeRuntimeMenuItem = (menu = {}) => ({
18
+ ...menu,
19
+ icon: normalizeRuntimeMenuIcon(menu?.icon),
20
+ menuKey: String(menu?.menuKey || menu?.menu_key || '').trim(),
21
+ menuType: normalizeRuntimeMenuType(menu?.menuType || menu?.menu_type),
22
+ routeParams:
23
+ menu?.routeParams && typeof menu.routeParams === 'object'
24
+ ? menu.routeParams
25
+ : {},
26
+ sortOrder: Number(menu?.sortOrder ?? menu?.sort_order ?? 0),
27
+ });
28
+
29
+ const MANAGER_RUNTIME_MENU_FALLBACK = [
30
30
  {
31
31
  id: 'manager-financeiro',
32
32
  label: 'Financeiro',
@@ -68,16 +68,25 @@ const MANAGER_RUNTIME_MENU_FALLBACK = [
68
68
  },
69
69
  ],
70
70
  },
71
- {
72
- id: 'manager-comercial',
73
- label: 'Comercial',
74
- icon: 'users',
75
- menus: [
76
- {
77
- id: 'clients',
78
- menuKey: 'clients',
79
- label: 'Cadastro de clientes',
80
- route: 'ClientsIndex',
71
+ {
72
+ id: 'manager-comercial',
73
+ label: 'Comercial',
74
+ icon: 'users',
75
+ menus: [
76
+ {
77
+ id: 'products',
78
+ menuKey: 'products',
79
+ label: 'Produtos',
80
+ route: 'ProductsPage',
81
+ icon: 'package',
82
+ color: '#16A34A',
83
+ sortOrder: 25,
84
+ },
85
+ {
86
+ id: 'clients',
87
+ menuKey: 'clients',
88
+ label: 'Cadastro de clientes',
89
+ route: 'ClientsIndex',
81
90
  icon: 'users',
82
91
  color: '#16A34A',
83
92
  sortOrder: 30,
@@ -125,76 +134,127 @@ const MANAGER_RUNTIME_MENU_FALLBACK = [
125
134
  color: '#64748B',
126
135
  sortOrder: 60,
127
136
  },
137
+ {
138
+ id: 'product_showcases',
139
+ menuKey: 'product_showcases',
140
+ label: 'Vitrines de preços',
141
+ route: 'ProductShowcasesPage',
142
+ icon: 'grid',
143
+ color: '#0F766E',
144
+ sortOrder: 65,
145
+ },
128
146
  ],
129
- },
130
- ];
131
-
132
- const ADMIN_RUNTIME_MENU_FALLBACK = [
133
- {
134
- id: 'admin-configuracoes',
135
- label: 'Configuracoes',
136
- icon: 'settings',
137
- menus: [
147
+ },
148
+ ];
149
+
150
+ const ADMIN_RUNTIME_MENU_FALLBACK = [
151
+ {
152
+ id: 'admin-configuracoes',
153
+ label: 'Configuracoes',
154
+ icon: 'settings',
155
+ menus: [
156
+ {
157
+ id: 'menu_access',
158
+ menuKey: 'menu_access',
159
+ label: 'Menus por perfil',
160
+ route: 'MenuAccessConfigPage',
161
+ icon: 'list',
162
+ color: '#64748B',
163
+ sortOrder: 10,
164
+ },
165
+ {
166
+ id: 'test_results',
167
+ menuKey: 'test_results',
168
+ label: 'Resultados de testes',
169
+ route: 'TestsPlaygroundPage',
170
+ icon: 'clipboard',
171
+ color: '#0EA5E9',
172
+ sortOrder: 20,
173
+ },
138
174
  {
139
- id: 'menu_access',
140
- menuKey: 'menu_access',
141
- label: 'Menus por perfil',
142
- route: 'MenuAccessConfigPage',
143
- icon: 'list',
144
- color: '#64748B',
145
- sortOrder: 10,
175
+ id: 'tenancies',
176
+ menuKey: 'tenancies',
177
+ label: 'Tenancies',
178
+ route: 'TenanciesPage',
179
+ icon: 'server',
180
+ color: '#0F766E',
181
+ sortOrder: 25,
146
182
  },
147
183
  {
148
- id: 'test_results',
149
- menuKey: 'test_results',
150
- label: 'Resultados de testes',
151
- route: 'TestsPlaygroundPage',
152
- icon: 'clipboard',
153
- color: '#0EA5E9',
154
- sortOrder: 20,
155
- },
156
- ],
157
- },
158
- ];
159
-
160
- const cloneRuntimeMenuModules = modules =>
161
- (Array.isArray(modules) ? modules : []).map(module => ({
162
- ...module,
163
- menus: Array.isArray(module?.menus)
164
- ? module.menus.map(menu => normalizeRuntimeMenuItem(menu))
165
- : [],
166
- }));
184
+ id: 'people_domains',
185
+ menuKey: 'people_domains',
186
+ label: 'Domínios',
187
+ route: 'PeopleDomainsPage',
188
+ icon: 'globe',
189
+ color: '#0EA5E9',
190
+ sortOrder: 30,
191
+ },
192
+ {
193
+ id: 'flowcharts',
194
+ menuKey: 'flowcharts',
195
+ label: 'Fluxogramas',
196
+ route: 'FlowchartsPage',
197
+ icon: 'git-branch',
198
+ color: '#0F766E',
199
+ sortOrder: 40,
200
+ },
201
+ ],
202
+ },
203
+ ];
167
204
 
168
- export const normalizeRuntimeMenuIcon = value => {
169
- const normalized = String(value || '').trim();
170
- if (!normalized) return '';
205
+ const cloneRuntimeMenuModules = modules =>
206
+ (Array.isArray(modules) ? modules : []).map(module => ({
207
+ ...module,
208
+ menus: Array.isArray(module?.menus)
209
+ ? module.menus.map(menu => normalizeRuntimeMenuItem(menu))
210
+ : [],
211
+ }));
171
212
 
172
- return RUNTIME_MENU_ICON_ALIASES[normalized.toLowerCase()] || normalized;
173
- };
213
+ export const normalizeRuntimeMenuIcon = value => {
214
+ const normalized = String(value || '').trim();
215
+ if (!normalized) return '';
216
+
217
+ return RUNTIME_MENU_ICON_ALIASES[normalized.toLowerCase()] || normalized;
218
+ };
219
+
220
+ const resolveRuntimeModuleSortOrder = module => {
221
+ const explicitSortOrder = Number(module?.sortOrder ?? module?.sort_order);
222
+ if (Number.isFinite(explicitSortOrder)) {
223
+ return explicitSortOrder;
224
+ }
225
+
226
+ return 0;
227
+ };
174
228
 
175
- export const normalizeRuntimeMenuResponse = (
176
- result,
177
- {appType, allowFallback = true} = {},
178
- ) => {
229
+ export const normalizeRuntimeMenuResponse = (
230
+ result,
231
+ {appType, allowFallback = true} = {},
232
+ ) => {
179
233
  const modules =
180
234
  result?.response?.data?.modules ||
181
235
  result?.data?.modules ||
182
236
  result?.modules ||
183
237
  {};
184
238
 
185
- const normalizedModules = Object.values(modules)
186
- .map(module => ({
239
+ const normalizedModules = Object.values(modules)
240
+ .map(module => ({
187
241
  ...module,
188
242
  icon: normalizeRuntimeMenuIcon(module?.icon),
243
+ sortOrder: resolveRuntimeModuleSortOrder(module),
189
244
  menus: (Array.isArray(module?.menus) ? module.menus : [])
190
245
  .map(menu => normalizeRuntimeMenuItem(menu))
191
246
  .sort((left, right) => {
192
- const orderDiff = Number(left?.sortOrder || 0) - Number(right?.sortOrder || 0);
193
- if (orderDiff !== 0) return orderDiff;
194
- return String(left?.label || '').localeCompare(String(right?.label || ''));
195
- }),
196
- }))
197
- .filter(module => module.menus.length > 0);
247
+ const orderDiff = Number(left?.sortOrder || 0) - Number(right?.sortOrder || 0);
248
+ if (orderDiff !== 0) return orderDiff;
249
+ return String(left?.label || '').localeCompare(String(right?.label || ''));
250
+ }),
251
+ }))
252
+ .sort((left, right) => {
253
+ const orderDiff = Number(left?.sortOrder || 0) - Number(right?.sortOrder || 0);
254
+ if (orderDiff !== 0) return orderDiff;
255
+ return String(left?.label || '').localeCompare(String(right?.label || ''));
256
+ })
257
+ .filter(module => module.menus.length > 0);
198
258
 
199
259
  if (normalizedModules.length > 0) {
200
260
  return normalizedModules;
@@ -202,51 +262,51 @@ export const normalizeRuntimeMenuResponse = (
202
262
 
203
263
  const normalizedAppType = String(appType || '').trim().toUpperCase();
204
264
 
205
- if (allowFallback && normalizedAppType === 'MANAGER') {
206
- return cloneRuntimeMenuModules(MANAGER_RUNTIME_MENU_FALLBACK);
207
- }
208
-
209
- if (allowFallback && normalizedAppType === 'ADMIN') {
210
- return cloneRuntimeMenuModules(ADMIN_RUNTIME_MENU_FALLBACK);
211
- }
212
-
213
- return [];
214
- };
215
-
216
- export const filterRuntimeMenuModulesByType = (menus, menuType) => {
217
- const normalizedMenuType =
218
- menuType === null || menuType === undefined || String(menuType).trim() === ''
219
- ? null
220
- : normalizeRuntimeMenuType(menuType, '');
221
-
222
- const modules = cloneRuntimeMenuModules(menus);
223
- if (!normalizedMenuType) {
224
- return modules;
225
- }
226
-
227
- return modules
228
- .map(module => ({
229
- ...module,
230
- menus: Array.isArray(module?.menus)
231
- ? module.menus.filter(
232
- menu => normalizeRuntimeMenuType(menu?.menuType, '') === normalizedMenuType,
233
- )
234
- : [],
235
- }))
236
- .filter(module => module.menus.length > 0);
237
- };
238
-
239
- export const flattenRuntimeMenuItemsByType = (menus, menuType) =>
240
- filterRuntimeMenuModulesByType(menus, menuType).flatMap(module =>
241
- Array.isArray(module?.menus) ? module.menus : [],
242
- );
243
-
244
- export const resolveRuntimeMenuLabel = (menu, translate) =>
245
- translate?.('menu', 'menu', menu?.menuKey) || menu?.label || menu?.menuKey || '';
246
-
247
- export const getRuntimeMenuRoutes = menus =>
248
- new Set(
249
- (Array.isArray(menus) ? menus : [])
265
+ if (allowFallback && normalizedAppType === 'MANAGER') {
266
+ return cloneRuntimeMenuModules(MANAGER_RUNTIME_MENU_FALLBACK);
267
+ }
268
+
269
+ if (allowFallback && normalizedAppType === 'ADMIN') {
270
+ return cloneRuntimeMenuModules(ADMIN_RUNTIME_MENU_FALLBACK);
271
+ }
272
+
273
+ return [];
274
+ };
275
+
276
+ export const filterRuntimeMenuModulesByType = (menus, menuType) => {
277
+ const normalizedMenuType =
278
+ menuType === null || menuType === undefined || String(menuType).trim() === ''
279
+ ? null
280
+ : normalizeRuntimeMenuType(menuType, '');
281
+
282
+ const modules = cloneRuntimeMenuModules(menus);
283
+ if (!normalizedMenuType) {
284
+ return modules;
285
+ }
286
+
287
+ return modules
288
+ .map(module => ({
289
+ ...module,
290
+ menus: Array.isArray(module?.menus)
291
+ ? module.menus.filter(
292
+ menu => normalizeRuntimeMenuType(menu?.menuType, '') === normalizedMenuType,
293
+ )
294
+ : [],
295
+ }))
296
+ .filter(module => module.menus.length > 0);
297
+ };
298
+
299
+ export const flattenRuntimeMenuItemsByType = (menus, menuType) =>
300
+ filterRuntimeMenuModulesByType(menus, menuType).flatMap(module =>
301
+ Array.isArray(module?.menus) ? module.menus : [],
302
+ );
303
+
304
+ export const resolveRuntimeMenuLabel = (menu, translate) =>
305
+ translate?.('menu', 'menu', menu?.menuKey) || menu?.label || menu?.menuKey || '';
306
+
307
+ export const getRuntimeMenuRoutes = menus =>
308
+ new Set(
309
+ (Array.isArray(menus) ? menus : [])
250
310
  .flatMap(module => (Array.isArray(module?.menus) ? module.menus : []))
251
311
  .map(menu => menu?.route)
252
312
  .filter(Boolean),
@@ -0,0 +1,43 @@
1
+ export const DEFAULT_RUNTIME_ZOOM_PERCENT = 100;
2
+ export const MIN_RUNTIME_ZOOM_PERCENT = 50;
3
+ export const MAX_RUNTIME_ZOOM_PERCENT = 150;
4
+
5
+ export const normalizeRuntimeZoomPercent = value => {
6
+ if (value === undefined || value === null || value === '') {
7
+ return DEFAULT_RUNTIME_ZOOM_PERCENT;
8
+ }
9
+
10
+ const numericValue = Number(String(value).replace('%', '').trim());
11
+
12
+ if (!Number.isFinite(numericValue)) {
13
+ return DEFAULT_RUNTIME_ZOOM_PERCENT;
14
+ }
15
+
16
+ return Math.min(
17
+ MAX_RUNTIME_ZOOM_PERCENT,
18
+ Math.max(MIN_RUNTIME_ZOOM_PERCENT, numericValue),
19
+ );
20
+ };
21
+
22
+ export const resolveRuntimeZoomScale = value =>
23
+ normalizeRuntimeZoomPercent(value) / 100;
24
+
25
+ export const buildRuntimeZoomStyle = (value, {isWeb = false} = {}) => {
26
+ const scale = resolveRuntimeZoomScale(value);
27
+
28
+ if (scale === 1) {
29
+ return null;
30
+ }
31
+
32
+ if (isWeb) {
33
+ return {zoom: scale};
34
+ }
35
+
36
+ const inverseSize = `${100 / scale}%`;
37
+
38
+ return {
39
+ height: inverseSize,
40
+ transform: [{scale}],
41
+ width: inverseSize,
42
+ };
43
+ };
@@ -38,12 +38,14 @@ export const SHOP_CATALOG_PRODUCT_TYPES_CONFIG_KEY =
38
38
  'shop-catalog-product-types';
39
39
  export const SHOP_GOOGLE_MAPS_API_KEY_CONFIG_KEY =
40
40
  'shop-google-maps-api-key';
41
- export const SHOP_FRANCHISE_PIN_ICON_URL_CONFIG_KEY =
42
- 'shop-franchise-pin-icon-url';
43
41
  export const SHOP_FRANCHISE_VISIBLE_COMPANY_IDS_CONFIG_KEY =
44
42
  'shop-franchise-visible-company-ids';
45
- export const SHOP_FRANCHISE_VISIBLE_ADDRESS_IDS_CONFIG_KEY =
46
- 'shop-franchise-visible-address-ids';
43
+ export const SHOP_FRANCHISE_VISIBLE_ADDRESS_IDS_CONFIG_KEY =
44
+ 'shop-franchise-visible-address-ids';
45
+ export const SHOP_FRANCHISE_ADDRESS_CATEGORY_IDS_CONFIG_KEY =
46
+ 'shop-franchise-address-category-ids';
47
+ export const SHOP_FRANCHISE_ADDRESS_CATEGORY_CONTEXT =
48
+ 'shop-franchise-address';
47
49
  export const SHOP_LOYALTY_COUPONS_ENABLED_CONFIG_KEY =
48
50
  'shop-loyalty-coupons-enabled';
49
51
  export const SHOP_LOYALTY_PRODUCT_IDS_CONFIG_KEY =
@@ -52,8 +54,13 @@ export const SHOP_LOYALTY_REQUIRED_SALES_CONFIG_KEY =
52
54
  'shop-loyalty-required-sales';
53
55
  export const SHOP_LOYALTY_GIFT_PRODUCT_ID_CONFIG_KEY =
54
56
  'shop-loyalty-gift-product-id';
55
- export const SHOP_LOYALTY_STAMP_ICON_URL_CONFIG_KEY =
56
- 'shop-loyalty-stamp-icon-url';
57
+ export const SHOP_SHOWCASE_TYPE_SETTING_KEY = 'shop_type';
58
+ export const SHOP_SHOWCASE_TYPE_MENU = 'menu';
59
+ export const SHOP_SHOWCASE_TYPE_ECOMMERCE = 'ecommerce';
60
+ export const SHOP_SHOWCASE_TYPE_OPTIONS = [
61
+ SHOP_SHOWCASE_TYPE_MENU,
62
+ SHOP_SHOWCASE_TYPE_ECOMMERCE,
63
+ ];
57
64
 
58
65
  export const normalizeShopEntityId = value => {
59
66
  if (!value) {
@@ -182,6 +189,14 @@ export const normalizeShopMoneyConfig = (value, fallback = 0) => {
182
189
 
183
190
  return Number.isFinite(normalized) ? Math.max(0, normalized) : fallback;
184
191
  };
192
+
193
+ export const normalizeShopShowcaseType = value => {
194
+ const normalized = String(value || '').trim().toLowerCase();
195
+
196
+ return SHOP_SHOWCASE_TYPE_OPTIONS.includes(normalized)
197
+ ? normalized
198
+ : SHOP_SHOWCASE_TYPE_MENU;
199
+ };
185
200
 
186
201
  export const getEnabledShopHomeOptions = ({
187
202
  salesPageEnabled,
@@ -274,15 +289,15 @@ export const resolveShopSettings = configs => {
274
289
  googleMapsApiKey: normalizeShopTextConfig(
275
290
  configMap[SHOP_GOOGLE_MAPS_API_KEY_CONFIG_KEY],
276
291
  ),
277
- franchisePinIconUrl: normalizeShopTextConfig(
278
- configMap[SHOP_FRANCHISE_PIN_ICON_URL_CONFIG_KEY],
279
- ),
280
292
  visibleFranchiseCompanyIds: normalizeShopEntityIds(
281
293
  configMap[SHOP_FRANCHISE_VISIBLE_COMPANY_IDS_CONFIG_KEY],
282
294
  ),
283
- visibleFranchiseAddressIds: normalizeShopEntityIds(
284
- configMap[SHOP_FRANCHISE_VISIBLE_ADDRESS_IDS_CONFIG_KEY],
285
- ),
295
+ visibleFranchiseAddressIds: normalizeShopEntityIds(
296
+ configMap[SHOP_FRANCHISE_VISIBLE_ADDRESS_IDS_CONFIG_KEY],
297
+ ),
298
+ franchiseAddressCategoryIds: normalizeShopEntityIds(
299
+ configMap[SHOP_FRANCHISE_ADDRESS_CATEGORY_IDS_CONFIG_KEY],
300
+ ),
286
301
  loyaltyProductIds: normalizeShopEntityIds(
287
302
  configMap[SHOP_LOYALTY_PRODUCT_IDS_CONFIG_KEY],
288
303
  ),
@@ -292,9 +307,6 @@ export const resolveShopSettings = configs => {
292
307
  loyaltyGiftProductId: normalizeShopEntityId(
293
308
  configMap[SHOP_LOYALTY_GIFT_PRODUCT_ID_CONFIG_KEY],
294
309
  ),
295
- loyaltyStampIconUrl: normalizeShopTextConfig(
296
- configMap[SHOP_LOYALTY_STAMP_ICON_URL_CONFIG_KEY],
297
- ),
298
310
  };
299
311
  };
300
312