@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,391 @@
|
|
|
1
|
+
import TcpSocket from 'react-native-tcp-socket';
|
|
2
|
+
import {Buffer} from 'buffer';
|
|
3
|
+
|
|
4
|
+
const DEFAULT_CONNECT_TIMEOUT = 5000;
|
|
5
|
+
const DEFAULT_FLUSH_DELAY = 180;
|
|
6
|
+
const BASE64_REGEX =
|
|
7
|
+
/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
|
8
|
+
const DEFAULT_CODE_PAGE = 'cp850';
|
|
9
|
+
|
|
10
|
+
const CP850_CHAR_MAP = {
|
|
11
|
+
'Ç': 0x80,
|
|
12
|
+
'ü': 0x81,
|
|
13
|
+
'é': 0x82,
|
|
14
|
+
'â': 0x83,
|
|
15
|
+
'ä': 0x84,
|
|
16
|
+
'à': 0x85,
|
|
17
|
+
'å': 0x86,
|
|
18
|
+
'ç': 0x87,
|
|
19
|
+
'ê': 0x88,
|
|
20
|
+
'ë': 0x89,
|
|
21
|
+
'è': 0x8a,
|
|
22
|
+
'ï': 0x8b,
|
|
23
|
+
'î': 0x8c,
|
|
24
|
+
'ì': 0x8d,
|
|
25
|
+
'Ä': 0x8e,
|
|
26
|
+
'Å': 0x8f,
|
|
27
|
+
'É': 0x90,
|
|
28
|
+
'æ': 0x91,
|
|
29
|
+
'Æ': 0x92,
|
|
30
|
+
'ô': 0x93,
|
|
31
|
+
'ö': 0x94,
|
|
32
|
+
'ò': 0x95,
|
|
33
|
+
'û': 0x96,
|
|
34
|
+
'ù': 0x97,
|
|
35
|
+
'ÿ': 0x98,
|
|
36
|
+
'Ö': 0x99,
|
|
37
|
+
'Ü': 0x9a,
|
|
38
|
+
'ø': 0x9b,
|
|
39
|
+
'£': 0x9c,
|
|
40
|
+
'Ø': 0x9d,
|
|
41
|
+
'×': 0x9e,
|
|
42
|
+
'ƒ': 0x9f,
|
|
43
|
+
'á': 0xa0,
|
|
44
|
+
'í': 0xa1,
|
|
45
|
+
'ó': 0xa2,
|
|
46
|
+
'ú': 0xa3,
|
|
47
|
+
'ñ': 0xa4,
|
|
48
|
+
'Ñ': 0xa5,
|
|
49
|
+
'ª': 0xa6,
|
|
50
|
+
'º': 0xa7,
|
|
51
|
+
'¿': 0xa8,
|
|
52
|
+
'®': 0xa9,
|
|
53
|
+
'¬': 0xaa,
|
|
54
|
+
'½': 0xab,
|
|
55
|
+
'¼': 0xac,
|
|
56
|
+
'¡': 0xad,
|
|
57
|
+
'«': 0xae,
|
|
58
|
+
'»': 0xaf,
|
|
59
|
+
'Á': 0xb5,
|
|
60
|
+
'Â': 0xb6,
|
|
61
|
+
'À': 0xb7,
|
|
62
|
+
'©': 0xb8,
|
|
63
|
+
'ã': 0xc6,
|
|
64
|
+
'Ã': 0xc7,
|
|
65
|
+
'ð': 0xd0,
|
|
66
|
+
'Ð': 0xd1,
|
|
67
|
+
'Ê': 0xd2,
|
|
68
|
+
'Ë': 0xd3,
|
|
69
|
+
'È': 0xd4,
|
|
70
|
+
'Í': 0xd6,
|
|
71
|
+
'Î': 0xd7,
|
|
72
|
+
'Ï': 0xd8,
|
|
73
|
+
'Ì': 0xde,
|
|
74
|
+
'Ó': 0xe0,
|
|
75
|
+
'Ô': 0xe2,
|
|
76
|
+
'Ò': 0xe3,
|
|
77
|
+
'õ': 0xe4,
|
|
78
|
+
'Õ': 0xe5,
|
|
79
|
+
'µ': 0xe6,
|
|
80
|
+
'Ú': 0xe9,
|
|
81
|
+
'Û': 0xea,
|
|
82
|
+
'Ù': 0xeb,
|
|
83
|
+
'ý': 0xec,
|
|
84
|
+
'Ý': 0xed,
|
|
85
|
+
'¯': 0xee,
|
|
86
|
+
'´': 0xef,
|
|
87
|
+
'±': 0xf1,
|
|
88
|
+
'¾': 0xf3,
|
|
89
|
+
'¶': 0xf4,
|
|
90
|
+
'§': 0xf5,
|
|
91
|
+
'÷': 0xf6,
|
|
92
|
+
'¸': 0xf7,
|
|
93
|
+
'°': 0xf8,
|
|
94
|
+
'¨': 0xf9,
|
|
95
|
+
'·': 0xfa,
|
|
96
|
+
'¹': 0xfb,
|
|
97
|
+
'³': 0xfc,
|
|
98
|
+
'²': 0xfd,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const normalizeHost = value => String(value || '').trim();
|
|
102
|
+
const normalizeCodePage = value =>
|
|
103
|
+
String(value || DEFAULT_CODE_PAGE).trim().toLowerCase();
|
|
104
|
+
const normalizePort = value => {
|
|
105
|
+
const numericValue = Number(String(value || '').replace(/\D+/g, ''));
|
|
106
|
+
return Number.isFinite(numericValue) && numericValue > 0
|
|
107
|
+
? numericValue
|
|
108
|
+
: 9100;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const isLikelyBase64 = value => {
|
|
112
|
+
const normalizedValue = String(value || '').replace(/\s+/g, '');
|
|
113
|
+
if (!normalizedValue || normalizedValue.length % 4 !== 0) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return BASE64_REGEX.test(normalizedValue);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const extractPrintTextPayload = payload => {
|
|
121
|
+
const resolvePrintableObject = value => {
|
|
122
|
+
if (!value || typeof value !== 'object') {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const operation = String(value?.operation || '').trim().toUpperCase();
|
|
127
|
+
if (operation !== 'PRINT_TEXT') {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return value;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
if (typeof payload === 'string') {
|
|
135
|
+
const trimmedPayload = payload.trim();
|
|
136
|
+
if (trimmedPayload.startsWith('{') || trimmedPayload.startsWith('[')) {
|
|
137
|
+
try {
|
|
138
|
+
const parsedPayload = JSON.parse(trimmedPayload);
|
|
139
|
+
const printableObject = resolvePrintableObject(parsedPayload);
|
|
140
|
+
if (printableObject) {
|
|
141
|
+
const values = Array.isArray(printableObject?.value)
|
|
142
|
+
? printableObject.value
|
|
143
|
+
: [printableObject?.value];
|
|
144
|
+
|
|
145
|
+
return values.map(item => String(item ?? '')).join('');
|
|
146
|
+
}
|
|
147
|
+
} catch (e) {
|
|
148
|
+
// keep the raw payload fallback below
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return '';
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const printableObject = resolvePrintableObject(payload);
|
|
156
|
+
if (!printableObject) {
|
|
157
|
+
return '';
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const values = Array.isArray(printableObject?.value)
|
|
161
|
+
? printableObject.value
|
|
162
|
+
: [printableObject?.value];
|
|
163
|
+
|
|
164
|
+
return values.map(item => String(item ?? '')).join('');
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const encodeTextPayload = (text, codePage = DEFAULT_CODE_PAGE) => {
|
|
168
|
+
const normalizedCodePage = normalizeCodePage(codePage);
|
|
169
|
+
if (['latin1', 'iso-8859-1', 'windows-1252', 'win1252'].includes(normalizedCodePage)) {
|
|
170
|
+
return Buffer.from(String(text || ''), 'latin1');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (normalizedCodePage !== 'cp850') {
|
|
174
|
+
return Buffer.from(String(text || ''), 'latin1');
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return Buffer.from(
|
|
178
|
+
Array.from(String(text || '')).map(character => {
|
|
179
|
+
const charCode = character.charCodeAt(0);
|
|
180
|
+
if (charCode <= 0x7f) {
|
|
181
|
+
return charCode;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return CP850_CHAR_MAP[character] ?? 0x3f;
|
|
185
|
+
}),
|
|
186
|
+
);
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
const toPrintBuffer = (payload, {codePage = DEFAULT_CODE_PAGE} = {}) => {
|
|
190
|
+
if (payload === null || payload === undefined) {
|
|
191
|
+
return Buffer.alloc(0);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const printableTextPayload = extractPrintTextPayload(payload);
|
|
195
|
+
if (printableTextPayload) {
|
|
196
|
+
return encodeTextPayload(printableTextPayload, codePage);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (Buffer.isBuffer(payload)) {
|
|
200
|
+
return payload;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (payload instanceof Uint8Array) {
|
|
204
|
+
return Buffer.from(payload);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (typeof payload !== 'string') {
|
|
208
|
+
return Buffer.from(JSON.stringify(payload), 'utf8');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (isLikelyBase64(payload)) {
|
|
212
|
+
return Buffer.from(payload.replace(/\s+/g, ''), 'base64');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return encodeTextPayload(payload, codePage);
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
export const isNetworkPrinterRuntimeSupported = true;
|
|
219
|
+
|
|
220
|
+
export const decodeNetworkPrinterPayload = (payload, options = {}) =>
|
|
221
|
+
toPrintBuffer(payload, options);
|
|
222
|
+
|
|
223
|
+
export const checkNetworkPrinterConnection = ({
|
|
224
|
+
host,
|
|
225
|
+
port,
|
|
226
|
+
connectTimeout = DEFAULT_CONNECT_TIMEOUT,
|
|
227
|
+
}) => {
|
|
228
|
+
const normalizedHost = normalizeHost(host);
|
|
229
|
+
if (!normalizedHost) {
|
|
230
|
+
return Promise.reject(
|
|
231
|
+
new Error('Endereco de rede da impressora nao informado.'),
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const normalizedPort = normalizePort(port);
|
|
236
|
+
|
|
237
|
+
return new Promise((resolve, reject) => {
|
|
238
|
+
let settled = false;
|
|
239
|
+
let socket = null;
|
|
240
|
+
|
|
241
|
+
const finish = (error = null) => {
|
|
242
|
+
if (settled) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
settled = true;
|
|
247
|
+
|
|
248
|
+
try {
|
|
249
|
+
socket?.removeAllListeners?.();
|
|
250
|
+
} catch (e) {
|
|
251
|
+
// noop
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
try {
|
|
255
|
+
socket?.end?.();
|
|
256
|
+
} catch (e) {
|
|
257
|
+
// noop
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
try {
|
|
261
|
+
socket?.destroy?.();
|
|
262
|
+
} catch (e) {
|
|
263
|
+
// noop
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (error) {
|
|
267
|
+
reject(error);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
resolve({
|
|
272
|
+
success: true,
|
|
273
|
+
host: normalizedHost,
|
|
274
|
+
port: normalizedPort,
|
|
275
|
+
});
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
socket = TcpSocket.createConnection(
|
|
279
|
+
{
|
|
280
|
+
host: normalizedHost,
|
|
281
|
+
port: normalizedPort,
|
|
282
|
+
reuseAddress: true,
|
|
283
|
+
connectTimeout,
|
|
284
|
+
},
|
|
285
|
+
() => {
|
|
286
|
+
finish();
|
|
287
|
+
},
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
socket.on('error', error => {
|
|
291
|
+
finish(error);
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
socket.setTimeout(connectTimeout, () => {
|
|
295
|
+
finish(new Error('Tempo esgotado ao conectar na impressora de rede.'));
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
export const printOnNetworkPrinter = ({
|
|
301
|
+
host,
|
|
302
|
+
port,
|
|
303
|
+
payload,
|
|
304
|
+
codePage = DEFAULT_CODE_PAGE,
|
|
305
|
+
connectTimeout = DEFAULT_CONNECT_TIMEOUT,
|
|
306
|
+
}) => {
|
|
307
|
+
const normalizedHost = normalizeHost(host);
|
|
308
|
+
if (!normalizedHost) {
|
|
309
|
+
return Promise.reject(
|
|
310
|
+
new Error('Endereco de rede da impressora nao informado.'),
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const normalizedPort = normalizePort(port);
|
|
315
|
+
const dataBuffer = toPrintBuffer(payload, {codePage});
|
|
316
|
+
|
|
317
|
+
if (!dataBuffer.length) {
|
|
318
|
+
return Promise.reject(new Error('Spool vazio para impressao em rede.'));
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return new Promise((resolve, reject) => {
|
|
322
|
+
let settled = false;
|
|
323
|
+
let socket = null;
|
|
324
|
+
|
|
325
|
+
const finish = (error = null) => {
|
|
326
|
+
if (settled) {
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
settled = true;
|
|
331
|
+
|
|
332
|
+
try {
|
|
333
|
+
socket?.removeAllListeners?.();
|
|
334
|
+
} catch (e) {
|
|
335
|
+
// noop
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (error) {
|
|
339
|
+
try {
|
|
340
|
+
socket?.destroy?.();
|
|
341
|
+
} catch (e) {
|
|
342
|
+
// noop
|
|
343
|
+
}
|
|
344
|
+
reject(error);
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
resolve({success: true});
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
socket = TcpSocket.createConnection(
|
|
352
|
+
{
|
|
353
|
+
host: normalizedHost,
|
|
354
|
+
port: normalizedPort,
|
|
355
|
+
reuseAddress: true,
|
|
356
|
+
connectTimeout,
|
|
357
|
+
},
|
|
358
|
+
() => {
|
|
359
|
+
socket.setNoDelay(true);
|
|
360
|
+
socket.write(dataBuffer, undefined, writeError => {
|
|
361
|
+
if (writeError) {
|
|
362
|
+
finish(writeError);
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
setTimeout(() => {
|
|
367
|
+
try {
|
|
368
|
+
socket.end();
|
|
369
|
+
} catch (e) {
|
|
370
|
+
try {
|
|
371
|
+
socket.destroy();
|
|
372
|
+
} catch (destroyError) {
|
|
373
|
+
// noop
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
finish();
|
|
378
|
+
}, DEFAULT_FLUSH_DELAY);
|
|
379
|
+
});
|
|
380
|
+
},
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
socket.on('error', error => {
|
|
384
|
+
finish(error);
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
socket.setTimeout(connectTimeout, () => {
|
|
388
|
+
finish(new Error('Tempo esgotado ao conectar na impressora de rede.'));
|
|
389
|
+
});
|
|
390
|
+
});
|
|
391
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const isNetworkPrinterRuntimeSupported = false;
|
|
2
|
+
|
|
3
|
+
export const decodeNetworkPrinterPayload = payload => payload;
|
|
4
|
+
|
|
5
|
+
export const checkNetworkPrinterConnection = async () => {
|
|
6
|
+
throw new Error(
|
|
7
|
+
'Teste de conectividade da impressora disponivel apenas no app nativo.',
|
|
8
|
+
);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const printOnNetworkPrinter = async () => {
|
|
12
|
+
throw new Error(
|
|
13
|
+
'Impressao de rede disponivel apenas no app nativo. No navegador, use um device local intermediario.',
|
|
14
|
+
);
|
|
15
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { create } from 'zustand';
|
|
2
|
+
import { useSyncExternalStore } from 'react';
|
|
3
|
+
import stores from '@stores';
|
|
4
|
+
import {bridgeStoreError} from '@controleonline/ui-common/src/react/stores/storeErrorBridge'
|
|
5
|
+
|
|
6
|
+
const storeState = {};
|
|
7
|
+
|
|
8
|
+
export const useStores = create((set, get) => {
|
|
9
|
+
if (Object.keys(storeState).length > 0) {
|
|
10
|
+
return storeState;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (!stores || Object.keys(stores).length === 0) {
|
|
14
|
+
console.warn('No stores defined.');
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
Object.keys(stores).forEach(storeName => {
|
|
19
|
+
const storeModule = stores[storeName];
|
|
20
|
+
|
|
21
|
+
if (
|
|
22
|
+
!storeModule ||
|
|
23
|
+
!storeModule.state ||
|
|
24
|
+
!storeModule.mutations ||
|
|
25
|
+
!storeModule.actions
|
|
26
|
+
) {
|
|
27
|
+
console.warn(
|
|
28
|
+
`Store "${storeName}" is missing required properties (state, mutations, or actions). Skipping.`,
|
|
29
|
+
);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
storeState[storeName] = {
|
|
34
|
+
...storeModule.state,
|
|
35
|
+
getters: new Proxy(storeModule.state, {
|
|
36
|
+
get: (_, prop) => {
|
|
37
|
+
const s = get()[storeName];
|
|
38
|
+
return s ? s[prop] : undefined;
|
|
39
|
+
},
|
|
40
|
+
}),
|
|
41
|
+
actions: {},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const commit = (type, payload, options = {}) => {
|
|
45
|
+
if (!storeModule.mutations[type]) {
|
|
46
|
+
console.error(`Mutation "${type}" not found in store "${storeName}"`);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const keyChanged = storeModule.mutations[type](
|
|
51
|
+
storeState[storeName].getters,
|
|
52
|
+
payload,
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
set(state => ({
|
|
56
|
+
[storeName]: {
|
|
57
|
+
...state[storeName],
|
|
58
|
+
[keyChanged]: payload,
|
|
59
|
+
},
|
|
60
|
+
}));
|
|
61
|
+
|
|
62
|
+
// Todas as stores precisam usar o mesmo feedback visual centralizado de erro.
|
|
63
|
+
bridgeStoreError({
|
|
64
|
+
storeName,
|
|
65
|
+
mutationType: type,
|
|
66
|
+
error: payload,
|
|
67
|
+
options,
|
|
68
|
+
})
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const dispatch = (actionName, ...args) => {
|
|
72
|
+
if (typeof actionName !== 'string' || !actionName) {
|
|
73
|
+
console.error(
|
|
74
|
+
`Dispatch received an invalid action name in store "${storeName}"`,
|
|
75
|
+
);
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
let targetStoreName = storeName;
|
|
80
|
+
let targetActionName = actionName;
|
|
81
|
+
|
|
82
|
+
if (actionName.includes('/')) {
|
|
83
|
+
const [parsedStoreName, parsedActionName] = actionName.split('/');
|
|
84
|
+
targetStoreName = parsedStoreName || storeName;
|
|
85
|
+
targetActionName = parsedActionName || actionName;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const targetStore = get()[targetStoreName];
|
|
89
|
+
const targetAction = targetStore?.actions?.[targetActionName];
|
|
90
|
+
|
|
91
|
+
if (typeof targetAction !== 'function') {
|
|
92
|
+
console.error(
|
|
93
|
+
`Action "${targetActionName}" not found in store "${targetStoreName}"`,
|
|
94
|
+
);
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return targetAction(...args);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
Object.keys(storeModule.actions).forEach(actionName => {
|
|
102
|
+
storeState[storeName].actions[actionName] = (...args) =>
|
|
103
|
+
storeModule.actions[actionName](
|
|
104
|
+
{commit, getters: storeState[storeName].getters, dispatch},
|
|
105
|
+
...args,
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
return storeState;
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const EMPTY_STORE = { getters: {}, actions: {} };
|
|
114
|
+
export const useStore = (storeName) =>
|
|
115
|
+
useSyncExternalStore(
|
|
116
|
+
useStores.subscribe,
|
|
117
|
+
() => {
|
|
118
|
+
const state = useStores.getState();
|
|
119
|
+
if (!state[storeName]) {
|
|
120
|
+
// warn once to help trace missing store causing ReferenceError
|
|
121
|
+
console.warn(`useStore: store not found "${String(storeName)}"`);
|
|
122
|
+
return EMPTY_STORE;
|
|
123
|
+
}
|
|
124
|
+
return state[storeName];
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
export const getAllStores = () => useStores.getState();
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {publishSystemError} from '@controleonline/ui-common/src/react/utils/systemErrorChannel'
|
|
2
|
+
import {resolveSystemErrorMessage} from '@controleonline/ui-common/src/react/utils/systemErrorMessage'
|
|
3
|
+
|
|
4
|
+
export const shouldSkipStoreErrorMutation = options =>
|
|
5
|
+
options?.skipSystemError === true
|
|
6
|
+
|
|
7
|
+
export const isStoreErrorMutation = (mutationType, error, options = {}) => {
|
|
8
|
+
if (shouldSkipStoreErrorMutation(options)) {
|
|
9
|
+
return false
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
String(mutationType || '').endsWith('SET_ERROR') &&
|
|
14
|
+
!!resolveSystemErrorMessage(error)
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const bridgeStoreError = ({
|
|
19
|
+
storeName,
|
|
20
|
+
mutationType,
|
|
21
|
+
error,
|
|
22
|
+
options = {},
|
|
23
|
+
}) => {
|
|
24
|
+
if (!isStoreErrorMutation(mutationType, error, options)) {
|
|
25
|
+
return false
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return publishSystemError(error, {
|
|
29
|
+
source: 'store',
|
|
30
|
+
storeName: String(storeName || ''),
|
|
31
|
+
mutationType: String(mutationType || ''),
|
|
32
|
+
...options,
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default bridgeStoreError
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const safeTrim = value => String(value || '').trim();
|
|
2
|
+
|
|
3
|
+
const serializeRegistration = registration => {
|
|
4
|
+
try {
|
|
5
|
+
return JSON.stringify(registration);
|
|
6
|
+
} catch {
|
|
7
|
+
return '';
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const syncBackgroundRuntimeRegistration = ({
|
|
12
|
+
backgroundRuntimeModule,
|
|
13
|
+
registration,
|
|
14
|
+
lastRegistrationIdRef,
|
|
15
|
+
lastRegistrationPayloadRef,
|
|
16
|
+
} = {}) => {
|
|
17
|
+
if (!backgroundRuntimeModule) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const nextRegistrationId = safeTrim(registration?.registrationId);
|
|
22
|
+
const nextPayload = registration ? serializeRegistration(registration) : '';
|
|
23
|
+
|
|
24
|
+
if (!nextRegistrationId || !nextPayload) {
|
|
25
|
+
const previousRegistrationId = lastRegistrationIdRef?.current || '';
|
|
26
|
+
if (lastRegistrationIdRef) {
|
|
27
|
+
lastRegistrationIdRef.current = '';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (lastRegistrationPayloadRef) {
|
|
31
|
+
lastRegistrationPayloadRef.current = '';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (previousRegistrationId) {
|
|
35
|
+
backgroundRuntimeModule.clearRegistration(previousRegistrationId).catch(
|
|
36
|
+
() => {},
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (
|
|
44
|
+
lastRegistrationIdRef?.current === nextRegistrationId &&
|
|
45
|
+
lastRegistrationPayloadRef?.current === nextPayload
|
|
46
|
+
) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const previousRegistrationId = lastRegistrationIdRef?.current || '';
|
|
51
|
+
if (
|
|
52
|
+
previousRegistrationId &&
|
|
53
|
+
previousRegistrationId !== nextRegistrationId
|
|
54
|
+
) {
|
|
55
|
+
backgroundRuntimeModule.clearRegistration(previousRegistrationId).catch(
|
|
56
|
+
() => {},
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (lastRegistrationIdRef) {
|
|
61
|
+
lastRegistrationIdRef.current = nextRegistrationId;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (lastRegistrationPayloadRef) {
|
|
65
|
+
lastRegistrationPayloadRef.current = nextPayload;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
backgroundRuntimeModule.syncRegistration(nextPayload).catch(() => {});
|
|
69
|
+
};
|