@eohjsc/react-native-smart-city 0.3.62 → 0.3.64

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 (78) hide show
  1. package/package.json +1 -1
  2. package/src/commons/Dashboard/MyPinnedSharedUnit/index.js +10 -0
  3. package/src/commons/Dashboard/MyUnit/index.js +9 -3
  4. package/src/commons/Device/HorizontalBarChart.js +3 -3
  5. package/src/commons/Device/WindSpeed/Anemometer/index.js +10 -26
  6. package/src/commons/FourButtonFilterHistory/index.js +1 -1
  7. package/src/configs/API.js +14 -0
  8. package/src/configs/Constants.js +1 -0
  9. package/src/context/actionType.ts +1 -0
  10. package/src/context/reducer.ts +10 -0
  11. package/src/navigations/AllGatewayStack.js +19 -9
  12. package/src/navigations/UnitStack.js +1 -1
  13. package/src/screens/AllGateway/DetailConfigActionInternal/__test__/index.test.js +104 -0
  14. package/src/screens/AllGateway/DetailConfigActionInternal/index.js +97 -0
  15. package/src/screens/{Gateway/DetailConfigActionModbus → AllGateway/DetailConfigActionInternal}/styles.js +0 -0
  16. package/src/screens/{Gateway → AllGateway}/DetailConfigActionModbus/__test__/index.test.js +0 -0
  17. package/src/screens/{Gateway → AllGateway}/DetailConfigActionModbus/index.js +0 -0
  18. package/src/screens/{Gateway/DeviceGatewayInfo → AllGateway/DetailConfigActionModbus}/styles.js +0 -0
  19. package/src/screens/{Gateway → AllGateway}/DetailConfigActionZigbee/__test__/index.test.js +0 -0
  20. package/src/screens/{Gateway → AllGateway}/DetailConfigActionZigbee/index.js +0 -0
  21. package/src/screens/{Gateway → AllGateway}/DetailConfigActionZigbee/styles.js +0 -0
  22. package/src/screens/{Gateway → AllGateway}/DeviceGatewayInfo/__test__/index.test.js +0 -0
  23. package/src/screens/{Gateway → AllGateway}/DeviceGatewayInfo/index.js +26 -2
  24. package/src/screens/{Gateway/GatewayInfo → AllGateway/DeviceGatewayInfo}/styles.js +0 -0
  25. package/src/screens/AllGateway/DeviceInternalDetail/__test__/index.test.js +387 -0
  26. package/src/screens/AllGateway/DeviceInternalDetail/index.js +188 -0
  27. package/src/screens/{Gateway/DeviceModbusDetail → AllGateway/DeviceInternalDetail}/styles.js +0 -0
  28. package/src/screens/{Gateway → AllGateway}/DeviceModbusDetail/__test__/index.test.js +0 -0
  29. package/src/screens/{Gateway → AllGateway}/DeviceModbusDetail/index.js +9 -17
  30. package/src/screens/{Gateway/DeviceZigbeeDetail → AllGateway/DeviceModbusDetail}/styles.js +0 -0
  31. package/src/screens/{Gateway → AllGateway}/DeviceZigbeeDetail/__test__/index.test.js +0 -0
  32. package/src/screens/{Gateway → AllGateway}/DeviceZigbeeDetail/index.js +9 -17
  33. package/src/screens/{Gateway/GatewayDetail → AllGateway/DeviceZigbeeDetail}/styles.js +0 -0
  34. package/src/screens/{Gateway → AllGateway}/GatewayConnectionMethods/__test__/index.test.js +0 -0
  35. package/src/screens/{Gateway → AllGateway}/GatewayConnectionMethods/index.js +0 -0
  36. package/src/screens/{Gateway → AllGateway}/GatewayConnectionMethods/styles.js +0 -0
  37. package/src/screens/{Gateway → AllGateway}/GatewayDetail/__test__/index.test.js +71 -31
  38. package/src/screens/{Gateway → AllGateway}/GatewayDetail/index.js +62 -42
  39. package/src/screens/AllGateway/GatewayDetail/styles.js +12 -0
  40. package/src/screens/{Gateway → AllGateway}/GatewayInfo/__test__/index.test.js +0 -0
  41. package/src/screens/{Gateway → AllGateway}/GatewayInfo/index.js +14 -17
  42. package/src/screens/AllGateway/GatewayInfo/styles.js +12 -0
  43. package/src/screens/{Gateway → AllGateway}/__test__/index.test.js +0 -0
  44. package/src/screens/{Gateway → AllGateway}/components/Detail/__test__/index.test.js +0 -0
  45. package/src/screens/{Gateway → AllGateway}/components/Detail/index.js +0 -0
  46. package/src/screens/{Gateway → AllGateway}/components/Detail/styles.js +0 -0
  47. package/src/screens/{Gateway → AllGateway}/components/DetailActionModbus/__test__/index.test.js +0 -0
  48. package/src/screens/{Gateway → AllGateway}/components/DetailActionModbus/index.js +0 -0
  49. package/src/screens/{Gateway → AllGateway}/components/DetailActionModbus/styles.js +0 -0
  50. package/src/screens/{Gateway → AllGateway}/components/DetailConfigAction/__test__/index.test.js +0 -0
  51. package/src/screens/{Gateway → AllGateway}/components/DetailConfigAction/index.js +0 -0
  52. package/src/screens/{Gateway → AllGateway}/components/DetailConfigAction/styles.js +0 -0
  53. package/src/screens/{Gateway → AllGateway}/components/GatewayItem/__test__/index.test.js +0 -0
  54. package/src/screens/{Gateway → AllGateway}/components/GatewayItem/index.js +0 -0
  55. package/src/screens/{Gateway → AllGateway}/components/GatewayItem/styles.js +0 -0
  56. package/src/screens/{Gateway → AllGateway}/components/Information/__test__/index.test.js +0 -0
  57. package/src/screens/{Gateway → AllGateway}/components/Information/index.js +0 -0
  58. package/src/screens/{Gateway → AllGateway}/components/Information/styles.js +0 -0
  59. package/src/screens/{Gateway → AllGateway}/components/RowItem/__test__/index.test.js +0 -0
  60. package/src/screens/{Gateway → AllGateway}/components/RowItem/index.js +0 -0
  61. package/src/screens/{Gateway → AllGateway}/components/RowItem/styles.js +0 -0
  62. package/src/screens/{Gateway → AllGateway}/components/TabPaneCT/__test__/index.test.js +0 -0
  63. package/src/screens/{Gateway → AllGateway}/components/TabPaneCT/index.js +0 -0
  64. package/src/screens/{Gateway → AllGateway}/components/TabPaneCT/styles.js +0 -0
  65. package/src/screens/{Gateway → AllGateway}/hooks/__test__/index.test.js +15 -2
  66. package/src/screens/{Gateway → AllGateway}/hooks/useGateway.js +91 -11
  67. package/src/screens/{Gateway → AllGateway}/index.js +2 -2
  68. package/src/screens/{Gateway → AllGateway}/styles.js +0 -0
  69. package/src/screens/{Gateway → AllGateway}/utils/index.js +0 -0
  70. package/src/screens/Device/__test__/DetailHistoryChart.test.js +25 -10
  71. package/src/screens/Device/components/DetailHistoryChart.js +72 -22
  72. package/src/screens/WaterQualityGuide/__test__/index.test.js +8 -8
  73. package/src/screens/WaterQualityGuide/index.js +32 -53
  74. package/src/utils/Functions/preloadImages.js +39 -0
  75. package/src/utils/I18n/translations/en.json +21 -16
  76. package/src/utils/I18n/translations/vi.json +21 -19
  77. package/src/utils/Route/index.js +2 -0
  78. package/src/utils/Storage.js +6 -0
@@ -0,0 +1,387 @@
1
+ import React from 'react';
2
+ import { create, act } from 'react-test-renderer';
3
+ import MockAdapter from 'axios-mock-adapter';
4
+ import { useRoute } from '@react-navigation/native';
5
+ import SegmentedControl from '@react-native-community/segmented-control';
6
+ import Toast from 'react-native-toast-message';
7
+
8
+ import { SCProvider } from '../../../../context';
9
+ import { mockSCStore } from '../../../../context/mockStore';
10
+ import DeviceInternalDetail from '..';
11
+ import { HeaderCustom } from '../../../../commons';
12
+ import { AccessibilityLabel } from '../../../../configs/Constants';
13
+ import Routes from '../../../../utils/Route';
14
+ import TabPaneCT from '../../components/TabPaneCT';
15
+ import MenuActionMore from '../../../../commons/MenuActionMore';
16
+ import api from '../../../../utils/Apis/axios';
17
+ import { API } from '../../../../configs';
18
+ import { PERMISSION_TYPE } from '../../../../configs/Constants';
19
+ import Detail from '../../components/Detail';
20
+ import ModalPopupCT from '../../../../commons/ModalPopupCT';
21
+
22
+ const mock = new MockAdapter(api.axiosInstance);
23
+
24
+ const wrapComponent = () => (
25
+ <SCProvider initState={mockSCStore({})}>
26
+ <DeviceInternalDetail />
27
+ </SCProvider>
28
+ );
29
+
30
+ jest.mock('react-native', () => {
31
+ const RN = jest.requireActual('react-native');
32
+ return Object.setPrototypeOf(
33
+ {
34
+ Alert: {
35
+ ...RN.Alert,
36
+ alert: jest.fn(),
37
+ },
38
+ },
39
+ RN
40
+ );
41
+ });
42
+
43
+ const mockPop = jest.fn();
44
+ const mockNavigate = jest.fn();
45
+ jest.mock('@react-navigation/native', () => {
46
+ return {
47
+ ...jest.requireActual('@react-navigation/native'),
48
+ useNavigation: () => ({
49
+ navigate: mockNavigate,
50
+ pop: mockPop,
51
+ }),
52
+ useRoute: jest.fn(),
53
+ useIsFocused: () => true,
54
+ };
55
+ });
56
+
57
+ const headerCustomOnPressMore = async (instance) => {
58
+ const headerCustom = instance?.findAllByType(HeaderCustom);
59
+ const buttonMore = headerCustom[0].findByProps({
60
+ accessibilityLabel: AccessibilityLabel.MENU_POPPER_MORE,
61
+ });
62
+ await act(async () => {
63
+ buttonMore.props.onPress();
64
+ });
65
+ };
66
+
67
+ describe('Test DeviceInternalDetail', () => {
68
+ let tree;
69
+ const listConfigReads = [
70
+ {
71
+ id: 1,
72
+ config: { name: 'config1' },
73
+ value_type: 'boolean',
74
+ pin_number: 0,
75
+ pin_mode: 'input',
76
+ },
77
+ {
78
+ id: 2,
79
+ config: { name: 'config2' },
80
+ value_type: 'integer',
81
+ pin_number: 0,
82
+ pin_mode: 'input',
83
+ },
84
+ ];
85
+ const listConfigWrites = [
86
+ {
87
+ id: 1,
88
+ config: { name: 'config1' },
89
+ value_type: 'boolean',
90
+ pin_number: 0,
91
+ pin_mode: 'output',
92
+ },
93
+ {
94
+ id: 2,
95
+ config: { name: 'config2' },
96
+ value_type: 'integer',
97
+ pin_number: 0,
98
+ pin_mode: 'output',
99
+ },
100
+ ];
101
+ const listActions = [
102
+ {
103
+ id: 1,
104
+ action: { name: 'action 1' },
105
+ pin: 0,
106
+ default_value: 0,
107
+ },
108
+ ];
109
+ beforeEach(() => {
110
+ useRoute.mockReturnValue({
111
+ params: {
112
+ device: { id: 1, name: 'abc' },
113
+ gatewayId: 1,
114
+ isInternal: true,
115
+ },
116
+ });
117
+ });
118
+ afterEach(() => {
119
+ mock.reset();
120
+ mock.resetHistory();
121
+ mockNavigate.mockClear();
122
+ Toast.show.mockClear();
123
+ });
124
+
125
+ it('test render DeviceInternalDetail', async () => {
126
+ await act(async () => {
127
+ tree = await create(wrapComponent());
128
+ });
129
+ const instance = tree.root;
130
+ const detail = instance?.findByType(Detail);
131
+ const headerCustom = detail.findAllByType(HeaderCustom);
132
+ const tabPaneCT = detail.findAllByType(TabPaneCT);
133
+ const menuActionMore = detail.findAllByType(MenuActionMore);
134
+
135
+ expect(headerCustom).toHaveLength(1);
136
+ expect(tabPaneCT).toHaveLength(1);
137
+ expect(menuActionMore).toHaveLength(1);
138
+ });
139
+
140
+ it('test render DeviceInternalDetail onPress more and onPress DeviceGatewayInfo', async () => {
141
+ await act(async () => {
142
+ tree = await create(wrapComponent());
143
+ });
144
+ const instance = tree.root;
145
+ const detail = instance?.findByType(Detail);
146
+ headerCustomOnPressMore(detail);
147
+ const menuActionMore = detail?.findAllByType(MenuActionMore);
148
+ expect(menuActionMore[0].props.isVisible).toEqual(true);
149
+ await act(async () => {
150
+ menuActionMore[0].props.listMenuItem[0].doAction();
151
+ });
152
+ expect(mockNavigate).toHaveBeenCalledWith(Routes.DeviceGatewayInfo, {
153
+ device: { id: 1, name: 'abc' },
154
+ isDevice: true,
155
+ isInternal: true,
156
+ });
157
+ });
158
+
159
+ it('test render DeviceInternalDetail onPress more and onPress Delete internal', async () => {
160
+ await act(async () => {
161
+ tree = await create(wrapComponent());
162
+ });
163
+ const instance = tree.root;
164
+ const detail = instance?.findByType(Detail);
165
+ headerCustomOnPressMore(detail);
166
+ const menuActionMore = detail?.findByType(MenuActionMore);
167
+ expect(menuActionMore.props.isVisible).toEqual(true);
168
+ await act(async () => {
169
+ menuActionMore.props.listMenuItem[1].doAction();
170
+ });
171
+ const modal = instance.findByType(ModalPopupCT);
172
+ await act(async () => {
173
+ await modal.props.onPressConfirm();
174
+ });
175
+ mock.onDelete(API.DEV_MODE.ARDUINO.DEVICE_DETAIL(1, 1)).reply(200);
176
+ expect(mockPop).toBeCalledWith(1);
177
+ expect(Toast.show).toBeCalledWith({
178
+ position: 'bottom',
179
+ text1: 'Delete successfully!',
180
+ text2: undefined,
181
+ type: 'success',
182
+ visibilityTime: 1000,
183
+ });
184
+ });
185
+
186
+ it('test render DeviceInternalDetail onPress TabPanel config write', async () => {
187
+ mock
188
+ .onGet(API.DEV_MODE.ARDUINO.CONFIG_PINS(1, 1))
189
+ .reply(200, listConfigWrites);
190
+ await act(async () => {
191
+ tree = await create(wrapComponent());
192
+ });
193
+ const instance = tree.root;
194
+ const detail = instance?.findByType(Detail);
195
+ const tabPaneCT = detail.findByType(TabPaneCT);
196
+ const segmentedControl = tabPaneCT.findByType(SegmentedControl);
197
+ await act(async () => {
198
+ await segmentedControl.props.onChange({
199
+ nativeEvent: { selectedSegmentIndex: 0 },
200
+ });
201
+ });
202
+ expect(tabPaneCT.props.listTabs[0].data).toEqual(listConfigWrites);
203
+ expect(tabPaneCT.props.listTabs[0].title).toEqual(
204
+ PERMISSION_TYPE.CONFIG_WRITE
205
+ );
206
+ });
207
+
208
+ it('test render DeviceInternalDetail onPress TabPanel config read', async () => {
209
+ mock
210
+ .onGet(API.DEV_MODE.ARDUINO.CONFIG_PINS(1, 1))
211
+ .reply(200, listConfigReads);
212
+ await act(async () => {
213
+ tree = await create(wrapComponent());
214
+ });
215
+ const instance = tree.root;
216
+ const detail = instance?.findByType(Detail);
217
+ const tabPaneCT = detail.findByType(TabPaneCT);
218
+ const segmentedControl = tabPaneCT.findByType(SegmentedControl);
219
+ await act(async () => {
220
+ await segmentedControl.props.onChange({
221
+ nativeEvent: { selectedSegmentIndex: 1 },
222
+ });
223
+ });
224
+ expect(tabPaneCT.props.listTabs[1].data).toEqual(listConfigReads);
225
+ expect(tabPaneCT.props.listTabs[1].title).toEqual(
226
+ PERMISSION_TYPE.CONFIG_READ
227
+ );
228
+ });
229
+
230
+ it('test render DeviceInternalDetail onPress TabPanel action', async () => {
231
+ mock.onGet(API.DEV_MODE.ARDUINO.ACTION(1, 1)).reply(200, listActions);
232
+ await act(async () => {
233
+ tree = await create(wrapComponent());
234
+ });
235
+ const instance = tree.root;
236
+ const detail = instance?.findByType(Detail);
237
+ const tabPaneCT = detail.findByType(TabPaneCT);
238
+ const segmentedControl = tabPaneCT.findByType(SegmentedControl);
239
+ await act(async () => {
240
+ await segmentedControl.props.onChange({
241
+ nativeEvent: { selectedSegmentIndex: 2 },
242
+ });
243
+ });
244
+ expect(tabPaneCT.props.listTabs[2].data).toEqual([
245
+ {
246
+ id: 1,
247
+ action: { name: 'action 1' },
248
+ pin: 0,
249
+ default_value: 0,
250
+ },
251
+ ]);
252
+ expect(tabPaneCT.props.listTabs[2].title).toEqual(PERMISSION_TYPE.ACTION);
253
+ });
254
+
255
+ it('test render DeviceInternalDetail onPress TabPanel config write onPressRow', async () => {
256
+ mock
257
+ .onGet(API.DEV_MODE.ARDUINO.CONFIG_PINS(1, 1))
258
+ .reply(200, listConfigWrites);
259
+ await act(async () => {
260
+ tree = await create(wrapComponent());
261
+ });
262
+ const instance = tree.root;
263
+ const detail = instance?.findByType(Detail);
264
+ const tabPaneCT = detail.findByType(TabPaneCT);
265
+ const segmentedControl = tabPaneCT.findByType(SegmentedControl);
266
+ await act(async () => {
267
+ await segmentedControl.props.onChange({
268
+ nativeEvent: { selectedSegmentIndex: 0 },
269
+ });
270
+ });
271
+ await act(async () => {
272
+ await detail.props.onPressRow(1);
273
+ });
274
+ expect(mockNavigate).toBeCalledWith(Routes.DetailConfigActionInterval, {
275
+ device: {
276
+ id: 1,
277
+ name: 'abc',
278
+ },
279
+ isAction: false,
280
+ isConfigRead: false,
281
+ isConfigWrite: true,
282
+ itemActionConfig: 1,
283
+ });
284
+ });
285
+
286
+ it('test render DeviceInternalDetail onPress TabPanel config read onPressRow', async () => {
287
+ mock
288
+ .onGet(API.DEV_MODE.ARDUINO.CONFIG_PINS(1, 1))
289
+ .reply(200, listConfigReads);
290
+ await act(async () => {
291
+ tree = await create(wrapComponent());
292
+ });
293
+ const instance = tree.root;
294
+ const detail = instance?.findByType(Detail);
295
+ const tabPaneCT = detail.findByType(TabPaneCT);
296
+ const segmentedControl = tabPaneCT.findByType(SegmentedControl);
297
+ await act(async () => {
298
+ await segmentedControl.props.onChange({
299
+ nativeEvent: { selectedSegmentIndex: 1 },
300
+ });
301
+ });
302
+ await act(async () => {
303
+ await detail.props.onPressRow(1);
304
+ });
305
+ expect(mockNavigate).toBeCalledWith(Routes.DetailConfigActionInterval, {
306
+ device: {
307
+ id: 1,
308
+ name: 'abc',
309
+ },
310
+ isAction: false,
311
+ isConfigRead: true,
312
+ isConfigWrite: false,
313
+ itemActionConfig: 1,
314
+ });
315
+ });
316
+
317
+ it('test render DeviceInternalDetail onPress TabPanel action onPressRow', async () => {
318
+ mock.onGet(API.DEV_MODE.ARDUINO.ACTION(1, 1)).reply(200, listActions);
319
+ await act(async () => {
320
+ tree = await create(wrapComponent());
321
+ });
322
+ const instance = tree.root;
323
+ const detail = instance?.findByType(Detail);
324
+ const tabPaneCT = detail.findByType(TabPaneCT);
325
+ const segmentedControl = tabPaneCT.findByType(SegmentedControl);
326
+ await act(async () => {
327
+ await segmentedControl.props.onChange({
328
+ nativeEvent: { selectedSegmentIndex: 2 },
329
+ });
330
+ });
331
+ await act(async () => {
332
+ await detail.props.onPressRow(1);
333
+ });
334
+ expect(mockNavigate).toBeCalledWith(Routes.DetailConfigActionInterval, {
335
+ device: {
336
+ id: 1,
337
+ name: 'abc',
338
+ },
339
+ isAction: true,
340
+ isConfigRead: false,
341
+ isConfigWrite: false,
342
+ itemActionConfig: 1,
343
+ });
344
+ });
345
+
346
+ it('test render DeviceInternalDetail onPress TabPanel config write onRefresh', async () => {
347
+ mock
348
+ .onGet(API.DEV_MODE.ARDUINO.CONFIG_PINS(1, 1))
349
+ .reply(200, listConfigWrites);
350
+
351
+ await act(async () => {
352
+ tree = await create(wrapComponent());
353
+ });
354
+ const instance = tree.root;
355
+ const detail = instance?.findByType(Detail);
356
+ const tabPaneCT = detail.findByType(TabPaneCT);
357
+ await act(async () => {
358
+ await detail.props.onRefresh();
359
+ });
360
+ expect(tabPaneCT.props.listTabs[0].data).toEqual(listConfigWrites);
361
+ expect(tabPaneCT.props.listTabs[0].title).toEqual(
362
+ PERMISSION_TYPE.CONFIG_WRITE
363
+ );
364
+ });
365
+
366
+ it('test render DeviceInternalDetail onPress TabPanel action onRefresh', async () => {
367
+ mock.onGet(API.DEV_MODE.ARDUINO.ACTION(1, 1)).reply(200, listActions);
368
+
369
+ await act(async () => {
370
+ tree = await create(wrapComponent());
371
+ });
372
+ const instance = tree.root;
373
+ const detail = instance?.findByType(Detail);
374
+ const tabPaneCT = detail.findByType(TabPaneCT);
375
+ const segmentedControl = tabPaneCT.findByType(SegmentedControl);
376
+ await act(async () => {
377
+ await segmentedControl.props.onChange({
378
+ nativeEvent: { selectedSegmentIndex: 2 },
379
+ });
380
+ });
381
+ await act(async () => {
382
+ await detail.props.onRefresh();
383
+ });
384
+ expect(tabPaneCT.props.listTabs[2].data).toEqual(listActions);
385
+ expect(tabPaneCT.props.listTabs[2].title).toEqual(PERMISSION_TYPE.ACTION);
386
+ });
387
+ });
@@ -0,0 +1,188 @@
1
+ import React, { memo, useMemo, useEffect, useCallback } from 'react';
2
+ import { View } from 'react-native';
3
+ import t from '../../../hooks/Common/useTranslations';
4
+ import {
5
+ useRoute,
6
+ useNavigation,
7
+ useIsFocused,
8
+ } from '@react-navigation/native';
9
+
10
+ import { useGateway } from '../hooks/useGateway';
11
+ import Routes from '../../../utils/Route';
12
+ import { PERMISSION_TYPE } from '../../../configs/Constants';
13
+ import Detail from '../components/Detail';
14
+ import styles from './styles';
15
+
16
+ const DeviceInternalDetail = () => {
17
+ const { params = {} } = useRoute();
18
+ const { device = {}, gatewayId = '', isInternal } = params;
19
+ const { navigate } = useNavigation();
20
+ const isFocused = useIsFocused();
21
+
22
+ const {
23
+ selectedIndex,
24
+ detailDeviceInternal,
25
+ dataModalPopupCT,
26
+ setSelectedIndex,
27
+ deleteDeviceDetail,
28
+ fetchConfigActionInterval,
29
+ setRefresh,
30
+ refresh,
31
+ saveDataModalPopupCT,
32
+ hideModalPopupCT,
33
+ } = useGateway();
34
+
35
+ const listTabs = useMemo(
36
+ () => [
37
+ {
38
+ id: 1,
39
+ title: PERMISSION_TYPE.CONFIG_WRITE,
40
+ data: detailDeviceInternal?.config_write,
41
+ },
42
+ {
43
+ id: 2,
44
+ title: PERMISSION_TYPE.CONFIG_READ,
45
+ data: detailDeviceInternal?.config_read,
46
+ },
47
+ {
48
+ id: 3,
49
+ title: PERMISSION_TYPE.ACTION,
50
+ data: detailDeviceInternal?.actions,
51
+ },
52
+ ],
53
+ [
54
+ detailDeviceInternal?.actions,
55
+ detailDeviceInternal?.config_read,
56
+ detailDeviceInternal?.config_write,
57
+ ]
58
+ );
59
+
60
+ const handleDeleteDevice = useCallback(() => {
61
+ saveDataModalPopupCT({
62
+ title: `${t('delete_device', { name: device?.sensor?.name })}`,
63
+ subTitle: t('message_delete_device'),
64
+ type: 'device',
65
+ isVisible: true,
66
+ isShowUnderstand: false,
67
+ isShowAlert: false,
68
+ isChecked: false,
69
+ onPressConfirm: () => {
70
+ hideModalPopupCT();
71
+ deleteDeviceDetail(gatewayId, device?.id, isInternal);
72
+ },
73
+ onPressCancel: () => hideModalPopupCT(),
74
+ });
75
+ }, [
76
+ deleteDeviceDetail,
77
+ device?.id,
78
+ device?.sensor?.name,
79
+ gatewayId,
80
+ hideModalPopupCT,
81
+ isInternal,
82
+ saveDataModalPopupCT,
83
+ ]);
84
+
85
+ const listMenuItem = useMemo(() => {
86
+ const RouteGatewayInformation = {
87
+ id: 1,
88
+ text: t('device_information'),
89
+ doAction: () =>
90
+ navigate(Routes.DeviceGatewayInfo, {
91
+ device,
92
+ isDevice: true,
93
+ isInternal,
94
+ }),
95
+ };
96
+ const ListDeleteGateway = {
97
+ id: 2,
98
+ text: t('delete_device'),
99
+ textStyle: styles.textColorRed,
100
+ doAction: handleDeleteDevice,
101
+ };
102
+ return [RouteGatewayInformation, ListDeleteGateway];
103
+ }, [handleDeleteDevice, navigate, device, isInternal]);
104
+
105
+ const isConfigRead = useMemo(() => {
106
+ return listTabs[selectedIndex]?.title === PERMISSION_TYPE.CONFIG_READ;
107
+ }, [listTabs, selectedIndex]);
108
+
109
+ const isConfigWrite = useMemo(() => {
110
+ return listTabs[selectedIndex]?.title === PERMISSION_TYPE.CONFIG_WRITE;
111
+ }, [listTabs, selectedIndex]);
112
+
113
+ const isAction = useMemo(() => {
114
+ return listTabs[selectedIndex]?.title === PERMISSION_TYPE.ACTION;
115
+ }, [listTabs, selectedIndex]);
116
+
117
+ useEffect(() => {
118
+ if (isFocused) {
119
+ if (isConfigRead || isConfigWrite) {
120
+ fetchConfigActionInterval(gatewayId, device?.id);
121
+ return;
122
+ }
123
+ if (isAction) {
124
+ fetchConfigActionInterval(gatewayId, device?.id, 'action');
125
+ return;
126
+ }
127
+ }
128
+ }, [
129
+ fetchConfigActionInterval,
130
+ gatewayId,
131
+ isFocused,
132
+ device?.id,
133
+ isConfigRead,
134
+ isConfigWrite,
135
+ isAction,
136
+ ]);
137
+
138
+ const onPressRow = useCallback(
139
+ (item) => {
140
+ navigate(Routes.DetailConfigActionInterval, {
141
+ itemActionConfig: item,
142
+ device: device,
143
+ isConfigRead,
144
+ isConfigWrite,
145
+ isAction,
146
+ });
147
+ },
148
+ [device, isAction, isConfigRead, isConfigWrite, navigate]
149
+ );
150
+
151
+ const onRefresh = useCallback(() => {
152
+ setRefresh(true);
153
+ if (isConfigRead || isConfigWrite) {
154
+ fetchConfigActionInterval(gatewayId, device?.id);
155
+ }
156
+ if (isAction) {
157
+ fetchConfigActionInterval(gatewayId, device?.id, 'action');
158
+ }
159
+ setRefresh(false);
160
+ }, [
161
+ device?.id,
162
+ fetchConfigActionInterval,
163
+ gatewayId,
164
+ isAction,
165
+ isConfigRead,
166
+ isConfigWrite,
167
+ setRefresh,
168
+ ]);
169
+
170
+ return (
171
+ <View style={styles.wrap}>
172
+ <Detail
173
+ title={device?.sensor?.name || ''}
174
+ listMenuItem={listMenuItem}
175
+ listTabs={listTabs}
176
+ selectedIndex={selectedIndex}
177
+ setSelectedIndex={setSelectedIndex}
178
+ isDevice
179
+ onPressRow={onPressRow}
180
+ onRefresh={onRefresh}
181
+ refresh={refresh}
182
+ dataModalPopupCT={dataModalPopupCT}
183
+ />
184
+ </View>
185
+ );
186
+ };
187
+
188
+ export default memo(DeviceInternalDetail);
@@ -23,13 +23,14 @@ const DeviceModbusDetail = () => {
23
23
  selectedIndex,
24
24
  detailDeviceModbus,
25
25
  dataModalPopupCT,
26
- setDataModalPopupCT,
27
26
  setSelectedIndex,
28
27
  deleteDeviceDetail,
29
28
  fetchRegistersModbus,
30
29
  fetchActionsModbus,
31
30
  setRefresh,
32
31
  refresh,
32
+ saveDataModalPopupCT,
33
+ hideModalPopupCT,
33
34
  } = useGateway();
34
35
 
35
36
  const listTabs = useMemo(
@@ -58,8 +59,7 @@ const DeviceModbusDetail = () => {
58
59
  );
59
60
 
60
61
  const handleDeleteDevice = useCallback(() => {
61
- setDataModalPopupCT((prev) => ({
62
- ...prev,
62
+ saveDataModalPopupCT({
63
63
  title: `${t('delete_device', { name: device?.sensor?.name })}`,
64
64
  subTitle: t('message_delete_device'),
65
65
  type: 'device',
@@ -68,27 +68,19 @@ const DeviceModbusDetail = () => {
68
68
  isShowAlert: false,
69
69
  isChecked: false,
70
70
  onPressConfirm: () => {
71
- setDataModalPopupCT((prevData) => ({
72
- ...prevData,
73
- isVisible: false,
74
- isChecked: false,
75
- }));
76
- deleteDeviceDetail(gatewayId, device?.id, false, isModbus);
71
+ hideModalPopupCT();
72
+ deleteDeviceDetail(gatewayId, device?.id, false, false, isModbus);
77
73
  },
78
- onPressCancel: () =>
79
- setDataModalPopupCT((prevData) => ({
80
- ...prevData,
81
- isVisible: false,
82
- isChecked: false,
83
- })),
84
- }));
74
+ onPressCancel: () => hideModalPopupCT(),
75
+ });
85
76
  }, [
86
77
  deleteDeviceDetail,
87
78
  device?.id,
88
79
  device?.sensor?.name,
89
80
  gatewayId,
81
+ hideModalPopupCT,
90
82
  isModbus,
91
- setDataModalPopupCT,
83
+ saveDataModalPopupCT,
92
84
  ]);
93
85
 
94
86
  const listMenuItem = useMemo(() => {
@@ -22,13 +22,14 @@ const DeviceZigbeeDetail = () => {
22
22
  const {
23
23
  selectedIndex,
24
24
  setSelectedIndex,
25
- setDataModalPopupCT,
26
25
  dataModalPopupCT,
27
26
  fetchActionConfigDevice,
28
27
  deleteDeviceDetail,
29
28
  detailDeviceZigbee,
30
29
  setRefresh,
31
30
  refresh,
31
+ saveDataModalPopupCT,
32
+ hideModalPopupCT,
32
33
  } = useGateway();
33
34
 
34
35
  const listTabs = useMemo(
@@ -48,8 +49,7 @@ const DeviceZigbeeDetail = () => {
48
49
  );
49
50
 
50
51
  const handleDeleteDevice = useCallback(() => {
51
- setDataModalPopupCT((prev) => ({
52
- ...prev,
52
+ saveDataModalPopupCT({
53
53
  title: `${t('delete_device', { name: device?.sensor?.name })}`,
54
54
  subTitle: t('message_delete_device'),
55
55
  type: 'device',
@@ -58,27 +58,19 @@ const DeviceZigbeeDetail = () => {
58
58
  isShowAlert: false,
59
59
  isChecked: false,
60
60
  onPressConfirm: () => {
61
- setDataModalPopupCT((prevData) => ({
62
- ...prevData,
63
- isVisible: false,
64
- isChecked: false,
65
- }));
66
- deleteDeviceDetail(gatewayId, device?.id, isZigbee, false);
61
+ hideModalPopupCT();
62
+ deleteDeviceDetail(gatewayId, device?.id, false, isZigbee, false);
67
63
  },
68
- onPressCancel: () =>
69
- setDataModalPopupCT((prevData) => ({
70
- ...prevData,
71
- isVisible: false,
72
- isChecked: false,
73
- })),
74
- }));
64
+ onPressCancel: () => hideModalPopupCT(),
65
+ });
75
66
  }, [
76
67
  deleteDeviceDetail,
77
68
  device?.id,
78
69
  device?.sensor?.name,
79
70
  gatewayId,
80
71
  isZigbee,
81
- setDataModalPopupCT,
72
+ saveDataModalPopupCT,
73
+ hideModalPopupCT,
82
74
  ]);
83
75
 
84
76
  const listMenuItem = useMemo(() => {