@eohjsc/react-native-smart-city 0.3.91 → 0.3.92

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 (204) hide show
  1. package/package.json +1 -1
  2. package/src/Images/Common/reorder.svg +3 -0
  3. package/src/commons/ActionGroup/OnOffSmartLock/AutoLock/AutoLockStyles.js +1 -1
  4. package/src/commons/ActionGroup/OnOffSmartLock/AutoLock/__test__/index.test.js +3 -1
  5. package/src/commons/ActionGroup/OnOffSmartLock/AutoLock/index.js +3 -3
  6. package/src/commons/ActionGroup/OnOffSmartLock/PasscodeList/__test__/index.test.js +3 -10
  7. package/src/commons/ActionGroup/OnOffSmartLock/PasscodeList/index.js +1 -0
  8. package/src/commons/ActionGroup/OnOffSmartLock/SetupGeneratePasscode/SetupGeneratePasscodeStyles.js +1 -1
  9. package/src/commons/ActionGroup/OnOffTemplate/SwitchButtonTemplate.js +13 -5
  10. package/src/commons/ActionGroup/SliderRangeTemplate.js +100 -69
  11. package/src/commons/ActionGroup/SliderRangeTemplateStyles.js +27 -27
  12. package/src/commons/ActionGroup/StatesGridActionTemplate.js +4 -1
  13. package/src/commons/ActionGroup/__test__/OnOffTemplate.test.js +4 -1
  14. package/src/commons/ActionGroup/__test__/SliderRangeTemplate.test.js +56 -0
  15. package/src/commons/ActionGroup/__test__/StatesGridActionTemplate.test.js +2 -2
  16. package/src/commons/ActionGroup/__test__/SwitchButtonTemplate.test.js +45 -8
  17. package/src/commons/ActionGroup/__test__/index.test.js +0 -19
  18. package/src/commons/ActionGroup/index.js +0 -3
  19. package/src/commons/ActionTemplate/CurtainAction.js +3 -3
  20. package/src/commons/ActionTemplate/CurtainActionStyles.js +1 -1
  21. package/src/commons/ActionTemplate/OnOffButtonAction.js +2 -2
  22. package/src/commons/ActionTemplate/OnOffButtonActionStyles.js +1 -1
  23. package/src/commons/ActionTemplate/OnOffSimpleAction.js +2 -2
  24. package/src/commons/ActionTemplate/OnOffSimpleActionStyles.js +1 -1
  25. package/src/commons/ActionTemplate/OnOffSmartLockAction.js +2 -2
  26. package/src/commons/ActionTemplate/OnOffSmartLockActionStyles.js +1 -1
  27. package/src/commons/ActionTemplate/OneButtonAction.js +1 -1
  28. package/src/commons/ActionTemplate/OneButtonActionStyles.js +1 -1
  29. package/src/commons/ActionTemplate/ThreeButtonAction.js +3 -3
  30. package/src/commons/ActionTemplate/ThreeButtonActionStyles.js +1 -1
  31. package/src/commons/Auth/AccountList.js +1 -1
  32. package/src/commons/Auth/__test__/OtpInputList.test.js +13 -17
  33. package/src/commons/Automate/ItemAutomate.js +10 -4
  34. package/src/commons/Automate/__test__/ItemAutomate.test.js +11 -11
  35. package/src/commons/Device/DeviceAlertStatus.js +2 -1
  36. package/src/commons/Device/ProgressBar/index.js +5 -11
  37. package/src/commons/Device/ProgressBar/styles.js +11 -3
  38. package/src/commons/Device/WindSpeed/Anemometer/index.js +2 -0
  39. package/src/commons/Device/WindSpeed/LinearChart/__test__/LinearChart.test.js +14 -1
  40. package/src/commons/Device/WindSpeed/LinearChart/index.js +4 -2
  41. package/src/commons/FlatListDnD/__test__/index.test.js +49 -0
  42. package/src/commons/FlatListDnD/index.js +37 -0
  43. package/src/commons/FlatListDnD/styles.js +12 -0
  44. package/src/commons/Form/__test__/TextInput.test.js +1 -1
  45. package/src/commons/Header/HeaderCustom.js +2 -1
  46. package/src/commons/HorizontalPicker/index.js +65 -38
  47. package/src/commons/IconComponent/index.js +3 -2
  48. package/src/commons/MediaPlayer/__test__/index.test.js +8 -3
  49. package/src/commons/MediaPlayer/index.js +11 -7
  50. package/src/commons/MenuActionMore/index.js +6 -4
  51. package/src/commons/Modal/ModalBottom.js +2 -3
  52. package/src/commons/Modal/ModalCustom.js +2 -3
  53. package/src/commons/NavBar/index.js +48 -50
  54. package/src/commons/OneTapTemplate/NumberUpDownActionTemplate.js +1 -1
  55. package/src/commons/OneTapTemplate/NumberUpDownActionTemplateStyles.js +1 -1
  56. package/src/commons/OneTapTemplate/OptionsDropdownActionTemplate.js +1 -1
  57. package/src/commons/OneTapTemplate/OptionsDropdownActionTemplateStyles.js +1 -1
  58. package/src/commons/OneTapTemplate/StatesGridActionTemplate.js +1 -1
  59. package/src/commons/OneTapTemplate/StatesGridActionTemplateStyles.js +1 -1
  60. package/src/commons/PreventAccess/index.js +1 -1
  61. package/src/commons/Sharing/StationDevicePermissions.js +4 -4
  62. package/src/commons/Sharing/WrapHeaderScrollable.js +5 -5
  63. package/src/commons/Sharing/__test__/DevicePermissionsCheckbox.test.js +2 -2
  64. package/src/commons/SubUnit/OneTap/ItemOneTap.js +7 -11
  65. package/src/commons/SubUnit/OneTap/__test__/SubUnitAutomate.test.js +11 -6
  66. package/src/commons/SubUnit/OneTap/index.js +19 -6
  67. package/src/commons/UnitSummary/AirQuality/__test__/index.test.js +4 -0
  68. package/src/commons/UnitSummary/ConfigHistoryChart/__test__/ConfigHistoryChart.test.js +1 -1
  69. package/src/configs/API.js +6 -0
  70. package/src/configs/AccessibilityLabel.js +1 -0
  71. package/src/configs/Colors.js +1 -1
  72. package/src/configs/Constants.js +12 -18
  73. package/src/hooks/Common/__test__/useStatusbar.test.js +5 -5
  74. package/src/hooks/Common/index.js +0 -2
  75. package/src/hooks/Common/useKeyboardShow.js +4 -4
  76. package/src/hooks/Common/useStatusBar.js +2 -2
  77. package/src/hooks/Common/useTitleHeader.js +5 -7
  78. package/src/hooks/IoT/__test__/useRemoteControl.test.js +11 -0
  79. package/src/hooks/IoT/useBluetoothConnection.js +6 -3
  80. package/src/hooks/index.js +1 -2
  81. package/src/navigations/UnitStack.js +33 -9
  82. package/src/screens/AddNewAutoSmart/__test__/AddNewAutoSmart.test.js +8 -31
  83. package/src/screens/AddNewAutoSmart/index.js +24 -60
  84. package/src/screens/AddNewGateway/SelectDeviceSubUnit.js +1 -2
  85. package/src/screens/AddNewGateway/__test__/AddNewGateway.test.js +5 -17
  86. package/src/screens/AddNewGateway/__test__/SelectDeviceSubUnit.test.js +5 -13
  87. package/src/screens/AddNewGateway/__test__/SelectDeviceUnit.test.js +9 -11
  88. package/src/screens/AddNewGateway/__test__/SelectModbusGateway.test.js +6 -14
  89. package/src/screens/AddNewGateway/__test__/SelectZigbeeGateway.test.js +6 -14
  90. package/src/screens/AddNewGateway/hooks/__Tests__/useWifiManage.test.js +3 -2
  91. package/src/screens/AddNewGateway/index.js +1 -1
  92. package/src/screens/AllCamera/index.js +2 -3
  93. package/src/screens/AllGateway/DetailConfigActionZigbee/__test__/index.test.js +0 -18
  94. package/src/screens/AllGateway/DetailConfigActionZigbee/index.js +1 -1
  95. package/src/screens/AllGateway/DeviceModbusDetail/__test__/index.test.js +5 -2
  96. package/src/screens/AllGateway/hooks/__test__/index.test.js +1 -1
  97. package/src/screens/{AddNewAction → Automate/AddNewAction}/ChooseAction.js +78 -119
  98. package/src/screens/{AddNewAction → Automate/AddNewAction}/ChooseConfig.js +45 -73
  99. package/src/screens/{AddNewAction → Automate/AddNewAction}/Components/LoadingSelectAction.js +1 -1
  100. package/src/screens/{AddNewAction → Automate/AddNewAction}/Components/SelectDevices.js +3 -3
  101. package/src/screens/{AddNewAction → Automate/AddNewAction}/Device/DeviceStyles.js +5 -1
  102. package/src/screens/{AddNewAction → Automate/AddNewAction}/Device/__test__/index.test.js +3 -3
  103. package/src/screens/{AddNewAction → Automate/AddNewAction}/Device/index.js +5 -4
  104. package/src/screens/{AddNewAction → Automate/AddNewAction}/NewActionWrapper.js +11 -10
  105. package/src/screens/{AddNewAction → Automate/AddNewAction}/SelectControlDevices.js +11 -49
  106. package/src/screens/{AddNewAction → Automate/AddNewAction}/SelectMonitorDevices.js +10 -42
  107. package/src/screens/{AddNewAction → Automate/AddNewAction}/SetupConfigCondition.js +52 -101
  108. package/src/screens/{AddNewAction → Automate/AddNewAction}/Styles/SelectActionStyles.js +1 -1
  109. package/src/screens/{AddNewAction → Automate/AddNewAction}/Styles/SelectSensorDevicesStyles.js +1 -1
  110. package/src/screens/{AddNewAction → Automate/AddNewAction}/Styles/SetupSensorStyles.js +4 -2
  111. package/src/screens/{AddNewAction → Automate/AddNewAction}/__test__/ChooseAction.test.js +10 -11
  112. package/src/screens/{AddNewAction → Automate/AddNewAction}/__test__/ChooseConfig.test.js +26 -27
  113. package/src/screens/{AddNewAction → Automate/AddNewAction}/__test__/SelectControlDevices.test.js +9 -9
  114. package/src/screens/{AddNewAction → Automate/AddNewAction}/__test__/SelectMonitorDevices.test.js +5 -5
  115. package/src/screens/{AddNewAction → Automate/AddNewAction}/__test__/SetupSensor.test.js +43 -13
  116. package/src/screens/Automate/Components/InputName.js +64 -0
  117. package/src/screens/{AddNewOneTap/AddNewOneTapStyles.js → Automate/Components/InputNameStyles.js} +2 -2
  118. package/src/screens/{EditActionsList → Automate/EditActionsList}/Styles/indexStyles.js +5 -1
  119. package/src/screens/{EditActionsList → Automate/EditActionsList}/__tests__/index.test.js +6 -6
  120. package/src/screens/{EditActionsList → Automate/EditActionsList}/index.js +18 -19
  121. package/src/screens/Automate/MultiUnits.js +68 -66
  122. package/src/screens/Automate/OneTap/__test__/AddNewOneTap.test.js +134 -0
  123. package/src/screens/Automate/OneTap/index.js +16 -0
  124. package/src/screens/Automate/Scenario/ScenarioName.js +15 -0
  125. package/src/screens/{AddNewOneTap → Automate/Scenario}/__test__/AddNewOneTap.test.js +27 -45
  126. package/src/screens/Automate/ScriptDetail/Components/DeleteScript.js +45 -0
  127. package/src/screens/Automate/ScriptDetail/Components/RenameScript.js +58 -0
  128. package/src/screens/{ScriptDetail → Automate/ScriptDetail}/Styles/indexStyles.js +1 -1
  129. package/src/screens/{ScriptDetail → Automate/ScriptDetail}/__test__/index.test.js +69 -72
  130. package/src/screens/{ScriptDetail → Automate/ScriptDetail}/__test__/useStarredScript.test.js +7 -6
  131. package/src/screens/{ScriptDetail → Automate/ScriptDetail}/hooks/useStarredScript.js +4 -4
  132. package/src/screens/Automate/ScriptDetail/index.js +346 -0
  133. package/src/screens/{ScriptDetail → Automate/ScriptDetail}/utils.js +32 -31
  134. package/src/screens/{SetSchedule → Automate/SetSchedule}/__test__/SelectWeekday.test.js +2 -2
  135. package/src/screens/{SetSchedule → Automate/SetSchedule}/__test__/index.test.js +21 -46
  136. package/src/screens/{SetSchedule → Automate/SetSchedule}/components/RepeatOptionsPopup.js +4 -4
  137. package/src/screens/{SetSchedule → Automate/SetSchedule}/components/RowItem.js +2 -2
  138. package/src/screens/{SetSchedule → Automate/SetSchedule}/components/SelectWeekday.js +3 -3
  139. package/src/screens/Automate/SetSchedule/index.js +140 -0
  140. package/src/screens/{SetSchedule → Automate/SetSchedule}/styles/RepeatOptionsPopupStyles.js +1 -1
  141. package/src/screens/{SetSchedule → Automate/SetSchedule}/styles/RowItemStyles.js +1 -1
  142. package/src/screens/{SetSchedule → Automate/SetSchedule}/styles/SelectWeekdayStyles.js +1 -1
  143. package/src/screens/{SetSchedule → Automate/SetSchedule}/styles/indexStyles.js +1 -1
  144. package/src/screens/Automate/ValueChange/ValueChangeName.js +16 -0
  145. package/src/screens/Automate/__test__/MultiUnits.test.js +76 -120
  146. package/src/screens/Automate/__test__/index.test.js +2 -9
  147. package/src/screens/Automate/constants.js +0 -0
  148. package/src/screens/Automate/index.js +11 -22
  149. package/src/screens/ChangePosition/__test__/index.test.js +75 -0
  150. package/src/screens/ChangePosition/index.js +112 -0
  151. package/src/screens/ChangePosition/styles.js +87 -0
  152. package/src/screens/Device/__test__/detail.test.js +202 -257
  153. package/src/screens/Device/__test__/sensorDisplayItem.test.js +4 -0
  154. package/src/screens/Device/components/SensorDisplayItem.js +2 -1
  155. package/src/screens/Device/components/VisualChart.js +55 -8
  156. package/src/screens/Device/detail.js +14 -0
  157. package/src/screens/Device/hooks/__test__/useEmergencyButton.test.js +35 -13
  158. package/src/screens/Device/hooks/useEvaluateValue.js +20 -2
  159. package/src/screens/Device/styles.js +7 -0
  160. package/src/screens/GuestInfo/components/__test__/AccessScheduleSheet.test.js +52 -0
  161. package/src/screens/MoveToAnotherSubUnit/__test__/index.test.js +18 -13
  162. package/src/screens/Notification/__test__/Notification.test.js +1 -1
  163. package/src/screens/PlayBackCamera/index.js +2 -3
  164. package/src/screens/SharedUnit/index.js +5 -4
  165. package/src/screens/Sharing/SelectUser.js +2 -2
  166. package/src/screens/Sharing/__test__/MemberList.test.js +9 -15
  167. package/src/screens/Sharing/__test__/MemberList2.test.js +10 -16
  168. package/src/screens/Sharing/__test__/SelectUser.test.js +8 -4
  169. package/src/screens/SideMenuDetail/SideMenuDetailStyles.js +1 -1
  170. package/src/screens/SmartAccount/index.js +1 -0
  171. package/src/screens/SubUnit/ManageSubUnit.js +4 -4
  172. package/src/screens/SubUnit/__test__/ManageSubUnit.test.js +9 -28
  173. package/src/screens/TDSGuide/index.js +1 -1
  174. package/src/screens/Template/GatewayList.js +4 -1
  175. package/src/screens/Template/__test__/detail.test.js +14 -20
  176. package/src/screens/Template/detail.js +1 -0
  177. package/src/screens/UVIndexGuide/index.js +2 -2
  178. package/src/screens/Unit/Detail.js +6 -5
  179. package/src/screens/Unit/SelectAddToFavorites.js +1 -1
  180. package/src/screens/Unit/__test__/ChooseLocation.test.js +8 -13
  181. package/src/screens/Unit/__test__/Detail.test.js +3 -1
  182. package/src/screens/Unit/__test__/SelectAddToFavorites.test.js +1 -1
  183. package/src/screens/Unit/__test__/SmartAccount.test.js +8 -14
  184. package/src/screens/UnitSummary/components/UvIndex/__test__/index.test.js +4 -0
  185. package/src/screens/UnitSummary/components/WaterQuality/__test__/index.test.js +6 -11
  186. package/src/screens/WaterQualityGuide/index.js +10 -5
  187. package/src/utils/I18n/translations/en.json +23 -18
  188. package/src/utils/I18n/translations/vi.json +21 -18
  189. package/src/utils/Route/index.js +3 -0
  190. package/src/utils/Utils.js +29 -0
  191. package/src/utils/__test__/Utils.test.js +6 -0
  192. package/src/commons/ActionGroup/CurtainButtonTemplate.js +0 -130
  193. package/src/commons/ActionGroup/__test__/CurtainButtonTemplate.test.js +0 -109
  194. package/src/commons/Auth/SocialButton.js +0 -54
  195. package/src/commons/Auth/__test__/SocialButton.test.js +0 -46
  196. package/src/commons/Sharing/__test__/StationDevicePermission.test.js +0 -85
  197. package/src/hooks/__test__/useInitDeepLink.test.js +0 -28
  198. package/src/hooks/useInitDeepLink.js +0 -25
  199. package/src/screens/AddNewOneTap/index.js +0 -156
  200. package/src/screens/ScriptDetail/hooks/index.js +0 -136
  201. package/src/screens/ScriptDetail/index.js +0 -446
  202. package/src/screens/SetSchedule/index.js +0 -200
  203. /package/src/screens/{AddNewAction → Automate/AddNewAction}/Components/index.js +0 -0
  204. /package/src/screens/{AddNewAction → Automate/AddNewAction}/__test__/LoadingSelectAction.test.js +0 -0
@@ -4,18 +4,18 @@ import DraggableFlatList from 'react-native-draggable-flatlist';
4
4
  import { useNavigation, useRoute } from '@react-navigation/native';
5
5
  import ParsedText from 'react-native-parsed-text';
6
6
 
7
- import { HeaderCustom } from '../../commons/Header';
8
- import { useTranslations } from '../../hooks/Common/useTranslations';
9
- import Text from '../../commons/Text';
7
+ import { HeaderCustom } from '../../../commons/Header';
8
+ import { useTranslations } from '../../../hooks/Common/useTranslations';
9
+ import Text from '../../../commons/Text';
10
10
  import styles from './Styles/indexStyles';
11
- import { API, Colors } from '../../configs';
12
- import FImage from '../../commons/FImage';
13
- import Rearrange from '../../../assets/images/Rearrange.svg';
14
- import Close from '../../../assets/images/Close.svg';
15
- import { axiosDelete, axiosPut } from '../../utils/Apis/axios';
16
- import { ModalBottom } from '../../commons/Modal';
17
- import { ToastBottomHelper } from '../../utils/Utils';
18
- import { AccessibilityLabel } from '../../configs/Constants';
11
+ import { API, Colors } from '../../../configs';
12
+ import FImage from '../../../commons/FImage';
13
+ import Rearrange from '../../../../assets/images/Rearrange.svg';
14
+ import Close from '../../../../assets/images/Close.svg';
15
+ import { axiosDelete, axiosPut } from '../../../utils/Apis/axios';
16
+ import { ModalBottom } from '../../../commons/Modal';
17
+ import { ToastBottomHelper } from '../../../utils/Utils';
18
+ import { AccessibilityLabel } from '../../../configs/Constants';
19
19
 
20
20
  const EditActionsList = memo(() => {
21
21
  const t = useTranslations();
@@ -37,11 +37,6 @@ const EditActionsList = memo(() => {
37
37
  })
38
38
  );
39
39
 
40
- const onPressCancel = useCallback(() => {
41
- goBack();
42
- // eslint-disable-next-line react-hooks/exhaustive-deps
43
- }, []);
44
-
45
40
  const onPressSave = useCallback(async () => {
46
41
  const { success } = await axiosPut(API.AUTOMATE.ORDER_SCRIPT_ACTION(id), {
47
42
  id_script_actions: actionsList.map((i) => i.id),
@@ -79,9 +74,13 @@ const EditActionsList = memo(() => {
79
74
  // eslint-disable-next-line react-hooks/exhaustive-deps
80
75
  }, [id, itemRemove, actionsList]);
81
76
 
82
- const renderItem = useCallback(({ item, index, drag }) => {
77
+ const renderItem = useCallback(({ item, index, drag, isActive }) => {
83
78
  return (
84
- <TouchableOpacity style={styles.wrapItem} onLongPress={drag}>
79
+ <TouchableOpacity
80
+ style={[styles.wrapItem, isActive ? styles.isDragging : {}]}
81
+ onPressIn={drag}
82
+ disabled={isActive}
83
+ >
85
84
  <View style={styles.leftItem}>
86
85
  <Text color={Colors.Gray9} type="H4" semibold>
87
86
  {index + 1 < 10 ? '0' + (index + 1) : index + 1}
@@ -153,7 +152,7 @@ const EditActionsList = memo(() => {
153
152
  </View>
154
153
  <View style={styles.wrapBottom}>
155
154
  <TouchableOpacity
156
- onPress={onPressCancel}
155
+ onPress={goBack}
157
156
  accessibilityLabel={AccessibilityLabel.BUTTON_CANCEL_EDIT_ACTION_LIST}
158
157
  >
159
158
  <Text type="H4" hilight semibold>
@@ -1,9 +1,9 @@
1
- import React, { useCallback, useState, useEffect, useMemo } from 'react';
2
- import { View, TouchableOpacity } from 'react-native';
1
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
+ import { TouchableOpacity, View } from 'react-native';
3
3
  import {
4
- useRoute,
5
- useNavigation,
6
4
  useIsFocused,
5
+ useNavigation,
6
+ useRoute,
7
7
  } from '@react-navigation/native';
8
8
  import { useSCContextSelector } from '../../context';
9
9
 
@@ -13,26 +13,26 @@ import { axiosGet, fetchWithCache } from '../../utils/Apis/axios';
13
13
  import { API, Colors } from '../../configs';
14
14
  import Text from '../../commons/Text';
15
15
  import styles from './Styles/MultiUnitsStyles';
16
- import { AUTOMATE_TYPE } from '../../configs/Constants';
16
+ import { AUTOMATE_TABS, AUTOMATE_TYPE } from '../../configs/Constants';
17
17
  import ItemOneTap from '../../commons/SubUnit/OneTap/ItemOneTap';
18
18
  import Routes from '../../utils/Route';
19
- import { useGetIdUser } from '../../hooks/Common';
20
19
  import ItemAddNew from '../../commons/Device/ItemAddNew';
21
20
 
22
21
  const MultiUnits = () => {
23
22
  const t = useTranslations();
24
23
  const isFocused = useIsFocused();
25
- const idUser = useGetIdUser();
26
24
  const { navigate } = useNavigation();
27
25
  const { params = {}, name: currentRouteName } = useRoute();
28
- const { isMultiUnits = false, unitName = '', unit, isOwner } = params;
26
+ const {
27
+ isMultiUnits = false,
28
+ unitName = '',
29
+ unit,
30
+ isOwner,
31
+ newAutomate,
32
+ } = params;
29
33
  const [data, setData] = useState([]);
30
- const tabName = useMemo(
31
- () => [t(AUTOMATE_TYPE.SCENARIO), t(AUTOMATE_TYPE.AUTOMATION)],
32
- // eslint-disable-next-line react-hooks/exhaustive-deps
33
- []
34
- );
35
- const [tabActive, setTabActive] = useState(tabName[0]);
34
+
35
+ const [tabActive, setTabActive] = useState(AUTOMATE_TABS.SCENARIO);
36
36
 
37
37
  const starredScriptIds = useSCContextSelector(
38
38
  (state) => state.automate.starredScriptIds
@@ -60,64 +60,48 @@ const MultiUnits = () => {
60
60
  setTabActive(tab);
61
61
  };
62
62
 
63
- const onPressItem = (item, isItemOwner) => () => {
64
- navigate(Routes.UnitStack, {
65
- screen: Routes.ScriptDetail,
66
- params: {
67
- id: item?.id,
68
- name: item?.script?.name,
69
- type: item?.type,
70
- havePermission: isItemOwner || idUser === item?.user,
71
- unit,
72
- isMultiUnits,
73
- automate: item,
74
- },
75
- });
76
- };
63
+ const onPressItem = useCallback(
64
+ (item) => {
65
+ navigate(Routes.UnitStack, {
66
+ screen: Routes.ScriptDetail,
67
+ params: {
68
+ id: item?.id,
69
+ unitId: unit?.id,
70
+ preAutomate: item,
71
+ },
72
+ });
73
+ },
74
+ [navigate, unit?.id]
75
+ );
76
+
77
+ useEffect(() => {
78
+ newAutomate && onPressItem(newAutomate);
79
+ }, [newAutomate, onPressItem]);
77
80
 
78
81
  const handleOnAddNew = useCallback(() => {
82
+ if (tabActive === AUTOMATE_TABS.SCENARIO) {
83
+ navigate(Routes.UnitStack, {
84
+ screen: Routes.ScenarioName,
85
+ params: {
86
+ automate: { type: AUTOMATE_TYPE.ONE_TAP, unit: unit?.id },
87
+ closeScreen: currentRouteName,
88
+ },
89
+ });
90
+ return;
91
+ }
92
+
79
93
  navigate(Routes.UnitStack, {
80
94
  screen: Routes.AddNewAutoSmart,
81
95
  params: {
82
- type:
83
- tabActive === t(AUTOMATE_TYPE.SCENARIO)
84
- ? AUTOMATE_TYPE.ONE_TAP_ONLY
85
- : AUTOMATE_TYPE.VALUE_CHANGE,
86
- unit: { id: unit?.id },
96
+ automate: { unit: unit?.id },
87
97
  closeScreen: currentRouteName,
88
- isMultiUnits,
89
98
  },
90
99
  });
91
- // eslint-disable-next-line react-hooks/exhaustive-deps
92
- }, [tabActive]);
93
-
94
- const renderTab = useMemo(
95
- () => (
96
- <View style={styles.wrapTab}>
97
- {tabName.map((item) => (
98
- <TouchableOpacity
99
- onPress={onPressTabName(item)}
100
- key={item}
101
- style={[styles.tabName, item === tabActive && styles.tabNameActive]}
102
- >
103
- <Text
104
- type="Body"
105
- semibold
106
- color={item === tabActive ? Colors.Primary : Colors.Gray6}
107
- >
108
- {item}
109
- </Text>
110
- </TouchableOpacity>
111
- ))}
112
- </View>
113
- ),
114
- // eslint-disable-next-line react-hooks/exhaustive-deps
115
- [tabActive]
116
- );
100
+ }, [currentRouteName, navigate, tabActive, unit?.id]);
117
101
 
118
102
  const renderContent = useMemo(() => {
119
103
  const listItems = data.filter((item) =>
120
- tabActive === t(AUTOMATE_TYPE.SCENARIO)
104
+ tabActive === AUTOMATE_TABS.SCENARIO
121
105
  ? item?.type === AUTOMATE_TYPE.ONE_TAP
122
106
  : item?.type !== AUTOMATE_TYPE.ONE_TAP
123
107
  );
@@ -138,7 +122,7 @@ const MultiUnits = () => {
138
122
  styles.wrapAutomateItem,
139
123
  index % 2 === 0 && styles.marginRigt8,
140
124
  ]}
141
- onPressItem={onPressItem(item, isOwner)}
125
+ onPressItem={() => onPressItem(item)}
142
126
  />
143
127
  ))}
144
128
  <ItemAddNew
@@ -152,9 +136,8 @@ const MultiUnits = () => {
152
136
  }, [data, tabActive]);
153
137
 
154
138
  useEffect(() => {
155
- getData();
156
- // eslint-disable-next-line react-hooks/exhaustive-deps
157
- }, [isFocused]);
139
+ isFocused && getData();
140
+ }, [getData, isFocused]);
158
141
 
159
142
  return (
160
143
  <View style={styles.wrap}>
@@ -163,7 +146,26 @@ const MultiUnits = () => {
163
146
  headerAniStyle={styles.headerAniStyle}
164
147
  >
165
148
  <View style={styles.wrapContent}>
166
- {renderTab}
149
+ <View style={styles.wrapTab}>
150
+ {Object.values(AUTOMATE_TABS).map((item) => (
151
+ <TouchableOpacity
152
+ onPress={onPressTabName(item)}
153
+ key={item}
154
+ style={[
155
+ styles.tabName,
156
+ item === tabActive && styles.tabNameActive,
157
+ ]}
158
+ >
159
+ <Text
160
+ type="Body"
161
+ semibold
162
+ color={item === tabActive ? Colors.Primary : Colors.Gray6}
163
+ >
164
+ {t(item)}
165
+ </Text>
166
+ </TouchableOpacity>
167
+ ))}
168
+ </View>
167
169
  {renderContent}
168
170
  </View>
169
171
  </WrapHeaderScrollable>
@@ -0,0 +1,134 @@
1
+ import React from 'react';
2
+ import MockAdapter from 'axios-mock-adapter';
3
+ import { Platform, TextInput, TouchableOpacity } from 'react-native';
4
+ import { act, create } from 'react-test-renderer';
5
+
6
+ import AddNewOneTap from '../index';
7
+ import { AccessibilityLabel } from '../../../../configs/Constants';
8
+ import { SCProvider } from '../../../../context';
9
+ import { mockSCStore } from '../../../../context/mockStore';
10
+ import Routes from '../../../../utils/Route';
11
+ import api from '../../../../utils/Apis/axios';
12
+ import { API } from '../../../../configs';
13
+ import { useNavigation, useRoute } from '@react-navigation/native';
14
+
15
+ const wrapComponent = (route) => {
16
+ useRoute.mockReturnValue(route);
17
+ return (
18
+ <SCProvider initState={mockSCStore({})}>
19
+ <AddNewOneTap route={route} />
20
+ </SCProvider>
21
+ );
22
+ };
23
+ const mock = new MockAdapter(api.axiosInstance);
24
+
25
+ jest.mock('react-redux', () => {
26
+ return {
27
+ ...jest.requireActual('react-redux'),
28
+ useSelector: () => 'vi',
29
+ };
30
+ });
31
+
32
+ let tree;
33
+
34
+ describe('test OneTap', () => {
35
+ const mockedNavigate = useNavigation().navigate;
36
+ beforeEach(() => {
37
+ mockedNavigate.mockClear();
38
+ });
39
+
40
+ it('create OneTap success', async () => {
41
+ Platform.OS = 'ios';
42
+ let route = {
43
+ params: {
44
+ type: 'one_tap',
45
+ unit: { id: 1 },
46
+ isMultiUnits: false,
47
+ isAutomateTab: false,
48
+ },
49
+ };
50
+
51
+ const response = {
52
+ id: 1,
53
+ unit: 1,
54
+ type: 'one_tap',
55
+ weekday_repeat: [],
56
+ script: { id: 1, name: 'William Miller' },
57
+ };
58
+
59
+ mock.onPost(API.AUTOMATE.CREATE_AUTOMATE()).reply(200, response);
60
+
61
+ await act(async () => {
62
+ tree = await create(wrapComponent(route));
63
+ });
64
+ const instance = tree.root;
65
+ const inputName = instance.findAll(
66
+ (el) =>
67
+ el.props.accessibilityLabel === AccessibilityLabel.NAME_YOUR_BUTTON &&
68
+ el.type === TextInput
69
+ );
70
+ expect(inputName).toHaveLength(1);
71
+
72
+ await act(async () => {
73
+ await inputName[0].props.onChangeText('Tap to up');
74
+ });
75
+
76
+ const item = instance.findAll(
77
+ (el) =>
78
+ el.props.accessibilityLabel === AccessibilityLabel.BOTTOM_VIEW_MAIN &&
79
+ el.type === TouchableOpacity
80
+ );
81
+
82
+ expect(item).toHaveLength(1);
83
+ await act(async () => {
84
+ await item[0].props.onPress();
85
+ });
86
+ });
87
+
88
+ it('create OneTap fail', async () => {
89
+ Platform.OS = 'android';
90
+ let route = {
91
+ params: { type: 'one_tap' },
92
+ };
93
+
94
+ mock.onPost(API.AUTOMATE.CREATE_AUTOMATE()).reply(400);
95
+
96
+ await act(async () => {
97
+ tree = await create(wrapComponent(route));
98
+ });
99
+
100
+ const item = tree.root.findAll(
101
+ (el) =>
102
+ el.props.accessibilityLabel === AccessibilityLabel.BOTTOM_VIEW_MAIN &&
103
+ el.type === TouchableOpacity
104
+ );
105
+
106
+ expect(item).toHaveLength(1);
107
+ await act(async () => {
108
+ await item[0].props.onPress();
109
+ });
110
+ expect(mockedNavigate).not.toBeCalled();
111
+ });
112
+
113
+ it('test onClose have automateId', async () => {
114
+ Platform.OS = 'android';
115
+ let route = {
116
+ params: {
117
+ closeScreen: Routes.ScriptDetail,
118
+ },
119
+ };
120
+ mock.onPost(API.AUTOMATE.CREATE_AUTOMATE()).reply(400);
121
+ await act(async () => {
122
+ tree = await create(wrapComponent(route));
123
+ });
124
+
125
+ const header = tree.root.findByProps({
126
+ accessibilityLabel: AccessibilityLabel.ICON_CLOSE,
127
+ });
128
+
129
+ await act(async () => {
130
+ header.props.onPress();
131
+ });
132
+ expect(mockedNavigate).toHaveBeenCalledWith(Routes.ScriptDetail);
133
+ });
134
+ });
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import InputName from '../Components/InputName';
3
+ import { useTranslations } from '../../../hooks/Common/useTranslations';
4
+
5
+ const AddNewOneTap = () => {
6
+ const t = useTranslations();
7
+
8
+ return (
9
+ <InputName
10
+ title={t('name_your_scenario')}
11
+ placeholder={t('name_your_button')}
12
+ />
13
+ );
14
+ };
15
+
16
+ export default AddNewOneTap;
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { useTranslations } from '../../../hooks/Common/useTranslations';
3
+ import InputName from '../Components/InputName';
4
+
5
+ const ScenarioName = () => {
6
+ const t = useTranslations();
7
+ return (
8
+ <InputName
9
+ title={t('name_your_scenario')}
10
+ placeholder={t('name_your_button')}
11
+ />
12
+ );
13
+ };
14
+
15
+ export default ScenarioName;
@@ -3,20 +3,23 @@ import MockAdapter from 'axios-mock-adapter';
3
3
  import { Platform, TextInput, TouchableOpacity } from 'react-native';
4
4
  import { act, create } from 'react-test-renderer';
5
5
 
6
- import AddNewOneTap from '..';
7
- import { AccessibilityLabel } from '../../../configs/Constants';
8
- import { SCProvider } from '../../../context';
9
- import { mockSCStore } from '../../../context/mockStore';
10
- import Routes from '../../../utils/Route';
11
- import { HeaderCustom } from '../../../commons/Header';
12
- import api from '../../../utils/Apis/axios';
13
- import { API } from '../../../configs';
14
-
15
- const wrapComponent = (route) => (
16
- <SCProvider initState={mockSCStore({})}>
17
- <AddNewOneTap route={route} />
18
- </SCProvider>
19
- );
6
+ import ScenarioName from '../ScenarioName';
7
+ import { AccessibilityLabel } from '../../../../configs/Constants';
8
+ import { SCProvider } from '../../../../context';
9
+ import { mockSCStore } from '../../../../context/mockStore';
10
+ import Routes from '../../../../utils/Route';
11
+ import api from '../../../../utils/Apis/axios';
12
+ import { API } from '../../../../configs';
13
+ import { useNavigation, useRoute } from '@react-navigation/native';
14
+
15
+ const wrapComponent = (route) => {
16
+ useRoute.mockReturnValue(route);
17
+ return (
18
+ <SCProvider initState={mockSCStore({})}>
19
+ <ScenarioName route={route} />
20
+ </SCProvider>
21
+ );
22
+ };
20
23
  const mock = new MockAdapter(api.axiosInstance);
21
24
 
22
25
  jest.mock('react-redux', () => {
@@ -26,24 +29,15 @@ jest.mock('react-redux', () => {
26
29
  };
27
30
  });
28
31
 
29
- const mockedNavigate = jest.fn();
30
- jest.mock('@react-navigation/native', () => {
31
- return {
32
- ...jest.requireActual('@react-navigation/native'),
33
- useNavigation: () => ({
34
- navigate: mockedNavigate,
35
- }),
36
- };
37
- });
38
-
39
32
  let tree;
40
33
 
41
- describe('test AddNewOneTap', () => {
34
+ describe('test OneTap', () => {
35
+ const mockedNavigate = useNavigation().navigate;
42
36
  beforeEach(() => {
43
37
  mockedNavigate.mockClear();
44
38
  });
45
39
 
46
- it('create AddNewOneTap success', async () => {
40
+ it('create OneTap success', async () => {
47
41
  Platform.OS = 'ios';
48
42
  let route = {
49
43
  params: {
@@ -94,7 +88,7 @@ describe('test AddNewOneTap', () => {
94
88
  });
95
89
  });
96
90
 
97
- it('create AddNewOneTap fail', async () => {
91
+ it('create OneTap fail', async () => {
98
92
  Platform.OS = 'android';
99
93
  let route = {
100
94
  params: { type: 'one_tap' },
@@ -123,13 +117,7 @@ describe('test AddNewOneTap', () => {
123
117
  Platform.OS = 'android';
124
118
  let route = {
125
119
  params: {
126
- automateId: 1,
127
- scriptName: 'script test',
128
- type: 'one_tap',
129
- havePermission: true,
130
- unit: { id: 1 },
131
- isMultiUnits: false,
132
- isAutomateTab: false,
120
+ closeScreen: Routes.ScriptDetail,
133
121
  },
134
122
  };
135
123
  mock.onPost(API.AUTOMATE.CREATE_AUTOMATE()).reply(400);
@@ -137,19 +125,13 @@ describe('test AddNewOneTap', () => {
137
125
  tree = await create(wrapComponent(route));
138
126
  });
139
127
 
140
- const header = tree.root.findByType(HeaderCustom);
128
+ const header = tree.root.findByProps({
129
+ accessibilityLabel: AccessibilityLabel.ICON_CLOSE,
130
+ });
141
131
 
142
132
  await act(async () => {
143
- header.props.onClose();
144
- });
145
- expect(mockedNavigate).toHaveBeenCalledWith(Routes.ScriptDetail, {
146
- id: 1,
147
- name: 'script test',
148
- type: undefined,
149
- havePermission: true,
150
- unit: { id: 1 },
151
- isMultiUnits: false,
152
- isAutomateTab: false,
133
+ header.props.onPress();
153
134
  });
135
+ expect(mockedNavigate).toHaveBeenCalledWith(Routes.ScriptDetail);
154
136
  });
155
137
  });
@@ -0,0 +1,45 @@
1
+ import React, { useCallback } from 'react';
2
+ import { API, Colors } from '../../../../configs';
3
+ import AlertAction from '../../../../commons/AlertAction';
4
+ import { axiosDelete } from '../../../../utils/Apis/axios';
5
+ import { ToastBottomHelper } from '../../../../utils/Utils';
6
+ import { useTranslations } from '../../../../hooks/Common/useTranslations';
7
+ import { useNavigation } from '@react-navigation/native';
8
+
9
+ const RenameScript = ({ automate, isVisible, setIsVisible }) => {
10
+ const t = useTranslations();
11
+ const { goBack } = useNavigation();
12
+
13
+ const deleteScript = useCallback(async () => {
14
+ const { success } = await axiosDelete(API.AUTOMATE.SCRIPT(automate.id));
15
+ if (success) {
16
+ setIsVisible(false);
17
+ goBack();
18
+ ToastBottomHelper.success(t('removed_successfully'));
19
+ } else {
20
+ ToastBottomHelper.error(t('remove_failed'));
21
+ }
22
+ }, [automate.id, goBack, setIsVisible, t]);
23
+
24
+ const hidePopup = () => setIsVisible(false);
25
+
26
+ return (
27
+ <AlertAction
28
+ visible={isVisible}
29
+ hideModal={hidePopup}
30
+ title={t('title_delete_script', {
31
+ scriptName: automate?.name,
32
+ })}
33
+ message={t('message_delete_script', {
34
+ scriptName: automate?.name,
35
+ })}
36
+ leftButtonTitle={t('cancel')}
37
+ leftButtonClick={hidePopup}
38
+ rightButtonTitle={t('remove')}
39
+ rightButtonClick={deleteScript}
40
+ rightButtonStyle={{ color: Colors.Red6 }}
41
+ />
42
+ );
43
+ };
44
+
45
+ export default RenameScript;
@@ -0,0 +1,58 @@
1
+ import React, { useCallback, useState } from 'react';
2
+ import { API, Colors } from '../../../../configs';
3
+ import _TextInput from '../../../../commons/Form/TextInput';
4
+ import styles from '../Styles/indexStyles';
5
+ import AlertAction from '../../../../commons/AlertAction';
6
+ import { axiosPatch } from '../../../../utils/Apis/axios';
7
+ import { ToastBottomHelper } from '../../../../utils/Utils';
8
+ import { useTranslations } from '../../../../hooks/Common/useTranslations';
9
+ import useKeyboardAnimated from '../../../../hooks/Explore/useKeyboardAnimated';
10
+
11
+ const RenameScript = ({ automate, setAutomate, isVisible, setIsVisible }) => {
12
+ const t = useTranslations();
13
+ const [inputName, setInputName] = useState(automate.name);
14
+ const transY = useKeyboardAnimated();
15
+
16
+ const renameScript = useCallback(async () => {
17
+ const { success, data: script } = await axiosPatch(
18
+ API.AUTOMATE.SCRIPT(automate.id),
19
+ {
20
+ name: inputName,
21
+ }
22
+ );
23
+ if (success) {
24
+ setAutomate((prev) => ({ ...prev, name: script.name }));
25
+ ToastBottomHelper.success(t('rename_successfully'));
26
+ } else {
27
+ ToastBottomHelper.error(t('rename_failed'));
28
+ }
29
+ setIsVisible(false);
30
+ }, [automate.id, inputName, setAutomate, setIsVisible, t]);
31
+
32
+ const hidePopup = () => setIsVisible(false);
33
+
34
+ return (
35
+ <AlertAction
36
+ visible={isVisible}
37
+ hideModal={hidePopup}
38
+ title={t('rename_automate')}
39
+ message=""
40
+ leftButtonTitle={t('cancel')}
41
+ leftButtonClick={hidePopup}
42
+ rightButtonTitle={t('rename')}
43
+ rightButtonClick={renameScript}
44
+ rightButtonStyle={{ color: Colors.Primary }}
45
+ transY={transY}
46
+ >
47
+ <_TextInput
48
+ onChange={setInputName}
49
+ value={inputName}
50
+ defaultValue={automate?.name}
51
+ textInputStyle={styles.textInput}
52
+ maxLength={64}
53
+ />
54
+ </AlertAction>
55
+ );
56
+ };
57
+
58
+ export default RenameScript;
@@ -1,4 +1,4 @@
1
- import { Colors } from '../../../configs';
1
+ import { Colors } from '../../../../configs';
2
2
  import { Platform, StyleSheet } from 'react-native';
3
3
  import { getBottomSpace } from 'react-native-iphone-x-helper';
4
4