@controleonline/ui-common 1.2.71 → 1.2.76
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/actions/workers/manager/action.yml +147 -0
- package/.github/actions/workers/qa/action.yml +44 -0
- package/.github/actions/workers/security/action.yml +44 -0
- package/.github/actions/workers/technical-documenter/action.yml +51 -0
- package/.github/workflows/manager-worker.yml +168 -0
- package/.github/workflows/publish-npm.yml +45 -0
- package/.gitmodules +3 -0
- package/AGENTS.md +6 -0
- package/README.md +14 -0
- package/package.json +3 -2
- package/src/api/fetch.js +1 -1
- package/src/api/index.js +92 -22
- package/src/react/components/AddImportModal.js +94 -110
- package/src/react/components/BottomNavigationBar.config.js +211 -231
- package/src/react/components/CategoryForm.js +52 -35
- package/src/react/components/DefaultProvider.native.js +131 -95
- package/src/react/components/DefaultProvider.web.js +148 -74
- package/src/react/components/NetworkPrinterPreviewModal.js +249 -0
- package/src/react/components/NetworkPrinterPreviewModal.styles.js +159 -0
- package/src/react/components/RuntimeInfoFooter.js +164 -104
- package/src/react/components/RuntimeInfoFooter.styles.js +3 -0
- package/src/react/components/UnifiedPaymentBar.js +7 -4
- package/src/react/components/UserAvatar.js +160 -0
- package/src/react/components/integrations/IntegrationHero/index.js +48 -0
- package/src/react/components/integrations/IntegrationHero/styles.js +57 -0
- package/src/react/components/integrations/IntegrationTabs/index.js +89 -0
- package/src/react/components/integrations/IntegrationTabs/styles.js +44 -0
- package/src/react/config/deviceConfigBootstrap.js +5 -3
- package/src/react/pages/Connections.js +229 -0
- package/src/react/pages/Connections.styles.js +222 -0
- package/src/react/pages/DeviceDetailPage.js +2865 -0
- package/src/react/pages/DeviceDetailPage.styles.js +308 -0
- package/src/react/pages/Devices/currentDevice.js +194 -0
- package/src/react/pages/Devices/deviceTypes/DeviceGroupCard.js +257 -0
- package/src/react/pages/Devices/deviceTypes/all.js +23 -0
- package/src/react/pages/Devices/deviceTypes/device.js +25 -0
- package/src/react/pages/Devices/deviceTypes/deviceListHelpers.js +178 -0
- package/src/react/pages/Devices/deviceTypes/display.js +26 -0
- package/src/react/pages/Devices/deviceTypes/index.js +145 -0
- package/src/react/pages/Devices/deviceTypes/ipCamera.js +35 -0
- package/src/react/pages/Devices/deviceTypes/pdv.js +88 -0
- package/src/react/pages/Devices/deviceTypes/printer.js +37 -0
- package/src/react/pages/Devices/deviceTypes/shared.js +453 -0
- package/src/react/pages/Devices/deviceTypes/useDeviceNetworkConnectivity.js +145 -0
- package/src/react/pages/Devices.js +183 -0
- package/src/react/pages/Devices.styles.js +353 -0
- package/src/react/pages/Food99IntegrationPage/components/Food99CatalogTab.js +219 -0
- package/src/react/pages/Food99IntegrationPage/components/Food99OverviewTab.js +134 -0
- package/src/react/pages/Food99IntegrationPage/components/Food99PreviewModal.js +173 -0
- package/src/react/pages/Food99IntegrationPage/components/Food99ProductCard.js +1 -0
- package/src/react/pages/Food99IntegrationPage/components/Food99QuickWalletModal.js +181 -0
- package/src/react/pages/Food99IntegrationPage/components/Food99SettingsTab.js +306 -0
- package/src/react/pages/Food99IntegrationPage/components/Food99StoreTab.js +417 -0
- package/src/react/pages/Food99IntegrationPage/index.js +1530 -0
- package/src/react/pages/Food99IntegrationPage/styles.js +792 -0
- package/src/react/pages/Food99IntegrationPage/utils.js +155 -0
- package/src/react/pages/Food99IntegrationPage.js +1 -0
- package/src/react/pages/Food99IntegrationPage.styles.js +1 -0
- package/src/react/pages/GenericLogPage.js +42 -167
- package/src/react/pages/IFoodIntegrationPage/components/IFoodCatalogTab.js +8 -0
- package/src/react/pages/IFoodIntegrationPage/components/IFoodOperationsTab.js +420 -0
- package/src/react/pages/IFoodIntegrationPage/components/IFoodOverviewTab.js +118 -0
- package/src/react/pages/IFoodIntegrationPage/components/IFoodPreviewModal.js +103 -0
- package/src/react/pages/IFoodIntegrationPage/components/IFoodProductCard.js +1 -0
- package/src/react/pages/IFoodIntegrationPage/components/IFoodStoreTab.js +150 -0
- package/src/react/pages/IFoodIntegrationPage/index.js +1298 -0
- package/src/react/pages/IFoodIntegrationPage/styles.js +764 -0
- package/src/react/pages/IFoodIntegrationPage/utils.js +91 -0
- package/src/react/pages/IFoodIntegrationPage.js +1 -0
- package/src/react/pages/IFoodIntegrationPage.styles.js +1 -0
- package/src/react/pages/Imports.js +214 -166
- package/src/react/pages/IntegrationConfigPage.js +744 -0
- package/src/react/pages/IntegrationConfigPage.styles.js +269 -0
- package/src/react/pages/Integrations.js +299 -0
- package/src/react/pages/Integrations.styles.js +130 -0
- package/src/react/pages/ManagerOrderNotificationsPage.js +642 -0
- package/src/react/pages/MarketplaceIntegrationPage/components/MarketplaceProductCard.js +205 -0
- package/src/react/pages/MarketplaceIntegrationPage/components/RemoteMarketplaceMenuTab.js +335 -0
- package/src/react/pages/MarketplaceIntegrationPage/index.js +60 -0
- package/src/react/pages/MarketplaceIntegrationPage/utils.js +137 -0
- package/src/react/pages/MercadoLivreIntegrationPage.js +538 -0
- package/src/react/pages/PrinterDeviceDetailPage.js +1916 -0
- package/src/react/pages/PrinterDeviceDetailPage.styles.js +223 -0
- package/src/react/pages/PrinterDeviceFormPage.js +521 -0
- package/src/react/pages/PrinterDeviceFormPage.styles.js +159 -0
- package/src/react/pages/WhatsAppConnectionPage.js +459 -0
- package/src/react/pages/WhatsAppConnectionPage.styles.js +284 -0
- package/src/react/pages/integrationsCatalog.js +399 -0
- package/src/react/services/Cielo/Cielo.js +193 -193
- package/src/react/utils/categoryContexts.js +46 -0
- package/src/react/utils/entityDisplay.js +222 -217
- package/src/react/utils/fileUrl.js +39 -20
- package/src/react/utils/integrationPage.js +16 -0
- package/src/react/utils/runtimeFooter.js +40 -22
- package/src/react/utils/runtimeLanguage.js +50 -9
- package/src/react/utils/runtimeMenu.js +191 -131
- package/src/react/utils/runtimeZoom.js +43 -0
- package/src/react/utils/shopConfig.js +27 -15
- package/src/react/utils/shopFranchises.js +126 -1
- package/src/react/utils/storeColumns.js +23 -4
- package/src/react/utils/userAvatar.js +104 -0
- package/src/store/categories/index.js +48 -20
- package/src/store/device_config/index.js +62 -21
- package/src/store/entity_log/index.js +22 -1
- package/src/store/imports/customActions.js +51 -0
- package/src/store/imports/index.js +89 -88
- package/src/store/status/index.js +11 -11
- package/src/store/themes/index.js +22 -0
- package/src/store/timezones/index.js +3 -1
- package/src/tests/browser/manager/connections.spec.js +143 -0
- package/src/tests/browser/manager/devices-current.spec.js +343 -0
- package/src/tests/browser/manager/mercado-livre-integration.spec.js +268 -0
- package/src/tests/react/api/deviceHeaders.test.js +114 -0
- package/src/tests/react/components/AddImportModal.test.js +166 -0
- package/src/tests/react/components/BottomNavigationBar.config.test.js +20 -0
- package/src/tests/react/components/UserAvatar.test.js +52 -0
- package/src/tests/react/pages/DevicePickerStyles.test.js +47 -0
- package/src/tests/react/pages/Devices/deviceListHelpers.test.js +39 -0
- package/src/tests/react/pages/DevicesCurrentDevice.test.js +198 -0
- package/src/tests/react/pages/connectionsHelpers.test.js +34 -0
- package/src/tests/react/pages/mercadoLivreIntegrationPageContract.test.mjs +16 -0
- package/src/tests/react/services/Cielo.test.js +190 -190
- package/src/tests/react/store/categoriesOrdering.test.js +26 -0
- package/src/tests/react/utils/appDomain.test.js +62 -0
- package/src/tests/react/utils/entityDisplay.test.js +2 -2
- package/src/tests/react/utils/fileUrl.test.js +3 -3
- package/src/tests/react/utils/formatter.test.mjs +33 -0
- package/src/tests/react/utils/runtimeFooter.test.js +29 -4
- package/src/tests/react/utils/runtimeLanguage.test.js +79 -9
- package/src/tests/react/utils/runtimeMenu.test.js +198 -134
- package/src/tests/react/utils/runtimeZoom.test.js +38 -0
- package/src/tests/react/utils/shopConfig.test.js +10 -9
- package/src/tests/react/utils/shopFranchises.test.js +43 -0
- package/src/tests/react/utils/translate.discovery.test.mjs +170 -0
- package/src/tests/react/utils/translate.test.helpers.mjs +152 -0
- package/src/tests/react/utils/translate.test.mjs +141 -349
- package/src/tests/react/utils/userAvatar.test.js +63 -0
- package/src/utils/appDomain.js +15 -4
- package/src/utils/formatter.js +104 -16
- package/src/utils/integrationConfigs.js +80 -80
- package/src/utils/translate.js +222 -438
- package/src/utils/translateDiscovery.js +96 -0
- package/src/utils/translateNormalize.js +33 -0
- package/src/utils/translatePending.js +92 -0
- package/src/utils/translateStorage.js +142 -0
- package/.github/agents/developer.agent.md +0 -30
- package/.github/agents/devops.agent.md +0 -30
- package/.github/agents/qa.agent.md +0 -30
- package/.github/agents/security.agent.md +0 -30
- package/.github/workflows/npmjs.yml +0 -35
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// Configurações fixas e helpers específicos da integração 99Food.
|
|
2
|
+
export const MINIMUM_REQUIRED_ITEMS = 5;
|
|
3
|
+
|
|
4
|
+
export const statusLabelMap = {
|
|
5
|
+
1: 'Online',
|
|
6
|
+
2: 'Offline',
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const subStatusLabelMap = {
|
|
10
|
+
1: 'Pronta',
|
|
11
|
+
2: 'Pausada',
|
|
12
|
+
3: 'Fechada',
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const filterTabs = [
|
|
16
|
+
{ key: 'all', label: 'Todos' },
|
|
17
|
+
{ key: 'eligible', label: 'Elegiveis' },
|
|
18
|
+
{ key: 'selected', label: 'Selecionados' },
|
|
19
|
+
{ key: 'blocked', label: 'Com bloqueio' },
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
export const publishStateLabelMap = {
|
|
23
|
+
submitted: 'Enviado',
|
|
24
|
+
processing: 'Processando',
|
|
25
|
+
published: 'Publicado',
|
|
26
|
+
failed: 'Falhou',
|
|
27
|
+
sync_error: 'Sync pendente',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const publishStateToneMap = {
|
|
31
|
+
submitted: '#2563EB',
|
|
32
|
+
processing: '#e67e22',
|
|
33
|
+
published: '#16A34A',
|
|
34
|
+
failed: '#DC2626',
|
|
35
|
+
sync_error: '#7C3AED',
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const deliveryMethodOptions = [
|
|
39
|
+
{ value: '2', label: 'Loja (2)' },
|
|
40
|
+
{ value: '1', label: 'Entrega 99 (1)' },
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
export const formatFood99ApiError = error => {
|
|
44
|
+
if (!error) return 'Nao foi possivel concluir a operacao.';
|
|
45
|
+
if (typeof error === 'string') return error;
|
|
46
|
+
|
|
47
|
+
if (Array.isArray(error?.message)) {
|
|
48
|
+
return error.message
|
|
49
|
+
.map(item => item?.message || item?.title || String(item))
|
|
50
|
+
.filter(Boolean)
|
|
51
|
+
.join('\n');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return error?.message || error?.description || error?.errmsg || 'Nao foi possivel concluir a operacao.';
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
58
|
+
|
|
59
|
+
export const normalizeTaskId = value => {
|
|
60
|
+
if (value === null || value === undefined || value === '') return null;
|
|
61
|
+
return String(value);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const resolveFood99HistoryFromTime = () => {
|
|
65
|
+
try {
|
|
66
|
+
const parts = new Intl.DateTimeFormat('en-CA', {
|
|
67
|
+
timeZone: 'America/Sao_Paulo',
|
|
68
|
+
year: 'numeric',
|
|
69
|
+
month: '2-digit',
|
|
70
|
+
day: '2-digit',
|
|
71
|
+
})
|
|
72
|
+
.formatToParts(new Date())
|
|
73
|
+
.reduce((accumulator, part) => {
|
|
74
|
+
if (part.type !== 'literal') {
|
|
75
|
+
accumulator[part.type] = part.value;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return accumulator;
|
|
79
|
+
}, {});
|
|
80
|
+
|
|
81
|
+
if (!parts.year || !parts.month || !parts.day) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return `${parts.year}-${parts.month}-${parts.day}T00:00:00-03:00`;
|
|
86
|
+
} catch {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export const sanitizeTimeInput = value => {
|
|
92
|
+
const digits = String(value || '')
|
|
93
|
+
.replace(/\D/g, '')
|
|
94
|
+
.slice(0, 4);
|
|
95
|
+
|
|
96
|
+
if (digits.length <= 2) return digits;
|
|
97
|
+
return `${digits.slice(0, 2)}:${digits.slice(2)}`;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export const isValidTimeInput = value => /^([01]\d|2[0-3]):[0-5]\d$/.test(String(value || '').trim());
|
|
101
|
+
|
|
102
|
+
export const sanitizeRadiusInput = value => {
|
|
103
|
+
const normalized = String(value || '').replace(/[^0-9.,]/g, '').replace(',', '.');
|
|
104
|
+
const [integerPart, ...decimals] = normalized.split('.');
|
|
105
|
+
if (decimals.length === 0) return integerPart;
|
|
106
|
+
return `${integerPart}.${decimals.join('').slice(0, 2)}`;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export const sanitizeConfirmMethodInput = value =>
|
|
110
|
+
String(value || '')
|
|
111
|
+
.replace(/\D/g, '')
|
|
112
|
+
.slice(0, 3);
|
|
113
|
+
|
|
114
|
+
export const normalizeDeliveryMethodCode = value => {
|
|
115
|
+
const normalized = String(value || '').trim();
|
|
116
|
+
if (normalized === '1' || normalized === '2') return normalized;
|
|
117
|
+
|
|
118
|
+
const lower = normalized.toLowerCase();
|
|
119
|
+
if (lower.includes('99') || lower.includes('platform') || lower.includes('didi')) return '1';
|
|
120
|
+
|
|
121
|
+
if (
|
|
122
|
+
lower.includes('store') ||
|
|
123
|
+
lower.includes('shop') ||
|
|
124
|
+
lower.includes('merchant') ||
|
|
125
|
+
lower.includes('self') ||
|
|
126
|
+
lower.includes('loja')
|
|
127
|
+
) {
|
|
128
|
+
return '2';
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return '';
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export const formatDeliveryMethodLabel = value => {
|
|
135
|
+
const code = normalizeDeliveryMethodCode(value);
|
|
136
|
+
if (code === '2') return 'Loja';
|
|
137
|
+
if (code === '1') return 'Entrega 99';
|
|
138
|
+
|
|
139
|
+
const raw = String(value || '').trim();
|
|
140
|
+
return raw || '-';
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
export const getPublishStateLabel = state => publishStateLabelMap[state] || 'Sem envio recente';
|
|
144
|
+
|
|
145
|
+
export const createEmptyStoreSettingsDraft = () => ({
|
|
146
|
+
deliveryRadiusKm: '',
|
|
147
|
+
openTime: '',
|
|
148
|
+
closeTime: '',
|
|
149
|
+
deliveryMethod: '',
|
|
150
|
+
confirmMethod: '',
|
|
151
|
+
deliveryAreaId: '',
|
|
152
|
+
settlementWalletId: '',
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
export const isErrnoSuccess = errno => String(errno ?? '').trim() === '0';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './Food99IntegrationPage/index';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './Food99IntegrationPage/styles';
|
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
ActivityIndicator,
|
|
4
4
|
ScrollView,
|
|
5
5
|
Text,
|
|
6
|
-
TextInput,
|
|
7
6
|
TouchableOpacity,
|
|
8
7
|
View,
|
|
9
8
|
} from 'react-native';
|
|
@@ -11,8 +10,7 @@ import {SafeAreaView} from 'react-native-safe-area-context';
|
|
|
11
10
|
import {useFocusEffect} from '@react-navigation/native';
|
|
12
11
|
import Icon from 'react-native-vector-icons/MaterialIcons';
|
|
13
12
|
import {useStore} from '@store';
|
|
14
|
-
import
|
|
15
|
-
import DateShortcutFilter from '@controleonline/ui-default/src/react/components/filters/DateShortcutFilter';
|
|
13
|
+
import DefaultExternalFilters from '@controleonline/ui-default/src/react/components/filters/DefaultExternalFilters';
|
|
16
14
|
import EntityLogContent from '@controleonline/ui-common/src/react/components/EntityLogContent';
|
|
17
15
|
import Formatter from '@controleonline/ui-common/src/utils/formatter';
|
|
18
16
|
import {resolveStoreConfigByClassName} from '@controleonline/ui-common/src/react/utils/storeColumns';
|
|
@@ -185,41 +183,14 @@ const buildTypeOptions = items => {
|
|
|
185
183
|
});
|
|
186
184
|
|
|
187
185
|
return [
|
|
188
|
-
{
|
|
186
|
+
{value: '', label: 'Todos'},
|
|
189
187
|
...Array.from(typeKeys).map(key => ({
|
|
190
|
-
key,
|
|
188
|
+
value: key,
|
|
191
189
|
label: getTypeMeta(key).label,
|
|
192
190
|
})),
|
|
193
191
|
];
|
|
194
192
|
};
|
|
195
193
|
|
|
196
|
-
const buildQuickClassOptions = items => {
|
|
197
|
-
const counts = new Map();
|
|
198
|
-
|
|
199
|
-
items.forEach(log => {
|
|
200
|
-
if (normalizeFilterKey(log?.type) !== 'entity' || !normalizeText(log?.class)) {
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
const key = getShortClassName(log.class);
|
|
205
|
-
counts.set(key, (counts.get(key) || 0) + 1);
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
return Array.from(counts.entries())
|
|
209
|
-
.sort((left, right) => {
|
|
210
|
-
if (right[1] !== left[1]) {
|
|
211
|
-
return right[1] - left[1];
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return left[0].localeCompare(right[0], 'pt-BR');
|
|
215
|
-
})
|
|
216
|
-
.slice(0, 12)
|
|
217
|
-
.map(([value]) => ({
|
|
218
|
-
label: formatClassLabel(value),
|
|
219
|
-
value,
|
|
220
|
-
}));
|
|
221
|
-
};
|
|
222
|
-
|
|
223
194
|
function MetaBadge({meta, styles}) {
|
|
224
195
|
return (
|
|
225
196
|
<View
|
|
@@ -420,20 +391,18 @@ export default function GenericLogPage({navigation}) {
|
|
|
420
391
|
status: 'idle',
|
|
421
392
|
totalItems: 0,
|
|
422
393
|
});
|
|
423
|
-
const [
|
|
424
|
-
const [dateFilterKey, setDateFilterKey] = useState('all');
|
|
425
|
-
const [customRange, setCustomRange] = useState({
|
|
426
|
-
from: '',
|
|
427
|
-
to: '',
|
|
428
|
-
});
|
|
429
|
-
const [classFilterInput, setClassFilterInput] = useState('');
|
|
430
|
-
const [appliedClassFilter, setAppliedClassFilter] = useState('');
|
|
394
|
+
const [filters, setFilters] = useState({});
|
|
431
395
|
const [expandedEntityKey, setExpandedEntityKey] = useState('');
|
|
432
396
|
|
|
433
397
|
const loadLogs = useCallback(async () => {
|
|
434
|
-
const
|
|
398
|
+
const dateFilter = filters.createdAt || {};
|
|
399
|
+
const {after, before} = getDateRange(
|
|
400
|
+
dateFilter.shortcut || dateFilter.value || 'all',
|
|
401
|
+
dateFilter.customRange || {from: '', to: ''},
|
|
402
|
+
{
|
|
435
403
|
useCurrentMoment: true,
|
|
436
|
-
|
|
404
|
+
},
|
|
405
|
+
);
|
|
437
406
|
|
|
438
407
|
setLogsState(current => ({
|
|
439
408
|
...current,
|
|
@@ -443,10 +412,10 @@ export default function GenericLogPage({navigation}) {
|
|
|
443
412
|
|
|
444
413
|
try {
|
|
445
414
|
const response = await entityLogActions.getTimeline({
|
|
446
|
-
...(
|
|
415
|
+
...(filters.type ? {type: filters.type} : {}),
|
|
447
416
|
...(after ? {'createdAt[after]': after} : {}),
|
|
448
417
|
...(before ? {'createdAt[before]': before} : {}),
|
|
449
|
-
...(
|
|
418
|
+
...(filters.class ? {class: filters.class} : {}),
|
|
450
419
|
});
|
|
451
420
|
|
|
452
421
|
const items = Array.isArray(response?.items) ? response.items : [];
|
|
@@ -464,29 +433,31 @@ export default function GenericLogPage({navigation}) {
|
|
|
464
433
|
totalItems: 0,
|
|
465
434
|
});
|
|
466
435
|
}
|
|
467
|
-
}, [
|
|
436
|
+
}, [entityLogActions, filters]);
|
|
468
437
|
|
|
469
438
|
const typeOptions = useMemo(
|
|
470
439
|
() => buildTypeOptions(logsState.items),
|
|
471
440
|
[logsState.items],
|
|
472
441
|
);
|
|
473
442
|
|
|
474
|
-
const quickClassOptions = useMemo(
|
|
475
|
-
() => buildQuickClassOptions(logsState.items),
|
|
476
|
-
[logsState.items],
|
|
477
|
-
);
|
|
478
|
-
|
|
479
443
|
const activeDateSummary = useMemo(
|
|
480
|
-
() =>
|
|
481
|
-
|
|
444
|
+
() => {
|
|
445
|
+
const dateFilter = filters.createdAt || {};
|
|
446
|
+
return resolveDateRangeSummary(
|
|
447
|
+
dateFilter.shortcut || dateFilter.value || 'all',
|
|
448
|
+
dateFilter.customRange || {from: '', to: ''},
|
|
449
|
+
{useCurrentMoment: true},
|
|
450
|
+
);
|
|
451
|
+
},
|
|
452
|
+
[filters.createdAt],
|
|
482
453
|
);
|
|
483
454
|
|
|
484
455
|
const hasActiveFilters = useMemo(
|
|
485
456
|
() =>
|
|
486
|
-
|
|
487
|
-
Boolean(
|
|
457
|
+
Boolean(filters.type) ||
|
|
458
|
+
Boolean(filters.class) ||
|
|
488
459
|
Boolean(activeDateSummary),
|
|
489
|
-
[activeDateSummary,
|
|
460
|
+
[activeDateSummary, filters.class, filters.type],
|
|
490
461
|
);
|
|
491
462
|
|
|
492
463
|
const resultsSummary = useMemo(() => {
|
|
@@ -503,30 +474,13 @@ export default function GenericLogPage({navigation}) {
|
|
|
503
474
|
|
|
504
475
|
return `${countLabel} no periodo ${activeDateSummary}`;
|
|
505
476
|
}, [activeDateSummary, logsState.items.length, logsState.totalItems]);
|
|
506
|
-
const
|
|
507
|
-
|
|
508
|
-
[
|
|
477
|
+
const getExternalFilterOptions = useCallback(
|
|
478
|
+
column => ((column?.name || column?.key) === 'type' ? typeOptions : []),
|
|
479
|
+
[typeOptions],
|
|
509
480
|
);
|
|
510
|
-
const selectedQuickClassLabel = useMemo(() => {
|
|
511
|
-
if (!appliedClassFilter) {
|
|
512
|
-
return 'Sugestoes';
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
return quickClassOptions.find(
|
|
516
|
-
option => normalizeFilterKey(option.value) === normalizeFilterKey(appliedClassFilter),
|
|
517
|
-
)?.label || formatClassLabel(appliedClassFilter);
|
|
518
|
-
}, [appliedClassFilter, quickClassOptions]);
|
|
519
|
-
|
|
520
|
-
const applyClassFilter = useCallback(() => {
|
|
521
|
-
setAppliedClassFilter(normalizeText(classFilterInput));
|
|
522
|
-
}, [classFilterInput]);
|
|
523
481
|
|
|
524
482
|
const clearAllFilters = useCallback(() => {
|
|
525
|
-
|
|
526
|
-
setDateFilterKey('all');
|
|
527
|
-
setCustomRange({from: '', to: ''});
|
|
528
|
-
setClassFilterInput('');
|
|
529
|
-
setAppliedClassFilter('');
|
|
483
|
+
setFilters({});
|
|
530
484
|
setExpandedEntityKey('');
|
|
531
485
|
}, []);
|
|
532
486
|
|
|
@@ -548,7 +502,7 @@ export default function GenericLogPage({navigation}) {
|
|
|
548
502
|
|
|
549
503
|
useEffect(() => {
|
|
550
504
|
setExpandedEntityKey('');
|
|
551
|
-
}, [
|
|
505
|
+
}, [filters, logsState.items]);
|
|
552
506
|
|
|
553
507
|
useFocusEffect(
|
|
554
508
|
useCallback(() => {
|
|
@@ -602,96 +556,17 @@ export default function GenericLogPage({navigation}) {
|
|
|
602
556
|
) : null}
|
|
603
557
|
</View>
|
|
604
558
|
|
|
605
|
-
<
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
borderSoft: '#E2E8F0',
|
|
617
|
-
cardBg: '#FFFFFF',
|
|
618
|
-
cardBgSoft: '#F8FAFC',
|
|
619
|
-
danger: '#DC2626',
|
|
620
|
-
isLight: true,
|
|
621
|
-
panelBg: '#EFF6FF',
|
|
622
|
-
pillTextDark: '#FFFFFF',
|
|
623
|
-
textPrimary: '#0F172A',
|
|
624
|
-
textSecondary: '#64748B',
|
|
625
|
-
}}
|
|
626
|
-
/>
|
|
627
|
-
|
|
628
|
-
{!!activeDateSummary && (
|
|
629
|
-
<Text style={styles.filterHint}>Periodo atual: {activeDateSummary}</Text>
|
|
630
|
-
)}
|
|
631
|
-
</View>
|
|
632
|
-
|
|
633
|
-
<View style={styles.filterGroup}>
|
|
634
|
-
<Text style={styles.filterLabel}>Tipo de log</Text>
|
|
635
|
-
<CompactFilterSelector
|
|
636
|
-
icon="filter"
|
|
637
|
-
label={selectedTypeLabel}
|
|
638
|
-
title="Tipo de log"
|
|
639
|
-
accentColor="#2563EB"
|
|
640
|
-
active={selectedType !== 'all'}
|
|
641
|
-
options={typeOptions}
|
|
642
|
-
selectedKey={selectedType}
|
|
643
|
-
onSelect={optionKey => {
|
|
644
|
-
setSelectedType(optionKey);
|
|
645
|
-
return true;
|
|
646
|
-
}}
|
|
647
|
-
/>
|
|
648
|
-
</View>
|
|
649
|
-
|
|
650
|
-
<View style={styles.filterGroup}>
|
|
651
|
-
<Text style={styles.filterLabel}>Classe / origem</Text>
|
|
652
|
-
<View style={styles.textFilterRow}>
|
|
653
|
-
<TextInput
|
|
654
|
-
value={classFilterInput}
|
|
655
|
-
onChangeText={setClassFilterInput}
|
|
656
|
-
placeholder="Ex.: Integration, Device, execute_operation"
|
|
657
|
-
placeholderTextColor="#94A3B8"
|
|
658
|
-
autoCapitalize="none"
|
|
659
|
-
autoCorrect={false}
|
|
660
|
-
style={styles.textFilterInput}
|
|
661
|
-
/>
|
|
662
|
-
|
|
663
|
-
<TouchableOpacity
|
|
664
|
-
activeOpacity={0.9}
|
|
665
|
-
onPress={applyClassFilter}
|
|
666
|
-
style={styles.primaryButton}>
|
|
667
|
-
<Text style={styles.primaryButtonText}>Aplicar</Text>
|
|
668
|
-
</TouchableOpacity>
|
|
669
|
-
</View>
|
|
670
|
-
|
|
671
|
-
{!!appliedClassFilter && (
|
|
672
|
-
<Text style={styles.filterHint}>Classe aplicada: {appliedClassFilter}</Text>
|
|
673
|
-
)}
|
|
674
|
-
|
|
675
|
-
{!!quickClassOptions.length && (
|
|
676
|
-
<CompactFilterSelector
|
|
677
|
-
icon="layers"
|
|
678
|
-
label={selectedQuickClassLabel}
|
|
679
|
-
title="Sugestoes de classe"
|
|
680
|
-
accentColor="#2563EB"
|
|
681
|
-
active={Boolean(appliedClassFilter)}
|
|
682
|
-
options={quickClassOptions.map(option => ({
|
|
683
|
-
key: option.value,
|
|
684
|
-
label: option.label,
|
|
685
|
-
}))}
|
|
686
|
-
selectedKey={appliedClassFilter}
|
|
687
|
-
onSelect={optionKey => {
|
|
688
|
-
setClassFilterInput(optionKey);
|
|
689
|
-
setAppliedClassFilter(optionKey);
|
|
690
|
-
return true;
|
|
691
|
-
}}
|
|
692
|
-
/>
|
|
693
|
-
)}
|
|
694
|
-
</View>
|
|
559
|
+
<DefaultExternalFilters
|
|
560
|
+
accentColor="#2563EB"
|
|
561
|
+
filters={filters}
|
|
562
|
+
getOptionsForColumn={getExternalFilterOptions}
|
|
563
|
+
onChangeFilters={setFilters}
|
|
564
|
+
storeName="entity_log"
|
|
565
|
+
/>
|
|
566
|
+
|
|
567
|
+
{!!activeDateSummary && (
|
|
568
|
+
<Text style={styles.filterHint}>Periodo atual: {activeDateSummary}</Text>
|
|
569
|
+
)}
|
|
695
570
|
</View>
|
|
696
571
|
|
|
697
572
|
{logsState.status === 'loading' ? (
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import Food99CatalogTab from '../../Food99IntegrationPage/components/Food99CatalogTab';
|
|
4
|
+
|
|
5
|
+
// Aba de cardápio do iFood, renderizada pelo mesmo componente compartilhado.
|
|
6
|
+
export default function IFoodCatalogTab(props) {
|
|
7
|
+
return <Food99CatalogTab {...props} providerKey="ifood" />;
|
|
8
|
+
}
|