@controleonline/ui-common 1.2.80 → 1.2.82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/AGENTS.md +8 -0
  2. package/package.json +9 -3
  3. package/src/api/fetch.js +7 -7
  4. package/src/react/components/AddImportModal.js +6 -2
  5. package/src/react/components/BackgroundRuntimeBridge.js +201 -215
  6. package/src/react/components/ConfirmModal.js +44 -9
  7. package/src/react/components/ConfirmModal.styles.js +55 -41
  8. package/src/react/components/CopyDeviceConfigModal.js +193 -0
  9. package/src/react/components/CopyDeviceConfigModal.styles.js +123 -0
  10. package/src/react/components/DefaultProvider.native.js +22 -0
  11. package/src/react/components/DefaultProvider.web.js +25 -1
  12. package/src/react/components/EntityLogBranch.js +482 -0
  13. package/src/react/components/EntityLogCards.js +369 -0
  14. package/src/react/components/EntityLogContent.js +113 -794
  15. package/src/react/components/LinkedOrderProductsTab.js +3 -3
  16. package/src/react/components/PrintService.js +130 -409
  17. package/src/react/components/RemoteCheckoutService.js +2 -2
  18. package/src/react/components/RuntimeBottomNavigationBar.js +141 -146
  19. package/src/react/components/RuntimeFooterMarqueeText.js +137 -0
  20. package/src/react/components/RuntimeInfoFooter.js +12 -15
  21. package/src/react/components/SystemErrorToast.js +49 -29
  22. package/src/react/components/SystemErrorToast.styles.js +43 -38
  23. package/src/react/components/UserAvatar.js +120 -28
  24. package/src/react/config/deviceConfigBootstrap.js +330 -304
  25. package/src/react/hooks/usePrintSpoolEffects.js +161 -0
  26. package/src/react/pages/DeviceDetailPage.js +6 -2882
  27. package/src/react/pages/Devices/detail/DeviceDetailAlertsCommandsSection.js +233 -0
  28. package/src/react/pages/Devices/detail/DeviceDetailHeader.js +138 -0
  29. package/src/react/pages/Devices/detail/DeviceDetailMovementSections.js +167 -0
  30. package/src/react/pages/Devices/detail/DeviceDetailOrdersPrintSection.js +216 -0
  31. package/src/react/pages/Devices/detail/DeviceDetailPaymentSection.js +44 -0
  32. package/src/react/pages/Devices/detail/DeviceDetailPdvConfigSection.js +390 -0
  33. package/src/react/pages/Devices/detail/DeviceDetailRenderers.js +135 -0
  34. package/src/react/pages/Devices/detail/DeviceDetailScreen.js +495 -0
  35. package/src/react/pages/Devices/detail/OptionButtonChip.js +65 -0
  36. package/src/react/pages/Devices/detail/deviceDetailConstants.js +36 -0
  37. package/src/react/pages/Devices/detail/deviceDetailHelpers.js +70 -0
  38. package/src/react/pages/Devices/detail/useDeviceDetailActions.js +483 -0
  39. package/src/react/pages/Devices/detail/useDeviceDetailCopyConfig.js +87 -0
  40. package/src/react/pages/Devices/detail/useDeviceDetailLoaders.js +327 -0
  41. package/src/react/pages/Devices/detail/useDeviceDetailSaves.js +429 -0
  42. package/src/react/pages/Devices/detail/useDeviceDetailStateA.js +489 -0
  43. package/src/react/pages/Devices/detail/useDeviceDetailStateB.js +98 -0
  44. package/src/react/pages/Devices/deviceTypes/index.js +2 -0
  45. package/src/react/pages/Devices/deviceTypes/pdv.js +11 -0
  46. package/src/react/pages/Imports.js +3 -2
  47. package/src/react/pages/IntegrationConfigFields.js +126 -0
  48. package/src/react/pages/IntegrationConfigPage.js +122 -591
  49. package/src/react/pages/IntegrationConfigPage.utils.js +95 -0
  50. package/src/react/print/usePrintButtonController.js +9 -1
  51. package/src/react/services/Getnet/Checkout.js +81 -0
  52. package/src/react/services/Getnet/Getnet.js +77 -0
  53. package/src/react/services/paymentGatewayExecution.js +20 -0
  54. package/src/react/utils/bottomNavigationToolbar.js +161 -0
  55. package/src/react/utils/commercialDocumentOrders.js +18 -6
  56. package/src/react/utils/copyDeviceConfigs.js +198 -0
  57. package/src/react/utils/fileUrl.js +43 -0
  58. package/src/react/utils/importStatus.js +19 -10
  59. package/src/react/utils/logSettings.js +7 -7
  60. package/src/react/utils/maintenanceSettings.js +16 -0
  61. package/src/react/utils/paymentDevices.js +6 -0
  62. package/src/react/utils/printManagedPrinter.js +45 -0
  63. package/src/react/utils/printRouting.js +63 -0
  64. package/src/react/utils/printSpoolUtils.js +119 -0
  65. package/src/react/utils/printerDevices.js +368 -368
  66. package/src/react/utils/runtimeFooter.js +10 -19
  67. package/src/react/utils/shopFranchises.js +186 -65
  68. package/src/react/utils/systemErrorMessage.js +71 -67
  69. package/src/store/device_config/customActions.js +119 -30
  70. package/src/tests/browser/manager/bottom-navigation-role-toolbar.spec.js +353 -0
  71. package/src/tests/browser/manager/device-detail-alias-save.spec.js +345 -0
  72. package/src/tests/browser/manager/device-detail-copy-config.spec.js +365 -0
  73. package/src/tests/browser/manager/runtime-footer-marquee.spec.js +262 -0
  74. package/src/tests/browser/manager/theme-confirm-toast.spec.js +236 -0
  75. package/src/tests/react/components/RuntimeFooterMarqueeText.test.js +171 -0
  76. package/src/tests/react/components/UserAvatar.test.js +6 -2
  77. package/src/tests/react/components/themeAwareModals.test.mjs +60 -0
  78. package/src/tests/react/config/deviceConfigBootstrap.test.js +104 -66
  79. package/src/tests/react/pages/deviceDetailDelete.test.js +78 -0
  80. package/src/tests/react/pages/receitaFederalIntegrationContract.test.mjs +48 -0
  81. package/src/tests/react/utils/bottomNavigationToolbar.test.js +222 -0
  82. package/src/tests/react/utils/copyDeviceConfigs.test.mjs +127 -0
  83. package/src/tests/react/utils/fileUrl.test.js +38 -0
  84. package/src/tests/react/utils/importStatus.test.js +26 -9
  85. package/src/tests/react/utils/passwordPolicy.test.js +27 -0
  86. package/src/tests/react/utils/printRouting.test.mjs +86 -0
  87. package/src/tests/react/utils/printSpoolUtils.test.mjs +52 -0
  88. package/src/tests/react/utils/runtimeFooter.test.js +7 -0
  89. package/src/tests/react/utils/shopFranchises.test.js +121 -115
  90. package/src/tests/react/utils/systemErrorMessage.test.js +32 -59
@@ -0,0 +1,126 @@
1
+ import React from 'react';
2
+ import { ActivityIndicator, Text, TextInput, TouchableOpacity, View } from 'react-native';
3
+ import Icon from 'react-native-vector-icons/Feather';
4
+ import DefaultUpload from '@controleonline/ui-default/src/react/components/upload/DefaultUpload';
5
+ import { extractFileId, toFileIri, uploadFileToApi } from '@controleonline/ui-default/src/react/components/upload/fileUpload';
6
+ import styles from './IntegrationConfigPage.styles';
7
+
8
+ const FileField = ({ field, value, editable, providerId, updateField }) => (
9
+ <View style={styles.fileFieldWrap}>
10
+ <Text style={styles.fieldHint}>
11
+ {value
12
+ ? `Arquivo vinculado (id: ${String(value).replace(/\D/g, '') || value})`
13
+ : 'Nenhum certificado vinculado.'}
14
+ </Text>
15
+ <DefaultUpload
16
+ relationStoreName="people"
17
+ relationField="people"
18
+ relationResource="people"
19
+ entityId={providerId}
20
+ companyId={providerId}
21
+ context={field.fileContext || 'company_certificate'}
22
+ libraryContexts={[field.fileContext || 'company_certificate']}
23
+ acceptedTypes={field.accept || '.pfx,.p12,application/x-pkcs12'}
24
+ fileType=""
25
+ fileTypeLabel="certificado"
26
+ title={field.label}
27
+ triggerLabel="Gerenciar certificado"
28
+ managerTitle="Gerenciador de arquivos"
29
+ searchPlaceholder="Buscar certificado"
30
+ uploadButtonLabel="Enviar certificado"
31
+ emptyAttachmentLabel="Nenhum certificado anexado."
32
+ emptyLibraryLabel="Nenhum arquivo encontrado."
33
+ uploadSuccessMessage="Certificado enviado."
34
+ attachSuccessMessage="Certificado vinculado."
35
+ removeSuccessMessage="Certificado removido."
36
+ showInlineContent={false}
37
+ uploadResultAlreadyAttached
38
+ requireEntity={false}
39
+ onUploadFile={async ({ file, companyId, context, entityId }) => {
40
+ const uploaded = await uploadFileToApi({
41
+ file,
42
+ context: context || field.fileContext || 'company_certificate',
43
+ peopleId: companyId || providerId,
44
+ entityId: entityId || providerId,
45
+ });
46
+ const id = extractFileId(uploaded);
47
+ const valueToSave = id ? String(id) : toFileIri(uploaded) || '';
48
+ if (!valueToSave) throw new Error('Upload sem identificador de arquivo.');
49
+ updateField(field.key, valueToSave);
50
+ return uploaded;
51
+ }}
52
+ onAttachFile={async fileObj => {
53
+ const id = extractFileId(fileObj);
54
+ const valueToSave = id ? String(id) : toFileIri(fileObj) || '';
55
+ if (!valueToSave) throw new Error('Arquivo sem identificador.');
56
+ updateField(field.key, valueToSave);
57
+ return fileObj;
58
+ }}
59
+ onRemoveAttachment={async () => {
60
+ updateField(field.key, '');
61
+ return true;
62
+ }}
63
+ renderTrigger={({ openManager, uploading }) => (
64
+ <TouchableOpacity
65
+ style={[styles.filePickerButton, !editable && styles.inputDisabled]}
66
+ disabled={!editable || uploading}
67
+ activeOpacity={0.85}
68
+ onPress={openManager}>
69
+ {uploading ? <ActivityIndicator color="#166534" /> : <Icon name="folder" size={16} color="#166534" />}
70
+ <Text style={styles.filePickerButtonText}>
71
+ {value ? 'Trocar certificado (gerenciador)' : 'Selecionar / enviar certificado'}
72
+ </Text>
73
+ </TouchableOpacity>
74
+ )}
75
+ />
76
+ </View>
77
+ );
78
+
79
+ export default function IntegrationConfigFields({
80
+ fields,
81
+ configValues,
82
+ editable,
83
+ embedded,
84
+ providerId,
85
+ updateField,
86
+ }) {
87
+ return fields.map(field => {
88
+ const value = configValues[field.key] || '';
89
+ return (
90
+ <View key={field.key} style={styles.fieldGroup}>
91
+ <Text style={styles.fieldLabel}>{field.label}</Text>
92
+ {!embedded ? <Text style={styles.fieldKey}>{field.key}</Text> : null}
93
+ {field.type === 'select' ? (
94
+ <View style={styles.selectList}>
95
+ {(field.options || []).map(option => {
96
+ const selected = String(value) === String(option.value);
97
+ return (
98
+ <TouchableOpacity
99
+ key={String(option.value)}
100
+ style={[styles.selectOption, selected && styles.selectOptionActive, !editable && styles.inputDisabled]}
101
+ disabled={!editable}
102
+ activeOpacity={0.85}
103
+ onPress={() => updateField(field.key, String(option.value))}>
104
+ <Text style={[styles.selectOptionText, selected && styles.selectOptionTextActive]}>{option.label}</Text>
105
+ </TouchableOpacity>
106
+ );
107
+ })}
108
+ </View>
109
+ ) : field.type === 'file' ? (
110
+ <FileField field={field} value={value} editable={editable} providerId={providerId} updateField={updateField} />
111
+ ) : (
112
+ <TextInput
113
+ style={[styles.input, !editable && styles.inputDisabled]}
114
+ value={value}
115
+ onChangeText={nextValue => updateField(field.key, nextValue)}
116
+ editable={editable}
117
+ autoCapitalize="none"
118
+ autoCorrect={false}
119
+ secureTextEntry={Boolean(field.secureTextEntry)}
120
+ placeholder={field.placeholder}
121
+ />
122
+ )}
123
+ </View>
124
+ );
125
+ });
126
+ }