@controleonline/ui-common 1.2.70
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/.github/agents/developer.agent.md +30 -0
- package/.github/agents/devops.agent.md +30 -0
- package/.github/agents/qa.agent.md +30 -0
- package/.github/agents/security.agent.md +30 -0
- package/.github/workflows/npmjs.yml +35 -0
- package/.github/workflows/pull-request-checks.yml +19 -0
- package/.scrutinizer.yml +24 -0
- package/FUNDING.yml +1 -0
- package/package.json +28 -0
- package/src/api/fetch.js +74 -0
- package/src/api/index.js +155 -0
- package/src/api/localDB.js +131 -0
- package/src/api/queue.js +66 -0
- package/src/react/assets/tap.mp3 +0 -0
- package/src/react/components/AddImportModal.js +157 -0
- package/src/react/components/AddImportModal.styles.js +81 -0
- package/src/react/components/BackgroundRuntimeBridge.js +219 -0
- package/src/react/components/BottomNavigationBar.config.js +238 -0
- package/src/react/components/BottomNavigationBar.js +120 -0
- package/src/react/components/BottomNavigationBar.styles.js +110 -0
- package/src/react/components/CategoryForm.js +572 -0
- package/src/react/components/CategoryForm.styles.js +334 -0
- package/src/react/components/ConfirmModal.js +24 -0
- package/src/react/components/ConfirmModal.styles.js +43 -0
- package/src/react/components/ContextHelpButton.js +69 -0
- package/src/react/components/ContextHelpButton.styles.js +62 -0
- package/src/react/components/DefaultProvider.native.js +848 -0
- package/src/react/components/DefaultProvider.styles.js +21 -0
- package/src/react/components/DefaultProvider.web.js +909 -0
- package/src/react/components/DeliveryPushBridge.native.js +314 -0
- package/src/react/components/DeliveryPushBridge.web.js +5 -0
- package/src/react/components/DeviceAlertSoundService.js +499 -0
- package/src/react/components/EntityLogContent.js +909 -0
- package/src/react/components/EntityLogContent.styles.js +400 -0
- package/src/react/components/EventBus.js +12 -0
- package/src/react/components/KioskModeBridge.js +65 -0
- package/src/react/components/LauncherModeBridge.js +47 -0
- package/src/react/components/LinkedOrderProductsTab.js +388 -0
- package/src/react/components/LinkedOrderProductsTab.styles.js +180 -0
- package/src/react/components/ManagerPushBridge.native.js +345 -0
- package/src/react/components/MessageService.js +314 -0
- package/src/react/components/Paywall/Google.js +89 -0
- package/src/react/components/PrintService.js +778 -0
- package/src/react/components/ProductCatalogCacheService.js +45 -0
- package/src/react/components/RemoteCheckoutService.js +292 -0
- package/src/react/components/RuntimeBottomNavigationBar.js +151 -0
- package/src/react/components/RuntimeInfoFooter.js +214 -0
- package/src/react/components/RuntimeInfoFooter.styles.js +56 -0
- package/src/react/components/SystemErrorToast.js +29 -0
- package/src/react/components/SystemErrorToast.styles.js +38 -0
- package/src/react/components/TouchFeedbackProvider.js +65 -0
- package/src/react/components/UnifiedPaymentBar.js +155 -0
- package/src/react/components/UnifiedPaymentBar.styles.js +174 -0
- package/src/react/components/WebsocketListener.native.js +487 -0
- package/src/react/components/WebsocketListener.web.js +102 -0
- package/src/react/components/inputs/IdInput.js +49 -0
- package/src/react/components/inputs/IdInput.styles.js +26 -0
- package/src/react/components/inputs/InvoiceDueDateFilterInput.js +74 -0
- package/src/react/components/inputs/InvoiceDueDateFilterInput.styles.js +34 -0
- package/src/react/components/inputs/InvoiceDueDateRangeFilterInput.js +115 -0
- package/src/react/components/inputs/InvoiceDueDateRangeFilterInput.styles.js +39 -0
- package/src/react/components/lists/CategoriesList.js +56 -0
- package/src/react/components/lists/PaymentTypeList.js +55 -0
- package/src/react/components/lists/ReceiverList.js +56 -0
- package/src/react/components/lists/SelectList.styles.js +18 -0
- package/src/react/components/lists/StatusList.js +55 -0
- package/src/react/components/lists/WalletList.js +54 -0
- package/src/react/components/radio/Spotify.js +144 -0
- package/src/react/components/radio/Spotify.styles.js +32 -0
- package/src/react/components/radio/YouTube.js +82 -0
- package/src/react/components/radio/YouTube.styles.js +16 -0
- package/src/react/components/toastConfig.js +16 -0
- package/src/react/config/deviceConfigBootstrap.js +571 -0
- package/src/react/index.js +4 -0
- package/src/react/localStorage.js +30 -0
- package/src/react/pages/EntityLogPage.js +124 -0
- package/src/react/pages/EntityLogPage.styles.js +17 -0
- package/src/react/pages/GenericLogPage.js +760 -0
- package/src/react/pages/GenericLogPage.styles.js +401 -0
- package/src/react/pages/Imports.js +361 -0
- package/src/react/pages/Imports.styles.js +223 -0
- package/src/react/pages/SettingsPage/PaymentTypesByWalletTab.js +462 -0
- package/src/react/pages/SettingsPage/index.js +1171 -0
- package/src/react/pages/SettingsPage/index.styles.js +122 -0
- package/src/react/print/jobs.js +147 -0
- package/src/react/print/providers/local.js +53 -0
- package/src/react/print/providers/remote.js +81 -0
- package/src/react/print/selection.js +296 -0
- package/src/react/print/usePrintButtonController.js +474 -0
- package/src/react/router/routes.js +42 -0
- package/src/react/services/NetworkPrinterService.native.js +391 -0
- package/src/react/services/NetworkPrinterService.web.js +15 -0
- package/src/react/stores/index.js +128 -0
- package/src/react/stores/storeErrorBridge.js +36 -0
- package/src/react/utils/backgroundRuntimeRegistration.js +69 -0
- package/src/react/utils/cashPayment.js +87 -0
- package/src/react/utils/commercialDocumentOrders.js +269 -0
- package/src/react/utils/dateRangeFilter.js +264 -0
- package/src/react/utils/deviceRuntime.js +193 -0
- package/src/react/utils/entityDisplay.js +231 -0
- package/src/react/utils/entityLog.js +649 -0
- package/src/react/utils/fileUrl.js +102 -0
- package/src/react/utils/frontendDebugLog.js +45 -0
- package/src/react/utils/googleMapsConfig.js +49 -0
- package/src/react/utils/importStatus.js +100 -0
- package/src/react/utils/invoiceDueDateMessages.js +14 -0
- package/src/react/utils/invoicePresentation.js +46 -0
- package/src/react/utils/logSettings.js +143 -0
- package/src/react/utils/maintenanceSettings.js +53 -0
- package/src/react/utils/managerOrderNotifications.js +523 -0
- package/src/react/utils/mapNavigation.js +76 -0
- package/src/react/utils/menuCatalogConfig.js +8 -0
- package/src/react/utils/menuCatalogDownload.js +157 -0
- package/src/react/utils/networkCameraDevices.js +175 -0
- package/src/react/utils/networkDeviceProfiles.js +135 -0
- package/src/react/utils/normalizedCatalogDownload.js +157 -0
- package/src/react/utils/notificationNavigation.js +94 -0
- package/src/react/utils/notificationSound.js +42 -0
- package/src/react/utils/paymentDevices.js +397 -0
- package/src/react/utils/paymentGatewayExecution.js +91 -0
- package/src/react/utils/paymentOptions.js +88 -0
- package/src/react/utils/peopleDisplay.js +39 -0
- package/src/react/utils/printerDevices.js +465 -0
- package/src/react/utils/remotePayment.js +61 -0
- package/src/react/utils/runtimeFooter.js +475 -0
- package/src/react/utils/runtimeLanguage.js +50 -0
- package/src/react/utils/runtimeMenu.js +224 -0
- package/src/react/utils/screenMetrics.js +30 -0
- package/src/react/utils/shopConfig.js +294 -0
- package/src/react/utils/shopFranchises.js +114 -0
- package/src/react/utils/socketRuntimePipeline.js +454 -0
- package/src/react/utils/spoolAckTracker.js +77 -0
- package/src/react/utils/storeColumns.js +427 -0
- package/src/react/utils/systemErrorChannel.js +109 -0
- package/src/react/utils/systemErrorMessage.js +67 -0
- package/src/react/utils/toastPresentation.js +53 -0
- package/src/react/utils/websocketSharedRuntime.js +826 -0
- package/src/store/acl/getters.js +4 -0
- package/src/store/acl/index.js +19 -0
- package/src/store/acl/mutation_types.js +4 -0
- package/src/store/acl/mutations.js +17 -0
- package/src/store/address/city.js +22 -0
- package/src/store/categories/category_file/index.js +25 -0
- package/src/store/categories/index.js +93 -0
- package/src/store/configs/customActions.js +131 -0
- package/src/store/configs/index.js +25 -0
- package/src/store/connections/customActions.js +26 -0
- package/src/store/connections/index.js +124 -0
- package/src/store/device/index.js +22 -0
- package/src/store/device_config/customActions.js +190 -0
- package/src/store/device_config/index.js +28 -0
- package/src/store/entity_log/customActions.js +63 -0
- package/src/store/entity_log/index.js +25 -0
- package/src/store/extra/data.js +85 -0
- package/src/store/extra/fields.js +88 -0
- package/src/store/file/actions.js +27 -0
- package/src/store/file/index.js +24 -0
- package/src/store/imports/index.js +88 -0
- package/src/store/print/customActions.js +251 -0
- package/src/store/print/index.js +28 -0
- package/src/store/printer/customActions.js +54 -0
- package/src/store/printer/index.js +26 -0
- package/src/store/runtime_debug/customActions.js +71 -0
- package/src/store/runtime_debug/index.js +30 -0
- package/src/store/status/index.js +65 -0
- package/src/store/timezones/index.js +43 -0
- package/src/store/websocket/customActions.js +24 -0
- package/src/store/websocket/index.js +28 -0
- package/src/tests/react/components/LauncherModeBridge.test.js +93 -0
- package/src/tests/react/config/deviceConfigBootstrap.test.js +337 -0
- package/src/tests/react/print/localPrintProvider.test.js +45 -0
- package/src/tests/react/utils/backgroundRuntimeRegistration.test.js +123 -0
- package/src/tests/react/utils/cashPayment.test.js +41 -0
- package/src/tests/react/utils/dateRangeFilter.test.mjs +29 -0
- package/src/tests/react/utils/entityDisplay.test.js +18 -0
- package/src/tests/react/utils/googleMapsConfig.test.js +32 -0
- package/src/tests/react/utils/importStatus.test.js +85 -0
- package/src/tests/react/utils/invoicePresentation.test.mjs +40 -0
- package/src/tests/react/utils/managerOrderNotifications.test.js +127 -0
- package/src/tests/react/utils/mapNavigation.test.js +58 -0
- package/src/tests/react/utils/notificationNavigation.test.js +39 -0
- package/src/tests/react/utils/notificationSound.test.js +27 -0
- package/src/tests/react/utils/paymentDevices.test.js +88 -0
- package/src/tests/react/utils/runtimeFooter.test.js +429 -0
- package/src/tests/react/utils/runtimeLanguage.test.js +80 -0
- package/src/tests/react/utils/runtimeMenu.test.js +174 -0
- package/src/tests/react/utils/shopFranchises.test.js +82 -0
- package/src/tests/react/utils/socketRuntimePipeline.test.js +124 -0
- package/src/tests/react/utils/spoolAckTracker.test.js +40 -0
- package/src/tests/react/utils/storeErrorBridge.test.js +66 -0
- package/src/tests/react/utils/systemErrorChannel.test.js +58 -0
- package/src/tests/react/utils/systemErrorMessage.test.js +59 -0
- package/src/tests/react/utils/toastPresentation.test.js +75 -0
- package/src/tests/react/utils/translate.test.mjs +396 -0
- package/src/tests/react/utils/websocketSharedRuntime.test.js +245 -0
- package/src/utils/apiEntryPoint.js +31 -0
- package/src/utils/appDomain.js +50 -0
- package/src/utils/config.js +14 -0
- package/src/utils/formatter.js +419 -0
- package/src/utils/integrationConfigs.js +79 -0
- package/src/utils/methods.js +23 -0
- package/src/utils/oauth.js +42 -0
- package/src/utils/translate.js +620 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
export const normalizeAppType = value => {
|
|
2
|
+
const normalized = String(value || '').trim().toUpperCase();
|
|
3
|
+
return normalized || 'MANAGER';
|
|
4
|
+
};
|
|
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 = [
|
|
30
|
+
{
|
|
31
|
+
id: 'manager-financeiro',
|
|
32
|
+
label: 'Financeiro',
|
|
33
|
+
icon: 'dollar-sign',
|
|
34
|
+
menus: [
|
|
35
|
+
{
|
|
36
|
+
id: 'financial_hub',
|
|
37
|
+
menuKey: 'financial_hub',
|
|
38
|
+
label: 'Financeiro',
|
|
39
|
+
route: 'FinancialHubPage',
|
|
40
|
+
icon: 'dollar-sign',
|
|
41
|
+
color: '#0284C7',
|
|
42
|
+
sortOrder: 10,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: 'income_statement',
|
|
46
|
+
menuKey: 'income_statement',
|
|
47
|
+
label: 'Demonstrativo de resultados',
|
|
48
|
+
route: 'IncomeStatement',
|
|
49
|
+
icon: 'bar-chart-2',
|
|
50
|
+
color: '#0F766E',
|
|
51
|
+
sortOrder: 15,
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: 'manager-operacoes',
|
|
57
|
+
label: 'Operacoes',
|
|
58
|
+
icon: 'shopping-bag',
|
|
59
|
+
menus: [
|
|
60
|
+
{
|
|
61
|
+
id: 'orders',
|
|
62
|
+
menuKey: 'orders',
|
|
63
|
+
label: 'Pedidos',
|
|
64
|
+
route: 'OrderHistoryPage',
|
|
65
|
+
icon: 'shopping-bag',
|
|
66
|
+
color: '#0EA5E9',
|
|
67
|
+
sortOrder: 20,
|
|
68
|
+
},
|
|
69
|
+
],
|
|
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',
|
|
81
|
+
icon: 'users',
|
|
82
|
+
color: '#16A34A',
|
|
83
|
+
sortOrder: 30,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
id: 'providers',
|
|
87
|
+
menuKey: 'providers',
|
|
88
|
+
label: 'Fornecedores',
|
|
89
|
+
route: 'ProvidersIndex',
|
|
90
|
+
icon: 'truck',
|
|
91
|
+
color: '#EA580C',
|
|
92
|
+
sortOrder: 35,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: 'franchisees',
|
|
96
|
+
menuKey: 'franchisees',
|
|
97
|
+
label: 'Cadastro de franquias',
|
|
98
|
+
route: 'FranchiseesIndex',
|
|
99
|
+
icon: 'map-pin',
|
|
100
|
+
color: '#0EA5E9',
|
|
101
|
+
sortOrder: 40,
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: 'manager-configuracoes',
|
|
107
|
+
label: 'Configuracoes',
|
|
108
|
+
icon: 'settings',
|
|
109
|
+
menus: [
|
|
110
|
+
{
|
|
111
|
+
id: 'devices',
|
|
112
|
+
menuKey: 'devices',
|
|
113
|
+
label: 'Dispositivos',
|
|
114
|
+
route: 'DevicesIndex',
|
|
115
|
+
icon: 'credit-card',
|
|
116
|
+
color: '#e67e22',
|
|
117
|
+
sortOrder: 50,
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
id: 'configurator',
|
|
121
|
+
menuKey: 'configurator',
|
|
122
|
+
label: 'Configurador',
|
|
123
|
+
route: 'ConfiguratorPage',
|
|
124
|
+
icon: 'settings',
|
|
125
|
+
color: '#64748B',
|
|
126
|
+
sortOrder: 60,
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
},
|
|
130
|
+
];
|
|
131
|
+
|
|
132
|
+
const cloneRuntimeMenuModules = modules =>
|
|
133
|
+
(Array.isArray(modules) ? modules : []).map(module => ({
|
|
134
|
+
...module,
|
|
135
|
+
menus: Array.isArray(module?.menus)
|
|
136
|
+
? module.menus.map(menu => normalizeRuntimeMenuItem(menu))
|
|
137
|
+
: [],
|
|
138
|
+
}));
|
|
139
|
+
|
|
140
|
+
export const normalizeRuntimeMenuIcon = value => {
|
|
141
|
+
const normalized = String(value || '').trim();
|
|
142
|
+
if (!normalized) return '';
|
|
143
|
+
|
|
144
|
+
return RUNTIME_MENU_ICON_ALIASES[normalized.toLowerCase()] || normalized;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export const normalizeRuntimeMenuResponse = (
|
|
148
|
+
result,
|
|
149
|
+
{appType, allowFallback = true} = {},
|
|
150
|
+
) => {
|
|
151
|
+
const modules =
|
|
152
|
+
result?.response?.data?.modules ||
|
|
153
|
+
result?.data?.modules ||
|
|
154
|
+
result?.modules ||
|
|
155
|
+
{};
|
|
156
|
+
|
|
157
|
+
const normalizedModules = Object.values(modules)
|
|
158
|
+
.map(module => ({
|
|
159
|
+
...module,
|
|
160
|
+
icon: normalizeRuntimeMenuIcon(module?.icon),
|
|
161
|
+
menus: (Array.isArray(module?.menus) ? module.menus : [])
|
|
162
|
+
.map(menu => normalizeRuntimeMenuItem(menu))
|
|
163
|
+
.sort((left, right) => {
|
|
164
|
+
const orderDiff = Number(left?.sortOrder || 0) - Number(right?.sortOrder || 0);
|
|
165
|
+
if (orderDiff !== 0) return orderDiff;
|
|
166
|
+
return String(left?.label || '').localeCompare(String(right?.label || ''));
|
|
167
|
+
}),
|
|
168
|
+
}))
|
|
169
|
+
.filter(module => module.menus.length > 0);
|
|
170
|
+
|
|
171
|
+
if (normalizedModules.length > 0) {
|
|
172
|
+
return normalizedModules;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const normalizedAppType = String(appType || '').trim().toUpperCase();
|
|
176
|
+
|
|
177
|
+
if (allowFallback && normalizedAppType === 'MANAGER') {
|
|
178
|
+
return cloneRuntimeMenuModules(MANAGER_RUNTIME_MENU_FALLBACK);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return [];
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
export const filterRuntimeMenuModulesByType = (menus, menuType) => {
|
|
185
|
+
const normalizedMenuType =
|
|
186
|
+
menuType === null || menuType === undefined || String(menuType).trim() === ''
|
|
187
|
+
? null
|
|
188
|
+
: normalizeRuntimeMenuType(menuType, '');
|
|
189
|
+
|
|
190
|
+
const modules = cloneRuntimeMenuModules(menus);
|
|
191
|
+
if (!normalizedMenuType) {
|
|
192
|
+
return modules;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return modules
|
|
196
|
+
.map(module => ({
|
|
197
|
+
...module,
|
|
198
|
+
menus: Array.isArray(module?.menus)
|
|
199
|
+
? module.menus.filter(
|
|
200
|
+
menu => normalizeRuntimeMenuType(menu?.menuType, '') === normalizedMenuType,
|
|
201
|
+
)
|
|
202
|
+
: [],
|
|
203
|
+
}))
|
|
204
|
+
.filter(module => module.menus.length > 0);
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
export const flattenRuntimeMenuItemsByType = (menus, menuType) =>
|
|
208
|
+
filterRuntimeMenuModulesByType(menus, menuType).flatMap(module =>
|
|
209
|
+
Array.isArray(module?.menus) ? module.menus : [],
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
export const resolveRuntimeMenuLabel = (menu, translate) =>
|
|
213
|
+
translate?.('menu', 'menu', menu?.menuKey) || menu?.label || menu?.menuKey || '';
|
|
214
|
+
|
|
215
|
+
export const getRuntimeMenuRoutes = menus =>
|
|
216
|
+
new Set(
|
|
217
|
+
(Array.isArray(menus) ? menus : [])
|
|
218
|
+
.flatMap(module => (Array.isArray(module?.menus) ? module.menus : []))
|
|
219
|
+
.map(menu => menu?.route)
|
|
220
|
+
.filter(Boolean),
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
export const userHasRole = (user, role) =>
|
|
224
|
+
Array.isArray(user?.roles) && user.roles.includes(role);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Dimensions, PixelRatio } from 'react-native';
|
|
2
|
+
|
|
3
|
+
export const SCREEN_METRIC_KEYS = ['deviceResolution', 'actualSize', 'windosSize'];
|
|
4
|
+
|
|
5
|
+
export const buildScreenMetrics = () => {
|
|
6
|
+
const windowSize = Dimensions.get('window');
|
|
7
|
+
const screenSize = Dimensions.get('screen');
|
|
8
|
+
const pixelRatio = Number(PixelRatio.get()) || 1;
|
|
9
|
+
|
|
10
|
+
const windowWidth = Math.round(Number(windowSize?.width) || 0);
|
|
11
|
+
const windowHeight = Math.round(Number(windowSize?.height) || 0);
|
|
12
|
+
const screenWidth = Math.round(Number(screenSize?.width) || 0);
|
|
13
|
+
const screenHeight = Math.round(Number(screenSize?.height) || 0);
|
|
14
|
+
const physicalWidth = Math.round((Number(screenSize?.width) || 0) * pixelRatio);
|
|
15
|
+
const physicalHeight = Math.round((Number(screenSize?.height) || 0) * pixelRatio);
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
deviceResolution: `${physicalWidth}x${physicalHeight}`,
|
|
19
|
+
actualSize: `${screenWidth}x${screenHeight}`,
|
|
20
|
+
windosSize: `${windowWidth}x${windowHeight}`,
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const appendScreenMetrics = (configs = {}, metrics = buildScreenMetrics()) => ({
|
|
25
|
+
...configs,
|
|
26
|
+
...metrics,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export const hasScreenMetricsChanges = (configs = {}, metrics = buildScreenMetrics()) =>
|
|
30
|
+
SCREEN_METRIC_KEYS.some(key => configs?.[key] !== metrics?.[key]);
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
const parseJsonValue = (value, fallback) => {
|
|
2
|
+
if (value === null || value === undefined || value === '') {
|
|
3
|
+
return fallback;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
if (typeof value === 'string') {
|
|
7
|
+
try {
|
|
8
|
+
return JSON.parse(value);
|
|
9
|
+
} catch {
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return value;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const SHOP_HOME_OPTION_SALES =
|
|
18
|
+
'sales';
|
|
19
|
+
export const SHOP_HOME_OPTION_FRANCHISE_LOCATOR =
|
|
20
|
+
'franchise-locator';
|
|
21
|
+
export const SHOP_HOME_OPTION_LOYALTY =
|
|
22
|
+
'loyalty';
|
|
23
|
+
export const SHOP_SALES_PAGE_ENABLED_CONFIG_KEY =
|
|
24
|
+
'shop-sales-page-enabled';
|
|
25
|
+
export const SHOP_FRANCHISE_LOCATOR_ENABLED_CONFIG_KEY =
|
|
26
|
+
'shop-franchise-locator-enabled';
|
|
27
|
+
export const SHOP_PRIMARY_ENTRY_CONFIG_KEY =
|
|
28
|
+
'shop-primary-entry';
|
|
29
|
+
export const SHOP_BOTTOM_BAR_ENABLED_CONFIG_KEY =
|
|
30
|
+
'shop-bottom-bar-enabled';
|
|
31
|
+
export const SHOP_CHARGE_ON_DELIVERY_ENABLED_CONFIG_KEY =
|
|
32
|
+
'shop-charge-on-delivery-enabled';
|
|
33
|
+
export const SHOP_DELIVERY_FEE_ENABLED_CONFIG_KEY =
|
|
34
|
+
'shop-delivery-fee-enabled';
|
|
35
|
+
export const SHOP_DELIVERY_FEE_VALUE_CONFIG_KEY =
|
|
36
|
+
'shop-delivery-fee-value';
|
|
37
|
+
export const SHOP_CATALOG_PRODUCT_TYPES_CONFIG_KEY =
|
|
38
|
+
'shop-catalog-product-types';
|
|
39
|
+
export const SHOP_GOOGLE_MAPS_API_KEY_CONFIG_KEY =
|
|
40
|
+
'shop-google-maps-api-key';
|
|
41
|
+
export const SHOP_FRANCHISE_PIN_ICON_URL_CONFIG_KEY =
|
|
42
|
+
'shop-franchise-pin-icon-url';
|
|
43
|
+
export const SHOP_FRANCHISE_VISIBLE_COMPANY_IDS_CONFIG_KEY =
|
|
44
|
+
'shop-franchise-visible-company-ids';
|
|
45
|
+
export const SHOP_FRANCHISE_VISIBLE_ADDRESS_IDS_CONFIG_KEY =
|
|
46
|
+
'shop-franchise-visible-address-ids';
|
|
47
|
+
export const SHOP_LOYALTY_COUPONS_ENABLED_CONFIG_KEY =
|
|
48
|
+
'shop-loyalty-coupons-enabled';
|
|
49
|
+
export const SHOP_LOYALTY_PRODUCT_IDS_CONFIG_KEY =
|
|
50
|
+
'shop-loyalty-product-ids';
|
|
51
|
+
export const SHOP_LOYALTY_REQUIRED_SALES_CONFIG_KEY =
|
|
52
|
+
'shop-loyalty-required-sales';
|
|
53
|
+
export const SHOP_LOYALTY_GIFT_PRODUCT_ID_CONFIG_KEY =
|
|
54
|
+
'shop-loyalty-gift-product-id';
|
|
55
|
+
|
|
56
|
+
export const normalizeShopEntityId = value => {
|
|
57
|
+
if (!value) {
|
|
58
|
+
return '';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (typeof value === 'object') {
|
|
62
|
+
return normalizeShopEntityId(value?.['@id'] || value?.id);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return String(value).replace(/\D+/g, '').trim();
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const normalizeShopProductId = value => normalizeShopEntityId(value);
|
|
69
|
+
|
|
70
|
+
export const normalizeShopTextConfig = (value, fallback = '') => {
|
|
71
|
+
const parsed = parseJsonValue(value, fallback);
|
|
72
|
+
|
|
73
|
+
if (parsed === null || parsed === undefined) {
|
|
74
|
+
return fallback;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return String(parsed).trim();
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const normalizeBooleanConfig = (value, fallback = false) => {
|
|
81
|
+
if (value === null || value === undefined || value === '') {
|
|
82
|
+
return fallback;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (typeof value === 'boolean') {
|
|
86
|
+
return value;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (typeof value === 'number') {
|
|
90
|
+
return value !== 0;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const parsed = parseJsonValue(value, value);
|
|
94
|
+
if (typeof parsed === 'boolean') {
|
|
95
|
+
return parsed;
|
|
96
|
+
}
|
|
97
|
+
if (typeof parsed === 'number') {
|
|
98
|
+
return parsed !== 0;
|
|
99
|
+
}
|
|
100
|
+
if (typeof parsed === 'string') {
|
|
101
|
+
const normalizedValue = parsed.trim().toLowerCase();
|
|
102
|
+
if (
|
|
103
|
+
['1', 'true', 'yes', 'sim', 'on', 'enabled', 'ativo'].includes(
|
|
104
|
+
normalizedValue,
|
|
105
|
+
)
|
|
106
|
+
) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
if (
|
|
110
|
+
['0', 'false', 'no', 'nao', 'off', 'disabled', 'inativo'].includes(
|
|
111
|
+
normalizedValue,
|
|
112
|
+
)
|
|
113
|
+
) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return fallback;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const normalizeShopEntityIds = value => {
|
|
122
|
+
const parsed = parseJsonValue(value, []);
|
|
123
|
+
const source = Array.isArray(parsed)
|
|
124
|
+
? parsed
|
|
125
|
+
: String(value || '').split(/\r?\n|,/);
|
|
126
|
+
|
|
127
|
+
return Array.from(
|
|
128
|
+
new Set(source.map(normalizeShopEntityId).filter(Boolean)),
|
|
129
|
+
);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export const normalizeShopProductIds = value => normalizeShopEntityIds(value);
|
|
133
|
+
|
|
134
|
+
export const SHOP_CATALOG_DEFAULT_PRODUCT_TYPES = [
|
|
135
|
+
'product',
|
|
136
|
+
'manufactured',
|
|
137
|
+
'custom',
|
|
138
|
+
'service',
|
|
139
|
+
];
|
|
140
|
+
|
|
141
|
+
export const normalizeShopCatalogProductTypes = value => {
|
|
142
|
+
const parsed = parseJsonValue(value, SHOP_CATALOG_DEFAULT_PRODUCT_TYPES);
|
|
143
|
+
const source = Array.isArray(parsed)
|
|
144
|
+
? parsed
|
|
145
|
+
: String(value || '').split(/\r?\n|,/);
|
|
146
|
+
const allowed = new Set(SHOP_CATALOG_DEFAULT_PRODUCT_TYPES);
|
|
147
|
+
const normalized = Array.from(
|
|
148
|
+
new Set(
|
|
149
|
+
source
|
|
150
|
+
.map(item => String(item || '').trim().toLowerCase())
|
|
151
|
+
.filter(item => allowed.has(item)),
|
|
152
|
+
),
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
return normalized.length > 0
|
|
156
|
+
? normalized
|
|
157
|
+
: SHOP_CATALOG_DEFAULT_PRODUCT_TYPES;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
export const normalizeShopLoyaltyRequiredSales = (value, fallback = 0) => {
|
|
161
|
+
const parsed = parseJsonValue(value, fallback);
|
|
162
|
+
const normalizedNumber = Number(parsed);
|
|
163
|
+
|
|
164
|
+
if (!Number.isFinite(normalizedNumber)) {
|
|
165
|
+
return fallback;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return Math.max(0, Math.trunc(normalizedNumber));
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
export const normalizeShopMoneyConfig = (value, fallback = 0) => {
|
|
172
|
+
const parsed = parseJsonValue(value, value);
|
|
173
|
+
const rawValue = String(parsed ?? '').trim();
|
|
174
|
+
const numericText = rawValue.includes(',')
|
|
175
|
+
? rawValue.replace(/\./g, '').replace(',', '.')
|
|
176
|
+
: rawValue;
|
|
177
|
+
const normalized = Number(
|
|
178
|
+
numericText.replace(/[^\d.-]/g, ''),
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
return Number.isFinite(normalized) ? Math.max(0, normalized) : fallback;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
export const getEnabledShopHomeOptions = ({
|
|
185
|
+
salesPageEnabled,
|
|
186
|
+
franchiseLocatorEnabled,
|
|
187
|
+
loyaltyCouponsEnabled,
|
|
188
|
+
}) => {
|
|
189
|
+
const enabledOptions = [];
|
|
190
|
+
|
|
191
|
+
if (salesPageEnabled) {
|
|
192
|
+
enabledOptions.push(SHOP_HOME_OPTION_SALES);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (franchiseLocatorEnabled) {
|
|
196
|
+
enabledOptions.push(SHOP_HOME_OPTION_FRANCHISE_LOCATOR);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (loyaltyCouponsEnabled) {
|
|
200
|
+
enabledOptions.push(SHOP_HOME_OPTION_LOYALTY);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return enabledOptions;
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export const normalizeShopPrimaryEntry = (
|
|
207
|
+
value,
|
|
208
|
+
availability = {},
|
|
209
|
+
) => {
|
|
210
|
+
const parsed = parseJsonValue(value, value);
|
|
211
|
+
const normalizedValue = String(parsed || '').trim().toLowerCase();
|
|
212
|
+
const enabledOptions = getEnabledShopHomeOptions(availability);
|
|
213
|
+
|
|
214
|
+
if (enabledOptions.includes(normalizedValue)) {
|
|
215
|
+
return normalizedValue;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return enabledOptions[0] || '';
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
export const resolveShopSettings = configs => {
|
|
222
|
+
const configMap =
|
|
223
|
+
configs && typeof configs === 'object' && !Array.isArray(configs)
|
|
224
|
+
? configs
|
|
225
|
+
: {};
|
|
226
|
+
|
|
227
|
+
const salesPageEnabled = normalizeBooleanConfig(
|
|
228
|
+
configMap[SHOP_SALES_PAGE_ENABLED_CONFIG_KEY],
|
|
229
|
+
);
|
|
230
|
+
const franchiseLocatorEnabled = normalizeBooleanConfig(
|
|
231
|
+
configMap[SHOP_FRANCHISE_LOCATOR_ENABLED_CONFIG_KEY],
|
|
232
|
+
);
|
|
233
|
+
const enabledHomeOptions = getEnabledShopHomeOptions({
|
|
234
|
+
salesPageEnabled,
|
|
235
|
+
franchiseLocatorEnabled,
|
|
236
|
+
loyaltyCouponsEnabled: normalizeBooleanConfig(
|
|
237
|
+
configMap[SHOP_LOYALTY_COUPONS_ENABLED_CONFIG_KEY],
|
|
238
|
+
),
|
|
239
|
+
});
|
|
240
|
+
const loyaltyCouponsEnabled = normalizeBooleanConfig(
|
|
241
|
+
configMap[SHOP_LOYALTY_COUPONS_ENABLED_CONFIG_KEY],
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
return {
|
|
245
|
+
salesPageEnabled,
|
|
246
|
+
franchiseLocatorEnabled,
|
|
247
|
+
loyaltyCouponsEnabled,
|
|
248
|
+
enabledHomeOptions,
|
|
249
|
+
primaryEntry: normalizeShopPrimaryEntry(
|
|
250
|
+
configMap[SHOP_PRIMARY_ENTRY_CONFIG_KEY],
|
|
251
|
+
{
|
|
252
|
+
salesPageEnabled,
|
|
253
|
+
franchiseLocatorEnabled,
|
|
254
|
+
loyaltyCouponsEnabled,
|
|
255
|
+
},
|
|
256
|
+
),
|
|
257
|
+
bottomBarEnabled: normalizeBooleanConfig(
|
|
258
|
+
configMap[SHOP_BOTTOM_BAR_ENABLED_CONFIG_KEY],
|
|
259
|
+
),
|
|
260
|
+
chargeOnDeliveryEnabled: normalizeBooleanConfig(
|
|
261
|
+
configMap[SHOP_CHARGE_ON_DELIVERY_ENABLED_CONFIG_KEY],
|
|
262
|
+
),
|
|
263
|
+
deliveryFeeEnabled: normalizeBooleanConfig(
|
|
264
|
+
configMap[SHOP_DELIVERY_FEE_ENABLED_CONFIG_KEY],
|
|
265
|
+
),
|
|
266
|
+
deliveryFeeValue: normalizeShopMoneyConfig(
|
|
267
|
+
configMap[SHOP_DELIVERY_FEE_VALUE_CONFIG_KEY],
|
|
268
|
+
),
|
|
269
|
+
catalogProductTypes: normalizeShopCatalogProductTypes(
|
|
270
|
+
configMap[SHOP_CATALOG_PRODUCT_TYPES_CONFIG_KEY],
|
|
271
|
+
),
|
|
272
|
+
googleMapsApiKey: normalizeShopTextConfig(
|
|
273
|
+
configMap[SHOP_GOOGLE_MAPS_API_KEY_CONFIG_KEY],
|
|
274
|
+
),
|
|
275
|
+
franchisePinIconUrl: normalizeShopTextConfig(
|
|
276
|
+
configMap[SHOP_FRANCHISE_PIN_ICON_URL_CONFIG_KEY],
|
|
277
|
+
),
|
|
278
|
+
visibleFranchiseCompanyIds: normalizeShopEntityIds(
|
|
279
|
+
configMap[SHOP_FRANCHISE_VISIBLE_COMPANY_IDS_CONFIG_KEY],
|
|
280
|
+
),
|
|
281
|
+
visibleFranchiseAddressIds: normalizeShopEntityIds(
|
|
282
|
+
configMap[SHOP_FRANCHISE_VISIBLE_ADDRESS_IDS_CONFIG_KEY],
|
|
283
|
+
),
|
|
284
|
+
loyaltyProductIds: normalizeShopEntityIds(
|
|
285
|
+
configMap[SHOP_LOYALTY_PRODUCT_IDS_CONFIG_KEY],
|
|
286
|
+
),
|
|
287
|
+
loyaltyRequiredSales: normalizeShopLoyaltyRequiredSales(
|
|
288
|
+
configMap[SHOP_LOYALTY_REQUIRED_SALES_CONFIG_KEY],
|
|
289
|
+
),
|
|
290
|
+
loyaltyGiftProductId: normalizeShopEntityId(
|
|
291
|
+
configMap[SHOP_LOYALTY_GIFT_PRODUCT_ID_CONFIG_KEY],
|
|
292
|
+
),
|
|
293
|
+
};
|
|
294
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
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
|
+
import {normalizeShopEntityId} from '@controleonline/ui-common/src/react/utils/shopConfig';
|
|
7
|
+
|
|
8
|
+
export const SHOP_FRANCHISE_LINK_TYPE = 'franchisee';
|
|
9
|
+
export const SHOP_FRANCHISE_PAGE_SIZE = 50;
|
|
10
|
+
|
|
11
|
+
const normalizeItemsPerPage = value =>
|
|
12
|
+
Math.max(1, Math.min(SHOP_FRANCHISE_PAGE_SIZE, Number(value) || SHOP_FRANCHISE_PAGE_SIZE));
|
|
13
|
+
|
|
14
|
+
const sortByLabel = (left, right) =>
|
|
15
|
+
String(left || '')
|
|
16
|
+
.localeCompare(String(right || ''), 'pt-BR', {
|
|
17
|
+
sensitivity: 'base',
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export const resolveFranchiseCompanyLabel = company =>
|
|
21
|
+
String(company?.alias || company?.name || '').trim() ||
|
|
22
|
+
`Franquia #${normalizeShopEntityId(company) || ''}`.trim();
|
|
23
|
+
|
|
24
|
+
export const fetchShopFranchiseCompanies = async ({
|
|
25
|
+
companyId,
|
|
26
|
+
search = '',
|
|
27
|
+
page = 1,
|
|
28
|
+
itemsPerPage = SHOP_FRANCHISE_PAGE_SIZE,
|
|
29
|
+
publicDirectory = false,
|
|
30
|
+
} = {}) => {
|
|
31
|
+
const params = {
|
|
32
|
+
page: Math.max(1, Number(page) || 1),
|
|
33
|
+
itemsPerPage: normalizeItemsPerPage(itemsPerPage),
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
if (String(search || '').trim()) {
|
|
37
|
+
params.search = String(search).trim();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const response = publicDirectory
|
|
41
|
+
? await api.fetch('/shop/franchises', {params})
|
|
42
|
+
: await api.fetch('people', {
|
|
43
|
+
params: {
|
|
44
|
+
...params,
|
|
45
|
+
'link.company': toEntityIri(companyId, 'people'),
|
|
46
|
+
'link.linkType': SHOP_FRANCHISE_LINK_TYPE,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
const items = extractCollectionItems(response);
|
|
50
|
+
|
|
51
|
+
return items
|
|
52
|
+
.map(company => ({
|
|
53
|
+
...company,
|
|
54
|
+
shopAddresses: Array.isArray(company?.shopAddresses)
|
|
55
|
+
? company.shopAddresses
|
|
56
|
+
: Array.isArray(company?.address)
|
|
57
|
+
? company.address
|
|
58
|
+
: [],
|
|
59
|
+
}))
|
|
60
|
+
.sort((left, right) =>
|
|
61
|
+
sortByLabel(
|
|
62
|
+
resolveFranchiseCompanyLabel(left),
|
|
63
|
+
resolveFranchiseCompanyLabel(right),
|
|
64
|
+
),
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const fetchShopFranchiseAddresses = async ({
|
|
69
|
+
peopleId,
|
|
70
|
+
search = '',
|
|
71
|
+
} = {}) => {
|
|
72
|
+
if (!peopleId) {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const params = {
|
|
77
|
+
people: toEntityIri(peopleId, 'people'),
|
|
78
|
+
itemsPerPage: SHOP_FRANCHISE_PAGE_SIZE,
|
|
79
|
+
page: 1,
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
if (String(search || '').trim()) {
|
|
83
|
+
params.search = String(search).trim();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const response = await api.fetch('addresses', {params});
|
|
87
|
+
return extractCollectionItems(response);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const fetchShopFranchiseDirectory = async ({
|
|
91
|
+
companyId,
|
|
92
|
+
publicDirectory = false,
|
|
93
|
+
search = '',
|
|
94
|
+
page = 1,
|
|
95
|
+
itemsPerPage = SHOP_FRANCHISE_PAGE_SIZE,
|
|
96
|
+
} = {}) => {
|
|
97
|
+
const companies = await fetchShopFranchiseCompanies({
|
|
98
|
+
companyId,
|
|
99
|
+
publicDirectory,
|
|
100
|
+
search,
|
|
101
|
+
page,
|
|
102
|
+
itemsPerPage,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
return companies.map(company => ({
|
|
106
|
+
...company,
|
|
107
|
+
shopAddresses: Array.isArray(company?.shopAddresses)
|
|
108
|
+
? company.shopAddresses
|
|
109
|
+
: Array.isArray(company?.address)
|
|
110
|
+
? company.address
|
|
111
|
+
: [],
|
|
112
|
+
}));
|
|
113
|
+
};
|
|
114
|
+
// 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.
|