@eohjsc/react-native-smart-city 0.3.48 → 0.3.50

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 (196) hide show
  1. package/package.json +4 -4
  2. package/src/Images/DevMode/file_copy.svg +3 -0
  3. package/src/Images/DevMode/inforCode.png +0 -0
  4. package/src/Images/DevMode/inforCode@2x.png +0 -0
  5. package/src/Images/DevMode/inforCode@3x.png +0 -0
  6. package/src/commons/Action/__test__/ItemQuickAction.test.js +0 -7
  7. package/src/commons/ActionGroup/OnOffTemplate/index.js +6 -8
  8. package/src/commons/ActionGroup/SliderRangeTemplate.js +7 -2
  9. package/src/commons/ActionGroup/__test__/ColorPickerTemplate.test.js +1 -8
  10. package/src/commons/ActionGroup/__test__/OnOffTemplate.test.js +99 -1
  11. package/src/commons/ActionGroup/__test__/SliderRangeTemplate.test.js +28 -11
  12. package/src/commons/ActionTemplate/__test__/CurtainAction.test.js +64 -0
  13. package/src/commons/ActionTemplate/__test__/OnOffSmartLockAction.test.js +54 -0
  14. package/src/commons/ActionTemplate/__test__/index.test.js +0 -7
  15. package/src/commons/Dashboard/MyPinnedSharedUnit/index.js +3 -3
  16. package/src/commons/Dashboard/MyUnit/__test__/MyUnit.test.js +1 -1
  17. package/src/commons/Dashboard/MyUnit/index.js +30 -4
  18. package/src/commons/DevMode/Styles/ItemStyles.js +1 -1
  19. package/src/commons/Device/HorizontalBarChart.js +0 -1
  20. package/src/commons/Device/PMSensor/PMSensorIndicatior.js +4 -1
  21. package/src/commons/FourButtonFilterHistory/__test__/FourButtonFilterHistory.test.js +0 -7
  22. package/src/commons/Header/HeaderCustom.js +13 -6
  23. package/src/commons/MediaPlayer/__test__/index.test.js +0 -7
  24. package/src/commons/MediaPlayerDetail/__test__/MediaPlayerFull.test.js +0 -1
  25. package/src/commons/MenuActionMore/index.js +4 -1
  26. package/src/commons/NavBar/index.js +1 -1
  27. package/src/commons/OneTapTemplate/OptionsDropdownActionTemplate.js +1 -1
  28. package/src/commons/OneTapTemplate/__test__/NumberUpDownActionTemplate.test.js +0 -7
  29. package/src/commons/OneTapTemplate/__test__/OptionsDropdownActionTemplate.test.js +0 -7
  30. package/src/commons/OneTapTemplate/__test__/StatesGridActionTemplate.test.js +0 -7
  31. package/src/commons/Processing/styles.js +0 -2
  32. package/src/commons/RowItem/index.js +6 -1
  33. package/src/commons/SelectUnit/index.js +4 -1
  34. package/src/commons/Sharing/WrapHeaderScrollable.js +5 -4
  35. package/src/commons/StatusBox/styles.js +8 -3
  36. package/src/commons/SubUnit/__test__/Favorites.test.js +0 -7
  37. package/src/commons/SubUnit/__test__/ShortDetail.test.js +0 -7
  38. package/src/commons/Tabbar/__test__/index.test.js +0 -7
  39. package/src/commons/Unit/__test__/HeaderUnit.test.js +0 -5
  40. package/src/commons/UnitSummary/ConfigHistoryChart/__test__/ConfigHistoryChart.test.js +9 -9
  41. package/src/commons/UnitSummary/ConfigHistoryChart/index.js +41 -39
  42. package/src/configs/API.js +28 -0
  43. package/src/configs/AccessibilityLabel.js +13 -0
  44. package/src/configs/Colors.js +4 -0
  45. package/src/configs/Constants.js +8 -0
  46. package/src/configs/Images.js +1 -0
  47. package/src/configs/SCConfig.js +3 -0
  48. package/src/context/actionType.ts +8 -1
  49. package/src/context/mockStore.ts +8 -2
  50. package/src/context/reducer.ts +27 -4
  51. package/src/hooks/IoT/__test__/useWatchConfigs.test.js +46 -0
  52. package/src/hooks/IoT/useBluetoothConnection.js +78 -4
  53. package/src/hooks/IoT/useBluetoothDeviceConnected.js +1 -1
  54. package/src/iot/RemoteControl/Bluetooth.js +0 -16
  55. package/src/iot/RemoteControl/__test__/Bluetooth.test.js +0 -25
  56. package/src/navigations/AddDeviceStack.js +0 -5
  57. package/src/navigations/Main.js +39 -0
  58. package/src/navigations/UnitStack.js +23 -9
  59. package/src/screens/AQIGuide/index.js +2 -2
  60. package/src/screens/ActivityLog/__test__/FilterPopup.test.js +0 -7
  61. package/src/screens/ActivityLog/__test__/ItemLog.test.js +0 -7
  62. package/src/screens/ActivityLog/__test__/index.test.js +0 -7
  63. package/src/screens/ActivityLog/styles/itemLogStyles.js +1 -0
  64. package/src/screens/AddLocationMaps/__test__/index.test.js +0 -7
  65. package/src/screens/AddNewAction/SelectAction.js +22 -18
  66. package/src/screens/AddNewAction/__test__/SelectAction.test.js +35 -16
  67. package/src/screens/AddNewAction/__test__/SelectSensorDevices.test.js +0 -7
  68. package/src/screens/AddNewDevice/__test__/AddNewDevice.test.js +1 -5
  69. package/src/screens/AddNewGateway/ConnectingDevice.js +25 -3
  70. package/src/screens/AddNewGateway/ConnectingWifiGuide.js +1 -1
  71. package/src/screens/AddNewGateway/ConnectingWifiGuideStyles.js +10 -0
  72. package/src/screens/AddNewGateway/ConnectingZigbeeDevice.js +5 -6
  73. package/src/screens/AddNewGateway/ShareWifiPassword.js +2 -1
  74. package/src/screens/AddNewGateway/__test__/AddNewGateway.test.js +0 -4
  75. package/src/screens/AddNewGateway/__test__/ConnectingModbusDevice.test.js +0 -4
  76. package/src/screens/AddNewGateway/__test__/ConnectingWifiDevice.test.js +2 -5
  77. package/src/screens/AddNewGateway/__test__/ConnectingZigbeeDevice.test.js +29 -6
  78. package/src/screens/AddNewGateway/__test__/RenameNewDevices.test.js +0 -7
  79. package/src/screens/AddNewGateway/__test__/SelectDeviceType.test.js +0 -4
  80. package/src/screens/AddNewGateway/__test__/SelectModbusGateway.test.js +0 -4
  81. package/src/screens/AddNewGateway/__test__/SelectZigbeeGateway.test.js +0 -4
  82. package/src/screens/AddNewOneTap/__test__/AddNewOneTap.test.js +0 -7
  83. package/src/screens/ConfirmUnitDeletion/__test__/ConfirmUnitDeletion.test.js +0 -1
  84. package/src/screens/Device/EditDevice/__test__/EditDevice.test.js +0 -7
  85. package/src/screens/Device/__test__/detail.test.js +1 -1
  86. package/src/screens/Device/detail.js +12 -6
  87. package/src/screens/Device/hooks/useDisconnectedDevice.js +26 -7
  88. package/src/screens/EmergencyContacts/__test__/hooks.test.js +79 -0
  89. package/src/screens/Gateway/DetailConfigActionModbus/__test__/index.test.js +138 -0
  90. package/src/screens/Gateway/DetailConfigActionModbus/index.js +180 -0
  91. package/src/screens/Gateway/DetailConfigActionModbus/styles.js +9 -0
  92. package/src/screens/Gateway/DetailConfigActionZigbee/__test__/index.test.js +73 -0
  93. package/src/screens/Gateway/DetailConfigActionZigbee/index.js +62 -0
  94. package/src/screens/Gateway/DetailConfigActionZigbee/styles.js +9 -0
  95. package/src/screens/Gateway/DeviceGatewayInfo/__test__/index.test.js +73 -0
  96. package/src/screens/Gateway/DeviceGatewayInfo/index.js +96 -0
  97. package/src/screens/Gateway/DeviceGatewayInfo/styles.js +9 -0
  98. package/src/screens/Gateway/DeviceModbusDetail/__test__/index.test.js +393 -0
  99. package/src/screens/Gateway/DeviceModbusDetail/index.js +176 -0
  100. package/src/screens/Gateway/DeviceModbusDetail/styles.js +12 -0
  101. package/src/screens/Gateway/DeviceZigbeeDetail/__test__/index.test.js +265 -0
  102. package/src/screens/Gateway/DeviceZigbeeDetail/index.js +148 -0
  103. package/src/screens/Gateway/DeviceZigbeeDetail/styles.js +12 -0
  104. package/src/screens/Gateway/GatewayConnectionMethods/__test__/index.test.js +37 -0
  105. package/src/screens/Gateway/GatewayConnectionMethods/index.js +73 -0
  106. package/src/screens/Gateway/GatewayConnectionMethods/styles.js +45 -0
  107. package/src/screens/Gateway/GatewayDetail/__test__/index.test.js +298 -0
  108. package/src/screens/Gateway/GatewayDetail/index.js +148 -0
  109. package/src/screens/Gateway/GatewayDetail/styles.js +12 -0
  110. package/src/screens/Gateway/GatewayInfo/__test__/index.test.js +137 -0
  111. package/src/screens/Gateway/GatewayInfo/index.js +115 -0
  112. package/src/screens/Gateway/GatewayInfo/styles.js +9 -0
  113. package/src/screens/Gateway/__test__/index.test.js +58 -0
  114. package/src/screens/Gateway/components/Detail/__test__/index.test.js +46 -0
  115. package/src/screens/Gateway/components/Detail/index.js +62 -0
  116. package/src/screens/Gateway/components/Detail/styles.js +27 -0
  117. package/src/screens/Gateway/components/DetailActionModbus/__test__/index.test.js +49 -0
  118. package/src/screens/Gateway/components/DetailActionModbus/index.js +52 -0
  119. package/src/screens/Gateway/components/DetailActionModbus/styles.js +32 -0
  120. package/src/screens/Gateway/components/DetailConfigAction/__test__/index.test.js +59 -0
  121. package/src/screens/Gateway/components/DetailConfigAction/index.js +69 -0
  122. package/src/screens/Gateway/components/DetailConfigAction/styles.js +21 -0
  123. package/src/screens/Gateway/components/GatewayItem/__test__/index.test.js +1 -1
  124. package/src/screens/Gateway/components/GatewayItem/styles.js +4 -33
  125. package/src/screens/Gateway/components/Information/__test__/index.test.js +70 -0
  126. package/src/screens/Gateway/components/Information/index.js +116 -0
  127. package/src/screens/Gateway/components/Information/styles.js +59 -0
  128. package/src/screens/Gateway/components/RowItem/__test__/index.test.js +67 -0
  129. package/src/screens/Gateway/components/RowItem/index.js +65 -0
  130. package/src/screens/Gateway/components/RowItem/styles.js +25 -0
  131. package/src/screens/Gateway/components/TabPaneCT/__test__/index.test.js +98 -0
  132. package/src/screens/Gateway/components/TabPaneCT/index.js +134 -0
  133. package/src/screens/Gateway/components/TabPaneCT/styles.js +58 -0
  134. package/src/screens/Gateway/hooks/__test__/index.test.js +93 -0
  135. package/src/screens/Gateway/hooks/useGateway.js +110 -16
  136. package/src/screens/Gateway/index.js +19 -3
  137. package/src/screens/Gateway/styles.js +6 -8
  138. package/src/screens/Gateway/utils/index.js +16 -0
  139. package/src/screens/GuestInfo/__test__/index.test.js +0 -7
  140. package/src/screens/HanetCamera/__test__/CaptureFaceID.test.js +0 -7
  141. package/src/screens/HanetCamera/__test__/Detail.test.js +0 -7
  142. package/src/screens/HanetCamera/__test__/ManageAccess.test.js +0 -7
  143. package/src/screens/HanetCamera/__test__/MemberInfo.test.js +0 -7
  144. package/src/screens/ManageAccess/__test__/ManageAccess.test.js +0 -6
  145. package/src/screens/ManageAccess/hooks/__test__/useManageAccess.test.js +0 -7
  146. package/src/screens/MoveToAnotherSubUnit/__test__/index.test.js +0 -7
  147. package/src/screens/Notification/__test__/Notification.test.js +0 -7
  148. package/src/screens/Notification/__test__/NotificationItem.test.js +1 -0
  149. package/src/screens/Notification/components/NotificationItem.js +16 -1
  150. package/src/screens/Notification/index.js +1 -0
  151. package/src/screens/Notification/styles/indexStyles.js +3 -0
  152. package/src/screens/PlayBackCamera/__test__/index.test.js +0 -1
  153. package/src/screens/ScriptDetail/__test__/index.test.js +0 -7
  154. package/src/screens/SelectUnit/__test__/index.test.js +0 -1
  155. package/src/screens/SetSchedule/__test__/index.test.js +0 -7
  156. package/src/screens/Sharing/Components/__test__/DeviceItem.test.js +0 -7
  157. package/src/screens/Sharing/Components/__test__/ItemChangeRole.test.js +0 -7
  158. package/src/screens/Sharing/Components/__test__/TitleCheckBox.test.js +0 -7
  159. package/src/screens/Sharing/SelectPermission.js +2 -2
  160. package/src/screens/Sharing/__test__/InfoMemberUnit.test.js +0 -6
  161. package/src/screens/Sharing/hooks/__test__/index.test.js +80 -0
  162. package/src/screens/SmartAccount/ListDevice/__test__/DeviceItem.test.js +0 -7
  163. package/src/screens/SmartAccount/SuccessfullyConnected/__test__/SuccessfullyConnected.test.js +26 -7
  164. package/src/screens/SmartAccount/SuccessfullyConnected/index.js +29 -11
  165. package/src/screens/SmartIr/__test__/ButtonsBottom.test.js +0 -6
  166. package/src/screens/SmartIr/__test__/GroupButtonByType.test.js +1 -6
  167. package/src/screens/SmartIr/__test__/SelectBrand.test.js +1 -6
  168. package/src/screens/SmartIr/__test__/SelectDeviceType.test.js +1 -6
  169. package/src/screens/SubUnit/AddSubUnit.js +1 -0
  170. package/src/screens/SubUnit/ManageSubUnit.js +4 -1
  171. package/src/screens/SubUnit/hooks/__test__/useEmergencyContacts.test.js +34 -0
  172. package/src/screens/SubUnit/hooks/__test__/useManageSubUnit.test.js +0 -7
  173. package/src/screens/SyncLGDevice/__test__/AddLGDevice.test.js +1 -8
  174. package/src/screens/Template/__test__/GatewayList.test.js +1 -1
  175. package/src/screens/Template/__test__/Information.test.js +1 -1
  176. package/src/screens/Unit/Detail.js +24 -18
  177. package/src/screens/Unit/__test__/AddMenu.test.js +0 -7
  178. package/src/screens/Unit/__test__/CheckSendEmail.test.js +1 -1
  179. package/src/screens/Unit/__test__/ChooseLocation.test.js +0 -7
  180. package/src/screens/Unit/__test__/Detail.test.js +63 -26
  181. package/src/screens/Unit/__test__/SelectAddToFavorites.test.js +0 -7
  182. package/src/screens/Unit/__test__/SelectAddress.test.js +0 -7
  183. package/src/screens/Unit/__test__/SmartAccount.test.js +0 -7
  184. package/src/screens/Unit/__test__/SmartAccountItem.test.js +0 -7
  185. package/src/screens/Unit/__test__/Summaries.test.js +0 -7
  186. package/src/screens/Unit/hook/useUnitConnectRemoteDevices.js +4 -3
  187. package/src/screens/UnitSummary/components/RunningDevices/__test__/index.test.js +2 -2
  188. package/src/utils/Apis/axios.js +52 -36
  189. package/src/utils/I18n/translations/en.json +32 -0
  190. package/src/utils/I18n/translations/vi.json +33 -1
  191. package/src/utils/Route/index.js +8 -0
  192. package/src/utils/Storage.js +0 -4
  193. package/src/utils/Utils.js +1 -1
  194. package/src/utils/__test__/Utils.test.js +27 -3
  195. package/src/screens/AddNewDevice/ConnectingDevices.js +0 -62
  196. package/src/screens/AddNewDevice/__test__/ConnectingDevices.test.js +0 -110
@@ -0,0 +1,93 @@
1
+ import { act, renderHook } from '@testing-library/react-hooks';
2
+ import MockAdapter from 'axios-mock-adapter';
3
+ import Toast from 'react-native-toast-message';
4
+
5
+ import api from '../../../../utils/Apis/axios';
6
+ import { API } from '../../../../configs';
7
+ import { useGateway } from '../useGateway';
8
+
9
+ const mock = new MockAdapter(api.axiosInstance);
10
+ jest.mock('@react-navigation/native', () => {
11
+ return {
12
+ ...jest.requireActual('@react-navigation/native'),
13
+ useNavigation: () => ({
14
+ pop: jest.fn(),
15
+ }),
16
+ };
17
+ });
18
+ describe('Test useGateway', () => {
19
+ let hook;
20
+ beforeEach(async () => {
21
+ await act(() => {
22
+ hook = renderHook(() => useGateway());
23
+ });
24
+ });
25
+ afterEach(() => {
26
+ mock.reset();
27
+ Toast.show.mockClear();
28
+ });
29
+
30
+ it('test useGateway fetchDataDetailGateway', async () => {
31
+ mock
32
+ .onGet(API.DEV_MODE.GATEWAY.DETAIL(1))
33
+ .reply(200, [{ id: 1, name: 'chip 1' }]);
34
+
35
+ await act(async () => {
36
+ await hook.result.current.fetchDataDetailGateway(1);
37
+ });
38
+ expect(hook.result.current.gatewayDetail).toEqual([
39
+ { id: 1, name: 'chip 1' },
40
+ ]);
41
+ });
42
+
43
+ it('test useGateway fetchDataGateways', async () => {
44
+ mock
45
+ .onGet(API.DEV_MODE.GATEWAY.LIST())
46
+ .reply(200, { results: [{ id: 1, name: 'chip 1' }] });
47
+
48
+ await act(async () => {
49
+ await hook.result.current.fetchDataGateways();
50
+ });
51
+ expect(hook.result.current.gateways).toEqual([{ id: 1, name: 'chip 1' }]);
52
+ });
53
+
54
+ it('test useGateway fetchDevicesGateway isModbus', async () => {
55
+ mock
56
+ .onGet(API.DEV_MODE.MODBUS.DEVICE(1))
57
+ .reply(200, [{ id: 1, name: 'device 1' }]);
58
+
59
+ await act(async () => {
60
+ await hook.result.current.fetchDevicesGateway(1, true, false);
61
+ });
62
+ expect(hook.result.current.gatewayDevices?.modbus).toEqual([
63
+ { id: 1, name: 'device 1' },
64
+ ]);
65
+ });
66
+
67
+ it('test useGateway fetchDevicesGateway isZigbee', async () => {
68
+ mock
69
+ .onGet(API.DEV_MODE.ZIGBEE.DEVICE(1))
70
+ .reply(200, [{ id: 1, name: 'device 1' }]);
71
+
72
+ await act(async () => {
73
+ await hook.result.current.fetchDevicesGateway(1, false, true);
74
+ });
75
+ expect(hook.result.current.gatewayDevices?.zigbee).toEqual([
76
+ { id: 1, name: 'device 1' },
77
+ ]);
78
+ });
79
+
80
+ it('test useGateway deleteGatewayDetail', async () => {
81
+ mock.onDelete(API.DEV_MODE.GATEWAY.DETAIL(1)).reply(200);
82
+ await act(async () => {
83
+ await hook.result.current.deleteGatewayDetail(1);
84
+ });
85
+ expect(Toast.show).toBeCalledWith({
86
+ position: 'bottom',
87
+ text1: 'Delete successfully!',
88
+ text2: undefined,
89
+ type: 'success',
90
+ visibilityTime: 1000,
91
+ });
92
+ });
93
+ });
@@ -1,38 +1,132 @@
1
1
  import { useCallback, useState } from 'react';
2
- import { axiosGet } from '../../../utils/Apis/axios';
2
+ import { useNavigation } from '@react-navigation/native';
3
+
4
+ import { ToastBottomHelper } from '../../../utils/Utils';
5
+ import { axiosGet, axiosDelete } from '../../../utils/Apis/axios';
3
6
  import API from '../../../configs/API';
7
+ import t from '../../../hooks/Common/useTranslations';
4
8
 
5
- export default () => {
6
- const [loading, setLoading] = useState(true);
7
- const [gateways, setGateways] = useState([]);
9
+ export const useGateway = () => {
10
+ const navigation = useNavigation();
11
+ const [refresh, setRefresh] = useState(false);
12
+ const [selectedIndex, setSelectedIndex] = useState(0);
8
13
  const [nameSearch, setNameSearch] = useState('');
14
+ const [gateways, setGateways] = useState([]);
9
15
  const [gatewayDetail, setGatewayDetail] = useState([]);
16
+ const [gatewayDevices, setGatewayDevices] = useState({});
17
+ const [detailDeviceZigbee, setDetailDeviceZigbee] = useState({});
18
+ const [detailDeviceModbus, setDetailDeviceModbus] = useState({});
10
19
 
11
- const fetchDataDetail = useCallback(async () => {
12
- setLoading(true);
13
- const { success, data } = await axiosGet(API.DEV_MODE.GATEWAY.LIST());
20
+ const fetchDataDetailGateway = useCallback(async (id) => {
21
+ const { success, data } = await axiosGet(API.DEV_MODE.GATEWAY.DETAIL(id));
22
+ success && setGatewayDetail(data || []);
23
+ }, []);
24
+
25
+ const fetchRegistersModbus = useCallback(async (gatewayId, deviceId) => {
26
+ const { success, data } = await axiosGet(
27
+ API.DEV_MODE.MODBUS.REGISTER(gatewayId, deviceId)
28
+ );
14
29
  if (success) {
15
- setGatewayDetail(data?.results || []);
30
+ const config_read =
31
+ data?.filter((register) => [1, 2, 3, 4].includes(register.func)) || [];
32
+ const config_write =
33
+ data?.filter((register) => ![1, 2, 3, 4].includes(register.func)) || [];
34
+
35
+ setDetailDeviceModbus((prev) => ({ ...prev, config_read, config_write }));
36
+ }
37
+ }, []);
38
+
39
+ const fetchActionsModbus = useCallback(async (gatewayId, deviceId) => {
40
+ const { success, data } = await axiosGet(
41
+ API.DEV_MODE.MODBUS.ACTION(gatewayId, deviceId)
42
+ );
43
+ success && setDetailDeviceModbus((prev) => ({ ...prev, actions: data }));
44
+ }, []);
45
+
46
+ const deleteGatewayDetail = useCallback(
47
+ async (id, numberGoBack = 1) => {
48
+ const { success } = await axiosDelete(API.DEV_MODE.GATEWAY.DETAIL(id));
49
+ success && ToastBottomHelper.success(t('delete_successfully'));
50
+ success && navigation.pop(numberGoBack);
51
+ },
52
+ [navigation]
53
+ );
54
+ const deleteDeviceDetail = useCallback(
55
+ async (gatewayId, deviceId, isZigbee, isModbus, numberGoBack = 1) => {
56
+ let success;
57
+ if (isZigbee) {
58
+ success = await axiosDelete(
59
+ API.DEV_MODE.ZIGBEE.DEVICE_DETAIL(gatewayId, deviceId)
60
+ );
61
+ success && setGatewayDevices((prev) => ({ ...prev, zigbee: [] }));
62
+ }
63
+ if (isModbus) {
64
+ success = await axiosDelete(
65
+ API.DEV_MODE.MODBUS.DEVICE_DETAIL(gatewayId, deviceId)
66
+ );
67
+ success && setGatewayDevices((prev) => ({ ...prev, modbus: [] }));
68
+ }
69
+ success && ToastBottomHelper.success(t('delete_successfully'));
70
+ success && navigation.pop(numberGoBack);
71
+ },
72
+ [navigation]
73
+ );
74
+
75
+ const fetchActionConfigDevice = useCallback(
76
+ async (gatewayId, deviceId, isConfig, isAction) => {
77
+ if (isConfig) {
78
+ const { success, data } = await axiosGet(
79
+ API.DEV_MODE.ZIGBEE.CONFIG_MAP(gatewayId, deviceId)
80
+ );
81
+ success &&
82
+ setDetailDeviceZigbee((prev) => ({ ...prev, configs: data }));
83
+ }
84
+ if (isAction) {
85
+ const { success, data } = await axiosGet(
86
+ API.DEV_MODE.ZIGBEE.ACTION(gatewayId, deviceId)
87
+ );
88
+ success &&
89
+ setDetailDeviceZigbee((prev) => ({ ...prev, actions: data }));
90
+ }
91
+ },
92
+ []
93
+ );
94
+
95
+ const fetchDevicesGateway = useCallback(async (id, isModbus, isZigbee) => {
96
+ if (isModbus) {
97
+ const { success, data } = await axiosGet(API.DEV_MODE.MODBUS.DEVICE(id));
98
+ success && setGatewayDevices((prev) => ({ ...prev, modbus: data }));
99
+ }
100
+ if (isZigbee) {
101
+ const { success, data } = await axiosGet(API.DEV_MODE.ZIGBEE.DEVICE(id));
102
+ success && setGatewayDevices((prev) => ({ ...prev, zigbee: data }));
16
103
  }
17
- setLoading(false);
18
104
  }, []);
19
105
 
20
106
  const fetchDataGateways = useCallback(async () => {
21
- setLoading(true);
22
107
  const { success, data } = await axiosGet(API.DEV_MODE.GATEWAY.LIST());
23
- if (success) {
24
- setGateways(data?.results || []);
25
- }
26
- setLoading(false);
108
+ success && setGateways(data?.results || []);
27
109
  }, []);
28
110
 
29
111
  return {
30
112
  gateways,
31
113
  fetchDataGateways,
32
- loading,
114
+ setRefresh,
115
+ refresh,
33
116
  setNameSearch,
34
117
  nameSearch,
35
118
  gatewayDetail,
36
- fetchDataDetail,
119
+ fetchDataDetailGateway,
120
+ fetchDevicesGateway,
121
+ deleteGatewayDetail,
122
+ deleteDeviceDetail,
123
+ fetchActionConfigDevice,
124
+ fetchRegistersModbus,
125
+ fetchActionsModbus,
126
+ gatewayDevices,
127
+ setSelectedIndex,
128
+ selectedIndex,
129
+ detailDeviceZigbee,
130
+ detailDeviceModbus,
37
131
  };
38
132
  };
@@ -8,15 +8,21 @@ import { Text } from '../../commons';
8
8
  import styles from './styles';
9
9
  import { Search, EmptyComponent } from '../../commons/DevMode';
10
10
  import GatewayItem from './components/GatewayItem';
11
- import useGateway from './hooks/useGateway';
11
+ import { useGateway } from './hooks/useGateway';
12
12
  import Routes from '../../utils/Route';
13
13
 
14
14
  const Gateway = ({ route }) => {
15
15
  const t = useTranslations();
16
16
  const isFocused = useIsFocused();
17
17
  const { navigate } = useNavigation();
18
- const { gateways, fetchDataGateways, setNameSearch, nameSearch } =
19
- useGateway();
18
+ const {
19
+ gateways,
20
+ fetchDataGateways,
21
+ setNameSearch,
22
+ nameSearch,
23
+ refresh,
24
+ setRefresh,
25
+ } = useGateway();
20
26
 
21
27
  const goGoDetail = useCallback(
22
28
  (item) => () => {
@@ -50,6 +56,12 @@ const Gateway = ({ route }) => {
50
56
  [goGoDetail]
51
57
  );
52
58
 
59
+ const onRefresh = useCallback(() => {
60
+ setRefresh(true);
61
+ fetchDataGateways();
62
+ setRefresh(false);
63
+ }, [fetchDataGateways, setRefresh]);
64
+
53
65
  useEffect(() => {
54
66
  isFocused && fetchDataGateways();
55
67
  }, [isFocused, fetchDataGateways]);
@@ -64,7 +76,11 @@ const Gateway = ({ route }) => {
64
76
  </Text>
65
77
  <Search onSearch={setNameSearch} />
66
78
  <FlatList
79
+ onRefresh={onRefresh}
80
+ refreshing={refresh}
67
81
  columnWrapperStyle={styles.spaceBetween}
82
+ showsVerticalScrollIndicator={false}
83
+ showsHorizontalScrollIndicator={false}
68
84
  contentContainerStyle={styles.contentContainerStyle}
69
85
  keyExtractor={(item) => item?.id}
70
86
  data={gatewaysSearched}
@@ -1,30 +1,28 @@
1
1
  import { StyleSheet } from 'react-native';
2
- import { Colors, Constants } from '../../configs';
2
+ import { Colors } from '../../configs';
3
3
 
4
4
  export default StyleSheet.create({
5
5
  wrap: {
6
6
  flex: 1,
7
7
  paddingTop: 16,
8
8
  paddingHorizontal: 16,
9
- backgroundColor: Colors.Gray2,
9
+ backgroundColor: Colors.White,
10
10
  },
11
11
  textTitle: {
12
12
  fontStyle: 'normal',
13
- fontWeight: 650,
13
+ fontWeight: '600',
14
14
  fontSize: 28,
15
15
  lineHeight: 36,
16
- marignBottom: 16,
17
- },
18
- scrollview: {
19
- flex: 1,
20
16
  },
21
17
  contentContainerStyle: {
18
+ flex: 1,
22
19
  flexDirection: 'column',
20
+ height: 'auto',
23
21
  },
24
22
  wrapEmpty: {
23
+ flex: 1,
25
24
  justifyContent: 'center',
26
25
  alignItems: 'center',
27
- height: Constants.height - 330,
28
26
  },
29
27
  spaceBetween: {
30
28
  justifyContent: 'space-between',
@@ -0,0 +1,16 @@
1
+ /* eslint-disable no-bitwise */
2
+ export const splitHexValue = (decValue) => {
3
+ const hexValue = decValue.toString(16).padStart(4, '0');
4
+ return [
5
+ parseInt(hexValue.substring(0, 2), 16),
6
+ parseInt(hexValue.substring(2), 16),
7
+ ];
8
+ };
9
+
10
+ export const calculateStartAddress = (sa1, sa2) => {
11
+ return (sa1 << 8) | sa2;
12
+ };
13
+
14
+ export const calculateLength = (len1, len2) => {
15
+ return (len1 << 8) | len2;
16
+ };
@@ -20,13 +20,6 @@ const wrapComponent = (route) => (
20
20
  </SCProvider>
21
21
  );
22
22
 
23
- jest.mock('react', () => {
24
- return {
25
- ...jest.requireActual('react'),
26
- memo: (x) => x,
27
- };
28
- });
29
-
30
23
  const mockGoBack = jest.fn();
31
24
  jest.mock('@react-navigation/native', () => {
32
25
  return {
@@ -17,13 +17,6 @@ const wrapComponent = (route) => (
17
17
  </SCProvider>
18
18
  );
19
19
 
20
- jest.mock('react', () => {
21
- return {
22
- ...jest.requireActual('react'),
23
- memo: (x) => x,
24
- };
25
- });
26
-
27
20
  const mockedNavigate = jest.fn();
28
21
  const mockedGoBack = jest.fn();
29
22
  jest.mock('@react-navigation/native', () => {
@@ -33,13 +33,6 @@ jest.mock('@react-navigation/native', () => {
33
33
  };
34
34
  });
35
35
 
36
- jest.mock('react', () => {
37
- return {
38
- ...jest.requireActual('react'),
39
- memo: (x) => x,
40
- };
41
- });
42
-
43
36
  describe('Test HanetCameraDetail', () => {
44
37
  Date.now = jest.fn(() => new Date('2021-09-09T10:00:00.000Z'));
45
38
  let tree, route, responseDisplay, responseCheckin;
@@ -21,13 +21,6 @@ const wrapComponent = (route) => (
21
21
  </SCProvider>
22
22
  );
23
23
 
24
- jest.mock('react', () => {
25
- return {
26
- ...jest.requireActual('react'),
27
- memo: (x) => x,
28
- };
29
- });
30
-
31
24
  const mockedNavigate = jest.fn();
32
25
  jest.mock('@react-navigation/native', () => {
33
26
  return {
@@ -20,13 +20,6 @@ const wrapComponent = (route) => (
20
20
  </SCProvider>
21
21
  );
22
22
 
23
- jest.mock('react', () => {
24
- return {
25
- ...jest.requireActual('react'),
26
- memo: (x) => x,
27
- };
28
- });
29
-
30
23
  const mockedNavigate = jest.fn();
31
24
  const mockedGoBack = jest.fn();
32
25
  jest.mock('@react-navigation/native', () => {
@@ -16,12 +16,6 @@ const mock = new MockAdapter(api.axiosInstance);
16
16
 
17
17
  const mockUseIsFocused = jest.fn();
18
18
  const mockedNavigate = jest.fn();
19
- jest.mock('react', () => {
20
- return {
21
- ...jest.requireActual('react'),
22
- memo: (x) => x,
23
- };
24
- });
25
19
 
26
20
  jest.mock('@react-navigation/native', () => {
27
21
  return {
@@ -6,13 +6,6 @@ import api from '../../../../utils/Apis/axios';
6
6
 
7
7
  const mock = new MockAdapter(api.axiosInstance);
8
8
 
9
- jest.mock('react', () => {
10
- return {
11
- ...jest.requireActual('react'),
12
- memo: (x) => x,
13
- };
14
- });
15
-
16
9
  describe('Test Use Manage Access', () => {
17
10
  const unit = { id: 1, name: 'unit name' };
18
11
  const sensor = {
@@ -24,13 +24,6 @@ jest.mock('@react-navigation/native', () => {
24
24
  };
25
25
  });
26
26
 
27
- jest.mock('react', () => {
28
- return {
29
- ...jest.requireActual('react'),
30
- memo: (x) => x,
31
- };
32
- });
33
-
34
27
  const wrapComponent = (route) => (
35
28
  <SCProvider initState={mockSCStore({})}>
36
29
  <MoveToAnotherSubUnit route={route} />
@@ -18,13 +18,6 @@ const wrapComponent = () => (
18
18
 
19
19
  const mock = new MockAdapter(api.axiosInstance);
20
20
 
21
- jest.mock('react', () => {
22
- return {
23
- ...jest.requireActual('react'),
24
- memo: (x) => x,
25
- };
26
- });
27
-
28
21
  jest.mock('react-native-onesignal', () => {
29
22
  return {
30
23
  disablePush: jest.fn(),
@@ -165,6 +165,7 @@ describe('test NotificationItem', () => {
165
165
  NOTIFICATION_TYPES.FIRE,
166
166
  NOTIFICATION_TYPES.SOS,
167
167
  NOTIFICATION_TYPES.FILTER_WATER,
168
+ NOTIFICATION_TYPES.LOW_BATTERY,
168
169
  ];
169
170
  for (const content_code of listSensorType2) {
170
171
  test(`create ItemNotification ${content_code}`, async () => {
@@ -187,6 +187,21 @@ const NotificationItem = memo(({ item }) => {
187
187
  }),
188
188
  iconContent: <Image source={Images.logo} style={styles.logo} />,
189
189
  };
190
+ case NOTIFICATION_TYPES.LOW_BATTERY:
191
+ return {
192
+ content: customColorText(t('text_notification_content_low_battery')),
193
+ redirect: () =>
194
+ navigation.navigate(Routes.UnitStack, {
195
+ screen: Routes.DeviceDetail,
196
+ params: {
197
+ unitId,
198
+ sensorId,
199
+ },
200
+ }),
201
+ iconContent: (
202
+ <IconComponent iconKit={icon} style={styles.iconNotification} />
203
+ ),
204
+ };
190
205
  case NOTIFICATION_TYPES.NOTIFY_REMOVE_UNIT:
191
206
  return {
192
207
  content: customColorText(
@@ -342,7 +357,7 @@ const NotificationItem = memo(({ item }) => {
342
357
  default:
343
358
  return null;
344
359
  }
345
- }, [content_code, customColorText, navigation, params, t]);
360
+ }, [content_code, customColorText, icon, navigation, params, t]);
346
361
 
347
362
  const { content, redirect, iconContent } = renderItem() || {};
348
363
 
@@ -96,6 +96,7 @@ const Notification = memo(() => {
96
96
  onLoadMore={handleOnLoadMore}
97
97
  onRefresh={onRefresh}
98
98
  disableLoadMore={page >= maxPageNotification}
99
+ styleScrollView={styles.styleScrollView}
99
100
  >
100
101
  {notifications.map((item, index) => (
101
102
  <NotificationItem item={item} key={index} />
@@ -16,4 +16,7 @@ export default StyleSheet.create({
16
16
  iconPlus: {
17
17
  marginRight: 22,
18
18
  },
19
+ styleScrollView: {
20
+ marginTop: -10,
21
+ },
19
22
  });
@@ -37,7 +37,6 @@ jest.mock('react', () => {
37
37
  return {
38
38
  ...jest.requireActual('react'),
39
39
  useState: jest.fn((init) => [init, mockSetState]),
40
- memo: (x) => x,
41
40
  };
42
41
  });
43
42
 
@@ -27,13 +27,6 @@ const wrapComponent = (route) => (
27
27
  </SCProvider>
28
28
  );
29
29
 
30
- jest.mock('react', () => {
31
- return {
32
- ...jest.requireActual('react'),
33
- memo: (x) => x,
34
- };
35
- });
36
-
37
30
  const mockGoBack = jest.fn();
38
31
  const mockNavigate = jest.fn();
39
32
  jest.mock('@react-navigation/native', () => {
@@ -22,7 +22,6 @@ const mockNavigate = jest.fn();
22
22
  jest.mock('react', () => {
23
23
  return {
24
24
  ...jest.requireActual('react'),
25
- memo: (x) => x,
26
25
  useState: jest.fn((init) => [init, mockSetState]),
27
26
  };
28
27
  });
@@ -21,13 +21,6 @@ const wrapComponent = (route) => (
21
21
  </SCProvider>
22
22
  );
23
23
 
24
- jest.mock('react', () => {
25
- return {
26
- ...jest.requireActual('react'),
27
- memo: (x) => x,
28
- };
29
- });
30
-
31
24
  const mockNavigate = jest.fn();
32
25
  const mockGoBack = jest.fn();
33
26
  const mockDispatch = jest.fn();
@@ -7,13 +7,6 @@ import DeviceItem from '../DeviceItem';
7
7
  import { Text } from 'react-native';
8
8
  import { AccessibilityLabel } from '../../../../configs/Constants';
9
9
 
10
- jest.mock('react', () => {
11
- return {
12
- ...jest.requireActual('react'),
13
- memo: (x) => x,
14
- };
15
- });
16
-
17
10
  const mockOnTickedDevice = jest.fn();
18
11
  const mockOnTickedChild = jest.fn();
19
12
  const wrapComponent = (item) => (
@@ -6,13 +6,6 @@ import { mockSCStore } from '../../../../context/mockStore';
6
6
  import ItemChangeRole from '../ItemChangeRole';
7
7
  import { TouchableOpacity } from 'react-native';
8
8
 
9
- jest.mock('react', () => {
10
- return {
11
- ...jest.requireActual('react'),
12
- memo: (x) => x,
13
- };
14
- });
15
-
16
9
  const mockOnPress = jest.fn();
17
10
  const wrapComponent = () => (
18
11
  <SCProvider initState={mockSCStore({})}>
@@ -6,13 +6,6 @@ import { mockSCStore } from '../../../../context/mockStore';
6
6
  import TitleCheckBox from '../TitleCheckBox';
7
7
  import { CheckBoxCustom } from '..';
8
8
 
9
- jest.mock('react', () => {
10
- return {
11
- ...jest.requireActual('react'),
12
- memo: (x) => x,
13
- };
14
- });
15
-
16
9
  const mockOnPress = jest.fn();
17
10
  const wrapComponent = (idGroup, id) => (
18
11
  <SCProvider initState={mockSCStore({})}>
@@ -8,7 +8,7 @@ import Text from '../../commons/Text';
8
8
  import { DeviceItem, TitleCheckBox } from './Components';
9
9
  import styles from './Styles/SelectPermissionStyles';
10
10
  import { axiosGet, axiosPost } from '../../utils/Apis/axios';
11
- import { object_Ids } from '../../utils/Utils';
11
+ import { objectIds } from '../../utils/Utils';
12
12
  import Routes from '../../utils/Route';
13
13
  import { API, Colors } from '../../configs';
14
14
  import { AccessibilityLabel } from '../../configs/Constants';
@@ -174,7 +174,7 @@ const SelectPermission = ({ route }) => {
174
174
  if (isUpdateSharedDevice) {
175
175
  if (hasDataChecked) {
176
176
  const { stationIds, deviceIds, actionIds, configIds } =
177
- object_Ids(dataDeviceShared);
177
+ objectIds(dataDeviceShared);
178
178
  for (let station in dataStations) {
179
179
  for (let item in dataStations[station].devices) {
180
180
  const itemTemp = dataStations[station].devices[item];
@@ -21,12 +21,6 @@ jest.mock('../../../hooks/Common', () => {
21
21
  });
22
22
  const mockUseIsFocused = jest.fn();
23
23
  const mockedNavigate = jest.fn();
24
- jest.mock('react', () => {
25
- return {
26
- ...jest.requireActual('react'),
27
- memo: (x) => x,
28
- };
29
- });
30
24
 
31
25
  const mockGoBack = jest.fn();
32
26