@eohjsc/react-native-smart-city 0.2.56 → 0.2.60
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/assets/images/Map/MarkerGeolocation.svg +4 -0
- package/assets/images/SonosSpeaker/buttonpause-active.svg +3 -0
- package/assets/images/SonosSpeaker/buttonpause-notactive.svg +3 -0
- package/assets/images/SonosSpeaker/picture-main-notactive.svg +5 -0
- package/assets/images/SonosSpeaker/picture-main.svg +6 -0
- package/assets/images/SonosSpeaker/picture-volume.svg +3 -0
- package/package.json +4 -22
- package/src/Images/Common/buttonLeftCurtain.png +0 -0
- package/src/Images/Common/buttonPause-center-curtain.png +0 -0
- package/src/Images/Common/buttonRightCurtain.png +0 -0
- package/src/commons/ActionGroup/CurtainButtonTemplate.js +139 -0
- package/src/commons/ActionGroup/CurtainButtonTemplateStyle.js +58 -0
- package/src/commons/ActionGroup/__test__/CurtainButtonTemplate.test.js +72 -0
- package/src/commons/ActionGroup/index.js +3 -0
- package/src/commons/Auth/__test__/AccountList.test.js +33 -0
- package/src/commons/CameraDevice/index.js +2 -0
- package/src/commons/CardShadow/index.js +1 -1
- package/src/commons/CardShadow/styles.js +1 -3
- package/src/commons/DateTimeRangeChange/DateTimeButton.js +1 -1
- package/src/commons/DateTimeRangeChange/index.js +2 -2
- package/src/commons/Device/HistoryChart.js +21 -55
- package/src/commons/Device/HorizontalBarChart.js +46 -30
- package/src/commons/Device/LinearChart.js +0 -34
- package/src/commons/Device/PMSensor/PMSensorIndicatior.js +1 -1
- package/src/commons/Device/PMSensor/PMSensorIndicatorStyles.js +2 -1
- package/src/commons/Device/SonosSpeaker/__test__/SonosSpeaker.test.js +57 -0
- package/src/commons/Device/SonosSpeaker/index.js +88 -0
- package/src/commons/Device/SonosSpeaker/styles.js +57 -0
- package/src/commons/Form/CurrencyInput.js +169 -0
- package/src/commons/Form/__test__/CurrencyInput.test.js +65 -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/MediaPlayerDetail/Styles/MediaPlayerDetailStyles.js +14 -0
- package/src/commons/MediaPlayerDetail/index.js +204 -161
- package/src/commons/SearchLocation/index.js +0 -1
- package/src/commons/Sharing/RowMember.js +7 -2
- package/src/commons/Sharing/__test__/RowMember.test.js +42 -0
- package/src/commons/SubUnit/ShortDetail.js +12 -6
- package/src/commons/UnitSummary/AirQuality/SegmentedRoundDisplay/index.js +1 -1
- package/src/commons/UnitSummary/ConfigHistoryChart.js +2 -1
- package/src/configs/API.js +13 -3
- package/src/configs/Constants.js +14 -4
- package/src/configs/Images.js +3 -0
- package/src/configs/SCConfig.js +8 -0
- package/src/context/actionType.ts +5 -0
- package/src/context/mockStore.ts +3 -0
- package/src/context/reducer.ts +14 -0
- package/src/iot/RemoteControl/Bluetooth.js +14 -0
- package/src/iot/RemoteControl/index.js +0 -1
- package/src/navigations/UnitStack.js +42 -4
- package/src/screens/ActivityLog/FilterPopup.js +1 -1
- package/src/screens/ActivityLog/ItemLog.js +11 -2
- package/src/screens/ActivityLog/__test__/ItemLog.test.js +46 -0
- package/src/screens/ActivityLog/hooks/index.js +1 -0
- package/src/screens/ActivityLog/index.js +0 -1
- package/src/screens/AddCommon/SelectSubUnit.js +24 -2
- package/src/screens/AddCommon/SelectUnit.js +12 -0
- package/src/screens/AddLocationMaps/index.js +139 -44
- package/src/screens/AddLocationMaps/indexStyle.js +14 -12
- package/src/screens/AddNewAction/SelectAction.js +1 -0
- package/src/screens/Automate/MultiUnits.js +8 -8
- package/src/screens/Automate/__test__/MultiUnits.test.js +2 -2
- package/src/screens/Automate/__test__/index.test.js +2 -0
- package/src/screens/Automate/index.js +4 -2
- package/src/screens/Device/__test__/detail.test.js +3 -7
- package/src/screens/Device/components/SensorDisplayItem.js +10 -10
- package/src/screens/Device/detail.js +65 -15
- package/src/screens/Device/hooks/useDisconnectedDevice.js +32 -26
- 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 +90 -0
- package/src/screens/EmergencySetting/styles/DropDownItem.js +38 -0
- package/src/screens/EmergencySetting/styles.js +19 -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/Notification/__test__/Notification.test.js +3 -3
- package/src/screens/Notification/components/NotificationItem.js +3 -6
- package/src/screens/Notification/index.js +2 -2
- package/src/screens/ScriptDetail/Styles/indexStyles.js +0 -1
- package/src/screens/ScriptDetail/__test__/index.test.js +13 -0
- package/src/screens/ScriptDetail/index.js +20 -17
- package/src/screens/SelectUnit/index.js +2 -0
- package/src/screens/Sharing/MemberList.js +2 -9
- package/src/screens/SubUnit/AddSubUnit.js +79 -59
- package/src/screens/SubUnit/AddSubUnitStyles.js +0 -2
- package/src/screens/SubUnit/__test__/AddSubUnit.test.js +4 -3
- package/src/screens/TDSGuide/index.js +6 -4
- package/src/screens/Unit/ChooseLocation.js +96 -0
- package/src/screens/Unit/ChooseLocationStyles.js +26 -0
- package/src/screens/Unit/Detail.js +14 -2
- package/src/screens/Unit/ManageUnit.js +4 -5
- package/src/screens/Unit/SelectAddress.js +240 -0
- package/src/screens/Unit/SelectAddressStyles.js +48 -0
- package/src/screens/Unit/SmartAccountItem.js +1 -1
- package/src/screens/Unit/Summaries.js +5 -1
- package/src/screens/Unit/__test__/ChooseLocation.test.js +112 -0
- package/src/screens/Unit/__test__/SelectAddress.test.js +216 -0
- package/src/screens/Unit/components/MyUnitDevice/index.js +21 -5
- package/src/screens/Unit/hook/useStateAlertRemove.js +3 -1
- package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +2 -2
- package/src/screens/UnitSummary/components/PowerConsumption/index.js +3 -2
- package/src/screens/UnitSummary/components/WaterQuality/Item/index.js +1 -3
- package/src/screens/UnitSummary/index.js +3 -2
- package/src/screens/WaterQualityGuide/index.js +1 -0
- package/src/utils/Apis/axios.js +17 -5
- package/src/utils/I18n/translations/en.json +19 -4
- package/src/utils/I18n/translations/vi.json +22 -7
- package/src/utils/Route/index.js +4 -1
- package/src/utils/Utils.js +22 -2
- package/assets/images/AddLocationMaps/PinLocation.svg +0 -3
- package/assets/images/AddLocationMaps/Point.svg +0 -3
- 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 -231
- package/src/commons/ThreeButtonHistory/index.js +0 -281
- package/src/commons/ThreeButtonHistory/styles.js +0 -65
- package/src/screens/Unit/ManageUnit/index.js +0 -286
- package/src/screens/Unit/SelectLocation.js +0 -161
- package/src/screens/Unit/SelectLocationStyles.js +0 -114
|
@@ -4,10 +4,11 @@ import { Alert, Linking, Platform } from 'react-native';
|
|
|
4
4
|
import { useTranslations } from '../../../hooks/Common/useTranslations';
|
|
5
5
|
import {
|
|
6
6
|
enableBluetoothForAndroid,
|
|
7
|
-
|
|
7
|
+
useIsBluetoothEnabled,
|
|
8
8
|
} from '../../../iot/RemoteControl/Bluetooth';
|
|
9
|
+
import { ToastBottomHelper } from '../../../utils/Utils';
|
|
9
10
|
|
|
10
|
-
export const useDisconnectedDevice = (
|
|
11
|
+
export const useDisconnectedDevice = (sensorName, isDeviceHasBle) => {
|
|
11
12
|
const t = useTranslations();
|
|
12
13
|
const openBluetoothIOS = () => {
|
|
13
14
|
Linking.openURL('App-Prefs:Bluetooth');
|
|
@@ -32,32 +33,37 @@ export const useDisconnectedDevice = (isConnected, sensorName) => {
|
|
|
32
33
|
onPress: () => enableBluetoothForAndroid(),
|
|
33
34
|
},
|
|
34
35
|
];
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
36
|
+
|
|
37
|
+
const netState = NetInfo.useNetInfo();
|
|
38
|
+
const isBluetoothEnabled = useIsBluetoothEnabled();
|
|
39
|
+
|
|
40
|
+
const checkNetWorkConnect = useCallback(
|
|
41
|
+
async (isHavingInternet, isBtEnabled) => {
|
|
42
|
+
if (isHavingInternet === false && isDeviceHasBle) {
|
|
43
|
+
// TODO avoid case first render isHavingInternet == null
|
|
44
|
+
if (isBtEnabled === true) {
|
|
45
|
+
ToastBottomHelper.info(
|
|
46
|
+
t('your_internet_is_disconnected', { name: sensorName }),
|
|
47
|
+
t('change_to_control_via_bluetooth_connection', {
|
|
48
|
+
name: sensorName,
|
|
49
|
+
})
|
|
50
|
+
);
|
|
51
|
+
} else if (isBtEnabled === false) {
|
|
52
|
+
Alert.alert(
|
|
53
|
+
'',
|
|
54
|
+
t(
|
|
55
|
+
'your_connection_to_the_server_was_disconnected_please_open_the_bluetooth_to_continue'
|
|
56
|
+
),
|
|
57
|
+
actions
|
|
58
|
+
);
|
|
59
|
+
}
|
|
55
60
|
}
|
|
56
|
-
}
|
|
61
|
+
},
|
|
57
62
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
58
|
-
|
|
63
|
+
[isDeviceHasBle]
|
|
64
|
+
);
|
|
59
65
|
|
|
60
66
|
useEffect(() => {
|
|
61
|
-
checkNetWorkConnect();
|
|
62
|
-
}, [checkNetWorkConnect]);
|
|
67
|
+
checkNetWorkConnect(netState.isConnected, isBluetoothEnabled);
|
|
68
|
+
}, [netState.isConnected, isBluetoothEnabled, checkNetWorkConnect]);
|
|
63
69
|
};
|
|
@@ -32,7 +32,7 @@ export default StyleSheet.create({
|
|
|
32
32
|
},
|
|
33
33
|
bottomButtonEmergencyContact: {
|
|
34
34
|
marginHorizontal: 16,
|
|
35
|
-
marginBottom:
|
|
35
|
+
marginBottom: 40,
|
|
36
36
|
},
|
|
37
37
|
locationName: {
|
|
38
38
|
flex: 1,
|
|
@@ -77,10 +77,10 @@ export default StyleSheet.create({
|
|
|
77
77
|
buttonStar: {
|
|
78
78
|
justifyContent: 'center',
|
|
79
79
|
alignItems: 'center',
|
|
80
|
+
marginRight: 14,
|
|
80
81
|
},
|
|
81
82
|
button: {
|
|
82
|
-
|
|
83
|
-
height: 40,
|
|
83
|
+
marginRight: 10,
|
|
84
84
|
justifyContent: 'center',
|
|
85
85
|
alignItems: 'center',
|
|
86
86
|
},
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { create, act } from 'react-test-renderer';
|
|
3
|
+
import { TouchableOpacity } from 'react-native';
|
|
4
|
+
|
|
5
|
+
import { SCProvider } from '../../../context';
|
|
6
|
+
import { mockSCStore } from '../../../context/mockStore';
|
|
7
|
+
import DropDownItem from '../components/DropDownItem';
|
|
8
|
+
import Text from '../../../commons/Text';
|
|
9
|
+
import { TESTID } from '../../../configs/Constants';
|
|
10
|
+
|
|
11
|
+
const mockonOpen = jest.fn();
|
|
12
|
+
|
|
13
|
+
const wrapComponent = (props) => (
|
|
14
|
+
<SCProvider initState={mockSCStore({})}>
|
|
15
|
+
<DropDownItem {...props} />
|
|
16
|
+
</SCProvider>
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
describe('Test DropDownItem', () => {
|
|
20
|
+
let tree;
|
|
21
|
+
|
|
22
|
+
test('test render DropDownItem', () => {
|
|
23
|
+
const props = {
|
|
24
|
+
label: 'mode',
|
|
25
|
+
data: [{ label: 'Stop (0)', value: 'stop' }],
|
|
26
|
+
isOpen: true,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
act(() => {
|
|
30
|
+
tree = create(wrapComponent(props));
|
|
31
|
+
});
|
|
32
|
+
const instance = tree.root;
|
|
33
|
+
const dropDownPicker = instance.findAll(
|
|
34
|
+
(el) =>
|
|
35
|
+
el.props.testID === TESTID.DROP_DOWN_PICKER_ITEM && el.type === Text
|
|
36
|
+
);
|
|
37
|
+
expect(dropDownPicker).toHaveLength(1);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('test onPress DropDown', () => {
|
|
41
|
+
const props = {
|
|
42
|
+
label: 'mode',
|
|
43
|
+
data: [{ label: 'Stop (0)', value: 'stop' }],
|
|
44
|
+
onOpen: mockonOpen,
|
|
45
|
+
index: 0,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
act(() => {
|
|
49
|
+
tree = create(wrapComponent(props));
|
|
50
|
+
});
|
|
51
|
+
const instance = tree.root;
|
|
52
|
+
const touchableOpacity = instance.findByType(TouchableOpacity);
|
|
53
|
+
act(() => {
|
|
54
|
+
touchableOpacity.props.onPress();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
expect(mockonOpen).toHaveBeenCalledWith(props.index);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { create, act } from 'react-test-renderer';
|
|
3
|
+
|
|
4
|
+
import { SCProvider } from '../../../context';
|
|
5
|
+
import { mockSCStore } from '../../../context/mockStore';
|
|
6
|
+
import EmergencySetting from '..';
|
|
7
|
+
import DropDownItem from '../components/DropDownItem';
|
|
8
|
+
|
|
9
|
+
const wrapComponent = () => (
|
|
10
|
+
<SCProvider initState={mockSCStore({})}>
|
|
11
|
+
<EmergencySetting />
|
|
12
|
+
</SCProvider>
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
describe('test EmergencySetting', () => {
|
|
16
|
+
let tree;
|
|
17
|
+
|
|
18
|
+
test('test render EmergencySetting', () => {
|
|
19
|
+
act(() => {
|
|
20
|
+
tree = create(wrapComponent());
|
|
21
|
+
});
|
|
22
|
+
const instance = tree.root;
|
|
23
|
+
const dropDownItem = instance.findAllByType(DropDownItem);
|
|
24
|
+
|
|
25
|
+
expect(dropDownItem.length).toEqual(3);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React, { useCallback, useState } from 'react';
|
|
2
|
+
import { View, TouchableOpacity } from 'react-native';
|
|
3
|
+
import { IconFill } from '@ant-design/icons-react-native';
|
|
4
|
+
|
|
5
|
+
import Text from '../../../commons/Text';
|
|
6
|
+
import styles from '../styles/DropDownItem';
|
|
7
|
+
import { Colors } from '../../../configs';
|
|
8
|
+
import { TESTID } from '../../../configs/Constants';
|
|
9
|
+
|
|
10
|
+
const DropDownItem = ({ label, data, onSelectItem, isOpen, onOpen, index }) => {
|
|
11
|
+
const [selecteValue, setSelectValue] = useState(data[0] || {});
|
|
12
|
+
|
|
13
|
+
const handleSelectItem = useCallback(
|
|
14
|
+
(item) => () => {
|
|
15
|
+
setSelectValue(item);
|
|
16
|
+
onSelectItem && onSelectItem();
|
|
17
|
+
},
|
|
18
|
+
[onSelectItem]
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
const handleOnOpen = useCallback(() => {
|
|
22
|
+
onOpen && onOpen(index);
|
|
23
|
+
}, [index, onOpen]);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
// eslint-disable-next-line react-native/no-inline-styles
|
|
27
|
+
<View style={[styles.wrap, { zIndex: isOpen ? 1 : 0 }]}>
|
|
28
|
+
{label && <Text>{label}</Text>}
|
|
29
|
+
<View style={styles.dropDownContainer}>
|
|
30
|
+
<TouchableOpacity style={styles.dropDownStyle} onPress={handleOnOpen}>
|
|
31
|
+
<Text>{selecteValue?.label}</Text>
|
|
32
|
+
<IconFill name="caret-down" size={18} color={Colors.Gray8} />
|
|
33
|
+
</TouchableOpacity>
|
|
34
|
+
|
|
35
|
+
{isOpen && (
|
|
36
|
+
<View style={[styles.dropDownItem]}>
|
|
37
|
+
{data.map((item, index) => (
|
|
38
|
+
<Text
|
|
39
|
+
style={styles.dropDownText}
|
|
40
|
+
onPress={handleSelectItem(item)}
|
|
41
|
+
key={index}
|
|
42
|
+
testID={TESTID.DROP_DOWN_PICKER_ITEM}
|
|
43
|
+
>
|
|
44
|
+
{item?.label}
|
|
45
|
+
</Text>
|
|
46
|
+
))}
|
|
47
|
+
</View>
|
|
48
|
+
)}
|
|
49
|
+
</View>
|
|
50
|
+
</View>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export default DropDownItem;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import React, { useState, useCallback, useMemo } from 'react';
|
|
2
|
+
import { View, ScrollView } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
5
|
+
|
|
6
|
+
import { HeaderCustom } from '../../commons/Header';
|
|
7
|
+
import DropDownItem from './components/DropDownItem';
|
|
8
|
+
import _TextInput from '../../commons/Form/TextInput';
|
|
9
|
+
|
|
10
|
+
import styles from './styles';
|
|
11
|
+
|
|
12
|
+
const EmergencySetting = () => {
|
|
13
|
+
const t = useTranslations();
|
|
14
|
+
const [openedDropdown, setOpenedDropdown] = useState(null);
|
|
15
|
+
const [duration, setDuration] = useState('');
|
|
16
|
+
|
|
17
|
+
const onChangeDuration = useCallback((text) => {
|
|
18
|
+
setDuration(text);
|
|
19
|
+
}, []);
|
|
20
|
+
|
|
21
|
+
const listData = useMemo(() => {
|
|
22
|
+
return [
|
|
23
|
+
{
|
|
24
|
+
label: t('mode'),
|
|
25
|
+
data: [
|
|
26
|
+
{ label: 'Stop (0)', value: 'stop' },
|
|
27
|
+
{ label: 'Stop (1)', value: 'stop' },
|
|
28
|
+
{ label: 'Stop (2)', value: 'stop' },
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
label: t('level'),
|
|
33
|
+
data: [
|
|
34
|
+
{ label: 'Low', value: 'low' },
|
|
35
|
+
{ label: 'High', value: 'High' },
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
label: t('strobe'),
|
|
40
|
+
data: [
|
|
41
|
+
{ label: 'True', value: 'true' },
|
|
42
|
+
{ label: 'False', value: 'true' },
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
}, [t]);
|
|
47
|
+
|
|
48
|
+
const handleOnOpen = useCallback((index) => {
|
|
49
|
+
setOpenedDropdown((oldIndex) => {
|
|
50
|
+
if (index === oldIndex) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
return index;
|
|
54
|
+
});
|
|
55
|
+
}, []);
|
|
56
|
+
|
|
57
|
+
const handleOnSelectItem = useCallback(() => {
|
|
58
|
+
setOpenedDropdown(null);
|
|
59
|
+
}, []);
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<View style={styles.wrap}>
|
|
63
|
+
<HeaderCustom title={t('setting')} isShowSeparator />
|
|
64
|
+
|
|
65
|
+
<ScrollView contentContainerStyle={styles.contentContainerStyle}>
|
|
66
|
+
{listData.map((item, index) => (
|
|
67
|
+
<DropDownItem
|
|
68
|
+
{...item}
|
|
69
|
+
key={index}
|
|
70
|
+
index={index}
|
|
71
|
+
onOpen={handleOnOpen}
|
|
72
|
+
isOpen={openedDropdown === index}
|
|
73
|
+
onSelectItem={handleOnSelectItem}
|
|
74
|
+
/>
|
|
75
|
+
))}
|
|
76
|
+
|
|
77
|
+
<_TextInput
|
|
78
|
+
wrapStyle={styles.wrapInput}
|
|
79
|
+
textInputStyle={styles.textInputStyle}
|
|
80
|
+
keyboardType="numeric"
|
|
81
|
+
onChange={onChangeDuration}
|
|
82
|
+
value={duration}
|
|
83
|
+
placeholder="0"
|
|
84
|
+
/>
|
|
85
|
+
</ScrollView>
|
|
86
|
+
</View>
|
|
87
|
+
);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export default EmergencySetting;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
import { Colors } from '../../../configs';
|
|
3
|
+
|
|
4
|
+
export default StyleSheet.create({
|
|
5
|
+
wrap: {
|
|
6
|
+
paddingHorizontal: 16,
|
|
7
|
+
paddingTop: 16,
|
|
8
|
+
},
|
|
9
|
+
dropDownContainer: {
|
|
10
|
+
marginTop: 8,
|
|
11
|
+
},
|
|
12
|
+
dropDownStyle: {
|
|
13
|
+
flexDirection: 'row',
|
|
14
|
+
justifyContent: 'space-between',
|
|
15
|
+
alignItems: 'center',
|
|
16
|
+
borderColor: Colors.Gray5,
|
|
17
|
+
borderRadius: 2,
|
|
18
|
+
borderWidth: 1,
|
|
19
|
+
paddingHorizontal: 16,
|
|
20
|
+
paddingVertical: 8,
|
|
21
|
+
},
|
|
22
|
+
dropDownItem: {
|
|
23
|
+
borderColor: Colors.Gray5,
|
|
24
|
+
borderRadius: 2,
|
|
25
|
+
borderTopWidth: 0,
|
|
26
|
+
borderWidth: 1,
|
|
27
|
+
paddingHorizontal: 16,
|
|
28
|
+
paddingBottom: 8,
|
|
29
|
+
backgroundColor: Colors.White,
|
|
30
|
+
position: 'absolute',
|
|
31
|
+
width: '100%',
|
|
32
|
+
top: 44,
|
|
33
|
+
left: 0,
|
|
34
|
+
},
|
|
35
|
+
dropDownText: {
|
|
36
|
+
marginTop: 8,
|
|
37
|
+
},
|
|
38
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
import { Colors } from '../../configs';
|
|
3
|
+
|
|
4
|
+
export default StyleSheet.create({
|
|
5
|
+
wrap: {
|
|
6
|
+
flex: 1,
|
|
7
|
+
backgroundColor: Colors.White,
|
|
8
|
+
},
|
|
9
|
+
contentContainerStyle: {
|
|
10
|
+
flexGrow: 1,
|
|
11
|
+
},
|
|
12
|
+
wrapInput: {
|
|
13
|
+
paddingHorizontal: 16,
|
|
14
|
+
},
|
|
15
|
+
textInputStyle: {
|
|
16
|
+
paddingTop: 8,
|
|
17
|
+
paddingBottom: 8,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import { create } from 'react-test-renderer';
|
|
4
|
+
import { act } from '@testing-library/react-hooks';
|
|
5
|
+
|
|
6
|
+
import { TESTID } from '../../../configs/Constants';
|
|
7
|
+
import { API } from '../../../configs';
|
|
8
|
+
import MoveToAnotherSubUnit from '../';
|
|
9
|
+
import { SCProvider } from '../../../context';
|
|
10
|
+
import { mockSCStore } from '../../../context/mockStore';
|
|
11
|
+
import BottomButtonView from '../../../commons/BottomButtonView';
|
|
12
|
+
|
|
13
|
+
jest.mock('axios');
|
|
14
|
+
jest.mock('react', () => {
|
|
15
|
+
return {
|
|
16
|
+
...jest.requireActual('react'),
|
|
17
|
+
memo: (x) => x,
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const wrapComponent = (route) => (
|
|
22
|
+
<SCProvider initState={mockSCStore({})}>
|
|
23
|
+
<MoveToAnotherSubUnit route={route} />
|
|
24
|
+
</SCProvider>
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
describe('Test Render ListSubUnit', () => {
|
|
28
|
+
let tree;
|
|
29
|
+
let route = {
|
|
30
|
+
params: {
|
|
31
|
+
unit: {
|
|
32
|
+
id: 200,
|
|
33
|
+
stations: [
|
|
34
|
+
{
|
|
35
|
+
id: 1,
|
|
36
|
+
name: 'Favourite',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: 2,
|
|
40
|
+
name: 'Sceriano',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: 3,
|
|
44
|
+
name: 'Room A',
|
|
45
|
+
sensors: [
|
|
46
|
+
{
|
|
47
|
+
action: null,
|
|
48
|
+
action2: null,
|
|
49
|
+
chip_id: 40,
|
|
50
|
+
description: null,
|
|
51
|
+
icon: '',
|
|
52
|
+
icon_kit: '',
|
|
53
|
+
id: 73,
|
|
54
|
+
is_managed_by_backend: true,
|
|
55
|
+
is_other_device: false,
|
|
56
|
+
name: 'Multi-Air Quality',
|
|
57
|
+
quick_action: null,
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: 4,
|
|
63
|
+
name: 'Room 2',
|
|
64
|
+
sensors: [],
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
station: {
|
|
69
|
+
id: 3,
|
|
70
|
+
name: 'Room 1',
|
|
71
|
+
},
|
|
72
|
+
sensor: {
|
|
73
|
+
action: null,
|
|
74
|
+
action2: null,
|
|
75
|
+
chip_id: 40,
|
|
76
|
+
description: null,
|
|
77
|
+
icon: '',
|
|
78
|
+
icon_kit: '',
|
|
79
|
+
id: 73,
|
|
80
|
+
is_managed_by_backend: true,
|
|
81
|
+
is_other_device: false,
|
|
82
|
+
name: 'Multi-Air Quality',
|
|
83
|
+
quick_action: null,
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
it('render ListSubUnit', async () => {
|
|
89
|
+
await act(async () => {
|
|
90
|
+
tree = await create(wrapComponent(route));
|
|
91
|
+
});
|
|
92
|
+
const instance = tree.root;
|
|
93
|
+
const rowSubUnit = instance.findAll(
|
|
94
|
+
(el) => el.props.testID === TESTID.ROW_SUB_UNIT
|
|
95
|
+
);
|
|
96
|
+
expect(rowSubUnit).toHaveLength(2);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('test move sensor', async () => {
|
|
100
|
+
await act(async () => {
|
|
101
|
+
tree = await create(wrapComponent(route));
|
|
102
|
+
});
|
|
103
|
+
const instance = tree.root;
|
|
104
|
+
const bottomButtonView = instance.findByType(BottomButtonView);
|
|
105
|
+
const rowSubUnit = instance.findAll(
|
|
106
|
+
(el) => el.props.testID === TESTID.ROW_SUB_UNIT
|
|
107
|
+
);
|
|
108
|
+
act(() => {
|
|
109
|
+
rowSubUnit[1].props.onSelect({
|
|
110
|
+
id: 4,
|
|
111
|
+
name: 'Room 2',
|
|
112
|
+
sensors: [],
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
act(() => {
|
|
116
|
+
bottomButtonView.props.onPressMain();
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
expect(axios.patch).toHaveBeenCalledWith(
|
|
120
|
+
API.SENSOR.CHANGE_SUB_UNIT(200, 3, 73),
|
|
121
|
+
{
|
|
122
|
+
station_id: 4,
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import React, { useState, useCallback, memo, useMemo } from 'react';
|
|
2
|
+
import { View, ScrollView, TouchableOpacity } from 'react-native';
|
|
3
|
+
import { useNavigation } from '@react-navigation/native';
|
|
4
|
+
|
|
5
|
+
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
6
|
+
import { HeaderCustom } from '../../commons/Header';
|
|
7
|
+
import styles from './styles/MoveToAnotherSubUnitStyles';
|
|
8
|
+
import { Colors } from '../../configs';
|
|
9
|
+
import Text from '../../commons/Text';
|
|
10
|
+
import RadioCircle from '../../commons/RadioCircle';
|
|
11
|
+
import BottomButtonView from '../../commons/BottomButtonView';
|
|
12
|
+
import Routes from '../../utils/Route';
|
|
13
|
+
import { axiosPatch } from '../../utils/Apis/axios';
|
|
14
|
+
import { API } from '../../configs';
|
|
15
|
+
import { TESTID } from '../../configs/Constants';
|
|
16
|
+
|
|
17
|
+
const RowSubUnit = ({ subUnit, isSelected, onSelect }) => {
|
|
18
|
+
const handleOnPress = useCallback(() => {
|
|
19
|
+
onSelect(subUnit);
|
|
20
|
+
}, [onSelect, subUnit]);
|
|
21
|
+
return (
|
|
22
|
+
<TouchableOpacity style={styles.rowSubUnit} onPress={handleOnPress}>
|
|
23
|
+
<RadioCircle active={isSelected} />
|
|
24
|
+
<View style={styles.wrapText}>
|
|
25
|
+
<Text type="H4" color={Colors.Gray9}>
|
|
26
|
+
{subUnit.name}
|
|
27
|
+
</Text>
|
|
28
|
+
</View>
|
|
29
|
+
</TouchableOpacity>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const MoveToAnotherSubUnit = memo(({ route }) => {
|
|
34
|
+
const t = useTranslations();
|
|
35
|
+
const { params = {} } = route;
|
|
36
|
+
const { unit, sensor, station } = params;
|
|
37
|
+
const { navigate } = useNavigation();
|
|
38
|
+
const [selectedSubUnit, setSelectedSubUnit] = useState(station);
|
|
39
|
+
|
|
40
|
+
const listStationUnit = useMemo(() => {
|
|
41
|
+
return unit.stations.slice(2);
|
|
42
|
+
}, [unit.stations]);
|
|
43
|
+
|
|
44
|
+
const handleOnSelect = useCallback((item) => {
|
|
45
|
+
setSelectedSubUnit(item);
|
|
46
|
+
}, []);
|
|
47
|
+
|
|
48
|
+
const onSubmit = useCallback(async () => {
|
|
49
|
+
const { success } = await axiosPatch(
|
|
50
|
+
API.SENSOR.CHANGE_SUB_UNIT(unit.id, station.id, sensor.id),
|
|
51
|
+
{
|
|
52
|
+
station_id: selectedSubUnit.id,
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
if (success) {
|
|
56
|
+
navigate(Routes.UnitDetail);
|
|
57
|
+
}
|
|
58
|
+
}, [navigate, selectedSubUnit.id, sensor.id, station.id, unit.id]);
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<View style={styles.wrap}>
|
|
62
|
+
<HeaderCustom title={t('move_to_another_sub_unit')} isShowSeparator />
|
|
63
|
+
<ScrollView>
|
|
64
|
+
<View style={styles.container}>
|
|
65
|
+
<View>
|
|
66
|
+
{listStationUnit.map((item, index) => (
|
|
67
|
+
<RowSubUnit
|
|
68
|
+
subUnit={item}
|
|
69
|
+
isSelected={selectedSubUnit === item}
|
|
70
|
+
onSelect={handleOnSelect}
|
|
71
|
+
testID={TESTID.ROW_SUB_UNIT}
|
|
72
|
+
key={index}
|
|
73
|
+
/>
|
|
74
|
+
))}
|
|
75
|
+
</View>
|
|
76
|
+
</View>
|
|
77
|
+
</ScrollView>
|
|
78
|
+
<BottomButtonView
|
|
79
|
+
style={styles.bottomButtonView}
|
|
80
|
+
mainTitle={t('text_submit')}
|
|
81
|
+
onPressMain={onSubmit}
|
|
82
|
+
typeMain={'primary'}
|
|
83
|
+
/>
|
|
84
|
+
</View>
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
export default MoveToAnotherSubUnit;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Colors } from '../../../configs';
|
|
2
|
+
import { StyleSheet } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export default StyleSheet.create({
|
|
5
|
+
container: {
|
|
6
|
+
paddingHorizontal: 16,
|
|
7
|
+
},
|
|
8
|
+
wrap: {
|
|
9
|
+
flex: 1,
|
|
10
|
+
backgroundColor: Colors.White,
|
|
11
|
+
},
|
|
12
|
+
rowSubUnit: {
|
|
13
|
+
flexDirection: 'row',
|
|
14
|
+
alignItems: 'center',
|
|
15
|
+
},
|
|
16
|
+
wrapText: {
|
|
17
|
+
flex: 1,
|
|
18
|
+
marginRight: 24,
|
|
19
|
+
marginLeft: 16,
|
|
20
|
+
paddingVertical: 16,
|
|
21
|
+
borderBottomWidth: 1,
|
|
22
|
+
borderBottomColor: Colors.Gray4,
|
|
23
|
+
},
|
|
24
|
+
content: {
|
|
25
|
+
margin: 16,
|
|
26
|
+
},
|
|
27
|
+
textLeft: {
|
|
28
|
+
borderColor: Colors.Gray9,
|
|
29
|
+
fontWeight: 'bold',
|
|
30
|
+
fontSize: 16,
|
|
31
|
+
},
|
|
32
|
+
textRight: {
|
|
33
|
+
borderColor: Colors.Gray7,
|
|
34
|
+
fontSize: 14,
|
|
35
|
+
},
|
|
36
|
+
separator: {
|
|
37
|
+
height: 1,
|
|
38
|
+
width: '100%',
|
|
39
|
+
borderBottomWidth: 1,
|
|
40
|
+
borderColor: Colors.Gray4,
|
|
41
|
+
marginBottom: 16,
|
|
42
|
+
},
|
|
43
|
+
bottomButtonView: {
|
|
44
|
+
paddingTop: 24,
|
|
45
|
+
paddingBottom: 32,
|
|
46
|
+
backgroundColor: Colors.White,
|
|
47
|
+
borderColor: Colors.ShadownTransparent,
|
|
48
|
+
borderTopWidth: 1,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
@@ -64,7 +64,7 @@ describe('test Notification', () => {
|
|
|
64
64
|
|
|
65
65
|
expect(notificationItem).toHaveLength(2);
|
|
66
66
|
expect(axios.get).toHaveBeenCalledWith(
|
|
67
|
-
API.NOTIFICATION.
|
|
67
|
+
API.NOTIFICATION.LIST_EOH_NOTIFICATIONS(1, ''),
|
|
68
68
|
{}
|
|
69
69
|
);
|
|
70
70
|
});
|
|
@@ -108,7 +108,7 @@ describe('test Notification', () => {
|
|
|
108
108
|
scrollView.props.onMomentumScrollEnd();
|
|
109
109
|
});
|
|
110
110
|
expect(axios.get).toHaveBeenCalledWith(
|
|
111
|
-
API.NOTIFICATION.
|
|
111
|
+
API.NOTIFICATION.LIST_EOH_NOTIFICATIONS(1, ''),
|
|
112
112
|
{}
|
|
113
113
|
);
|
|
114
114
|
});
|
|
@@ -152,7 +152,7 @@ describe('test Notification', () => {
|
|
|
152
152
|
refreshControl.props.onRefresh();
|
|
153
153
|
});
|
|
154
154
|
expect(axios.get).toHaveBeenCalledWith(
|
|
155
|
-
API.NOTIFICATION.
|
|
155
|
+
API.NOTIFICATION.LIST_EOH_NOTIFICATIONS(1, ''),
|
|
156
156
|
{}
|
|
157
157
|
);
|
|
158
158
|
});
|