@eohjsc/react-native-smart-city 0.2.82 → 0.2.85

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.
Files changed (99) hide show
  1. package/assets/images/Event.svg +9 -0
  2. package/assets/images/brightness.svg +12 -0
  3. package/package.json +4 -2
  4. package/src/Images/Common/SuccessfullyConnected.svg +4 -0
  5. package/src/Images/Common/eye-closed.png +0 -0
  6. package/src/Images/Common/eye-closed@2x.png +0 -0
  7. package/src/Images/Common/eye-closed@3x.png +0 -0
  8. package/src/Images/Common/eye.png +0 -0
  9. package/src/Images/Common/eye@2x.png +0 -0
  10. package/src/Images/Common/eye@3x.png +0 -0
  11. package/src/commons/ActionGroup/CurtainButtonTemplate.js +32 -21
  12. package/src/commons/ActionGroup/LightActionTemplate.js +103 -0
  13. package/src/commons/ActionGroup/LightActionTemplateStyles.js +57 -0
  14. package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +8 -6
  15. package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +33 -31
  16. package/src/commons/ActionGroup/OnOffTemplate/index.js +11 -3
  17. package/src/commons/ActionGroup/OneBigButtonTemplate.js +10 -7
  18. package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +5 -2
  19. package/src/commons/ActionGroup/StatesGridActionTemplate.js +7 -3
  20. package/src/commons/ActionGroup/ThreeButtonTemplate.js +33 -24
  21. package/src/commons/ActionGroup/__test__/LightActionTemplate.test.js +59 -0
  22. package/src/commons/ActionGroup/__test__/OnOffTemplate.test.js +18 -6
  23. package/src/commons/ActionGroup/__test__/OneBigButtonTemplate.test.js +9 -1
  24. package/src/commons/ActionGroup/__test__/OptionsDropdownTemplate.test.js +25 -13
  25. package/src/commons/ActionGroup/__test__/index.test.js +48 -14
  26. package/src/commons/ActionGroup/index.js +3 -0
  27. package/src/commons/Automate/ItemAutomate.js +1 -1
  28. package/src/commons/Automate/ItemAutomateStyles.js +5 -1
  29. package/src/commons/CardShadow/index.js +5 -2
  30. package/src/commons/CardShadow/styles.js +2 -3
  31. package/src/commons/ConnectingProcess/DeviceItem/DeviceItem.js +16 -0
  32. package/src/commons/ConnectingProcess/DeviceItem/DeviceItemStyles.js +42 -0
  33. package/src/commons/ConnectingProcess/__test__/Connecting.test.js +27 -0
  34. package/src/commons/ConnectingProcess/__test__/DeviceItem.test.js +18 -0
  35. package/src/commons/ConnectingProcess/index.js +202 -0
  36. package/src/commons/ConnectingProcess/styles.js +69 -0
  37. package/src/commons/Device/HorizontalBarChart.js +7 -1
  38. package/src/commons/Device/ItemDevice.js +8 -5
  39. package/src/commons/Device/LinearChart.js +1 -0
  40. package/src/commons/Device/WaterQualitySensor/ListQualityIndicator.js +1 -1
  41. package/src/commons/Device/WaterQualitySensor/QualityIndicatorsItem.js +1 -1
  42. package/src/commons/EmergencyButton/AlertSendConfirm.js +2 -2
  43. package/src/commons/EmergencyButton/AlertSent.js +2 -2
  44. package/src/commons/Form/TextInputPassword.js +1 -1
  45. package/src/commons/FullLoading/index.js +35 -0
  46. package/src/commons/SubUnit/Favorites/index.js +2 -0
  47. package/src/commons/SubUnit/OneTap/ItemOneTap.js +3 -0
  48. package/src/commons/SubUnit/ShortDetail.js +7 -1
  49. package/src/commons/index.js +2 -0
  50. package/src/configs/API.js +6 -4
  51. package/src/configs/Constants.js +25 -0
  52. package/src/configs/Images.js +2 -0
  53. package/src/context/actionType.ts +2 -0
  54. package/src/context/reducer.ts +10 -0
  55. package/src/hooks/Common/useBlockBackAndroid.js +3 -1
  56. package/src/iot/RemoteControl/Internet.js +8 -1
  57. package/src/iot/RemoteControl/index.js +4 -2
  58. package/src/navigations/AddDeviceStack.js +10 -0
  59. package/src/screens/AddCommon/SelectSubUnit.js +29 -6
  60. package/src/screens/AddCommon/SelectUnit.js +24 -2
  61. package/src/screens/AddCommon/__test__/SelectSubUnit.test.js +120 -1
  62. package/src/screens/AddCommon/__test__/SelectUnit.test.js +16 -1
  63. package/src/screens/AddNewAction/SelectAction.js +46 -28
  64. package/src/screens/AddNewAutoSmart/__test__/AddNewAutoSmart.test.js +3 -3
  65. package/src/screens/AddNewAutoSmart/index.js +18 -1
  66. package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +55 -16
  67. package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +52 -23
  68. package/src/screens/AddNewGateway/SelectGateway.js +132 -0
  69. package/src/screens/AddNewGateway/SelectGatewayStyles.js +55 -0
  70. package/src/screens/AddNewGateway/__test__/SetupGateway.test.js +0 -52
  71. package/src/screens/Device/EditDevice/__test__/EditDevice.test.js +2 -2
  72. package/src/screens/Device/EditDevice/index.js +2 -2
  73. package/src/screens/Device/__test__/detail.test.js +18 -11
  74. package/src/screens/Device/components/SensorConnectStatusViewHeader.js +2 -2
  75. package/src/screens/Device/components/SensorDisplayItem.js +2 -2
  76. package/src/screens/Device/detail.js +64 -26
  77. package/src/screens/Device/styles.js +2 -0
  78. package/src/screens/Notification/__test__/NotificationItem.test.js +197 -15
  79. package/src/screens/Notification/components/NotificationItem.js +188 -14
  80. package/src/screens/Notification/styles/NotificationItemStyles.js +3 -3
  81. package/src/screens/ScanChipQR/__test__/ScanChipQR.test.js +10 -7
  82. package/src/screens/ScanChipQR/hooks/index.js +48 -40
  83. package/src/screens/SubUnit/AddSubUnit.js +4 -1
  84. package/src/screens/SubUnit/__test__/AddSubUnit.test.js +148 -0
  85. package/src/screens/Unit/Detail.js +33 -1
  86. package/src/screens/Unit/ManageUnit.js +1 -1
  87. package/src/screens/Unit/ManageUnitStyles.js +0 -6
  88. package/src/screens/Unit/SmartAccount.js +5 -1
  89. package/src/screens/Unit/Summaries.js +2 -2
  90. package/src/screens/Unit/__test__/CheckSendEmail.test.js +10 -0
  91. package/src/screens/Unit/__test__/Detail.test.js +10 -0
  92. package/src/screens/Unit/components/__test__/SharedUnit.test.js +21 -2
  93. package/src/screens/UnitSummary/__test__/index.test.js +3 -3
  94. package/src/screens/UnitSummary/components/RunningDevices/__test__/index.test.js +2 -2
  95. package/src/screens/UnitSummary/index.js +52 -9
  96. package/src/utils/Apis/axios.js +1 -1
  97. package/src/utils/I18n/translations/en.json +16 -0
  98. package/src/utils/I18n/translations/vi.json +16 -1
  99. package/src/utils/Route/index.js +2 -0
@@ -1,10 +1,16 @@
1
- import React, { memo, useState, useCallback } from 'react';
1
+ import React, {
2
+ memo,
3
+ useState,
4
+ useCallback,
5
+ useContext,
6
+ useEffect,
7
+ } from 'react';
2
8
  import {
3
9
  View,
4
10
  StyleSheet,
5
11
  TouchableOpacity,
6
12
  ScrollView,
7
- TextInput,
13
+ ActivityIndicator,
8
14
  } from 'react-native';
9
15
  import { HeaderCustom } from '../../../commons/Header';
10
16
  import { Colors } from '../../../configs';
@@ -12,6 +18,9 @@ import Text from '../../../commons/Text';
12
18
  import { useTranslations } from '../../../hooks/Common/useTranslations';
13
19
  import WifiIcon from '../../../../assets/images/wifi.svg';
14
20
  import ButtonPopup from '../../../commons/ButtonPopup';
21
+ import TextInputPassword from '../../../commons/Form/TextInputPassword';
22
+ import { SCContext, useSCContextSelector } from '../../../context';
23
+ import { Action } from '../../../context/actionType';
15
24
 
16
25
  const GatewayWifiList = memo(({ route }) => {
17
26
  const { list_wifi, socket } = route.params;
@@ -20,6 +29,11 @@ const GatewayWifiList = memo(({ route }) => {
20
29
  const [isShowPopupPassword, setIsShowPopupPassword] = useState(false);
21
30
  const [password, setPassword] = useState('');
22
31
  const [selectedWifi, setSelectedWifi] = useState('');
32
+ const { setAction } = useContext(SCContext);
33
+
34
+ const isConnectWifiGateway = useSCContextSelector(
35
+ (state) => state.app.isConnectWifiGateway
36
+ );
23
37
 
24
38
  const showPopupPassword = (ssid) => {
25
39
  setIsShowPopupPassword(true);
@@ -32,21 +46,27 @@ const GatewayWifiList = memo(({ route }) => {
32
46
  },
33
47
  [setPassword]
34
48
  );
35
-
36
- const connectWifi = async () => {
37
- await socket.send(
38
- JSON.stringify({
39
- type: 'connect',
40
- data: { wifi: { ssid: selectedWifi, pass: password } },
41
- }),
42
- undefined,
43
- undefined,
44
- 54321,
45
- '192.168.27.1',
46
- undefined
47
- );
48
- };
49
-
49
+ const connectWifi = useCallback(async () => {
50
+ if (!isConnectWifiGateway) {
51
+ await socket.send(
52
+ JSON.stringify({
53
+ type: 'connect',
54
+ data: { wifi: { ssid: selectedWifi, pass: password } },
55
+ }),
56
+ undefined,
57
+ undefined,
58
+ 54321,
59
+ '192.168.27.1',
60
+ undefined
61
+ );
62
+ setAction(Action.IS_CONNECT_WIFI_GATEWAY, true);
63
+ }
64
+ }, [isConnectWifiGateway, password, selectedWifi, setAction, socket]);
65
+ useEffect(() => {
66
+ if (!isConnectWifiGateway) {
67
+ setIsShowPopupPassword(false);
68
+ }
69
+ }, [isConnectWifiGateway]);
50
70
  return (
51
71
  <View style={styles.screen}>
52
72
  <HeaderCustom title={t('connect_device')} isShowSeparator />
@@ -79,19 +99,28 @@ const GatewayWifiList = memo(({ route }) => {
79
99
 
80
100
  <ButtonPopup
81
101
  visible={isShowPopupPassword}
82
- mainTitle={t('connect')}
83
- onPressMain={() => connectWifi()}
102
+ mainTitle={
103
+ isConnectWifiGateway ? (
104
+ <ActivityIndicator color={Colors.White} size={'small'} />
105
+ ) : (
106
+ t('connect')
107
+ )
108
+ }
109
+ onPressMain={connectWifi}
84
110
  secondaryTitle={t('cancel')}
111
+ typeSecondary={isConnectWifiGateway ? 'disabled' : 'cancel'}
85
112
  onPressSecondary={() => setIsShowPopupPassword(false)}
86
113
  hideClose={true}
87
114
  >
88
115
  <>
89
116
  <Text>{t('enter_wifi_password')}</Text>
90
- <TextInput
91
- secureTextEntry={true}
92
- style={styles.input}
93
- onChangeText={onPasswordChange}
117
+ <TextInputPassword
118
+ secureTextEntry
119
+ placeholder={t('password')}
120
+ onChange={onPasswordChange}
94
121
  value={password}
122
+ textInputStyle={styles.input}
123
+ selectionColor={Colors.Primary}
95
124
  />
96
125
  </>
97
126
  </ButtonPopup>
@@ -0,0 +1,132 @@
1
+ import React, { useCallback, useEffect, useState } from 'react';
2
+ import { useIsFocused, useNavigation } from '@react-navigation/native';
3
+ import { useTranslations } from '../../hooks/Common/useTranslations';
4
+ import { SafeAreaView, ScrollView, TouchableOpacity, View } from 'react-native';
5
+
6
+ import { API } from '../../configs';
7
+ import { Section, RadioCircle, ViewButtonBottom } from '../../commons';
8
+ import { axiosGet } from '../../utils/Apis/axios';
9
+ import Text from '../../commons/Text';
10
+ import Routes from '../../utils/Route';
11
+ import { TESTID } from '../../configs/Constants';
12
+ import styles from './SelectGatewayStyles';
13
+
14
+ const AddNewGatewaySelectGateway = ({ route }) => {
15
+ const t = useTranslations();
16
+ const navigation = useNavigation();
17
+ const isFocused = useIsFocused();
18
+ const { addType, unit_id, scan_sensor_data, devicePrefixName } = route.params;
19
+ const [selectedIndex, setSelectedIndex] = useState(-1);
20
+
21
+ const [gateways, setGateways] = useState([]);
22
+ const [title, setTitle] = useState('');
23
+ const [subTitle, setSubTitle] = useState('');
24
+ const [gateway, setGateway] = useState({});
25
+
26
+ useEffect(() => {
27
+ switch (addType) {
28
+ case 'AddDeviceNewFlow':
29
+ setTitle(t('text_select_a_gateway'));
30
+ setSubTitle(t('text_select_a_gateway'));
31
+ break;
32
+ default:
33
+ setTitle(t('text_select_a_gateway'));
34
+ setSubTitle(t('text_select_a_gateway'));
35
+ break;
36
+ }
37
+ }, [title, subTitle, addType, t]);
38
+
39
+ const fetchDetails = useCallback(async () => {
40
+ const { success, data } = await axiosGet(
41
+ API.CHIP.GET_CHIPS_FROM_UNIT(unit_id)
42
+ );
43
+ if (success) {
44
+ setGateways(data);
45
+ }
46
+ }, [unit_id]);
47
+
48
+ useEffect(() => {
49
+ isFocused && fetchDetails();
50
+ }, [fetchDetails, isFocused]);
51
+
52
+ const onPressNext = useCallback(() => {
53
+ switch (addType) {
54
+ case 'AddDeviceNewFlow':
55
+ navigation.navigate(Routes.AddCommonSelectSubUnit, {
56
+ unit_id: unit_id,
57
+ addType: 'AddDeviceNewFlow',
58
+ scan_sensor_data,
59
+ gateway,
60
+ devicePrefixName,
61
+ });
62
+ break;
63
+ default:
64
+ break;
65
+ }
66
+ }, [
67
+ addType,
68
+ devicePrefixName,
69
+ gateway,
70
+ navigation,
71
+ scan_sensor_data,
72
+ unit_id,
73
+ ]);
74
+
75
+ const handleSelectIndex = (index) => {
76
+ setGateway(gateways[index]);
77
+ if (index !== selectedIndex) {
78
+ setSelectedIndex(index);
79
+ } else {
80
+ setSelectedIndex(-1);
81
+ }
82
+ };
83
+
84
+ return (
85
+ <SafeAreaView style={styles.container}>
86
+ <Text semibold style={styles.title}>
87
+ {title}
88
+ </Text>
89
+ <Text style={styles.subtitle}>{subTitle}</Text>
90
+ <View style={styles.contentContainer}>
91
+ <ScrollView
92
+ style={styles.scrollContainer}
93
+ showsVerticalScrollIndicator={false}
94
+ >
95
+ <Section type={'border'}>
96
+ {gateways.map((item, index) => (
97
+ <TouchableOpacity
98
+ key={index}
99
+ style={styles.rowContainer}
100
+ onPress={() => handleSelectIndex(index)}
101
+ >
102
+ <RadioCircle
103
+ active={selectedIndex === index}
104
+ testID={TESTID.SELECT_GATEWAY_RADIO_BUTTON}
105
+ />
106
+ <TouchableOpacity
107
+ style={styles.row}
108
+ onPress={() => handleSelectIndex(index)}
109
+ testID={TESTID.SELECT_GATEWAY_NAME}
110
+ >
111
+ <Text style={styles.text} testID={TESTID.SELECT_GATEWAY_NAME}>
112
+ {item.name}
113
+ </Text>
114
+ </TouchableOpacity>
115
+ </TouchableOpacity>
116
+ ))}
117
+ </Section>
118
+ </ScrollView>
119
+ <ViewButtonBottom
120
+ leftTitle={t('cancel')}
121
+ onLeftClick={() => navigation.goBack()}
122
+ rightTitle={t('next')}
123
+ rightDisabled={selectedIndex === -1}
124
+ onRightClick={onPressNext}
125
+ testIDPrefix={TESTID.PREFIX.SELECT_UNIT}
126
+ />
127
+ </View>
128
+ </SafeAreaView>
129
+ );
130
+ };
131
+
132
+ export default AddNewGatewaySelectGateway;
@@ -0,0 +1,55 @@
1
+ import { Colors } from '../../configs';
2
+
3
+ import { StyleSheet, StatusBar, Platform } from 'react-native';
4
+
5
+ export default StyleSheet.create({
6
+ container: {
7
+ flex: 1,
8
+ backgroundColor: Colors.Gray2,
9
+ paddingTop: Platform.OS === 'android' ? StatusBar.currentHeight : 0,
10
+ },
11
+ contentContainer: {
12
+ flex: 1,
13
+ justifyContent: 'space-between',
14
+ },
15
+ scrollContainer: {
16
+ width: '100%',
17
+ flex: 1,
18
+ },
19
+ title: {
20
+ color: Colors.Gray9,
21
+ fontSize: 20,
22
+ lineHeight: 28,
23
+ marginTop: 8,
24
+ marginBottom: 4,
25
+ marginLeft: 16,
26
+ },
27
+ subtitle: {
28
+ color: Colors.Gray8,
29
+ fontSize: 14,
30
+ lineHeight: 22,
31
+ marginLeft: 16,
32
+ marginBottom: 16,
33
+ },
34
+ row: {
35
+ flex: 1,
36
+ paddingVertical: 16,
37
+ borderBottomColor: Colors.Gray4,
38
+ borderBottomWidth: 1,
39
+ marginRight: 24,
40
+ marginLeft: 16,
41
+ },
42
+ rowContainer: {
43
+ flexDirection: 'row',
44
+ alignItems: 'center',
45
+ paddingLeft: 16,
46
+ },
47
+ text: {
48
+ fontSize: 16,
49
+ lineHeight: 24,
50
+ color: Colors.Gray9,
51
+ },
52
+ buttonAdd: {
53
+ marginHorizontal: 16,
54
+ },
55
+ });
@@ -7,9 +7,6 @@ import { SCProvider } from '../../../context';
7
7
  import { mockSCStore } from '../../../context/mockStore';
8
8
  import SetupGatewayWifi from '../SetupGatewayWifi';
9
9
  import DisplayChecking from '../../../commons/DisplayChecking';
10
- import { AlertAction } from '../../../commons';
11
- import _TextInputPassword from '../../../commons/Form/TextInputPassword';
12
- import _TextInput from '../../../commons/Form/TextInput';
13
10
 
14
11
  const wrapComponent = (route) => (
15
12
  <SCProvider initState={mockSCStore({})}>
@@ -90,53 +87,4 @@ describe('Test SetupGatewayWifi', () => {
90
87
  const displayLoadingConnect = instance.findByType(DisplayChecking);
91
88
  expect(displayLoadingConnect.props.visible).toBeTruthy();
92
89
  });
93
-
94
- test('test render AlertAction', async () => {
95
- await act(async () => {
96
- tree = await create(wrapComponent(route));
97
- });
98
- const instance = tree.root;
99
- const alertAction = instance.findByType(AlertAction);
100
- await act(async () => {
101
- alertAction.props.hideModal();
102
- alertAction.props.leftButtonClick();
103
- });
104
- expect(alertAction).toBeDefined();
105
- });
106
-
107
- test('test render _TextInputPassword', async () => {
108
- await act(async () => {
109
- tree = await create(wrapComponent(route));
110
- });
111
- const instance = tree.root;
112
- const textInputPassword = instance.findByType(_TextInputPassword);
113
- await act(async () => {
114
- textInputPassword.props.onChange('new_name');
115
- });
116
- expect(textInputPassword.props.value).toEqual('new_name');
117
- });
118
-
119
- test('test render TextInput', async () => {
120
- await act(async () => {
121
- tree = await create(wrapComponent(route));
122
- });
123
- const instance = tree.root;
124
- const textInput = instance.findByType(_TextInput);
125
- await act(async () => {
126
- textInput.props.onChange('new_text');
127
- });
128
- expect(textInput.props.value).toEqual('new_text');
129
- });
130
-
131
- test('test render DisplayChecking', async () => {
132
- await act(async () => {
133
- tree = await create(wrapComponent(route));
134
- });
135
- const instance = tree.root;
136
- const displayChecking = instance.findByType(DisplayChecking);
137
- await act(async () => {
138
- displayChecking.props.onClose();
139
- });
140
- expect(displayChecking).toBeDefined();
141
- });
142
90
  });
@@ -90,7 +90,7 @@ describe('Test EditDevice', () => {
90
90
  await act(async () => {
91
91
  await alertAction.props.rightButtonClick();
92
92
  });
93
- expect(axios.patch).toHaveBeenCalledWith(API.SENSOR.RENAME_SENSOR(1), {
93
+ expect(axios.patch).toHaveBeenCalledWith(API.SENSOR.SENSOR_DETAIL(1), {
94
94
  name: 'new_name',
95
95
  });
96
96
  expect(alertAction.props.visible).toBeFalsy();
@@ -119,7 +119,7 @@ describe('Test EditDevice', () => {
119
119
  await act(async () => {
120
120
  await alertAction.props.rightButtonClick();
121
121
  });
122
- expect(axios.delete).toHaveBeenCalledWith(API.SENSOR.REMOVE_SENSOR(1));
122
+ expect(axios.delete).toHaveBeenCalledWith(API.SENSOR.SENSOR_DETAIL(1));
123
123
  expect(alertAction.props.visible).toBeFalsy();
124
124
  expect(mockPop).toHaveBeenCalled();
125
125
  });
@@ -29,7 +29,7 @@ const EditDevice = memo(() => {
29
29
  useEditDevice();
30
30
  const renameSensor = useCallback(async () => {
31
31
  const { success, data } = await axiosPatch(
32
- API.SENSOR.RENAME_SENSOR(sensor?.id),
32
+ API.SENSOR.SENSOR_DETAIL(sensor?.id),
33
33
  {
34
34
  name: inputName,
35
35
  }
@@ -53,7 +53,7 @@ const EditDevice = memo(() => {
53
53
 
54
54
  const deleteSensor = useCallback(async () => {
55
55
  hideAlertAction();
56
- const { success } = await axiosDelete(API.SENSOR.REMOVE_SENSOR(sensor?.id));
56
+ const { success } = await axiosDelete(API.SENSOR.SENSOR_DETAIL(sensor?.id));
57
57
 
58
58
  if (success) {
59
59
  navigation.pop(2);
@@ -93,7 +93,7 @@ describe('test DeviceDetail', () => {
93
93
  beforeEach(() => {
94
94
  route = {
95
95
  params: {
96
- unit: {
96
+ unitData: {
97
97
  id: 1,
98
98
  name: 'Unit name',
99
99
  address: '298 Dien Bien Phu',
@@ -105,10 +105,11 @@ describe('test DeviceDetail', () => {
105
105
  id: 2,
106
106
  name: 'Station name',
107
107
  },
108
- sensor: {
108
+ sensorData: {
109
109
  id: 1,
110
110
  is_managed_by_backend: true,
111
111
  station: { id: 2, name: 'Station name' },
112
+ name: 'Sensor name',
112
113
  },
113
114
  title: 'Button',
114
115
  },
@@ -252,7 +253,9 @@ describe('test DeviceDetail', () => {
252
253
  });
253
254
  expect(axios.post).toHaveBeenCalledWith(API.SENSOR.QUICK_ACTION(1), {
254
255
  key: responseDisplay.data.items[1].configuration.configuration.action1,
256
+ data: null,
255
257
  source: 'internet',
258
+ action_name: undefined,
256
259
  });
257
260
 
258
261
  const button2 = instance.find(
@@ -263,7 +266,9 @@ describe('test DeviceDetail', () => {
263
266
  });
264
267
  expect(axios.post).toHaveBeenCalledWith(API.SENSOR.QUICK_ACTION(1), {
265
268
  key: responseDisplay.data.items[1].configuration.configuration.action2,
269
+ data: null,
266
270
  source: 'internet',
271
+ action_name: undefined,
267
272
  });
268
273
 
269
274
  const button3 = instance.find(
@@ -274,7 +279,9 @@ describe('test DeviceDetail', () => {
274
279
  });
275
280
  expect(axios.post).toHaveBeenCalledWith(API.SENSOR.QUICK_ACTION(1), {
276
281
  key: responseDisplay.data.items[1].configuration.configuration.action3,
282
+ data: null,
277
283
  source: 'internet',
284
+ action_name: undefined,
278
285
  });
279
286
  });
280
287
 
@@ -628,7 +635,7 @@ describe('test DeviceDetail', () => {
628
635
  });
629
636
 
630
637
  test('not fetch value if not managed by backend', async () => {
631
- route.params.sensor.is_managed_by_backend = false;
638
+ route.params.sensorData.is_managed_by_backend = false;
632
639
 
633
640
  await act(async () => {
634
641
  tree = await create(wrapComponent(account, route));
@@ -638,7 +645,7 @@ describe('test DeviceDetail', () => {
638
645
  });
639
646
 
640
647
  test('render CurrentRainSensor but is other device', async () => {
641
- route.params.sensor.is_other_device = true;
648
+ route.params.sensorData.is_other_device = true;
642
649
  route.params.isGGHomeConnected = true;
643
650
 
644
651
  const responseDisplay = {
@@ -708,9 +715,9 @@ describe('test DeviceDetail', () => {
708
715
  });
709
716
 
710
717
  test('Add device to Favourites', async () => {
711
- const unit_id = route.params.unit.id;
718
+ const unit_id = route.params.unitData.id;
712
719
  const station_id = route.params.station.id;
713
- const sensor = route.params.sensor;
720
+ const sensor = route.params.sensorData;
714
721
  sensor.is_favourite = false;
715
722
 
716
723
  await act(async () => {
@@ -736,9 +743,9 @@ describe('test DeviceDetail', () => {
736
743
  });
737
744
 
738
745
  test('Remove device from Favourites', async () => {
739
- const unit_id = route.params.unit.id;
746
+ const unit_id = route.params.unitData.id;
740
747
  const station_id = route.params.station.id;
741
- const sensor = route.params.sensor;
748
+ const sensor = route.params.sensorData;
742
749
  sensor.is_favourite = true;
743
750
 
744
751
  await act(async () => {
@@ -810,12 +817,12 @@ describe('test DeviceDetail', () => {
810
817
  await menu.props.onItemClick(gotoActivityLog);
811
818
  });
812
819
  expect(mockedNavigate).toHaveBeenCalledWith(Routes.ActivityLog, {
813
- id: route.params.sensor.id,
820
+ id: route.params.sensorData.id,
814
821
  type: 'action',
815
- share: route.params.unit,
822
+ share: route.params.unitData,
816
823
  filterEnabled: {
817
824
  date: true,
818
- user: Boolean(route.params.unit.id),
825
+ user: Boolean(route.params.unitData.id),
819
826
  },
820
827
  });
821
828
  });
@@ -3,7 +3,7 @@ import { ConnectedViewHeader, DisconnectedView } from '../../../commons/Device';
3
3
  import { DEVICE_TYPE } from '../../../configs/Constants';
4
4
 
5
5
  export const SensorConnectStatusViewHeader = (props) => {
6
- if (!!props.sensor && !props.sensor.is_other_device) {
6
+ if (!!props.sensor && !props.sensor?.is_other_device) {
7
7
  if (props.connected) {
8
8
  return (
9
9
  <>
@@ -31,7 +31,7 @@ export const SensorConnectStatusViewHeader = (props) => {
31
31
  return <DisconnectedView sensor={props.sensor} />;
32
32
  }
33
33
  } else {
34
- if (props.sensor.device_type === DEVICE_TYPE.LG_THINQ) {
34
+ if (props.sensor?.device_type === DEVICE_TYPE.LG_THINQ) {
35
35
  return (
36
36
  <>
37
37
  <ConnectedViewHeader lastUpdated={props.lastUpdated} />
@@ -40,8 +40,8 @@ export const SensorDisplayItem = ({
40
40
  const t = useTranslations();
41
41
  const userId = useSCContextSelector((state) => state.auth.account.user.id);
42
42
  const doAction = useCallback(
43
- (action, data) => {
44
- sendRemoteCommand(sensor, action, data, userId);
43
+ (action, data, actionName) => {
44
+ sendRemoteCommand(sensor, action, data, userId, actionName);
45
45
  },
46
46
  [sensor, userId]
47
47
  );