@eohjsc/react-native-smart-city 0.4.46 → 0.4.48
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/README.md +1 -5
- package/android/build.gradle +24 -19
- package/package.json +11 -14
- package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +7 -4
- package/src/commons/ActionGroup/__test__/ColorPickerTemplate.test.js +3 -6
- package/src/commons/ActionGroup/__test__/NumberUpDownTemplate.test.js +1 -4
- package/src/commons/ActionGroup/__test__/TwoButtonTemplate.test.js +11 -1
- package/src/commons/Dashboard/MyPinnedSharedUnit/__test__/MyPinnedSharedUnit.test.js +5 -0
- package/src/commons/Dashboard/MyPinnedSharedUnit/index.js +6 -1
- package/src/commons/Dashboard/MyUnit/index.js +6 -8
- package/src/commons/DateTimeRangeChange/index.js +3 -3
- package/src/commons/Device/Hanet/ItemHanetDevice.js +1 -5
- package/src/commons/Device/ItemAddNew/index.js +2 -6
- package/src/commons/Device/ItemDevice.js +1 -5
- package/src/commons/FlatListDnD/__test__/index.test.js +25 -27
- package/src/commons/GroupCheckBox/__test__/GroupCheckBox.test.js +22 -1
- package/src/commons/HeaderAni/index.js +2 -12
- package/src/commons/MediaPlayerDetail/__test__/MediaPlayerFull.test.js +23 -1
- package/src/commons/Modal/ModalCustom.js +2 -2
- package/src/commons/SubUnit/OneTap/ItemOneTap.js +2 -10
- package/src/commons/Unit/HeaderUnit/index.js +7 -18
- package/src/commons/Unit/SharedUnit.js +43 -58
- package/src/commons/Unit/__test__/SharedUnit.test.js +100 -60
- package/src/commons/UnitSummary/ConfigHistoryChart/__test__/ConfigHistoryChart.test.js +289 -0
- package/src/commons/UnitSummary/ConfigHistoryChart/index.js +59 -1
- package/src/commons/WrapParallaxScrollView/index.js +0 -4
- package/src/configs/AccessibilityLabel.js +0 -3
- package/src/hooks/IoT/__test__/useRemoteControl.test.js +51 -52
- package/src/hooks/IoT/__test__/useWatchConfigs.test.js +2 -3
- package/src/navigations/AutomateStack.js +2 -5
- package/src/navigations/NotificationStack.js +2 -28
- package/src/navigations/SharedStack.js +2 -8
- package/src/navigations/UnitStack.js +2 -2
- package/src/screens/AllGateway/DeviceModbusDetail/__test__/index.test.js +32 -31
- package/src/screens/Automate/EditActionsList/__tests__/index.test.js +68 -69
- package/src/screens/Automate/ScriptDetail/Styles/indexStyles.js +0 -1
- package/src/screens/Automate/ScriptDetail/index.js +7 -4
- package/src/screens/ChangePosition/__test__/index.test.js +32 -34
- package/src/screens/ConfirmUnitDeletion/__test__/ConfirmUnitDeletion.test.js +11 -1
- package/src/screens/Device/__test__/detail.test.js +1 -61
- package/src/screens/Device/components/ChartWrapper.js +12 -14
- package/src/screens/Device/components/VisualChart.js +1 -7
- package/src/screens/Device/components/__test__/VisualChart.test.js +3 -0
- package/src/screens/Device/detail.js +31 -28
- package/src/screens/Device/hooks/__test__/useEvaluateValue.test.js +18 -20
- package/src/screens/Device/styles.js +0 -3
- package/src/screens/Notification/__test__/Notification.test.js +8 -14
- package/src/screens/Notification/components/NotificationItem.js +0 -1
- package/src/screens/Notification/index.js +48 -42
- package/src/screens/Notification/styles/indexStyles.js +3 -6
- package/src/screens/SharedUnit/index.js +4 -1
- package/src/screens/Sharing/InfoMemberUnit.js +1 -3
- package/src/screens/Sharing/MemberList.js +3 -16
- package/src/screens/Sharing/__test__/InfoMemberUnit.test.js +0 -2
- package/src/screens/Sharing/__test__/SelectPermission.test.js +137 -96
- package/src/screens/Template/__test__/EditTemplate.test.js +45 -48
- package/src/screens/Unit/__test__/SelectAddress.test.js +11 -4
- package/src/screens/Unit/components/SharedUnit/index.js +9 -6
- package/src/screens/Unit/components/__test__/SharedUnit.test.js +15 -19
- package/src/screens/UnitSummary/components/3PPowerConsumption/__test__/3PPowerConsumption.test.js +11 -1
- package/src/utils/Monitor.js +2 -2
- package/src/Images/Common/pushpin-full.svg +0 -3
- package/src/Images/Common/pushpin-outline.svg +0 -3
- package/src/Images/Common/star-full.svg +0 -3
- package/src/Images/Common/star-outline.svg +0 -3
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { act, create } from 'react-test-renderer';
|
|
3
|
+
import MockAdapter from 'axios-mock-adapter';
|
|
4
|
+
|
|
5
|
+
import ConfigHistoryChart from '../';
|
|
6
|
+
import api from '../../../../utils/Apis/axios';
|
|
7
|
+
import { mockSCStore } from '../../../../context/mockStore';
|
|
8
|
+
import { SCProvider } from '../../../../context';
|
|
9
|
+
import API from '../../../../configs/API';
|
|
10
|
+
import { getPusher } from '../../../../utils/Pusher';
|
|
11
|
+
import Highcharts from '../../../Highcharts';
|
|
12
|
+
|
|
13
|
+
const mock = new MockAdapter(api.axiosInstance);
|
|
14
|
+
|
|
15
|
+
const wrapComponent = (configs = []) => (
|
|
16
|
+
<SCProvider initState={mockSCStore({})}>
|
|
17
|
+
<ConfigHistoryChart configs={configs} />
|
|
18
|
+
</SCProvider>
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
describe('Test HistoryChart', () => {
|
|
22
|
+
let tree;
|
|
23
|
+
|
|
24
|
+
beforeAll(() => {
|
|
25
|
+
jest.useFakeTimers();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
getPusher().subscribe.mockClear();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const assertChartData = async (data) => {
|
|
33
|
+
const chart = tree.root.findByType(Highcharts);
|
|
34
|
+
expect(chart.props.options.series[0].data).toEqual(
|
|
35
|
+
data.map((i) => [i.x, i.y])
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
it('Test render null', async () => {
|
|
40
|
+
await act(async () => {
|
|
41
|
+
tree = create(wrapComponent());
|
|
42
|
+
});
|
|
43
|
+
const instance = tree.root;
|
|
44
|
+
const HistoryCharts = instance.findAllByType(Highcharts);
|
|
45
|
+
expect(HistoryCharts).toHaveLength(0);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('Test render chart empty data', async () => {
|
|
49
|
+
const response = {
|
|
50
|
+
data: {
|
|
51
|
+
configs: [
|
|
52
|
+
{
|
|
53
|
+
id: 1,
|
|
54
|
+
head: [],
|
|
55
|
+
tail: [],
|
|
56
|
+
middle: {
|
|
57
|
+
ready: [],
|
|
58
|
+
not_ready: [],
|
|
59
|
+
channel: '',
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
mock.onGet(API.CONFIG.DISPLAY_HISTORY_V3()).reply(200, response.data);
|
|
66
|
+
const configs = [{ id: 1 }];
|
|
67
|
+
await act(async () => {
|
|
68
|
+
tree = await create(wrapComponent(configs));
|
|
69
|
+
jest.runAllTimers();
|
|
70
|
+
});
|
|
71
|
+
await assertChartData([]);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('Test render chart empty head data', async () => {
|
|
75
|
+
const response = {
|
|
76
|
+
data: {
|
|
77
|
+
configs: [
|
|
78
|
+
{
|
|
79
|
+
id: 1,
|
|
80
|
+
head: [],
|
|
81
|
+
tail: [{ x: 1, y: 2 }],
|
|
82
|
+
middle: {
|
|
83
|
+
ready: [],
|
|
84
|
+
not_ready: [],
|
|
85
|
+
channel: '',
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
mock.onGet(API.CONFIG.DISPLAY_HISTORY_V3()).reply(200, response.data);
|
|
92
|
+
const configs = [{ id: 1 }];
|
|
93
|
+
await act(async () => {
|
|
94
|
+
tree = await create(wrapComponent(configs));
|
|
95
|
+
jest.runAllTimers();
|
|
96
|
+
});
|
|
97
|
+
await assertChartData([{ x: 1, y: 2 }]);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('Test render chart empty tail data', async () => {
|
|
101
|
+
const response = {
|
|
102
|
+
data: {
|
|
103
|
+
configs: [
|
|
104
|
+
{
|
|
105
|
+
id: 1,
|
|
106
|
+
head: [{ x: 1, y: 2 }],
|
|
107
|
+
tail: [],
|
|
108
|
+
middle: {
|
|
109
|
+
ready: [],
|
|
110
|
+
not_ready: [],
|
|
111
|
+
channel: '',
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
mock.onGet(API.CONFIG.DISPLAY_HISTORY_V3()).reply(200, response.data);
|
|
118
|
+
const configs = [{ id: 1 }];
|
|
119
|
+
await act(async () => {
|
|
120
|
+
tree = await create(wrapComponent(configs));
|
|
121
|
+
jest.runAllTimers();
|
|
122
|
+
});
|
|
123
|
+
await assertChartData([{ x: 1, y: 2 }]);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('Test render chart merge head and tail data', async () => {
|
|
127
|
+
const response = {
|
|
128
|
+
data: {
|
|
129
|
+
configs: [
|
|
130
|
+
{
|
|
131
|
+
id: 1,
|
|
132
|
+
head: [{ x: 1, y: 2 }],
|
|
133
|
+
tail: [{ x: 2, y: 3 }],
|
|
134
|
+
middle: {
|
|
135
|
+
ready: [],
|
|
136
|
+
not_ready: [],
|
|
137
|
+
channel: '',
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
mock.onGet(API.CONFIG.DISPLAY_HISTORY_V3()).reply(200, response.data);
|
|
144
|
+
const configs = [{ id: 1 }];
|
|
145
|
+
await act(async () => {
|
|
146
|
+
tree = await create(wrapComponent(configs));
|
|
147
|
+
jest.runAllTimers();
|
|
148
|
+
});
|
|
149
|
+
await assertChartData([
|
|
150
|
+
{ x: 1, y: 2 },
|
|
151
|
+
{ x: 2, y: 3 },
|
|
152
|
+
]);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('Test render chart merge fetch ready data', async () => {
|
|
156
|
+
const cacheUrl = 'https://s3.eoh.io/xxx.json';
|
|
157
|
+
const response = {
|
|
158
|
+
data: {
|
|
159
|
+
configs: [
|
|
160
|
+
{
|
|
161
|
+
id: 1,
|
|
162
|
+
head: [{ x: 1, y: 2 }],
|
|
163
|
+
tail: [{ x: 2, y: 3 }],
|
|
164
|
+
middle: {
|
|
165
|
+
ready: [{ date: '2022-03-03', url: cacheUrl }],
|
|
166
|
+
not_ready: [],
|
|
167
|
+
channel: '',
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
mock.onGet(API.CONFIG.DISPLAY_HISTORY_V3()).reply(200, response.data);
|
|
174
|
+
mock.onGet(cacheUrl).reply(200, [{ x: 3, y: 4 }]);
|
|
175
|
+
const configs = [{ id: 1 }];
|
|
176
|
+
await act(async () => {
|
|
177
|
+
tree = await create(wrapComponent(configs));
|
|
178
|
+
jest.runAllTimers();
|
|
179
|
+
});
|
|
180
|
+
await assertChartData([
|
|
181
|
+
{ x: 1, y: 2 },
|
|
182
|
+
{ x: 3, y: 4 },
|
|
183
|
+
{ x: 2, y: 3 },
|
|
184
|
+
]);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('Test render chart merge fetch not-ready data', async () => {
|
|
188
|
+
const cacheUrl = 'https://s3.eoh.io/xxx.json';
|
|
189
|
+
const response = {
|
|
190
|
+
data: {
|
|
191
|
+
configs: [
|
|
192
|
+
{
|
|
193
|
+
id: 1,
|
|
194
|
+
head: [{ x: 1, y: 2 }],
|
|
195
|
+
tail: [{ x: 2, y: 3 }],
|
|
196
|
+
middle: {
|
|
197
|
+
ready: [],
|
|
198
|
+
not_ready: [{ date: '2022-03-03', url: cacheUrl }],
|
|
199
|
+
channel: 'cache-xxx',
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
],
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
mock.onGet(API.CONFIG.DISPLAY_HISTORY_V3()).reply(200, response.data);
|
|
206
|
+
mock.onGet(cacheUrl).reply(200, [{ x: 3, y: 4 }]);
|
|
207
|
+
const configs = [{ id: 1 }];
|
|
208
|
+
await act(async () => {
|
|
209
|
+
tree = await create(wrapComponent(configs));
|
|
210
|
+
jest.runAllTimers();
|
|
211
|
+
});
|
|
212
|
+
await assertChartData([
|
|
213
|
+
{ x: 1, y: 2 },
|
|
214
|
+
{ x: 2, y: 3 },
|
|
215
|
+
]);
|
|
216
|
+
await act(async () => {
|
|
217
|
+
await getPusher()
|
|
218
|
+
.subscribe('cache-xxx')
|
|
219
|
+
.trigger('caching-value-log-process', {
|
|
220
|
+
success: true,
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
await assertChartData([
|
|
224
|
+
{ x: 1, y: 2 },
|
|
225
|
+
{ x: 3, y: 4 },
|
|
226
|
+
{ x: 2, y: 3 },
|
|
227
|
+
]);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it('Test render chart merge fetch both ready and not-ready data', async () => {
|
|
231
|
+
const cacheUrl1 = 'https://s3.eoh.io/xxx1.json';
|
|
232
|
+
const cacheUrl2 = 'https://s3.eoh.io/xxx2.json';
|
|
233
|
+
const cacheUrl3 = 'https://s3.eoh.io/xxx3.json';
|
|
234
|
+
const cacheUrl4 = 'https://s3.eoh.io/xxx4.json';
|
|
235
|
+
const response = {
|
|
236
|
+
data: {
|
|
237
|
+
configs: [
|
|
238
|
+
{
|
|
239
|
+
id: 1,
|
|
240
|
+
head: [{ x: 1, y: 2 }],
|
|
241
|
+
tail: [{ x: 2, y: 3 }],
|
|
242
|
+
middle: {
|
|
243
|
+
ready: [
|
|
244
|
+
{ date: '2022-03-02', url: cacheUrl1 },
|
|
245
|
+
{ date: '2022-03-04', url: cacheUrl3 },
|
|
246
|
+
],
|
|
247
|
+
not_ready: [
|
|
248
|
+
{ date: '2022-03-03', url: cacheUrl2 },
|
|
249
|
+
{ date: '2022-03-05', url: cacheUrl4 },
|
|
250
|
+
],
|
|
251
|
+
channel: 'cache-xxx',
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
],
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
mock.onGet(API.CONFIG.DISPLAY_HISTORY_V3()).reply(200, response.data);
|
|
258
|
+
mock.onGet(cacheUrl1).reply(200, [{ x: 3, y: 4 }]);
|
|
259
|
+
mock.onGet(cacheUrl2).reply(200, [{ x: 4, y: 5 }]);
|
|
260
|
+
mock.onGet(cacheUrl3).reply(200, [{ x: 5, y: 6 }]);
|
|
261
|
+
mock.onGet(cacheUrl4).reply(200, [{ x: 7, y: 8 }]);
|
|
262
|
+
const configs = [{ id: 1 }];
|
|
263
|
+
await act(async () => {
|
|
264
|
+
tree = await create(wrapComponent(configs));
|
|
265
|
+
jest.runAllTimers();
|
|
266
|
+
});
|
|
267
|
+
await assertChartData([
|
|
268
|
+
{ x: 1, y: 2 },
|
|
269
|
+
{ x: 3, y: 4 },
|
|
270
|
+
{ x: 5, y: 6 },
|
|
271
|
+
{ x: 2, y: 3 },
|
|
272
|
+
]);
|
|
273
|
+
await act(async () => {
|
|
274
|
+
await getPusher()
|
|
275
|
+
.subscribe('cache-xxx')
|
|
276
|
+
.trigger('caching-value-log-process', {
|
|
277
|
+
success: true,
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
await assertChartData([
|
|
281
|
+
{ x: 1, y: 2 },
|
|
282
|
+
{ x: 3, y: 4 },
|
|
283
|
+
{ x: 4, y: 5 },
|
|
284
|
+
{ x: 5, y: 6 },
|
|
285
|
+
{ x: 7, y: 8 },
|
|
286
|
+
{ x: 2, y: 3 },
|
|
287
|
+
]);
|
|
288
|
+
});
|
|
289
|
+
});
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
1
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
|
+
import moment from 'moment';
|
|
2
3
|
|
|
3
4
|
import { API } from '../../../configs';
|
|
5
|
+
import HistoryChart from '../../../commons/Device/HistoryChart';
|
|
4
6
|
import { axiosGet } from '../../../utils/Apis/axios';
|
|
5
7
|
import { getPusher } from '../../../utils/Pusher';
|
|
6
8
|
|
|
@@ -99,6 +101,7 @@ export const updateConfigChart = async (
|
|
|
99
101
|
...config.middle.not_ready,
|
|
100
102
|
...config.middle.ready,
|
|
101
103
|
];
|
|
104
|
+
|
|
102
105
|
middleDataByDay.sort((a, b) => (a.date > b.date ? 1 : -1)); // small to large
|
|
103
106
|
const middleData = middleDataByDay.map((x) => x.data).flat();
|
|
104
107
|
data_by_id[config.id] = [...config.head, ...middleData, ...config.tail];
|
|
@@ -111,3 +114,58 @@ export const updateConfigChart = async (
|
|
|
111
114
|
}
|
|
112
115
|
});
|
|
113
116
|
};
|
|
117
|
+
|
|
118
|
+
let timeoutId;
|
|
119
|
+
|
|
120
|
+
const ConfigHistoryChart = ({ configs }) => {
|
|
121
|
+
const [chartData, setChartData] = useState(configs);
|
|
122
|
+
const [startDate, setStartDate] = useState(
|
|
123
|
+
moment().subtract(1, 'days').valueOf()
|
|
124
|
+
);
|
|
125
|
+
const [endDate, setEndDate] = useState(moment().valueOf());
|
|
126
|
+
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
const fetchData = async () => {
|
|
129
|
+
let params = new URLSearchParams();
|
|
130
|
+
let configuration = configs.filter((item) => item.id);
|
|
131
|
+
configuration.map((item) => {
|
|
132
|
+
params.append('configs', item.id);
|
|
133
|
+
});
|
|
134
|
+
params.append(
|
|
135
|
+
'date_from',
|
|
136
|
+
moment(startDate).utc().format('YYYY-MM-DD HH:mm:ss')
|
|
137
|
+
);
|
|
138
|
+
params.append(
|
|
139
|
+
'date_to',
|
|
140
|
+
moment(endDate).utc().format('YYYY-MM-DD HH:mm:ss')
|
|
141
|
+
);
|
|
142
|
+
const { success, data } = await axiosGet(
|
|
143
|
+
API.CONFIG.DISPLAY_HISTORY_V3(),
|
|
144
|
+
{
|
|
145
|
+
params,
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
updateConfigChart(success, data, configuration, setChartData);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
timeoutId = setTimeout(fetchData, 200);
|
|
152
|
+
return () => {
|
|
153
|
+
clearTimeout(timeoutId);
|
|
154
|
+
};
|
|
155
|
+
}, [startDate, endDate, configs]);
|
|
156
|
+
|
|
157
|
+
if (!chartData.length) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return (
|
|
162
|
+
<HistoryChart
|
|
163
|
+
configuration={{ type: 'line_chart', date_format: 'DD.MM' }}
|
|
164
|
+
datas={chartData}
|
|
165
|
+
setStartDate={setStartDate}
|
|
166
|
+
setEndDate={setEndDate}
|
|
167
|
+
/>
|
|
168
|
+
);
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
export default ConfigHistoryChart;
|
|
@@ -88,7 +88,6 @@ const WrapParallaxScrollView = ({
|
|
|
88
88
|
hideRight={hideRight}
|
|
89
89
|
hideRightPlus={hideRightPlus}
|
|
90
90
|
idButtonMore={idButtonMore}
|
|
91
|
-
iconBackStyle={styles.iconBackStyle}
|
|
92
91
|
/>
|
|
93
92
|
</View>
|
|
94
93
|
),
|
|
@@ -137,7 +136,4 @@ const styles = StyleSheet.create({
|
|
|
137
136
|
position: 'absolute',
|
|
138
137
|
bottom: 40,
|
|
139
138
|
},
|
|
140
|
-
iconBackStyle: {
|
|
141
|
-
tintColor: Colors.Black,
|
|
142
|
-
},
|
|
143
139
|
});
|
|
@@ -126,8 +126,6 @@ export default {
|
|
|
126
126
|
HORIZONTAL_BAR_CHART: 'HORIZONTAL_BAR_CHART',
|
|
127
127
|
DEVICE_SHOW_REMOVE: 'DEVICE_SHOW_REMOVE',
|
|
128
128
|
DEVICE_SHOW_RENAME: 'DEVICE_SHOW_RENAME',
|
|
129
|
-
PIN_BUTTON: 'PIN_BUTTON',
|
|
130
|
-
STAR_BUTTON: 'STAR_BUTTON',
|
|
131
129
|
|
|
132
130
|
// common
|
|
133
131
|
COMMON_LOADING_ANIMATION: 'COMMON_LOADING_ANIMATION',
|
|
@@ -675,7 +673,6 @@ export default {
|
|
|
675
673
|
GATEWAY_CONNECTION_METHODS_TEXT: 'GATEWAY_CONNECTION_METHODS_TEXT',
|
|
676
674
|
//Notification
|
|
677
675
|
CUSTOM_TEXT: 'CUSTOM_TEXT',
|
|
678
|
-
NotificationItemText: 'NotificationItemText',
|
|
679
676
|
//ButtonWrapper
|
|
680
677
|
BUTTON_WRAPPER: 'BUTTON_WRAPPER',
|
|
681
678
|
//devmod
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { act, renderHook } from '@testing-library/react-hooks';
|
|
3
3
|
import { useRemoteControl } from '../index';
|
|
4
4
|
import {
|
|
5
|
-
|
|
5
|
+
BLUETOOOH_DEVICE_UNSTABLE,
|
|
6
6
|
sendCommandOverBluetooth,
|
|
7
7
|
SEND_COMMAND_OVER_BLUETOOTH_FAIL,
|
|
8
8
|
} from '../../../iot/RemoteControl/Bluetooth';
|
|
@@ -35,7 +35,6 @@ describe('Test useRemoteControl', () => {
|
|
|
35
35
|
sendCommandOverBluetooth.mockClear();
|
|
36
36
|
sendCommandOverHomeAssistant.mockClear();
|
|
37
37
|
sendCommandOverInternet.mockClear();
|
|
38
|
-
jest.useFakeTimers();
|
|
39
38
|
|
|
40
39
|
sensor = {
|
|
41
40
|
id: 1,
|
|
@@ -255,58 +254,58 @@ describe('Test useRemoteControl', () => {
|
|
|
255
254
|
expect(sendCommandOverBluetooth).not.toBeCalled();
|
|
256
255
|
});
|
|
257
256
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
257
|
+
it('test send remote command via bluetooth case when bluetooh device unstable', async () => {
|
|
258
|
+
action.command_prefer_over_bluetooth = true;
|
|
259
|
+
action.command_prefer_over_internet = false;
|
|
260
|
+
const { result: sendRemoteCommand } = renderHook(() => useRemoteControl(), {
|
|
261
|
+
wrapper,
|
|
262
|
+
});
|
|
264
263
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
264
|
+
sendCommandOverBluetooth.mockImplementation(() => {
|
|
265
|
+
return BLUETOOOH_DEVICE_UNSTABLE;
|
|
266
|
+
});
|
|
267
|
+
await act(async () => {
|
|
268
|
+
await sendRemoteCommand.current(sensor, action, data, userId);
|
|
269
|
+
});
|
|
270
|
+
await flushPromises();
|
|
271
|
+
expect(sendCommandOverBluetooth).toBeCalledWith(
|
|
272
|
+
sensor,
|
|
273
|
+
action,
|
|
274
|
+
data,
|
|
275
|
+
userId
|
|
276
|
+
);
|
|
277
|
+
expect(sendCommandOverBluetooth).toBeCalledTimes(6);
|
|
278
|
+
});
|
|
280
279
|
|
|
281
280
|
// eslint-disable-next-line max-len
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
281
|
+
it('test send remote command via bluetooth case when bluetooh device unstable 5 times will switch send internet', async () => {
|
|
282
|
+
action.command_prefer_over_bluetooth = true;
|
|
283
|
+
action.command_prefer_over_internet = false;
|
|
284
|
+
const { result: sendRemoteCommand } = renderHook(() => useRemoteControl(), {
|
|
285
|
+
wrapper,
|
|
286
|
+
});
|
|
288
287
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
288
|
+
sendCommandOverBluetooth.mockImplementation(() => {
|
|
289
|
+
return BLUETOOOH_DEVICE_UNSTABLE;
|
|
290
|
+
});
|
|
291
|
+
sendCommandOverInternet.mockImplementation(async () => true);
|
|
292
|
+
await act(async () => {
|
|
293
|
+
await sendRemoteCommand.current(sensor, action, data, userId);
|
|
294
|
+
});
|
|
295
|
+
await flushPromises();
|
|
296
|
+
expect(sendCommandOverBluetooth).toBeCalledWith(
|
|
297
|
+
sensor,
|
|
298
|
+
action,
|
|
299
|
+
data,
|
|
300
|
+
userId
|
|
301
|
+
);
|
|
302
|
+
expect(sendCommandOverInternet).toBeCalledWith(
|
|
303
|
+
sensor,
|
|
304
|
+
action,
|
|
305
|
+
data,
|
|
306
|
+
'bluetooth'
|
|
307
|
+
);
|
|
308
|
+
expect(sendCommandOverBluetooth).toBeCalledTimes(6);
|
|
309
|
+
expect(sendCommandOverInternet).toBeCalledTimes(1);
|
|
310
|
+
});
|
|
312
311
|
});
|
|
@@ -40,8 +40,7 @@ describe('Test useWatchConfigs', () => {
|
|
|
40
40
|
renderHook(() => useWatchConfigs([1]), {
|
|
41
41
|
wrapper,
|
|
42
42
|
});
|
|
43
|
-
|
|
44
|
-
expect(
|
|
45
|
-
expect(unwatchMultiConfigs).not.toBeCalledWith([1]);
|
|
43
|
+
expect(watchMultiConfigs).toBeCalledWith([1]);
|
|
44
|
+
expect(unwatchMultiConfigs).toBeCalledWith([1]);
|
|
46
45
|
});
|
|
47
46
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { memo, useCallback, useEffect, useContext } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { TouchableOpacity } from 'react-native';
|
|
3
3
|
import { createStackNavigator } from '@react-navigation/stack';
|
|
4
4
|
import { useNavigation } from '@react-navigation/core';
|
|
5
5
|
import { Icon } from '@ant-design/react-native';
|
|
@@ -44,10 +44,7 @@ const AutomateStack = memo(() => {
|
|
|
44
44
|
title: t('smart'),
|
|
45
45
|
headerLeft: () => (
|
|
46
46
|
<TouchableOpacity style={Theme.menuIcon} onPress={toggleDrawer}>
|
|
47
|
-
<Icon
|
|
48
|
-
name={Platform.OS === 'android' ? 'menu-unfold' : 'menu'}
|
|
49
|
-
color={Colors.Black}
|
|
50
|
-
/>
|
|
47
|
+
<Icon name={'menu'} color={Colors.Black} />
|
|
51
48
|
</TouchableOpacity>
|
|
52
49
|
),
|
|
53
50
|
headerTitleAlign: 'left',
|
|
@@ -1,44 +1,18 @@
|
|
|
1
|
-
import React, { memo
|
|
1
|
+
import React, { memo } from 'react';
|
|
2
2
|
import { createStackNavigator } from '@react-navigation/stack';
|
|
3
3
|
|
|
4
4
|
import Routes from '../utils/Route';
|
|
5
5
|
import Notification from '../screens/Notification';
|
|
6
6
|
import { screenOptions } from './utils';
|
|
7
|
-
import { TouchableOpacity } from 'react-native';
|
|
8
|
-
import { Colors, Theme } from '../configs';
|
|
9
|
-
import { useNavigation } from '@react-navigation/native';
|
|
10
|
-
import { Icon } from '@ant-design/react-native';
|
|
11
|
-
import { useTranslations } from '../hooks/Common/useTranslations';
|
|
12
|
-
import { Platform } from 'react-native';
|
|
13
7
|
|
|
14
8
|
const Stack = createStackNavigator();
|
|
15
9
|
|
|
16
10
|
const NotificationStack = memo(() => {
|
|
17
|
-
const navigation = useNavigation();
|
|
18
|
-
const t = useTranslations();
|
|
19
|
-
|
|
20
|
-
const toggleDrawer = useCallback(() => {
|
|
21
|
-
navigation.toggleDrawer();
|
|
22
|
-
}, [navigation]);
|
|
23
|
-
|
|
24
11
|
return (
|
|
25
12
|
<Stack.Navigator
|
|
26
13
|
screenOptions={{
|
|
27
14
|
...screenOptions,
|
|
28
|
-
headerShown:
|
|
29
|
-
title: t('notifications'),
|
|
30
|
-
headerLeft: () => (
|
|
31
|
-
<TouchableOpacity style={Theme.menuIcon} onPress={toggleDrawer}>
|
|
32
|
-
<Icon
|
|
33
|
-
name={Platform.OS === 'android' ? 'menu-unfold' : 'menu'}
|
|
34
|
-
color={Colors.Black}
|
|
35
|
-
/>
|
|
36
|
-
</TouchableOpacity>
|
|
37
|
-
),
|
|
38
|
-
headerTitleAlign: 'left',
|
|
39
|
-
headerStyle: {
|
|
40
|
-
backgroundColor: Colors.Gray2,
|
|
41
|
-
},
|
|
15
|
+
headerShown: false,
|
|
42
16
|
}}
|
|
43
17
|
>
|
|
44
18
|
<Stack.Screen name={Routes.Notification} component={Notification} />
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { memo } from 'react';
|
|
2
2
|
import { createStackNavigator } from '@react-navigation/stack';
|
|
3
|
-
import { TouchableOpacity, StyleSheet
|
|
3
|
+
import { TouchableOpacity, StyleSheet } from 'react-native';
|
|
4
4
|
import { useNavigation, useRoute } from '@react-navigation/native';
|
|
5
5
|
import { Icon } from '@ant-design/react-native';
|
|
6
6
|
import { useTranslations } from '../hooks/Common/useTranslations';
|
|
@@ -29,13 +29,7 @@ const SharedStack = memo(() => {
|
|
|
29
29
|
onPress={() => (params?.isMainSource ? toggleDrawer() : goBack())}
|
|
30
30
|
>
|
|
31
31
|
<Icon
|
|
32
|
-
name={
|
|
33
|
-
params?.isMainSource
|
|
34
|
-
? Platform.OS === 'android'
|
|
35
|
-
? 'menu-unfold'
|
|
36
|
-
: 'menu'
|
|
37
|
-
: 'arrow-left'
|
|
38
|
-
}
|
|
32
|
+
name={params?.isMainSource ? 'menu' : 'arrow-left'}
|
|
39
33
|
color={Colors.Black}
|
|
40
34
|
/>
|
|
41
35
|
</TouchableOpacity>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { memo, useContext, useEffect } from 'react';
|
|
2
|
-
import { AppState,
|
|
2
|
+
import { AppState, View } from 'react-native';
|
|
3
3
|
import { IconOutline } from '@ant-design/icons-react-native';
|
|
4
4
|
import { createStackNavigator } from '@react-navigation/stack';
|
|
5
5
|
import { BleManager } from 'react-native-ble-plx';
|
|
@@ -172,7 +172,7 @@ export const UnitStack = memo((props) => {
|
|
|
172
172
|
headerTitleAlign: 'center',
|
|
173
173
|
headerBackImage: () => (
|
|
174
174
|
<IconOutline
|
|
175
|
-
name=
|
|
175
|
+
name="left"
|
|
176
176
|
size={27}
|
|
177
177
|
color={Colors.Black}
|
|
178
178
|
style={styles.icLeft}
|