@controleonline/ui-common 1.2.93 → 1.2.95
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/docs/homepage-1056.md +12 -0
- package/package.json +1 -1
- package/src/react/components/BottomNavigationBar.js +14 -4
- package/src/react/components/BottomNavigationBar.soft.styles.js +28 -0
- package/src/react/components/DefaultProvider.styles.js +3 -0
- package/src/react/components/DefaultProvider.web.js +7 -3
- package/src/react/components/RuntimeBottomNavigationBar.js +2 -0
- package/src/react/components/RuntimeInfoFooter.home.spacing.js +5 -0
- package/src/react/components/RuntimeInfoFooter.js +8 -2
- package/src/react/components/UserAvatar.js +3 -1
- package/src/react/pages/IntegrationConfigPage.js +62 -14
- package/src/react/pages/IntegrationConfigPage.utils.js +17 -0
- package/src/react/pages/integrationsCatalog.js +71 -0
- package/src/utils/integrationConfigs.js +23 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Homepage ADMIN/MANAGER — app-community#1056
|
|
2
|
+
|
|
3
|
+
Soft appearance is opt-in for HomePage only. Existing menu routes/parameters, permissions, stores and translations are preserved. App-provided homepage colors and components are used only in this appearance. Default consumers retain their current behavior.
|
|
4
|
+
|
|
5
|
+
Source: https://github.com/ControleOnline/app-community/issues/1056
|
|
6
|
+
Local evidence: 40 homepage tests and 34 runtime footer/zoom tests passed. No production authorization.
|
|
7
|
+
|
|
8
|
+
## Web login translation bootstrap
|
|
9
|
+
|
|
10
|
+
Keep the navigation tree mounted while translations initialize. Hide the shell and disable pointer/accessibility interaction until the existing translation readiness contract succeeds. Unmounting navigation during login resets its route and repeatedly mounts/registers the bottom bar, causing React maximum update depth. No route, permission, translation source, theme or zoom changes. Native behavior is unchanged.
|
|
11
|
+
|
|
12
|
+
Regression evidence: app-community homepage bootstrapNavigation.test.js reproduced maximum update depth before the fix, then passed after it. 44 tests across 9 homepage suites passed. Runtime Dev reproduced the unfixed bug; new runtime verification is required after consuming ui-common 1.2.95.
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import React, {useLayoutEffect, useMemo} from 'react';
|
|
2
2
|
import {Pressable, Text, View} from 'react-native';
|
|
3
|
-
import
|
|
3
|
+
import LegacyIcon from 'react-native-vector-icons/Feather';
|
|
4
|
+
import HomeIcon from '@controleonline/../../src/components/HomeIcon';
|
|
4
5
|
import {useTheme} from './DefaultProvider';
|
|
5
6
|
import RuntimeInfoFooter from './RuntimeInfoFooter';
|
|
6
7
|
import {resolveMenuRouteParams} from '../utils/menuNavigation';
|
|
7
8
|
import createStyles from './BottomNavigationBar.styles';
|
|
9
|
+
import softenStyles from './BottomNavigationBar.soft.styles';
|
|
10
|
+
import {resolveHomepagePalette} from '@controleonline/../../src/styles/homepagePalette';
|
|
8
11
|
|
|
9
12
|
const BottomNavigationBar = ({
|
|
10
13
|
navigation,
|
|
@@ -14,7 +17,10 @@ const BottomNavigationBar = ({
|
|
|
14
17
|
colors = {},
|
|
15
18
|
testID = 'bottom-navigation',
|
|
16
19
|
useModernWebChromeProps = false,
|
|
20
|
+
appearance = 'legacy',
|
|
17
21
|
}) => {
|
|
22
|
+
const Icon = appearance === 'soft' ? HomeIcon : LegacyIcon;
|
|
23
|
+
colors = appearance === 'soft' ? resolveHomepagePalette(colors) : colors;
|
|
18
24
|
const theme = useTheme?.() || {};
|
|
19
25
|
const runtimeFooter = theme?.runtimeFooter || null;
|
|
20
26
|
const registerBottomNavigation =
|
|
@@ -31,14 +37,14 @@ const BottomNavigationBar = ({
|
|
|
31
37
|
|
|
32
38
|
const styles = useMemo(
|
|
33
39
|
() =>
|
|
34
|
-
createStyles({
|
|
40
|
+
softenStyles(createStyles({
|
|
35
41
|
activeBackground,
|
|
36
42
|
dockBackground,
|
|
37
43
|
dockBorder,
|
|
38
44
|
dockShadow,
|
|
39
45
|
activeBorder,
|
|
40
46
|
useModernWebChromeProps,
|
|
41
|
-
}),
|
|
47
|
+
}), colors, appearance),
|
|
42
48
|
[
|
|
43
49
|
activeBackground,
|
|
44
50
|
activeBorder,
|
|
@@ -46,6 +52,7 @@ const BottomNavigationBar = ({
|
|
|
46
52
|
dockBorder,
|
|
47
53
|
dockShadow,
|
|
48
54
|
useModernWebChromeProps,
|
|
55
|
+
appearance,
|
|
49
56
|
],
|
|
50
57
|
);
|
|
51
58
|
|
|
@@ -116,8 +123,11 @@ const BottomNavigationBar = ({
|
|
|
116
123
|
? [styles.host, styles.hostPointerEventsBoxNone]
|
|
117
124
|
: styles.host;
|
|
118
125
|
const footerProps = {
|
|
126
|
+
appearance,
|
|
119
127
|
appVersion: runtimeFooter?.appVersion,
|
|
120
|
-
colors:
|
|
128
|
+
colors: appearance === 'soft'
|
|
129
|
+
? {...runtimeFooter?.colors, footerBackground: colors.footerBackground, footerText: colors.footerText}
|
|
130
|
+
: runtimeFooter?.colors || {},
|
|
121
131
|
mainCompany: runtimeFooter?.mainCompany,
|
|
122
132
|
device: runtimeFooter?.device,
|
|
123
133
|
useModernWebChromeProps,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {Platform} from 'react-native';
|
|
2
|
+
|
|
3
|
+
// Only the homepage opts into this chrome; preserve all default navigation styles.
|
|
4
|
+
export default (styles, colors, appearance) => appearance !== 'soft' ? styles : {
|
|
5
|
+
...styles,
|
|
6
|
+
dock: [styles.dock, {
|
|
7
|
+
paddingHorizontal: 0,
|
|
8
|
+
paddingTop: 0,
|
|
9
|
+
paddingBottom: 0,
|
|
10
|
+
borderWidth: 0,
|
|
11
|
+
borderTopWidth: 1,
|
|
12
|
+
borderColor: colors.navigationBorder,
|
|
13
|
+
borderTopLeftRadius: 0,
|
|
14
|
+
borderTopRightRadius: 0,
|
|
15
|
+
elevation: 0,
|
|
16
|
+
shadowOpacity: 0,
|
|
17
|
+
...(Platform.OS === 'web' ? {boxShadow: 'none'} : {}),
|
|
18
|
+
}],
|
|
19
|
+
itemsRow: [styles.itemsRow, {minHeight: 64, paddingHorizontal: 12, paddingVertical: 5}],
|
|
20
|
+
item: [styles.item, {minHeight: 54, borderRadius: 12}],
|
|
21
|
+
itemLabel: [styles.itemLabel, {fontSize: 11, fontWeight: '400'}],
|
|
22
|
+
footerSlot: [styles.footerSlot, {
|
|
23
|
+
borderTopWidth: 1,
|
|
24
|
+
borderColor: colors.navigationBorder,
|
|
25
|
+
paddingHorizontal: 0,
|
|
26
|
+
minHeight: 28,
|
|
27
|
+
}],
|
|
28
|
+
};
|
|
@@ -395,15 +395,19 @@ export const DefaultProvider = ({
|
|
|
395
395
|
|
|
396
396
|
useWebThemePalette({resolveDomainThemeColors, baseThemeColors, mainCompany, resolveThemePalette, runtimeColors, applyPaletteToRuntimeColors, applyThemeCssVariables, actions, currentCompany, isShopClientApp});
|
|
397
397
|
|
|
398
|
-
|
|
399
|
-
return <View style={providerStyles.loadingContainer} />;
|
|
400
|
-
}
|
|
398
|
+
const translationPending = requiresTranslateBootstrap && !isTranslateBootstrapReady;
|
|
401
399
|
|
|
402
400
|
return (
|
|
403
401
|
<ThemeContext.Provider value={themeContextValue}>
|
|
404
402
|
<View
|
|
403
|
+
pointerEvents={translationPending ? 'none' : 'auto'}
|
|
404
|
+
accessibilityElementsHidden={translationPending}
|
|
405
|
+
importantForAccessibility={translationPending ? 'no-hide-descendants' : 'auto'}
|
|
405
406
|
style={[
|
|
406
407
|
providerStyles.shell,
|
|
408
|
+
// Keep navigation mounted while translations load. Unmounting it
|
|
409
|
+
// resets the login route and repeatedly registers the bottom bar.
|
|
410
|
+
translationPending && providerStyles.translationPending,
|
|
407
411
|
{
|
|
408
412
|
backgroundColor: colors?.background || runtimeColors.background,
|
|
409
413
|
},
|
|
@@ -19,6 +19,7 @@ const {
|
|
|
19
19
|
} = require('@controleonline/ui-common/src/react/utils/bottomNavigationToolbar');
|
|
20
20
|
|
|
21
21
|
const RuntimeBottomNavigationBar = ({
|
|
22
|
+
appearance = 'legacy',
|
|
22
23
|
activeRouteName: activeRouteNameProp,
|
|
23
24
|
colors: colorsOverride,
|
|
24
25
|
disabled: disabledOverride,
|
|
@@ -159,6 +160,7 @@ const RuntimeBottomNavigationBar = ({
|
|
|
159
160
|
|
|
160
161
|
return (
|
|
161
162
|
<BottomNavigationBar
|
|
163
|
+
appearance={appearance}
|
|
162
164
|
activeRouteName={effectiveActiveRoute}
|
|
163
165
|
colors={colors}
|
|
164
166
|
disabled={isDisabled}
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
} from '@controleonline/ui-common/src/react/utils/runtimeFooter';
|
|
23
23
|
import styles from './RuntimeInfoFooter.styles';
|
|
24
24
|
import RuntimeFooterMarqueeText from './RuntimeFooterMarqueeText';
|
|
25
|
+
import resolveHomeFooterSpacing from './RuntimeInfoFooter.home.spacing';
|
|
25
26
|
|
|
26
27
|
const ROTATION_INTERVAL_MS = 4000;
|
|
27
28
|
const COMPACT_BREAKPOINT = 720;
|
|
@@ -66,6 +67,7 @@ const RuntimeInfoFooter = ({
|
|
|
66
67
|
device,
|
|
67
68
|
colors,
|
|
68
69
|
useModernWebChromeProps = false,
|
|
70
|
+
appearance = 'legacy',
|
|
69
71
|
}) => {
|
|
70
72
|
const {width} = useWindowDimensions();
|
|
71
73
|
const insets = useSafeAreaInsets();
|
|
@@ -258,6 +260,7 @@ const RuntimeInfoFooter = ({
|
|
|
258
260
|
: inlineText
|
|
259
261
|
) || primaryText || device?.id || '';
|
|
260
262
|
const backgroundColor = colors?.footerBackground;
|
|
263
|
+
const homeSpacing = resolveHomeFooterSpacing(appearance, Platform.OS, insets.bottom);
|
|
261
264
|
const borderColor = colors?.footerBorder;
|
|
262
265
|
const textColor = resolveVisibleFooterTextColor(colors);
|
|
263
266
|
const loadingColor = colors?.footerLink || colors?.primary || textColor;
|
|
@@ -267,7 +270,9 @@ const RuntimeInfoFooter = ({
|
|
|
267
270
|
: styles.shell;
|
|
268
271
|
|
|
269
272
|
return (
|
|
270
|
-
<View {...shellProps} style={shellStyle
|
|
273
|
+
<View {...shellProps} style={[shellStyle, homeSpacing && {
|
|
274
|
+
paddingBottom: homeSpacing.safeAreaBottom, backgroundColor,
|
|
275
|
+
}]}>
|
|
271
276
|
<View
|
|
272
277
|
testID="runtime-info-footer"
|
|
273
278
|
style={[
|
|
@@ -276,7 +281,8 @@ const RuntimeInfoFooter = ({
|
|
|
276
281
|
{
|
|
277
282
|
backgroundColor,
|
|
278
283
|
borderTopColor: borderColor,
|
|
279
|
-
paddingBottom: bottomInset,
|
|
284
|
+
paddingBottom: homeSpacing ? homeSpacing.contentPadding : bottomInset,
|
|
285
|
+
...(homeSpacing && !showDebugInfo ? {paddingTop: homeSpacing.contentPadding} : {}),
|
|
280
286
|
},
|
|
281
287
|
]}>
|
|
282
288
|
<View style={styles.primaryRow}>
|
|
@@ -156,6 +156,7 @@ const useDisplayUri = uri => {
|
|
|
156
156
|
|
|
157
157
|
const UserAvatar = ({
|
|
158
158
|
imageUrl,
|
|
159
|
+
imageHeaders,
|
|
159
160
|
email,
|
|
160
161
|
name,
|
|
161
162
|
size = 40,
|
|
@@ -215,7 +216,8 @@ const UserAvatar = ({
|
|
|
215
216
|
<View style={containerStyle}>
|
|
216
217
|
{displayUri ? (
|
|
217
218
|
<Image
|
|
218
|
-
source={
|
|
219
|
+
source={imageHeaders && Platform.OS !== 'web' && displayUri === imageUrl
|
|
220
|
+
? {uri: displayUri, headers: imageHeaders} : {uri: displayUri}}
|
|
219
221
|
style={styles.image}
|
|
220
222
|
onError={() => setSourceIndex(index => index + 1)}
|
|
221
223
|
/>
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
lines 378
|
|
2
|
+
ok True
|
|
3
|
+
eCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
4
|
import { ActivityIndicator, Platform, RefreshControl, ScrollView, Text, TouchableOpacity, View } from 'react-native';
|
|
3
5
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
4
6
|
import { useFocusEffect } from '@react-navigation/native';
|
|
@@ -14,6 +16,7 @@ import { fetchPeopleConfigs } from './fetchPeopleConfigs';
|
|
|
14
16
|
import IntegrationConfigFields from './IntegrationConfigFields';
|
|
15
17
|
import {
|
|
16
18
|
ROUTE_PROVIDER_MAP,
|
|
19
|
+
expandBundledConfig,
|
|
17
20
|
extractAuthorizationUrl,
|
|
18
21
|
formatApiError,
|
|
19
22
|
formatUberOAuthError,
|
|
@@ -112,6 +115,8 @@ export default function IntegrationConfigPage({ route, embedded = false, fiscalT
|
|
|
112
115
|
const allFieldKeysSig = useMemo(() => allFieldKeys.join('|'), [allFieldKeys]);
|
|
113
116
|
// Pure config providers (e.g. receita-federal) do not use marketplace/integrations.
|
|
114
117
|
const needsMarketplaceIntegration = Boolean(providerConfig?.oauthConnect);
|
|
118
|
+
const bundleKey = normalizeTextValue(providerConfig?.bundleKey);
|
|
119
|
+
const configVisibility = normalizeTextValue(providerConfig?.visibility) || 'public';
|
|
115
120
|
|
|
116
121
|
useEffect(() => {
|
|
117
122
|
setConfigValues({});
|
|
@@ -135,14 +140,28 @@ export default function IntegrationConfigPage({ route, embedded = false, fiscalT
|
|
|
135
140
|
}
|
|
136
141
|
if (showLoading) setLoading(true);
|
|
137
142
|
try {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const
|
|
143
|
+
if (bundleKey) {
|
|
144
|
+
const configItems = await fetchPeopleConfigs({
|
|
145
|
+
peopleIri: providerIri,
|
|
146
|
+
configKeys: [bundleKey],
|
|
147
|
+
});
|
|
148
|
+
const bundled = configItems.find(
|
|
149
|
+
item => String(item?.configKey || '').trim() === bundleKey,
|
|
150
|
+
);
|
|
144
151
|
const mergeFields = allConfigFields.length ? allConfigFields : visibleFields;
|
|
145
|
-
setConfigValues(current =>
|
|
152
|
+
setConfigValues(current =>
|
|
153
|
+
expandBundledConfig(mergeFields, bundled?.configValue, current),
|
|
154
|
+
);
|
|
155
|
+
} else {
|
|
156
|
+
const keys = allFieldKeys.length
|
|
157
|
+
? allFieldKeys
|
|
158
|
+
: visibleFields.map(field => field.key).filter(Boolean);
|
|
159
|
+
|
|
160
|
+
if (keys.length) {
|
|
161
|
+
const configItems = await fetchPeopleConfigs({ peopleIri: providerIri, configKeys: keys });
|
|
162
|
+
const mergeFields = allConfigFields.length ? allConfigFields : visibleFields;
|
|
163
|
+
setConfigValues(current => mergeTabValues(mergeFields, configItems, current));
|
|
164
|
+
}
|
|
146
165
|
}
|
|
147
166
|
|
|
148
167
|
if (needsMarketplaceIntegration) {
|
|
@@ -170,6 +189,7 @@ export default function IntegrationConfigPage({ route, embedded = false, fiscalT
|
|
|
170
189
|
allConfigFields,
|
|
171
190
|
allFieldKeys,
|
|
172
191
|
allFieldKeysSig,
|
|
192
|
+
bundleKey,
|
|
173
193
|
needsMarketplaceIntegration,
|
|
174
194
|
providerConfig,
|
|
175
195
|
providerIri,
|
|
@@ -246,16 +266,44 @@ export default function IntegrationConfigPage({ route, embedded = false, fiscalT
|
|
|
246
266
|
showError('Nao foi possivel identificar a integracao selecionada.');
|
|
247
267
|
return;
|
|
248
268
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
269
|
+
|
|
270
|
+
let configs;
|
|
271
|
+
if (bundleKey) {
|
|
272
|
+
const payloadObject = {};
|
|
273
|
+
(visibleFields || []).forEach(field => {
|
|
274
|
+
payloadObject[field.key] = normalizeTextValue(configValues[field.key]);
|
|
275
|
+
});
|
|
276
|
+
configs = [
|
|
277
|
+
{
|
|
278
|
+
configKey: bundleKey,
|
|
279
|
+
configValue: toConfigRequestValue(payloadObject),
|
|
280
|
+
},
|
|
281
|
+
];
|
|
282
|
+
} else {
|
|
283
|
+
configs = visibleFields.map(field => ({
|
|
284
|
+
configKey: field.key,
|
|
285
|
+
configValue: toConfigRequestValue(normalizeTextValue(configValues[field.key])),
|
|
286
|
+
}));
|
|
287
|
+
}
|
|
288
|
+
|
|
253
289
|
try {
|
|
254
|
-
await persistConfigs({ configs, people: providerIri, module: 4, visibility:
|
|
290
|
+
await persistConfigs({ configs, people: providerIri, module: 4, visibility: configVisibility });
|
|
255
291
|
showSuccess(`${activeTabDef?.label || providerConfig.label} salvo com sucesso.`);
|
|
256
292
|
await loadPageData({ showLoading: false });
|
|
257
293
|
} catch (error) { showError(error?.message || 'Nao foi possivel salvar a integracao.'); }
|
|
258
|
-
}, [
|
|
294
|
+
}, [
|
|
295
|
+
activeTabDef,
|
|
296
|
+
bundleKey,
|
|
297
|
+
configValues,
|
|
298
|
+
configVisibility,
|
|
299
|
+
loadPageData,
|
|
300
|
+
persistConfigs,
|
|
301
|
+
providerConfig,
|
|
302
|
+
providerIri,
|
|
303
|
+
showError,
|
|
304
|
+
showSuccess,
|
|
305
|
+
visibleFields,
|
|
306
|
+
]);
|
|
259
307
|
|
|
260
308
|
if (!providerConfig) return <CenterState icon="alert-triangle" iconColor="#e67e22" title="Integracao indisponivel" text="A tela solicitada nao possui configuracao cadastrada." />;
|
|
261
309
|
if (!providerId) return <CenterState icon="building" iconColor="#94A3B8" title="Empresa nao identificada" text="Abra a ficha da empresa para gravar as configuracoes fiscais nela." />;
|
|
@@ -5,6 +5,7 @@ export const ROUTE_PROVIDER_MAP = {
|
|
|
5
5
|
AsaasIntegrationPage: 'asaas',
|
|
6
6
|
ClickSignIntegrationPage: 'clicksign',
|
|
7
7
|
ReceitaFederalIntegrationPage: 'receita-federal',
|
|
8
|
+
SemPararIntegrationPage: 'sem-parar',
|
|
8
9
|
};
|
|
9
10
|
|
|
10
11
|
export const routeNameToPath = routeName =>
|
|
@@ -53,6 +54,22 @@ export const mergeTabValues = (fields, source, current = {}) => {
|
|
|
53
54
|
return next;
|
|
54
55
|
};
|
|
55
56
|
|
|
57
|
+
/** Expand a single JSON config (bundleKey) into flat field values. */
|
|
58
|
+
export const expandBundledConfig = (fields, rawValue, current = {}) => {
|
|
59
|
+
let parsed = rawValue;
|
|
60
|
+
if (typeof rawValue === 'string') {
|
|
61
|
+
try {
|
|
62
|
+
parsed = JSON.parse(rawValue);
|
|
63
|
+
} catch {
|
|
64
|
+
parsed = {};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
68
|
+
parsed = {};
|
|
69
|
+
}
|
|
70
|
+
return mergeTabValues(fields, parsed, current);
|
|
71
|
+
};
|
|
72
|
+
|
|
56
73
|
export const buildFieldValues = (providerConfig, source) =>
|
|
57
74
|
mergeTabValues(getConfigFields(providerConfig), source, {});
|
|
58
75
|
|
|
@@ -70,6 +70,16 @@ export const INTEGRATION_LIST = [
|
|
|
70
70
|
accent: '#166534',
|
|
71
71
|
icon: 'file-text',
|
|
72
72
|
},
|
|
73
|
+
{
|
|
74
|
+
key: 'sem-parar',
|
|
75
|
+
label: 'Sem Parar',
|
|
76
|
+
route: 'IntegrationConfigPage',
|
|
77
|
+
routeParams: {
|
|
78
|
+
providerKey: 'sem-parar',
|
|
79
|
+
},
|
|
80
|
+
accent: '#0EA5E9',
|
|
81
|
+
icon: 'truck',
|
|
82
|
+
},
|
|
73
83
|
];
|
|
74
84
|
|
|
75
85
|
export const INTEGRATION_CONFIGS = {
|
|
@@ -257,6 +267,67 @@ export const INTEGRATION_CONFIGS = {
|
|
|
257
267
|
],
|
|
258
268
|
fields: [],
|
|
259
269
|
},
|
|
270
|
+
|
|
271
|
+
'sem-parar': {
|
|
272
|
+
key: 'sem-parar',
|
|
273
|
+
label: 'Sem Parar',
|
|
274
|
+
accent: '#0EA5E9',
|
|
275
|
+
icon: 'truck',
|
|
276
|
+
description:
|
|
277
|
+
'Credenciais da empresa para emissao de vale-pedagio via Sem Parar.',
|
|
278
|
+
saveLabel: 'Salvar Sem Parar',
|
|
279
|
+
// Backend (api-platform-integration SemPararConfig) reads a single private JSON key.
|
|
280
|
+
bundleKey: 'SEM_PARAR',
|
|
281
|
+
visibility: 'private',
|
|
282
|
+
requiredKeys: ['ENABLED', 'CLIENT_ID', 'CLIENT_SECRET', 'USERNAME', 'PASSWORD'],
|
|
283
|
+
fields: [
|
|
284
|
+
{
|
|
285
|
+
key: 'ENABLED',
|
|
286
|
+
label: 'Ativo',
|
|
287
|
+
type: 'select',
|
|
288
|
+
options: [
|
|
289
|
+
{value: '1', label: 'Sim'},
|
|
290
|
+
{value: '0', label: 'Nao'},
|
|
291
|
+
],
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
key: 'ENVIRONMENT',
|
|
295
|
+
label: 'Ambiente',
|
|
296
|
+
type: 'select',
|
|
297
|
+
options: [
|
|
298
|
+
{value: 'sandbox', label: 'Sandbox'},
|
|
299
|
+
{value: 'production', label: 'Producao'},
|
|
300
|
+
],
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
key: 'CLIENT_ID',
|
|
304
|
+
label: 'Client ID',
|
|
305
|
+
placeholder: 'Client ID Sem Parar',
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
key: 'CLIENT_SECRET',
|
|
309
|
+
label: 'Client secret',
|
|
310
|
+
placeholder: 'Client secret Sem Parar',
|
|
311
|
+
secureTextEntry: true,
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
key: 'USERNAME',
|
|
315
|
+
label: 'Usuario',
|
|
316
|
+
placeholder: 'Usuario da API',
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
key: 'PASSWORD',
|
|
320
|
+
label: 'Senha',
|
|
321
|
+
placeholder: 'Senha da API',
|
|
322
|
+
secureTextEntry: true,
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
key: 'CONVENIADO',
|
|
326
|
+
label: 'Conveniado',
|
|
327
|
+
placeholder: 'Codigo do conveniado (se aplicavel)',
|
|
328
|
+
},
|
|
329
|
+
],
|
|
330
|
+
},
|
|
260
331
|
};
|
|
261
332
|
|
|
262
333
|
export const getIntegrationListItem = key =>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export const CIELO_CONFIG_KEY = 'CIELO';
|
|
2
2
|
export const NEW_RELIC_CONFIG_KEY = 'NEW_RELIC';
|
|
3
3
|
export const SPOTIFY_CONFIG_KEY = 'SPOTIFY';
|
|
4
|
+
export const SEM_PARAR_CONFIG_KEY = 'SEM_PARAR';
|
|
4
5
|
|
|
5
6
|
export const DEFAULT_CIELO_CONFIG = {
|
|
6
7
|
ACCESS_TOKEN: '',
|
|
@@ -23,6 +24,21 @@ export const DEFAULT_SPOTIFY_CONFIG = {
|
|
|
23
24
|
CLIENT_SECRET: '',
|
|
24
25
|
};
|
|
25
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Company-scoped Sem Parar credentials for vale-pedágio emission.
|
|
29
|
+
* ENABLED: "1" | "0"
|
|
30
|
+
* ENVIRONMENT: "sandbox" | "production"
|
|
31
|
+
*/
|
|
32
|
+
export const DEFAULT_SEM_PARAR_CONFIG = {
|
|
33
|
+
ENABLED: '0',
|
|
34
|
+
CLIENT_ID: '',
|
|
35
|
+
CLIENT_SECRET: '',
|
|
36
|
+
USERNAME: '',
|
|
37
|
+
PASSWORD: '',
|
|
38
|
+
ENVIRONMENT: 'sandbox',
|
|
39
|
+
CONVENIADO: '',
|
|
40
|
+
};
|
|
41
|
+
|
|
26
42
|
const isConfigMap = value =>
|
|
27
43
|
value && typeof value === 'object' && !Array.isArray(value);
|
|
28
44
|
|
|
@@ -78,3 +94,10 @@ export const resolveSpotifyConfig = configs =>
|
|
|
78
94
|
SPOTIFY_CONFIG_KEY,
|
|
79
95
|
DEFAULT_SPOTIFY_CONFIG,
|
|
80
96
|
);
|
|
97
|
+
|
|
98
|
+
export const resolveSemPararConfig = configs =>
|
|
99
|
+
resolveIntegrationConfig(
|
|
100
|
+
configs,
|
|
101
|
+
SEM_PARAR_CONFIG_KEY,
|
|
102
|
+
DEFAULT_SEM_PARAR_CONFIG,
|
|
103
|
+
);
|