@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.
- package/android/build.gradle +24 -19
- package/package.json +12 -14
- package/src/commons/Action/ItemQuickAction.js +0 -1
- package/src/commons/ActionGroup/ColorPickerTemplate.js +4 -3
- package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +3 -3
- package/src/commons/ActionGroup/OnOffSmartLock/OnOffSmartLock.js +2 -2
- package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +5 -4
- package/src/commons/ActionGroup/OnOffTemplate/SwitchButtonTemplate.js +4 -4
- package/src/commons/ActionGroup/OnOffTemplate/index.js +5 -6
- package/src/commons/ActionGroup/OneBigButtonTemplate.js +4 -4
- package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +17 -6
- package/src/commons/ActionGroup/SliderRangeTemplate.js +3 -5
- package/src/commons/ActionGroup/SmartTiviActionTemplate/SmartTiviActionTemplate.js +7 -7
- package/src/commons/ActionGroup/StatesGridActionTemplate.js +20 -6
- package/src/commons/ActionGroup/ThreeButtonTemplate/__test__/ThreeButtonTemplate.test.js +6 -6
- package/src/commons/ActionGroup/ThreeButtonTemplate/index.js +2 -2
- package/src/commons/ActionGroup/TimerActionTemplate.js +2 -3
- package/src/commons/ActionGroup/TwoButtonTemplate/index.js +135 -133
- package/src/commons/ActionGroup/__test__/ColorPickerTemplate.test.js +14 -37
- package/src/commons/ActionGroup/__test__/NumberUpDownTemplate.test.js +31 -71
- package/src/commons/ActionGroup/__test__/OnOffButtonTemplate.test.js +11 -11
- package/src/commons/ActionGroup/__test__/OnOffSmartLock.test.js +17 -13
- package/src/commons/ActionGroup/__test__/OnOffTemplate.test.js +48 -44
- package/src/commons/ActionGroup/__test__/OneBigButtonTemplate.test.js +22 -56
- package/src/commons/ActionGroup/__test__/OptionsDropdownTemplate.test.js +21 -123
- package/src/commons/ActionGroup/__test__/SliderRangeTemplate.test.js +16 -12
- package/src/commons/ActionGroup/__test__/StatesGridActionTemplate.test.js +38 -73
- package/src/commons/ActionGroup/__test__/SwitchButtonTemplate.test.js +15 -11
- package/src/commons/ActionGroup/__test__/TimerActionTemplate.test.js +15 -11
- package/src/commons/ActionGroup/__test__/TimerActionTemplateWithutConfigValue.test.js +9 -9
- package/src/commons/ActionGroup/__test__/TwoButtonTemplate.test.js +31 -21
- package/src/commons/ActionGroup/__test__/index.test.js +21 -36
- package/src/commons/ActionGroup/index.js +7 -4
- package/src/commons/Dashboard/MyPinnedSharedUnit/__test__/MyPinnedSharedUnit.test.js +5 -0
- package/src/commons/Dashboard/MyUnit/index.js +2 -2
- package/src/commons/DateTimeRangeChange/index.js +3 -3
- package/src/commons/Device/HistoryChart.js +1 -1
- package/src/commons/Device/HorizontalBarChart.js +4 -3
- package/src/commons/Device/LinearChart.js +5 -3
- 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/OneTapTemplate/__test__/NumberUpDownActionTemplate.test.js +3 -5
- package/src/commons/Processing/index.js +0 -1
- package/src/commons/Processing/styles.js +0 -3
- package/src/commons/SubUnit/OneTap/ItemOneTap.js +0 -1
- package/src/commons/Unit/HeaderUnit/index.js +8 -15
- package/src/commons/UnitSummary/ConfigHistoryChart/__test__/ConfigHistoryChart.test.js +289 -0
- package/src/commons/UnitSummary/ConfigHistoryChart/index.js +59 -1
- package/src/configs/AccessibilityLabel.js +0 -1
- package/src/hooks/IoT/__test__/useRemoteControl.test.js +51 -52
- package/src/hooks/IoT/__test__/useWatchConfigs.test.js +2 -3
- package/src/hooks/useMqtt.js +2 -5
- package/src/iot/mqtt.js +0 -2
- package/src/navigations/UnitStack.js +2 -2
- package/src/screens/AddNewGateway/ConnectingDevice.js +2 -2
- package/src/screens/AddNewGateway/ShareWifiPassword.js +2 -2
- package/src/screens/AllGateway/DeviceModbusDetail/__test__/index.test.js +32 -31
- package/src/screens/Automate/AddNewAction/SetupConfigCondition.js +2 -19
- package/src/screens/Automate/AddNewAction/__test__/{SetupConfigCondition.test.js → SetupSensor.test.js} +0 -97
- package/src/screens/Automate/EditActionsList/__tests__/index.test.js +68 -69
- 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 +45 -40
- package/src/screens/Device/__test__/sensorDisplayItem.test.js +2 -14
- package/src/screens/Device/components/ChartWrapper.js +12 -14
- package/src/screens/Device/components/SensorDisplayItem.js +2 -18
- package/src/screens/Device/components/VisualChart.js +3 -17
- package/src/screens/Device/components/__test__/VisualChart.test.js +15 -12
- package/src/screens/Device/detail.js +15 -34
- package/src/screens/Device/hooks/__test__/useEvaluateValue.test.js +18 -20
- package/src/screens/Device/styles.js +0 -3
- package/src/screens/Sharing/MemberList.js +3 -16
- package/src/screens/Sharing/__test__/SelectPermission.test.js +137 -96
- package/src/screens/Template/__test__/EditTemplate.test.js +45 -48
- package/src/screens/Unit/SelectAddToFavorites.js +0 -1
- package/src/screens/Unit/__test__/SelectAddress.test.js +11 -4
- package/src/screens/UnitSummary/components/3PPowerConsumption/__test__/3PPowerConsumption.test.js +11 -1
- package/src/utils/Apis/axios.js +0 -1
- package/src/utils/I18n/translations/en.js +0 -2
- package/src/utils/I18n/translations/vi.js +0 -2
- package/src/utils/Monitor.js +2 -2
- package/src/commons/Highcharts/index.js +0 -111
- 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
|
|
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 (
|
|
38
|
+
const renderOptions = async () => {
|
|
40
39
|
await act(async () => {
|
|
41
|
-
tree = await create(wrapComponent(data
|
|
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();
|
|
@@ -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
|
|
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
|
-
<
|
|
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={
|
|
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={'
|
|
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',
|