@eohjsc/react-native-smart-city 0.3.37 → 0.3.39

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 (63) hide show
  1. package/package.json +1 -1
  2. package/src/commons/AlertAction/index.js +5 -1
  3. package/src/commons/Device/ItemDevice.js +21 -34
  4. package/src/commons/Form/TextInput.js +9 -1
  5. package/src/commons/UnitSummary/ConfigHistoryChart/index.js +6 -3
  6. package/src/commons/WrapParallaxScrollView/index.js +6 -1
  7. package/src/configs/API.js +1 -1
  8. package/src/configs/AccessibilityLabel.js +13 -1
  9. package/src/configs/Constants.js +9 -12
  10. package/src/context/actionType.ts +4 -0
  11. package/src/context/mockStore.ts +3 -0
  12. package/src/context/reducer.ts +17 -0
  13. package/src/hooks/Common/index.js +0 -2
  14. package/src/hooks/Common/useDevicesStatus.js +26 -28
  15. package/src/hooks/IoT/__test__/useRemoteControl.test.js +3 -0
  16. package/src/hooks/IoT/index.js +8 -0
  17. package/src/hooks/IoT/useBluetoothConnection.js +27 -0
  18. package/src/hooks/IoT/useBluetoothDeviceConnected.js +18 -0
  19. package/src/hooks/IoT/useEoHBackendDeviceConnected.js +21 -0
  20. package/src/hooks/{Common → IoT}/useHomeAssistantDeviceConnected.js +0 -0
  21. package/src/hooks/IoT/useRemoteControl.js +8 -19
  22. package/src/iot/RemoteControl/Bluetooth.js +5 -12
  23. package/src/iot/RemoteControl/__test__/Bluetooth.test.js +19 -63
  24. package/src/navigations/UnitStack.js +11 -1
  25. package/src/screens/AddCommon/SelectSubUnit.js +3 -0
  26. package/src/screens/AddLocationMaps/index.js +1 -0
  27. package/src/screens/AddNewGateway/ConnectingWifiDevice.js +4 -2
  28. package/src/screens/AddNewGateway/ConnectingWifiGuide.js +5 -4
  29. package/src/screens/AddNewGateway/RenameNewDevices.js +7 -6
  30. package/src/screens/AddNewGateway/ScanGatewayQR.js +2 -6
  31. package/src/screens/AddNewGateway/ScanWifiDeviceQR.js +1 -4
  32. package/src/screens/AddNewGateway/ShareWifiPassword.js +4 -2
  33. package/src/screens/AddNewGateway/__test__/ConnectingWifiDevice.test.js +1 -0
  34. package/src/screens/AddNewGateway/__test__/ConnectingWifiGuide.test.js +14 -9
  35. package/src/screens/AddNewGateway/__test__/ConnectingZigbeeDevice.test.js +29 -1
  36. package/src/screens/AddNewGateway/__test__/ScanGatewayQR.test.js +1 -1
  37. package/src/screens/AddNewGateway/__test__/ScanWifiDeviceQR.test.js +1 -1
  38. package/src/screens/ConfirmUnitDeletion/index.js +6 -1
  39. package/src/screens/Device/__test__/detail.test.js +1 -0
  40. package/src/screens/Device/detail.js +53 -59
  41. package/src/screens/Notification/__test__/NotificationItem.test.js +44 -40
  42. package/src/screens/Notification/components/NotificationItem.js +134 -141
  43. package/src/screens/SmartAccount/Connecting/index.js +3 -0
  44. package/src/screens/SmartAccount/ListDevice/__test__/ListDevice.test.js +6 -2
  45. package/src/screens/SmartAccount/ListDevice/index.js +17 -12
  46. package/src/screens/SmartAccount/SuccessfullyConnected/__test__/SuccessfullyConnected.test.js +61 -7
  47. package/src/screens/SmartAccount/SuccessfullyConnected/index.js +102 -27
  48. package/src/screens/SmartAccount/SuccessfullyConnected/styles.js +58 -1
  49. package/src/screens/SmartAccount/__test__/Connecting.test.js +3 -0
  50. package/src/screens/SubUnit/AddSubUnit.js +5 -1
  51. package/src/screens/Unit/MoreMenu.js +3 -3
  52. package/src/screens/Unit/SelectAddress.js +1 -0
  53. package/src/screens/Unit/components/MyUnitDevice/index.js +1 -1
  54. package/src/screens/Unit/hook/useUnitConnectRemoteDevices.js +11 -8
  55. package/src/screens/UnitSummary/__test__/index.test.js +38 -2
  56. package/src/screens/UnitSummary/components/RunningDevices/__test__/index.test.js +1 -1
  57. package/src/screens/UnitSummary/components/RunningDevices/index.js +3 -17
  58. package/src/screens/UnitSummary/index.js +6 -1
  59. package/src/utils/Apis/axios.js +1 -0
  60. package/src/utils/__test__/Utils.test.js +19 -1
  61. package/src/screens/SmartAccount/SuccessfullyConnected/DeviceItem.js +0 -37
  62. package/src/screens/SmartAccount/SuccessfullyConnected/DeviceItemStyles.js +0 -49
  63. package/src/screens/SmartAccount/SuccessfullyConnected/__test__/DeviceItem.test.js +0 -65
@@ -30,7 +30,7 @@ jest.mock('@react-navigation/native', () => {
30
30
  useNavigation: () => ({
31
31
  navigate: mockedNavigate,
32
32
  }),
33
- useFocusEffect: jest.fn(),
33
+ useIsFocused: () => true,
34
34
  };
35
35
  });
36
36
 
@@ -58,6 +58,7 @@ describe('Test UnitSummary', () => {
58
58
 
59
59
  beforeEach(() => {
60
60
  mock.resetHistory();
61
+
61
62
  Date.now = jest.fn(() => new Date('2021-01-24T12:00:00.000Z'));
62
63
  route = {
63
64
  params: {
@@ -101,7 +102,9 @@ describe('Test UnitSummary', () => {
101
102
 
102
103
  it('render fetchSummaryDetail success', async () => {
103
104
  jest.useFakeTimers();
104
- mock.onGet(API.UNIT.UNIT_SUMMARY_DETAIL(1, 1)).reply(200);
105
+ mock
106
+ .onGet(API.UNIT.UNIT_SUMMARY_DETAIL(1, 1))
107
+ .reply(200, { data: { last_updated: '' } });
105
108
  await act(async () => {
106
109
  tree = await create(wrapComponent(route));
107
110
  });
@@ -110,7 +113,35 @@ describe('Test UnitSummary', () => {
110
113
  });
111
114
  const instance = tree.root;
112
115
  const refreshControl = instance.findByType(RefreshControl);
116
+ const wrapHeader = instance.findByProps({
117
+ accessibilityLabel: AccessibilityLabel.WRAP_HEADER_SCROLL,
118
+ });
119
+
113
120
  expect(refreshControl).toBeDefined();
121
+ expect(wrapHeader.props.subTitle).toEqual(null);
122
+ });
123
+
124
+ it('render fetchUnitSummary success', async () => {
125
+ route.params.summaryData = null;
126
+ jest.useFakeTimers();
127
+ mock.onGet(API.UNIT.UNIT_SUMMARY_DETAIL(1, 1)).reply(200, { data: {} });
128
+ mock
129
+ .onGet(API.UNIT.UNIT_SUMMARY(1))
130
+ .reply(200, [{ id: 1, screen: Routes.AirQuality }]);
131
+ await act(async () => {
132
+ tree = await create(wrapComponent(route));
133
+ });
134
+ await act(async () => {
135
+ jest.runOnlyPendingTimers();
136
+ });
137
+ const instance = tree.root;
138
+ const componentName = instance.findByProps({
139
+ accessibilityLabel: AccessibilityLabel.COMPONENT_NAME,
140
+ });
141
+
142
+ expect(componentName).toBeDefined();
143
+ expect(componentName.props.summaryDetail).toEqual({});
144
+ expect(componentName.props.unit).toEqual({ id: 1 });
114
145
  });
115
146
 
116
147
  it('render fetchUnitDetail success', async () => {
@@ -184,6 +215,7 @@ describe('Test UnitSummary', () => {
184
215
  Routes.UvIndex,
185
216
  Routes.WaterQuality,
186
217
  Routes.ThreePhasePowerConsumption,
218
+ null,
187
219
  ];
188
220
  let list_result = [
189
221
  {
@@ -213,6 +245,10 @@ describe('Test UnitSummary', () => {
213
245
  {
214
246
  componentName: ThreePhasePowerConsumption,
215
247
  },
248
+ {
249
+ guideName: null,
250
+ componentName: null,
251
+ },
216
252
  ];
217
253
 
218
254
  list_value.forEach((value, index) => {
@@ -19,7 +19,7 @@ jest.mock('@react-navigation/native', () => {
19
19
  useNavigation: () => ({
20
20
  navigate: mockedNavigate,
21
21
  }),
22
- useFocusEffect: jest.fn(),
22
+ useIsFocused: () => true,
23
23
  };
24
24
  });
25
25
 
@@ -1,27 +1,13 @@
1
- import React, { memo, useEffect } from 'react';
1
+ import React, { memo } from 'react';
2
2
  import { StyleSheet, View } from 'react-native';
3
3
  import ItemDevice from '../../../../commons/Device/ItemDevice';
4
- import { scanBluetoothDevices } from '../../../../iot/RemoteControl/Bluetooth';
5
- import { useHomeAssistantConnection } from '../../../../hooks/IoT';
6
4
  import { useDevicesStatus } from '../../../../hooks/Common';
5
+ import { useUnitConnectRemoteDevices } from '../../../Unit/hook/useUnitConnectRemoteDevices';
7
6
 
8
7
  const RunningDevices = memo(({ unit, summaryDetail }) => {
9
8
  const { devices } = summaryDetail;
10
9
 
11
- const { connectHomeAssistant } = useHomeAssistantConnection();
12
-
13
- useEffect(() => {
14
- if (unit.remote_control_options) {
15
- if (unit.remote_control_options.bluetooth) {
16
- scanBluetoothDevices(unit.remote_control_options.bluetooth);
17
- }
18
- if (unit.remote_control_options.googlehome) {
19
- (async () =>
20
- await connectHomeAssistant(unit.remote_control_options.googlehome))();
21
- }
22
- }
23
- // eslint-disable-next-line react-hooks/exhaustive-deps
24
- }, [unit]);
10
+ useUnitConnectRemoteDevices(unit);
25
11
 
26
12
  useDevicesStatus(unit, devices);
27
13
 
@@ -166,6 +166,7 @@ const UnitSummary = memo(({ route }) => {
166
166
  return (
167
167
  <View style={[styles.container]}>
168
168
  <WrapHeaderScrollable
169
+ accessibilityLabel={AccessibilityLabel.WRAP_HEADER_SCROLL}
169
170
  title={summary?.name}
170
171
  subTitle={lastUpdatedStr}
171
172
  rightComponent={
@@ -188,7 +189,11 @@ const UnitSummary = memo(({ route }) => {
188
189
  onRefresh={onRefresh}
189
190
  >
190
191
  {ComponentName && (
191
- <ComponentName summaryDetail={summaryDetail} unit={unit} />
192
+ <ComponentName
193
+ summaryDetail={summaryDetail}
194
+ unit={unit}
195
+ accessibilityLabel={AccessibilityLabel.COMPONENT_NAME}
196
+ />
192
197
  )}
193
198
  </WrapHeaderScrollable>
194
199
  </View>
@@ -52,6 +52,7 @@ const parseErrorResponse = async (error) => {
52
52
  if (message?.message) {
53
53
  message = message.message;
54
54
  }
55
+ message = `${firstKey}: ${message}`;
55
56
  } else {
56
57
  message = error.data || error.problem;
57
58
  }
@@ -1,4 +1,10 @@
1
- import { validateEmail, formatMoney } from '../Utils';
1
+ import {
2
+ validateEmail,
3
+ formatMoney,
4
+ insertToString,
5
+ removeFromString,
6
+ isObjectEmpty,
7
+ } from '../Utils';
2
8
 
3
9
  describe('Test utils', () => {
4
10
  it('test validateEmail', async () => {
@@ -9,4 +15,16 @@ describe('Test utils', () => {
9
15
  const result = formatMoney(10000);
10
16
  expect(result).toEqual('10.000 đ');
11
17
  });
18
+ it('test insertToString', async () => {
19
+ const result = insertToString('test', 1, 2);
20
+ expect(result).toEqual('t2est');
21
+ });
22
+ it('test removeFromString', async () => {
23
+ const result = removeFromString('test', 1);
24
+ expect(result).toEqual('tst');
25
+ });
26
+ it('test isObjectEmpty', async () => {
27
+ const result = isObjectEmpty({ id: 1 });
28
+ expect(result).toEqual(false);
29
+ });
12
30
  });
@@ -1,37 +0,0 @@
1
- import React, { memo, useCallback, useState } from 'react';
2
- import { View } from 'react-native';
3
-
4
- import FImage from '../../../commons/FImage';
5
- import { API } from '../../../configs';
6
- import { axiosPatch } from '../../../utils/Apis/axios';
7
- import _TextInput from '../../../commons/Form/TextInput';
8
- import AccessibilityLabel from '../../../configs/AccessibilityLabel';
9
- import styles from './DeviceItemStyles';
10
-
11
- const DeviceItem = memo(({ icon, name, itemId }) => {
12
- const [newName, setNewName] = useState(name);
13
-
14
- const handleBlur = useCallback(async () => {
15
- await axiosPatch(API.DEVICE.END_DEVICE_DETAIL(itemId), {
16
- name: newName,
17
- });
18
- }, [itemId, newName]);
19
-
20
- return (
21
- <View style={styles.container}>
22
- <FImage source={{ uri: icon }} style={styles.iconSensor} />
23
- <_TextInput
24
- value={newName}
25
- textInputStyle={styles.textItem}
26
- onChange={setNewName}
27
- onBlur={handleBlur}
28
- maxLength={64}
29
- accessibilityLabel={
30
- AccessibilityLabel.ON_CHANGE_NAME_DEVICE_SMART_ACCOUNT
31
- }
32
- />
33
- </View>
34
- );
35
- });
36
-
37
- export default DeviceItem;
@@ -1,49 +0,0 @@
1
- import { StyleSheet } from 'react-native';
2
- import { Colors, Constants } from '../../../configs';
3
-
4
- const marginItem = 12;
5
- const marginHorizontal = 5;
6
- const widthItem = (Constants.width - marginHorizontal * 2 - marginItem) / 2;
7
- const heightItem = (widthItem / 166) * 60;
8
-
9
- export default StyleSheet.create({
10
- container: {
11
- paddingHorizontal: 15,
12
- borderRadius: 10,
13
- width: 250,
14
- height: heightItem,
15
- borderWidth: 1,
16
- borderColor: Colors.Gray4,
17
- backgroundColor: Colors.White,
18
- justifyContent: 'center',
19
- alignItems: 'center',
20
- marginBottom: 16,
21
- flexDirection: 'row',
22
- shadowColor: Colors.Shadow,
23
- shadowOffset: {
24
- width: 0,
25
- height: 2,
26
- },
27
- shadowOpacity: 0.1,
28
- shadowRadius: 3,
29
- elevation: 6,
30
- paddingLeft: 30,
31
- paddingRight: 30,
32
- },
33
- iconSensor: {
34
- width: 32,
35
- height: 32,
36
- resizeMode: 'contain',
37
- },
38
- textItem: {
39
- display: 'flex',
40
- justifyContent: 'center',
41
- alignItems: 'center',
42
- borderWidth: 0,
43
- borderBottomWidth: 1,
44
- borderBottomColor: Colors.Primary,
45
- textAlign: 'center',
46
- marginTop: -10,
47
- fontSize: 16,
48
- },
49
- });
@@ -1,65 +0,0 @@
1
- import React from 'react';
2
- import { act, create } from 'react-test-renderer';
3
- import _TextInput from '../../../../commons/Form/TextInput';
4
- import { API } from '../../../../configs';
5
- import AccessibilityLabel from '../../../../configs/AccessibilityLabel';
6
- import { SCProvider } from '../../../../context';
7
- import { mockSCStore } from '../../../../context/mockStore';
8
- import MockAdapter from 'axios-mock-adapter';
9
- import DeviceItem from '../DeviceItem';
10
- import api from '../../../../utils/Apis/axios';
11
-
12
- const mock = new MockAdapter(api.axiosInstance);
13
-
14
- const wrapComponent = (props) => (
15
- <SCProvider initState={mockSCStore({})}>
16
- <DeviceItem {...props} />
17
- </SCProvider>
18
- );
19
-
20
- jest.mock('react', () => {
21
- return {
22
- ...jest.requireActual('react'),
23
- memo: (x) => x,
24
- };
25
- });
26
-
27
- describe('Test SmartAccount', () => {
28
- let tree;
29
- it('test DeviceItem', async () => {
30
- let props = {
31
- icon: '',
32
- name: 'test',
33
- itemId: 2,
34
- };
35
- await act(async () => {
36
- tree = await create(wrapComponent(props));
37
- });
38
- const instance = tree.root;
39
- const texts = instance.findAllByType(_TextInput);
40
- expect(texts).toHaveLength(1);
41
- });
42
-
43
- it('test onchange name device', async () => {
44
- let props = {
45
- icon: '',
46
- name: 'test',
47
- itemId: 2,
48
- };
49
- await act(async () => {
50
- tree = await create(wrapComponent(props));
51
- });
52
- const instance = tree.root;
53
- const textInput = instance.find(
54
- (el) =>
55
- el.props.accessibilityLabel ===
56
- AccessibilityLabel.ON_CHANGE_NAME_DEVICE_SMART_ACCOUNT &&
57
- el.type === _TextInput
58
- );
59
- await act(async () => {
60
- await textInput.props.onBlur('new name');
61
- });
62
- mock.onPatch(API.DEVICE.END_DEVICE_DETAIL(1)).reply(200);
63
- expect(textInput).toBeDefined();
64
- });
65
- });