@eohjsc/react-native-smart-city 0.2.93 → 0.2.96
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/Device/air-dry.svg +3 -0
- package/assets/images/Device/auto.svg +3 -0
- package/assets/images/Device/circulator.svg +4 -0
- package/assets/images/Device/clean.svg +5 -0
- package/package.json +2 -2
- package/src/Images/Common/member.svg +4 -0
- package/src/Images/Common/owner.svg +3 -0
- package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +5 -1
- package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +5 -1
- package/src/commons/ActionGroup/StatesGridActionTemplate.js +42 -36
- package/src/commons/ActionGroup/StatesGridActionTemplateStyle.js +5 -10
- package/src/commons/ActionGroup/__test__/OptionsDropdownTemplate.test.js +2 -2
- package/src/commons/Connecting /__test__/Connecting.test.js +23 -0
- package/src/commons/Connecting /index.js +67 -0
- package/src/commons/Connecting /styles.js +28 -0
- package/src/commons/ConnectingProcess/index.js +3 -54
- package/src/commons/Explore/SearchBox/__test__/SearchBox.test.js +19 -0
- package/src/commons/Explore/SearchBox/index.js +2 -0
- package/src/commons/MenuActionMore/index.js +10 -3
- package/src/commons/Modal/ModalCustom.js +9 -1
- package/src/commons/Sharing/MemberList.js +5 -10
- package/src/commons/Sharing/RowMember.js +128 -38
- package/src/commons/Sharing/__test__/MemberList.test.js +3 -3
- package/src/commons/Sharing/__test__/RowMember.test.js +4 -4
- package/src/configs/API.js +12 -2
- package/src/configs/Colors.js +1 -0
- package/src/configs/Constants.js +13 -0
- package/src/hooks/Common/useSensorsStatus.js +33 -23
- package/src/navigations/UnitStack.js +16 -0
- package/src/screens/AddCommon/SelectSubUnit.js +1 -0
- package/src/screens/AddCommon/__test__/SelectSubUnit.test.js +2 -0
- package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +12 -3
- package/src/screens/AddNewGateway/PlugAndPlay/FirstWarning.js +5 -1
- package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +9 -1
- package/src/screens/EditActionsList/Styles/indexStyles.js +1 -0
- package/src/screens/EmergencyContacts/EmergencyContactsList.js +1 -1
- package/src/screens/EmergencyContacts/EmergencyContactsSelectContacts.js +29 -11
- package/src/screens/EmergencyContacts/__test__/EmergencyContactList.test.js +1 -0
- package/src/screens/EmergencyContacts/__test__/EmergencyContactsSelectContacts.test.js +56 -0
- package/src/screens/EnterPassword/__test__/EnterPassword.test.js +124 -0
- package/src/screens/EnterPassword/index.js +84 -0
- package/src/screens/EnterPassword/styles.js +36 -0
- package/src/screens/MoveToAnotherSubUnit/index.js +3 -1
- package/src/screens/Sharing/Components/ItemChangeRole.js +43 -0
- package/src/screens/Sharing/Components/SensorItem.js +7 -1
- package/src/screens/Sharing/Components/Styles/ItemChangeRoleStyles.js +35 -0
- package/src/screens/Sharing/Components/__test__/ItemChangeRole.test.js +37 -0
- package/src/screens/Sharing/Components/__test__/SensorItem.test.js +53 -0
- package/src/screens/Sharing/InfoMemberUnit.js +274 -0
- package/src/screens/Sharing/MemberList.js +50 -53
- package/src/screens/Sharing/SelectPermission.js +93 -12
- package/src/screens/Sharing/Styles/inforMemberUnitStyles.js +92 -0
- package/src/screens/Sharing/__test__/InfoMemberUnit.test.js +121 -0
- package/src/screens/Sharing/__test__/MemberList.test.js +9 -24
- package/src/screens/Sharing/__test__/SelectPermission.test.js +53 -0
- package/src/screens/Sharing/hooks/index.js +76 -32
- package/src/screens/Unit/Detail.js +12 -10
- package/src/screens/Unit/ManageUnit.js +5 -5
- package/src/screens/Unit/ManageUnitStyles.js +1 -0
- package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +1 -1
- package/src/screens/UnitSummary/components/PowerConsumption/index.js +1 -1
- package/src/utils/I18n/translations/en.json +14 -2
- package/src/utils/I18n/translations/vi.json +11 -1
- package/src/utils/Route/index.js +2 -0
- package/src/utils/Utils.js +21 -0
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import React, { memo, useMemo } from 'react';
|
|
2
|
-
import { StyleSheet, View } from 'react-native';
|
|
3
|
-
import { IconOutline } from '@ant-design/icons-react-native';
|
|
2
|
+
import { StyleSheet, View, TouchableOpacity, Image } from 'react-native';
|
|
4
3
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
5
|
-
|
|
6
4
|
import { Colors } from '../../configs';
|
|
7
5
|
import Text from '../../commons/Text';
|
|
8
6
|
import { shortEmailName } from '../../utils/Utils';
|
|
9
|
-
|
|
10
|
-
import
|
|
7
|
+
import { CircleView } from '../CircleView';
|
|
8
|
+
import { useNavigation } from '@react-navigation/native';
|
|
9
|
+
import Routes from '../../utils/Route';
|
|
11
10
|
|
|
12
11
|
const arrColor = [
|
|
13
12
|
Colors.GeekBlue3,
|
|
@@ -19,46 +18,88 @@ const arrColor = [
|
|
|
19
18
|
Colors.Cyan2,
|
|
20
19
|
];
|
|
21
20
|
const RowMember = memo(
|
|
22
|
-
({
|
|
21
|
+
({
|
|
22
|
+
member,
|
|
23
|
+
index,
|
|
24
|
+
ownerId,
|
|
25
|
+
unit,
|
|
26
|
+
currentUserId,
|
|
27
|
+
type,
|
|
28
|
+
leftIcon = true,
|
|
29
|
+
rightComponent = true,
|
|
30
|
+
}) => {
|
|
23
31
|
const t = useTranslations();
|
|
24
|
-
const
|
|
25
|
-
() => ownerId === currentUserId && member.id !== ownerId,
|
|
26
|
-
[currentUserId, member.id, ownerId]
|
|
27
|
-
);
|
|
32
|
+
const { navigate } = useNavigation();
|
|
28
33
|
const [role, roleColor] = useMemo(
|
|
29
34
|
() =>
|
|
30
|
-
member
|
|
35
|
+
member?.id === ownerId
|
|
31
36
|
? [t('owner'), Colors.Primary]
|
|
32
|
-
: member
|
|
33
|
-
? [t('me'), Colors.
|
|
34
|
-
: ['',
|
|
35
|
-
[currentUserId, member
|
|
37
|
+
: member?.id === currentUserId
|
|
38
|
+
? [t('me'), Colors.Primary]
|
|
39
|
+
: [t('member'), Colors.Gray6],
|
|
40
|
+
[currentUserId, member?.id, ownerId, t]
|
|
36
41
|
);
|
|
37
|
-
const
|
|
42
|
+
const firstWordsInName = useMemo(() => {
|
|
43
|
+
const wordTemp = member?.name || shortEmailName(member?.email) || '';
|
|
44
|
+
return wordTemp?.charAt();
|
|
45
|
+
}, [member?.email, member?.name]);
|
|
46
|
+
|
|
38
47
|
if (member?.id === ownerId && member?.share_id) {
|
|
39
48
|
return null;
|
|
40
49
|
}
|
|
50
|
+
const circleColorTypes = {
|
|
51
|
+
primary: 'primary',
|
|
52
|
+
disable: 'disable',
|
|
53
|
+
noneBG: 'none',
|
|
54
|
+
};
|
|
55
|
+
const circleColor = type
|
|
56
|
+
? circleColorTypes[type]
|
|
57
|
+
: arrColor[index % arrColor.length];
|
|
58
|
+
|
|
59
|
+
const onPressInfo = () => {
|
|
60
|
+
navigate(Routes.UnitMemberInformation, {
|
|
61
|
+
member,
|
|
62
|
+
ownerId,
|
|
63
|
+
unit,
|
|
64
|
+
});
|
|
65
|
+
};
|
|
41
66
|
return (
|
|
42
67
|
<View style={styles.rowContainer}>
|
|
43
|
-
<
|
|
44
|
-
style={
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
<
|
|
60
|
-
|
|
61
|
-
|
|
68
|
+
<TouchableOpacity onPress={onPressInfo} disabled={type === 'disable'}>
|
|
69
|
+
<View style={styles.Border}>
|
|
70
|
+
{!!leftIcon && (
|
|
71
|
+
<View style={styles.paddingLeft16}>
|
|
72
|
+
{member?.avatar ? (
|
|
73
|
+
<Image
|
|
74
|
+
source={{ uri: member?.avatar }}
|
|
75
|
+
style={styles.avatar}
|
|
76
|
+
/>
|
|
77
|
+
) : (
|
|
78
|
+
<CircleView size={40} backgroundColor={circleColor} center>
|
|
79
|
+
<Text color={Colors.White}>{firstWordsInName}</Text>
|
|
80
|
+
</CircleView>
|
|
81
|
+
)}
|
|
82
|
+
</View>
|
|
83
|
+
)}
|
|
84
|
+
<View style={styles.columnFlex}>
|
|
85
|
+
<Text style={styles.titleName}>
|
|
86
|
+
{member?.name || shortEmailName(member?.email) || ''}
|
|
87
|
+
</Text>
|
|
88
|
+
{member?.phone_number && (
|
|
89
|
+
<Text style={styles.status}> {member?.phone_number}</Text>
|
|
90
|
+
)}
|
|
91
|
+
</View>
|
|
92
|
+
{!!rightComponent && (
|
|
93
|
+
<View style={styles.endFlex}>
|
|
94
|
+
{!!role && (
|
|
95
|
+
<Text style={[styles.textRole, { color: roleColor }]}>
|
|
96
|
+
{role}
|
|
97
|
+
</Text>
|
|
98
|
+
)}
|
|
99
|
+
</View>
|
|
100
|
+
)}
|
|
101
|
+
</View>
|
|
102
|
+
</TouchableOpacity>
|
|
62
103
|
</View>
|
|
63
104
|
);
|
|
64
105
|
}
|
|
@@ -68,9 +109,7 @@ export default RowMember;
|
|
|
68
109
|
|
|
69
110
|
const styles = StyleSheet.create({
|
|
70
111
|
rowContainer: {
|
|
71
|
-
|
|
72
|
-
alignItems: 'center',
|
|
73
|
-
paddingHorizontal: 16,
|
|
112
|
+
flex: 1,
|
|
74
113
|
},
|
|
75
114
|
iconContainer: {
|
|
76
115
|
alignItems: 'center',
|
|
@@ -107,4 +146,55 @@ const styles = StyleSheet.create({
|
|
|
107
146
|
textCenter: {
|
|
108
147
|
alignSelf: 'center',
|
|
109
148
|
},
|
|
149
|
+
columnFlex: {
|
|
150
|
+
paddingLeft: 16,
|
|
151
|
+
justifyContent: 'center',
|
|
152
|
+
flexDirection: 'column',
|
|
153
|
+
},
|
|
154
|
+
rowFlex: {
|
|
155
|
+
flexDirection: 'row',
|
|
156
|
+
},
|
|
157
|
+
endFlex: {
|
|
158
|
+
flex: 1,
|
|
159
|
+
justifyContent: 'flex-start',
|
|
160
|
+
alignItems: 'flex-end',
|
|
161
|
+
paddingRight: 16,
|
|
162
|
+
},
|
|
163
|
+
Border: {
|
|
164
|
+
display: 'flex',
|
|
165
|
+
width: '100%',
|
|
166
|
+
borderWidth: 0,
|
|
167
|
+
borderColor: Colors.Gray4,
|
|
168
|
+
borderBottomWidth: 1,
|
|
169
|
+
borderStyle: 'solid',
|
|
170
|
+
flexDirection: 'row',
|
|
171
|
+
paddingTop: 16,
|
|
172
|
+
paddingBottom: 16,
|
|
173
|
+
},
|
|
174
|
+
titleName: {
|
|
175
|
+
fontSize: 16,
|
|
176
|
+
lineHeight: 24,
|
|
177
|
+
fontStyle: 'normal',
|
|
178
|
+
fontWeight: '400',
|
|
179
|
+
color: Colors.Gray9,
|
|
180
|
+
},
|
|
181
|
+
status: {
|
|
182
|
+
fontSize: 12,
|
|
183
|
+
lineHeight: 20,
|
|
184
|
+
fontStyle: 'normal',
|
|
185
|
+
fontWeight: '400',
|
|
186
|
+
color: Colors.Gray7,
|
|
187
|
+
},
|
|
188
|
+
container: {
|
|
189
|
+
paddingTop: 0,
|
|
190
|
+
},
|
|
191
|
+
paddingLeft16: {
|
|
192
|
+
paddingLeft: 16,
|
|
193
|
+
},
|
|
194
|
+
avatar: {
|
|
195
|
+
height: 40,
|
|
196
|
+
width: 40,
|
|
197
|
+
borderRadius: 40,
|
|
198
|
+
backgroundColor: Colors.Primary,
|
|
199
|
+
},
|
|
110
200
|
});
|
|
@@ -27,7 +27,7 @@ describe('MemberList', () => {
|
|
|
27
27
|
});
|
|
28
28
|
const instance = tree.root;
|
|
29
29
|
const textInputs = instance.findAllByType(Text);
|
|
30
|
-
expect(textInputs.length).toBe(
|
|
30
|
+
expect(textInputs.length).toBe(5);
|
|
31
31
|
});
|
|
32
32
|
test('MemberList snapshot id dataMember !== ownerId', () => {
|
|
33
33
|
const dataMember = [{ id: 1, name: 'CEO' }];
|
|
@@ -36,7 +36,7 @@ describe('MemberList', () => {
|
|
|
36
36
|
});
|
|
37
37
|
const instance = tree.root;
|
|
38
38
|
const textInputs = instance.findAllByType(Text);
|
|
39
|
-
expect(textInputs.length).toBe(
|
|
39
|
+
expect(textInputs.length).toBe(5);
|
|
40
40
|
});
|
|
41
41
|
test('MemberList snapshot id dataMember === currentUserId', () => {
|
|
42
42
|
const dataMember = [{ id: 1, name: 'CEO' }];
|
|
@@ -45,7 +45,7 @@ describe('MemberList', () => {
|
|
|
45
45
|
});
|
|
46
46
|
const instance = tree.root;
|
|
47
47
|
const textInputs = instance.findAllByType(Text);
|
|
48
|
-
expect(textInputs.length).toBe(
|
|
48
|
+
expect(textInputs.length).toBe(5);
|
|
49
49
|
});
|
|
50
50
|
test('MemberList dataMember null', () => {
|
|
51
51
|
const dataMember = [];
|
|
@@ -26,8 +26,8 @@ describe('RowMember', () => {
|
|
|
26
26
|
});
|
|
27
27
|
const instance = tree.root;
|
|
28
28
|
const textInputs = instance.findAllByType(Text);
|
|
29
|
-
expect(textInputs.length).toBe(
|
|
30
|
-
expect(textInputs[
|
|
29
|
+
expect(textInputs.length).toBe(5);
|
|
30
|
+
expect(textInputs[1].props.children).toEqual('CEO');
|
|
31
31
|
});
|
|
32
32
|
test('RowMember owner dont have name show start of email ', () => {
|
|
33
33
|
const dataMember = { id: 1, name: '', email: 'abc@gmail.com' };
|
|
@@ -36,7 +36,7 @@ describe('RowMember', () => {
|
|
|
36
36
|
});
|
|
37
37
|
const instance = tree.root;
|
|
38
38
|
const textInputs = instance.findAllByType(Text);
|
|
39
|
-
expect(textInputs.length).toBe(
|
|
40
|
-
expect(textInputs[
|
|
39
|
+
expect(textInputs.length).toBe(5);
|
|
40
|
+
expect(textInputs[1].props.children).toEqual('abc');
|
|
41
41
|
});
|
|
42
42
|
});
|
package/src/configs/API.js
CHANGED
|
@@ -39,6 +39,8 @@ const API = {
|
|
|
39
39
|
SCConfig.apiRoot + `/property_manager/units/${id}/add_gateway/`,
|
|
40
40
|
SENSORS_STATUS: (id) =>
|
|
41
41
|
SCConfig.apiRoot + `/property_manager/units/${id}/sensors_status/`,
|
|
42
|
+
CHANGE_OWNER: (id) =>
|
|
43
|
+
SCConfig.apiRoot + `/property_manager/units/${id}/change_owner/`,
|
|
42
44
|
FAVOURITE_DEVICES: (id) =>
|
|
43
45
|
SCConfig.apiRoot + `/property_manager/units/${id}/favourite_devices/`,
|
|
44
46
|
},
|
|
@@ -137,9 +139,9 @@ const API = {
|
|
|
137
139
|
CHECK_SEND_EMAIL: () =>
|
|
138
140
|
SCConfig.apiRoot + '/connection_manager/googlehome/check_send_email/',
|
|
139
141
|
},
|
|
140
|
-
|
|
142
|
+
VALUE_CONSUME: {
|
|
141
143
|
DISPLAY_HISTORY: () =>
|
|
142
|
-
SCConfig.apiRoot + '/property_manager/
|
|
144
|
+
SCConfig.apiRoot + '/property_manager/value_consume/display_history/',
|
|
143
145
|
},
|
|
144
146
|
SHARE: {
|
|
145
147
|
UNITS: () => SCConfig.apiRoot + '/property_manager/sharing/units/',
|
|
@@ -150,6 +152,12 @@ const API = {
|
|
|
150
152
|
UNITS_MEMBER_DETAIL: (id, shareId) =>
|
|
151
153
|
SCConfig.apiRoot +
|
|
152
154
|
`/property_manager/sharing/units/${id}/members/${shareId}/`,
|
|
155
|
+
UNIT_MEMBER_INFO: (unit_id, member_id) =>
|
|
156
|
+
SCConfig.apiRoot +
|
|
157
|
+
`/property_manager/sharing/units/${unit_id}/member/${member_id}/information/`,
|
|
158
|
+
UNIT_MEMBER_SHARE_DEVICE: (unit_id, member_id) =>
|
|
159
|
+
SCConfig.apiRoot +
|
|
160
|
+
`/property_manager/sharing/units/${unit_id}/member/${member_id}/shared_devices/`,
|
|
153
161
|
SHARE: () => SCConfig.apiRoot + '/property_manager/sharing/share/',
|
|
154
162
|
},
|
|
155
163
|
EMERGENCY: {
|
|
@@ -157,6 +165,8 @@ const API = {
|
|
|
157
165
|
},
|
|
158
166
|
EMERGENCY_BUTTON: {
|
|
159
167
|
CREATE_CONTACT: () => SCConfig.apiRoot + '/emergency_button/contacts/',
|
|
168
|
+
CREATE_BATCH: () =>
|
|
169
|
+
SCConfig.apiRoot + '/emergency_button/contacts/create_batch/',
|
|
160
170
|
CONTACTS: () => SCConfig.apiRoot + '/emergency_button/contacts/',
|
|
161
171
|
REMOVE_CONTACTS: (id) =>
|
|
162
172
|
SCConfig.apiRoot + `/emergency_button/contacts/${id}/`,
|
package/src/configs/Colors.js
CHANGED
|
@@ -126,6 +126,7 @@ export const Colors = {
|
|
|
126
126
|
BlackTransparent1: 'rgba(0, 0, 0, 0.1)',
|
|
127
127
|
BlackTransparent2: 'rgba(0, 0, 0, 0.2)',
|
|
128
128
|
BlackTransparent3: 'rgba(0, 0, 0, 0.3)',
|
|
129
|
+
BlackTransparent3_5: 'rgba(0, 0, 0, 0.35)',
|
|
129
130
|
BlackTransparent4: 'rgba(0, 0, 0, 0.4)',
|
|
130
131
|
BlackTransparent5: 'rgba(0, 0, 0, 0.5)',
|
|
131
132
|
BlackTransparent6: 'rgba(0, 0, 0, 0.6)',
|
package/src/configs/Constants.js
CHANGED
|
@@ -217,6 +217,10 @@ export const TESTID = {
|
|
|
217
217
|
MY_UNIT_NO_UNIT: 'MY_UNIT_NO_UNIT',
|
|
218
218
|
ITEM_UNIT: 'ITEM_UNIT',
|
|
219
219
|
|
|
220
|
+
//member list
|
|
221
|
+
SHARING_MEMBER: 'SHARING_MEMBER',
|
|
222
|
+
REMOVE_MEMBER: 'REMOVE_MEMBER',
|
|
223
|
+
|
|
220
224
|
// SmartTiviTemplate
|
|
221
225
|
SMART_TIVI_TEMPLATE: {
|
|
222
226
|
BIG_BUTTON: 'BIG_BUTTON',
|
|
@@ -309,6 +313,10 @@ export const TESTID = {
|
|
|
309
313
|
BUTTON_SELECT_VISA: 'BUTTON_SELECT_VISA',
|
|
310
314
|
BUTTON_SELECT_MASTER_CARD: 'BUTTON_SELECT_MASTER_CARD',
|
|
311
315
|
|
|
316
|
+
//Enter Password
|
|
317
|
+
ENTER_PASSWORD_TEXT_INPUT_PASSWORD: 'ENTER_PASSWORD_TEXT_INPUT_PASSWORD',
|
|
318
|
+
ENTER_PASSWORD_BUTTON_DONE: 'ENTER_PASSWORD_BUTTON_DONE',
|
|
319
|
+
|
|
312
320
|
// Map Dashboard
|
|
313
321
|
PARKING_MARKER: 'PARKING_MARKER',
|
|
314
322
|
|
|
@@ -424,6 +432,8 @@ export const TESTID = {
|
|
|
424
432
|
ITEM_QUICK_ACTION_PRESS: 'ITEM_QUICK_ACTION_PRESS',
|
|
425
433
|
TIME_COUNT_DOWN_TEXT: 'TIME_COUNT_DOWN_TEXT',
|
|
426
434
|
ACTION_ITEM: 'ACTION_ITEM',
|
|
435
|
+
// Sensor Item
|
|
436
|
+
TEXT_SENSOR_ITEM: 'TEXT_SENSOR_ITEM',
|
|
427
437
|
|
|
428
438
|
// DeviceInfo
|
|
429
439
|
DEVICE_INFO_BATTERY: 'DEVICE_INFO_BATTERY',
|
|
@@ -687,6 +697,9 @@ export const TESTID = {
|
|
|
687
697
|
BUTTON_YOUR_LOCATION: 'BUTTON_YOUR_LOCATION',
|
|
688
698
|
BUTTON_CHOOSE_ON_MAP: 'BUTTON_CHOOSE_ON_MAP',
|
|
689
699
|
|
|
700
|
+
//searchBox
|
|
701
|
+
ON_FOCUS_SEARCH_B0X: 'ON_FOCUS_SEARCH_B0X',
|
|
702
|
+
|
|
690
703
|
// MoveToAnotherSubUnit
|
|
691
704
|
ROW_SUB_UNIT: 'ROW_SUB_UNIT',
|
|
692
705
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { useState, useEffect, useRef } from 'react';
|
|
1
|
+
import { useState, useEffect, useRef, useCallback } from 'react';
|
|
2
2
|
import { useIsFocused } from '@react-navigation/native';
|
|
3
|
+
import { throttle } from 'lodash';
|
|
3
4
|
import { axiosGet } from '../../utils/Apis/axios';
|
|
4
5
|
import { API } from '../../configs';
|
|
5
6
|
|
|
@@ -9,35 +10,44 @@ const useSensorsStatus = (unit, sensors) => {
|
|
|
9
10
|
const [sensorsStatus, setSensorsStatus] = useState([]);
|
|
10
11
|
const [serverDown, setServerDown] = useState(false);
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
);
|
|
26
|
-
if (success) {
|
|
27
|
-
setSensorsStatus(data);
|
|
28
|
-
setServerDown(false);
|
|
29
|
-
} else if (resp_status >= 500) {
|
|
30
|
-
setServerDown(true);
|
|
13
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
14
|
+
const getSensorsStatus = useCallback(
|
|
15
|
+
throttle(async (unit, sensors) => {
|
|
16
|
+
const params = new URLSearchParams();
|
|
17
|
+
if (sensors?.length > 0) {
|
|
18
|
+
sensors.forEach((sensor) => {
|
|
19
|
+
params.append('sensors', sensor.id);
|
|
20
|
+
});
|
|
21
|
+
const { success, data, resp_status } = await axiosGet(
|
|
22
|
+
API.UNIT.SENSORS_STATUS(unit.id),
|
|
23
|
+
{
|
|
24
|
+
params: params,
|
|
31
25
|
}
|
|
26
|
+
);
|
|
27
|
+
if (success) {
|
|
28
|
+
setSensorsStatus(data);
|
|
29
|
+
setServerDown(false);
|
|
30
|
+
} else if (resp_status > 500) {
|
|
31
|
+
setServerDown(true);
|
|
32
32
|
}
|
|
33
|
-
}
|
|
34
|
-
|
|
33
|
+
}
|
|
34
|
+
}, 3000),
|
|
35
|
+
[]
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (isFocused) {
|
|
40
|
+
getSensorsStatus(unit, sensors);
|
|
41
|
+
const updateInterval = setInterval(
|
|
42
|
+
() => getSensorsStatus(unit, sensors),
|
|
43
|
+
5000
|
|
44
|
+
);
|
|
35
45
|
intervalSensorStatus.current = updateInterval;
|
|
36
46
|
return () => clearInterval(updateInterval);
|
|
37
47
|
} else {
|
|
38
48
|
clearInterval(intervalSensorStatus.current);
|
|
39
49
|
}
|
|
40
|
-
}, [isFocused,
|
|
50
|
+
}, [isFocused, getSensorsStatus, unit, sensors]);
|
|
41
51
|
|
|
42
52
|
const getStatus = (sensor) => {
|
|
43
53
|
sensorsStatus.find((s) => s.id === sensor.id);
|
|
@@ -49,6 +49,8 @@ import SetUpSensor from '../screens/AddNewAction/SetupSensor';
|
|
|
49
49
|
import EditDevice from '../screens/Device/EditDevice/index';
|
|
50
50
|
import EmergencySetting from '../screens/EmergencySetting';
|
|
51
51
|
import ConfirmUnitDeletion from '../screens/ConfirmUnitDeletion';
|
|
52
|
+
import InfoMemberUnit from '../screens/Sharing/InfoMemberUnit';
|
|
53
|
+
import EnterPassword from '../screens/EnterPassword';
|
|
52
54
|
import { HanetCameraStack } from './HanetCameraStack';
|
|
53
55
|
|
|
54
56
|
import { axiosGet } from '../utils/Apis/axios';
|
|
@@ -268,6 +270,20 @@ export const UnitStack = memo((props) => {
|
|
|
268
270
|
headerShown: false,
|
|
269
271
|
}}
|
|
270
272
|
/>
|
|
273
|
+
<Stack.Screen
|
|
274
|
+
name={Route.UnitMemberInformation}
|
|
275
|
+
component={InfoMemberUnit}
|
|
276
|
+
options={{
|
|
277
|
+
headerShown: false,
|
|
278
|
+
}}
|
|
279
|
+
/>
|
|
280
|
+
<Stack.Screen
|
|
281
|
+
name={Route.EnterPassword}
|
|
282
|
+
component={EnterPassword}
|
|
283
|
+
options={{
|
|
284
|
+
headerShown: false,
|
|
285
|
+
}}
|
|
286
|
+
/>
|
|
271
287
|
<Stack.Screen
|
|
272
288
|
name={Route.DeviceInfo}
|
|
273
289
|
component={DeviceInfo}
|
|
@@ -133,6 +133,8 @@ describe('Test SelectSubUnit container', () => {
|
|
|
133
133
|
expect(mockedNavigate).toBeCalledWith('ScanChipQR', {
|
|
134
134
|
addType: 'AddNewGateway',
|
|
135
135
|
station: undefined,
|
|
136
|
+
isNewFlow: false,
|
|
137
|
+
unit_name: undefined,
|
|
136
138
|
});
|
|
137
139
|
break;
|
|
138
140
|
case 'AddHassiDevice':
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
Text,
|
|
12
12
|
PermissionsAndroid,
|
|
13
13
|
Platform,
|
|
14
|
-
ActivityIndicator,
|
|
15
14
|
} from 'react-native';
|
|
16
15
|
import WifiManager from 'react-native-wifi-reborn';
|
|
17
16
|
import { useNavigation } from '@react-navigation/native';
|
|
@@ -27,6 +26,7 @@ import Routes from '../../../utils/Route';
|
|
|
27
26
|
import { SCContext } from '../../../context';
|
|
28
27
|
import { Action } from '../../../context/actionType';
|
|
29
28
|
import { TESTID } from '../../../configs/Constants';
|
|
29
|
+
import Connecting from '../../../commons/Connecting ';
|
|
30
30
|
|
|
31
31
|
const isIos = Platform.OS === 'ios';
|
|
32
32
|
const isAndroid = Platform.OS === 'android';
|
|
@@ -50,6 +50,9 @@ const ConnectWifiWarning = memo(({ route }) => {
|
|
|
50
50
|
const t = useTranslations();
|
|
51
51
|
const { navigate, goBack } = useNavigation();
|
|
52
52
|
const [isLoading, setIsLoading] = useState(false);
|
|
53
|
+
const [isConnect, setIsConnect] = useState(false);
|
|
54
|
+
const [isPercentConnect, setIsPercentConnect] = useState(0);
|
|
55
|
+
|
|
53
56
|
const { setAction } = useContext(SCContext);
|
|
54
57
|
|
|
55
58
|
const getPermissionWifiAndroid = useCallback(async () => {
|
|
@@ -76,6 +79,7 @@ const ConnectWifiWarning = memo(({ route }) => {
|
|
|
76
79
|
const handleSend = async () => {
|
|
77
80
|
let intervalSend = null;
|
|
78
81
|
if (isIos) {
|
|
82
|
+
await setIsPercentConnect(1);
|
|
79
83
|
await socket.on('message', (msg, rinfo) => {
|
|
80
84
|
clearInterval(intervalSend);
|
|
81
85
|
const data = JSON.parse(msg.toString());
|
|
@@ -110,6 +114,7 @@ const ConnectWifiWarning = memo(({ route }) => {
|
|
|
110
114
|
});
|
|
111
115
|
} else {
|
|
112
116
|
const socket = dgram.createSocket({ type: 'udp4' });
|
|
117
|
+
await setIsPercentConnect(1);
|
|
113
118
|
await socket.bind(54321);
|
|
114
119
|
await socket.on('message', (msg, rinfo) => {
|
|
115
120
|
const data = JSON.parse(msg.toString());
|
|
@@ -147,6 +152,7 @@ const ConnectWifiWarning = memo(({ route }) => {
|
|
|
147
152
|
|
|
148
153
|
const handleConnectWifiGateway = async () => {
|
|
149
154
|
setIsLoading(true);
|
|
155
|
+
setIsConnect(true);
|
|
150
156
|
// eslint-disable-next-line promise/prefer-await-to-then
|
|
151
157
|
WifiManager.connectToProtectedSSID(wifi_ssid, wifi_pass, false).then(
|
|
152
158
|
() => {
|
|
@@ -185,8 +191,11 @@ const ConnectWifiWarning = memo(({ route }) => {
|
|
|
185
191
|
</>
|
|
186
192
|
) : (
|
|
187
193
|
<View style={styles.centerLoading}>
|
|
188
|
-
<
|
|
189
|
-
|
|
194
|
+
<Connecting
|
|
195
|
+
isLoading={isLoading}
|
|
196
|
+
isConnect={isConnect}
|
|
197
|
+
isPercentConnect={isPercentConnect}
|
|
198
|
+
/>
|
|
190
199
|
</View>
|
|
191
200
|
)}
|
|
192
201
|
</View>
|
|
@@ -37,10 +37,11 @@ const FirstWarning = memo(({ route }) => {
|
|
|
37
37
|
</View>
|
|
38
38
|
</View>
|
|
39
39
|
<ViewButtonBottom
|
|
40
|
-
leftTitle={t('
|
|
40
|
+
leftTitle={t('cancel')}
|
|
41
41
|
onLeftClick={goBack}
|
|
42
42
|
rightTitle={t('text_next')}
|
|
43
43
|
onRightClick={onRight}
|
|
44
|
+
styleButtonLeftText={styles.buttonLeftText}
|
|
44
45
|
/>
|
|
45
46
|
</View>
|
|
46
47
|
);
|
|
@@ -72,4 +73,7 @@ const styles = StyleSheet.create({
|
|
|
72
73
|
paddingBottom: 30,
|
|
73
74
|
color: Colors.Red,
|
|
74
75
|
},
|
|
76
|
+
buttonLeftText: {
|
|
77
|
+
color: Colors.Gray6,
|
|
78
|
+
},
|
|
75
79
|
});
|
|
@@ -205,9 +205,17 @@ const GatewayWifiList = memo(({ route }) => {
|
|
|
205
205
|
}
|
|
206
206
|
}, [isSendWifi, setAction]);
|
|
207
207
|
|
|
208
|
+
const handleOnGoBack = useCallback(() => {
|
|
209
|
+
navigate(Routes.Dashboard);
|
|
210
|
+
}, [navigate]);
|
|
211
|
+
|
|
208
212
|
return (
|
|
209
213
|
<View style={styles.screen}>
|
|
210
|
-
<HeaderCustom
|
|
214
|
+
<HeaderCustom
|
|
215
|
+
onGoBack={handleOnGoBack}
|
|
216
|
+
title={t('connect_home_wifi')}
|
|
217
|
+
isShowSeparator
|
|
218
|
+
/>
|
|
211
219
|
<View>
|
|
212
220
|
<Text style={styles.title} semibold type="H3">
|
|
213
221
|
{t('set_network')}
|
|
@@ -82,7 +82,7 @@ export const EmergencyContactsList = ({ route }) => {
|
|
|
82
82
|
id: 2,
|
|
83
83
|
text: t('select_unit_members'),
|
|
84
84
|
route: Routes.EmergencyContactsSelectContacts,
|
|
85
|
-
data: { unitId, group },
|
|
85
|
+
data: { unitId, group, lengthListContacts: listContacts.length },
|
|
86
86
|
},
|
|
87
87
|
];
|
|
88
88
|
|
|
@@ -8,15 +8,20 @@ import { RowUser } from '../../commons/RowUser';
|
|
|
8
8
|
import WrapHeaderScrollable from '../../commons/Sharing/WrapHeaderScrollable';
|
|
9
9
|
import { API, Colors, Theme } from '../../configs';
|
|
10
10
|
import { TESTID } from '../../configs/Constants';
|
|
11
|
+
|
|
11
12
|
import { axiosGet, axiosPost } from '../../utils/Apis/axios';
|
|
12
13
|
import { ToastBottomHelper } from '../../utils/Utils';
|
|
13
14
|
|
|
15
|
+
const MAX_EMERGENCY_CONTACTS = 5;
|
|
16
|
+
|
|
14
17
|
export const EmergencyContactsSelectContacts = ({ route }) => {
|
|
15
18
|
const t = useTranslations();
|
|
16
19
|
const { goBack } = useNavigation();
|
|
17
|
-
const { unitId, group } = route.params;
|
|
20
|
+
const { unitId, group, lengthListContacts } = route.params;
|
|
18
21
|
const [dataContact, setDataContact] = useState([]);
|
|
22
|
+
const [currentContacts, setCurrentContact] = useState([]);
|
|
19
23
|
const [loading, setLoading] = useState(true);
|
|
24
|
+
const NUMBER_EMERGENCY_CONTACTS = MAX_EMERGENCY_CONTACTS - lengthListContacts;
|
|
20
25
|
|
|
21
26
|
const loadMembers = useCallback(async (id) => {
|
|
22
27
|
setLoading(true);
|
|
@@ -27,22 +32,33 @@ export const EmergencyContactsSelectContacts = ({ route }) => {
|
|
|
27
32
|
}
|
|
28
33
|
}, []);
|
|
29
34
|
|
|
30
|
-
const [currentContacts, setCurrentContact] = useState('');
|
|
31
|
-
|
|
32
35
|
const onPressContact = useCallback(
|
|
33
|
-
(
|
|
34
|
-
|
|
36
|
+
(name, phone_number) => () => {
|
|
37
|
+
if (currentContacts.some((contact) => contact?.name === name)) {
|
|
38
|
+
setCurrentContact((oldArray) =>
|
|
39
|
+
oldArray.filter((contact) => contact?.name !== name)
|
|
40
|
+
);
|
|
41
|
+
} else {
|
|
42
|
+
if (NUMBER_EMERGENCY_CONTACTS !== currentContacts.length) {
|
|
43
|
+
setCurrentContact((oldArray) => [
|
|
44
|
+
...oldArray,
|
|
45
|
+
{ name, phone_number },
|
|
46
|
+
]);
|
|
47
|
+
} else {
|
|
48
|
+
ToastBottomHelper.error(t('maxmium_contacts'));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
35
51
|
},
|
|
36
|
-
[]
|
|
52
|
+
[NUMBER_EMERGENCY_CONTACTS, currentContacts, t]
|
|
37
53
|
);
|
|
38
54
|
|
|
39
55
|
const goSave = useCallback(async () => {
|
|
40
|
-
const { success } = await axiosPost(API.EMERGENCY_BUTTON.
|
|
56
|
+
const { success } = await axiosPost(API.EMERGENCY_BUTTON.CREATE_BATCH(), {
|
|
41
57
|
group: group.id,
|
|
42
|
-
|
|
43
|
-
name: currentContacts?.name,
|
|
58
|
+
contacts: currentContacts,
|
|
44
59
|
});
|
|
45
60
|
if (success) {
|
|
61
|
+
ToastBottomHelper.success(t('saving_contact_successful'));
|
|
46
62
|
goBack();
|
|
47
63
|
} else {
|
|
48
64
|
ToastBottomHelper.error(t('create_contact_failed'));
|
|
@@ -66,10 +82,12 @@ export const EmergencyContactsSelectContacts = ({ route }) => {
|
|
|
66
82
|
}
|
|
67
83
|
text={contact.name}
|
|
68
84
|
subtext={contact.phone_number}
|
|
69
|
-
onPress={onPressContact(contact)}
|
|
85
|
+
onPress={onPressContact(contact.name, contact.phone_number)}
|
|
70
86
|
rightComponent={
|
|
71
87
|
<View style={styles.buttonRemove}>
|
|
72
|
-
{currentContacts
|
|
88
|
+
{currentContacts.some(
|
|
89
|
+
(item) => item?.name === contact?.name
|
|
90
|
+
) && (
|
|
73
91
|
<IconOutline
|
|
74
92
|
name={'check-circle'}
|
|
75
93
|
size={20}
|