@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.
- package/package.json +1 -1
- package/src/commons/Dashboard/MyPinnedSharedUnit/index.js +10 -0
- package/src/commons/Dashboard/MyUnit/index.js +9 -3
- package/src/commons/Device/HorizontalBarChart.js +3 -3
- package/src/commons/Device/WindSpeed/Anemometer/index.js +10 -26
- package/src/commons/FourButtonFilterHistory/index.js +1 -1
- package/src/configs/API.js +14 -0
- package/src/configs/Constants.js +1 -0
- package/src/context/actionType.ts +1 -0
- package/src/context/reducer.ts +10 -0
- package/src/navigations/AllGatewayStack.js +19 -9
- package/src/navigations/UnitStack.js +1 -1
- package/src/screens/AllGateway/DetailConfigActionInternal/__test__/index.test.js +104 -0
- package/src/screens/AllGateway/DetailConfigActionInternal/index.js +97 -0
- package/src/screens/{Gateway/DetailConfigActionModbus → AllGateway/DetailConfigActionInternal}/styles.js +0 -0
- package/src/screens/{Gateway → AllGateway}/DetailConfigActionModbus/__test__/index.test.js +0 -0
- package/src/screens/{Gateway → AllGateway}/DetailConfigActionModbus/index.js +0 -0
- package/src/screens/{Gateway/DeviceGatewayInfo → AllGateway/DetailConfigActionModbus}/styles.js +0 -0
- package/src/screens/{Gateway → AllGateway}/DetailConfigActionZigbee/__test__/index.test.js +0 -0
- package/src/screens/{Gateway → AllGateway}/DetailConfigActionZigbee/index.js +0 -0
- package/src/screens/{Gateway → AllGateway}/DetailConfigActionZigbee/styles.js +0 -0
- package/src/screens/{Gateway → AllGateway}/DeviceGatewayInfo/__test__/index.test.js +0 -0
- package/src/screens/{Gateway → AllGateway}/DeviceGatewayInfo/index.js +26 -2
- package/src/screens/{Gateway/GatewayInfo → AllGateway/DeviceGatewayInfo}/styles.js +0 -0
- package/src/screens/AllGateway/DeviceInternalDetail/__test__/index.test.js +387 -0
- package/src/screens/AllGateway/DeviceInternalDetail/index.js +188 -0
- package/src/screens/{Gateway/DeviceModbusDetail → AllGateway/DeviceInternalDetail}/styles.js +0 -0
- package/src/screens/{Gateway → AllGateway}/DeviceModbusDetail/__test__/index.test.js +0 -0
- package/src/screens/{Gateway → AllGateway}/DeviceModbusDetail/index.js +9 -17
- package/src/screens/{Gateway/DeviceZigbeeDetail → AllGateway/DeviceModbusDetail}/styles.js +0 -0
- package/src/screens/{Gateway → AllGateway}/DeviceZigbeeDetail/__test__/index.test.js +0 -0
- package/src/screens/{Gateway → AllGateway}/DeviceZigbeeDetail/index.js +9 -17
- package/src/screens/{Gateway/GatewayDetail → AllGateway/DeviceZigbeeDetail}/styles.js +0 -0
- package/src/screens/{Gateway → AllGateway}/GatewayConnectionMethods/__test__/index.test.js +0 -0
- package/src/screens/{Gateway → AllGateway}/GatewayConnectionMethods/index.js +0 -0
- package/src/screens/{Gateway → AllGateway}/GatewayConnectionMethods/styles.js +0 -0
- package/src/screens/{Gateway → AllGateway}/GatewayDetail/__test__/index.test.js +71 -31
- package/src/screens/{Gateway → AllGateway}/GatewayDetail/index.js +62 -42
- package/src/screens/AllGateway/GatewayDetail/styles.js +12 -0
- package/src/screens/{Gateway → AllGateway}/GatewayInfo/__test__/index.test.js +0 -0
- package/src/screens/{Gateway → AllGateway}/GatewayInfo/index.js +14 -17
- package/src/screens/AllGateway/GatewayInfo/styles.js +12 -0
- package/src/screens/{Gateway → AllGateway}/__test__/index.test.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/Detail/__test__/index.test.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/Detail/index.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/Detail/styles.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/DetailActionModbus/__test__/index.test.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/DetailActionModbus/index.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/DetailActionModbus/styles.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/DetailConfigAction/__test__/index.test.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/DetailConfigAction/index.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/DetailConfigAction/styles.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/GatewayItem/__test__/index.test.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/GatewayItem/index.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/GatewayItem/styles.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/Information/__test__/index.test.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/Information/index.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/Information/styles.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/RowItem/__test__/index.test.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/RowItem/index.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/RowItem/styles.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/TabPaneCT/__test__/index.test.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/TabPaneCT/index.js +0 -0
- package/src/screens/{Gateway → AllGateway}/components/TabPaneCT/styles.js +0 -0
- package/src/screens/{Gateway → AllGateway}/hooks/__test__/index.test.js +15 -2
- package/src/screens/{Gateway → AllGateway}/hooks/useGateway.js +91 -11
- package/src/screens/{Gateway → AllGateway}/index.js +2 -2
- package/src/screens/{Gateway → AllGateway}/styles.js +0 -0
- package/src/screens/{Gateway → AllGateway}/utils/index.js +0 -0
- package/src/screens/Device/__test__/DetailHistoryChart.test.js +25 -10
- package/src/screens/Device/components/DetailHistoryChart.js +72 -22
- package/src/screens/WaterQualityGuide/__test__/index.test.js +8 -8
- package/src/screens/WaterQualityGuide/index.js +32 -53
- package/src/utils/Functions/preloadImages.js +39 -0
- package/src/utils/I18n/translations/en.json +21 -16
- package/src/utils/I18n/translations/vi.json +21 -19
- package/src/utils/Route/index.js +2 -0
- 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);
|
package/src/screens/{Gateway/DeviceModbusDetail → AllGateway/DeviceInternalDetail}/styles.js
RENAMED
|
File without changes
|
|
File without changes
|
|
@@ -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
|
-
|
|
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
|
-
|
|
72
|
-
|
|
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
|
-
|
|
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
|
-
|
|
83
|
+
saveDataModalPopupCT,
|
|
92
84
|
]);
|
|
93
85
|
|
|
94
86
|
const listMenuItem = useMemo(() => {
|
|
File without changes
|
|
File without changes
|
|
@@ -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
|
-
|
|
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
|
-
|
|
62
|
-
|
|
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
|
-
|
|
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
|
-
|
|
72
|
+
saveDataModalPopupCT,
|
|
73
|
+
hideModalPopupCT,
|
|
82
74
|
]);
|
|
83
75
|
|
|
84
76
|
const listMenuItem = useMemo(() => {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|