@eohjsc/react-native-smart-city 0.4.41 → 0.4.42

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 (85) hide show
  1. package/android/build.gradle +24 -19
  2. package/package.json +12 -14
  3. package/src/commons/Action/ItemQuickAction.js +0 -1
  4. package/src/commons/ActionGroup/ColorPickerTemplate.js +4 -3
  5. package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +3 -3
  6. package/src/commons/ActionGroup/OnOffSmartLock/OnOffSmartLock.js +2 -2
  7. package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +5 -4
  8. package/src/commons/ActionGroup/OnOffTemplate/SwitchButtonTemplate.js +4 -4
  9. package/src/commons/ActionGroup/OnOffTemplate/index.js +5 -6
  10. package/src/commons/ActionGroup/OneBigButtonTemplate.js +4 -4
  11. package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +17 -6
  12. package/src/commons/ActionGroup/SliderRangeTemplate.js +3 -5
  13. package/src/commons/ActionGroup/SmartTiviActionTemplate/SmartTiviActionTemplate.js +7 -7
  14. package/src/commons/ActionGroup/StatesGridActionTemplate.js +20 -6
  15. package/src/commons/ActionGroup/ThreeButtonTemplate/__test__/ThreeButtonTemplate.test.js +6 -6
  16. package/src/commons/ActionGroup/ThreeButtonTemplate/index.js +2 -2
  17. package/src/commons/ActionGroup/TimerActionTemplate.js +2 -3
  18. package/src/commons/ActionGroup/TwoButtonTemplate/index.js +135 -133
  19. package/src/commons/ActionGroup/__test__/ColorPickerTemplate.test.js +14 -37
  20. package/src/commons/ActionGroup/__test__/NumberUpDownTemplate.test.js +31 -71
  21. package/src/commons/ActionGroup/__test__/OnOffButtonTemplate.test.js +11 -11
  22. package/src/commons/ActionGroup/__test__/OnOffSmartLock.test.js +17 -13
  23. package/src/commons/ActionGroup/__test__/OnOffTemplate.test.js +48 -44
  24. package/src/commons/ActionGroup/__test__/OneBigButtonTemplate.test.js +22 -56
  25. package/src/commons/ActionGroup/__test__/OptionsDropdownTemplate.test.js +21 -123
  26. package/src/commons/ActionGroup/__test__/SliderRangeTemplate.test.js +16 -12
  27. package/src/commons/ActionGroup/__test__/StatesGridActionTemplate.test.js +38 -73
  28. package/src/commons/ActionGroup/__test__/SwitchButtonTemplate.test.js +15 -11
  29. package/src/commons/ActionGroup/__test__/TimerActionTemplate.test.js +15 -11
  30. package/src/commons/ActionGroup/__test__/TimerActionTemplateWithutConfigValue.test.js +9 -9
  31. package/src/commons/ActionGroup/__test__/TwoButtonTemplate.test.js +31 -21
  32. package/src/commons/ActionGroup/__test__/index.test.js +21 -36
  33. package/src/commons/ActionGroup/index.js +7 -4
  34. package/src/commons/Dashboard/MyPinnedSharedUnit/__test__/MyPinnedSharedUnit.test.js +5 -0
  35. package/src/commons/Dashboard/MyUnit/index.js +2 -2
  36. package/src/commons/DateTimeRangeChange/index.js +3 -3
  37. package/src/commons/Device/HistoryChart.js +1 -1
  38. package/src/commons/Device/HorizontalBarChart.js +4 -3
  39. package/src/commons/Device/LinearChart.js +5 -3
  40. package/src/commons/FlatListDnD/__test__/index.test.js +25 -27
  41. package/src/commons/GroupCheckBox/__test__/GroupCheckBox.test.js +22 -1
  42. package/src/commons/HeaderAni/index.js +2 -12
  43. package/src/commons/MediaPlayerDetail/__test__/MediaPlayerFull.test.js +23 -1
  44. package/src/commons/OneTapTemplate/__test__/NumberUpDownActionTemplate.test.js +3 -5
  45. package/src/commons/Processing/index.js +0 -1
  46. package/src/commons/Processing/styles.js +0 -3
  47. package/src/commons/SubUnit/OneTap/ItemOneTap.js +0 -1
  48. package/src/commons/Unit/HeaderUnit/index.js +8 -15
  49. package/src/commons/UnitSummary/ConfigHistoryChart/__test__/ConfigHistoryChart.test.js +289 -0
  50. package/src/commons/UnitSummary/ConfigHistoryChart/index.js +59 -1
  51. package/src/configs/AccessibilityLabel.js +0 -1
  52. package/src/hooks/IoT/__test__/useRemoteControl.test.js +51 -52
  53. package/src/hooks/IoT/__test__/useWatchConfigs.test.js +2 -3
  54. package/src/hooks/useMqtt.js +2 -5
  55. package/src/iot/mqtt.js +0 -2
  56. package/src/navigations/UnitStack.js +2 -2
  57. package/src/screens/AddNewGateway/ConnectingDevice.js +2 -2
  58. package/src/screens/AddNewGateway/ShareWifiPassword.js +2 -2
  59. package/src/screens/AllGateway/DeviceModbusDetail/__test__/index.test.js +32 -31
  60. package/src/screens/Automate/AddNewAction/SetupConfigCondition.js +2 -19
  61. package/src/screens/Automate/AddNewAction/__test__/{SetupConfigCondition.test.js → SetupSensor.test.js} +0 -97
  62. package/src/screens/Automate/EditActionsList/__tests__/index.test.js +68 -69
  63. package/src/screens/ChangePosition/__test__/index.test.js +32 -34
  64. package/src/screens/ConfirmUnitDeletion/__test__/ConfirmUnitDeletion.test.js +11 -1
  65. package/src/screens/Device/__test__/detail.test.js +45 -40
  66. package/src/screens/Device/__test__/sensorDisplayItem.test.js +2 -14
  67. package/src/screens/Device/components/ChartWrapper.js +12 -14
  68. package/src/screens/Device/components/SensorDisplayItem.js +2 -18
  69. package/src/screens/Device/components/VisualChart.js +3 -17
  70. package/src/screens/Device/components/__test__/VisualChart.test.js +15 -12
  71. package/src/screens/Device/detail.js +15 -34
  72. package/src/screens/Device/hooks/__test__/useEvaluateValue.test.js +18 -20
  73. package/src/screens/Device/styles.js +0 -3
  74. package/src/screens/Sharing/MemberList.js +3 -16
  75. package/src/screens/Sharing/__test__/SelectPermission.test.js +137 -96
  76. package/src/screens/Template/__test__/EditTemplate.test.js +45 -48
  77. package/src/screens/Unit/SelectAddToFavorites.js +0 -1
  78. package/src/screens/Unit/__test__/SelectAddress.test.js +11 -4
  79. package/src/screens/UnitSummary/components/3PPowerConsumption/__test__/3PPowerConsumption.test.js +11 -1
  80. package/src/utils/Apis/axios.js +0 -1
  81. package/src/utils/I18n/translations/en.js +0 -2
  82. package/src/utils/I18n/translations/vi.js +0 -2
  83. package/src/utils/Monitor.js +2 -2
  84. package/src/commons/Highcharts/index.js +0 -111
  85. package/src/commons/icon/index.js +0 -57
@@ -1,12 +1,6 @@
1
1
  import React, { memo, useCallback } from 'react';
2
2
  import { Icon } from '@ant-design/react-native';
3
- import {
4
- TouchableOpacity,
5
- StyleSheet,
6
- Animated,
7
- View,
8
- Platform,
9
- } from 'react-native';
3
+ import { TouchableOpacity, StyleSheet, Animated, View } from 'react-native';
10
4
  import { useNavigation } from '@react-navigation/native';
11
5
  import { getStatusBarHeight } from 'react-native-iphone-x-helper';
12
6
 
@@ -101,11 +95,7 @@ const HeaderAni = memo(
101
95
  onPress={onPressLeft}
102
96
  accessibilityLabel={AccessibilityLabel.ICON_BACK}
103
97
  >
104
- <Icon
105
- name={Platform.OS === 'android' ? 'left-square' : 'left'}
106
- size={27}
107
- color={Colors.Gray9}
108
- />
98
+ <Icon name={'left'} size={27} color={Colors.Gray9} />
109
99
  </TouchableOpacity>
110
100
  <View styles={styles.wrapRightComponent}>{rightComponent}</View>
111
101
  </Animated.View>
@@ -1,10 +1,18 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
  import { TouchableOpacity } from 'react-native';
3
3
  import { act, create } from 'react-test-renderer';
4
4
  import { SCProvider } from '../../../context';
5
5
  import { mockSCStore } from '../../../context/mockStore';
6
6
  import MediaPlayerFull from '../MediaPlayerFull';
7
7
 
8
+ const mockSetState = jest.fn();
9
+ jest.mock('react', () => {
10
+ return {
11
+ ...jest.requireActual('react'),
12
+ useState: jest.fn((init) => [init, mockSetState]),
13
+ };
14
+ });
15
+
8
16
  const wrapComponent = (props) => (
9
17
  <SCProvider initState={mockSCStore({})}>
10
18
  <MediaPlayerFull {...props} />
@@ -14,7 +22,14 @@ const wrapComponent = (props) => (
14
22
  describe('Test MediaPlayerFull', () => {
15
23
  let tree;
16
24
 
25
+ afterEach(() => {
26
+ useState.mockClear();
27
+ });
28
+
17
29
  it('Test render', async () => {
30
+ useState.mockImplementationOnce((init) => [false, mockSetState]);
31
+ useState.mockImplementationOnce((init) => [false, mockSetState]);
32
+ useState.mockImplementationOnce((init) => [init, mockSetState]);
18
33
  await act(async () => {
19
34
  tree = await create(
20
35
  wrapComponent({
@@ -29,13 +44,18 @@ describe('Test MediaPlayerFull', () => {
29
44
  await act(async () => {
30
45
  TouchableOpacities[0].props.onPress();
31
46
  });
47
+ expect(mockSetState).toBeCalledWith(false);
32
48
  await act(async () => {
33
49
  TouchableOpacities[1].props.onPress();
34
50
  TouchableOpacities[2].props.onPress();
35
51
  });
52
+ expect(mockSetState).toBeCalledWith(true);
36
53
  });
37
54
 
38
55
  it('Test render 2', async () => {
56
+ useState.mockImplementationOnce((init) => [true, mockSetState]);
57
+ useState.mockImplementationOnce((init) => [true, mockSetState]);
58
+ useState.mockImplementationOnce((init) => [init, mockSetState]);
39
59
  await act(async () => {
40
60
  tree = await create(
41
61
  wrapComponent({
@@ -52,9 +72,11 @@ describe('Test MediaPlayerFull', () => {
52
72
  await act(async () => {
53
73
  TouchableOpacities[0].props.onPress();
54
74
  });
75
+ expect(mockSetState).toBeCalledWith(false);
55
76
  await act(async () => {
56
77
  TouchableOpacities[1].props.onPress();
57
78
  TouchableOpacities[2].props.onPress();
58
79
  });
80
+ expect(mockSetState).toBeCalledWith(true);
59
81
  });
60
82
  });
@@ -11,12 +11,11 @@ import SelectActionCard from '../../SelectActionCard';
11
11
 
12
12
  const mockOnSelectAction = jest.fn();
13
13
 
14
- const wrapComponent = (item, params = {}) => (
14
+ const wrapComponent = (item) => (
15
15
  <SCProvider initState={mockSCStore({})}>
16
16
  <NumberUpDownActionTemplate
17
17
  item={item}
18
18
  onSelectAction={mockOnSelectAction}
19
- {...params}
20
19
  />
21
20
  </SCProvider>
22
21
  );
@@ -36,9 +35,9 @@ describe('Test NumberUpDownActionTemplate', () => {
36
35
  },
37
36
  };
38
37
 
39
- const renderOptions = async (params = {}) => {
38
+ const renderOptions = async () => {
40
39
  await act(async () => {
41
- tree = await create(wrapComponent(data, params));
40
+ tree = await create(wrapComponent(data));
42
41
  });
43
42
  const instance = tree.root;
44
43
  const card = instance.findByType(SelectActionCard);
@@ -99,7 +98,6 @@ describe('Test NumberUpDownActionTemplate', () => {
99
98
  });
100
99
  expect(mockOnSelectAction).toHaveBeenCalled();
101
100
  });
102
-
103
101
  it('Test config null show valueDefault', async () => {
104
102
  data.configuration.config = null;
105
103
  const instance = await renderOptions();
@@ -149,7 +149,6 @@ const Processing = ({
149
149
  onLeftClick={goBack}
150
150
  rightTitle={t('ok')}
151
151
  onRightClick={handleOk}
152
- wrapStyle={styles.wrapViewButton}
153
152
  />
154
153
  </View>
155
154
  </ModalCustom>
@@ -51,7 +51,4 @@ export default StyleSheet.create({
51
51
  txtCenter: {
52
52
  textAlign: 'center',
53
53
  },
54
- wrapViewButton: {
55
- position: 'relative',
56
- },
57
54
  });
@@ -60,7 +60,6 @@ const ItemOneTap = memo(({ automate = {}, wrapSyles, onPressItem }) => {
60
60
  const activateAt = activate_at
61
61
  ? timeDifference(new Date(), moment(activate_at), true)
62
62
  : null;
63
-
64
63
  return (
65
64
  <TouchableWithoutFeedback
66
65
  onPress={onPressItem || goToDetail}
@@ -4,11 +4,9 @@ import { Icon } from '@ant-design/react-native';
4
4
  import { useNavigation } from '@react-navigation/native';
5
5
  import { getStatusBarHeight } from 'react-native-iphone-x-helper';
6
6
 
7
- import { Colors, Device, Images } from '../../../configs';
7
+ import { Colors, Device } from '../../../configs';
8
8
  import Text from '../../Text';
9
9
  import { AccessibilityLabel } from '../../../configs/Constants';
10
- import { Image } from 'react-native';
11
- import { Platform } from 'react-native';
12
10
 
13
11
  const HeaderUnit = memo(
14
12
  ({
@@ -49,7 +47,11 @@ const HeaderUnit = memo(
49
47
  style={styles.btnLeft}
50
48
  onPress={onPressBack}
51
49
  >
52
- <Image source={Images.arrowLeft} style={styles.iconBack} />
50
+ <Icon
51
+ name={'left'}
52
+ size={27}
53
+ color={transparent ? Colors.White : Colors.Black}
54
+ />
53
55
  </TouchableOpacity>
54
56
  <View style={[styles.boxTitle, styleBoxTitle]}>
55
57
  {title && (
@@ -68,7 +70,7 @@ const HeaderUnit = memo(
68
70
  onPress={onPressAdd}
69
71
  >
70
72
  <Icon
71
- name={Platform.OS === 'android' ? 'plus-square' : 'plus'}
73
+ name={'plus'}
72
74
  size={27}
73
75
  color={transparent ? Colors.White : Colors.Black}
74
76
  />
@@ -81,10 +83,9 @@ const HeaderUnit = memo(
81
83
  accessibilityLabel={idButtonMore}
82
84
  >
83
85
  <Icon
84
- name={'ellipsis'}
86
+ name={'more'}
85
87
  size={27}
86
88
  color={transparent ? Colors.White : Colors.Black}
87
- style={styles.iconMore}
88
89
  />
89
90
  </TouchableOpacity>
90
91
  </View>
@@ -145,12 +146,4 @@ const styles = StyleSheet.create({
145
146
  borderBottomWidth: 1,
146
147
  borderBottomColor: Colors.Gray4,
147
148
  },
148
- iconMore: {
149
- transform: [{ rotate: '90deg' }],
150
- },
151
- iconBack: {
152
- tintColor: Colors.White,
153
- width: 16,
154
- height: 20,
155
- },
156
149
  });
@@ -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 HighchartsReactNative from '@eohjsc/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(HighchartsReactNative);
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(HighchartsReactNative);
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;
@@ -647,7 +647,6 @@ export default {
647
647
  TOUCHABLE_ACTION_ADD_ITEM_FAVORITE: 'TOUCHABLE_ACTION_ADD_ITEM_FAVORITE',
648
648
  TOUCHABLE_ACTION_ADD_ITEM_AUTOMATE_FAVORITE:
649
649
  'TOUCHABLE_ACTION_ADD_ITEM_AUTOMATE_FAVORITE',
650
- BUTTON_SELECT_FAVORITES: 'BUTTON_SELECT_FAVORITES',
651
650
 
652
651
  // Smart Account
653
652
  LOGIN_SMART_ACCOUNT: 'LOGIN_SMART_ACCOUNT',