@eohjsc/react-native-smart-city 0.7.41 → 0.7.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/package.json +1 -1
- package/src/commons/Dashboard/MyDashboardDevice/index.js +14 -12
- package/src/commons/Dashboard/MyUnit/index.js +4 -3
- package/src/commons/DateTimeRangeChange/index.js +5 -5
- package/src/commons/Device/HorizontalBarChart.js +11 -24
- package/src/commons/Device/PowerConsumptionChart.js +195 -103
- package/src/commons/Form/CurrencyInput.js +9 -18
- package/src/commons/SubUnit/Favorites/index.js +35 -10
- package/src/commons/SubUnit/ShortDetail.js +17 -4
- package/src/commons/SubUnit/__test__/Favorites.test.js +90 -0
- package/src/commons/SubUnit/__test__/ShortDetail.test.js +45 -2
- package/src/hooks/IoT/__test__/useValueEvaluation.test.js +12 -12
- package/src/iot/UpdateStates.js +37 -16
- package/src/iot/mqtt.js +23 -0
- package/src/screens/Device/__test__/DeviceDetail-3rdparty.test.js +16 -5
- package/src/screens/Device/__test__/DeviceDetail-arduino.test.js +10 -0
- package/src/screens/Device/__test__/DeviceDetail-modbus.test.js +37 -8
- package/src/screens/Device/__test__/DeviceDetail-zigbee.test.js +16 -5
- package/src/screens/Device/__test__/DeviceDetail.test.js +17 -6
- package/src/screens/Device/__test__/sensorDisplayItem.test.js +47 -11
- package/src/screens/Device/components/SensorDisplayItem.js +23 -5
- package/src/screens/Device/styles.js +4 -0
- package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +8 -49
- package/src/screens/UnitSummary/components/PowerConsumption/__test__/PowerConsumption.test.js +121 -6
- package/src/screens/UnitSummary/components/PowerConsumption/index.js +6 -47
- package/src/utils/I18n/translations/en.js +1 -0
- package/src/utils/I18n/translations/vi.js +1 -0
- package/src/utils/chartHelper/index.js +53 -0
- package/src/utils/chartHelper/getMaxValueIndex.js +0 -11
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import MockAdapter from 'axios-mock-adapter';
|
|
2
|
-
import React from 'react';
|
|
3
2
|
import renderer, { act } from 'react-test-renderer';
|
|
4
3
|
|
|
5
|
-
import { SCProvider } from '../../../context';
|
|
6
|
-
import { mockSCStore } from '../../../context/mockStore';
|
|
7
|
-
import { SensorDisplayItem } from '../components/SensorDisplayItem';
|
|
8
4
|
import ActionGroup from '../../../commons/ActionGroup';
|
|
9
|
-
import
|
|
5
|
+
import DeviceAlertStatus from '../../../commons/Device/DeviceAlertStatus';
|
|
10
6
|
import FlatListItems from '../../../commons/Device/FlatListItems';
|
|
11
|
-
import VisualChart from '../components/VisualChart';
|
|
12
7
|
import FooterInfo from '../../../commons/Device/FooterInfo';
|
|
13
|
-
import
|
|
8
|
+
import LabelValue from '../../../commons/Device/LabelValue';
|
|
9
|
+
import PowerConsumptionChart from '../../../commons/Device/PowerConsumptionChart';
|
|
14
10
|
import ProgressBar from '../../../commons/Device/ProgressBar';
|
|
15
|
-
import Compass from '../../../commons/Device/WindDirection/Compass';
|
|
16
|
-
import DeviceAlertStatus from '../../../commons/Device/DeviceAlertStatus';
|
|
17
11
|
import CurrentRainSensor from '../../../commons/Device/RainningSensor/CurrentRainSensor';
|
|
18
|
-
import
|
|
12
|
+
import Compass from '../../../commons/Device/WindDirection/Compass';
|
|
13
|
+
import Anemometer from '../../../commons/Device/WindSpeed/Anemometer';
|
|
14
|
+
import MediaPlayerDetail from '../../../commons/MediaPlayerDetail';
|
|
19
15
|
import Text from '../../../commons/Text';
|
|
20
|
-
import
|
|
16
|
+
import { SCProvider } from '../../../context';
|
|
17
|
+
import { mockSCStore } from '../../../context/mockStore';
|
|
21
18
|
import api from '../../../utils/Apis/axios';
|
|
19
|
+
import SmartIr from '../../SmartIr';
|
|
20
|
+
import { SensorDisplayItem } from '../components/SensorDisplayItem';
|
|
21
|
+
import VisualChart from '../components/VisualChart';
|
|
22
22
|
|
|
23
23
|
const mockIncrementReviewTrigger = jest.fn();
|
|
24
24
|
const mockAskReview = jest.fn();
|
|
@@ -484,4 +484,40 @@ describe('Test SensorDisplayItem', () => {
|
|
|
484
484
|
const labels = instance.findAllByType(Text);
|
|
485
485
|
expect(labels[0].props.children).toEqual('Label');
|
|
486
486
|
});
|
|
487
|
+
|
|
488
|
+
it('test render power_consume', async () => {
|
|
489
|
+
const item = {
|
|
490
|
+
id: 10452,
|
|
491
|
+
order: 0,
|
|
492
|
+
template: 'summary',
|
|
493
|
+
configuration: {
|
|
494
|
+
template: 'power_consume',
|
|
495
|
+
configs: [
|
|
496
|
+
{
|
|
497
|
+
id: 78,
|
|
498
|
+
color: 'green',
|
|
499
|
+
},
|
|
500
|
+
],
|
|
501
|
+
aggregation_period: 'month',
|
|
502
|
+
},
|
|
503
|
+
label: 'Power Consume',
|
|
504
|
+
is_configuration_ready: true,
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
const sensor = {
|
|
508
|
+
name: 'Sensor name',
|
|
509
|
+
is_managed_by_backend: false,
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
await act(async () => {
|
|
513
|
+
tree = await renderer.create(wrapComponent({ item, sensor }));
|
|
514
|
+
});
|
|
515
|
+
const instance = tree.root;
|
|
516
|
+
const powerConsumptionChart = instance.findAllByType(PowerConsumptionChart);
|
|
517
|
+
expect(powerConsumptionChart).toHaveLength(1);
|
|
518
|
+
expect(powerConsumptionChart[0].props.label).toEqual('Power Consume');
|
|
519
|
+
expect(powerConsumptionChart[0].props.powerConfigId).toEqual(78);
|
|
520
|
+
expect(powerConsumptionChart[0].props.defaultPeriod).toEqual('month');
|
|
521
|
+
expect(powerConsumptionChart[0].props.color).toEqual('green');
|
|
522
|
+
});
|
|
487
523
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useCallback, useState } from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
3
|
import ActionGroup from '../../../commons/ActionGroup';
|
|
4
4
|
import DeviceAlertStatus from '../../../commons/Device/DeviceAlertStatus';
|
|
@@ -6,16 +6,17 @@ import EmergencyButton from '../../../commons/Device/Emergency/EmergencyButton';
|
|
|
6
6
|
import EmergencyDetail from '../../../commons/Device/Emergency/EmergencyDetail';
|
|
7
7
|
import FlatListItems from '../../../commons/Device/FlatListItems';
|
|
8
8
|
import FooterInfo from '../../../commons/Device/FooterInfo';
|
|
9
|
+
import LabelValue from '../../../commons/Device/LabelValue';
|
|
9
10
|
import PMSensorIndicator from '../../../commons/Device/PMSensor/PMSensorIndicator';
|
|
11
|
+
import PowerConsumptionChart from '../../../commons/Device/PowerConsumptionChart';
|
|
10
12
|
import ProgressBar from '../../../commons/Device/ProgressBar';
|
|
11
|
-
import LabelValue from '../../../commons/Device/LabelValue';
|
|
12
13
|
import CurrentRainSensor from '../../../commons/Device/RainningSensor/CurrentRainSensor';
|
|
13
14
|
import ListQualityIndicator from '../../../commons/Device/WaterQualitySensor/ListQualityIndicator';
|
|
14
15
|
import Compass from '../../../commons/Device/WindDirection/Compass';
|
|
15
16
|
import Anemometer from '../../../commons/Device/WindSpeed/Anemometer';
|
|
16
17
|
import MediaPlayerDetail from '../../../commons/MediaPlayerDetail';
|
|
17
|
-
import IFrame from '../../../commons/Widgets/IFrame/IFrame';
|
|
18
18
|
import Text from '../../../commons/Text';
|
|
19
|
+
import IFrame from '../../../commons/Widgets/IFrame/IFrame';
|
|
19
20
|
import { Device } from '../../../configs';
|
|
20
21
|
import { AccessibilityLabel, WIDGET_TYPE } from '../../../configs/Constants';
|
|
21
22
|
import { useSCContextSelector } from '../../../context';
|
|
@@ -47,14 +48,12 @@ export const SensorDisplayItem = ({
|
|
|
47
48
|
const { configuration = {}, id: idTemplate, label } = item;
|
|
48
49
|
const { type, template, uri, id, name, title, value_evaluation } =
|
|
49
50
|
configuration;
|
|
50
|
-
|
|
51
51
|
const sendRemoteCommand = useRemoteControl(bluetoothDevice);
|
|
52
52
|
const [processing, setProcessing] = useState(false);
|
|
53
53
|
// eslint-disable-next-line no-unused-vars
|
|
54
54
|
const [configValues, setConfigValues] = useConfigGlobalState('configValues');
|
|
55
55
|
|
|
56
56
|
const evaluateValue = useEvaluateValue();
|
|
57
|
-
|
|
58
57
|
const checkConfigValue = (configValue) => {
|
|
59
58
|
if (configValue === null || configValue === undefined) {
|
|
60
59
|
return false;
|
|
@@ -322,6 +321,25 @@ export const SensorDisplayItem = ({
|
|
|
322
321
|
return <FooterInfo data={configuration} />;
|
|
323
322
|
case 'smart_ir':
|
|
324
323
|
return <SmartIr item={item} />;
|
|
324
|
+
case 'summary':
|
|
325
|
+
switch (item?.configuration?.template) {
|
|
326
|
+
case 'power_consume':
|
|
327
|
+
return (
|
|
328
|
+
<View>
|
|
329
|
+
{configuration?.configs[0]?.id && (
|
|
330
|
+
<PowerConsumptionChart
|
|
331
|
+
label={label}
|
|
332
|
+
powerConfigId={configuration?.configs[0]?.id}
|
|
333
|
+
defaultPeriod={configuration?.aggregation_period}
|
|
334
|
+
color={configuration?.configs[0]?.color}
|
|
335
|
+
style={styles.powerConsumption}
|
|
336
|
+
/>
|
|
337
|
+
)}
|
|
338
|
+
</View>
|
|
339
|
+
);
|
|
340
|
+
default:
|
|
341
|
+
return null;
|
|
342
|
+
}
|
|
325
343
|
default:
|
|
326
344
|
break;
|
|
327
345
|
}
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import Text from '../../../../commons/Text';
|
|
4
|
-
import { API, Colors } from '../../../../configs';
|
|
5
|
-
import moment from 'moment';
|
|
1
|
+
import { memo, useMemo } from 'react';
|
|
2
|
+
import { StyleSheet, View } from 'react-native';
|
|
6
3
|
import { Section, Today } from '../../../../commons';
|
|
7
|
-
import ListQualityIndicator from '../../../../commons/Device/WaterQualitySensor/ListQualityIndicator';
|
|
8
4
|
import PMSensorIndicator from '../../../../commons/Device/PMSensor/PMSensorIndicator';
|
|
9
|
-
import VisualChart from '../../../Device/components/VisualChart';
|
|
10
|
-
import { useTranslations } from '../../../../hooks/Common/useTranslations';
|
|
11
5
|
import PowerConsumptionChart from '../../../../commons/Device/PowerConsumptionChart';
|
|
12
|
-
import
|
|
6
|
+
import ListQualityIndicator from '../../../../commons/Device/WaterQualitySensor/ListQualityIndicator';
|
|
7
|
+
import Text from '../../../../commons/Text';
|
|
8
|
+
import { Colors } from '../../../../configs';
|
|
13
9
|
import { AccessibilityLabel } from '../../../../configs/Constants';
|
|
10
|
+
import { useTranslations } from '../../../../hooks/Common/useTranslations';
|
|
14
11
|
import { useWatchConfigs } from '../../../../hooks/IoT';
|
|
12
|
+
import VisualChart from '../../../Device/components/VisualChart';
|
|
15
13
|
|
|
16
14
|
const ThreePhasePowerConsumption = memo(({ summaryDetail }) => {
|
|
17
15
|
const t = useTranslations();
|
|
@@ -114,36 +112,6 @@ const ThreePhasePowerConsumption = memo(({ summaryDetail }) => {
|
|
|
114
112
|
return !!listConfigs;
|
|
115
113
|
}, [listConfigs]);
|
|
116
114
|
|
|
117
|
-
const [groupBy, setGroupBy] = useState('date');
|
|
118
|
-
const [getData, setData] = useState({});
|
|
119
|
-
const [chartConfig, setChartConfig] = useState({
|
|
120
|
-
unit: 'kWh',
|
|
121
|
-
price: '',
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
const fetchData = useCallback(
|
|
125
|
-
async (startDate, endDate) => {
|
|
126
|
-
let params = new URLSearchParams();
|
|
127
|
-
params.append('config', total_power);
|
|
128
|
-
params.append('group_by', groupBy);
|
|
129
|
-
if (groupBy === 'date') {
|
|
130
|
-
params.append('date_from', moment(startDate).format('YYYY-MM-DD'));
|
|
131
|
-
params.append('date_to', moment(endDate).format('YYYY-MM-DD'));
|
|
132
|
-
}
|
|
133
|
-
const { success, data } = await axiosGet(
|
|
134
|
-
API.VALUE_CONSUME.DISPLAY_HISTORY(),
|
|
135
|
-
{
|
|
136
|
-
params,
|
|
137
|
-
},
|
|
138
|
-
true
|
|
139
|
-
);
|
|
140
|
-
if (success) {
|
|
141
|
-
setData(data);
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
[groupBy, total_power]
|
|
145
|
-
);
|
|
146
|
-
|
|
147
115
|
const dataTotal = useMemo(() => {
|
|
148
116
|
return total_power
|
|
149
117
|
? [
|
|
@@ -186,16 +154,7 @@ const ThreePhasePowerConsumption = memo(({ summaryDetail }) => {
|
|
|
186
154
|
</Text>
|
|
187
155
|
|
|
188
156
|
<PMSensorIndicator data={dataTotal} style={styles.styleTotalPower} />
|
|
189
|
-
{total_power &&
|
|
190
|
-
<PowerConsumptionChart
|
|
191
|
-
onChangeDate={fetchData}
|
|
192
|
-
datas={getData}
|
|
193
|
-
chartConfig={chartConfig}
|
|
194
|
-
setChartConfig={setChartConfig}
|
|
195
|
-
groupBy={groupBy}
|
|
196
|
-
setGroupBy={setGroupBy}
|
|
197
|
-
/>
|
|
198
|
-
)}
|
|
157
|
+
{total_power && <PowerConsumptionChart powerConfigId={total_power} />}
|
|
199
158
|
</Section>
|
|
200
159
|
</>
|
|
201
160
|
);
|
package/src/screens/UnitSummary/components/PowerConsumption/__test__/PowerConsumption.test.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import renderer, { act, create } from 'react-test-renderer';
|
|
3
1
|
import MockAdapter from 'axios-mock-adapter';
|
|
2
|
+
import renderer, { act, create } from 'react-test-renderer';
|
|
4
3
|
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
4
|
+
import moment from 'moment';
|
|
5
|
+
import { Today } from '../../../../../commons';
|
|
6
|
+
import DateTimeRangeChange from '../../../../../commons/DateTimeRangeChange';
|
|
7
|
+
import PowerConsumptionChart from '../../../../../commons/Device/PowerConsumptionChart';
|
|
7
8
|
import ListQualityIndicator from '../../../../../commons/Device/WaterQualitySensor/ListQualityIndicator';
|
|
8
|
-
import
|
|
9
|
+
import { API, Colors } from '../../../../../configs';
|
|
10
|
+
import { AccessibilityLabel } from '../../../../../configs/Constants';
|
|
9
11
|
import { SCProvider } from '../../../../../context';
|
|
10
12
|
import { mockSCStore } from '../../../../../context/mockStore';
|
|
11
13
|
import api from '../../../../../utils/Apis/axios';
|
|
12
|
-
import
|
|
14
|
+
import PowerConsumption from '../index';
|
|
13
15
|
|
|
14
16
|
const mock = new MockAdapter(api.axiosInstance);
|
|
15
17
|
|
|
@@ -193,4 +195,117 @@ describe('Test PowerConsumption', () => {
|
|
|
193
195
|
const listQualityIndicator = instance.findByType(ListQualityIndicator);
|
|
194
196
|
expect(listQualityIndicator.props.data).toEqual([]);
|
|
195
197
|
});
|
|
198
|
+
|
|
199
|
+
it('render PowerConsumption with total sum is 0', async () => {
|
|
200
|
+
const summaryDetail = {
|
|
201
|
+
listConfigs: {
|
|
202
|
+
total_power: 207,
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
const data = [
|
|
207
|
+
{
|
|
208
|
+
config: 207,
|
|
209
|
+
data: [
|
|
210
|
+
{ x: 'Fri-14.06', y: 0 },
|
|
211
|
+
{ x: 'Sat-15.06', y: 0 },
|
|
212
|
+
],
|
|
213
|
+
},
|
|
214
|
+
];
|
|
215
|
+
mock.onGet(API.VALUE_CONSUME.DISPLAY_HISTORY()).reply(200, data);
|
|
216
|
+
await act(async () => {
|
|
217
|
+
tree = await create(wrapComponent(summaryDetail));
|
|
218
|
+
});
|
|
219
|
+
const instance = tree.root;
|
|
220
|
+
|
|
221
|
+
const input_calculate_cost = instance.find(
|
|
222
|
+
(el) =>
|
|
223
|
+
el.props.accessibilityLabel === AccessibilityLabel.INPUT_CALCULATE_COST
|
|
224
|
+
);
|
|
225
|
+
await act(async () => {
|
|
226
|
+
input_calculate_cost.props.onChangeText('1000');
|
|
227
|
+
});
|
|
228
|
+
const button_calculate_cost = instance.find(
|
|
229
|
+
(el) =>
|
|
230
|
+
el.props.accessibilityLabel === AccessibilityLabel.BUTTON_CALCULATE_COST
|
|
231
|
+
);
|
|
232
|
+
await act(async () => {
|
|
233
|
+
button_calculate_cost.props.onPress();
|
|
234
|
+
});
|
|
235
|
+
const totalPrice = instance.find(
|
|
236
|
+
(el) => el.props.accessibilityLabel === AccessibilityLabel.TOTAL_PRICE
|
|
237
|
+
);
|
|
238
|
+
expect(totalPrice.props.children).toEqual('0 đ');
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it('render PowerConsumption with empty data array', async () => {
|
|
242
|
+
const summaryDetail = {
|
|
243
|
+
listConfigs: {
|
|
244
|
+
total_power: 207,
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
mock.onGet(API.VALUE_CONSUME.DISPLAY_HISTORY()).reply(200, []);
|
|
249
|
+
await act(async () => {
|
|
250
|
+
tree = await create(wrapComponent(summaryDetail));
|
|
251
|
+
});
|
|
252
|
+
const instance = tree.root;
|
|
253
|
+
|
|
254
|
+
const input_calculate_cost = instance.find(
|
|
255
|
+
(el) =>
|
|
256
|
+
el.props.accessibilityLabel === AccessibilityLabel.INPUT_CALCULATE_COST
|
|
257
|
+
);
|
|
258
|
+
await act(async () => {
|
|
259
|
+
input_calculate_cost.props.onChangeText('1000');
|
|
260
|
+
});
|
|
261
|
+
const button_calculate_cost = instance.find(
|
|
262
|
+
(el) =>
|
|
263
|
+
el.props.accessibilityLabel === AccessibilityLabel.BUTTON_CALCULATE_COST
|
|
264
|
+
);
|
|
265
|
+
await act(async () => {
|
|
266
|
+
button_calculate_cost.props.onPress();
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
const totalPrice = instance.find(
|
|
270
|
+
(el) => el.props.accessibilityLabel === AccessibilityLabel.TOTAL_PRICE
|
|
271
|
+
);
|
|
272
|
+
expect(totalPrice.props.children).toEqual('0 đ');
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it('cover selectStart and selectEnd in PowerConsumptionChart', async () => {
|
|
276
|
+
const summaryDetail = {
|
|
277
|
+
listConfigs: {
|
|
278
|
+
total_power: 207,
|
|
279
|
+
},
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
mock.onGet(API.VALUE_CONSUME.DISPLAY_HISTORY()).reply(200, []);
|
|
283
|
+
await act(async () => {
|
|
284
|
+
tree = await create(wrapComponent(summaryDetail));
|
|
285
|
+
});
|
|
286
|
+
const instance = tree.root;
|
|
287
|
+
|
|
288
|
+
const powerConsumptionChart = instance.findByType(PowerConsumptionChart);
|
|
289
|
+
const dateTimeRangeChange =
|
|
290
|
+
powerConsumptionChart.findByType(DateTimeRangeChange);
|
|
291
|
+
expect(dateTimeRangeChange).toBeDefined();
|
|
292
|
+
|
|
293
|
+
const newStartDate = moment().subtract(10, 'days');
|
|
294
|
+
const newEndDate = moment().subtract(1, 'days');
|
|
295
|
+
|
|
296
|
+
await act(async () => {
|
|
297
|
+
dateTimeRangeChange.props.selectStart(newStartDate);
|
|
298
|
+
});
|
|
299
|
+
await act(async () => {
|
|
300
|
+
dateTimeRangeChange.props.selectEnd(newEndDate);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
// Check if the component still renders correctly after date changes
|
|
304
|
+
expect(
|
|
305
|
+
powerConsumptionChart.findByType(DateTimeRangeChange).props.startTime
|
|
306
|
+
).toEqual(newStartDate);
|
|
307
|
+
expect(
|
|
308
|
+
powerConsumptionChart.findByType(DateTimeRangeChange).props.endTime
|
|
309
|
+
).toEqual(newEndDate);
|
|
310
|
+
});
|
|
196
311
|
});
|
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { memo, useCallback, useMemo } from 'react';
|
|
2
2
|
import { StyleSheet } from 'react-native';
|
|
3
3
|
import { useTranslations } from '../../../../hooks/Common/useTranslations';
|
|
4
|
-
import moment from 'moment';
|
|
5
4
|
|
|
6
|
-
import { API, Colors } from '../../../../configs';
|
|
7
|
-
import Text from '../../../../commons/Text';
|
|
8
5
|
import { Section, Today } from '../../../../commons';
|
|
9
|
-
import ListQualityIndicator from '../../../../commons/Device/WaterQualitySensor/ListQualityIndicator';
|
|
10
6
|
import PMSensorIndicator from '../../../../commons/Device/PMSensor/PMSensorIndicator';
|
|
11
7
|
import PowerConsumptionChart from '../../../../commons/Device/PowerConsumptionChart';
|
|
8
|
+
import ListQualityIndicator from '../../../../commons/Device/WaterQualitySensor/ListQualityIndicator';
|
|
9
|
+
import Text from '../../../../commons/Text';
|
|
10
|
+
import { Colors } from '../../../../configs';
|
|
12
11
|
import { AccessibilityLabel } from '../../../../configs/Constants';
|
|
13
|
-
import { axiosGet } from '../../../../utils/Apis/axios';
|
|
14
|
-
import VisualChart from '../../../Device/components/VisualChart';
|
|
15
12
|
import { useWatchConfigs } from '../../../../hooks/IoT';
|
|
13
|
+
import VisualChart from '../../../Device/components/VisualChart';
|
|
16
14
|
|
|
17
15
|
const PowerConsumption = memo(({ summaryDetail }) => {
|
|
18
16
|
const t = useTranslations();
|
|
@@ -21,16 +19,9 @@ const PowerConsumption = memo(({ summaryDetail }) => {
|
|
|
21
19
|
listConfigs || {};
|
|
22
20
|
useWatchConfigs([volt, current, active_power, power_factor, total_power]);
|
|
23
21
|
|
|
24
|
-
const [groupBy, setGroupBy] = useState('date');
|
|
25
|
-
const [getData, setData] = useState([]);
|
|
26
|
-
const [chartConfig, setChartConfig] = useState({
|
|
27
|
-
unit: 'kWh',
|
|
28
|
-
price: '',
|
|
29
|
-
});
|
|
30
22
|
const showBoxHistory = useMemo(() => {
|
|
31
23
|
return !!listConfigs;
|
|
32
24
|
}, [listConfigs]);
|
|
33
|
-
|
|
34
25
|
const createDataItem = useCallback(
|
|
35
26
|
(id, color, title, measure) => ({
|
|
36
27
|
id,
|
|
@@ -80,29 +71,6 @@ const PowerConsumption = memo(({ summaryDetail }) => {
|
|
|
80
71
|
: [];
|
|
81
72
|
}, [createDataItem, total_power]);
|
|
82
73
|
|
|
83
|
-
const fetchData = useCallback(
|
|
84
|
-
async (startDate, endDate) => {
|
|
85
|
-
let params = new URLSearchParams();
|
|
86
|
-
params.append('config', total_power);
|
|
87
|
-
params.append('group_by', groupBy);
|
|
88
|
-
if (groupBy === 'date') {
|
|
89
|
-
params.append('date_from', moment(startDate).format('YYYY-MM-DD'));
|
|
90
|
-
params.append('date_to', moment(endDate).format('YYYY-MM-DD'));
|
|
91
|
-
}
|
|
92
|
-
const { success, data } = await axiosGet(
|
|
93
|
-
API.VALUE_CONSUME.DISPLAY_HISTORY(),
|
|
94
|
-
{
|
|
95
|
-
params,
|
|
96
|
-
},
|
|
97
|
-
true
|
|
98
|
-
);
|
|
99
|
-
if (success) {
|
|
100
|
-
setData(data);
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
[groupBy, total_power]
|
|
104
|
-
);
|
|
105
|
-
|
|
106
74
|
return (
|
|
107
75
|
<>
|
|
108
76
|
<Section type={'border'}>
|
|
@@ -123,16 +91,7 @@ const PowerConsumption = memo(({ summaryDetail }) => {
|
|
|
123
91
|
</Text>
|
|
124
92
|
|
|
125
93
|
<PMSensorIndicator data={dataTotal} style={styles.styleTotalPower} />
|
|
126
|
-
{total_power &&
|
|
127
|
-
<PowerConsumptionChart
|
|
128
|
-
onChangeDate={fetchData}
|
|
129
|
-
datas={getData}
|
|
130
|
-
chartConfig={chartConfig}
|
|
131
|
-
setChartConfig={setChartConfig}
|
|
132
|
-
groupBy={groupBy}
|
|
133
|
-
setGroupBy={setGroupBy}
|
|
134
|
-
/>
|
|
135
|
-
)}
|
|
94
|
+
{total_power && <PowerConsumptionChart powerConfigId={total_power} />}
|
|
136
95
|
</Section>
|
|
137
96
|
</>
|
|
138
97
|
);
|
|
@@ -529,6 +529,7 @@ export default {
|
|
|
529
529
|
saved_vehicle: 'Saved Vehicle',
|
|
530
530
|
set_a_number: 'Set a number',
|
|
531
531
|
text_total_power_consumption: 'Total Power Consumption',
|
|
532
|
+
power_consumption_chart: 'Power Consumption Chart',
|
|
532
533
|
input_price_to_calculate_electricity_cost:
|
|
533
534
|
'Input price to calculate electricity cost',
|
|
534
535
|
calculate_cost: 'Calculate cost',
|
|
@@ -590,6 +590,7 @@ export default {
|
|
|
590
590
|
save_this_vehicle: 'Lưu và đặt phương tiện mặc định',
|
|
591
591
|
saved_vehicle: 'Phương tiện đã lưu',
|
|
592
592
|
text_total_power_consumption: 'Tổng điện năng tiêu thụ',
|
|
593
|
+
power_consumption_chart: 'Biểu đồ điện năng tiêu thụ',
|
|
593
594
|
input_price_to_calculate_electricity_cost:
|
|
594
595
|
'Nhập số tiền để tính giá tiền điện đã sử dụng',
|
|
595
596
|
calculate_cost: 'Tính giá điện',
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export const getMaxValueIndex = (data) => {
|
|
2
|
+
let max = {};
|
|
3
|
+
let _index = 0;
|
|
4
|
+
for (let i = 0; i < data.length; i++) {
|
|
5
|
+
if (max.y == null || data[i].y > max.y) {
|
|
6
|
+
max = { ...data[i] };
|
|
7
|
+
_index = i;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return { _index, max };
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const createDataLabelFormatter = () => {
|
|
14
|
+
return `function () {
|
|
15
|
+
const { unit, price } = JSON.parse(this.series.name || '{}');
|
|
16
|
+
|
|
17
|
+
// Re-define formatMoney for WebView scope since this function is stringified
|
|
18
|
+
const _formatMoney = (number) => {
|
|
19
|
+
const formatNumber = number.toFixed();
|
|
20
|
+
return (
|
|
21
|
+
parseInt(formatNumber, 10)
|
|
22
|
+
.toFixed(0)
|
|
23
|
+
.toString()
|
|
24
|
+
.replace(/(\\d)(?=(\\d\\d\\d)+(?!\\d))/g, '$1.') + 'đ'
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Hardcode Primary color or access it if available.
|
|
29
|
+
const Colors = { Primary: '#00979D' };
|
|
30
|
+
|
|
31
|
+
const textColor =
|
|
32
|
+
this.color === Colors.Primary
|
|
33
|
+
? this.y === 0
|
|
34
|
+
? '#262626'
|
|
35
|
+
: '#FFFFFF'
|
|
36
|
+
: '#262626';
|
|
37
|
+
|
|
38
|
+
const valueStyle = "color:" + textColor + ";font-weight:normal;font-size:12px;";
|
|
39
|
+
const costStyle = valueStyle + 'font-weight:bold;';
|
|
40
|
+
const label = "<span style=\\"" + valueStyle + "\\">" + this.y + (unit || '') + "</span>";
|
|
41
|
+
|
|
42
|
+
if (price === '' || price === null || isNaN(price)) {
|
|
43
|
+
return label;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
label +
|
|
48
|
+
"<span style=\\"" + costStyle + "\\">" + "/" +
|
|
49
|
+
_formatMoney(this.y * price) +
|
|
50
|
+
"</span></span>"
|
|
51
|
+
);
|
|
52
|
+
}`;
|
|
53
|
+
};
|