@controleonline/ui-common 1.2.87 → 1.2.88
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/workflows/integration-source-gate.yml +68 -0
- package/.github/workflows/manager-worker.yml +7 -156
- package/.github/workflows/publish-npm.yml +73 -27
- package/.github/workflows/pull-request-checks.yml +7 -5
- package/docs/technical/Device-Detail-Alias-UI-Sync.md +141 -0
- package/package.json +13 -8
- package/src/react/components/BottomNavigationBar.js +178 -174
- package/src/react/components/BottomNavigationBar.styles.js +139 -118
- package/src/react/components/DefaultProvider.native.js +427 -421
- package/src/react/components/DefaultProvider.web.js +131 -125
- package/src/react/components/RemoteCheckoutService.js +3 -3
- package/src/react/components/RuntimeFooterMarqueeText.js +88 -36
- package/src/react/components/RuntimeInfoFooter.js +76 -43
- package/src/react/components/RuntimeInfoFooter.styles.js +22 -14
- package/src/react/config/deviceConfigBootstrap.js +3 -3
- package/src/react/pages/Devices/detail/DeviceDetailAlertsCommandsSection.js +4 -22
- package/src/react/pages/Devices/detail/DeviceDetailMovementSections.js +6 -2
- package/src/react/pages/Devices/detail/DeviceDetailOrdersPrintSection.js +4 -0
- package/src/react/pages/Devices/detail/DeviceDetailScreen.js +23 -338
- package/src/react/pages/Devices/detail/createDeviceDetailContext.js +20 -0
- package/src/react/pages/Devices/detail/useDeviceDetailActions.js +11 -36
- package/src/react/pages/Devices/detail/useDeviceDetailLoaders.js +129 -37
- package/src/react/pages/Devices/detail/useDeviceDetailSaves.js +11 -38
- package/src/react/pages/Devices/detail/useDeviceDetailStateA.js +9 -28
- package/src/react/pages/IntegrationConfigFields.js +1 -0
- package/src/react/pages/IntegrationConfigPage.js +101 -45
- package/src/react/pages/IntegrationConfigPage.utils.js +21 -13
- package/src/react/pages/fetchPeopleConfigs.js +21 -0
- package/src/react/pages/integrationsCatalog.js +15 -110
- package/src/react/services/Cielo/Cielo.js +9 -9
- package/src/react/services/Getnet/Getnet.web.js +25 -0
- package/src/react/utils/companyAuthority.js +36 -0
- package/src/react/utils/fileUrl.js +14 -5
- package/src/react/utils/paymentDevices.js +375 -270
- package/src/react/utils/printerDevices.js +2 -2
- package/src/react/utils/runtimeFooter.js +178 -224
- package/src/react/utils/runtimeFooterText.js +160 -0
- package/src/react/utils/runtimeLanguage.js +5 -5
- package/src/react/utils/runtimeZoom.js +29 -5
- package/src/react/utils/shopFranchises.js +167 -12
- package/src/react/utils/storeColumns.js +235 -217
- package/src/react/utils/systemErrorMessage.js +2 -1
- package/src/store/integration/index.js +43 -0
- package/src/tests/browser/manager/device-detail-apply-config-defined.spec.js +31 -0
- package/src/tests/browser/manager/device-detail-composition.spec.js +295 -0
- package/src/tests/browser/manager/device-detail-copy-config.spec.js +11 -1
- package/src/tests/browser/manager/device-detail-pdv-current-company.spec.js +273 -0
- package/src/tests/browser/manager/runtime-footer-rotation.spec.js +397 -0
- package/src/tests/react/components/DefaultProviderAuthority.test.js +28 -0
- package/src/tests/react/components/RuntimeFooterMarqueeText.build.test.js +29 -0
- package/src/tests/react/config/deviceConfigBootstrap.test.js +24 -1
- package/src/tests/react/pages/applyCurrentDeviceConfig.test.js +85 -0
- package/src/tests/react/pages/deviceDetailComposition.test.js +65 -0
- package/src/tests/react/pages/deviceDetailHookDependencies.test.mjs +31 -0
- package/src/tests/react/pages/deviceDetailLoaderDependencies.test.mjs +28 -0
- package/src/tests/react/pages/receitaFederalIntegrationContract.test.mjs +27 -6
- package/src/tests/react/services/Cielo.test.js +2 -2
- package/src/tests/react/utils/companyAuthority.test.js +53 -0
- package/src/tests/react/utils/formatter.test.mjs +6 -0
- package/src/tests/react/utils/paymentDevices.test.js +72 -0
- package/src/tests/react/utils/runtimeFooter.test.js +35 -0
- package/src/tests/react/utils/runtimeFooterText.test.js +88 -0
- package/src/tests/react/utils/runtimeLanguage.test.js +4 -4
- package/src/tests/react/utils/runtimeZoom.test.js +20 -0
- package/src/tests/react/utils/shopFranchises.test.js +32 -13
- package/src/tests/react/utils/translate.test.mjs +6 -6
- package/src/utils/formatter.js +7 -3
- package/src/utils/translate.js +16 -16
- package/src/utils/translatePending.js +6 -6
- package/src/utils/translateStorage.js +2 -2
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
const React = require('react');
|
|
2
2
|
const {useEffect, useRef, useState} = React;
|
|
3
|
-
const
|
|
3
|
+
const RN = require('react-native');
|
|
4
|
+
const Animated = RN.Animated;
|
|
5
|
+
const Text = RN.Text;
|
|
6
|
+
const View = RN.View;
|
|
7
|
+
const Platform = RN.Platform || {OS: 'native'};
|
|
8
|
+
const USE_NATIVE_DRIVER = Platform.OS !== 'web';
|
|
9
|
+
const IS_WEB = Platform.OS === 'web';
|
|
4
10
|
|
|
5
11
|
const GAP_PX = 32;
|
|
6
12
|
const MS_PER_PX = 28;
|
|
@@ -10,21 +16,28 @@ const HOLD_MS = 1200;
|
|
|
10
16
|
/**
|
|
11
17
|
* Single-line footer text. When content overflows the available width,
|
|
12
18
|
* scrolls horizontally in a continuous loop. Short text stays static.
|
|
19
|
+
* On web, avoids Animated opacity/transform issues that hid the label.
|
|
20
|
+
* RN Web also needs intrinsic sizing because Text can collapse to width 0
|
|
21
|
+
* inside a flex row.
|
|
22
|
+
*
|
|
23
|
+
* IMPORTANT: do not use destructuring defaults on require('react-native')
|
|
24
|
+
* — Metro web export fails with "Property name expected type of string
|
|
25
|
+
* but got undefined" (staging Deploy).
|
|
13
26
|
*/
|
|
14
|
-
const RuntimeFooterMarqueeText =
|
|
15
|
-
text
|
|
16
|
-
color
|
|
17
|
-
style
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
27
|
+
const RuntimeFooterMarqueeText = props => {
|
|
28
|
+
const text = props && props.text;
|
|
29
|
+
const color = props && props.color;
|
|
30
|
+
const style = props && props.style;
|
|
31
|
+
const testID =
|
|
32
|
+
(props && props.testID) || 'runtime-footer-marquee-text';
|
|
33
|
+
|
|
21
34
|
const [containerWidth, setContainerWidth] = useState(0);
|
|
22
35
|
const [contentWidth, setContentWidth] = useState(0);
|
|
23
36
|
const translateX = useRef(new Animated.Value(0)).current;
|
|
24
37
|
const animationRef = useRef(null);
|
|
25
38
|
|
|
26
39
|
const shouldMarquee =
|
|
27
|
-
containerWidth > 0 && contentWidth > containerWidth + 2;
|
|
40
|
+
!IS_WEB && containerWidth > 0 && contentWidth > containerWidth + 2;
|
|
28
41
|
|
|
29
42
|
useEffect(() => {
|
|
30
43
|
if (animationRef.current) {
|
|
@@ -40,26 +53,23 @@ const RuntimeFooterMarqueeText = ({
|
|
|
40
53
|
|
|
41
54
|
const distance = contentWidth + GAP_PX;
|
|
42
55
|
const duration = Math.max(Math.round(distance * MS_PER_PX), MIN_DURATION_MS);
|
|
43
|
-
|
|
44
56
|
const loop = Animated.loop(
|
|
45
57
|
Animated.sequence([
|
|
46
58
|
Animated.delay(HOLD_MS),
|
|
47
59
|
Animated.timing(translateX, {
|
|
48
60
|
toValue: -distance,
|
|
49
|
-
duration,
|
|
50
|
-
useNativeDriver:
|
|
61
|
+
duration: duration,
|
|
62
|
+
useNativeDriver: USE_NATIVE_DRIVER,
|
|
51
63
|
}),
|
|
52
64
|
Animated.timing(translateX, {
|
|
53
65
|
toValue: 0,
|
|
54
66
|
duration: 0,
|
|
55
|
-
useNativeDriver:
|
|
67
|
+
useNativeDriver: USE_NATIVE_DRIVER,
|
|
56
68
|
}),
|
|
57
69
|
]),
|
|
58
70
|
);
|
|
59
|
-
|
|
60
71
|
animationRef.current = loop;
|
|
61
72
|
loop.start();
|
|
62
|
-
|
|
63
73
|
return () => {
|
|
64
74
|
loop.stop();
|
|
65
75
|
animationRef.current = null;
|
|
@@ -68,30 +78,81 @@ const RuntimeFooterMarqueeText = ({
|
|
|
68
78
|
}, [shouldMarquee, contentWidth, containerWidth, text, translateX]);
|
|
69
79
|
|
|
70
80
|
const handleContainerLayout = event => {
|
|
71
|
-
const nextWidth = Math.round(
|
|
72
|
-
|
|
81
|
+
const nextWidth = Math.round(
|
|
82
|
+
(event &&
|
|
83
|
+
event.nativeEvent &&
|
|
84
|
+
event.nativeEvent.layout &&
|
|
85
|
+
event.nativeEvent.layout.width) ||
|
|
86
|
+
0,
|
|
87
|
+
);
|
|
88
|
+
setContainerWidth(current => (current === nextWidth ? current : nextWidth));
|
|
73
89
|
};
|
|
74
90
|
|
|
75
91
|
const handleTextLayout = event => {
|
|
76
|
-
const nextWidth = Math.round(
|
|
77
|
-
|
|
92
|
+
const nextWidth = Math.round(
|
|
93
|
+
(event &&
|
|
94
|
+
event.nativeEvent &&
|
|
95
|
+
event.nativeEvent.layout &&
|
|
96
|
+
event.nativeEvent.layout.width) ||
|
|
97
|
+
0,
|
|
98
|
+
);
|
|
99
|
+
setContentWidth(current => (current === nextWidth ? current : nextWidth));
|
|
78
100
|
};
|
|
79
101
|
|
|
80
102
|
const textStyle = [
|
|
81
103
|
style,
|
|
82
104
|
{
|
|
83
|
-
color,
|
|
84
|
-
flex: undefined,
|
|
105
|
+
color: color,
|
|
85
106
|
flexShrink: 0,
|
|
86
107
|
flexGrow: 0,
|
|
108
|
+
minHeight: 14,
|
|
87
109
|
},
|
|
88
|
-
shouldMarquee ? {textAlign: 'left'} : {textAlign: 'center'},
|
|
89
110
|
];
|
|
90
111
|
|
|
112
|
+
if (IS_WEB) {
|
|
113
|
+
textStyle.push({
|
|
114
|
+
display: 'inline-block',
|
|
115
|
+
width: 'auto',
|
|
116
|
+
maxWidth: 'none',
|
|
117
|
+
whiteSpace: 'nowrap',
|
|
118
|
+
flexBasis: 'auto',
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
textStyle.push(shouldMarquee ? {textAlign: 'left'} : {textAlign: 'center'});
|
|
123
|
+
|
|
124
|
+
const content = React.createElement(
|
|
125
|
+
Text,
|
|
126
|
+
{
|
|
127
|
+
numberOfLines: 1,
|
|
128
|
+
ellipsizeMode: IS_WEB ? 'tail' : 'clip',
|
|
129
|
+
onLayout: handleTextLayout,
|
|
130
|
+
style: textStyle,
|
|
131
|
+
},
|
|
132
|
+
text,
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
if (IS_WEB) {
|
|
136
|
+
return React.createElement(
|
|
137
|
+
View,
|
|
138
|
+
{
|
|
139
|
+
testID: testID,
|
|
140
|
+
style: {
|
|
141
|
+
flex: 1,
|
|
142
|
+
overflow: 'hidden',
|
|
143
|
+
justifyContent: 'center',
|
|
144
|
+
opacity: 1,
|
|
145
|
+
},
|
|
146
|
+
onLayout: handleContainerLayout,
|
|
147
|
+
},
|
|
148
|
+
content,
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
91
152
|
return React.createElement(
|
|
92
153
|
View,
|
|
93
154
|
{
|
|
94
|
-
testID,
|
|
155
|
+
testID: testID,
|
|
95
156
|
style: {flex: 1, overflow: 'hidden', justifyContent: 'center'},
|
|
96
157
|
onLayout: handleContainerLayout,
|
|
97
158
|
},
|
|
@@ -101,21 +162,12 @@ const RuntimeFooterMarqueeText = ({
|
|
|
101
162
|
style: {
|
|
102
163
|
flexDirection: 'row',
|
|
103
164
|
alignItems: 'center',
|
|
104
|
-
opacity,
|
|
105
|
-
transform: [{translateX}],
|
|
165
|
+
opacity: 1,
|
|
166
|
+
transform: [{translateX: translateX}],
|
|
106
167
|
alignSelf: shouldMarquee ? 'flex-start' : 'stretch',
|
|
107
168
|
},
|
|
108
169
|
},
|
|
109
|
-
|
|
110
|
-
Text,
|
|
111
|
-
{
|
|
112
|
-
numberOfLines: 1,
|
|
113
|
-
ellipsizeMode: 'clip',
|
|
114
|
-
onLayout: handleTextLayout,
|
|
115
|
-
style: textStyle,
|
|
116
|
-
},
|
|
117
|
-
text,
|
|
118
|
-
),
|
|
170
|
+
content,
|
|
119
171
|
shouldMarquee
|
|
120
172
|
? React.createElement(
|
|
121
173
|
Text,
|
|
@@ -124,7 +176,7 @@ const RuntimeFooterMarqueeText = ({
|
|
|
124
176
|
ellipsizeMode: 'clip',
|
|
125
177
|
accessible: false,
|
|
126
178
|
importantForAccessibility: 'no',
|
|
127
|
-
style: [
|
|
179
|
+
style: textStyle.concat([{marginLeft: GAP_PX}]),
|
|
128
180
|
},
|
|
129
181
|
text,
|
|
130
182
|
)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import React, {useEffect, useMemo,
|
|
1
|
+
import React, {useEffect, useMemo, useState} from 'react';
|
|
2
2
|
import {
|
|
3
3
|
ActivityIndicator,
|
|
4
|
-
|
|
4
|
+
Platform,
|
|
5
5
|
Text,
|
|
6
6
|
View,
|
|
7
7
|
useWindowDimensions,
|
|
@@ -24,13 +24,45 @@ import styles from './RuntimeInfoFooter.styles';
|
|
|
24
24
|
import RuntimeFooterMarqueeText from './RuntimeFooterMarqueeText';
|
|
25
25
|
|
|
26
26
|
const ROTATION_INTERVAL_MS = 4000;
|
|
27
|
-
const FADE_DURATION_MS = 260;
|
|
28
27
|
const COMPACT_BREAKPOINT = 720;
|
|
29
28
|
const MAX_INLINE_TEXT_LENGTH = 84;
|
|
29
|
+
const FALLBACK_TEXT_COLOR = '#0f172a';
|
|
30
|
+
|
|
31
|
+
const normalizeColor = value =>
|
|
32
|
+
String(value || '')
|
|
33
|
+
.trim()
|
|
34
|
+
.toLowerCase()
|
|
35
|
+
.replace(/\s+/g, '');
|
|
36
|
+
|
|
37
|
+
/** Prefer theme colors, but never render text the same as the footer background. */
|
|
38
|
+
const resolveVisibleFooterTextColor = colors => {
|
|
39
|
+
const candidates = [
|
|
40
|
+
colors?.footerText,
|
|
41
|
+
colors?.textSecondary,
|
|
42
|
+
colors?.text,
|
|
43
|
+
FALLBACK_TEXT_COLOR,
|
|
44
|
+
];
|
|
45
|
+
const background = normalizeColor(
|
|
46
|
+
colors?.footerBackground || colors?.navigationBackground || '',
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
for (const candidate of candidates) {
|
|
50
|
+
const normalized = normalizeColor(candidate);
|
|
51
|
+
if (!normalized) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (background && normalized === background) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
return candidate;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return FALLBACK_TEXT_COLOR;
|
|
61
|
+
};
|
|
30
62
|
|
|
31
63
|
const RuntimeInfoFooter = ({
|
|
32
64
|
appVersion,
|
|
33
|
-
|
|
65
|
+
mainCompany,
|
|
34
66
|
device,
|
|
35
67
|
colors,
|
|
36
68
|
useModernWebChromeProps = false,
|
|
@@ -38,7 +70,6 @@ const RuntimeInfoFooter = ({
|
|
|
38
70
|
const {width} = useWindowDimensions();
|
|
39
71
|
const insets = useSafeAreaInsets();
|
|
40
72
|
const [activeIndex, setActiveIndex] = useState(0);
|
|
41
|
-
const fadeOpacity = useRef(new Animated.Value(1)).current;
|
|
42
73
|
const allStores = useStores(state => state);
|
|
43
74
|
const deviceConfigStore = useStore('device_config');
|
|
44
75
|
const runtimeDebugStore = useStore('runtime_debug');
|
|
@@ -64,10 +95,27 @@ const RuntimeInfoFooter = ({
|
|
|
64
95
|
}),
|
|
65
96
|
[appVersion, device, deviceConfigItem, footerDebugInfo.primaryText],
|
|
66
97
|
);
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
98
|
+
const peopleStore = useStore('people');
|
|
99
|
+
const configsStore = useStore('configs');
|
|
100
|
+
const currentCompany = peopleStore?.getters?.currentCompany || {};
|
|
101
|
+
const storeMainCompany = peopleStore?.getters?.mainCompany || {};
|
|
102
|
+
const companyConfigs = configsStore?.getters?.items;
|
|
103
|
+
const companyFooterText = useMemo(() => {
|
|
104
|
+
const candidates = [
|
|
105
|
+
getRuntimeFooterText(currentCompany),
|
|
106
|
+
getRuntimeFooterText(storeMainCompany),
|
|
107
|
+
getRuntimeFooterText(mainCompany),
|
|
108
|
+
getRuntimeFooterText(null, companyConfigs),
|
|
109
|
+
getRuntimeFooterText(null, deviceConfigItem?.configs),
|
|
110
|
+
];
|
|
111
|
+
return candidates.find(Boolean) || '';
|
|
112
|
+
}, [
|
|
113
|
+
companyConfigs,
|
|
114
|
+
currentCompany?.configs,
|
|
115
|
+
mainCompany?.configs,
|
|
116
|
+
deviceConfigItem?.configs,
|
|
117
|
+
storeMainCompany?.configs,
|
|
118
|
+
]);
|
|
71
119
|
const footerTextLines = useMemo(
|
|
72
120
|
() => getRuntimeFooterTextLines(companyFooterText),
|
|
73
121
|
[companyFooterText],
|
|
@@ -166,14 +214,15 @@ const RuntimeInfoFooter = ({
|
|
|
166
214
|
),
|
|
167
215
|
[allStores],
|
|
168
216
|
);
|
|
169
|
-
const bottomInset =
|
|
217
|
+
const bottomInset =
|
|
218
|
+
Platform.OS === 'web'
|
|
219
|
+
? 0
|
|
220
|
+
: Math.max(Number(insets.bottom) || 0, 16);
|
|
170
221
|
|
|
171
222
|
useEffect(() => {
|
|
172
223
|
if (!shouldRotate || rotationEntries.length <= 1) {
|
|
173
224
|
setActiveIndex(0);
|
|
174
|
-
|
|
175
|
-
fadeOpacity.setValue(1);
|
|
176
|
-
return;
|
|
225
|
+
return undefined;
|
|
177
226
|
}
|
|
178
227
|
|
|
179
228
|
let timeoutId;
|
|
@@ -181,31 +230,14 @@ const RuntimeInfoFooter = ({
|
|
|
181
230
|
|
|
182
231
|
const scheduleTransition = () => {
|
|
183
232
|
timeoutId = setTimeout(() => {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (!finished || cancelled) {
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
setActiveIndex(current => (current + 1) % rotationEntries.length);
|
|
194
|
-
|
|
195
|
-
Animated.timing(fadeOpacity, {
|
|
196
|
-
toValue: 1,
|
|
197
|
-
duration: FADE_DURATION_MS,
|
|
198
|
-
useNativeDriver: true,
|
|
199
|
-
}).start(({finished: fadeInFinished}) => {
|
|
200
|
-
if (fadeInFinished && !cancelled) {
|
|
201
|
-
scheduleTransition();
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
});
|
|
233
|
+
if (cancelled) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
setActiveIndex(current => (current + 1) % rotationEntries.length);
|
|
237
|
+
scheduleTransition();
|
|
205
238
|
}, ROTATION_INTERVAL_MS);
|
|
206
239
|
};
|
|
207
240
|
|
|
208
|
-
fadeOpacity.setValue(1);
|
|
209
241
|
scheduleTransition();
|
|
210
242
|
|
|
211
243
|
return () => {
|
|
@@ -213,21 +245,22 @@ const RuntimeInfoFooter = ({
|
|
|
213
245
|
if (timeoutId) {
|
|
214
246
|
clearTimeout(timeoutId);
|
|
215
247
|
}
|
|
216
|
-
fadeOpacity.stopAnimation();
|
|
217
248
|
};
|
|
218
|
-
}, [
|
|
249
|
+
}, [rotationEntries.length, shouldRotate]);
|
|
219
250
|
|
|
220
251
|
if (rotationEntries.length === 0 && !showDebugInfo) {
|
|
221
252
|
return null;
|
|
222
253
|
}
|
|
223
254
|
|
|
224
|
-
const displayedText =
|
|
225
|
-
|
|
226
|
-
|
|
255
|
+
const displayedText = (
|
|
256
|
+
shouldRotate
|
|
257
|
+
? rotationEntries[activeIndex]
|
|
258
|
+
: inlineText
|
|
259
|
+
) || primaryText || device?.id || '';
|
|
227
260
|
const backgroundColor = colors?.footerBackground;
|
|
228
261
|
const borderColor = colors?.footerBorder;
|
|
229
|
-
const textColor = colors
|
|
230
|
-
const loadingColor = colors?.footerLink;
|
|
262
|
+
const textColor = resolveVisibleFooterTextColor(colors);
|
|
263
|
+
const loadingColor = colors?.footerLink || colors?.primary || textColor;
|
|
231
264
|
const shellProps = useModernWebChromeProps ? {} : {pointerEvents: 'none'};
|
|
232
265
|
const shellStyle = useModernWebChromeProps
|
|
233
266
|
? [styles.shell, {pointerEvents: 'none'}]
|
|
@@ -264,7 +297,7 @@ const RuntimeInfoFooter = ({
|
|
|
264
297
|
: displayedText
|
|
265
298
|
}
|
|
266
299
|
color={textColor}
|
|
267
|
-
opacity={
|
|
300
|
+
opacity={1}
|
|
268
301
|
style={styles.primaryText}
|
|
269
302
|
testID="runtime-footer-primary-text"
|
|
270
303
|
/>
|
|
@@ -3,36 +3,43 @@ import { StyleSheet } from 'react-native'
|
|
|
3
3
|
const styles = StyleSheet.create({
|
|
4
4
|
shell: {
|
|
5
5
|
width: '100%',
|
|
6
|
+
alignSelf: 'stretch',
|
|
6
7
|
},
|
|
7
8
|
container: {
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
width: '100%',
|
|
10
|
+
alignSelf: 'stretch',
|
|
11
|
+
minHeight: 28,
|
|
12
|
+
borderTopWidth: 0,
|
|
10
13
|
justifyContent: 'center',
|
|
11
|
-
paddingHorizontal:
|
|
12
|
-
|
|
14
|
+
paddingHorizontal: 12,
|
|
15
|
+
paddingTop: 4,
|
|
16
|
+
paddingBottom: 6,
|
|
13
17
|
},
|
|
14
18
|
containerExpanded: {
|
|
15
|
-
paddingVertical:
|
|
19
|
+
paddingVertical: 8,
|
|
16
20
|
},
|
|
17
21
|
primaryRow: {
|
|
18
22
|
flexDirection: 'row',
|
|
19
23
|
alignItems: 'center',
|
|
20
24
|
justifyContent: 'center',
|
|
21
|
-
|
|
25
|
+
width: '100%',
|
|
26
|
+
minHeight: 18,
|
|
22
27
|
},
|
|
23
28
|
statusDotWrap: {
|
|
24
|
-
|
|
25
|
-
minHeight:
|
|
26
|
-
marginRight:
|
|
29
|
+
width: 18,
|
|
30
|
+
minHeight: 18,
|
|
31
|
+
marginRight: 6,
|
|
27
32
|
alignItems: 'center',
|
|
28
33
|
justifyContent: 'center',
|
|
34
|
+
flexShrink: 0,
|
|
29
35
|
},
|
|
30
36
|
loadingWrap: {
|
|
31
|
-
|
|
32
|
-
minHeight:
|
|
33
|
-
marginLeft:
|
|
37
|
+
width: 18,
|
|
38
|
+
minHeight: 18,
|
|
39
|
+
marginLeft: 6,
|
|
34
40
|
alignItems: 'center',
|
|
35
41
|
justifyContent: 'center',
|
|
42
|
+
flexShrink: 0,
|
|
36
43
|
},
|
|
37
44
|
statusDot: {
|
|
38
45
|
width: 7,
|
|
@@ -42,8 +49,9 @@ const styles = StyleSheet.create({
|
|
|
42
49
|
},
|
|
43
50
|
primaryText: {
|
|
44
51
|
flex: 1,
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
minWidth: 0,
|
|
53
|
+
fontSize: 11,
|
|
54
|
+
lineHeight: 14,
|
|
47
55
|
textAlign: 'center',
|
|
48
56
|
fontWeight: '500',
|
|
49
57
|
},
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
appendScreenMetrics,
|
|
3
3
|
hasScreenMetricsChanges,
|
|
4
|
-
} from '@controleonline/ui-common/src/react/utils/screenMetrics';
|
|
4
|
+
} from '@controleonline/ui-common/src/react/utils/screenMetrics.js';
|
|
5
5
|
import {
|
|
6
6
|
normalizeBooleanConfig,
|
|
7
7
|
SHOP_LOYALTY_COUPONS_ENABLED_CONFIG_KEY,
|
|
8
|
-
} from '@controleonline/ui-common/src/react/utils/shopConfig';
|
|
8
|
+
} from '@controleonline/ui-common/src/react/utils/shopConfig.js';
|
|
9
9
|
|
|
10
10
|
export const CIELO_DEVICES = ['quantum', 'ingenico', 'positivo'];
|
|
11
11
|
export const SUPPORTED_POS_GATEWAYS = ['cielo', 'infinite-pay'];
|
|
@@ -51,7 +51,7 @@ export const POS_CHECK_ORDER_TYPE_TABLE = 'table';
|
|
|
51
51
|
export const POS_CHECK_ORDER_TYPE_STAMP = 'stamp';
|
|
52
52
|
export const POS_CHECK_ORDER_MANAGEMENT_MODE_MANAGE = 'manage';
|
|
53
53
|
export const POS_CHECK_ORDER_MANAGEMENT_MODE_EXISTING_ONLY = 'existing-only';
|
|
54
|
-
export const POS_OPERATION_MODE_DEFAULT =
|
|
54
|
+
export const POS_OPERATION_MODE_DEFAULT = POS_OPERATION_MODE_COUNTER;
|
|
55
55
|
export const POS_PRINT_MODE_ORDER = 'order';
|
|
56
56
|
export const POS_PRINT_MODE_FORM = 'form';
|
|
57
57
|
export const POS_PRINT_MODE_DEFAULT = POS_PRINT_MODE_ORDER;
|
|
@@ -1,29 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Text, View,
|
|
2
|
+
import { Text, View, TextInput, TouchableOpacity } from 'react-native';
|
|
3
3
|
import { Picker } from '@react-native-picker/picker';
|
|
4
4
|
import Icon from 'react-native-vector-icons/Feather';
|
|
5
5
|
import styles from '../../DeviceDetailPage.styles';
|
|
6
|
-
import {
|
|
7
|
-
POS_OPERATION_MODE_OPTIONS,
|
|
8
|
-
POS_OPERATION_MODE_COUNTER,
|
|
9
|
-
POS_PRINT_MODE_ORDER,
|
|
10
|
-
POS_PRINT_MODE_FORM,
|
|
11
|
-
POS_CHECK_ORDER_TYPE_NONE,
|
|
12
|
-
POS_CHECK_ORDER_TYPE_TAB,
|
|
13
|
-
POS_CHECK_ORDER_TYPE_TABLE,
|
|
14
|
-
POS_CHECK_ORDER_TYPE_STAMP,
|
|
15
|
-
POS_CHECK_ORDER_MANAGEMENT_MODE_MANAGE,
|
|
16
|
-
POS_CHECK_ORDER_MANAGEMENT_MODE_EXISTING_ONLY,
|
|
17
|
-
POS_CASH_MANAGEMENT_MODE_CASH_REGISTER,
|
|
18
|
-
POS_CASH_MANAGEMENT_MODE_DAILY,
|
|
19
|
-
POS_OPERATION_MODE_CONFIG_KEY,
|
|
20
|
-
DEVICE_ORDER_VISIBILITY_COMPANY,
|
|
21
|
-
DEVICE_ORDER_VISIBILITY_DEVICE,
|
|
22
|
-
resolvePosOperationMode,
|
|
23
|
-
} from '@controleonline/ui-common/src/react/config/deviceConfigBootstrap';
|
|
24
|
-
import { normalizeEntityId } from '@controleonline/ui-common/src/react/utils/paymentDevices';
|
|
25
|
-
import { getProductShowcaseLabel } from './deviceDetailHelpers';
|
|
26
|
-
import { tt } from './deviceDetailConstants';
|
|
27
6
|
|
|
28
7
|
/**
|
|
29
8
|
* Extracted from DeviceDetailScreen for modularization (≤500 lines).
|
|
@@ -32,6 +11,8 @@ import { tt } from './deviceDetailConstants';
|
|
|
32
11
|
export default function DeviceDetailAlertsCommandsSection(ctx) {
|
|
33
12
|
const {
|
|
34
13
|
themeColors, brandColors, palette,
|
|
14
|
+
shouldShowDeviceBehavior, shouldShowRemotePayment, shouldShowRemoteCommands,
|
|
15
|
+
deviceRuntimeDebugInfoEnabled, setDeviceRuntimeDebugInfoEnabled,
|
|
35
16
|
renderHelpButton, renderOptionButtons, renderSwitchRow, renderProduct,
|
|
36
17
|
posOperationMode, setPosOperationMode, savePosOperationMode, savingPosOperationMode,
|
|
37
18
|
productShowcaseId, setProductShowcaseId, saveProductShowcaseConfig,
|
|
@@ -66,6 +47,7 @@ export default function DeviceDetailAlertsCommandsSection(ctx) {
|
|
|
66
47
|
|
|
67
48
|
return (
|
|
68
49
|
<>
|
|
50
|
+
{shouldShowDeviceBehavior && (
|
|
69
51
|
<View style={styles.section}>
|
|
70
52
|
<Text style={styles.sectionTitle}>
|
|
71
53
|
<Icon name="volume-2" size={13} /> {' '}Aviso Sonoro
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Text, View, FlatList, TextInput } from 'react-native';
|
|
2
|
+
import { Text, View, FlatList, TextInput, TouchableOpacity } from 'react-native';
|
|
3
3
|
import Icon from 'react-native-vector-icons/Feather';
|
|
4
4
|
import Formatter from '@controleonline/ui-common/src/utils/formatter';
|
|
5
5
|
import styles from '../../DeviceDetailPage.styles';
|
|
6
6
|
import { hex } from './deviceDetailConstants';
|
|
7
|
+
import { paymentIcon } from './deviceDetailHelpers';
|
|
8
|
+
import { withOpacity } from '@controleonline/../../src/styles/branding';
|
|
9
|
+
import { inlineStyle_1301_61 } from '../../DeviceDetailPage.styles';
|
|
7
10
|
|
|
8
11
|
/**
|
|
9
12
|
* PDV movement tab sections.
|
|
@@ -12,7 +15,8 @@ import { hex } from './deviceDetailConstants';
|
|
|
12
15
|
export default function DeviceDetailMovementSections(ctx) {
|
|
13
16
|
const {
|
|
14
17
|
showPdvMovementTab, inflowData, productTotal, wallets, filteredProducts, search, setSearch,
|
|
15
|
-
renderProduct, loadingMovementData,
|
|
18
|
+
renderProduct, loadingMovementData, inflowTotal, products, isOpen,
|
|
19
|
+
actionLoading, handleToggle, loadingConfigData, brandColors,
|
|
16
20
|
} = ctx;
|
|
17
21
|
|
|
18
22
|
return (
|
|
@@ -21,6 +21,7 @@ import {tt} from './deviceDetailConstants';
|
|
|
21
21
|
export default function DeviceDetailOrdersPrintSection(ctx) {
|
|
22
22
|
const {
|
|
23
23
|
themeColors,
|
|
24
|
+
shouldShowOrderVisibility,
|
|
24
25
|
renderHelpButton,
|
|
25
26
|
renderOptionButtons,
|
|
26
27
|
renderSwitchRow,
|
|
@@ -53,6 +54,7 @@ export default function DeviceDetailOrdersPrintSection(ctx) {
|
|
|
53
54
|
|
|
54
55
|
return (
|
|
55
56
|
<>
|
|
57
|
+
{shouldShowOrderVisibility && (
|
|
56
58
|
<View style={styles.section}>
|
|
57
59
|
<Text style={styles.sectionTitle}>
|
|
58
60
|
<Icon name="list" size={13} /> {' '}Pedidos do Device
|
|
@@ -120,6 +122,8 @@ export default function DeviceDetailOrdersPrintSection(ctx) {
|
|
|
120
122
|
</View>
|
|
121
123
|
</View>
|
|
122
124
|
|
|
125
|
+
)}
|
|
126
|
+
|
|
123
127
|
{isDisplayDevice && (
|
|
124
128
|
<View style={styles.section}>
|
|
125
129
|
<Text style={styles.sectionTitle}>
|