@eohjsc/react-native-smart-city 0.7.7 → 0.7.9
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/assets/images/AddNewDevice/add-scan-device-icon.svg +13 -0
- package/assets/images/Email.svg +9 -0
- package/assets/images/lan.svg +3 -0
- package/assets/images/wifi-open.svg +3 -0
- package/package.json +4 -3
- package/src/commons/ActionGroup/StatesGridActionTemplate.js +7 -3
- package/src/commons/ActionGroup/__test__/StatesGridActionTemplate.test.js +7 -3
- package/src/commons/AlertAction/index.js +1 -0
- package/src/commons/Auth/AccountItem.js +17 -3
- package/src/commons/Auth/AccountList.js +3 -7
- package/src/commons/ConnectWifi/__test__/ConnectWifi.test.js +373 -0
- package/src/commons/ConnectWifi/index.js +201 -0
- package/src/commons/ConnectWifi/styles.js +69 -0
- package/src/commons/Device/LabelValue/__test__/LabelValue.test.js +74 -0
- package/src/commons/Device/LabelValue/index.js +49 -0
- package/src/commons/Device/LabelValue/styles.js +33 -0
- package/src/commons/Form/TextInputPassword.js +1 -1
- package/src/commons/OneTapTemplate/StatesGridActionTemplate.js +6 -2
- package/src/configs/API.js +12 -0
- package/src/configs/AccessibilityLabel.js +7 -0
- package/src/configs/Constants.js +1 -0
- package/src/hooks/Common/index.js +2 -2
- package/src/hooks/Common/useBlockBack.js +36 -0
- package/src/hooks/useMqtt.js +10 -5
- package/src/navigations/AddGatewayStack.js +2 -0
- package/src/navigations/AllGatewayStack.js +4 -0
- package/src/navigations/Main.js +2 -2
- package/src/navigations/UnitStack.js +32 -0
- package/src/screens/AddNewGateway/ConnectingWifiDevice.js +7 -6
- package/src/screens/AddNewGateway/ScanDeviceLocal.js +267 -0
- package/src/screens/AddNewGateway/ScanDeviceLocalStyles.js +58 -0
- package/src/screens/AddNewGateway/SelectDeviceSubUnit.js +10 -2
- package/src/screens/AddNewGateway/SelectDeviceType.js +19 -2
- package/src/screens/AddNewGateway/__test__/ScanDeviceLocal.test.js +475 -0
- package/src/screens/AddNewGateway/__test__/SelectDeviceType.test.js +2 -2
- package/src/screens/AddNewGateway/configs/API.js +8 -0
- package/src/screens/AddNewGateway/hooks/useConnectDevice.js +59 -0
- package/src/screens/AllGateway/GatewayInfo/__test__/index.test.js +58 -1
- package/src/screens/AllGateway/GatewayInfo/index.js +8 -6
- package/src/screens/AllGateway/GatewayWifi/__test__/index.test.js +319 -0
- package/src/screens/AllGateway/GatewayWifi/index.js +107 -0
- package/src/screens/AllGateway/Successfully/__test__/index.test.js +77 -0
- package/src/screens/AllGateway/Successfully/index.js +66 -0
- package/src/screens/AllGateway/Successfully/styles.js +35 -0
- package/src/screens/AllGateway/components/Information/index.js +17 -1
- package/src/screens/AllGateway/components/RowItem/index.js +12 -1
- package/src/screens/AllGateway/hooks/__test__/index.test.js +18 -0
- package/src/screens/AllGateway/hooks/useGateway.js +13 -0
- package/src/screens/Automate/AddNewAction/SetupConfigCondition.js +3 -3
- package/src/screens/Automate/AddNewAction/SetupScriptEmail.js +79 -0
- package/src/screens/Automate/AddNewAction/SetupScriptReceiverEmail.js +166 -0
- package/src/screens/Automate/AddNewAction/Styles/SetupScriptEmailStyles.js +37 -0
- package/src/screens/Automate/AddNewAction/Styles/SetupScriptReceiverEmailStyles.js +79 -0
- package/src/screens/Automate/AddNewAction/__test__/ChooseAction.test.js +1 -1
- package/src/screens/Automate/AddNewAction/__test__/SetupConfigCondition.test.js +13 -5
- package/src/screens/Automate/AddNewAction/__test__/SetupScriptEmail.test.js +76 -0
- package/src/screens/Automate/AddNewAction/__test__/SetupScriptReceiverEmail.test.js +105 -0
- package/src/screens/Automate/EditActionsList/Styles/UpdateReceiverEmailScriptStyles.js +78 -0
- package/src/screens/Automate/EditActionsList/UpdateEmailScript.js +80 -0
- package/src/screens/Automate/EditActionsList/UpdateReceiverEmailScript.js +179 -0
- package/src/screens/Automate/EditActionsList/__tests__/UpdateEmailScript.test.js +81 -0
- package/src/screens/Automate/EditActionsList/__tests__/UpdateReceiverEmailScript.test.js +83 -0
- package/src/screens/Automate/EditActionsList/__tests__/index.test.js +38 -5
- package/src/screens/Automate/EditActionsList/index.js +59 -2
- package/src/screens/Automate/ScriptDetail/Components/AddActionScript.js +20 -0
- package/src/screens/Automate/ScriptDetail/Styles/indexStyles.js +5 -3
- package/src/screens/Automate/ScriptDetail/__test__/index.test.js +127 -21
- package/src/screens/Automate/ScriptDetail/index.js +57 -14
- package/src/screens/Device/__test__/sensorDisplayItem.test.js +22 -0
- package/src/screens/Device/components/SensorDisplayItem.js +10 -0
- package/src/screens/SharedUnit/index.js +2 -2
- package/src/screens/Sharing/SelectUser.js +47 -47
- package/src/screens/Sharing/__test__/SelectUser.test.js +57 -103
- package/src/screens/SubUnit/ManageSubUnit.js +94 -90
- package/src/screens/SubUnit/ManageSubUnitStyles.js +4 -6
- package/src/screens/SubUnit/RearrageSubUnit.js +90 -0
- package/src/screens/SubUnit/RearrrageSubUnitStyle.js +65 -0
- package/src/screens/SubUnit/__test__/ManageSubUnit.test.js +35 -19
- package/src/screens/SubUnit/__test__/RearrangeSubUnit.test.js +129 -0
- package/src/screens/SubUnit/hooks/__test__/useManageSubUnit.test.js +6 -7
- package/src/screens/SubUnit/hooks/useManageSubUnit.js +8 -16
- package/src/screens/Unit/Detail.js +2 -6
- package/src/screens/Unit/ManageUnit.js +1 -1
- package/src/utils/Functions/__test__/ShortEmail.test.js +5 -0
- package/src/utils/I18n/translations/en.js +46 -8
- package/src/utils/I18n/translations/vi.js +37 -4
- package/src/utils/Route/index.js +7 -0
- package/src/commons/Auth/__test__/AccountItem.test.js +0 -31
- package/src/hooks/Common/useBlockBackAndroid.js +0 -21
- package/src/screens/SubUnit/DetailStyles.js +0 -46
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import React, { memo, useCallback, useMemo, useState } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
FlatList,
|
|
5
|
+
TouchableOpacity,
|
|
6
|
+
ActivityIndicator,
|
|
7
|
+
Platform,
|
|
8
|
+
} from 'react-native';
|
|
9
|
+
import LottieView from 'lottie-react-native';
|
|
10
|
+
import WifiIcon from '../../../assets/images/wifi.svg';
|
|
11
|
+
import WifiOpenIcon from '../../../assets/images/wifi-open.svg';
|
|
12
|
+
import { HeaderCustom, FullLoading, ButtonPopup, Text } from '../../commons';
|
|
13
|
+
import _TextInput from '../Form/TextInput';
|
|
14
|
+
import _TextInputPassword from '../Form/TextInputPassword';
|
|
15
|
+
import AccessibilityLabel from '../../configs/AccessibilityLabel';
|
|
16
|
+
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
17
|
+
import { Colors } from '../../configs';
|
|
18
|
+
import { ToastBottomHelper } from '../../utils/Utils';
|
|
19
|
+
import LoadingCircle from '../../Images/Common/loading-circle.json';
|
|
20
|
+
import styles from './styles';
|
|
21
|
+
|
|
22
|
+
const ConnectWifi = ({
|
|
23
|
+
title,
|
|
24
|
+
wifiList,
|
|
25
|
+
onConnect,
|
|
26
|
+
onGoBack,
|
|
27
|
+
isShowLoading,
|
|
28
|
+
setIsShowLoading,
|
|
29
|
+
}) => {
|
|
30
|
+
const t = useTranslations();
|
|
31
|
+
|
|
32
|
+
const [isOther, setIsOther] = useState(false);
|
|
33
|
+
const [isOpenWifi, setIsOpenWifi] = useState(false);
|
|
34
|
+
const [isShowPopupPassword, setIsShowPopupPassword] = useState(false);
|
|
35
|
+
|
|
36
|
+
const [wifiSsid, setWifiSsid] = useState('');
|
|
37
|
+
const [wifiPassword, setWifiPassword] = useState('');
|
|
38
|
+
|
|
39
|
+
const hidePopupPassword = useCallback(() => {
|
|
40
|
+
setIsShowPopupPassword(false);
|
|
41
|
+
}, []);
|
|
42
|
+
|
|
43
|
+
const handleSelectWifi = useCallback((item) => {
|
|
44
|
+
setWifiSsid(item.ssid);
|
|
45
|
+
setWifiPassword('');
|
|
46
|
+
setIsOther(false);
|
|
47
|
+
setIsOpenWifi(item?.encryption === 'OPEN');
|
|
48
|
+
setIsShowPopupPassword(true);
|
|
49
|
+
}, []);
|
|
50
|
+
|
|
51
|
+
const handleOtherOption = useCallback(() => {
|
|
52
|
+
setWifiSsid('');
|
|
53
|
+
setWifiPassword('');
|
|
54
|
+
setIsOther(true);
|
|
55
|
+
setIsOpenWifi(false);
|
|
56
|
+
setIsShowPopupPassword(true);
|
|
57
|
+
}, []);
|
|
58
|
+
|
|
59
|
+
const onConnectWifi = useCallback(() => {
|
|
60
|
+
if (!onConnect) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!wifiSsid) {
|
|
65
|
+
ToastBottomHelper.error(t('please_enter_wifi_name'));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (!isOpenWifi && !isOther && !wifiPassword) {
|
|
69
|
+
ToastBottomHelper.error(t('please_enter_wifi_password'));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (wifiPassword && wifiPassword.length < 8) {
|
|
73
|
+
ToastBottomHelper.error(t('password_must_be_at_least_8_characters'));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
setIsShowLoading(true);
|
|
78
|
+
setIsShowPopupPassword(false);
|
|
79
|
+
|
|
80
|
+
onConnect({ wifiSsid, wifiPassword });
|
|
81
|
+
}, [
|
|
82
|
+
onConnect,
|
|
83
|
+
wifiSsid,
|
|
84
|
+
wifiPassword,
|
|
85
|
+
isOpenWifi,
|
|
86
|
+
isOther,
|
|
87
|
+
setIsShowLoading,
|
|
88
|
+
t,
|
|
89
|
+
]);
|
|
90
|
+
|
|
91
|
+
const wifiListWithOther = useMemo(
|
|
92
|
+
() => [...wifiList, { ssid: `${t('other')}...`, isOther: true }],
|
|
93
|
+
[wifiList, t]
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
const renderItem = useCallback(
|
|
97
|
+
({ item }) => (
|
|
98
|
+
<TouchableOpacity
|
|
99
|
+
onPress={() =>
|
|
100
|
+
item.isOther ? handleOtherOption() : handleSelectWifi(item)
|
|
101
|
+
}
|
|
102
|
+
accessibilityLabel={`${AccessibilityLabel.SELECT_WIFI}-${
|
|
103
|
+
item.isOther ? 'other' : item.ssid
|
|
104
|
+
}`}
|
|
105
|
+
>
|
|
106
|
+
<View style={styles.listItem}>
|
|
107
|
+
<View style={styles.textItem}>
|
|
108
|
+
<Text type="H4">{item.ssid}</Text>
|
|
109
|
+
</View>
|
|
110
|
+
{!item.isOther && (
|
|
111
|
+
<View style={styles.wifiIcon}>
|
|
112
|
+
{item?.encryption === 'OPEN' ? <WifiOpenIcon /> : <WifiIcon />}
|
|
113
|
+
</View>
|
|
114
|
+
)}
|
|
115
|
+
</View>
|
|
116
|
+
</TouchableOpacity>
|
|
117
|
+
),
|
|
118
|
+
[handleSelectWifi, handleOtherOption]
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<View style={styles.container}>
|
|
123
|
+
<HeaderCustom onGoBack={onGoBack} title={t(title)} isShowSeparator />
|
|
124
|
+
|
|
125
|
+
<View style={styles.rowContainer}>
|
|
126
|
+
<Text style={styles.subTitle} type="Body">
|
|
127
|
+
{t('select_network')}
|
|
128
|
+
</Text>
|
|
129
|
+
{!wifiList.length && (
|
|
130
|
+
<ActivityIndicator style={styles.containerLoading} />
|
|
131
|
+
)}
|
|
132
|
+
</View>
|
|
133
|
+
|
|
134
|
+
<FlatList
|
|
135
|
+
style={styles.listContainer}
|
|
136
|
+
keyExtractor={(item, index) => `${item.ssid}-${index}`}
|
|
137
|
+
data={wifiListWithOther}
|
|
138
|
+
renderItem={renderItem}
|
|
139
|
+
extraData={wifiListWithOther}
|
|
140
|
+
numColumns={1}
|
|
141
|
+
/>
|
|
142
|
+
|
|
143
|
+
<ButtonPopup
|
|
144
|
+
accessibilityLabel={AccessibilityLabel.GATEWAY_WIFI_LIST.BUTTON_POPUP}
|
|
145
|
+
visible={isShowPopupPassword}
|
|
146
|
+
mainTitle={t('connect')}
|
|
147
|
+
onPressMain={onConnectWifi}
|
|
148
|
+
secondaryTitle={t('cancel')}
|
|
149
|
+
typeSecondary={'cancel'}
|
|
150
|
+
onPressSecondary={hidePopupPassword}
|
|
151
|
+
hideClose
|
|
152
|
+
avoidKeyboard={Platform.OS === 'ios'}
|
|
153
|
+
>
|
|
154
|
+
<Text type="H3" semibold>
|
|
155
|
+
{isOther
|
|
156
|
+
? t('enter_wifi_name_password')
|
|
157
|
+
: isOpenWifi
|
|
158
|
+
? `${t('connect_to_wifi')} '${wifiSsid}'`
|
|
159
|
+
: `${t('enter_wifi_password')} '${wifiSsid}'`}
|
|
160
|
+
</Text>
|
|
161
|
+
{isOther && (
|
|
162
|
+
<_TextInput
|
|
163
|
+
placeholder={t('wifi_name')}
|
|
164
|
+
onChange={setWifiSsid}
|
|
165
|
+
value={wifiSsid}
|
|
166
|
+
textInputStyle={styles.input}
|
|
167
|
+
selectionColor={Colors.Primary}
|
|
168
|
+
autoFocus
|
|
169
|
+
/>
|
|
170
|
+
)}
|
|
171
|
+
{!isOpenWifi && (
|
|
172
|
+
<_TextInputPassword
|
|
173
|
+
secureTextEntry
|
|
174
|
+
placeholder={t('password')}
|
|
175
|
+
onChange={setWifiPassword}
|
|
176
|
+
value={wifiPassword}
|
|
177
|
+
textInputStyle={styles.input}
|
|
178
|
+
selectionColor={Colors.Primary}
|
|
179
|
+
autoFocus={!isOther}
|
|
180
|
+
/>
|
|
181
|
+
)}
|
|
182
|
+
</ButtonPopup>
|
|
183
|
+
|
|
184
|
+
{isShowLoading && (
|
|
185
|
+
<FullLoading
|
|
186
|
+
styleBackground={styles.backgroundLoading}
|
|
187
|
+
customIcon={
|
|
188
|
+
<LottieView
|
|
189
|
+
source={LoadingCircle}
|
|
190
|
+
autoPlay
|
|
191
|
+
loop
|
|
192
|
+
style={styles.loading}
|
|
193
|
+
/>
|
|
194
|
+
}
|
|
195
|
+
/>
|
|
196
|
+
)}
|
|
197
|
+
</View>
|
|
198
|
+
);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
export default memo(ConnectWifi);
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
import { Colors } from '../../configs';
|
|
3
|
+
|
|
4
|
+
export default StyleSheet.create({
|
|
5
|
+
container: {
|
|
6
|
+
flex: 1,
|
|
7
|
+
backgroundColor: Colors.Gray2,
|
|
8
|
+
},
|
|
9
|
+
rowContainer: {
|
|
10
|
+
flexDirection: 'row',
|
|
11
|
+
alignItems: 'center',
|
|
12
|
+
},
|
|
13
|
+
title: {
|
|
14
|
+
marginVertical: 16,
|
|
15
|
+
marginLeft: 16,
|
|
16
|
+
},
|
|
17
|
+
subTitle: {
|
|
18
|
+
fontSize: 14,
|
|
19
|
+
lineHeight: 22,
|
|
20
|
+
marginTop: 16,
|
|
21
|
+
marginLeft: 16,
|
|
22
|
+
marginBottom: 16,
|
|
23
|
+
},
|
|
24
|
+
listContainer: {
|
|
25
|
+
flex: 1,
|
|
26
|
+
borderWidth: 1,
|
|
27
|
+
backgroundColor: Colors.White,
|
|
28
|
+
borderRadius: 20,
|
|
29
|
+
borderColor: Colors.Gray4,
|
|
30
|
+
},
|
|
31
|
+
listItem: {
|
|
32
|
+
flex: 1,
|
|
33
|
+
flexDirection: 'row',
|
|
34
|
+
justifyContent: 'space-between',
|
|
35
|
+
alignItems: 'center',
|
|
36
|
+
borderBottomColor: Colors.Gray4,
|
|
37
|
+
borderBottomWidth: 1,
|
|
38
|
+
paddingVertical: 16,
|
|
39
|
+
marginRight: 24,
|
|
40
|
+
marginLeft: 16,
|
|
41
|
+
},
|
|
42
|
+
textItem: {
|
|
43
|
+
flex: 1,
|
|
44
|
+
height: 'auto',
|
|
45
|
+
paddingLeft: 16,
|
|
46
|
+
},
|
|
47
|
+
wifiIcon: {
|
|
48
|
+
paddingRight: 16,
|
|
49
|
+
},
|
|
50
|
+
loading: {
|
|
51
|
+
width: 40,
|
|
52
|
+
height: 40,
|
|
53
|
+
},
|
|
54
|
+
backgroundLoading: {
|
|
55
|
+
backgroundColor: Colors.Gray21,
|
|
56
|
+
},
|
|
57
|
+
containerLoading: {
|
|
58
|
+
flex: 1,
|
|
59
|
+
justifyContent: 'center',
|
|
60
|
+
alignItems: 'flex-start',
|
|
61
|
+
marginLeft: 16,
|
|
62
|
+
},
|
|
63
|
+
input: {
|
|
64
|
+
height: 45,
|
|
65
|
+
borderWidth: 1,
|
|
66
|
+
padding: 20,
|
|
67
|
+
borderColor: Colors.Gray5,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import renderer, { act } from 'react-test-renderer';
|
|
3
|
+
import * as Progress from 'react-native-progress';
|
|
4
|
+
import LabelValue from '..';
|
|
5
|
+
import Text from '../../../Text';
|
|
6
|
+
|
|
7
|
+
describe('Test LabelValue', () => {
|
|
8
|
+
let tree;
|
|
9
|
+
let item;
|
|
10
|
+
let data;
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
item = {
|
|
13
|
+
label: 'Distance',
|
|
14
|
+
configuration: {
|
|
15
|
+
align: 'align_left',
|
|
16
|
+
color: '#eb144c',
|
|
17
|
+
min_value: 0,
|
|
18
|
+
max_value: 100,
|
|
19
|
+
status_bar: true,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
data = [{ value: 10, unit: 'm' }];
|
|
23
|
+
});
|
|
24
|
+
it('render LabelValue', async () => {
|
|
25
|
+
await act(async () => {
|
|
26
|
+
tree = await renderer.create(
|
|
27
|
+
<LabelValue item={item} data={data} isWidgetOrder={false} />
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
const instance = tree.root;
|
|
31
|
+
const texts = instance.findAllByType(Text);
|
|
32
|
+
const progressBar = instance.findByType(Progress.Bar);
|
|
33
|
+
|
|
34
|
+
expect(texts[0].props.children).toEqual('Distance');
|
|
35
|
+
expect(texts[1].props.children).toEqual('10 m');
|
|
36
|
+
expect(texts[1].props.style.alignSelf).toEqual('flex-start');
|
|
37
|
+
expect(progressBar.props.color).toEqual('#eb144c');
|
|
38
|
+
expect(progressBar.props.progress).toEqual(0.1);
|
|
39
|
+
});
|
|
40
|
+
it('render LabelValue with invalid data, align right', async () => {
|
|
41
|
+
item.configuration.align = 'align_right';
|
|
42
|
+
await act(async () => {
|
|
43
|
+
tree = await renderer.create(
|
|
44
|
+
<LabelValue item={item} isWidgetOrder={false} />
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
const instance = tree.root;
|
|
48
|
+
const texts = instance.findAllByType(Text);
|
|
49
|
+
const progressBar = instance.findByType(Progress.Bar);
|
|
50
|
+
|
|
51
|
+
expect(texts[0].props.children).toEqual('Distance');
|
|
52
|
+
expect(texts[1].props.children).toEqual('-- ');
|
|
53
|
+
expect(texts[1].props.style.alignSelf).toEqual('flex-end');
|
|
54
|
+
expect(progressBar.props.color).toEqual('#eb144c');
|
|
55
|
+
expect(progressBar.props.progress).toEqual(0);
|
|
56
|
+
});
|
|
57
|
+
it('render LabelValue with status bar false, align middle', async () => {
|
|
58
|
+
item.configuration.status_bar = false;
|
|
59
|
+
item.configuration.align = 'align_middle';
|
|
60
|
+
await act(async () => {
|
|
61
|
+
tree = await renderer.create(
|
|
62
|
+
<LabelValue item={item} data={data} isWidgetOrder={true} />
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
const instance = tree.root;
|
|
66
|
+
const texts = instance.findAllByType(Text);
|
|
67
|
+
const progressBar = instance.findAllByType(Progress.Bar);
|
|
68
|
+
|
|
69
|
+
expect(texts[0].props.children).toEqual('Distance');
|
|
70
|
+
expect(texts[1].props.children).toEqual('10 m');
|
|
71
|
+
expect(texts[1].props.style.alignSelf).toEqual('center');
|
|
72
|
+
expect(progressBar.length).toEqual(0);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React, { memo } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import * as Progress from 'react-native-progress';
|
|
4
|
+
|
|
5
|
+
import { Colors } from '../../../configs';
|
|
6
|
+
import Text from '../../Text';
|
|
7
|
+
import styles from './styles';
|
|
8
|
+
|
|
9
|
+
const LabelValue = memo(({ data = [], item, isWidgetOrder }) => {
|
|
10
|
+
const {
|
|
11
|
+
configuration: { align, color, max_value, min_value, status_bar },
|
|
12
|
+
label,
|
|
13
|
+
} = item;
|
|
14
|
+
const { value, unit = '' } = data.length ? data[0] : {};
|
|
15
|
+
const percent = ((value ?? min_value) - min_value) / (max_value - min_value);
|
|
16
|
+
const alignValueText =
|
|
17
|
+
align === 'align_middle'
|
|
18
|
+
? 'center'
|
|
19
|
+
: align === 'align_left'
|
|
20
|
+
? 'flex-start'
|
|
21
|
+
: 'flex-end';
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<View style={[styles.container, isWidgetOrder && styles.wrapOrderItem]}>
|
|
25
|
+
<Text type="H3" semibold color={Colors.Gray9} style={styles.textLabel}>
|
|
26
|
+
{label}
|
|
27
|
+
</Text>
|
|
28
|
+
<Text
|
|
29
|
+
bold
|
|
30
|
+
type="H1"
|
|
31
|
+
style={{ ...styles.textValue, alignSelf: alignValueText }}
|
|
32
|
+
>
|
|
33
|
+
{`${value ?? '--'} ${unit}`}
|
|
34
|
+
</Text>
|
|
35
|
+
{!!status_bar && (
|
|
36
|
+
<Progress.Bar
|
|
37
|
+
style={styles.progressBar}
|
|
38
|
+
width={null}
|
|
39
|
+
height={8}
|
|
40
|
+
unfilledColor={Colors.Gray4}
|
|
41
|
+
progress={percent}
|
|
42
|
+
color={color}
|
|
43
|
+
/>
|
|
44
|
+
)}
|
|
45
|
+
</View>
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export default LabelValue;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
|
|
3
|
+
import { Colors } from '../../../configs';
|
|
4
|
+
|
|
5
|
+
export default StyleSheet.create({
|
|
6
|
+
container: {
|
|
7
|
+
flexDirection: 'column',
|
|
8
|
+
justifyContent: 'center',
|
|
9
|
+
marginLeft: 15,
|
|
10
|
+
marginRight: 15,
|
|
11
|
+
marginBottom: 10,
|
|
12
|
+
padding: 5,
|
|
13
|
+
borderRadius: 10,
|
|
14
|
+
borderWidth: 1,
|
|
15
|
+
borderColor: Colors.Gray4,
|
|
16
|
+
borderStyle: 'solid',
|
|
17
|
+
},
|
|
18
|
+
wrapOrderItem: {
|
|
19
|
+
marginBottom: 0,
|
|
20
|
+
},
|
|
21
|
+
textLabel: {
|
|
22
|
+
marginLeft: 8,
|
|
23
|
+
marginTop: 8,
|
|
24
|
+
},
|
|
25
|
+
textValue: {
|
|
26
|
+
margin: 8,
|
|
27
|
+
},
|
|
28
|
+
progressBar: {
|
|
29
|
+
borderWidth: 0,
|
|
30
|
+
borderRadius: 10,
|
|
31
|
+
marginHorizontal: 8,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
@@ -16,10 +16,14 @@ const ActionItem = ({
|
|
|
16
16
|
item,
|
|
17
17
|
}) => {
|
|
18
18
|
const handleSelectAction = useCallback(() => {
|
|
19
|
-
let actionData =
|
|
19
|
+
let actionData = { value: is_on_value };
|
|
20
20
|
const { allow_config_store_value, config, is_on_value } = item;
|
|
21
21
|
if (allow_config_store_value && config) {
|
|
22
|
-
actionData = {
|
|
22
|
+
actionData = {
|
|
23
|
+
config_id: config,
|
|
24
|
+
config_value: is_on_value,
|
|
25
|
+
value: is_on_value,
|
|
26
|
+
};
|
|
23
27
|
}
|
|
24
28
|
setActionName(item.text);
|
|
25
29
|
|
package/src/configs/API.js
CHANGED
|
@@ -42,6 +42,8 @@ const API = {
|
|
|
42
42
|
CREATE_SUB_UNIT: (unitId) => `/property_manager/${unitId}/sub_units/`,
|
|
43
43
|
MANAGE_SUB_UNIT: (unitId, id) =>
|
|
44
44
|
`/property_manager/${unitId}/sub_units/${id}/`,
|
|
45
|
+
ORDER_SUB_UNITS: (unitId) =>
|
|
46
|
+
`/property_manager/${unitId}/sub_units/order_sub_units/`,
|
|
45
47
|
},
|
|
46
48
|
CHIP: {
|
|
47
49
|
GET_CHIPS_FROM_UNIT: (id) => `/property_manager/get_chips/?unit_id=${id}`,
|
|
@@ -103,12 +105,16 @@ const API = {
|
|
|
103
105
|
`/property_manager/automate/${automateId}/update_script_notify/`,
|
|
104
106
|
UPDATE_SCRIPT_ACTION: (automateId) =>
|
|
105
107
|
`/property_manager/automate/${automateId}/update_script_action/`,
|
|
108
|
+
UPDATE_SCRIPT_EMAIL: (automateId) =>
|
|
109
|
+
`/property_manager/automate/${automateId}/update_script_email/`,
|
|
106
110
|
ADD_SCRIPT_ACTION: (id) =>
|
|
107
111
|
`/property_manager/automate/${id}/add_script_action/`,
|
|
108
112
|
ADD_SCRIPT_NOTIFY: (id) =>
|
|
109
113
|
`/property_manager/automate/${id}/add_script_notify/`,
|
|
110
114
|
ADD_SCRIPT_DELAY: (id) =>
|
|
111
115
|
`/property_manager/automate/${id}/add_script_delay/`,
|
|
116
|
+
ADD_SCRIPT_EMAIL: (id) =>
|
|
117
|
+
`/property_manager/automate/${id}/add_script_email/`,
|
|
112
118
|
|
|
113
119
|
FETCH_AUTOMATE: (automateId) => `/property_manager/automate/${automateId}/`,
|
|
114
120
|
CREATE_AUTOMATE: () => '/property_manager/automate/',
|
|
@@ -144,6 +150,9 @@ const API = {
|
|
|
144
150
|
UNIT_MEMBER_SHARE_DEVICE: (unit_id, member_id) =>
|
|
145
151
|
`/property_manager/sharing/units/${unit_id}/member/${member_id}/shared_devices/`,
|
|
146
152
|
SHARE: () => '/property_manager/sharing/share/',
|
|
153
|
+
SHARE_V2: () => '/property_manager/sharing/share_v2/',
|
|
154
|
+
SEARCH_USER_BY_PHONE: (phone) => `/accounts/search/phone/${phone}/`,
|
|
155
|
+
SEARCH_USER_BY_EMAIL: (email) => `/accounts/search/email/${email}/`,
|
|
147
156
|
},
|
|
148
157
|
EMERGENCY_BUTTON: {
|
|
149
158
|
CREATE_CONTACT: () => '/emergency_button/contacts/',
|
|
@@ -257,6 +266,9 @@ const API = {
|
|
|
257
266
|
ACTION: (gatewayId, deviceId) =>
|
|
258
267
|
`/iot/modules/zigbee/gateways/${gatewayId}/devices/${deviceId}/zigbee_actions/`,
|
|
259
268
|
},
|
|
269
|
+
CHIP_QR_CODE: {
|
|
270
|
+
DETAIL_BY_SECRET: () => '/chip_manager/chip_qr_code/by_secret/',
|
|
271
|
+
},
|
|
260
272
|
MODBUS: {
|
|
261
273
|
DETAIL: (id) => `/iot/modules/modbus/gateways/${id}/`,
|
|
262
274
|
DEVICE: (gatewayId) =>
|
|
@@ -115,6 +115,7 @@ export default {
|
|
|
115
115
|
SUB_UNIT_FAVORITES: 'SUB_UNIT_FAVORITES',
|
|
116
116
|
ANIMATED_SCROLL: 'ANIMATED_SCROLL',
|
|
117
117
|
ADD_SUB_UNIT: 'ADD_SUB_UNIT',
|
|
118
|
+
REARRANGE_SUB_UNIT: 'REARRANGE_SUB_UNIT',
|
|
118
119
|
|
|
119
120
|
// NavBar
|
|
120
121
|
NAVBAR_ICON_BARS: 'NAVBAR_ICON_BARS',
|
|
@@ -454,8 +455,13 @@ export default {
|
|
|
454
455
|
SELECT_UNIT: 'SELECT_UNIT',
|
|
455
456
|
SELECT_MEMBER_UNIT: 'SELECT_MEMBER_UNIT',
|
|
456
457
|
|
|
458
|
+
// Select device
|
|
459
|
+
SELECT_DEVICE: 'SELECT_DEVICE',
|
|
460
|
+
SELECT_RADIO_DEVICE: 'SELECT_RADIO_DEVICE',
|
|
461
|
+
|
|
457
462
|
// select wifi
|
|
458
463
|
SELECT_WIFI: 'SELECT_WIFI',
|
|
464
|
+
CHANGE_WIFI: 'CHANGE_WIFI',
|
|
459
465
|
|
|
460
466
|
SHARED_UNIT: 'SHARED_UNIT',
|
|
461
467
|
|
|
@@ -467,6 +473,7 @@ export default {
|
|
|
467
473
|
MANAGE_UNIT: 'MANAGE_UNIT',
|
|
468
474
|
MANAGE_UNIT_ALERT: 'MANAGE_UNIT_ALERT',
|
|
469
475
|
SELECT_UNIT: 'SELECT_UNIT',
|
|
476
|
+
SELECT_DEVICE: 'SELECT_DEVICE',
|
|
470
477
|
BUTTON_ADD_AUTO_SMART: 'BUTTON_ADD_AUTO_SMART',
|
|
471
478
|
BUTTON_CONNECT_WIFI: 'BUTTON_CONNECT_WIFI',
|
|
472
479
|
BUTTON_BOTTOM_SMART_ACCOUNT: 'BUTTON_BOTTOM_SMART_ACCOUNT',
|
package/src/configs/Constants.js
CHANGED
|
@@ -4,7 +4,7 @@ import useForceUpdate from './useForceUpdate';
|
|
|
4
4
|
import useKeyboardShow from './useKeyboardShow';
|
|
5
5
|
import usePopover from './usePopover';
|
|
6
6
|
import useDevicesStatus from './useDevicesStatus';
|
|
7
|
-
import {
|
|
7
|
+
import { useBlockBack } from './useBlockBack';
|
|
8
8
|
import { useIsOwnerOfUnit } from './useIsOwnerOfUnit';
|
|
9
9
|
import { useStatusBar } from './useStatusBar';
|
|
10
10
|
import { useGetIdUser } from './useGetIdUser';
|
|
@@ -15,7 +15,7 @@ export {
|
|
|
15
15
|
useForceUpdate,
|
|
16
16
|
useKeyboardShow,
|
|
17
17
|
usePopover,
|
|
18
|
-
|
|
18
|
+
useBlockBack,
|
|
19
19
|
useIsOwnerOfUnit,
|
|
20
20
|
useStatusBar,
|
|
21
21
|
useGetIdUser,
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { useFocusEffect, useNavigation } from '@react-navigation/native';
|
|
2
|
+
import { useCallback, useRef } from 'react';
|
|
3
|
+
import { BackHandler } from 'react-native';
|
|
4
|
+
|
|
5
|
+
export const useBlockBack = (actionBack) => {
|
|
6
|
+
const navigation = useNavigation();
|
|
7
|
+
const isBeforeRemoveHandled = useRef(false);
|
|
8
|
+
|
|
9
|
+
const blockBack = useCallback(() => {
|
|
10
|
+
actionBack && actionBack();
|
|
11
|
+
return true;
|
|
12
|
+
}, [actionBack]);
|
|
13
|
+
|
|
14
|
+
useFocusEffect(
|
|
15
|
+
useCallback(() => {
|
|
16
|
+
const onBeforeRemove = (e) => {
|
|
17
|
+
if (!isBeforeRemoveHandled.current) {
|
|
18
|
+
isBeforeRemoveHandled.current = true;
|
|
19
|
+
e.preventDefault();
|
|
20
|
+
blockBack();
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
BackHandler.addEventListener('hardwareBackPress', blockBack);
|
|
25
|
+
const unsubscribe = navigation.addListener(
|
|
26
|
+
'beforeRemove',
|
|
27
|
+
onBeforeRemove
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
return () => {
|
|
31
|
+
BackHandler.removeEventListener('hardwareBackPress', blockBack);
|
|
32
|
+
unsubscribe();
|
|
33
|
+
};
|
|
34
|
+
}, [blockBack, navigation])
|
|
35
|
+
);
|
|
36
|
+
};
|
package/src/hooks/useMqtt.js
CHANGED
|
@@ -27,15 +27,20 @@ const useChipJsonConfiguration = (dashboardId) => {
|
|
|
27
27
|
};
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
const { code, mqtt_server } = chip;
|
|
33
|
-
const { websocket_host, websocket_port } = mqtt_server;
|
|
34
|
-
|
|
30
|
+
export const connectMqttServer = (mqttServer, code) => {
|
|
31
|
+
const { websocket_host, websocket_port } = mqttServer;
|
|
35
32
|
const client = mqtt.connect(`wss://${websocket_host}:${websocket_port}`, {
|
|
36
33
|
username: code,
|
|
37
34
|
password: code,
|
|
38
35
|
});
|
|
36
|
+
return client;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const connectChipMqtt = (chip) => {
|
|
40
|
+
const configById = {};
|
|
41
|
+
const { code, mqtt_server } = chip;
|
|
42
|
+
|
|
43
|
+
const client = connectMqttServer(mqtt_server, code);
|
|
39
44
|
|
|
40
45
|
(chip?.sensors).forEach((sensor) => {
|
|
41
46
|
(sensor?.configs).forEach((config) => {
|
|
@@ -19,6 +19,7 @@ import ShareWifiPassword from '../screens/AddNewGateway/ShareWifiPassword';
|
|
|
19
19
|
import ScanGatewayQR from '../screens/AddNewGateway/ScanGatewayQR';
|
|
20
20
|
import RenameNewDevices from '../screens/AddNewGateway/RenameNewDevices';
|
|
21
21
|
import ConnectingWifiGuide from '../screens/AddNewGateway/ConnectingWifiGuide';
|
|
22
|
+
import ScanDeviceLocal from '../screens/AddNewGateway/ScanDeviceLocal';
|
|
22
23
|
import ZigbeeDeviceConnectGuide from '../screens/AddNewGateway/PlugAndPlay/ZigbeeDeviceConnectGuide';
|
|
23
24
|
|
|
24
25
|
const Stack = createNativeStackNavigator();
|
|
@@ -87,6 +88,7 @@ export const AddGatewayStack = memo(() => {
|
|
|
87
88
|
name={Route.ZigbeeDeviceConnectGuide}
|
|
88
89
|
component={ZigbeeDeviceConnectGuide}
|
|
89
90
|
/>
|
|
91
|
+
<Stack.Screen name={Route.ScanDeviceLocal} component={ScanDeviceLocal} />
|
|
90
92
|
</Stack.Navigator>
|
|
91
93
|
);
|
|
92
94
|
});
|
|
@@ -3,6 +3,8 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
|
|
3
3
|
|
|
4
4
|
import GatewayDetail from '../screens/AllGateway/GatewayDetail';
|
|
5
5
|
import GatewayInfo from '../screens/AllGateway/GatewayInfo';
|
|
6
|
+
import GatewayWifi from '../screens/AllGateway/GatewayWifi';
|
|
7
|
+
import Successfully from '../screens/AllGateway/Successfully';
|
|
6
8
|
import GatewayConnectionMethods from '../screens/AllGateway/GatewayConnectionMethods';
|
|
7
9
|
import DeviceZigbeeDetail from '../screens/AllGateway/DeviceZigbeeDetail';
|
|
8
10
|
import DeviceInternalDetail from '../screens/AllGateway/DeviceInternalDetail';
|
|
@@ -27,6 +29,8 @@ export const AllGatewayStack = memo(() => {
|
|
|
27
29
|
>
|
|
28
30
|
<Stack.Screen component={GatewayDetail} name={Route.GatewayDetail} />
|
|
29
31
|
<Stack.Screen component={GatewayInfo} name={Route.GatewayInfo} />
|
|
32
|
+
<Stack.Screen component={GatewayWifi} name={Route.GatewayWifi} />
|
|
33
|
+
<Stack.Screen component={Successfully} name={Route.Successfully} />
|
|
30
34
|
<Stack.Screen
|
|
31
35
|
component={DeviceGatewayInfo}
|
|
32
36
|
name={Route.DeviceGatewayInfo}
|
package/src/navigations/Main.js
CHANGED
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
// import DeviceModbusDetail from '../screens/Gateway/DeviceModbusDetail';
|
|
37
37
|
// import DetailConfigActionModbus from '../screens/Gateway/DetailConfigActionModbus';
|
|
38
38
|
// import DetailChildConfigActionModbus from '../screens/Gateway/DetailConfigActionModbus';
|
|
39
|
-
// import {
|
|
39
|
+
// import { useBlockBack } from '../hooks/Common';
|
|
40
40
|
|
|
41
41
|
// const Tab = createBottomTabNavigator();
|
|
42
42
|
// const Drawer = createDrawerNavigator();
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
// };
|
|
122
122
|
|
|
123
123
|
// const DrawerScreen = () => {
|
|
124
|
-
//
|
|
124
|
+
// useBlockBack();
|
|
125
125
|
// return (
|
|
126
126
|
// <Drawer.Navigator
|
|
127
127
|
// backBehavior="none"
|