@eohjsc/react-native-smart-city 0.2.92 → 0.2.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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/assets/images/Device/current-state.svg +3 -0
- package/assets/images/Device/door-state.svg +3 -0
- package/assets/images/Device/wind-strength.svg +12 -0
- package/package.json +1 -1
- package/src/commons/Action/ItemQuickAction.js +1 -0
- package/src/commons/Action/__test__/ItemQuickAction.test.js +49 -2
- package/src/commons/ActionGroup/OnOffTemplate/OnOffSimpleTemplateStyle.js +2 -1
- package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +31 -11
- package/src/commons/ActionGroup/OptionsDropdownActionTemplateStyle.js +5 -2
- package/src/commons/ActionGroup/StatesGridActionTemplate.js +42 -36
- package/src/commons/ActionGroup/StatesGridActionTemplateStyle.js +5 -10
- package/src/commons/ActionGroup/TimerActionTemplate.js +14 -10
- package/src/commons/ActionGroup/TimerActionTemplateStyles.js +12 -0
- package/src/commons/ActionGroup/TwoButtonTemplate/TwoButtonTemplateStyles.js +55 -0
- package/src/commons/ActionGroup/TwoButtonTemplate/index.js +170 -0
- package/src/commons/ActionGroup/__test__/TimerActionTemplate.test.js +1 -1
- package/src/commons/ActionGroup/__test__/TwoButtonTemplate.test.js +112 -0
- package/src/commons/ActionGroup/index.js +3 -0
- package/src/commons/CameraDevice/index.js +6 -1
- package/src/commons/Device/HistoryChart.js +2 -2
- package/src/commons/Device/ItemDevice.js +3 -13
- package/src/commons/Explore/SearchBox/__test__/SearchBox.test.js +19 -0
- package/src/commons/Explore/SearchBox/index.js +2 -0
- package/src/commons/IconComponent/index.js +32 -26
- package/src/commons/MediaPlayerDetail/index.js +16 -4
- package/src/commons/MenuActionMore/index.js +2 -2
- package/src/commons/Modal/ModalCustom.js +9 -1
- package/src/commons/SubUnit/Favorites/index.js +8 -7
- package/src/commons/SubUnit/__test__/Favorites.test.js +33 -35
- package/src/configs/API.js +6 -2
- package/src/configs/Colors.js +1 -0
- package/src/configs/Constants.js +24 -0
- package/src/context/actionType.ts +17 -0
- package/src/context/mockStore.ts +18 -0
- package/src/context/reducer.ts +102 -0
- package/src/iot/RemoteControl/Bluetooth.js +2 -0
- package/src/iot/RemoteControl/GoogleHome.js +1 -0
- package/src/navigations/AutomateStack.js +16 -1
- package/src/navigations/UnitStack.js +27 -0
- package/src/screens/AddCommon/SelectSubUnit.js +1 -0
- package/src/screens/AddCommon/__test__/SelectSubUnit.test.js +2 -0
- package/src/screens/AddNewAction/Device/__test__/index.test.js +1 -1
- package/src/screens/AddNewAction/SelectAction.js +13 -15
- package/src/screens/AddNewAction/__test__/SelectAction.test.js +0 -7
- package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +2 -0
- package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +2 -0
- package/src/screens/AddNewGateway/PlugAndPlay/__test__/ConnectWifiWarning.test.js +9 -0
- package/src/screens/AddNewGateway/PlugAndPlay/__test__/GatewayWifiList.test.js +15 -0
- package/src/screens/AddNewGateway/SetupGatewayWifi.js +6 -1
- package/src/screens/AddNewGateway/__test__/SetupGateway.test.js +34 -0
- package/src/screens/AllCamera/index.js +1 -0
- package/src/screens/Automate/MultiUnits.js +9 -9
- package/src/screens/Automate/index.js +21 -20
- package/src/screens/Device/__test__/detail.test.js +119 -86
- package/src/screens/Device/detail.js +38 -51
- package/src/screens/Device/hooks/useFavoriteDevice.js +38 -0
- package/src/screens/EmergencyContacts/EmergencyContactsList.js +1 -1
- package/src/screens/EmergencyContacts/EmergencyContactsSelectContacts.js +41 -44
- package/src/screens/EmergencyContacts/__test__/EmergencyContactList.test.js +1 -0
- package/src/screens/EmergencyContacts/__test__/EmergencyContactsSelectContacts.test.js +18 -19
- package/src/screens/MoveToAnotherSubUnit/index.js +3 -1
- package/src/screens/Notification/__test__/NotificationItem.test.js +64 -53
- package/src/screens/Notification/components/NotificationItem.js +13 -4
- package/src/screens/ScriptDetail/__test__/index.test.js +15 -4
- package/src/screens/ScriptDetail/hooks/useStarredScript.js +32 -0
- package/src/screens/ScriptDetail/index.js +11 -20
- package/src/screens/SharedUnit/__test__/TabHeader.test.js +5 -0
- package/src/screens/Sharing/SelectUser.js +3 -23
- package/src/screens/Sharing/__test__/SelectUser.test.js +12 -80
- package/src/screens/SmartIr/__test__/GroupButtonByType.test.js +33 -0
- package/src/screens/SmartIr/components/GroupButtonByType/GroupButtonByType.js +2 -0
- package/src/screens/Unit/ChooseLocation.js +5 -0
- package/src/screens/Unit/Detail.js +33 -37
- package/src/screens/Unit/ManageUnit.js +21 -20
- package/src/screens/Unit/ManageUnitStyles.js +1 -0
- package/src/screens/Unit/SelectAddress.js +8 -2
- package/src/screens/Unit/Summaries.js +12 -15
- package/src/screens/Unit/__test__/Detail.test.js +25 -0
- package/src/screens/Unit/components/__test__/Header.test.js +32 -0
- package/src/screens/Unit/hook/useFavorites.js +28 -0
- package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +1 -1
- package/src/screens/UnitSummary/components/PowerConsumption/index.js +1 -1
- package/src/utils/Apis/axios.js +7 -2
- package/src/utils/I18n/translations/en.json +2 -5
- package/src/utils/I18n/translations/vi.json +1 -4
|
@@ -16,7 +16,7 @@ import { Icon } from '@ant-design/react-native';
|
|
|
16
16
|
import { useCountUp } from './hooks/useCountUp';
|
|
17
17
|
import { getData as getLocalData } from '../../utils/Storage';
|
|
18
18
|
import { API, Colors } from '../../configs';
|
|
19
|
-
import { axiosGet
|
|
19
|
+
import { axiosGet } from '../../utils/Apis/axios';
|
|
20
20
|
import {
|
|
21
21
|
isDeviceConnected,
|
|
22
22
|
scanBluetoothDevices,
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
useAlertResolveEmergency,
|
|
30
30
|
useEmergencyButton,
|
|
31
31
|
} from './hooks/useEmergencyButton';
|
|
32
|
+
import { useFavoriteDevice } from './hooks/useFavoriteDevice';
|
|
32
33
|
import BottomButtonView from '../../commons/BottomButtonView';
|
|
33
34
|
import Text from '../../commons/Text';
|
|
34
35
|
import { transformDatetime } from '../../utils/Converter/time';
|
|
@@ -69,7 +70,6 @@ const DeviceDetail = ({ route }) => {
|
|
|
69
70
|
const [unit, setUnit] = useState(unitData || { id: unitId });
|
|
70
71
|
const [sensor, setSensor] = useState(sensorData || { id: sensorId });
|
|
71
72
|
const [station, setStation] = useState(sensor?.station);
|
|
72
|
-
const [isFavourite, setIsFavourite] = useState(sensor?.is_favourite);
|
|
73
73
|
const { isOwner } = useIsOwnerOfUnit(unit?.user_id);
|
|
74
74
|
const [sensorName, setSensorName] = useState(sensor?.name);
|
|
75
75
|
const [lockShowing, acquireLockShowing, releaseLockShowing] = useBoolean();
|
|
@@ -83,9 +83,9 @@ const DeviceDetail = ({ route }) => {
|
|
|
83
83
|
const isNetworkConnected = useSCContextSelector(
|
|
84
84
|
(state) => state.app.isNetworkConnected
|
|
85
85
|
);
|
|
86
|
-
const isBluetoothEnabled = useSCContextSelector(
|
|
87
|
-
|
|
88
|
-
);
|
|
86
|
+
const isBluetoothEnabled = useSCContextSelector((state) => {
|
|
87
|
+
return state.app.isBluetoothEnabled;
|
|
88
|
+
});
|
|
89
89
|
|
|
90
90
|
const isDeviceConnectedViaBle = useMemo(
|
|
91
91
|
() =>
|
|
@@ -110,41 +110,28 @@ const DeviceDetail = ({ route }) => {
|
|
|
110
110
|
|
|
111
111
|
useDisconnectedDevice(sensorName, isDeviceHasBle, serverDown);
|
|
112
112
|
|
|
113
|
-
const isShowSetupEmergencyContact = useMemo(
|
|
114
|
-
|
|
115
|
-
(
|
|
116
|
-
item
|
|
117
|
-
|
|
118
|
-
|
|
113
|
+
const isShowSetupEmergencyContact = useMemo(
|
|
114
|
+
() =>
|
|
115
|
+
display.items.filter(
|
|
116
|
+
(item) =>
|
|
117
|
+
item.type === 'emergency' && item.configuration.type === 'button'
|
|
118
|
+
).length > 0,
|
|
119
|
+
[display.items]
|
|
120
|
+
);
|
|
119
121
|
|
|
120
|
-
const isShowSetUpSmartLock = useMemo(
|
|
121
|
-
|
|
122
|
-
(
|
|
123
|
-
item
|
|
124
|
-
|
|
125
|
-
|
|
122
|
+
const isShowSetUpSmartLock = useMemo(
|
|
123
|
+
() =>
|
|
124
|
+
display.items.filter(
|
|
125
|
+
(item) =>
|
|
126
|
+
item.type === 'smartLock' && item.configuration.type === 'button'
|
|
127
|
+
).length > 0,
|
|
128
|
+
[display.items]
|
|
129
|
+
);
|
|
126
130
|
|
|
127
|
-
const addToFavorites =
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if (success) {
|
|
132
|
-
setIsFavourite(true);
|
|
133
|
-
}
|
|
134
|
-
}, [unit, sensor]);
|
|
135
|
-
|
|
136
|
-
const removeFromFavorites = useCallback(async () => {
|
|
137
|
-
const { success } = await axiosPost(
|
|
138
|
-
API.SENSOR.REMOVE_FROM_FAVOURITES(
|
|
139
|
-
unit?.id,
|
|
140
|
-
sensor?.station.id,
|
|
141
|
-
sensor?.id
|
|
142
|
-
)
|
|
143
|
-
);
|
|
144
|
-
if (success) {
|
|
145
|
-
setIsFavourite(false);
|
|
146
|
-
}
|
|
147
|
-
}, [unit, sensor]);
|
|
131
|
+
const { isFavorite, addToFavorites, removeFromFavorites } = useFavoriteDevice(
|
|
132
|
+
unit,
|
|
133
|
+
sensor
|
|
134
|
+
);
|
|
148
135
|
|
|
149
136
|
const currentUserId = useSelector((state) =>
|
|
150
137
|
get(state, 'auth.account.user.id', 0)
|
|
@@ -162,10 +149,10 @@ const DeviceDetail = ({ route }) => {
|
|
|
162
149
|
}, [unitId]);
|
|
163
150
|
|
|
164
151
|
useEffect(() => {
|
|
165
|
-
if (unitId) {
|
|
152
|
+
if (unitId && !unitData) {
|
|
166
153
|
fetchUnitDetail();
|
|
167
154
|
}
|
|
168
|
-
}, [fetchUnitDetail,
|
|
155
|
+
}, [fetchUnitDetail, unitId, unitData]);
|
|
169
156
|
|
|
170
157
|
const fetchSensorDetail = useCallback(async () => {
|
|
171
158
|
const { success, data } = await axiosGet(
|
|
@@ -179,10 +166,10 @@ const DeviceDetail = ({ route }) => {
|
|
|
179
166
|
}, [sensorId]);
|
|
180
167
|
|
|
181
168
|
useEffect(() => {
|
|
182
|
-
if (sensorId) {
|
|
169
|
+
if (sensorId && !sensorData) {
|
|
183
170
|
fetchSensorDetail();
|
|
184
171
|
}
|
|
185
|
-
}, [fetchSensorDetail,
|
|
172
|
+
}, [fetchSensorDetail, sensorId, sensorData]);
|
|
186
173
|
|
|
187
174
|
const fetchDataDeviceDetail = useCallback(async () => {
|
|
188
175
|
if (!token) {
|
|
@@ -192,7 +179,7 @@ const DeviceDetail = ({ route }) => {
|
|
|
192
179
|
return;
|
|
193
180
|
}
|
|
194
181
|
|
|
195
|
-
const { success, data
|
|
182
|
+
const { success, data } = await axiosGet(
|
|
196
183
|
API.SENSOR.DISPLAY(sensor?.id),
|
|
197
184
|
{},
|
|
198
185
|
true
|
|
@@ -216,8 +203,6 @@ const DeviceDetail = ({ route }) => {
|
|
|
216
203
|
}
|
|
217
204
|
}
|
|
218
205
|
}
|
|
219
|
-
} else if (resp_status >= 500) {
|
|
220
|
-
setServerDown(true);
|
|
221
206
|
}
|
|
222
207
|
setLoading((preState) => ({ ...preState, displayTemplate: false }));
|
|
223
208
|
|
|
@@ -347,7 +332,7 @@ const DeviceDetail = ({ route }) => {
|
|
|
347
332
|
text: t('passcode_list'),
|
|
348
333
|
});
|
|
349
334
|
}
|
|
350
|
-
if (!
|
|
335
|
+
if (!isFavorite) {
|
|
351
336
|
menuItems.unshift({
|
|
352
337
|
doAction: addToFavorites,
|
|
353
338
|
text: t('add_to_favorites'),
|
|
@@ -365,7 +350,7 @@ const DeviceDetail = ({ route }) => {
|
|
|
365
350
|
isShowSetupEmergencyContact,
|
|
366
351
|
isShowSetUpSmartLock,
|
|
367
352
|
t,
|
|
368
|
-
|
|
353
|
+
isFavorite,
|
|
369
354
|
sensor,
|
|
370
355
|
unit,
|
|
371
356
|
sensorName,
|
|
@@ -434,7 +419,7 @@ const DeviceDetail = ({ route }) => {
|
|
|
434
419
|
});
|
|
435
420
|
|
|
436
421
|
const fetchValues = async () => {
|
|
437
|
-
const { success, data } = await axiosGet(
|
|
422
|
+
const { success, data, resp_status } = await axiosGet(
|
|
438
423
|
API.SENSOR.DISPLAY_VALUES_V2(sensor?.id),
|
|
439
424
|
{
|
|
440
425
|
params: params,
|
|
@@ -445,6 +430,8 @@ const DeviceDetail = ({ route }) => {
|
|
|
445
430
|
setConnected(data.is_connected);
|
|
446
431
|
transformDatetime(data, ['last_updated']);
|
|
447
432
|
setLastUpdated(data.last_updated);
|
|
433
|
+
} else if (resp_status >= 500) {
|
|
434
|
+
setServerDown(true);
|
|
448
435
|
}
|
|
449
436
|
setLoading((preState) => ({ ...preState, isConnected: false }));
|
|
450
437
|
};
|
|
@@ -626,10 +613,10 @@ const DeviceDetail = ({ route }) => {
|
|
|
626
613
|
<View style={styles.headerRight}>
|
|
627
614
|
<TouchableOpacity
|
|
628
615
|
style={styles.buttonStar}
|
|
629
|
-
onPress={
|
|
616
|
+
onPress={isFavorite ? removeFromFavorites : addToFavorites}
|
|
630
617
|
testID={TESTID.HEADER_DEVICE_BUTTON_STAR}
|
|
631
618
|
>
|
|
632
|
-
{
|
|
619
|
+
{isFavorite ? (
|
|
633
620
|
<IconFill name="star" size={25} color={Colors.Yellow6} />
|
|
634
621
|
) : (
|
|
635
622
|
<IconOutline name="star" size={25} />
|
|
@@ -653,7 +640,7 @@ const DeviceDetail = ({ route }) => {
|
|
|
653
640
|
</View>
|
|
654
641
|
),
|
|
655
642
|
[
|
|
656
|
-
|
|
643
|
+
isFavorite,
|
|
657
644
|
removeFromFavorites,
|
|
658
645
|
addToFavorites,
|
|
659
646
|
isShowSetupEmergencyContact,
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useContext, useCallback } from 'react';
|
|
2
|
+
import { API } from '../../../configs';
|
|
3
|
+
import { SCContext, useSCContextSelector } from '../../../context';
|
|
4
|
+
import { Action } from '../../../context/actionType';
|
|
5
|
+
import { axiosPost } from '../../../utils/Apis/axios';
|
|
6
|
+
|
|
7
|
+
export const useFavoriteDevice = (unit, device) => {
|
|
8
|
+
const { setAction } = useContext(SCContext);
|
|
9
|
+
const favoriteDeviceIds = useSCContextSelector(
|
|
10
|
+
(state) => state.unit.favoriteDeviceIds
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
const isFavorite = favoriteDeviceIds.includes(device.id);
|
|
14
|
+
|
|
15
|
+
const addToFavorites = useCallback(async () => {
|
|
16
|
+
const { success } = await axiosPost(
|
|
17
|
+
API.SENSOR.ADD_TO_FAVOURITES(unit?.id, device?.station?.id, device?.id)
|
|
18
|
+
);
|
|
19
|
+
success && setAction(Action.ADD_DEVICE_TO_FAVORITES, device.id);
|
|
20
|
+
}, [unit, device, setAction]);
|
|
21
|
+
|
|
22
|
+
const removeFromFavorites = useCallback(async () => {
|
|
23
|
+
const { success } = await axiosPost(
|
|
24
|
+
API.SENSOR.REMOVE_FROM_FAVOURITES(
|
|
25
|
+
unit?.id,
|
|
26
|
+
device?.station?.id,
|
|
27
|
+
device?.id
|
|
28
|
+
)
|
|
29
|
+
);
|
|
30
|
+
success && setAction(Action.REMOVE_DEVICE_FROM_FAVORITES, device.id);
|
|
31
|
+
}, [unit, device, setAction]);
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
isFavorite,
|
|
35
|
+
addToFavorites,
|
|
36
|
+
removeFromFavorites,
|
|
37
|
+
};
|
|
38
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useState } from 'react';
|
|
1
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
2
|
import { SafeAreaView, StyleSheet, View } from 'react-native';
|
|
3
3
|
import { IconOutline } from '@ant-design/icons-react-native';
|
|
4
4
|
import { useNavigation } from '@react-navigation/native';
|
|
@@ -6,59 +6,55 @@ import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
|
6
6
|
import { Section, ViewButtonBottom } from '../../commons';
|
|
7
7
|
import { RowUser } from '../../commons/RowUser';
|
|
8
8
|
import WrapHeaderScrollable from '../../commons/Sharing/WrapHeaderScrollable';
|
|
9
|
-
import { Colors, Theme } from '../../configs';
|
|
9
|
+
import { API, Colors, Theme } from '../../configs';
|
|
10
10
|
import { TESTID } from '../../configs/Constants';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const dataContact = [
|
|
14
|
-
{
|
|
15
|
-
id: 1,
|
|
16
|
-
name: 'Peter Pan',
|
|
17
|
-
phone: '0931245690',
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
id: 2,
|
|
21
|
-
name: 'John Wick',
|
|
22
|
-
phone: '0912345678',
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
id: 3,
|
|
26
|
-
name: 'Batoze Pre',
|
|
27
|
-
phone: '0921456876',
|
|
28
|
-
},
|
|
29
|
-
];
|
|
11
|
+
import { axiosGet, axiosPost } from '../../utils/Apis/axios';
|
|
12
|
+
import { ToastBottomHelper } from '../../utils/Utils';
|
|
30
13
|
|
|
31
14
|
export const EmergencyContactsSelectContacts = ({ route }) => {
|
|
32
15
|
const t = useTranslations();
|
|
33
16
|
const { goBack } = useNavigation();
|
|
34
|
-
|
|
17
|
+
const { unitId, group } = route.params;
|
|
18
|
+
const [dataContact, setDataContact] = useState([]);
|
|
19
|
+
const [loading, setLoading] = useState(true);
|
|
35
20
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
21
|
+
const loadMembers = useCallback(async (id) => {
|
|
22
|
+
setLoading(true);
|
|
23
|
+
const { success, data } = await axiosGet(API.SHARE.UNITS_MEMBERS(id));
|
|
24
|
+
if (success) {
|
|
25
|
+
setLoading(false);
|
|
26
|
+
setDataContact(data);
|
|
27
|
+
}
|
|
28
|
+
}, []);
|
|
29
|
+
|
|
30
|
+
const [currentContacts, setCurrentContact] = useState('');
|
|
40
31
|
|
|
41
32
|
const onPressContact = useCallback(
|
|
42
33
|
(contact) => () => {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (indexOfContact > -1) {
|
|
46
|
-
const newContacts = [...currentContacts];
|
|
47
|
-
newContacts.splice(indexOfContact, 1);
|
|
48
|
-
setCurrentContact(newContacts);
|
|
49
|
-
} else {
|
|
50
|
-
setCurrentContact([...currentContacts, contact.phone]);
|
|
51
|
-
}
|
|
34
|
+
setCurrentContact(contact);
|
|
52
35
|
},
|
|
53
|
-
[
|
|
36
|
+
[]
|
|
54
37
|
);
|
|
38
|
+
|
|
39
|
+
const goSave = useCallback(async () => {
|
|
40
|
+
const { success } = await axiosPost(API.EMERGENCY_BUTTON.CREATE_CONTACT(), {
|
|
41
|
+
group: group.id,
|
|
42
|
+
phone_number: currentContacts?.phone_number,
|
|
43
|
+
name: currentContacts?.name,
|
|
44
|
+
});
|
|
45
|
+
if (success) {
|
|
46
|
+
goBack();
|
|
47
|
+
} else {
|
|
48
|
+
ToastBottomHelper.error(t('create_contact_failed'));
|
|
49
|
+
}
|
|
50
|
+
}, [currentContacts, goBack, group.id, t]);
|
|
51
|
+
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
loadMembers(unitId);
|
|
54
|
+
}, [loadMembers, unitId]);
|
|
55
55
|
return (
|
|
56
56
|
<SafeAreaView style={styles.container}>
|
|
57
|
-
<WrapHeaderScrollable
|
|
58
|
-
title={t('select_contacts')}
|
|
59
|
-
// loading={loading}
|
|
60
|
-
// onRefresh={onRefresh}
|
|
61
|
-
>
|
|
57
|
+
<WrapHeaderScrollable title={t('select_contacts')} loading={loading}>
|
|
62
58
|
<Section type={'border'}>
|
|
63
59
|
{dataContact.map((contact, index) => (
|
|
64
60
|
<RowUser
|
|
@@ -69,11 +65,11 @@ export const EmergencyContactsSelectContacts = ({ route }) => {
|
|
|
69
65
|
<IconOutline name={'user'} size={20} color={Colors.White} />
|
|
70
66
|
}
|
|
71
67
|
text={contact.name}
|
|
72
|
-
subtext={contact.
|
|
68
|
+
subtext={contact.phone_number}
|
|
73
69
|
onPress={onPressContact(contact)}
|
|
74
70
|
rightComponent={
|
|
75
71
|
<View style={styles.buttonRemove}>
|
|
76
|
-
{currentContacts
|
|
72
|
+
{currentContacts?.phone_number === contact.phone_number && (
|
|
77
73
|
<IconOutline
|
|
78
74
|
name={'check-circle'}
|
|
79
75
|
size={20}
|
|
@@ -90,7 +86,8 @@ export const EmergencyContactsSelectContacts = ({ route }) => {
|
|
|
90
86
|
leftTitle={t('cancel')}
|
|
91
87
|
onLeftClick={goBack}
|
|
92
88
|
rightTitle={t('save')}
|
|
93
|
-
|
|
89
|
+
onRightClick={goSave}
|
|
90
|
+
rightDisabled={false}
|
|
94
91
|
/>
|
|
95
92
|
</SafeAreaView>
|
|
96
93
|
);
|
|
@@ -5,35 +5,34 @@ import { TESTID } from '../../../configs/Constants';
|
|
|
5
5
|
import { SCProvider } from '../../../context';
|
|
6
6
|
import { mockSCStore } from '../../../context/mockStore';
|
|
7
7
|
|
|
8
|
-
const wrapComponent = (
|
|
8
|
+
const wrapComponent = (route) => (
|
|
9
9
|
<SCProvider initState={mockSCStore({})}>
|
|
10
|
-
<EmergencyContactsSelectContacts />
|
|
10
|
+
<EmergencyContactsSelectContacts route={route} />
|
|
11
11
|
</SCProvider>
|
|
12
12
|
);
|
|
13
13
|
|
|
14
14
|
describe('test EmergencyContactsSelectContacts', () => {
|
|
15
|
+
let route;
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
route = {
|
|
18
|
+
params: {
|
|
19
|
+
unitId: 1,
|
|
20
|
+
group: 1,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
|
|
15
25
|
let tree;
|
|
16
26
|
|
|
17
|
-
test('
|
|
27
|
+
test('onPress ErgencyContactsSelectContacts', async () => {
|
|
18
28
|
act(() => {
|
|
19
|
-
tree = create(wrapComponent());
|
|
29
|
+
tree = create(wrapComponent(route));
|
|
20
30
|
});
|
|
21
31
|
const instance = tree.root;
|
|
22
|
-
const rowUser = instance.findAllByProps({
|
|
23
|
-
testID: TESTID.EMERGENCY_SELECT_CONTACT,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
expect(rowUser).toHaveLength(3);
|
|
27
|
-
});
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const instance = tree.root;
|
|
34
|
-
const rowUser = instance.findAllByProps({
|
|
35
|
-
testID: TESTID.EMERGENCY_SELECT_CONTACT,
|
|
36
|
-
});
|
|
37
|
-
expect(rowUser).toHaveLength(3);
|
|
33
|
+
const rowUser = instance.findAllByProps(
|
|
34
|
+
(item) => item.props.testID === TESTID.EMERGENCY_SELECT_CONTACT
|
|
35
|
+
);
|
|
36
|
+
expect(rowUser[0]).toBeDefined();
|
|
38
37
|
});
|
|
39
38
|
});
|
|
@@ -35,7 +35,9 @@ const MoveToAnotherSubUnit = memo(({ route }) => {
|
|
|
35
35
|
const { params = {} } = route;
|
|
36
36
|
const { unit, sensor, station } = params;
|
|
37
37
|
const { navigate } = useNavigation();
|
|
38
|
-
const [selectedSubUnit, setSelectedSubUnit] = useState(
|
|
38
|
+
const [selectedSubUnit, setSelectedSubUnit] = useState(
|
|
39
|
+
unit.stations?.find((subUnit) => subUnit.id === station.id)
|
|
40
|
+
);
|
|
39
41
|
|
|
40
42
|
const listStationUnit = useMemo(() => {
|
|
41
43
|
return unit.stations.slice(2);
|
|
@@ -36,7 +36,7 @@ describe('test NotificationItem', () => {
|
|
|
36
36
|
id: 1,
|
|
37
37
|
content_code: '',
|
|
38
38
|
is_read: true,
|
|
39
|
-
params:
|
|
39
|
+
params: "{'booking_id': 1, 'booking_id_new': 1}",
|
|
40
40
|
created_at: '',
|
|
41
41
|
icon: '',
|
|
42
42
|
};
|
|
@@ -49,62 +49,47 @@ describe('test NotificationItem', () => {
|
|
|
49
49
|
{
|
|
50
50
|
content_code: NOTIFICATION_TYPES.REMIND_TO_MAKE_PAYMENT,
|
|
51
51
|
screen: Routes.SmartParkingBookingDetails,
|
|
52
|
-
params: { id: 1 },
|
|
52
|
+
params: "{ 'id': 1 }",
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
content_code: NOTIFICATION_TYPES.EXPIRE_PARKING_SESSION,
|
|
56
56
|
screen: Routes.SmartParkingBookingDetails,
|
|
57
|
-
params: { id: 1 },
|
|
57
|
+
params: "{ 'id': 1 }",
|
|
58
58
|
},
|
|
59
59
|
{
|
|
60
60
|
content_code: NOTIFICATION_TYPES.REMIND_TO_SCAN_QR_CODE,
|
|
61
61
|
screen: Routes.SmartParkingBookingDetails,
|
|
62
|
-
params: { id: 1 },
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
content_code: NOTIFICATION_TYPES.USER_CANCEL,
|
|
66
|
-
screen: Routes.MyBookingList,
|
|
67
|
-
params: { tab: 1 },
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
content_code: NOTIFICATION_TYPES.SYSTEM_CANCEL_NO_PAYMENT,
|
|
71
|
-
screen: Routes.MyBookingList,
|
|
72
|
-
params: { tab: 1 },
|
|
62
|
+
params: "{ 'id': 1 }",
|
|
73
63
|
},
|
|
74
64
|
{
|
|
75
65
|
content_code: NOTIFICATION_TYPES.BOOKING_SUCCESSFULLY,
|
|
76
66
|
screen: Routes.SmartParkingBookingDetails,
|
|
77
|
-
params: { id: 1 },
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
content_code: NOTIFICATION_TYPES.PARKING_COMPLETED,
|
|
81
|
-
screen: Routes.MyBookingList,
|
|
82
|
-
params: { tab: 1 },
|
|
67
|
+
params: "{ 'id': 1 }",
|
|
83
68
|
},
|
|
84
69
|
{
|
|
85
70
|
content_code: NOTIFICATION_TYPES.BOOKING_EXPIRED_AND_VIOLATION_CREATED,
|
|
86
71
|
screen: Routes.SmartParkingBookingDetails,
|
|
87
|
-
params: { id: 1 },
|
|
72
|
+
params: "{ 'id': 1 }",
|
|
88
73
|
},
|
|
89
74
|
{
|
|
90
75
|
content_code: NOTIFICATION_TYPES.MOVE_CAR_WITHOUT_PAY_VIOLATION,
|
|
91
76
|
screen: Routes.SmartParkingBookingDetails,
|
|
92
|
-
params: { id: 1 },
|
|
77
|
+
params: "{ 'id': 1 }",
|
|
93
78
|
},
|
|
94
79
|
{
|
|
95
80
|
content_code: NOTIFICATION_TYPES.PAY_FINE_SUCCESSFULLY,
|
|
96
81
|
screen: Routes.SmartParkingBookingDetails,
|
|
97
|
-
params: { id: 1 },
|
|
82
|
+
params: "{ 'id': 1 }",
|
|
98
83
|
},
|
|
99
84
|
{
|
|
100
85
|
content_code: NOTIFICATION_TYPES.STOP_VIOLATION_FREE_PARKING_ZONE,
|
|
101
86
|
screen: Routes.SmartParkingBookingDetails,
|
|
102
|
-
params: { id: 1 },
|
|
87
|
+
params: "{ 'id': 1 }",
|
|
103
88
|
},
|
|
104
89
|
{
|
|
105
90
|
content_code: NOTIFICATION_TYPES.PAY_FINE_AND_EXTEND_SUCCESSFULLY,
|
|
106
91
|
screen: Routes.SmartParkingBookingDetails,
|
|
107
|
-
params: { id: 1 },
|
|
92
|
+
params: "{ 'id': 1 }",
|
|
108
93
|
},
|
|
109
94
|
];
|
|
110
95
|
|
|
@@ -121,7 +106,42 @@ describe('test NotificationItem', () => {
|
|
|
121
106
|
});
|
|
122
107
|
expect(mockNavigate).toHaveBeenCalledWith(Routes.SmartParkingStack, {
|
|
123
108
|
screen: notify.screen,
|
|
124
|
-
params:
|
|
109
|
+
params: { id: 1 },
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const listCaseSmartParking2 = [
|
|
115
|
+
{
|
|
116
|
+
content_code: NOTIFICATION_TYPES.USER_CANCEL,
|
|
117
|
+
screen: Routes.MyBookingList,
|
|
118
|
+
params: "{ 'tab': 1 }",
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
content_code: NOTIFICATION_TYPES.SYSTEM_CANCEL_NO_PAYMENT,
|
|
122
|
+
screen: Routes.MyBookingList,
|
|
123
|
+
params: "{ 'tab': 1 }",
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
content_code: NOTIFICATION_TYPES.PARKING_COMPLETED,
|
|
127
|
+
screen: Routes.MyBookingList,
|
|
128
|
+
params: "{ 'tab': 1 }",
|
|
129
|
+
},
|
|
130
|
+
];
|
|
131
|
+
for (const notify of listCaseSmartParking2) {
|
|
132
|
+
test(`create ItemNotification ${notify.content_code}`, () => {
|
|
133
|
+
item.content_code = notify.content_code;
|
|
134
|
+
act(() => {
|
|
135
|
+
tree = create(wrapComponent(item));
|
|
136
|
+
});
|
|
137
|
+
const instance = tree.root;
|
|
138
|
+
const button = instance.findByType(TouchableOpacity);
|
|
139
|
+
act(() => {
|
|
140
|
+
button.props.onPress();
|
|
141
|
+
});
|
|
142
|
+
expect(mockNavigate).toHaveBeenCalledWith(Routes.SmartParkingStack, {
|
|
143
|
+
screen: notify.screen,
|
|
144
|
+
params: { tab: 1 },
|
|
125
145
|
});
|
|
126
146
|
});
|
|
127
147
|
}
|
|
@@ -160,15 +180,7 @@ describe('test NotificationItem', () => {
|
|
|
160
180
|
for (const sensorType of listSensorType) {
|
|
161
181
|
test(`create ItemNotification NOTIFY_INDICATOR sensor_type ${sensorType}`, () => {
|
|
162
182
|
item.content_code = NOTIFICATION_TYPES.NOTIFY_INDICATOR;
|
|
163
|
-
item.params =
|
|
164
|
-
unit_name: 'EoH Office',
|
|
165
|
-
status: 'Very Poor',
|
|
166
|
-
sensor_type: sensorType,
|
|
167
|
-
unit_id: 5,
|
|
168
|
-
summary_id: 11,
|
|
169
|
-
sensor_id: '',
|
|
170
|
-
});
|
|
171
|
-
|
|
183
|
+
item.params = `{'sensor_type': '${sensorType}', 'unit_id': 5, 'summary_id': 11}`;
|
|
172
184
|
act(() => {
|
|
173
185
|
tree = create(wrapComponent(item));
|
|
174
186
|
});
|
|
@@ -196,14 +208,7 @@ describe('test NotificationItem', () => {
|
|
|
196
208
|
for (const sensorType of listSensorType2) {
|
|
197
209
|
test(`create ItemNotification NOTIFY_INDICATOR sensor_type ${sensorType}`, () => {
|
|
198
210
|
item.content_code = NOTIFICATION_TYPES.NOTIFY_INDICATOR;
|
|
199
|
-
item.params =
|
|
200
|
-
unit_name: 'Lavida Smart Home',
|
|
201
|
-
status: '',
|
|
202
|
-
sensor_type: sensorType,
|
|
203
|
-
unit_id: 70,
|
|
204
|
-
summary_id: '',
|
|
205
|
-
sensor_id: 394,
|
|
206
|
-
});
|
|
211
|
+
item.params = `{'sensor_type': '${sensorType}', 'unit_id': 70, 'sensor_id': 394}`;
|
|
207
212
|
|
|
208
213
|
act(() => {
|
|
209
214
|
tree = create(wrapComponent(item));
|
|
@@ -225,14 +230,8 @@ describe('test NotificationItem', () => {
|
|
|
225
230
|
|
|
226
231
|
test('test onClick Item Notify', () => {
|
|
227
232
|
item.content_code = NOTIFICATION_TYPES.NOTIFY_INDICATOR;
|
|
228
|
-
item.params =
|
|
229
|
-
|
|
230
|
-
status: 'Very Poor',
|
|
231
|
-
sensor_type: 'air_quality',
|
|
232
|
-
unit_id: 5,
|
|
233
|
-
summary_id: 11,
|
|
234
|
-
sensor_id: '',
|
|
235
|
-
});
|
|
233
|
+
item.params =
|
|
234
|
+
"{'sensor_type': 'air_quality', 'unit_id': 5, 'summary_id': 11}";
|
|
236
235
|
item.is_read = false;
|
|
237
236
|
act(() => {
|
|
238
237
|
tree = create(wrapComponent(item));
|
|
@@ -254,9 +253,21 @@ describe('test NotificationItem', () => {
|
|
|
254
253
|
|
|
255
254
|
test('test render Notify not in any case', () => {
|
|
256
255
|
item.content_code = 'NEW CASE';
|
|
257
|
-
item.params =
|
|
258
|
-
|
|
256
|
+
(item.params = "{ 'unit_id': 1 }"),
|
|
257
|
+
act(() => {
|
|
258
|
+
tree = create(wrapComponent(item));
|
|
259
|
+
});
|
|
260
|
+
const instance = tree.root;
|
|
261
|
+
const button = instance.findByType(TouchableOpacity);
|
|
262
|
+
act(() => {
|
|
263
|
+
button.props.onPress();
|
|
259
264
|
});
|
|
265
|
+
expect(mockNavigate).not.toHaveBeenCalledWith();
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
test('test render Notify params is object', () => {
|
|
269
|
+
item.content_code = 'NEW CASE';
|
|
270
|
+
item.params = { unit_id: 1 };
|
|
260
271
|
act(() => {
|
|
261
272
|
tree = create(wrapComponent(item));
|
|
262
273
|
});
|
|
@@ -22,14 +22,24 @@ const NotificationItem = memo(({ item }) => {
|
|
|
22
22
|
return /\B'|'\B/g;
|
|
23
23
|
}, []);
|
|
24
24
|
|
|
25
|
+
const paramsJSON = useMemo(() => {
|
|
26
|
+
if (typeof params === 'object') {
|
|
27
|
+
return params;
|
|
28
|
+
}
|
|
29
|
+
// TODO return this later
|
|
30
|
+
let stringParams = JSON.stringify(params);
|
|
31
|
+
stringParams = stringParams.replace(regex, '"');
|
|
32
|
+
stringParams = stringParams.substring(1, stringParams.length - 1);
|
|
33
|
+
return JSON.parse(stringParams);
|
|
34
|
+
}, [params, regex]);
|
|
35
|
+
|
|
25
36
|
let arrParams = useMemo(() => {
|
|
26
37
|
const values = [];
|
|
27
|
-
const paramsJSON = JSON.parse(params.replace(regex, '"'));
|
|
28
38
|
Object.entries(paramsJSON).forEach(([key, value]) => {
|
|
29
39
|
values.push(value);
|
|
30
40
|
});
|
|
31
41
|
return values;
|
|
32
|
-
}, [
|
|
42
|
+
}, [paramsJSON]);
|
|
33
43
|
|
|
34
44
|
const customColorText = (text, params) => {
|
|
35
45
|
return text.split('**').map((str, i) =>
|
|
@@ -46,7 +56,6 @@ const NotificationItem = memo(({ item }) => {
|
|
|
46
56
|
};
|
|
47
57
|
|
|
48
58
|
const renderItem = useCallback(() => {
|
|
49
|
-
const paramsJSON = JSON.parse(params.replace(regex, '"'));
|
|
50
59
|
const booking_id = paramsJSON.booking_id && paramsJSON.booking_id;
|
|
51
60
|
const unitId = paramsJSON?.unit_id;
|
|
52
61
|
const sensorId = paramsJSON?.sensor_id;
|
|
@@ -513,7 +522,7 @@ const NotificationItem = memo(({ item }) => {
|
|
|
513
522
|
iconContent: <Image source={Images.logo} style={styles.logo} />,
|
|
514
523
|
};
|
|
515
524
|
}
|
|
516
|
-
}, [arrParams, content_code, navigation,
|
|
525
|
+
}, [arrParams, content_code, navigation, paramsJSON, t]);
|
|
517
526
|
|
|
518
527
|
const { content, redirect, iconContent } = renderItem() || {};
|
|
519
528
|
|