@eohjsc/react-native-smart-city 0.2.59 → 0.2.63
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 +115 -68
- package/assets/images/Map/MarkerGeolocation.svg +4 -0
- package/package.json +3 -3
- package/src/commons/ActionGroup/CurtainButtonTemplate.js +10 -2
- package/src/commons/ActionGroup/__test__/CurtainButtonTemplate.test.js +1 -1
- package/src/commons/ActionGroup/__test__/MenuActionAddSchedule.test.js +71 -0
- package/src/commons/ActionGroup/hooks/AccessScheduleDetailStyles.js +41 -0
- package/src/commons/ActionGroup/hooks/MenuActionAddSchedule.js +110 -0
- package/src/commons/ActionGroup/hooks/MenuActionAddScheduleStyle.js +69 -0
- package/src/commons/ActionGroup/hooks/RecurringDetail.js +97 -0
- package/src/commons/DateTimeRangeChange/DateTimeButton.js +7 -2
- package/src/commons/Device/HistoryChart.js +80 -81
- package/src/commons/Device/HorizontalBarChart.js +48 -31
- package/src/commons/Device/LinearChart.js +28 -1
- package/src/commons/Form/CurrencyInput.js +1 -0
- package/src/commons/FourButtonFilterHistory/__test__/FourButtonFilterHistory.test.js +48 -0
- package/src/commons/FourButtonFilterHistory/index.js +72 -0
- package/src/commons/FourButtonFilterHistory/styles.js +22 -0
- package/src/commons/ImagePicker/index.js +27 -33
- package/src/commons/MediaPlayerDetail/Styles/MediaPlayerDetailStyles.js +11 -1
- package/src/commons/MediaPlayerDetail/index.js +14 -5
- package/src/commons/SubUnit/OneTap/OneTapStyles.js +20 -1
- package/src/commons/SubUnit/OneTap/__test__/SubUnitAutomate.test.js +151 -40
- package/src/commons/SubUnit/OneTap/index.js +64 -12
- package/src/commons/UnitSummary/AirQuality/index.js +9 -7
- package/src/commons/UnitSummary/ConfigHistoryChart.js +2 -1
- package/src/configs/API.js +3 -0
- package/src/configs/Constants.js +15 -0
- package/src/iot/RemoteControl/Bluetooth.js +6 -3
- package/src/iot/RemoteControl/GoogleHome.js +6 -3
- package/src/iot/RemoteControl/Internet.js +1 -0
- package/src/iot/RemoteControl/LG.js +2 -1
- package/src/iot/RemoteControl/index.js +13 -6
- package/src/navigations/SharedStack.js +11 -9
- package/src/navigations/UnitStack.js +26 -2
- package/src/screens/ActivityLog/ItemLog.js +3 -3
- package/src/screens/ActivityLog/__test__/ItemLog.test.js +5 -2
- package/src/screens/ActivityLog/hooks/index.js +2 -1
- package/src/screens/ActivityLog/index.js +0 -1
- package/src/screens/AddLocationMaps/index.js +4 -2
- package/src/screens/AddNewAction/SelectSensorDevices.js +18 -11
- package/src/screens/AddNewAction/Styles/SelectSensorDevicesStyles.js +5 -1
- package/src/screens/AddNewAction/__test__/SelectSensorDevices.test.js +6 -1
- package/src/screens/Automate/MultiUnits.js +7 -4
- package/src/screens/Automate/__test__/MultiUnits.test.js +1 -1
- package/src/screens/Automate/__test__/index.test.js +12 -0
- package/src/screens/ConfirmUnitDeletion/__test__/ConfirmUnitDeletion.test.js +61 -0
- package/src/screens/ConfirmUnitDeletion/index.js +64 -0
- package/src/screens/ConfirmUnitDeletion/styles.js +37 -0
- package/src/screens/Device/__test__/detail.test.js +3 -2
- package/src/screens/Device/detail.js +48 -15
- package/src/screens/Device/hooks/useDisconnectedDevice.js +2 -1
- package/src/screens/Device/styles.js +3 -3
- package/src/screens/EmergencySetting/__test__/DropDownItem.test.js +59 -0
- package/src/screens/EmergencySetting/__test__/index.test.js +27 -0
- package/src/screens/EmergencySetting/components/DropDownItem.js +54 -0
- package/src/screens/EmergencySetting/index.js +92 -0
- package/src/screens/EmergencySetting/styles/DropDownItem.js +38 -0
- package/src/screens/EmergencySetting/styles.js +25 -0
- package/src/screens/MoveToAnotherSubUnit/__test__/index.test.js +126 -0
- package/src/screens/MoveToAnotherSubUnit/index.js +88 -0
- package/src/screens/MoveToAnotherSubUnit/styles/MoveToAnotherSubUnitStyles.js +50 -0
- package/src/screens/ScriptDetail/Styles/indexStyles.js +0 -1
- package/src/screens/ScriptDetail/index.js +1 -0
- package/src/screens/SubUnit/AddSubUnit.js +3 -3
- package/src/screens/SubUnit/AddSubUnitStyles.js +0 -2
- package/src/screens/SubUnit/EditSubUnit.js +16 -7
- package/src/screens/SubUnit/EditSubUnitStyles.js +2 -3
- package/src/screens/SubUnit/__test__/EditSubUnit.test.js +2 -2
- package/src/screens/TDSGuide/index.js +1 -1
- package/src/screens/Unit/ChooseLocation.js +3 -7
- package/src/screens/Unit/ChooseLocationStyles.js +5 -8
- package/src/screens/Unit/Detail.js +16 -6
- package/src/screens/Unit/ManageUnit.js +20 -26
- package/src/screens/Unit/SmartAccount.js +25 -41
- package/src/screens/Unit/SmartAccountItem.js +2 -1
- package/src/screens/Unit/SmartAccountStyles.js +0 -1
- package/src/screens/Unit/__test__/ManageUnit.test.js +0 -6
- package/src/screens/Unit/__test__/SmartAccount.test.js +24 -0
- package/src/screens/Unit/__test__/SmartAccountItem.test.js +72 -0
- package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +58 -59
- package/src/screens/UnitSummary/components/PowerConsumption/index.js +26 -22
- package/src/screens/UnitSummary/components/Temperature/ItemTemperature/index.js +2 -2
- package/src/screens/UnitSummary/components/Temperature/index.js +15 -14
- package/src/screens/UnitSummary/components/UvIndex/index.js +6 -5
- package/src/screens/UnitSummary/components/WaterQuality/index.js +9 -7
- package/src/screens/UnitSummary/index.js +11 -7
- package/src/screens/WaterQualityGuide/index.js +1 -0
- package/src/utils/Apis/axios.js +4 -4
- package/src/utils/I18n/translations/en.json +20 -2
- package/src/utils/I18n/translations/vi.json +21 -2
- package/src/utils/Route/index.js +3 -0
- package/src/utils/Utils.js +4 -0
- package/src/commons/ThreeButtonHistory/CalendarHeader.js +0 -35
- package/src/commons/ThreeButtonHistory/CalendarHeaderStyles.js +0 -17
- package/src/commons/ThreeButtonHistory/SelectMonth.js +0 -53
- package/src/commons/ThreeButtonHistory/SelectMonthStyles.js +0 -29
- package/src/commons/ThreeButtonHistory/__test__/SelectMonth.test.js +0 -37
- package/src/commons/ThreeButtonHistory/__test__/ThreeButtonHistory.test.js +0 -240
- package/src/commons/ThreeButtonHistory/index.js +0 -310
- package/src/commons/ThreeButtonHistory/styles.js +0 -65
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import renderer, { act } from 'react-test-renderer';
|
|
3
|
+
|
|
4
|
+
import { SCProvider } from '../../../context';
|
|
5
|
+
import { mockSCStore } from '../../../context/mockStore';
|
|
6
|
+
import { SmartAccountItem } from '../SmartAccountItem';
|
|
7
|
+
import { TouchableOpacity } from 'react-native';
|
|
8
|
+
import { TESTID } from '../../../configs/Constants';
|
|
9
|
+
|
|
10
|
+
const mockedOnShowMenuMore = jest.fn();
|
|
11
|
+
const mockedGotoSmartAccountDetail = jest.fn();
|
|
12
|
+
|
|
13
|
+
const wrapComponent = (route) => (
|
|
14
|
+
<SCProvider initState={mockSCStore({})}>
|
|
15
|
+
<SmartAccountItem
|
|
16
|
+
onShowMenuMore={mockedOnShowMenuMore}
|
|
17
|
+
gotoSmartAccountDetail={mockedGotoSmartAccountDetail}
|
|
18
|
+
/>
|
|
19
|
+
</SCProvider>
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
const mockedNavigate = jest.fn();
|
|
23
|
+
|
|
24
|
+
jest.mock('@react-navigation/native', () => {
|
|
25
|
+
return {
|
|
26
|
+
...jest.requireActual('@react-navigation/native'),
|
|
27
|
+
useNavigation: () => ({
|
|
28
|
+
goBack: mockedNavigate,
|
|
29
|
+
}),
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
jest.mock('react', () => {
|
|
34
|
+
return {
|
|
35
|
+
...jest.requireActual('react'),
|
|
36
|
+
memo: (x) => x,
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
jest.mock('axios');
|
|
41
|
+
describe('Test SmartAccountItem', () => {
|
|
42
|
+
let tree;
|
|
43
|
+
test('test render SmartAccountItem', async () => {
|
|
44
|
+
await act(async () => {
|
|
45
|
+
tree = await renderer.create(wrapComponent());
|
|
46
|
+
});
|
|
47
|
+
const instance = tree.root;
|
|
48
|
+
|
|
49
|
+
const onPressGotoSmartAccountDetail = instance.find(
|
|
50
|
+
(el) =>
|
|
51
|
+
el.props.testID === TESTID.SMART_ACCOUNT_ITEM &&
|
|
52
|
+
el.type === TouchableOpacity
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
await act(async () => {
|
|
56
|
+
onPressGotoSmartAccountDetail.props.onPress();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
expect(mockedGotoSmartAccountDetail).toHaveBeenCalled();
|
|
60
|
+
|
|
61
|
+
const onPressMore = instance.find(
|
|
62
|
+
(el) =>
|
|
63
|
+
el.props.testID === TESTID.SMART_ACCOUNT_ITEM_PRESSMORE &&
|
|
64
|
+
el.type === TouchableOpacity
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
await act(async () => {
|
|
68
|
+
onPressMore.props.onPress();
|
|
69
|
+
});
|
|
70
|
+
expect(mockedOnShowMenuMore).toHaveBeenCalled();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -12,7 +12,7 @@ import HistoryChart from '../../../../commons/Device/HistoryChart';
|
|
|
12
12
|
import { axiosGet } from '../../../../utils/Apis/axios';
|
|
13
13
|
import { TESTID } from '../../../../configs/Constants';
|
|
14
14
|
|
|
15
|
-
const ThreePhasePowerConsumption = memo(({
|
|
15
|
+
const ThreePhasePowerConsumption = memo(({ summaryDetail }) => {
|
|
16
16
|
const t = useTranslations();
|
|
17
17
|
const {
|
|
18
18
|
volt1Value,
|
|
@@ -133,12 +133,63 @@ const ThreePhasePowerConsumption = memo(({ unit, summary, summaryDetail }) => {
|
|
|
133
133
|
return !!listConfigs;
|
|
134
134
|
}, [listConfigs]);
|
|
135
135
|
|
|
136
|
-
const
|
|
137
|
-
return
|
|
136
|
+
const configs = useMemo(() => {
|
|
137
|
+
return [
|
|
138
|
+
{
|
|
139
|
+
id: listConfigs?.volt_1,
|
|
140
|
+
title: 'Volt 1',
|
|
141
|
+
color: Colors.Red6,
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
id: listConfigs?.volt_2,
|
|
145
|
+
title: 'Volt 2',
|
|
146
|
+
color: Colors.Red8,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
id: listConfigs?.volt_3,
|
|
150
|
+
title: 'Volt 3',
|
|
151
|
+
color: Colors.Red9,
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
id: listConfigs?.current_1,
|
|
155
|
+
title: 'Current 1',
|
|
156
|
+
color: Colors.Blue10,
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
id: listConfigs?.current_2,
|
|
160
|
+
title: 'Current 2',
|
|
161
|
+
color: Colors.Blue11,
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
id: listConfigs?.current_3,
|
|
165
|
+
title: 'Current 3',
|
|
166
|
+
color: Colors.Blue12,
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
id: listConfigs?.active_power,
|
|
170
|
+
title: 'Active Power',
|
|
171
|
+
color: Colors.Orange6,
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
id: listConfigs?.power_factor_1,
|
|
175
|
+
title: 'Power Factor 1',
|
|
176
|
+
color: Colors.Green6,
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
id: listConfigs?.power_factor_2,
|
|
180
|
+
title: 'Power Factor 2',
|
|
181
|
+
color: Colors.Green9,
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
id: listConfigs?.power_factor_3,
|
|
185
|
+
title: 'Power Factor 3',
|
|
186
|
+
color: Colors.Green10,
|
|
187
|
+
},
|
|
188
|
+
];
|
|
138
189
|
}, [listConfigs]);
|
|
139
190
|
|
|
140
191
|
const [startDate, setStartDate] = useState(
|
|
141
|
-
moment().subtract(
|
|
192
|
+
moment().subtract(6, 'days').valueOf()
|
|
142
193
|
);
|
|
143
194
|
const [endDate, setEndDate] = useState(moment().valueOf());
|
|
144
195
|
const [groupBy, setGroupBy] = useState('date');
|
|
@@ -168,7 +219,7 @@ const ThreePhasePowerConsumption = memo(({ unit, summary, summaryDetail }) => {
|
|
|
168
219
|
if (listConfigs?.total_power) {
|
|
169
220
|
fetchData();
|
|
170
221
|
}
|
|
171
|
-
}, [startDate, endDate, listConfigs, groupBy]);
|
|
222
|
+
}, [startDate, endDate, listConfigs?.total_power, groupBy]);
|
|
172
223
|
return (
|
|
173
224
|
<>
|
|
174
225
|
<Section type={'border'}>
|
|
@@ -180,60 +231,7 @@ const ThreePhasePowerConsumption = memo(({ unit, summary, summaryDetail }) => {
|
|
|
180
231
|
/>
|
|
181
232
|
{showBoxHistory && (
|
|
182
233
|
<View>
|
|
183
|
-
<ConfigHistoryChart
|
|
184
|
-
configs={[
|
|
185
|
-
{
|
|
186
|
-
id: listIdsConfig.volt_1,
|
|
187
|
-
title: 'Volt 1',
|
|
188
|
-
color: Colors.Red6,
|
|
189
|
-
},
|
|
190
|
-
{
|
|
191
|
-
id: listIdsConfig.volt_2,
|
|
192
|
-
title: 'Volt 2',
|
|
193
|
-
color: Colors.Red8,
|
|
194
|
-
},
|
|
195
|
-
{
|
|
196
|
-
id: listIdsConfig.volt_3,
|
|
197
|
-
title: 'Volt 3',
|
|
198
|
-
color: Colors.Red9,
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
id: listIdsConfig.current_1,
|
|
202
|
-
title: 'Current 1',
|
|
203
|
-
color: Colors.Blue10,
|
|
204
|
-
},
|
|
205
|
-
{
|
|
206
|
-
id: listIdsConfig.current_2,
|
|
207
|
-
title: 'Current 2',
|
|
208
|
-
color: Colors.Blue11,
|
|
209
|
-
},
|
|
210
|
-
{
|
|
211
|
-
id: listIdsConfig.current_3,
|
|
212
|
-
title: 'Current 3',
|
|
213
|
-
color: Colors.Blue12,
|
|
214
|
-
},
|
|
215
|
-
{
|
|
216
|
-
id: listIdsConfig.active_power,
|
|
217
|
-
title: 'Active Power',
|
|
218
|
-
color: Colors.Orange6,
|
|
219
|
-
},
|
|
220
|
-
{
|
|
221
|
-
id: listIdsConfig.power_factor_1,
|
|
222
|
-
title: 'Power Factor 1',
|
|
223
|
-
color: Colors.Green6,
|
|
224
|
-
},
|
|
225
|
-
{
|
|
226
|
-
id: listIdsConfig.power_factor_2,
|
|
227
|
-
title: 'Power Factor 2',
|
|
228
|
-
color: Colors.Green9,
|
|
229
|
-
},
|
|
230
|
-
{
|
|
231
|
-
id: listIdsConfig.power_factor_3,
|
|
232
|
-
title: 'Power Factor 3',
|
|
233
|
-
color: Colors.Green10,
|
|
234
|
-
},
|
|
235
|
-
]}
|
|
236
|
-
/>
|
|
234
|
+
<ConfigHistoryChart configs={configs} />
|
|
237
235
|
</View>
|
|
238
236
|
)}
|
|
239
237
|
</Section>
|
|
@@ -253,6 +251,7 @@ const ThreePhasePowerConsumption = memo(({ unit, summary, summaryDetail }) => {
|
|
|
253
251
|
startDate={startDate}
|
|
254
252
|
setEndDate={setEndDate}
|
|
255
253
|
setStartDate={setStartDate}
|
|
254
|
+
groupBy={groupBy}
|
|
256
255
|
setGroupBy={setGroupBy}
|
|
257
256
|
configuration={{
|
|
258
257
|
type: 'horizontal_bar_chart',
|
|
@@ -78,7 +78,7 @@ const PowerConsumption = memo(({ summaryDetail }) => {
|
|
|
78
78
|
dataTotal.push(totalPower);
|
|
79
79
|
|
|
80
80
|
const [startDate, setStartDate] = useState(
|
|
81
|
-
moment().subtract(
|
|
81
|
+
moment().subtract(6, 'days').valueOf()
|
|
82
82
|
);
|
|
83
83
|
const [endDate, setEndDate] = useState(moment().valueOf());
|
|
84
84
|
const [groupBy, setGroupBy] = useState('date');
|
|
@@ -108,7 +108,29 @@ const PowerConsumption = memo(({ summaryDetail }) => {
|
|
|
108
108
|
if (listConfigs?.total_power) {
|
|
109
109
|
fetchData();
|
|
110
110
|
}
|
|
111
|
-
}, [startDate, endDate, listConfigs, groupBy]);
|
|
111
|
+
}, [startDate, endDate, listConfigs?.total_power, groupBy]);
|
|
112
|
+
|
|
113
|
+
const configs = useMemo(() => {
|
|
114
|
+
return [
|
|
115
|
+
{ id: listIdsConfig?.volt, title: 'Volt', color: 'red' },
|
|
116
|
+
{
|
|
117
|
+
id: listIdsConfig?.current,
|
|
118
|
+
title: 'Current',
|
|
119
|
+
color: 'blue',
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
id: listIdsConfig?.active_power,
|
|
123
|
+
title: 'Active Power',
|
|
124
|
+
color: 'orange',
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
id: listIdsConfig?.power_factor,
|
|
128
|
+
title: 'Power Factor',
|
|
129
|
+
color: 'green',
|
|
130
|
+
},
|
|
131
|
+
];
|
|
132
|
+
}, [listIdsConfig]);
|
|
133
|
+
|
|
112
134
|
return (
|
|
113
135
|
<>
|
|
114
136
|
<Section type={'border'}>
|
|
@@ -120,26 +142,7 @@ const PowerConsumption = memo(({ summaryDetail }) => {
|
|
|
120
142
|
/>
|
|
121
143
|
{showBoxHistory && (
|
|
122
144
|
<View>
|
|
123
|
-
<ConfigHistoryChart
|
|
124
|
-
configs={[
|
|
125
|
-
{ id: listIdsConfig.volt, title: 'Volt', color: 'red' },
|
|
126
|
-
{
|
|
127
|
-
id: listIdsConfig.active_power,
|
|
128
|
-
title: 'Current',
|
|
129
|
-
color: 'blue',
|
|
130
|
-
},
|
|
131
|
-
{
|
|
132
|
-
id: listIdsConfig.current,
|
|
133
|
-
title: 'Active Power',
|
|
134
|
-
color: 'orange',
|
|
135
|
-
},
|
|
136
|
-
{
|
|
137
|
-
id: listIdsConfig.power_factor,
|
|
138
|
-
title: 'Power Factor',
|
|
139
|
-
color: 'green',
|
|
140
|
-
},
|
|
141
|
-
]}
|
|
142
|
-
/>
|
|
145
|
+
<ConfigHistoryChart configs={configs} />
|
|
143
146
|
</View>
|
|
144
147
|
)}
|
|
145
148
|
</Section>
|
|
@@ -160,6 +163,7 @@ const PowerConsumption = memo(({ summaryDetail }) => {
|
|
|
160
163
|
endDate={endDate}
|
|
161
164
|
setEndDate={setEndDate}
|
|
162
165
|
setStartDate={setStartDate}
|
|
166
|
+
groupBy={groupBy}
|
|
163
167
|
setGroupBy={setGroupBy}
|
|
164
168
|
configuration={{
|
|
165
169
|
type: 'horizontal_bar_chart',
|
|
@@ -10,13 +10,13 @@ const ItemTemperature = memo((props) => {
|
|
|
10
10
|
const { svgMain, title, des, value } = props;
|
|
11
11
|
return (
|
|
12
12
|
<View style={styles.container}>
|
|
13
|
-
<Text
|
|
13
|
+
<Text type="H4" color={Colors.Gray8} style={styles.textTitle}>
|
|
14
14
|
{title}
|
|
15
15
|
</Text>
|
|
16
16
|
<Text size={24} color={Colors.Gray9} style={styles.textValue}>
|
|
17
17
|
{value}
|
|
18
18
|
</Text>
|
|
19
|
-
<Text
|
|
19
|
+
<Text type="H4" color={Colors.Gray8}>
|
|
20
20
|
{des}
|
|
21
21
|
</Text>
|
|
22
22
|
<View style={styles.boxSvg}>{svgMain}</View>
|
|
@@ -56,6 +56,20 @@ const Temperature = memo(({ summaryDetail }) => {
|
|
|
56
56
|
[summaryDetail]
|
|
57
57
|
);
|
|
58
58
|
|
|
59
|
+
const configs = useMemo(() => {
|
|
60
|
+
return [
|
|
61
|
+
{
|
|
62
|
+
id: listConfigs?.temp,
|
|
63
|
+
title: t('text_temperature'),
|
|
64
|
+
color: Colors.Blue10,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: listConfigs?.humi,
|
|
68
|
+
title: t('text_humidity'),
|
|
69
|
+
color: Colors.Red6,
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
}, [listConfigs?.humi, listConfigs?.temp, t]);
|
|
59
73
|
return (
|
|
60
74
|
<>
|
|
61
75
|
<Section type={'border'}>
|
|
@@ -78,20 +92,7 @@ const Temperature = memo(({ summaryDetail }) => {
|
|
|
78
92
|
</Section>
|
|
79
93
|
{showBoxHistory && (
|
|
80
94
|
<Section type={'border'}>
|
|
81
|
-
<ConfigHistoryChart
|
|
82
|
-
configs={[
|
|
83
|
-
{
|
|
84
|
-
id: listConfigs.temp,
|
|
85
|
-
title: t('text_temperature'),
|
|
86
|
-
color: Colors.Blue10,
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
id: listConfigs.humi,
|
|
90
|
-
title: t('text_humidity'),
|
|
91
|
-
color: Colors.Red6,
|
|
92
|
-
},
|
|
93
|
-
]}
|
|
94
|
-
/>
|
|
95
|
+
<ConfigHistoryChart configs={configs} />
|
|
95
96
|
</Section>
|
|
96
97
|
)}
|
|
97
98
|
</>
|
|
@@ -22,6 +22,11 @@ const UvIndex = memo(({ summaryDetail }) => {
|
|
|
22
22
|
} else if (summaryDetail.uv_value > 10) {
|
|
23
23
|
valueRefined = 10;
|
|
24
24
|
}
|
|
25
|
+
|
|
26
|
+
const configs = useMemo(() => {
|
|
27
|
+
return [{ id: uv_id, title: t('text_uv_index'), color: Colors.Blue10 }];
|
|
28
|
+
}, [t, uv_id]);
|
|
29
|
+
|
|
25
30
|
return (
|
|
26
31
|
<>
|
|
27
32
|
<Section type={'border'}>
|
|
@@ -70,11 +75,7 @@ const UvIndex = memo(({ summaryDetail }) => {
|
|
|
70
75
|
</Section>
|
|
71
76
|
{showBoxHistory && (
|
|
72
77
|
<Section type={'border'}>
|
|
73
|
-
<ConfigHistoryChart
|
|
74
|
-
configs={[
|
|
75
|
-
{ id: uv_id, title: t('text_uv_index'), color: Colors.Blue10 },
|
|
76
|
-
]}
|
|
77
|
-
/>
|
|
78
|
+
<ConfigHistoryChart configs={configs} />
|
|
78
79
|
</Section>
|
|
79
80
|
)}
|
|
80
81
|
</>
|
|
@@ -12,6 +12,14 @@ const WaterQuality = memo(({ summaryDetail }) => {
|
|
|
12
12
|
const showBoxHistory = useMemo(() => {
|
|
13
13
|
return ph_id || tur_id || clo_id ? true : false;
|
|
14
14
|
}, [ph_id, tur_id, clo_id]);
|
|
15
|
+
|
|
16
|
+
const configs = useMemo(() => {
|
|
17
|
+
return [
|
|
18
|
+
{ id: ph_id, title: 'pH', color: 'red' },
|
|
19
|
+
{ id: tur_id, title: 'Turbidity', color: 'blue' },
|
|
20
|
+
{ id: clo_id, title: 'Chlorine residual', color: 'orange' },
|
|
21
|
+
];
|
|
22
|
+
}, [ph_id, tur_id, clo_id]);
|
|
15
23
|
return (
|
|
16
24
|
<>
|
|
17
25
|
<Section type={'border'}>
|
|
@@ -52,13 +60,7 @@ const WaterQuality = memo(({ summaryDetail }) => {
|
|
|
52
60
|
</Section>
|
|
53
61
|
{showBoxHistory && (
|
|
54
62
|
<Section type={'border'}>
|
|
55
|
-
<ConfigHistoryChart
|
|
56
|
-
configs={[
|
|
57
|
-
{ id: ph_id, title: 'pH', color: 'red' },
|
|
58
|
-
{ id: tur_id, title: 'Turbidity', color: 'blue' },
|
|
59
|
-
{ id: clo_id, title: 'Chlorine residual', color: 'orange' },
|
|
60
|
-
]}
|
|
61
|
-
/>
|
|
63
|
+
<ConfigHistoryChart configs={configs} />
|
|
62
64
|
</Section>
|
|
63
65
|
)}
|
|
64
66
|
</>
|
|
@@ -4,6 +4,7 @@ import { useNavigation } from '@react-navigation/native';
|
|
|
4
4
|
import { TouchableOpacity } from 'react-native';
|
|
5
5
|
import { IconOutline } from '@ant-design/icons-react-native';
|
|
6
6
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
7
|
+
import moment from 'moment';
|
|
7
8
|
|
|
8
9
|
import { API, Colors } from '../../configs';
|
|
9
10
|
import Routes from '../../utils/Route';
|
|
@@ -18,6 +19,7 @@ import Temperature from './components/Temperature';
|
|
|
18
19
|
import UvIndex from './components/UvIndex';
|
|
19
20
|
import WaterQuality from './components/WaterQuality';
|
|
20
21
|
import { TESTID } from '../../configs/Constants';
|
|
22
|
+
import { timeDifference } from '../../utils/Converter/time';
|
|
21
23
|
|
|
22
24
|
const UnitSummary = memo(({ route }) => {
|
|
23
25
|
const t = useTranslations();
|
|
@@ -25,6 +27,7 @@ const UnitSummary = memo(({ route }) => {
|
|
|
25
27
|
const [summaryDetail, setSummaryDetail] = useState({});
|
|
26
28
|
|
|
27
29
|
const [loading, setLoading] = useState(false);
|
|
30
|
+
const [lastUpdated, setLastUpdated] = useState();
|
|
28
31
|
const navigation = useNavigation();
|
|
29
32
|
|
|
30
33
|
const getComponentAndGuide = useCallback(() => {
|
|
@@ -75,6 +78,7 @@ const UnitSummary = memo(({ route }) => {
|
|
|
75
78
|
setLoading(false);
|
|
76
79
|
if (success) {
|
|
77
80
|
setSummaryDetail(data.data);
|
|
81
|
+
setLastUpdated(data.data.last_updated);
|
|
78
82
|
}
|
|
79
83
|
}, [summary.id, unit.id]);
|
|
80
84
|
|
|
@@ -84,7 +88,7 @@ const UnitSummary = memo(({ route }) => {
|
|
|
84
88
|
|
|
85
89
|
const autoUpdate = setInterval(() => {
|
|
86
90
|
fetchSummaryDetail();
|
|
87
|
-
},
|
|
91
|
+
}, 10000); // fetch each 10 second
|
|
88
92
|
|
|
89
93
|
return () => clearInterval(autoUpdate);
|
|
90
94
|
}, [fetchSummaryDetail]);
|
|
@@ -98,11 +102,15 @@ const UnitSummary = memo(({ route }) => {
|
|
|
98
102
|
const ComponentName = UnitSummaryDetail.componentName;
|
|
99
103
|
const GuideName = UnitSummaryDetail.guideName;
|
|
100
104
|
|
|
105
|
+
const lastUpdatedStr = lastUpdated
|
|
106
|
+
? `${t('last_updated')} ${timeDifference(moment(), moment(lastUpdated))}`
|
|
107
|
+
: null;
|
|
108
|
+
|
|
101
109
|
return (
|
|
102
110
|
<View style={[styles.container]}>
|
|
103
111
|
<WrapHeaderScrollable
|
|
104
112
|
title={summary.name}
|
|
105
|
-
subTitle={
|
|
113
|
+
subTitle={lastUpdatedStr}
|
|
106
114
|
rightComponent={
|
|
107
115
|
GuideName ? (
|
|
108
116
|
<View style={styles.rightComponent}>
|
|
@@ -122,11 +130,7 @@ const UnitSummary = memo(({ route }) => {
|
|
|
122
130
|
loading={loading}
|
|
123
131
|
onRefresh={onRefresh}
|
|
124
132
|
>
|
|
125
|
-
<ComponentName
|
|
126
|
-
summaryDetail={summaryDetail}
|
|
127
|
-
unit={unit}
|
|
128
|
-
summary={summary}
|
|
129
|
-
/>
|
|
133
|
+
<ComponentName summaryDetail={summaryDetail} unit={unit} />
|
|
130
134
|
</WrapHeaderScrollable>
|
|
131
135
|
</View>
|
|
132
136
|
);
|
package/src/utils/Apis/axios.js
CHANGED
|
@@ -2,6 +2,7 @@ import axios from 'axios';
|
|
|
2
2
|
import { deleteData, getData, storeData } from '../Storage';
|
|
3
3
|
import { ToastBottomHelper } from '../Utils';
|
|
4
4
|
import NetInfo from '@react-native-community/netinfo';
|
|
5
|
+
import { Platform } from 'react-native';
|
|
5
6
|
|
|
6
7
|
export const replaceParams = (apiURL, params) => {
|
|
7
8
|
let _result = apiURL;
|
|
@@ -165,13 +166,12 @@ export function createFormData(data, list_file_field) {
|
|
|
165
166
|
}
|
|
166
167
|
|
|
167
168
|
formData.append(key, {
|
|
168
|
-
|
|
169
|
-
type: item.
|
|
170
|
-
|
|
169
|
+
uri: Platform.OS === 'ios' ? item.sourceURL : item.path,
|
|
170
|
+
type: item.mime,
|
|
171
|
+
name: item.filename || item.path?.split('/').pop(),
|
|
171
172
|
});
|
|
172
173
|
return;
|
|
173
174
|
}
|
|
174
|
-
|
|
175
175
|
formData.append(key, data[key]);
|
|
176
176
|
});
|
|
177
177
|
|
|
@@ -471,7 +471,7 @@
|
|
|
471
471
|
"scan_qr_code_at_%{spot}": "Scan QR code at spot %{spot}",
|
|
472
472
|
"extend": "Extend",
|
|
473
473
|
"verify_qr_code": "Verifying code...",
|
|
474
|
-
"
|
|
474
|
+
"tds_information": "TDS Information",
|
|
475
475
|
"what_is_tds_title": "What is TDS?",
|
|
476
476
|
"what_is_tds_text": "TDS: is the total dissolved solids present in a certain amount of water - (the total number of charged ions, including salts, minerals or metals) that exist in a certain volume of water. High TDS is also responsible for turbidity and sedimentation in water. TDS is expressed in mg / L or parts per million (parts per million).",
|
|
477
477
|
"tds_guidlines_title": "TDS guidlines for drinking water",
|
|
@@ -781,6 +781,8 @@
|
|
|
781
781
|
"Script": "Script",
|
|
782
782
|
"One-Tap": "One-Tap",
|
|
783
783
|
"Scenario": "Scenario",
|
|
784
|
+
"one_tap": "One-Tap",
|
|
785
|
+
"scenario": "Scenario",
|
|
784
786
|
"automation": "Automation",
|
|
785
787
|
"set_schedule": "Set schedule",
|
|
786
788
|
"select_date": "Select date",
|
|
@@ -844,9 +846,25 @@
|
|
|
844
846
|
"name_your_unit": "Name your unit",
|
|
845
847
|
"script_updated_by": "Script updated by",
|
|
846
848
|
"qr_scan_guidelines": "The QR code will be detected automatically when it’s positioned within the guide lines.",
|
|
849
|
+
"move_to_another_sub_unit": "Move to another Sub unit",
|
|
847
850
|
"now_playing": "Now Playing",
|
|
848
851
|
"pause": "Pause",
|
|
852
|
+
"setting": "Setting",
|
|
853
|
+
"duration": "Duration",
|
|
854
|
+
"level": "Level",
|
|
855
|
+
"strobe": "Strobe",
|
|
849
856
|
"volume": "Volume",
|
|
850
857
|
"this_notification_will_be_updated_soon": "This notification will be updated soon",
|
|
851
|
-
"
|
|
858
|
+
"text_submit": "Submit",
|
|
859
|
+
"remove_account": "Remove Account",
|
|
860
|
+
"text_sub_unit_not_have_device": "You don't have sub-unit with a device to control",
|
|
861
|
+
"tap_to_add_new_schedule": "Tap + to add new schedule",
|
|
862
|
+
"confirmation": "Confirmation",
|
|
863
|
+
"enter_yes_to_perform": "You need to enter 'YES' to perform this action",
|
|
864
|
+
"please_enter_correct":"Please enter correct",
|
|
865
|
+
"add_schedule": "Add Schedule",
|
|
866
|
+
"curtain_opens": "Curtain opens",
|
|
867
|
+
"curtain_closes": "Curtain closes",
|
|
868
|
+
"schedule_name": "Schedule name",
|
|
869
|
+
"enter_name": "Enter name"
|
|
852
870
|
}
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"%{number}_filter_need_to_be_replaced": "%{number} lõi lọc cần được thay thế.",
|
|
58
58
|
"replace_all_filters": "Tất cả lõi lọc cần được thay thế.",
|
|
59
59
|
"auth_already_have_an_account": "Bạn đã có tài khoản? ",
|
|
60
|
-
"
|
|
60
|
+
"tds_information": "Chỉ số TDS",
|
|
61
61
|
"what_is_tds_title": "TDS là gì?",
|
|
62
62
|
"set_a_number": "Đặt một số",
|
|
63
63
|
"add_action": "Thêm hành động",
|
|
@@ -783,6 +783,8 @@
|
|
|
783
783
|
"Script": "Kịch bản",
|
|
784
784
|
"One-Tap": "Một chạm",
|
|
785
785
|
"Scenario": "Kịch bản",
|
|
786
|
+
"one_tap": "Một chạm",
|
|
787
|
+
"scenario": "Kịch bản",
|
|
786
788
|
"automation": "Tự động",
|
|
787
789
|
"set_schedule": "Đặt lịch",
|
|
788
790
|
"select_date": "Chọn ngày",
|
|
@@ -845,9 +847,26 @@
|
|
|
845
847
|
"name_your_unit": "Đặt tên cho khu vực của bạn",
|
|
846
848
|
"script_updated_by": "Kịch bản được cập nhật bởi",
|
|
847
849
|
"qr_scan_guidelines": "Mã QR sẽ được phát hiện tự động khi nó được định vị trong các dòng hướng dẫn.",
|
|
850
|
+
"move_to_another_sub_unit": "Chuyển sang khu vực khác",
|
|
848
851
|
"now_playing": "Đang chạy",
|
|
849
852
|
"pause": "Tạm dừng",
|
|
853
|
+
"setting": "Cài đặt",
|
|
854
|
+
"duration": "Khoảng thời gian",
|
|
855
|
+
"level": "Cấp độ",
|
|
856
|
+
"strobe": "Nhấp nháy",
|
|
850
857
|
"volume": "Âm lượng",
|
|
851
858
|
"this_notification_will_be_updated_soon": "Thông báo này sẽ sớm được cập nhật",
|
|
852
|
-
"
|
|
859
|
+
"text_submit": "Xác nhận",
|
|
860
|
+
"tap_to_add_new_schedule": "Nhấn + để thêm lịch trình mới",
|
|
861
|
+
"remove_account": "Xóa tài khoản",
|
|
862
|
+
"text_subunit_not_have_device": "Bạn không có khu vực nào có thiết bị để điều khiển",
|
|
863
|
+
"choose_at_least_one": "Vui lòng chọn ít nhất 1 thiết bị.",
|
|
864
|
+
"confirmation": "Xác Nhận",
|
|
865
|
+
"enter_yes_to_perform": "Bạn cần nhập 'YES' để thực hiện hành động này",
|
|
866
|
+
"please_enter_correct":"Vui lòng nhập đúng",
|
|
867
|
+
"add_schedule": "Thêm lịch trình",
|
|
868
|
+
"curtain_opens": "Rèm mở",
|
|
869
|
+
"curtain_closes": "Rèm đóng",
|
|
870
|
+
"schedule_name": "Tên lịch trình",
|
|
871
|
+
"enter_name": "Nhập tên"
|
|
853
872
|
}
|
package/src/utils/Route/index.js
CHANGED
|
@@ -96,6 +96,7 @@ const Routes = {
|
|
|
96
96
|
TermAndPolicy: 'TermAndPolicy',
|
|
97
97
|
Browser: 'Browser',
|
|
98
98
|
ManageAccess: 'ManageAccess',
|
|
99
|
+
MoveToAnotherSubUnit: 'MoveToAnotherSubUnit',
|
|
99
100
|
SelectSensorDevices: 'SelectSensorDevices',
|
|
100
101
|
SelectAction: 'SelectAction',
|
|
101
102
|
GuestInfo: 'GuestInfo',
|
|
@@ -119,6 +120,8 @@ const Routes = {
|
|
|
119
120
|
ListSmartAccount: 'ListSmartAccount',
|
|
120
121
|
ListDeviceSmartAccount: 'ListDeviceSmartAccount',
|
|
121
122
|
SmartAccountConnecting: 'SmartAccountConnecting',
|
|
123
|
+
EmergencySetting: 'EmergencySetting',
|
|
124
|
+
ConfirmUnitDeletion: 'ConfirmUnitDeletion',
|
|
122
125
|
};
|
|
123
126
|
|
|
124
127
|
export default Routes;
|
package/src/utils/Utils.js
CHANGED
|
@@ -120,6 +120,10 @@ export const removeFromString = (str, index) => {
|
|
|
120
120
|
return str.substr(0, index) + str.substr(index + 1);
|
|
121
121
|
};
|
|
122
122
|
|
|
123
|
+
export const arePropsEqual = (prevProps, nextProps) => {
|
|
124
|
+
return JSON.stringify(prevProps) === JSON.stringify(nextProps);
|
|
125
|
+
};
|
|
126
|
+
|
|
123
127
|
export default {
|
|
124
128
|
validateEmail,
|
|
125
129
|
isObjectEmpty,
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
View,
|
|
4
|
-
TouchableOpacity,
|
|
5
|
-
TouchableWithoutFeedback,
|
|
6
|
-
Image,
|
|
7
|
-
} from 'react-native';
|
|
8
|
-
import Text from '../Text';
|
|
9
|
-
import { Images } from '../../configs';
|
|
10
|
-
import styles from './CalendarHeaderStyles';
|
|
11
|
-
|
|
12
|
-
const CalendarHeader = ({
|
|
13
|
-
currentMonth,
|
|
14
|
-
onAddMonth,
|
|
15
|
-
onSubtractMonth,
|
|
16
|
-
onPressTitle,
|
|
17
|
-
}) => {
|
|
18
|
-
return (
|
|
19
|
-
<View style={styles.wrap}>
|
|
20
|
-
<TouchableOpacity onPress={onSubtractMonth} style={styles.button}>
|
|
21
|
-
<Image source={Images.arrowLeft} />
|
|
22
|
-
</TouchableOpacity>
|
|
23
|
-
<TouchableWithoutFeedback onPress={onPressTitle}>
|
|
24
|
-
<Text type="H4" bold>
|
|
25
|
-
{currentMonth.format('MMMM YYYY')}
|
|
26
|
-
</Text>
|
|
27
|
-
</TouchableWithoutFeedback>
|
|
28
|
-
<TouchableOpacity onPress={onAddMonth} style={styles.button}>
|
|
29
|
-
<Image source={Images.arrowLeft} style={styles.arrow} />
|
|
30
|
-
</TouchableOpacity>
|
|
31
|
-
</View>
|
|
32
|
-
);
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export default CalendarHeader;
|