@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,102 @@
|
|
|
1
|
+
import { env as APP_ENV } from '@env';
|
|
2
|
+
import { buildAssetUrl } from '@controleonline/../../src/styles/branding';
|
|
3
|
+
import {
|
|
4
|
+
resolveAppDomain,
|
|
5
|
+
resolveCompanyDomain,
|
|
6
|
+
} from '@controleonline/ui-common/src/utils/appDomain';
|
|
7
|
+
|
|
8
|
+
const IMAGE_PATH_PATTERN = /\.(?:avif|bmp|gif|ico|jpe?g|png|svg|webp)(?:\?|$)/i;
|
|
9
|
+
|
|
10
|
+
const normalizeText = value => String(value || '').trim();
|
|
11
|
+
|
|
12
|
+
const unwrapFile = file => {
|
|
13
|
+
if (!file || typeof file !== 'object' || Array.isArray(file)) {
|
|
14
|
+
return file;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (file.file) {
|
|
18
|
+
return unwrapFile(file.file);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return file;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const resolveDirectFileUrl = file => {
|
|
25
|
+
if (!file) {
|
|
26
|
+
return '';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (typeof file === 'string') {
|
|
30
|
+
const normalizedFile = normalizeText(file);
|
|
31
|
+
if (
|
|
32
|
+
/^https?:\/\//i.test(normalizedFile) ||
|
|
33
|
+
/^\/\//.test(normalizedFile) ||
|
|
34
|
+
/\/download(?:\?|$)/i.test(normalizedFile) ||
|
|
35
|
+
IMAGE_PATH_PATTERN.test(normalizedFile)
|
|
36
|
+
) {
|
|
37
|
+
return buildAssetUrl(normalizedFile) || normalizedFile;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return '';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (typeof file === 'object' && !Array.isArray(file)) {
|
|
44
|
+
return buildAssetUrl(file) || '';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return '';
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const extractFileId = file => {
|
|
51
|
+
const normalizedFile = unwrapFile(file);
|
|
52
|
+
|
|
53
|
+
if (!normalizedFile) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (typeof normalizedFile === 'number') {
|
|
58
|
+
return normalizedFile;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (typeof normalizedFile === 'string') {
|
|
62
|
+
const matches = normalizedFile.match(/\d+/g);
|
|
63
|
+
return matches ? Number(matches[matches.length - 1]) : null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (typeof normalizedFile === 'object') {
|
|
67
|
+
const rawValue =
|
|
68
|
+
normalizedFile?.id ||
|
|
69
|
+
normalizedFile?.['@id'] ||
|
|
70
|
+
normalizedFile?.fileId ||
|
|
71
|
+
normalizedFile?.file_id ||
|
|
72
|
+
'';
|
|
73
|
+
|
|
74
|
+
return extractFileId(rawValue);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return null;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// Centraliza a resolucao de imagem/arquivo do backend em uma unica regra.
|
|
81
|
+
export const resolveFileImageUrl = (file, {company = null, appDomain = ''} = {}) => {
|
|
82
|
+
const normalizedFile = unwrapFile(file);
|
|
83
|
+
const directUrl = resolveDirectFileUrl(normalizedFile);
|
|
84
|
+
if (directUrl) {
|
|
85
|
+
return directUrl;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const fileId = extractFileId(normalizedFile);
|
|
89
|
+
if (!fileId) {
|
|
90
|
+
return '';
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const fallbackDomain = normalizeText(appDomain) || resolveAppDomain(APP_ENV?.DOMAIN);
|
|
94
|
+
const host = resolveCompanyDomain(company, fallbackDomain);
|
|
95
|
+
const query = host ? `?app-domain=${encodeURIComponent(host)}` : '';
|
|
96
|
+
const relativeUrl = `/files/${fileId}/download${query}`;
|
|
97
|
+
const apiEntryPoint = normalizeText(APP_ENV?.API_ENTRYPOINT).replace(/\/$/, '');
|
|
98
|
+
|
|
99
|
+
return apiEntryPoint ? `${apiEntryPoint}${relativeUrl}` : relativeUrl;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export const resolveFileDownloadUrl = resolveFileImageUrl;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {api} from '@controleonline/ui-common/src/api'
|
|
2
|
+
|
|
3
|
+
const normalizeContext = value =>
|
|
4
|
+
value && typeof value === 'object' && !Array.isArray(value) ? value : {}
|
|
5
|
+
|
|
6
|
+
export const sendFrontendDebugLog = async ({
|
|
7
|
+
channel = 'frontend-debug',
|
|
8
|
+
class: entityClass = '',
|
|
9
|
+
context = {},
|
|
10
|
+
entityRow = null,
|
|
11
|
+
level = 'info',
|
|
12
|
+
message = 'Frontend debug log',
|
|
13
|
+
row = null,
|
|
14
|
+
} = {}) => {
|
|
15
|
+
if (typeof __DEV__ !== 'undefined' && !__DEV__) {
|
|
16
|
+
return null
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const normalizedContext = {
|
|
20
|
+
...normalizeContext(context),
|
|
21
|
+
href:
|
|
22
|
+
typeof window !== 'undefined' && window?.location?.href
|
|
23
|
+
? window.location.href
|
|
24
|
+
: '',
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const response = await api.fetch('/logs/frontend-debug', {
|
|
29
|
+
method: 'POST',
|
|
30
|
+
body: {
|
|
31
|
+
channel,
|
|
32
|
+
level,
|
|
33
|
+
message,
|
|
34
|
+
context: normalizedContext,
|
|
35
|
+
entityClass,
|
|
36
|
+
entityRow: entityRow ?? row,
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
return response
|
|
41
|
+
} catch {
|
|
42
|
+
return null
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// 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.
|
|
@@ -0,0 +1,49 @@
|
|
|
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
|
+
const normalizeTextConfig = (value, fallback = '') => {
|
|
18
|
+
const parsed = parseJsonValue(value, fallback);
|
|
19
|
+
|
|
20
|
+
if (parsed === null || parsed === undefined) {
|
|
21
|
+
return fallback;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return String(parsed).trim();
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const GOOGLE_MAPS_WEB_API_KEY_CONFIG_KEY = 'web-google-maps-api-key';
|
|
28
|
+
export const GOOGLE_MAPS_ANDROID_API_KEY_CONFIG_KEY =
|
|
29
|
+
'android-google-maps-api-key';
|
|
30
|
+
|
|
31
|
+
export const resolveGoogleMapsSettings = configs => {
|
|
32
|
+
const configMap =
|
|
33
|
+
configs && typeof configs === 'object' && !Array.isArray(configs)
|
|
34
|
+
? configs
|
|
35
|
+
: {};
|
|
36
|
+
|
|
37
|
+
const webGoogleMapsApiKey = normalizeTextConfig(
|
|
38
|
+
configMap[GOOGLE_MAPS_WEB_API_KEY_CONFIG_KEY],
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const androidGoogleMapsApiKey = normalizeTextConfig(
|
|
42
|
+
configMap[GOOGLE_MAPS_ANDROID_API_KEY_CONFIG_KEY],
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
webGoogleMapsApiKey,
|
|
47
|
+
androidGoogleMapsApiKey,
|
|
48
|
+
};
|
|
49
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
const PROCESSING_IMPORT_STATUSES = ['pending', 'processing', 'queued', 'uploading', 'uploaded']
|
|
2
|
+
const ERROR_IMPORT_STATUSES = ['error', 'failed', 'failure', 'invalid']
|
|
3
|
+
const SUCCESS_IMPORT_STATUSES = ['done', 'success', 'completed', 'processed', 'finished']
|
|
4
|
+
|
|
5
|
+
function normalizeImportStatus(value) {
|
|
6
|
+
return String(value || '')
|
|
7
|
+
.trim()
|
|
8
|
+
.toLowerCase()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function getImportStatusMeta(item) {
|
|
12
|
+
const rawStatus =
|
|
13
|
+
item?.status?.realStatus ||
|
|
14
|
+
item?.status?.status ||
|
|
15
|
+
item?.status?.name ||
|
|
16
|
+
''
|
|
17
|
+
const normalizedStatus = normalizeImportStatus(rawStatus)
|
|
18
|
+
|
|
19
|
+
if (PROCESSING_IMPORT_STATUSES.includes(normalizedStatus)) {
|
|
20
|
+
return {
|
|
21
|
+
isProcessing: true,
|
|
22
|
+
isError: false,
|
|
23
|
+
labelKey: 'processing',
|
|
24
|
+
rawStatus,
|
|
25
|
+
backgroundColor: '#FEF3C7',
|
|
26
|
+
textColor: '#B45309',
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (ERROR_IMPORT_STATUSES.includes(normalizedStatus)) {
|
|
31
|
+
return {
|
|
32
|
+
isProcessing: false,
|
|
33
|
+
isError: true,
|
|
34
|
+
labelKey: 'error',
|
|
35
|
+
rawStatus,
|
|
36
|
+
backgroundColor: '#FEE2E2',
|
|
37
|
+
textColor: '#B91C1C',
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (SUCCESS_IMPORT_STATUSES.includes(normalizedStatus)) {
|
|
42
|
+
return {
|
|
43
|
+
isProcessing: false,
|
|
44
|
+
isError: false,
|
|
45
|
+
labelKey: 'done',
|
|
46
|
+
rawStatus,
|
|
47
|
+
backgroundColor: '#DCFCE7',
|
|
48
|
+
textColor: '#15803D',
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
isProcessing: false,
|
|
54
|
+
isError: false,
|
|
55
|
+
labelKey: 'fallback',
|
|
56
|
+
rawStatus,
|
|
57
|
+
backgroundColor: '#E2E8F0',
|
|
58
|
+
textColor: '#475569',
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function getImportErrorDetail(item) {
|
|
63
|
+
const candidates = [
|
|
64
|
+
item?.error,
|
|
65
|
+
item?.errorMessage,
|
|
66
|
+
item?.status?.message,
|
|
67
|
+
item?.status?.description,
|
|
68
|
+
item?.status?.detail,
|
|
69
|
+
item?.detail,
|
|
70
|
+
item?.message,
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
return candidates.find(candidate => String(candidate || '').trim()) || ''
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function resolveImportLabels(translate) {
|
|
77
|
+
return {
|
|
78
|
+
refreshLabel: translate?.('imports', 'button', 'refresh'),
|
|
79
|
+
processingLabel: translate?.('imports', 'status', 'processing'),
|
|
80
|
+
errorLabel: translate?.('imports', 'status', 'error'),
|
|
81
|
+
doneLabel: translate?.('imports', 'status', 'done'),
|
|
82
|
+
noStatusLabel: translate?.('imports', 'status', 'no_status'),
|
|
83
|
+
processingHelpLabel: translate?.('imports', 'message', 'processing_after_upload'),
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function resolveImportStatusLabel(statusMeta, labels = {}) {
|
|
88
|
+
if (statusMeta?.labelKey === 'processing') return labels.processingLabel
|
|
89
|
+
if (statusMeta?.labelKey === 'error') return labels.errorLabel
|
|
90
|
+
if (statusMeta?.labelKey === 'done') return labels.doneLabel
|
|
91
|
+
return statusMeta?.rawStatus || labels.noStatusLabel
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
module.exports = {
|
|
95
|
+
getImportErrorDetail,
|
|
96
|
+
getImportStatusMeta,
|
|
97
|
+
normalizeImportStatus,
|
|
98
|
+
resolveImportLabels,
|
|
99
|
+
resolveImportStatusLabel,
|
|
100
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const resolveInvoiceInvalidDateFormatMessage = () =>
|
|
2
|
+
global.t?.t('invoice', 'validation', 'Use o formato DD/MM/YYYY ou YYYY-MM-DD')
|
|
3
|
+
|
|
4
|
+
export const resolveInvoiceSingleDatePlaceholder = () =>
|
|
5
|
+
global.t?.t('invoice', 'placeholder', 'DD/MM/YYYY')
|
|
6
|
+
|
|
7
|
+
export const resolveInvoiceRangeLabel = () =>
|
|
8
|
+
global.t?.t('invoice', 'label', 'Vencimento (início/fim)')
|
|
9
|
+
|
|
10
|
+
export const resolveInvoiceRangeStartPlaceholder = () =>
|
|
11
|
+
global.t?.t('invoice', 'placeholder', 'Início: DD/MM/YYYY')
|
|
12
|
+
|
|
13
|
+
export const resolveInvoiceRangeEndPlaceholder = () =>
|
|
14
|
+
global.t?.t('invoice', 'placeholder', 'Fim: DD/MM/YYYY')
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const normalizeText = value => String(value ?? '').trim()
|
|
2
|
+
|
|
3
|
+
const normalizeInvoiceType = value => {
|
|
4
|
+
const normalizedValue = normalizeText(value).toLowerCase()
|
|
5
|
+
return normalizedValue || 'invoice'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const formatInvoiceTypeLabel = value => {
|
|
9
|
+
const normalizedInvoiceType = normalizeInvoiceType(value)
|
|
10
|
+
|
|
11
|
+
const labels = {
|
|
12
|
+
invoice: 'Invoice',
|
|
13
|
+
payment: 'Payment',
|
|
14
|
+
discount: 'Discount',
|
|
15
|
+
tax: 'Tax',
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (labels[normalizedInvoiceType]) {
|
|
19
|
+
return labels[normalizedInvoiceType]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return normalizedInvoiceType
|
|
23
|
+
.split(/[_\s-]+/)
|
|
24
|
+
.filter(Boolean)
|
|
25
|
+
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
|
|
26
|
+
.join(' ')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const getInvoicePaymentTypeLabel = invoice =>
|
|
30
|
+
normalizeText(invoice?.paymentType?.paymentType || invoice?.paymentType?.name)
|
|
31
|
+
|
|
32
|
+
const getInvoicePartyLabel = entity =>
|
|
33
|
+
normalizeText(
|
|
34
|
+
entity?.alias ||
|
|
35
|
+
entity?.name ||
|
|
36
|
+
entity?.fantasy_name ||
|
|
37
|
+
entity?.company ||
|
|
38
|
+
entity?.document,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
module.exports = {
|
|
42
|
+
normalizeInvoiceType,
|
|
43
|
+
formatInvoiceTypeLabel,
|
|
44
|
+
getInvoicePaymentTypeLabel,
|
|
45
|
+
getInvoicePartyLabel,
|
|
46
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
export const LOG_ERROR_EMAIL_ENABLED_KEY = 'log-error-email-enabled';
|
|
2
|
+
export const LOG_ERROR_EMAIL_RECIPIENTS_KEY = 'log-error-email-recipients';
|
|
3
|
+
export const LOG_POLICY_CONFIG_KEY = 'log-policy';
|
|
4
|
+
|
|
5
|
+
export const LOG_POLICY_ITEMS = [
|
|
6
|
+
{
|
|
7
|
+
key: 'backend_error',
|
|
8
|
+
title: 'Erros do backend',
|
|
9
|
+
description:
|
|
10
|
+
'Registra excecoes e falhas HTTP do backend. E o grupo principal para erros 500.',
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
key: 'entity',
|
|
14
|
+
title: 'Historico de entidades',
|
|
15
|
+
description:
|
|
16
|
+
'Mantem os diffs de criacao, alteracao e remocao das entidades do sistema.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
key: 'generic',
|
|
20
|
+
title: 'Logs genericos',
|
|
21
|
+
description:
|
|
22
|
+
'Agrupa logs tecnicos de integracao, workers e eventos que nao sao timeline de entidade.',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
key: 'operation_patterns',
|
|
26
|
+
title: 'Padroes operacionais',
|
|
27
|
+
description:
|
|
28
|
+
'Mantem registros tecnicos ligados a padroes e diagnosticos operacionais do sistema.',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
key: 'frontend_debug',
|
|
32
|
+
title: 'Debug do front-end',
|
|
33
|
+
description:
|
|
34
|
+
'Recebe logs enviados pelo React para apoio de debug e investigacao remota.',
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
export const DEFAULT_LOG_POLICY = LOG_POLICY_ITEMS.reduce((accumulator, item) => {
|
|
39
|
+
accumulator[item.key] = {
|
|
40
|
+
enabled: true,
|
|
41
|
+
retentionDays: null,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
return accumulator;
|
|
45
|
+
}, {});
|
|
46
|
+
|
|
47
|
+
const parseJsonValue = (value, fallback) => {
|
|
48
|
+
if (value === null || value === undefined || value === '') {
|
|
49
|
+
return fallback;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (typeof value === 'string') {
|
|
53
|
+
try {
|
|
54
|
+
return JSON.parse(value);
|
|
55
|
+
} catch {
|
|
56
|
+
return fallback;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return value;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const normalizeBoolean = value => {
|
|
64
|
+
if (typeof value === 'boolean') {
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (typeof value === 'number') {
|
|
69
|
+
return value === 1;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return ['1', 'true', 'yes', 'on'].includes(
|
|
73
|
+
String(value || '').trim().toLowerCase(),
|
|
74
|
+
);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const normalizeRetentionDays = value => {
|
|
78
|
+
const normalizedValue = String(value || '').replace(/\D+/g, '').trim();
|
|
79
|
+
if (!normalizedValue) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const parsedValue = Number(normalizedValue);
|
|
84
|
+
|
|
85
|
+
return Number.isFinite(parsedValue) && parsedValue > 0 ? parsedValue : null;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export const normalizeLogAlertRecipients = value => {
|
|
89
|
+
const parsedValue = parseJsonValue(value, value);
|
|
90
|
+
const source = Array.isArray(parsedValue)
|
|
91
|
+
? parsedValue
|
|
92
|
+
: String(parsedValue || '').split(/[\n,;]+/);
|
|
93
|
+
|
|
94
|
+
return Array.from(
|
|
95
|
+
new Set(
|
|
96
|
+
source
|
|
97
|
+
.map(item => String(item || '').trim().toLowerCase())
|
|
98
|
+
.filter(Boolean)
|
|
99
|
+
.filter(item => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(item)),
|
|
100
|
+
),
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export const findInvalidLogAlertRecipients = value => {
|
|
105
|
+
const parsedValue = parseJsonValue(value, value);
|
|
106
|
+
const source = Array.isArray(parsedValue)
|
|
107
|
+
? parsedValue
|
|
108
|
+
: String(parsedValue || '').split(/[\n,;]+/);
|
|
109
|
+
|
|
110
|
+
return Array.from(
|
|
111
|
+
new Set(
|
|
112
|
+
source
|
|
113
|
+
.map(item => String(item || '').trim().toLowerCase())
|
|
114
|
+
.filter(Boolean)
|
|
115
|
+
.filter(item => !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(item)),
|
|
116
|
+
),
|
|
117
|
+
);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export const normalizeLogPolicy = value => {
|
|
121
|
+
const parsedValue = parseJsonValue(value, {});
|
|
122
|
+
const safeValue =
|
|
123
|
+
parsedValue && typeof parsedValue === 'object' && !Array.isArray(parsedValue)
|
|
124
|
+
? parsedValue
|
|
125
|
+
: {};
|
|
126
|
+
|
|
127
|
+
return LOG_POLICY_ITEMS.reduce((accumulator, item) => {
|
|
128
|
+
const config = safeValue[item.key] || {};
|
|
129
|
+
|
|
130
|
+
accumulator[item.key] = {
|
|
131
|
+
enabled:
|
|
132
|
+
config.enabled === undefined
|
|
133
|
+
? DEFAULT_LOG_POLICY[item.key].enabled
|
|
134
|
+
: normalizeBoolean(config.enabled),
|
|
135
|
+
retentionDays: normalizeRetentionDays(config.retentionDays),
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
return accumulator;
|
|
139
|
+
}, {});
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export const formatRecipientsForInput = value =>
|
|
143
|
+
normalizeLogAlertRecipients(value).join('\n');
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export const MAINTENANCE_ROUTINES_CONFIG_KEY = 'maintenance-routines';
|
|
2
|
+
|
|
3
|
+
export const MAINTENANCE_ROUTINE_ITEMS = [
|
|
4
|
+
{
|
|
5
|
+
key: 'cleanup_logs',
|
|
6
|
+
title: 'Limpeza de logs',
|
|
7
|
+
description:
|
|
8
|
+
'Executa a politica de retencao dos logs e remove registros expirados.',
|
|
9
|
+
defaultEnabled: true,
|
|
10
|
+
defaultCronExpression: '* * * * *',
|
|
11
|
+
},
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
export const normalizeMaintenanceRoutines = value => {
|
|
15
|
+
let parsed = value;
|
|
16
|
+
|
|
17
|
+
if (typeof parsed === 'string') {
|
|
18
|
+
try {
|
|
19
|
+
parsed = JSON.parse(parsed);
|
|
20
|
+
} catch {
|
|
21
|
+
parsed = {};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const source = parsed && typeof parsed === 'object' ? parsed : {};
|
|
26
|
+
|
|
27
|
+
return MAINTENANCE_ROUTINE_ITEMS.reduce((accumulator, item) => {
|
|
28
|
+
const routine =
|
|
29
|
+
source[item.key] && typeof source[item.key] === 'object'
|
|
30
|
+
? source[item.key]
|
|
31
|
+
: {};
|
|
32
|
+
|
|
33
|
+
const cronExpression = String(
|
|
34
|
+
routine.cronExpression || item.defaultCronExpression,
|
|
35
|
+
).trim();
|
|
36
|
+
|
|
37
|
+
accumulator[item.key] = {
|
|
38
|
+
enabled:
|
|
39
|
+
routine.enabled === undefined
|
|
40
|
+
? item.defaultEnabled
|
|
41
|
+
: Boolean(routine.enabled),
|
|
42
|
+
cronExpression: cronExpression || item.defaultCronExpression,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
return accumulator;
|
|
46
|
+
}, {});
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const isLikelyCronExpression = value =>
|
|
50
|
+
String(value || '')
|
|
51
|
+
.trim()
|
|
52
|
+
.split(/\s+/)
|
|
53
|
+
.filter(Boolean).length === 5;
|