@eohjsc/react-native-smart-city 0.3.80 → 0.3.82
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 +2 -2
- package/src/commons/ActionGroup/OnOffTemplate/SwitchButtonTemplate.js +63 -0
- package/src/commons/ActionGroup/__test__/OnOffButtonTemplate.test.js +54 -12
- package/src/commons/ActionGroup/__test__/SwitchButtonTemplate.test.js +93 -0
- package/src/commons/ActionGroup/index.js +3 -0
- package/src/commons/Device/ProgressBar/__test__/ProgressBar.test.js +49 -0
- package/src/commons/Device/ProgressBar/index.js +45 -0
- package/src/commons/Device/ProgressBar/styles.js +33 -0
- package/src/commons/Popover/__test__/index.test.js +31 -0
- package/src/configs/Colors.js +1 -0
- package/src/configs/IOPinConstants.js +92 -165
- package/src/screens/AddNewDevice/__test__/AddNewDevice.test.js +17 -8
- package/src/screens/AddNewDevice/index.js +5 -4
- package/src/screens/AllGateway/DetailConfigActionInternal/__test__/index.test.js +1 -1
- package/src/screens/AllGateway/DetailConfigActionInternal/index.js +21 -23
- package/src/screens/AllGateway/DeviceInternalDetail/__test__/index.test.js +8 -6
- package/src/screens/AllGateway/DeviceInternalDetail/index.js +2 -0
- package/src/screens/AllGateway/hooks/useGateway.js +30 -2
- package/src/screens/Device/__test__/DetailHistoryChart.test.js +34 -21
- package/src/screens/Device/__test__/EmergencyCountdown.test.js +34 -0
- package/src/screens/Device/components/SensorDisplayItem.js +3 -0
- package/src/screens/EmergencySetting/__test__/index.test.js +22 -0
- package/src/screens/SyncLGDevice/AddLGDevice.js +5 -4
- package/src/screens/Unit/Detail.js +8 -7
- package/src/screens/Unit/hook/useFavorites.js +1 -1
- package/src/utils/Converter/__test__/timer.test.js +7 -0
- package/src/utils/Functions/preloadImages.js +1 -1
- package/src/utils/I18n/translations/en.json +1 -0
- package/src/utils/I18n/translations/vi.json +1 -0
- package/src/utils/Utils.js +23 -12
- package/src/utils/__test__/Utils.test.js +4 -4
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import renderer, { act } from 'react-test-renderer';
|
|
3
|
+
|
|
4
|
+
import { EmergencyCountdown } from '../components/EmergencyCountdown';
|
|
5
|
+
import { SCProvider } from '../../../context';
|
|
6
|
+
import { mockSCStore } from '../../../context/mockStore';
|
|
7
|
+
import Text from '../../../commons/Text';
|
|
8
|
+
|
|
9
|
+
const wrapComponent = (countUpStr, typeEmergency) => (
|
|
10
|
+
<SCProvider initState={mockSCStore({})}>
|
|
11
|
+
<EmergencyCountdown countUpStr={countUpStr} typeEmergency={typeEmergency} />
|
|
12
|
+
</SCProvider>
|
|
13
|
+
);
|
|
14
|
+
describe('Test EmergencyCountdown', () => {
|
|
15
|
+
let tree;
|
|
16
|
+
it(' EmergencyCountdown resolved_emergency', async () => {
|
|
17
|
+
await act(async () => {
|
|
18
|
+
tree = renderer.create(wrapComponent('stopCount', 'resolved_emergency'));
|
|
19
|
+
});
|
|
20
|
+
const instance = tree.root;
|
|
21
|
+
const texts = instance.findAllByType(Text);
|
|
22
|
+
expect(texts[1].props.children).toEqual('');
|
|
23
|
+
});
|
|
24
|
+
it(' EmergencyCountdown not resolved_emergency', async () => {
|
|
25
|
+
await act(async () => {
|
|
26
|
+
tree = renderer.create(
|
|
27
|
+
wrapComponent('stopCount', 'not_resolve_emergency')
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
const instance = tree.root;
|
|
31
|
+
const texts = instance.findAllByType(Text);
|
|
32
|
+
expect(texts[1].props.children).toEqual('stopCount');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -21,6 +21,7 @@ import { useSCContextSelector } from '../../../context';
|
|
|
21
21
|
import { useRemoteControl } from '../../../hooks/IoT';
|
|
22
22
|
import { useConfigGlobalState } from '../../../iot/states';
|
|
23
23
|
import { useEvaluateValue } from '../hooks/useEvaluateValue';
|
|
24
|
+
import ProgressBar from '../../../commons/Device/ProgressBar';
|
|
24
25
|
|
|
25
26
|
export const SensorDisplayItem = ({
|
|
26
27
|
item = {},
|
|
@@ -127,6 +128,8 @@ export const SensorDisplayItem = ({
|
|
|
127
128
|
);
|
|
128
129
|
case 'gauge':
|
|
129
130
|
return <Anemometer data={getData(item)} item={item} />;
|
|
131
|
+
case 'progress_bar':
|
|
132
|
+
return <ProgressBar data={getData(item)} item={item} />;
|
|
130
133
|
case 'compass':
|
|
131
134
|
return <Compass data={getData(item)} />;
|
|
132
135
|
case 'alert_status':
|
|
@@ -24,4 +24,26 @@ describe('test EmergencySetting', () => {
|
|
|
24
24
|
|
|
25
25
|
expect(dropDownItem.length).toEqual(3);
|
|
26
26
|
});
|
|
27
|
+
it('test render EmergencySetting onOpen', async () => {
|
|
28
|
+
await act(async () => {
|
|
29
|
+
tree = await create(wrapComponent());
|
|
30
|
+
});
|
|
31
|
+
const instance = tree.root;
|
|
32
|
+
const dropDownItem = instance.findAllByType(DropDownItem);
|
|
33
|
+
expect(dropDownItem[0].props.isOpen).toEqual(false);
|
|
34
|
+
await act(async () => {
|
|
35
|
+
dropDownItem[0].props.onOpen();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
it('test render EmergencySetting onSelectItem', async () => {
|
|
39
|
+
await act(async () => {
|
|
40
|
+
tree = await create(wrapComponent());
|
|
41
|
+
});
|
|
42
|
+
const instance = tree.root;
|
|
43
|
+
const dropDownItem = instance.findAllByType(DropDownItem);
|
|
44
|
+
expect(dropDownItem[0].props.isOpen).toEqual(false);
|
|
45
|
+
await act(async () => {
|
|
46
|
+
dropDownItem[0].props.onSelectItem();
|
|
47
|
+
});
|
|
48
|
+
});
|
|
27
49
|
});
|
|
@@ -71,10 +71,11 @@ const AddLGDevice = memo(({ route }) => {
|
|
|
71
71
|
navigate(Routes.Dashboard);
|
|
72
72
|
}, [backend_url, code, navigate, stationId, t]);
|
|
73
73
|
|
|
74
|
-
const stations =
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
const stations =
|
|
75
|
+
unit?.stations?.map((item) => ({
|
|
76
|
+
...item,
|
|
77
|
+
title: item.name,
|
|
78
|
+
})) || [];
|
|
78
79
|
|
|
79
80
|
return (
|
|
80
81
|
<View style={styles.wrap}>
|
|
@@ -143,16 +143,17 @@ const SubUnitList = ({
|
|
|
143
143
|
}, [stationId, listStation]);
|
|
144
144
|
|
|
145
145
|
useEffect(() => {
|
|
146
|
-
if (unit
|
|
147
|
-
let listMenu =
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
146
|
+
if (unit?.stations) {
|
|
147
|
+
let listMenu =
|
|
148
|
+
unit.stations?.map((item, index) => ({
|
|
149
|
+
text: item.name,
|
|
150
|
+
station: item,
|
|
151
|
+
id: item.id,
|
|
152
|
+
})) || [];
|
|
152
153
|
setListMenuItem(listMenu);
|
|
153
154
|
setListStation(listMenu.concat([{ text: '' }]));
|
|
154
155
|
}
|
|
155
|
-
}, [unit
|
|
156
|
+
}, [unit?.stations]);
|
|
156
157
|
|
|
157
158
|
useEffect(() => {
|
|
158
159
|
if (!unit?.stations || !unit.stations[indexStation]) {
|
|
@@ -11,7 +11,7 @@ export const useFavorites = (stations, automatesData) => {
|
|
|
11
11
|
|
|
12
12
|
const favoriteDevices = useMemo(() => {
|
|
13
13
|
return []
|
|
14
|
-
.concat(...stations
|
|
14
|
+
.concat(...stations?.map((station) => station.sensors || []))
|
|
15
15
|
.filter((device) => favoriteDeviceIds.includes(device.id));
|
|
16
16
|
}, [stations, favoriteDeviceIds]);
|
|
17
17
|
|
|
@@ -2,6 +2,13 @@ import { getDateData, getTitleFromTime, timeDifference } from '../time';
|
|
|
2
2
|
|
|
3
3
|
describe('Test timer', () => {
|
|
4
4
|
let result;
|
|
5
|
+
it('Test timeDifference when elapsed < msPerMinute and second<0', async () => {
|
|
6
|
+
result = await timeDifference(
|
|
7
|
+
new Date('2022-08-01T03:24:01'),
|
|
8
|
+
new Date('2022-08-01T03:24:03')
|
|
9
|
+
);
|
|
10
|
+
expect(result).toBe('0 seconds ago');
|
|
11
|
+
});
|
|
5
12
|
it('Test timeDifference when elapsed < msPerMinute and symbol=false', async () => {
|
|
6
13
|
result = await timeDifference(
|
|
7
14
|
new Date('2022-08-01T03:24:01'),
|
|
@@ -25,7 +25,7 @@ export const preloadImagesFromUnits = async (units, storeKey) => {
|
|
|
25
25
|
// eslint-disable-next-line promise/prefer-await-to-then
|
|
26
26
|
).then((results) => {
|
|
27
27
|
const icons = results
|
|
28
|
-
.map((item) => item?.stations
|
|
28
|
+
.map((item) => item?.stations?.map((i) => i?.background) || [])
|
|
29
29
|
.flat()
|
|
30
30
|
.filter(Boolean);
|
|
31
31
|
FastImage.preload(
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"add_user_note": "Please note that your personal data including records of your control of the connected devices and services will be shared with other members in the same unit.",
|
|
12
12
|
"add_user_invitation_sent": "Invitation sent",
|
|
13
13
|
"cancel": "Cancel",
|
|
14
|
+
"max_value": "Max value",
|
|
14
15
|
"text_password": "Password",
|
|
15
16
|
"text_sign_up": "Sign up",
|
|
16
17
|
"text_sign_up_capitalize": "Sign up",
|
|
@@ -717,6 +717,7 @@
|
|
|
717
717
|
"command_homeassistant_ready": "Home Assistant kết nối thành công",
|
|
718
718
|
"command_homeassistant_lost": "Home Assistant bị mất kết nối. Đang kết nối lại...",
|
|
719
719
|
"confirm": "Xác nhận",
|
|
720
|
+
"max_value": "Giá trị lớn nhất",
|
|
720
721
|
"pick_a_date": "Chọn ngày",
|
|
721
722
|
"car_validate_warning": "Vui lòng nhập đúng định dạng biển số xe \nVD: %{example}",
|
|
722
723
|
"are_you_sure_this_resolved": "Bạn có chắc tình huống khẩn cấp này đã được xử lý xong? Các thành viên thuộc địa điểm này cũng sẽ nhận được thông báo.",
|
package/src/utils/Utils.js
CHANGED
|
@@ -9,18 +9,15 @@ import {
|
|
|
9
9
|
RASPBERRY_PI_DIGITAL,
|
|
10
10
|
RASPBERRY_PI_ANALOG_WRITE,
|
|
11
11
|
RASPBERRY_PI_ANALOG_READ,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
ESP8266_DIGITAL,
|
|
13
|
+
ESP8266_ANALOG_READ,
|
|
14
|
+
ESP8266_ANALOG_WRITE,
|
|
15
|
+
STM32_PIN,
|
|
16
16
|
READ_DIGITAL_PIN_MODE,
|
|
17
17
|
READ_ANALOG_PIN_MODE,
|
|
18
18
|
WRITE_DIGITAL_PIN_MODE,
|
|
19
19
|
WRITE_ANALOG_PIN_MODE,
|
|
20
20
|
LANGUAGE,
|
|
21
|
-
ESP8266_DIGITAL,
|
|
22
|
-
ESP8266_ANALOG_READ,
|
|
23
|
-
ESP8266_ANALOG_WRITE,
|
|
24
21
|
} from '../configs/IOPinConstants';
|
|
25
22
|
|
|
26
23
|
export const setAxiosDefaultAuthToken = (token) => {
|
|
@@ -154,7 +151,11 @@ export const notImplemented = (t) => {
|
|
|
154
151
|
|
|
155
152
|
export const roundNumber = (value, round = 2) => {
|
|
156
153
|
if (typeof value === 'string') {
|
|
157
|
-
|
|
154
|
+
const temp = value.split(' ');
|
|
155
|
+
return (
|
|
156
|
+
Math.round((isNaN(temp[0]) ? 0 : temp[0]) * 10 ** round) / 10 ** round +
|
|
157
|
+
` ${temp[1] || ''}`
|
|
158
|
+
);
|
|
158
159
|
}
|
|
159
160
|
return value;
|
|
160
161
|
};
|
|
@@ -193,12 +194,22 @@ export const PIN_MAPPING = {
|
|
|
193
194
|
},
|
|
194
195
|
stm32: {
|
|
195
196
|
read: {
|
|
196
|
-
boolean:
|
|
197
|
-
integer:
|
|
197
|
+
boolean: STM32_PIN,
|
|
198
|
+
integer: STM32_PIN,
|
|
199
|
+
},
|
|
200
|
+
write: {
|
|
201
|
+
boolean: STM32_PIN,
|
|
202
|
+
integer: STM32_PIN,
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
stm32_wifi: {
|
|
206
|
+
read: {
|
|
207
|
+
boolean: STM32_PIN,
|
|
208
|
+
integer: STM32_PIN,
|
|
198
209
|
},
|
|
199
210
|
write: {
|
|
200
|
-
boolean:
|
|
201
|
-
integer:
|
|
211
|
+
boolean: STM32_PIN,
|
|
212
|
+
integer: STM32_PIN,
|
|
202
213
|
},
|
|
203
214
|
},
|
|
204
215
|
raspberry_pi: {
|
|
@@ -174,10 +174,10 @@ describe('Test utils', () => {
|
|
|
174
174
|
|
|
175
175
|
it('Test roundNumber', async () => {
|
|
176
176
|
let result;
|
|
177
|
-
result = await roundNumber('
|
|
178
|
-
expect(result).toBe(0);
|
|
179
|
-
result = await roundNumber('123.123');
|
|
180
|
-
expect(result).toBe(123.12);
|
|
177
|
+
result = await roundNumber('NaN kwh');
|
|
178
|
+
expect(result).toBe('0 kwh');
|
|
179
|
+
result = await roundNumber('123.123 kwh');
|
|
180
|
+
expect(result).toBe('123.12 kwh');
|
|
181
181
|
result = await roundNumber(12.12);
|
|
182
182
|
expect(result).toBe(12.12);
|
|
183
183
|
});
|