@eohjsc/react-native-smart-city 0.3.53 → 0.3.55
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/package.json +2 -1
- package/src/Images/Common/loading-circle.json +1 -0
- package/src/commons/ActionGroup/SliderRangeTemplate.js +1 -1
- package/src/commons/ActionGroup/index.js +6 -2
- package/src/commons/ButtonPopup/index.js +2 -0
- package/src/commons/DevMode/EmptyComponent.js +2 -2
- package/src/commons/DevMode/Item.js +2 -4
- package/src/commons/DevMode/Styles/ItemStyles.js +6 -0
- package/src/commons/Device/WaterQualitySensor/ListQualityIndicator.js +9 -6
- package/src/commons/FullLoading/__test__/index.test.js +43 -0
- package/src/commons/FullLoading/index.js +13 -3
- package/src/commons/Header/HeaderCustom.js +6 -1
- package/src/commons/Header/Styles/HeaderCustomStyles.js +4 -1
- package/src/commons/Processing/index.js +20 -18
- package/src/commons/Processing/styles.js +4 -3
- package/src/commons/StatusBox/index.js +23 -5
- package/src/commons/StatusBox/styles.js +7 -6
- package/src/configs/API.js +1 -1
- package/src/configs/AccessibilityLabel.js +1 -1
- package/src/configs/Colors.js +2 -0
- package/src/hooks/IoT/__test__/useRemoteControl.test.js +22 -21
- package/src/hooks/IoT/useRemoteControl.js +8 -7
- package/src/iot/RemoteControl/Bluetooth.js +1 -1
- package/src/navigations/Main.js +3 -1
- package/src/screens/AddNewGateway/ConnectingModbusDevice.js +16 -19
- package/src/screens/AddNewGateway/ConnectingWifiGuide.js +139 -75
- package/src/screens/AddNewGateway/ConnectingWifiGuideStyles.js +8 -7
- package/src/screens/AddNewGateway/RenameNewDevices.js +147 -70
- package/src/screens/AddNewGateway/RenameNewDevicesStyles.js +35 -16
- package/src/screens/AddNewGateway/ShareWifiPassword.js +176 -107
- package/src/screens/AddNewGateway/ShareWifiPasswordStyles.js +14 -1
- package/src/screens/AddNewGateway/__test__/ConnectingWifiGuide.test.js +53 -7
- package/src/screens/AddNewGateway/__test__/RenameNewDevices.test.js +44 -10
- package/src/screens/AddNewGateway/hooks/__Tests__/useStateAlertRename.test.js +57 -0
- package/src/screens/AddNewGateway/hooks/__Tests__/useWifiManage.test.js +22 -0
- package/src/screens/AddNewGateway/hooks/useWifiManage.js +29 -0
- package/src/screens/Device/__test__/detail.test.js +7 -1
- package/src/screens/Device/components/SensorDisplayItem.js +10 -2
- package/src/screens/Gateway/GatewayInfo/__test__/index.test.js +1 -1
- package/src/screens/Gateway/__test__/index.test.js +1 -1
- package/src/screens/Gateway/components/GatewayItem/index.js +1 -1
- package/src/screens/Gateway/components/GatewayItem/styles.js +4 -0
- package/src/screens/Gateway/components/Information/__test__/index.test.js +1 -1
- package/src/screens/Gateway/components/Information/index.js +5 -3
- package/src/screens/Gateway/components/Information/styles.js +3 -0
- package/src/screens/Gateway/components/TabPaneCT/index.js +31 -27
- package/src/screens/Gateway/components/TabPaneCT/styles.js +7 -1
- package/src/screens/Gateway/index.js +10 -10
- package/src/screens/Gateway/styles.js +3 -1
- package/src/screens/Notification/__test__/Notification.test.js +9 -1
- package/src/screens/Notification/index.js +7 -4
- package/src/screens/Smart/__test__/index.test.js +16 -4
- package/src/screens/Smart/index.js +15 -1
- package/src/screens/Smart/styles.js +15 -0
- package/src/screens/Template/EditTemplate.js +1 -1
- package/src/screens/Template/Styles/indexStyles.js +1 -1
- package/src/screens/Template/detail.js +26 -2
- package/src/screens/Template/index.js +1 -1
- package/src/screens/Unit/MoreMenu.js +56 -58
- package/src/screens/Unit/__test__/MoreMenu.test.js +59 -0
- package/src/screens/Unit/hook/useUnitConnectRemoteDevices.js +6 -3
- package/src/screens/UnitSummary/components/RunningDevices/__test__/index.test.js +7 -1
- package/src/utils/I18n/translations/en.json +10 -8
- package/src/utils/I18n/translations/vi.json +10 -7
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import WifiManager from 'react-native-wifi-reborn';
|
|
3
|
+
import { Platform } from 'react-native';
|
|
4
|
+
|
|
5
|
+
const useWifiManage = () => {
|
|
6
|
+
const getCurrentWifiSSID = useCallback(async () => {
|
|
7
|
+
const currentConnectingWifi =
|
|
8
|
+
(await WifiManager.getCurrentWifiSSID()) || '';
|
|
9
|
+
return currentConnectingWifi;
|
|
10
|
+
}, []);
|
|
11
|
+
|
|
12
|
+
const disconnectWifi = useCallback(async (ssid) => {
|
|
13
|
+
try {
|
|
14
|
+
Platform.OS === 'ios'
|
|
15
|
+
? await WifiManager.disconnectFromSSID(ssid)
|
|
16
|
+
: await WifiManager.disconnect();
|
|
17
|
+
} catch (e) {
|
|
18
|
+
// eslint-disable-next-line no-console
|
|
19
|
+
console.log('wifiManage-disconnect', e);
|
|
20
|
+
}
|
|
21
|
+
}, []);
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
getCurrentWifiSSID,
|
|
25
|
+
disconnectWifi,
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export { useWifiManage };
|
|
@@ -106,7 +106,13 @@ describe('test DeviceDetail', () => {
|
|
|
106
106
|
name: 'Unit name',
|
|
107
107
|
address: '298 Dien Bien Phu',
|
|
108
108
|
remote_control_options: {
|
|
109
|
-
googlehome:
|
|
109
|
+
googlehome: [
|
|
110
|
+
{
|
|
111
|
+
config_maps: [],
|
|
112
|
+
auth: {},
|
|
113
|
+
chip_id: 1,
|
|
114
|
+
},
|
|
115
|
+
],
|
|
110
116
|
},
|
|
111
117
|
},
|
|
112
118
|
station: {
|
|
@@ -43,13 +43,20 @@ export const SensorDisplayItem = ({
|
|
|
43
43
|
const { configuration = {}, id: idTemplate } = item;
|
|
44
44
|
const { type, uri, id, name, title } = configuration;
|
|
45
45
|
|
|
46
|
+
const { isEditingTemplate } = useSCContextSelector((state) => state.devMode);
|
|
47
|
+
|
|
46
48
|
const sendRemoteCommand = useRemoteControl();
|
|
47
49
|
|
|
48
50
|
const doAction = useCallback(
|
|
49
51
|
(action, data) => {
|
|
50
|
-
sendRemoteCommand(
|
|
52
|
+
sendRemoteCommand(
|
|
53
|
+
isEditingTemplate ? action?.end_device : sensor,
|
|
54
|
+
action,
|
|
55
|
+
data,
|
|
56
|
+
userId
|
|
57
|
+
);
|
|
51
58
|
},
|
|
52
|
-
[sensor,
|
|
59
|
+
[isEditingTemplate, sensor, sendRemoteCommand, userId]
|
|
53
60
|
);
|
|
54
61
|
|
|
55
62
|
if (type === 'compass') {
|
|
@@ -81,6 +88,7 @@ export const SensorDisplayItem = ({
|
|
|
81
88
|
doAction={doAction}
|
|
82
89
|
sensor={sensor}
|
|
83
90
|
id={idTemplate}
|
|
91
|
+
item={item}
|
|
84
92
|
/>
|
|
85
93
|
);
|
|
86
94
|
case 'history':
|
|
@@ -91,7 +91,7 @@ describe('Test GatewayInfo', () => {
|
|
|
91
91
|
const btnConnect = buttonConnect(instance);
|
|
92
92
|
const btnDelete = buttonDelete(instance);
|
|
93
93
|
expect(headerCustom).toHaveLength(1);
|
|
94
|
-
expect(alert.props.children[1].props.children).toEqual(
|
|
94
|
+
expect(alert.props.children[1].props.children.props.children).toEqual(
|
|
95
95
|
t('go_to_eoh_web_to_see_firmware')
|
|
96
96
|
);
|
|
97
97
|
expect(flatList).toHaveLength(1);
|
|
@@ -46,7 +46,7 @@ describe('Test Gateway screen', () => {
|
|
|
46
46
|
accessibilityLabel: AccessibilityLabel.LIST_GATEWAY,
|
|
47
47
|
});
|
|
48
48
|
const flatLists = instance.findAllByType(FlatList);
|
|
49
|
-
expect(view.props.children[0].props.
|
|
49
|
+
expect(view.props.children[0].props.name).toEqual('Gateway');
|
|
50
50
|
expect(flatLists).toHaveLength(1);
|
|
51
51
|
});
|
|
52
52
|
|
|
@@ -6,7 +6,7 @@ import styles from './styles';
|
|
|
6
6
|
|
|
7
7
|
const GatewayItem = ({ item, onPress }) => {
|
|
8
8
|
return (
|
|
9
|
-
<View style={styles.wrap}>
|
|
9
|
+
<View style={[styles.wrap, !item?.is_connected && styles.borderDisconnect]}>
|
|
10
10
|
<TouchableOpacity style={styles.button} onPress={onPress}>
|
|
11
11
|
<View style={styles.viewTitle}>
|
|
12
12
|
<Text type="Body" bold color={Colors.Gray9} style={styles.textTitle}>
|
|
@@ -49,7 +49,7 @@ describe('Test Information', () => {
|
|
|
49
49
|
const flatList = instance.findAllByType(FlatList);
|
|
50
50
|
expect(headerCustom).toHaveLength(1);
|
|
51
51
|
expect(flatList).toHaveLength(1);
|
|
52
|
-
expect(viewAlert.props.children[1].props.children).toEqual(
|
|
52
|
+
expect(viewAlert.props.children[1].props.children.props.children).toEqual(
|
|
53
53
|
'Go to EoH web to see firmware configuration'
|
|
54
54
|
);
|
|
55
55
|
const buttonConnect = instance.findByProps({
|
|
@@ -44,9 +44,11 @@ const Information = ({
|
|
|
44
44
|
accessibilityLabel={AccessibilityLabel.GATEWAY_INFO_ALERT}
|
|
45
45
|
>
|
|
46
46
|
<Image source={Images.inforCode} />
|
|
47
|
-
<
|
|
48
|
-
{
|
|
49
|
-
|
|
47
|
+
<View style={styles.flex1}>
|
|
48
|
+
<Text type="H4" style={styles.marginLeft16}>
|
|
49
|
+
{t('go_to_eoh_web_to_see_firmware')}
|
|
50
|
+
</Text>
|
|
51
|
+
</View>
|
|
50
52
|
</View>
|
|
51
53
|
</View>
|
|
52
54
|
)}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import React, { useCallback, memo, useMemo, useRef } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
TouchableOpacity,
|
|
5
|
+
Image,
|
|
6
|
+
ScrollView,
|
|
7
|
+
RefreshControl,
|
|
8
|
+
} from 'react-native';
|
|
3
9
|
import SegmentedControl from '@react-native-community/segmented-control';
|
|
4
10
|
import Carousel from 'react-native-snap-carousel';
|
|
5
11
|
|
|
@@ -33,7 +39,7 @@ const TabPaneCT = ({
|
|
|
33
39
|
},
|
|
34
40
|
[onPressRow]
|
|
35
41
|
);
|
|
36
|
-
const
|
|
42
|
+
const ItemGateWay = useCallback(
|
|
37
43
|
({ item }) => {
|
|
38
44
|
const { sensor = {}, config = {}, action = {} } = item || {};
|
|
39
45
|
const { name = '', is_connected = '' } = {
|
|
@@ -47,9 +53,17 @@ const TabPaneCT = ({
|
|
|
47
53
|
style={[styles.deviceItem, isDevice && styles.buttonItem]}
|
|
48
54
|
onPress={handleOnPressRow(item)}
|
|
49
55
|
>
|
|
50
|
-
<
|
|
56
|
+
<View style={styles.flex1}>
|
|
57
|
+
<Text type="H4" numberOfLines={1}>
|
|
58
|
+
{name}
|
|
59
|
+
</Text>
|
|
60
|
+
</View>
|
|
51
61
|
{!isDevice ? (
|
|
52
|
-
<StatusBox
|
|
62
|
+
<StatusBox
|
|
63
|
+
status={is_connected}
|
|
64
|
+
typeConnect
|
|
65
|
+
styleWrap={styles.statusBox}
|
|
66
|
+
/>
|
|
53
67
|
) : (
|
|
54
68
|
<Image style={styles.arrowRight} source={Images.arrowLeft} />
|
|
55
69
|
)}
|
|
@@ -62,7 +76,14 @@ const TabPaneCT = ({
|
|
|
62
76
|
const renderItemPanel = useCallback(
|
|
63
77
|
({ item }) => {
|
|
64
78
|
return (
|
|
65
|
-
<
|
|
79
|
+
<ScrollView
|
|
80
|
+
style={[styles.pane, stylesPane]}
|
|
81
|
+
showsVerticalScrollIndicator={false}
|
|
82
|
+
refreshControl={
|
|
83
|
+
<RefreshControl onRefresh={onRefresh} refreshing={refresh} />
|
|
84
|
+
}
|
|
85
|
+
accessibilityLabel={AccessibilityLabel.TAB_PANE_CT_SCROLLVIEW}
|
|
86
|
+
>
|
|
66
87
|
{!isDevice && (
|
|
67
88
|
<View style={styles.titleTab}>
|
|
68
89
|
<Text type="H4" bold>{`${t('device')} (${
|
|
@@ -70,30 +91,13 @@ const TabPaneCT = ({
|
|
|
70
91
|
})`}</Text>
|
|
71
92
|
</View>
|
|
72
93
|
)}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
{
|
|
78
|
-
...styles.contentContainerStyle,
|
|
79
|
-
},
|
|
80
|
-
isDevice && { ...styles.paddingTop16 },
|
|
81
|
-
]}
|
|
82
|
-
// eslint-disable-next-line no-shadow
|
|
83
|
-
keyExtractor={(item) => item?.id}
|
|
84
|
-
showsVerticalScrollIndicator={false}
|
|
85
|
-
showsHorizontalScrollIndicator={false}
|
|
86
|
-
onRefresh={onRefresh}
|
|
87
|
-
refreshing={refresh}
|
|
88
|
-
data={item?.data || []}
|
|
89
|
-
renderItem={renderItem}
|
|
90
|
-
extraData={item?.data || []}
|
|
91
|
-
numColumns={1}
|
|
92
|
-
/>
|
|
93
|
-
</View>
|
|
94
|
+
{(item?.data || []).map((data, index) => (
|
|
95
|
+
<ItemGateWay item={data} key={index.toString()} />
|
|
96
|
+
))}
|
|
97
|
+
</ScrollView>
|
|
94
98
|
);
|
|
95
99
|
},
|
|
96
|
-
[
|
|
100
|
+
[isDevice, onRefresh, stylesPane, refresh]
|
|
97
101
|
);
|
|
98
102
|
|
|
99
103
|
const onChangeTabs = useCallback(
|
|
@@ -25,7 +25,6 @@ export default StyleSheet.create({
|
|
|
25
25
|
marginBottom: 16,
|
|
26
26
|
},
|
|
27
27
|
contentContainerStyle: {
|
|
28
|
-
flex: 1,
|
|
29
28
|
width: '100%',
|
|
30
29
|
height: '100%',
|
|
31
30
|
},
|
|
@@ -40,6 +39,7 @@ export default StyleSheet.create({
|
|
|
40
39
|
alignItems: 'center',
|
|
41
40
|
justifyContent: 'space-between',
|
|
42
41
|
paddingBottom: 16,
|
|
42
|
+
width: 'auto',
|
|
43
43
|
},
|
|
44
44
|
paddingTop16: {
|
|
45
45
|
paddingTop: 16,
|
|
@@ -55,4 +55,10 @@ export default StyleSheet.create({
|
|
|
55
55
|
colorGray9: {
|
|
56
56
|
color: Colors.Gray9,
|
|
57
57
|
},
|
|
58
|
+
flex1: {
|
|
59
|
+
flex: 1,
|
|
60
|
+
},
|
|
61
|
+
statusBox: {
|
|
62
|
+
width: 'auto',
|
|
63
|
+
},
|
|
58
64
|
});
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import React, { useCallback, memo, useEffect, useMemo } from 'react';
|
|
2
2
|
import { View, FlatList } from 'react-native';
|
|
3
3
|
import { useNavigation, useIsFocused } from '@react-navigation/native';
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
7
|
-
import { Text } from '../../commons';
|
|
8
|
-
import styles from './styles';
|
|
9
|
-
import { Search, EmptyComponent } from '../../commons/DevMode';
|
|
4
|
+
|
|
5
|
+
import { Search, EmptyComponent, Label } from '../../commons/DevMode';
|
|
10
6
|
import GatewayItem from './components/GatewayItem';
|
|
7
|
+
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
11
8
|
import { useGateway } from './hooks/useGateway';
|
|
9
|
+
import { AccessibilityLabel } from '../../configs/Constants';
|
|
12
10
|
import Routes from '../../utils/Route';
|
|
11
|
+
import styles from './styles';
|
|
13
12
|
|
|
14
13
|
const Gateway = ({ route }) => {
|
|
15
14
|
const t = useTranslations();
|
|
@@ -71,9 +70,7 @@ const Gateway = ({ route }) => {
|
|
|
71
70
|
style={styles.wrap}
|
|
72
71
|
accessibilityLabel={AccessibilityLabel.LIST_GATEWAY}
|
|
73
72
|
>
|
|
74
|
-
<
|
|
75
|
-
{t('gateway')}
|
|
76
|
-
</Text>
|
|
73
|
+
<Label name={t('gateway')} />
|
|
77
74
|
<Search onSearch={setNameSearch} />
|
|
78
75
|
<FlatList
|
|
79
76
|
onRefresh={onRefresh}
|
|
@@ -81,7 +78,10 @@ const Gateway = ({ route }) => {
|
|
|
81
78
|
columnWrapperStyle={styles.spaceBetween}
|
|
82
79
|
showsVerticalScrollIndicator={false}
|
|
83
80
|
showsHorizontalScrollIndicator={false}
|
|
84
|
-
contentContainerStyle={
|
|
81
|
+
contentContainerStyle={[
|
|
82
|
+
styles.contentContainerStyle,
|
|
83
|
+
gatewaysSearched?.length === 0 && styles.flex1,
|
|
84
|
+
]}
|
|
85
85
|
keyExtractor={(item) => item?.id}
|
|
86
86
|
data={gatewaysSearched}
|
|
87
87
|
renderItem={renderItem}
|
|
@@ -15,7 +15,6 @@ export default StyleSheet.create({
|
|
|
15
15
|
lineHeight: 36,
|
|
16
16
|
},
|
|
17
17
|
contentContainerStyle: {
|
|
18
|
-
flex: 1,
|
|
19
18
|
flexDirection: 'column',
|
|
20
19
|
height: 'auto',
|
|
21
20
|
},
|
|
@@ -27,4 +26,7 @@ export default StyleSheet.create({
|
|
|
27
26
|
spaceBetween: {
|
|
28
27
|
justifyContent: 'space-between',
|
|
29
28
|
},
|
|
29
|
+
flex1: {
|
|
30
|
+
flex: 1,
|
|
31
|
+
},
|
|
30
32
|
});
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { act, create } from 'react-test-renderer';
|
|
3
3
|
import MockAdapter from 'axios-mock-adapter';
|
|
4
4
|
import { Animated, RefreshControl } from 'react-native';
|
|
5
|
+
import { NavigationContext } from '@react-navigation/native';
|
|
5
6
|
|
|
6
7
|
import { SCProvider } from '../../../context';
|
|
7
8
|
import { mockSCStore } from '../../../context/mockStore';
|
|
@@ -12,7 +13,14 @@ import api from '../../../utils/Apis/axios';
|
|
|
12
13
|
|
|
13
14
|
const wrapComponent = () => (
|
|
14
15
|
<SCProvider initState={mockSCStore({})}>
|
|
15
|
-
<
|
|
16
|
+
<NavigationContext.Provider
|
|
17
|
+
value={{
|
|
18
|
+
addListener: jest.fn(() => jest.fn()),
|
|
19
|
+
isFocused: () => true,
|
|
20
|
+
}}
|
|
21
|
+
>
|
|
22
|
+
<Notification />
|
|
23
|
+
</NavigationContext.Provider>
|
|
16
24
|
</SCProvider>
|
|
17
25
|
);
|
|
18
26
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { memo, useMemo, useState, useCallback, useEffect } from 'react';
|
|
2
2
|
import { View, TouchableOpacity } from 'react-native';
|
|
3
3
|
import { Icon } from '@ant-design/react-native';
|
|
4
|
+
import { useFocusEffect } from '@react-navigation/native';
|
|
4
5
|
|
|
5
6
|
import styles from './styles/indexStyles';
|
|
6
7
|
import { API, Colors } from '../../configs';
|
|
@@ -59,10 +60,12 @@ const Notification = memo(() => {
|
|
|
59
60
|
}
|
|
60
61
|
}, []);
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
useFocusEffect(
|
|
64
|
+
useCallback(() => {
|
|
65
|
+
fetchNotifications(1);
|
|
66
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
67
|
+
}, [])
|
|
68
|
+
);
|
|
66
69
|
|
|
67
70
|
const handleOnLoadMore = useCallback(() => {
|
|
68
71
|
page += 1;
|
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { View } from 'react-native';
|
|
3
2
|
import { act, create } from 'react-test-renderer';
|
|
3
|
+
|
|
4
|
+
import { SCProvider } from '../../../context';
|
|
5
|
+
import { mockSCStore } from '../../../context/mockStore';
|
|
6
|
+
import { EmptyComponent } from '../../../commons/DevMode';
|
|
7
|
+
import t from '../../../hooks/Common/useTranslations';
|
|
8
|
+
|
|
4
9
|
import Smart from '..';
|
|
5
10
|
|
|
11
|
+
const wrapComponent = (route) => (
|
|
12
|
+
<SCProvider initState={mockSCStore({})}>
|
|
13
|
+
<Smart route={route} />
|
|
14
|
+
</SCProvider>
|
|
15
|
+
);
|
|
16
|
+
|
|
6
17
|
describe('Test Template screen', () => {
|
|
7
18
|
let tree;
|
|
8
19
|
it('Test render', async () => {
|
|
9
20
|
await act(async () => {
|
|
10
|
-
tree = await create(
|
|
21
|
+
tree = await create(wrapComponent());
|
|
11
22
|
});
|
|
12
23
|
const instance = tree.root;
|
|
13
|
-
const
|
|
14
|
-
expect(
|
|
24
|
+
const emptyComponent = instance.findByType(EmptyComponent);
|
|
25
|
+
expect(emptyComponent.props.text1).toEqual(t('text_under_development'));
|
|
26
|
+
expect(emptyComponent.props.text2).toEqual(t('text_working_hard'));
|
|
15
27
|
});
|
|
16
28
|
});
|
|
@@ -1,8 +1,22 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
|
+
import { EmptyComponent } from '../../commons/DevMode';
|
|
4
|
+
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
5
|
+
|
|
6
|
+
import styles from './styles';
|
|
3
7
|
|
|
4
8
|
const Smart = () => {
|
|
5
|
-
|
|
9
|
+
const t = useTranslations();
|
|
10
|
+
return (
|
|
11
|
+
<View style={styles.wrap}>
|
|
12
|
+
<View style={styles.wrapEmpty}>
|
|
13
|
+
<EmptyComponent
|
|
14
|
+
text1={t('text_under_development')}
|
|
15
|
+
text2={t('text_working_hard')}
|
|
16
|
+
/>
|
|
17
|
+
</View>
|
|
18
|
+
</View>
|
|
19
|
+
);
|
|
6
20
|
};
|
|
7
21
|
|
|
8
22
|
export default Smart;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
import { Colors } from '../../configs';
|
|
3
|
+
|
|
4
|
+
export default StyleSheet.create({
|
|
5
|
+
wrap: {
|
|
6
|
+
flex: 1,
|
|
7
|
+
backgroundColor: Colors.White,
|
|
8
|
+
padding: 16,
|
|
9
|
+
},
|
|
10
|
+
wrapEmpty: {
|
|
11
|
+
justifyContent: 'center',
|
|
12
|
+
alignItems: 'center',
|
|
13
|
+
marginTop: 200,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
@@ -19,6 +19,7 @@ import t from '../../hooks/Common/useTranslations';
|
|
|
19
19
|
import Routes from '../../utils/Route';
|
|
20
20
|
import { SensorDisplayItem } from '../Device/components/SensorDisplayItem';
|
|
21
21
|
import { axiosGet } from '../../utils/Apis/axios';
|
|
22
|
+
import { watchMultiConfigs } from '../../iot/Monitor';
|
|
22
23
|
|
|
23
24
|
const TemplateDetail = () => {
|
|
24
25
|
const refMenuAction = useRef();
|
|
@@ -30,6 +31,23 @@ const TemplateDetail = () => {
|
|
|
30
31
|
const [data, setData] = useState([]);
|
|
31
32
|
const [isLoading, setIsLoading] = useState(true);
|
|
32
33
|
|
|
34
|
+
const listIds = useMemo(() => {
|
|
35
|
+
const configIds = [];
|
|
36
|
+
// eslint-disable-next-line no-shadow
|
|
37
|
+
data.forEach((item) => {
|
|
38
|
+
switch (item.type) {
|
|
39
|
+
case 'value':
|
|
40
|
+
(item?.configuration?.configs || []).forEach((config) => {
|
|
41
|
+
configIds.push(config.id);
|
|
42
|
+
});
|
|
43
|
+
break;
|
|
44
|
+
default:
|
|
45
|
+
configIds.push(item?.configuration?.configuration?.config);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return configIds;
|
|
49
|
+
}, [data]);
|
|
50
|
+
|
|
33
51
|
// eslint-disable-next-line no-shadow
|
|
34
52
|
const onItemClick = useCallback((item) => {
|
|
35
53
|
item.doAction();
|
|
@@ -67,7 +85,7 @@ const TemplateDetail = () => {
|
|
|
67
85
|
const listMenuItem = useMemo(
|
|
68
86
|
() => [
|
|
69
87
|
{
|
|
70
|
-
text: t('
|
|
88
|
+
text: t('edit_dashboard'),
|
|
71
89
|
doAction: goToDetail(Routes.EditTemplate, { setData, data }),
|
|
72
90
|
},
|
|
73
91
|
{
|
|
@@ -79,7 +97,7 @@ const TemplateDetail = () => {
|
|
|
79
97
|
doAction: goToDetail(Routes.GatewayList),
|
|
80
98
|
},
|
|
81
99
|
{
|
|
82
|
-
text: t('
|
|
100
|
+
text: t('delete_dashboard'),
|
|
83
101
|
doAction: goToDetail(Routes.GatewayList),
|
|
84
102
|
textStyle: { color: Colors.Red },
|
|
85
103
|
},
|
|
@@ -114,6 +132,10 @@ const TemplateDetail = () => {
|
|
|
114
132
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
115
133
|
}, []);
|
|
116
134
|
|
|
135
|
+
useEffect(() => {
|
|
136
|
+
listIds.length && watchMultiConfigs(listIds);
|
|
137
|
+
}, [listIds]);
|
|
138
|
+
|
|
117
139
|
return (
|
|
118
140
|
<View style={styles.wrap}>
|
|
119
141
|
<WrapHeaderScrollable
|
|
@@ -121,6 +143,7 @@ const TemplateDetail = () => {
|
|
|
121
143
|
headerAniStyle={styles.headerAniStyle}
|
|
122
144
|
rightComponent={rightComponent}
|
|
123
145
|
onGoBack={goBack}
|
|
146
|
+
onRefresh={getWidgets}
|
|
124
147
|
>
|
|
125
148
|
{!isLoading && !data?.length
|
|
126
149
|
? renderEmpty
|
|
@@ -133,6 +156,7 @@ const TemplateDetail = () => {
|
|
|
133
156
|
offsetTitle={'offsetTitle'}
|
|
134
157
|
setOffsetTitle={'setOffsetTitle'}
|
|
135
158
|
maxValue={100}
|
|
159
|
+
sensor={item}
|
|
136
160
|
/>
|
|
137
161
|
);
|
|
138
162
|
})}
|
|
@@ -71,7 +71,7 @@ const Template = () => {
|
|
|
71
71
|
return (
|
|
72
72
|
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
|
73
73
|
<View style={styles.wrap}>
|
|
74
|
-
<Label name={t('
|
|
74
|
+
<Label name={t('dashboard')} />
|
|
75
75
|
<Search onSearch={onSearch} />
|
|
76
76
|
<FlatList
|
|
77
77
|
contentContainerStyle={styles.contentContainerStyle}
|