@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.
Files changed (126) hide show
  1. package/assets/images/Map/MarkerGeolocation.svg +4 -0
  2. package/assets/images/SonosSpeaker/buttonpause-active.svg +3 -0
  3. package/assets/images/SonosSpeaker/buttonpause-notactive.svg +3 -0
  4. package/assets/images/SonosSpeaker/picture-main-notactive.svg +5 -0
  5. package/assets/images/SonosSpeaker/picture-main.svg +6 -0
  6. package/assets/images/SonosSpeaker/picture-volume.svg +3 -0
  7. package/package.json +4 -22
  8. package/src/Images/Common/buttonLeftCurtain.png +0 -0
  9. package/src/Images/Common/buttonPause-center-curtain.png +0 -0
  10. package/src/Images/Common/buttonRightCurtain.png +0 -0
  11. package/src/commons/ActionGroup/CurtainButtonTemplate.js +139 -0
  12. package/src/commons/ActionGroup/CurtainButtonTemplateStyle.js +58 -0
  13. package/src/commons/ActionGroup/__test__/CurtainButtonTemplate.test.js +72 -0
  14. package/src/commons/ActionGroup/index.js +3 -0
  15. package/src/commons/Auth/__test__/AccountList.test.js +33 -0
  16. package/src/commons/CameraDevice/index.js +2 -0
  17. package/src/commons/CardShadow/index.js +1 -1
  18. package/src/commons/CardShadow/styles.js +1 -3
  19. package/src/commons/DateTimeRangeChange/DateTimeButton.js +1 -1
  20. package/src/commons/DateTimeRangeChange/index.js +2 -2
  21. package/src/commons/Device/HistoryChart.js +21 -55
  22. package/src/commons/Device/HorizontalBarChart.js +46 -30
  23. package/src/commons/Device/LinearChart.js +0 -34
  24. package/src/commons/Device/PMSensor/PMSensorIndicatior.js +1 -1
  25. package/src/commons/Device/PMSensor/PMSensorIndicatorStyles.js +2 -1
  26. package/src/commons/Device/SonosSpeaker/__test__/SonosSpeaker.test.js +57 -0
  27. package/src/commons/Device/SonosSpeaker/index.js +88 -0
  28. package/src/commons/Device/SonosSpeaker/styles.js +57 -0
  29. package/src/commons/Form/CurrencyInput.js +169 -0
  30. package/src/commons/Form/__test__/CurrencyInput.test.js +65 -0
  31. package/src/commons/FourButtonFilterHistory/__test__/FourButtonFilterHistory.test.js +48 -0
  32. package/src/commons/FourButtonFilterHistory/index.js +72 -0
  33. package/src/commons/FourButtonFilterHistory/styles.js +22 -0
  34. package/src/commons/MediaPlayerDetail/Styles/MediaPlayerDetailStyles.js +14 -0
  35. package/src/commons/MediaPlayerDetail/index.js +204 -161
  36. package/src/commons/SearchLocation/index.js +0 -1
  37. package/src/commons/Sharing/RowMember.js +7 -2
  38. package/src/commons/Sharing/__test__/RowMember.test.js +42 -0
  39. package/src/commons/SubUnit/ShortDetail.js +12 -6
  40. package/src/commons/UnitSummary/AirQuality/SegmentedRoundDisplay/index.js +1 -1
  41. package/src/commons/UnitSummary/ConfigHistoryChart.js +2 -1
  42. package/src/configs/API.js +13 -3
  43. package/src/configs/Constants.js +14 -4
  44. package/src/configs/Images.js +3 -0
  45. package/src/configs/SCConfig.js +8 -0
  46. package/src/context/actionType.ts +5 -0
  47. package/src/context/mockStore.ts +3 -0
  48. package/src/context/reducer.ts +14 -0
  49. package/src/iot/RemoteControl/Bluetooth.js +14 -0
  50. package/src/iot/RemoteControl/index.js +0 -1
  51. package/src/navigations/UnitStack.js +42 -4
  52. package/src/screens/ActivityLog/FilterPopup.js +1 -1
  53. package/src/screens/ActivityLog/ItemLog.js +11 -2
  54. package/src/screens/ActivityLog/__test__/ItemLog.test.js +46 -0
  55. package/src/screens/ActivityLog/hooks/index.js +1 -0
  56. package/src/screens/ActivityLog/index.js +0 -1
  57. package/src/screens/AddCommon/SelectSubUnit.js +24 -2
  58. package/src/screens/AddCommon/SelectUnit.js +12 -0
  59. package/src/screens/AddLocationMaps/index.js +139 -44
  60. package/src/screens/AddLocationMaps/indexStyle.js +14 -12
  61. package/src/screens/AddNewAction/SelectAction.js +1 -0
  62. package/src/screens/Automate/MultiUnits.js +8 -8
  63. package/src/screens/Automate/__test__/MultiUnits.test.js +2 -2
  64. package/src/screens/Automate/__test__/index.test.js +2 -0
  65. package/src/screens/Automate/index.js +4 -2
  66. package/src/screens/Device/__test__/detail.test.js +3 -7
  67. package/src/screens/Device/components/SensorDisplayItem.js +10 -10
  68. package/src/screens/Device/detail.js +65 -15
  69. package/src/screens/Device/hooks/useDisconnectedDevice.js +32 -26
  70. package/src/screens/Device/styles.js +3 -3
  71. package/src/screens/EmergencySetting/__test__/DropDownItem.test.js +59 -0
  72. package/src/screens/EmergencySetting/__test__/index.test.js +27 -0
  73. package/src/screens/EmergencySetting/components/DropDownItem.js +54 -0
  74. package/src/screens/EmergencySetting/index.js +90 -0
  75. package/src/screens/EmergencySetting/styles/DropDownItem.js +38 -0
  76. package/src/screens/EmergencySetting/styles.js +19 -0
  77. package/src/screens/MoveToAnotherSubUnit/__test__/index.test.js +126 -0
  78. package/src/screens/MoveToAnotherSubUnit/index.js +88 -0
  79. package/src/screens/MoveToAnotherSubUnit/styles/MoveToAnotherSubUnitStyles.js +50 -0
  80. package/src/screens/Notification/__test__/Notification.test.js +3 -3
  81. package/src/screens/Notification/components/NotificationItem.js +3 -6
  82. package/src/screens/Notification/index.js +2 -2
  83. package/src/screens/ScriptDetail/Styles/indexStyles.js +0 -1
  84. package/src/screens/ScriptDetail/__test__/index.test.js +13 -0
  85. package/src/screens/ScriptDetail/index.js +20 -17
  86. package/src/screens/SelectUnit/index.js +2 -0
  87. package/src/screens/Sharing/MemberList.js +2 -9
  88. package/src/screens/SubUnit/AddSubUnit.js +79 -59
  89. package/src/screens/SubUnit/AddSubUnitStyles.js +0 -2
  90. package/src/screens/SubUnit/__test__/AddSubUnit.test.js +4 -3
  91. package/src/screens/TDSGuide/index.js +6 -4
  92. package/src/screens/Unit/ChooseLocation.js +96 -0
  93. package/src/screens/Unit/ChooseLocationStyles.js +26 -0
  94. package/src/screens/Unit/Detail.js +14 -2
  95. package/src/screens/Unit/ManageUnit.js +4 -5
  96. package/src/screens/Unit/SelectAddress.js +240 -0
  97. package/src/screens/Unit/SelectAddressStyles.js +48 -0
  98. package/src/screens/Unit/SmartAccountItem.js +1 -1
  99. package/src/screens/Unit/Summaries.js +5 -1
  100. package/src/screens/Unit/__test__/ChooseLocation.test.js +112 -0
  101. package/src/screens/Unit/__test__/SelectAddress.test.js +216 -0
  102. package/src/screens/Unit/components/MyUnitDevice/index.js +21 -5
  103. package/src/screens/Unit/hook/useStateAlertRemove.js +3 -1
  104. package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +2 -2
  105. package/src/screens/UnitSummary/components/PowerConsumption/index.js +3 -2
  106. package/src/screens/UnitSummary/components/WaterQuality/Item/index.js +1 -3
  107. package/src/screens/UnitSummary/index.js +3 -2
  108. package/src/screens/WaterQualityGuide/index.js +1 -0
  109. package/src/utils/Apis/axios.js +17 -5
  110. package/src/utils/I18n/translations/en.json +19 -4
  111. package/src/utils/I18n/translations/vi.json +22 -7
  112. package/src/utils/Route/index.js +4 -1
  113. package/src/utils/Utils.js +22 -2
  114. package/assets/images/AddLocationMaps/PinLocation.svg +0 -3
  115. package/assets/images/AddLocationMaps/Point.svg +0 -3
  116. package/src/commons/ThreeButtonHistory/CalendarHeader.js +0 -35
  117. package/src/commons/ThreeButtonHistory/CalendarHeaderStyles.js +0 -17
  118. package/src/commons/ThreeButtonHistory/SelectMonth.js +0 -53
  119. package/src/commons/ThreeButtonHistory/SelectMonthStyles.js +0 -29
  120. package/src/commons/ThreeButtonHistory/__test__/SelectMonth.test.js +0 -37
  121. package/src/commons/ThreeButtonHistory/__test__/ThreeButtonHistory.test.js +0 -231
  122. package/src/commons/ThreeButtonHistory/index.js +0 -281
  123. package/src/commons/ThreeButtonHistory/styles.js +0 -65
  124. package/src/screens/Unit/ManageUnit/index.js +0 -286
  125. package/src/screens/Unit/SelectLocation.js +0 -161
  126. 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
- isBluetoothEnabled,
7
+ useIsBluetoothEnabled,
8
8
  } from '../../../iot/RemoteControl/Bluetooth';
9
+ import { ToastBottomHelper } from '../../../utils/Utils';
9
10
 
10
- export const useDisconnectedDevice = (isConnected, sensorName) => {
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
- const checkNetWorkConnect = useCallback(async () => {
36
- const netState = await NetInfo.fetch();
37
- if (!isConnected || !netState.isConnected) {
38
- const isBtEnabled = await isBluetoothEnabled();
39
- if (isBtEnabled) {
40
- Alert.alert(
41
- '',
42
- t(
43
- 'your_internet_is_disconnected_change_to_control_via_bluetooth_connection',
44
- { name: sensorName }
45
- )
46
- );
47
- } else {
48
- Alert.alert(
49
- '',
50
- t(
51
- 'your_connection_to_the_server_was_disconnected_please_open_the_bluetooth_to_continue'
52
- ),
53
- actions
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
- }, [isConnected]);
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: 32,
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
- width: 35,
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.LIST_ALL_NOTIFICATIONS(1, ''),
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.LIST_ALL_NOTIFICATIONS(1, ''),
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.LIST_ALL_NOTIFICATIONS(1, ''),
155
+ API.NOTIFICATION.LIST_EOH_NOTIFICATIONS(1, ''),
156
156
  {}
157
157
  );
158
158
  });