@eohjsc/react-native-smart-city 0.4.48 → 0.4.49

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 (25) hide show
  1. package/package.json +1 -1
  2. package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +4 -7
  3. package/src/commons/ActionGroup/__test__/NumberUpDownTemplate.test.js +4 -1
  4. package/src/commons/Dashboard/MyUnit/index.js +8 -6
  5. package/src/commons/Device/HorizontalBarChart.js +3 -0
  6. package/src/commons/Modal/ModalCustom.js +2 -2
  7. package/src/configs/API.js +1 -0
  8. package/src/screens/AddNewGateway/ConnectingWifiDevice.js +5 -4
  9. package/src/screens/AddNewGateway/ConnectingWifiGuide.js +47 -12
  10. package/src/screens/AddNewGateway/RenameNewDevices.js +126 -10
  11. package/src/screens/AddNewGateway/RenameNewDevicesStyles.js +26 -5
  12. package/src/screens/AddNewGateway/ShareWifiPassword.js +39 -7
  13. package/src/screens/AddNewGateway/__test__/ConnectingWifiDevice.test.js +36 -7
  14. package/src/screens/AddNewGateway/__test__/ConnectingWifiGuide.test.js +41 -32
  15. package/src/screens/AddNewGateway/__test__/RenameNewDevices.test.js +106 -2
  16. package/src/screens/AddNewGateway/__test__/ShareWifiPassword.test.js +35 -2
  17. package/src/screens/Device/__test__/detail.test.js +67 -8
  18. package/src/screens/Device/detail.js +17 -27
  19. package/src/screens/Sharing/Components/CheckBoxCustom.js +14 -2
  20. package/src/screens/Sharing/InfoMemberUnit.js +3 -1
  21. package/src/screens/Sharing/__test__/InfoMemberUnit.test.js +2 -0
  22. package/src/screens/SmartAccount/Connecting/index.js +0 -1
  23. package/src/screens/SmartAccount/__test__/Connecting.test.js +92 -0
  24. package/src/utils/I18n/translations/en.js +19 -5
  25. package/src/utils/I18n/translations/vi.js +19 -5
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
+ import { Alert } from 'react-native';
2
3
  import { act, create } from 'react-test-renderer';
3
4
  import MockAdapter from 'axios-mock-adapter';
4
- import RNCNetInfoMock from '@react-native-community/netinfo/jest/netinfo-mock';
5
+ import NetInfo from '@react-native-community/netinfo';
5
6
 
6
7
  import ConnectingWifiDevice from '../ConnectingWifiDevice';
7
8
  import { SCProvider } from '../../../context';
@@ -9,6 +10,7 @@ import { mockSCStore } from '../../../context/mockStore';
9
10
  import api from '../../../utils/Apis/axios';
10
11
  import Processing from '../../../commons/Processing';
11
12
  import ConnectingDevice from '../ConnectingDevice';
13
+ import { API } from '../../../configs';
12
14
 
13
15
  const wrapComponent = (route) => (
14
16
  <SCProvider initState={mockSCStore({})}>
@@ -17,7 +19,7 @@ const wrapComponent = (route) => (
17
19
  );
18
20
 
19
21
  const mock = new MockAdapter(api.axiosInstance);
20
-
22
+ jest.spyOn(Alert, 'alert').mockImplementation(() => {});
21
23
  const mockedNavigate = jest.fn();
22
24
  const mockedGoBack = jest.fn();
23
25
 
@@ -37,13 +39,16 @@ describe('Test connecting wifi device', () => {
37
39
 
38
40
  afterEach(() => {
39
41
  mockedNavigate.mockClear();
42
+ mockedGoBack.mockClear();
43
+ Alert.alert.mockReset();
44
+ mock.reset();
40
45
  });
41
46
 
42
47
  beforeEach(() => {
43
48
  jest.useFakeTimers();
44
49
  route = {
45
50
  params: {
46
- unitId: 1,
51
+ unit: { id: 1 },
47
52
  subUnit: {
48
53
  id: 2,
49
54
  },
@@ -54,19 +59,43 @@ describe('Test connecting wifi device', () => {
54
59
  };
55
60
  });
56
61
 
57
- it('rendering', async () => {
62
+ const connectingWifiDevice = async () => {
58
63
  await act(async () => {
59
64
  tree = await create(wrapComponent(route));
60
65
  });
61
66
  const instance = tree.root;
62
67
  expect(instance.findAllByType(Processing)).toHaveLength(1);
63
- jest.runOnlyPendingTimers();
64
68
 
65
- expect(mock.history.post).toHaveLength(0);
66
69
  const connectingDevice = instance.findByType(ConnectingDevice);
67
70
  await act(async () => {
68
71
  connectingDevice.props.onReady('channelName');
69
72
  });
70
- expect(RNCNetInfoMock.addEventListener).toBeCalled();
73
+ NetInfo.triggerEvent({ isConnected: true, isInternetReachable: true });
74
+ await act(async () => {
75
+ jest.runAllTimers();
76
+ });
77
+ expect(NetInfo.addEventListener).toBeCalled();
78
+ };
79
+
80
+ it('onReady call api scan chip', async () => {
81
+ mock.onPost(API.UNIT.CHIP_SCAN(1)).reply(200, { id: 1 });
82
+ await connectingWifiDevice();
83
+ expect(mock.history.post).toHaveLength(1);
84
+ expect(mock.history.post[0].data).toEqual(
85
+ JSON.stringify({
86
+ station: 2,
87
+ channel_name: 'channelName',
88
+ })
89
+ );
90
+ });
91
+
92
+ it('onReady call api scan chip but fail', async () => {
93
+ mock.onPost(API.UNIT.CHIP_SCAN(1)).reply(400);
94
+ await connectingWifiDevice();
95
+ expect(Alert.alert.mock.calls[1][0]).toEqual('Fail add wifi device');
96
+ await act(async () => {
97
+ Alert.alert.mock.calls[1][2][0].onPress();
98
+ });
99
+ expect(mockedGoBack).toBeCalled();
71
100
  });
72
101
  });
@@ -1,6 +1,5 @@
1
1
  import React from 'react';
2
2
  import renderer, { act } from 'react-test-renderer';
3
- import Toast from 'react-native-toast-message';
4
3
  import { Platform, TouchableOpacity, Alert } from 'react-native';
5
4
  import WifiManager from 'react-native-wifi-reborn';
6
5
  import dgram from 'react-native-udp';
@@ -13,7 +12,7 @@ import AccessibilityLabel from '../../../configs/AccessibilityLabel';
13
12
 
14
13
  const mockedGoBack = jest.fn();
15
14
  const mockedNavigate = jest.fn();
16
- const mockedRetry = jest.fn();
15
+ jest.spyOn(Alert, 'alert').mockImplementation(() => {});
17
16
  jest.mock('@react-navigation/native', () => {
18
17
  return {
19
18
  ...jest.requireActual('@react-navigation/native'),
@@ -53,6 +52,7 @@ describe('test share wifi password', () => {
53
52
  socket.bind.mockClear();
54
53
  socket.send.mockClear();
55
54
  socket.close.mockClear();
55
+ Alert.alert.mockReset();
56
56
  });
57
57
 
58
58
  it('render connect wifi guide', async () => {
@@ -123,7 +123,6 @@ describe('test share wifi password', () => {
123
123
  });
124
124
 
125
125
  it('fail connect to wifi android show alert push cancel', async () => {
126
- jest.spyOn(Alert, 'alert');
127
126
  Platform.OS = 'android';
128
127
  const route = { params: routeParams };
129
128
  WifiManager.reScanAndLoadWifiList.mockImplementationOnce(async () => [
@@ -138,9 +137,11 @@ describe('test share wifi password', () => {
138
137
  tree = await renderer.create(wrapComponent(route));
139
138
  });
140
139
  await ConnectWifiActionButton(tree.root);
141
- expect(Alert.alert.mock.calls[0][0]).toEqual("Cannot find Device's Wifi");
140
+ expect(Alert.alert.mock.calls[0][0]).toEqual(
141
+ 'The devices wifi "eoh.robot." could not be found'
142
+ );
142
143
  expect(Alert.alert.mock.calls[0][1]).toEqual(
143
- 'Try to turn on device or Try again'
144
+ 'Try to turn on device or try again'
144
145
  );
145
146
  await act(async () => {
146
147
  Alert.alert.mock.calls[0][2][0].onPress();
@@ -149,16 +150,6 @@ describe('test share wifi password', () => {
149
150
  });
150
151
 
151
152
  it('fail connect to wifi android show error push retry', async () => {
152
- jest.spyOn(Alert, 'alert');
153
- Alert.alert(
154
- "Cannot find Device's Wifi",
155
- 'Try to turn on device or Try again',
156
- [
157
- { text: 'Cancel', onPress: mockedGoBack },
158
- { text: 'Retry', onPress: mockedRetry },
159
- ]
160
- );
161
-
162
153
  Platform.OS = 'android';
163
154
  const route = { params: routeParams };
164
155
  WifiManager.reScanAndLoadWifiList.mockImplementationOnce(async () => [
@@ -173,14 +164,23 @@ describe('test share wifi password', () => {
173
164
  tree = await renderer.create(wrapComponent(route));
174
165
  });
175
166
  await ConnectWifiActionButton(tree.root);
176
- expect(Alert.alert.mock.calls[1][0]).toEqual("Cannot find Device's Wifi");
177
- expect(Alert.alert.mock.calls[1][1]).toEqual(
178
- 'Try to turn on device or Try again'
167
+ expect(Alert.alert.mock.calls).toHaveLength(1);
168
+ expect(Alert.alert.mock.calls[0][0]).toEqual(
169
+ 'The devices wifi "eoh.robot." could not be found'
170
+ );
171
+ expect(Alert.alert.mock.calls[0][1]).toEqual(
172
+ 'Try to turn on device or try again'
179
173
  );
180
174
  await act(async () => {
181
- Alert.alert.mock.calls[1][2][1].onPress();
175
+ Alert.alert.mock.calls[0][2][1].onPress();
182
176
  });
183
- expect(mockedRetry).toBeCalledTimes(1);
177
+ expect(Alert.alert.mock.calls).toHaveLength(2);
178
+ expect(Alert.alert.mock.calls[1][0]).toEqual(
179
+ "Cannot connect to device's wifi eoh.robot.xxx"
180
+ );
181
+ expect(Alert.alert.mock.calls[1][1]).toEqual(
182
+ 'Try to turn on device or try again'
183
+ );
184
184
  });
185
185
 
186
186
  it('fail load wifi list android', async () => {
@@ -244,17 +244,23 @@ describe('test share wifi password', () => {
244
244
  });
245
245
  // todo Bang should test wifi display
246
246
  expect(socket.close).toBeCalled();
247
-
248
- expect(mockedNavigate).toBeCalledWith('ShareWifiPassword', {
249
- unit: {
250
- id: 1,
251
- },
252
- subUnit: {
253
- id: 1,
254
- },
255
- wifiList: [{ ssid: 'wifi 1' }, { ssid: 'wifi.2' }],
256
- qrData: { org_slug: 'eoh', prefix: 'robot' },
257
- });
247
+ expect(mockedNavigate).toBeCalledWith(
248
+ 'ShareWifiPassword',
249
+ expect.objectContaining({
250
+ qrData: {
251
+ org_slug: 'eoh',
252
+ prefix: 'robot',
253
+ },
254
+ wifiList: [
255
+ {
256
+ ssid: 'wifi 1',
257
+ },
258
+ {
259
+ ssid: 'wifi.2',
260
+ },
261
+ ],
262
+ })
263
+ );
258
264
 
259
265
  // expect(mockedNavigate.mock.calls[0][0]).toEqual(Routes.ShareWifiPassword);
260
266
  });
@@ -274,6 +280,9 @@ describe('test share wifi password', () => {
274
280
  await act(async () => {
275
281
  socket.on.mock.calls[1][1]();
276
282
  });
277
- expect(Toast.show).toBeCalled();
283
+
284
+ expect(Alert.alert.mock.calls[0][0]).toEqual(
285
+ 'Fail trigger scan wifi on device undefined'
286
+ );
278
287
  });
279
288
  });
@@ -11,6 +11,7 @@ import AccessibilityLabel from '../../../configs/AccessibilityLabel';
11
11
  import Text from '../../../commons/Text';
12
12
  import _TextInput from '../../../commons/Form/TextInput';
13
13
  import API from '../../../configs/API';
14
+ import { CheckBoxCustom } from '../../Sharing/Components';
14
15
 
15
16
  const wrapComponent = (route) => (
16
17
  <SCProvider initState={mockSCStore({})}>
@@ -336,7 +337,7 @@ describe('Test rename new devices', () => {
336
337
  );
337
338
  });
338
339
 
339
- it('update end device name', async () => {
340
+ it('update end device name and select end device', async () => {
340
341
  mock.onGet().reply(200, {
341
342
  id: 1,
342
343
  can_rename: true,
@@ -345,6 +346,14 @@ describe('Test rename new devices', () => {
345
346
  id: 1,
346
347
  name: 'sensor',
347
348
  end_devices: [
349
+ {
350
+ id: 3,
351
+ name: 'end_device 3',
352
+ },
353
+ {
354
+ id: 2,
355
+ name: 'end_device 2',
356
+ },
348
357
  {
349
358
  id: 1,
350
359
  name: 'end_device',
@@ -365,22 +374,29 @@ describe('Test rename new devices', () => {
365
374
  `${AccessibilityLabel.CONNECTED_DEVICE_RENAME_DEVICE}-end_device-1` &&
366
375
  el.type === _TextInput
367
376
  );
377
+ const checkBoxCustom = instance.findAllByType(CheckBoxCustom);
378
+
368
379
  await act(async () => {
369
380
  chipNameField.props.onChange('new name');
370
381
  });
371
382
 
383
+ await act(async () => {
384
+ checkBoxCustom[1].props.onPress();
385
+ });
386
+
372
387
  const doneButton = instance.find(
373
388
  (el) =>
374
389
  el.props.accessibilityLabel === AccessibilityLabel.BUTTON_DONE &&
375
390
  el.type === TouchableOpacity
376
391
  );
377
392
  mock.onPost(API.CHIP.RENAME_DEVICES(1)).reply(200);
393
+ mock.onPost(API.DEVICE.DELETE_END_DEVICES()).reply(200);
378
394
 
379
395
  await act(async () => {
380
396
  doneButton.props.onPress();
381
397
  });
382
398
 
383
- expect(mock.history.post).toHaveLength(1);
399
+ expect(mock.history.post).toHaveLength(2);
384
400
  expect(mock.history.post[0].data).toEqual(
385
401
  JSON.stringify({
386
402
  id: 1,
@@ -390,6 +406,10 @@ describe('Test rename new devices', () => {
390
406
  id: 1,
391
407
  name: 'sensor',
392
408
  end_devices: [
409
+ {
410
+ id: 2,
411
+ name: 'end_device 2',
412
+ },
393
413
  {
394
414
  id: 1,
395
415
  name: 'new name',
@@ -438,4 +458,88 @@ describe('Test rename new devices', () => {
438
458
  expect(mock.history.post).toHaveLength(0);
439
459
  mockedDispatchNavigate();
440
460
  });
461
+
462
+ it('should handle onPress event for CheckBoxCustom select all', async () => {
463
+ mock.onGet().reply(200, {
464
+ id: 1,
465
+ can_rename: true,
466
+ sensors: [
467
+ {
468
+ id: 1,
469
+ name: 'sensor',
470
+ end_devices: [
471
+ {
472
+ id: 1,
473
+ name: 'end_device',
474
+ },
475
+ {
476
+ id: 2,
477
+ name: 'end_device 2',
478
+ },
479
+ ],
480
+ },
481
+ ],
482
+ });
483
+
484
+ await act(async () => {
485
+ tree = await create(wrapComponent(route));
486
+ });
487
+ const instance = tree.root;
488
+ const checkBoxCustom = instance.findAllByType(CheckBoxCustom);
489
+ expect(checkBoxCustom[0].props.isChecked).toEqual(true);
490
+
491
+ await act(async () => {
492
+ await checkBoxCustom[0].props.onPress();
493
+ });
494
+
495
+ expect(checkBoxCustom[0].props.isChecked).toEqual(false);
496
+
497
+ await act(async () => {
498
+ await checkBoxCustom[0].props.onPress();
499
+ });
500
+
501
+ expect(checkBoxCustom[0].props.isChecked).toEqual(true);
502
+ });
503
+
504
+ it('should handle onPress event for CheckBoxCustom detail', async () => {
505
+ mock.onGet().reply(200, {
506
+ id: 1,
507
+ can_rename: true,
508
+ sensors: [
509
+ {
510
+ id: 1,
511
+ name: 'sensor',
512
+ end_devices: [
513
+ {
514
+ id: 1,
515
+ name: 'end_device',
516
+ },
517
+ {
518
+ id: 2,
519
+ name: 'end_device 2',
520
+ },
521
+ ],
522
+ },
523
+ ],
524
+ });
525
+
526
+ await act(async () => {
527
+ tree = await create(wrapComponent(route));
528
+ });
529
+ const instance = tree.root;
530
+ const checkBoxCustom = instance.findAllByType(CheckBoxCustom);
531
+ expect(checkBoxCustom[1].props.isChecked).toEqual(true);
532
+
533
+ await act(async () => {
534
+ await checkBoxCustom[1].props.onPress();
535
+ });
536
+
537
+ expect(checkBoxCustom[1].props.isChecked).toEqual(false);
538
+
539
+ await act(async () => {
540
+ await checkBoxCustom[1].props.onPress();
541
+ });
542
+
543
+ expect(checkBoxCustom[1].props.isChecked).toEqual(true);
544
+ });
441
545
  });
@@ -1,9 +1,10 @@
1
1
  import React from 'react';
2
2
  import renderer, { act } from 'react-test-renderer';
3
- import { Platform, TouchableOpacity } from 'react-native';
3
+ import { Alert, Platform, TouchableOpacity } from 'react-native';
4
4
  import dgram from 'react-native-udp';
5
5
  import Toast from 'react-native-toast-message';
6
6
  import WifiManager from 'react-native-wifi-reborn';
7
+ import NetInfo from '@react-native-community/netinfo';
7
8
 
8
9
  import ShareWifiPassword from '../ShareWifiPassword';
9
10
  import { SCProvider } from '../../../context';
@@ -16,6 +17,10 @@ import { flushPromises } from '../../AllGateway/test-utils';
16
17
 
17
18
  const mockedGoBack = jest.fn();
18
19
  const mockedNavigate = jest.fn();
20
+ const mockedReconnectWifiSSID = jest.fn();
21
+ jest.spyOn(Alert, 'alert').mockImplementation(() => {});
22
+ jest.mock('@react-native-community/netinfo');
23
+
19
24
  jest.mock('@react-navigation/native', () => {
20
25
  return {
21
26
  ...jest.requireActual('@react-navigation/native'),
@@ -42,6 +47,8 @@ describe('test share wifi password', () => {
42
47
  socket.bind.mockClear();
43
48
  socket.send.mockClear();
44
49
  socket.close.mockClear();
50
+ Alert.alert.mockReset();
51
+ mockedNavigate.mockClear();
45
52
  });
46
53
 
47
54
  it('render share wifi', async () => {
@@ -115,7 +122,13 @@ describe('test share wifi password', () => {
115
122
  ) => {
116
123
  jest.useFakeTimers();
117
124
  Platform.OS = 'android';
118
- const route = { params: { prefix: 'robot' } };
125
+ const route = {
126
+ params: {
127
+ prefix: 'robot',
128
+ wifiDevice: 'eoh.era.xxx',
129
+ reconnectWifiSSID: mockedReconnectWifiSSID,
130
+ },
131
+ };
119
132
  await act(async () => {
120
133
  tree = await renderer.create(wrapComponent(route));
121
134
  });
@@ -141,6 +154,26 @@ describe('test share wifi password', () => {
141
154
  });
142
155
  };
143
156
 
157
+ it('enter wrong password to gateway and disconnect to wifi device', async () => {
158
+ await receiveGatewayInfo({
159
+ status: 'error',
160
+ });
161
+ expect(mockedReconnectWifiSSID).toBeCalled();
162
+ expect(Alert.alert.mock.calls).toHaveLength(1);
163
+ expect(Alert.alert.mock.calls[0][0]).toEqual('Cannot connect to wifi ""');
164
+
165
+ NetInfo.triggerEvent({ isConnected: true, isInternetReachable: true });
166
+ expect(Alert.alert.mock.calls).toHaveLength(2);
167
+ expect(Alert.alert.mock.calls[1][0]).toEqual(
168
+ 'The connection to the wifi device has been lost.'
169
+ );
170
+ await act(async () => {
171
+ Alert.alert.mock.calls[1][2][0].onPress();
172
+ });
173
+ expect(mockedNavigate).toBeCalled();
174
+ expect(mockedNavigate.mock.calls[0][0]).toEqual(Routes.ConnectingWifiGuide);
175
+ });
176
+
144
177
  it('close socket after gateway success connect to wifi', async () => {
145
178
  await receiveGatewayInfo();
146
179
  const socket = dgram.createSocket({});
@@ -194,6 +194,7 @@ describe('test DeviceDetail', () => {
194
194
  useLayoutEffectSpy.mockImplementation(() => setState);
195
195
  mock.reset();
196
196
  mockedNavigate.mockClear();
197
+ watchMultiConfigs.mockReset();
197
198
  });
198
199
 
199
200
  it('render DeviceDetail render SensorDisplayItem', async () => {
@@ -697,18 +698,17 @@ describe('test DeviceDetail', () => {
697
698
  items: [
698
699
  {
699
700
  configuration: {
700
- template: 'OnOffSimpleActionTemplate',
701
- configuration: {
702
- config: 5,
703
- icon: 'up',
704
- is_on_value: [],
701
+ config: 131357,
702
+ config_data: {
703
+ sensor_id: 36700,
704
+ chip_id: 8296,
705
705
  },
706
706
  title: 'Turn on / off',
707
707
  },
708
708
  id: 18,
709
709
  order: 2,
710
- template: 'action',
711
- type: 'action',
710
+ template: 'OnOffSimpleActionTemplate',
711
+ type: 'OnOffSimpleActionTemplate',
712
712
  },
713
713
  ],
714
714
  };
@@ -813,6 +813,65 @@ describe('test DeviceDetail', () => {
813
813
  el.props.accessibilityLabel === AccessibilityLabel.SENSOR_DISPLAY_ITEM
814
814
  );
815
815
  expect(sensorDisplayItem.length).toEqual(1);
816
- expect(watchMultiConfigs).toHaveBeenCalled();
816
+ expect(watchMultiConfigs).toHaveBeenCalledWith([]);
817
+ });
818
+
819
+ it('watch action config', async () => {
820
+ mock.onGet(API.CHIP.JSON_CONFIGURATION).reply(200, []);
821
+ const responseDisplay = {
822
+ items: [
823
+ {
824
+ id: 1,
825
+ order: 0,
826
+ template: 'on_off_button_action_template',
827
+ type: 'on_off_button_action_template',
828
+ configuration: {
829
+ config: 2,
830
+ },
831
+ },
832
+ ],
833
+ };
834
+ const responseDisplayValueV2 = {
835
+ configs: [{ id: 2 }],
836
+ is_connected: true,
837
+ last_updated: '2021-01-24T12:00:00.000Z',
838
+ };
839
+ mockAxios(responseDisplay, responseDisplayValueV2);
840
+ await act(async () => {
841
+ tree = await create(wrapComponent(store, account, route));
842
+ });
843
+
844
+ expect(watchMultiConfigs).toHaveBeenCalledWith([]);
845
+ });
846
+
847
+ it('watch stages grid action config', async () => {
848
+ mock.onGet(API.CHIP.JSON_CONFIGURATION).reply(200, []);
849
+ const responseDisplay = {
850
+ items: [
851
+ {
852
+ id: 1,
853
+ order: 0,
854
+ template: 'StatesGridActionTemplate',
855
+ configuration: {
856
+ options: [
857
+ {
858
+ config: 3,
859
+ },
860
+ ],
861
+ },
862
+ },
863
+ ],
864
+ };
865
+ const responseDisplayValueV2 = {
866
+ configs: [{ id: 2 }],
867
+ is_connected: true,
868
+ last_updated: '2021-01-24T12:00:00.000Z',
869
+ };
870
+ mockAxios(responseDisplay, responseDisplayValueV2);
871
+ await act(async () => {
872
+ tree = await create(wrapComponent(store, account, route));
873
+ });
874
+
875
+ expect(watchMultiConfigs).toHaveBeenCalledWith([]);
817
876
  });
818
877
  });
@@ -59,7 +59,7 @@ import { useReceiveNotifications } from '../../hooks';
59
59
  import useChipJsonConfiguration, {
60
60
  useConnectChipMqtt,
61
61
  } from '../../hooks/useMqtt';
62
- import { realWatchMultiConfigs } from '../../iot/Monitor';
62
+ import { watchMultiConfigs } from '../../iot/Monitor';
63
63
 
64
64
  const DeviceDetail = ({ route }) => {
65
65
  const configIdsTemp = useRef([]);
@@ -136,8 +136,7 @@ const DeviceDetail = ({ route }) => {
136
136
  }
137
137
 
138
138
  return action.some((item) => {
139
- const { configuration } = item?.configuration;
140
- return JSON.stringify(configuration).includes(
139
+ return JSON.stringify(item?.configuration)?.includes(
141
140
  '"command_prefer_over_bluetooth":true'
142
141
  );
143
142
  });
@@ -329,9 +328,7 @@ const DeviceDetail = ({ route }) => {
329
328
 
330
329
  const listMenuItem = useMemo(() => {
331
330
  const menuItems = [];
332
- if (
333
- display.items.some((i) => getActionComponent(i.configuration.template))
334
- ) {
331
+ if (display.items.some((i) => getActionComponent(i.template))) {
335
332
  menuItems.push({
336
333
  route: Routes.ActivityLog,
337
334
  data: {
@@ -500,31 +497,24 @@ const DeviceDetail = ({ route }) => {
500
497
  let params = new URLSearchParams();
501
498
  const configIds = [];
502
499
 
500
+ // todo Bang refactor widgets like dashboard
503
501
  display.items.map((item) => {
504
- const type = item?.template || item?.type;
505
502
  if (!item.configuration) {
506
503
  return;
507
504
  }
508
- if (!['action', 'value'].includes(type)) {
509
- return;
510
- }
511
- if (type === 'action') {
512
- if (
513
- [
514
- 'on_off_button_action_template',
515
- 'one_button_action_template',
516
- ].includes(item.configuration.template)
517
- ) {
518
- !configIds.includes(item.configuration.configuration.config) &&
519
- configIds.push(item.configuration.configuration.config);
505
+ item.configuration.configs?.map((config) => {
506
+ if (!configIds.includes(config.id)) {
507
+ configIds.push(config.id);
520
508
  }
521
- }
522
- if (type === 'value') {
523
- item.configuration.configs.map((config) => {
524
- if (!configIds.includes(config.id)) {
525
- configIds.push(config.id);
526
- }
527
- });
509
+ });
510
+ item.configuration.options?.map((option) => {
511
+ if (!configIds.includes(option.config)) {
512
+ configIds.push(option.config);
513
+ }
514
+ });
515
+ if (item.configuration.config) {
516
+ !configIds.includes(item.configuration.config) &&
517
+ configIds.push(item.configuration.config);
528
518
  }
529
519
  });
530
520
  configIdsTemp.current = configIds.filter(Boolean);
@@ -720,7 +710,7 @@ const DeviceDetail = ({ route }) => {
720
710
  }, [sensor]);
721
711
 
722
712
  useEffect(() => {
723
- appState === 'active' && realWatchMultiConfigs(configIdsTemp.current);
713
+ appState === 'active' && watchMultiConfigs(configIdsTemp.current);
724
714
  }, [appState]);
725
715
 
726
716
  const shouldRender =
@@ -4,14 +4,26 @@ import AccessibilityLabel from '../../../configs/AccessibilityLabel';
4
4
  import Images from '../../../configs/Images';
5
5
  import styles from './Styles/CheckBoxCustomStyles';
6
6
 
7
- const CheckBoxCustom = ({ isChecked, onPress, wrapStyle, id }) => {
7
+ const CheckBoxCustom = ({
8
+ isChecked,
9
+ onPress,
10
+ wrapStyle,
11
+ wrapViewCustom,
12
+ id,
13
+ }) => {
8
14
  return (
9
15
  <TouchableOpacity
10
16
  style={[styles.wrapBtn, wrapStyle]}
11
17
  onPress={onPress}
12
18
  accessibilityLabel={`${AccessibilityLabel.CHECK_BOX_CUSTOM}-${id}`}
13
19
  >
14
- <View style={[styles.wrapView, isChecked && styles.viewChecked]}>
20
+ <View
21
+ style={[
22
+ styles.wrapView,
23
+ wrapViewCustom,
24
+ isChecked && styles.viewChecked,
25
+ ]}
26
+ >
15
27
  {isChecked && <Image source={Images.check} />}
16
28
  </View>
17
29
  </TouchableOpacity>
@@ -58,7 +58,9 @@ const InfoMemberUnit = memo(({ route }) => {
58
58
  if (stateAlertAction?.is_change) {
59
59
  hideAlertAction();
60
60
  if (itemSelected?.role?.is_owner) {
61
- setIsShowWarning(true);
61
+ setTimeout(() => {
62
+ setIsShowWarning(true);
63
+ }, 500);
62
64
  }
63
65
  } else {
64
66
  removeMember(