@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
@@ -3,19 +3,24 @@ import { create, act } from 'react-test-renderer';
3
3
  import Toast from 'react-native-toast-message';
4
4
 
5
5
  import MockAdapter from 'axios-mock-adapter';
6
- import { SCProvider } from '../../../context';
7
- import { mockSCStore } from '../../../context/mockStore';
8
- import ScriptDetail from '..';
9
- import MenuActionMore from '../../../commons/MenuActionMore';
10
- import AlertAction from '../../../commons/AlertAction';
11
- import _TextInput from '../../../commons/Form/TextInput';
12
- import { AUTOMATE_TYPE, AccessibilityLabel } from '../../../configs/Constants';
13
- import { API } from '../../../configs';
6
+ import { SCProvider } from '../../../../context';
7
+ import { mockSCStore } from '../../../../context/mockStore';
8
+ import ScriptDetail from '../index';
9
+ import MenuActionMore from '../../../../commons/MenuActionMore';
10
+ import AlertAction from '../../../../commons/AlertAction';
11
+ import _TextInput from '../../../../commons/Form/TextInput';
12
+ import {
13
+ AUTOMATE_TYPE,
14
+ AccessibilityLabel,
15
+ } from '../../../../configs/Constants';
16
+ import { API } from '../../../../configs';
14
17
  import { TouchableOpacity } from 'react-native';
15
- import Routes from '../../../utils/Route';
16
- import WrapHeaderScrollable from '../../../commons/Sharing/WrapHeaderScrollable';
17
- import ItemAutomate from '../../../commons/Automate/ItemAutomate';
18
- import api from '../../../utils/Apis/axios';
18
+ import Routes from '../../../../utils/Route';
19
+ import WrapHeaderScrollable from '../../../../commons/Sharing/WrapHeaderScrollable';
20
+ import ItemAutomate from '../../../../commons/Automate/ItemAutomate';
21
+ import api from '../../../../utils/Apis/axios';
22
+ import Text from '../../../../commons/Text';
23
+ import { useNavigation } from '@react-navigation/native';
19
24
 
20
25
  const wrapComponent = (route) => (
21
26
  <SCProvider initState={mockSCStore({})}>
@@ -23,18 +28,6 @@ const wrapComponent = (route) => (
23
28
  </SCProvider>
24
29
  );
25
30
 
26
- const mockGoBack = jest.fn();
27
- const mockNavigate = jest.fn();
28
- jest.mock('@react-navigation/native', () => {
29
- return {
30
- ...jest.requireActual('@react-navigation/native'),
31
- useNavigation: () => ({
32
- goBack: mockGoBack,
33
- navigate: mockNavigate,
34
- }),
35
- };
36
- });
37
-
38
31
  const mock = new MockAdapter(api.axiosInstance);
39
32
 
40
33
  describe('Test ScriptDetail', () => {
@@ -42,18 +35,19 @@ describe('Test ScriptDetail', () => {
42
35
  let data;
43
36
  let tree;
44
37
 
38
+ const mockGoBack = useNavigation().goBack;
39
+ const mockNavigate = useNavigation().navigate;
45
40
  beforeEach(() => {
46
41
  mockGoBack.mockClear();
42
+ mockNavigate.mockClear();
43
+ mock.reset();
47
44
  route = {
48
45
  params: {
49
46
  id: 1,
50
- name: 'script',
51
- unit: { id: 2 },
52
- type: AUTOMATE_TYPE.ONE_TAP,
53
- havePermission: true,
54
- automate: {
47
+ preAutomate: {
48
+ unit: 2,
55
49
  author: 'Le Minh Tam',
56
- id: 1009,
50
+ id: 1,
57
51
  type: 'value_change',
58
52
  value_change: {
59
53
  condition: '<',
@@ -63,9 +57,6 @@ describe('Test ScriptDetail', () => {
63
57
  sensor_id: 73,
64
58
  value: 35,
65
59
  },
66
- script: {
67
- id: 1,
68
- },
69
60
  },
70
61
  },
71
62
  };
@@ -89,7 +80,7 @@ describe('Test ScriptDetail', () => {
89
80
  });
90
81
  const instance = tree.root;
91
82
  const menu = instance.findByType(MenuActionMore);
92
- const alertAction = instance.findByType(AlertAction);
83
+ const alertAction = instance.findAllByType(AlertAction)[0];
93
84
  const rename = menu.props.listMenuItem[0];
94
85
 
95
86
  await act(async () => {
@@ -115,7 +106,7 @@ describe('Test ScriptDetail', () => {
115
106
  });
116
107
  const instance = tree.root;
117
108
  const menu = instance.findByType(MenuActionMore);
118
- const alertAction = instance.findByType(AlertAction);
109
+ const alertAction = instance.findAllByType(AlertAction)[0];
119
110
  const rename = menu.props.listMenuItem[0];
120
111
 
121
112
  await act(async () => {
@@ -124,7 +115,7 @@ describe('Test ScriptDetail', () => {
124
115
  expect(menu.props.isVisible).toBeFalsy();
125
116
  expect(alertAction.props.visible).toBeTruthy();
126
117
 
127
- mock.onPatch(API.AUTOMATE.SCRIPT(1)).reply(500, { name: 'new_name' });
118
+ mock.onPatch(API.AUTOMATE.SCRIPT(1)).reply(500);
128
119
  await act(async () => {
129
120
  await alertAction.props.rightButtonClick();
130
121
  });
@@ -138,8 +129,8 @@ describe('Test ScriptDetail', () => {
138
129
  });
139
130
  const instance = tree.root;
140
131
  const menu = instance.findByType(MenuActionMore);
141
- const alertAction = instance.findByType(AlertAction);
142
- const deleteItem = menu.props.listMenuItem[3];
132
+ const alertAction = instance.findAllByType(AlertAction)[1];
133
+ const deleteItem = menu.props.listMenuItem[2];
143
134
 
144
135
  await act(async () => {
145
136
  await menu.props.onItemClick(deleteItem);
@@ -187,6 +178,8 @@ describe('Test ScriptDetail', () => {
187
178
 
188
179
  it('test activate one tap', async () => {
189
180
  mock.onGet(API.AUTOMATE.SCRIPT(1)).reply(200, data);
181
+ route.params.preAutomate.type = AUTOMATE_TYPE.ONE_TAP;
182
+
190
183
  await act(async () => {
191
184
  tree = await create(wrapComponent(route));
192
185
  });
@@ -220,12 +213,8 @@ describe('Test ScriptDetail', () => {
220
213
  await button.props.onPress();
221
214
  });
222
215
  expect(mockNavigate).toHaveBeenCalledWith(Routes.SelectControlDevices, {
223
- unit: route.params.unit,
224
- automateId: route.params.id,
225
- scriptName: route.params.name,
226
- type: AUTOMATE_TYPE.ONE_TAP,
227
- oldType: AUTOMATE_TYPE.ONE_TAP,
228
- automate: route.params.automate,
216
+ unitId: route.params.preAutomate.unit,
217
+ automateId: route.params.preAutomate.id,
229
218
  });
230
219
  });
231
220
 
@@ -240,21 +229,24 @@ describe('Test ScriptDetail', () => {
240
229
  await act(async () => {
241
230
  await WrapHeaderScrollables[0].props.onGoBack();
242
231
  });
243
- expect(mockNavigate).toBeCalled();
232
+ expect(mockGoBack).toBeCalled();
244
233
  });
245
234
 
246
- const _testGoToActivityLog = (automateType, activityLogType, isMultiUnit) => {
247
- it('test go to activity log', async () => {
248
- route.params.type = automateType;
249
- if (isMultiUnit) {
250
- route.params.unit.id = undefined;
251
- }
235
+ const _testGoToActivityLog = (
236
+ count,
237
+ automateType,
238
+ activityLogType,
239
+ unitId
240
+ ) => {
241
+ it(`test go to activity log ${count}`, async () => {
242
+ route.params.preAutomate.type = automateType;
243
+ route.params.preAutomate.unit = unitId;
252
244
  await act(async () => {
253
245
  tree = await create(wrapComponent(route));
254
246
  });
255
247
  const instance = tree.root;
256
248
  const menu = instance.findByType(MenuActionMore);
257
- const gotoActivityLog = menu.props.listMenuItem[2];
249
+ const gotoActivityLog = menu.props.listMenuItem[1];
258
250
 
259
251
  await act(async () => {
260
252
  await menu.props.onItemClick(gotoActivityLog);
@@ -262,9 +254,9 @@ describe('Test ScriptDetail', () => {
262
254
  expect(mockNavigate).toHaveBeenCalledWith(Routes.ActivityLog, {
263
255
  id: route.params.id,
264
256
  type: activityLogType,
265
- share: route.params.unit,
257
+ share: unitId,
266
258
  filterEnabled: {
267
- user: !isMultiUnit,
259
+ user: !!unitId,
268
260
  date: true,
269
261
  },
270
262
  });
@@ -272,18 +264,19 @@ describe('Test ScriptDetail', () => {
272
264
  };
273
265
 
274
266
  _testGoToActivityLog(
267
+ 1,
275
268
  AUTOMATE_TYPE.ONE_TAP,
276
269
  `automate.${AUTOMATE_TYPE.ONE_TAP}`,
277
- false
270
+ 2
278
271
  );
279
- _testGoToActivityLog(AUTOMATE_TYPE.VALUE_CHANGE, 'automate', false);
280
- _testGoToActivityLog(AUTOMATE_TYPE.VALUE_CHANGE, 'automate', true);
272
+ _testGoToActivityLog(2, AUTOMATE_TYPE.VALUE_CHANGE, 'automate', 2);
273
+ _testGoToActivityLog(3, AUTOMATE_TYPE.VALUE_CHANGE, 'automate', undefined);
281
274
 
282
275
  it('Test render textCondition value change >', async () => {
283
276
  route.params = {
284
277
  ...route.params,
285
- type: AUTOMATE_TYPE.VALUE_CHANGE,
286
- automate: {
278
+ preAutomate: {
279
+ type: AUTOMATE_TYPE.VALUE_CHANGE,
287
280
  value_change: {
288
281
  config_name: 'Light Value',
289
282
  value: 3,
@@ -296,7 +289,7 @@ describe('Test ScriptDetail', () => {
296
289
  });
297
290
  const instance = tree.root;
298
291
  const itemAutomate = instance.findByType(ItemAutomate);
299
- expect(itemAutomate.props.textCondition).toEqual(
292
+ expect(itemAutomate.findAllByType(Text)[1].props.children).toEqual(
300
293
  'Light Value higher than 3'
301
294
  );
302
295
 
@@ -309,8 +302,8 @@ describe('Test ScriptDetail', () => {
309
302
  it('Test render textCondition value change =', async () => {
310
303
  route.params = {
311
304
  ...route.params,
312
- type: AUTOMATE_TYPE.VALUE_CHANGE,
313
- automate: {
305
+ preAutomate: {
306
+ type: AUTOMATE_TYPE.VALUE_CHANGE,
314
307
  value_change: { config_name: 'Light Value', value: 3, condition: '=' },
315
308
  },
316
309
  };
@@ -319,14 +312,16 @@ describe('Test ScriptDetail', () => {
319
312
  });
320
313
  const instance = tree.root;
321
314
  const itemAutomate = instance.findByType(ItemAutomate);
322
- expect(itemAutomate.props.textCondition).toEqual('Light Value equal 3');
315
+ expect(itemAutomate.findAllByType(Text)[1].props.children).toEqual(
316
+ 'Light Value equal 3'
317
+ );
323
318
  });
324
319
 
325
320
  it('Test render textCondition value change <', async () => {
326
321
  route.params = {
327
322
  ...route.params,
328
- type: AUTOMATE_TYPE.VALUE_CHANGE,
329
- automate: {
323
+ preAutomate: {
324
+ type: AUTOMATE_TYPE.VALUE_CHANGE,
330
325
  value_change: {
331
326
  config_name: 'Light Value',
332
327
  value: 3,
@@ -339,7 +334,7 @@ describe('Test ScriptDetail', () => {
339
334
  });
340
335
  const instance = tree.root;
341
336
  const itemAutomate = instance.findByType(ItemAutomate);
342
- expect(itemAutomate.props.textCondition).toEqual(
337
+ expect(itemAutomate.findAllByType(Text)[1].props.children).toEqual(
343
338
  'Light Value lower than 3'
344
339
  );
345
340
  });
@@ -347,8 +342,8 @@ describe('Test ScriptDetail', () => {
347
342
  it('Test render textCondition schedule repeat everyday', async () => {
348
343
  route.params = {
349
344
  ...route.params,
350
- type: AUTOMATE_TYPE.SCHEDULE,
351
- automate: {
345
+ preAutomate: {
346
+ type: AUTOMATE_TYPE.SCHEDULE,
352
347
  schedule: {
353
348
  repeat: 'every_day',
354
349
  date_repeat: '2022-01-02',
@@ -361,14 +356,16 @@ describe('Test ScriptDetail', () => {
361
356
  });
362
357
  const instance = tree.root;
363
358
  const itemAutomate = instance.findByType(ItemAutomate);
364
- expect(itemAutomate.props.textCondition).toEqual('Every day at 19:00');
359
+ expect(itemAutomate.findAllByType(Text)[1].props.children).toEqual(
360
+ 'Every day at 19:00'
361
+ );
365
362
  });
366
363
 
367
364
  it('Test render textCondition schedule repeat weekday', async () => {
368
365
  route.params = {
369
366
  ...route.params,
370
- type: AUTOMATE_TYPE.SCHEDULE,
371
- automate: {
367
+ preAutomate: {
368
+ type: AUTOMATE_TYPE.SCHEDULE,
372
369
  schedule: {
373
370
  repeat: 'every_week',
374
371
  date_repeat: '2022-01-02',
@@ -382,7 +379,7 @@ describe('Test ScriptDetail', () => {
382
379
  });
383
380
  const instance = tree.root;
384
381
  const itemAutomate = instance.findByType(ItemAutomate);
385
- expect(itemAutomate.props.textCondition).toEqual(
382
+ expect(itemAutomate.findAllByType(Text)[1].props.children).toEqual(
386
383
  'Mon, Tue, Thu, Sat at 19:00'
387
384
  );
388
385
  });
@@ -1,12 +1,12 @@
1
1
  import React from 'react';
2
2
  import { act, renderHook } from '@testing-library/react-hooks';
3
- import { SCProvider } from '../../../context';
4
- import { mockSCStore } from '../../../context/mockStore';
3
+ import { SCProvider } from '../../../../context';
4
+ import { mockSCStore } from '../../../../context/mockStore';
5
5
  import { useStarredScript } from '../hooks/useStarredScript';
6
6
  import MockAdapter from 'axios-mock-adapter';
7
- import api from '../../../utils/Apis/axios';
8
- import { API } from '../../../configs';
9
- import { Action } from '../../../context/actionType';
7
+ import api from '../../../../utils/Apis/axios';
8
+ import { API } from '../../../../configs';
9
+ import { Action } from '../../../../context/actionType';
10
10
 
11
11
  const mockedSetAction = jest.fn();
12
12
  const mock = new MockAdapter(api.axiosInstance);
@@ -22,8 +22,9 @@ React.useContext = mockUseContext;
22
22
 
23
23
  jest.mock('react-native-deep-linking');
24
24
 
25
- describe('Test useStarredScript', async () => {
25
+ describe('Test useStarredScript', () => {
26
26
  let props;
27
+
27
28
  beforeEach(() => {
28
29
  mockedSetAction.mockClear();
29
30
  props = {
@@ -1,8 +1,8 @@
1
1
  import { useCallback, useContext } from 'react';
2
- import { SCContext, useSCContextSelector } from '../../../context';
3
- import { Action } from '../../../context/actionType';
4
- import { axiosPost } from '../../../utils/Apis/axios';
5
- import { API } from '../../../configs';
2
+ import { SCContext, useSCContextSelector } from '../../../../context';
3
+ import { Action } from '../../../../context/actionType';
4
+ import { axiosPost } from '../../../../utils/Apis/axios';
5
+ import { API } from '../../../../configs';
6
6
 
7
7
  export const useStarredScript = (automate) => {
8
8
  const { setAction } = useContext(SCContext);
@@ -0,0 +1,346 @@
1
+ import React, {
2
+ useCallback,
3
+ useEffect,
4
+ useMemo,
5
+ useRef,
6
+ useState,
7
+ } from 'react';
8
+ import { Image, Platform, TouchableOpacity, View } from 'react-native';
9
+ import { PopoverMode } from 'react-native-popover-view';
10
+ import { IconFill, IconOutline } from '@ant-design/icons-react-native';
11
+ import { Icon } from '@ant-design/react-native';
12
+
13
+ import { useTranslations } from '../../../hooks/Common/useTranslations';
14
+ import styles from './Styles/indexStyles';
15
+ import Text from '../../../commons/Text';
16
+ import WrapHeaderScrollable from '../../../commons/Sharing/WrapHeaderScrollable';
17
+ import { API, Colors } from '../../../configs';
18
+ import { usePopover } from '../../../hooks/Common';
19
+ import { useStarredScript } from './hooks/useStarredScript';
20
+ import MenuActionMore from '../../../commons/MenuActionMore';
21
+ import Add from '../../../../assets/images/Add.svg';
22
+ import { useNavigation, useRoute } from '@react-navigation/native';
23
+ import { axiosGet, axiosPost } from '../../../utils/Apis/axios';
24
+ import FImage from '../../../commons/FImage';
25
+ import Routes from '../../../utils/Route';
26
+ import { ToastBottomHelper } from '../../../utils/Utils';
27
+ import ItemAutomate from '../../../commons/Automate/ItemAutomate';
28
+ import withPreventDoubleClick from '../../../commons/WithPreventDoubleClick';
29
+ import { AccessibilityLabel, AUTOMATE_TYPE } from '../../../configs/Constants';
30
+ import RenameScript from './Components/RenameScript';
31
+ import DeleteScript from './Components/DeleteScript';
32
+ import Images from '../../../configs/Images';
33
+
34
+ const PreventDoubleTouch = withPreventDoubleClick(TouchableOpacity);
35
+
36
+ const ScriptDetail = ({ route }) => {
37
+ const { navigate, goBack } = useNavigation();
38
+ const { params = {} } = route;
39
+ const refMenuAction = useRef();
40
+ const { childRef, showingPopover, showPopoverWithRef, hidePopover } =
41
+ usePopover();
42
+ const t = useTranslations();
43
+ const {
44
+ id,
45
+ saveAt,
46
+ preAutomate = {}, // pre-loaded automate data
47
+ newAutomate, // updated automate data
48
+ } = params;
49
+ const [automate, setAutomate] = useState(preAutomate);
50
+ const [data, setData] = useState([]);
51
+ const [isShowRename, setIsShowRename] = useState(false);
52
+ const [isShowDelete, setIsShowDelete] = useState(false);
53
+
54
+ const onShowActivityLog = useCallback(() => {
55
+ navigate(Routes.ActivityLog, {
56
+ id: id,
57
+ type:
58
+ automate?.type === AUTOMATE_TYPE.ONE_TAP
59
+ ? `automate.${AUTOMATE_TYPE.ONE_TAP}`
60
+ : 'automate',
61
+ share: automate.unit,
62
+ filterEnabled: {
63
+ date: true,
64
+ user: Boolean(automate.unit),
65
+ },
66
+ });
67
+ }, [navigate, id, automate?.type, automate.unit]);
68
+
69
+ const listMenuItem = useMemo(
70
+ () => [
71
+ { text: t('rename'), doAction: () => setIsShowRename(true) },
72
+ {
73
+ text: t('activity_log'),
74
+ doAction: onShowActivityLog,
75
+ },
76
+ {
77
+ text: t('delete_script'),
78
+ doAction: () => setIsShowDelete(true),
79
+ },
80
+ ],
81
+ [t, onShowActivityLog]
82
+ );
83
+
84
+ const handleShowMenuAction = useCallback(
85
+ () => showPopoverWithRef(refMenuAction),
86
+ [showPopoverWithRef]
87
+ );
88
+
89
+ const onItemClick = useCallback((item) => {
90
+ item.doAction();
91
+ }, []);
92
+
93
+ const fetchAutomateActions = useCallback(async () => {
94
+ const { success, data: automateData } = await axiosGet(
95
+ API.AUTOMATE.SCRIPT(id)
96
+ );
97
+ success && setData(automateData?.script_actions || []);
98
+ }, [id]);
99
+
100
+ const fetchAutomate = useCallback(async () => {
101
+ const { success, data: automateData } = await axiosGet(
102
+ API.AUTOMATE.FETCH_AUTOMATE(id)
103
+ );
104
+ success && setAutomate(automateData);
105
+ }, [id]);
106
+
107
+ const onPressEdit = useCallback(() => {
108
+ navigate(Routes.EditActionsList, {
109
+ data,
110
+ id,
111
+ unitId: automate.unit,
112
+ });
113
+ }, [data, id, navigate, automate.unit]);
114
+
115
+ const handleScriptAction = useCallback(async () => {
116
+ const { success } = await axiosPost(API.AUTOMATE.ACTION_ONE_TAP(id));
117
+ if (success) {
118
+ ToastBottomHelper.success(t('Activated successfully.'));
119
+ } else {
120
+ ToastBottomHelper.error(t('Activation failed.'));
121
+ }
122
+ }, [id, t]);
123
+
124
+ const handleUpdateAutomate = useCallback(async () => {
125
+ navigate(Routes.AddNewAutoSmart, {
126
+ automate,
127
+ closeScreen: route.name,
128
+ });
129
+ }, [navigate, automate, route.name]);
130
+
131
+ useEffect(() => {
132
+ fetchAutomate();
133
+ }, [fetchAutomate]);
134
+
135
+ const rightComponent = useMemo(
136
+ () => (
137
+ <View style={styles.rightComponent}>
138
+ <ButtonStar automate={automate} />
139
+ <TouchableOpacity
140
+ onPress={handleShowMenuAction}
141
+ ref={refMenuAction}
142
+ style={[styles.headerButton, styles.moreButton]}
143
+ >
144
+ <Icon name={'more'} size={27} color={Colors.Black} />
145
+ </TouchableOpacity>
146
+ </View>
147
+ ),
148
+ [automate, refMenuAction, handleShowMenuAction]
149
+ );
150
+
151
+ useEffect(() => {
152
+ fetchAutomateActions();
153
+ }, [fetchAutomateActions]);
154
+
155
+ useEffect(() => {
156
+ saveAt && fetchAutomateActions();
157
+ }, [saveAt, fetchAutomateActions]);
158
+
159
+ useEffect(() => {
160
+ newAutomate && setAutomate(newAutomate);
161
+ }, [newAutomate]);
162
+
163
+ return (
164
+ <View style={styles.wrap}>
165
+ <WrapHeaderScrollable
166
+ title={automate?.name}
167
+ headerAniStyle={styles.headerAniStyle}
168
+ rightComponent={rightComponent}
169
+ onGoBack={goBack}
170
+ >
171
+ <View style={styles.wrapContent}>
172
+ <Text type="H3" semibold>
173
+ {t('how_to_start')}
174
+ </Text>
175
+ <ItemAutomate automate={automate} onPress={handleUpdateAutomate} />
176
+ {automate?.type === AUTOMATE_TYPE.ONE_TAP && (
177
+ <TouchableOpacity
178
+ onPress={handleScriptAction}
179
+ style={styles.activeButton}
180
+ accessibilityLabel={AccessibilityLabel.BUTTON_ACTIVATE_ONE_TAP}
181
+ >
182
+ <Image source={Images.activeButton} />
183
+ </TouchableOpacity>
184
+ )}
185
+
186
+ <View style={styles.row}>
187
+ <Text type="H3" color={Colors.Gray9} semibold>
188
+ {t('active_list')}
189
+ </Text>
190
+ {data.length > 0 && (
191
+ <TouchableOpacity
192
+ onPress={onPressEdit}
193
+ style={styles.editButton}
194
+ accessibilityLabel={
195
+ AccessibilityLabel.BUTTON_EDIT_SCRIPT_ACTION
196
+ }
197
+ >
198
+ <Text type="Label" hilight>
199
+ {t('edit')}
200
+ </Text>
201
+ </TouchableOpacity>
202
+ )}
203
+ </View>
204
+ {data.map((item, index) => (
205
+ <Item key={item?.id} item={item} index={index} />
206
+ ))}
207
+ <ItemAdd automate={automate} index={data.length} />
208
+ </View>
209
+ </WrapHeaderScrollable>
210
+ <MenuActionMore
211
+ isVisible={showingPopover}
212
+ hideMore={hidePopover}
213
+ listMenuItem={listMenuItem}
214
+ childRef={childRef}
215
+ onItemClick={onItemClick}
216
+ isTextCenter={false}
217
+ wrapStyle={styles.wrapStyle}
218
+ mode={
219
+ Platform.OS === 'ios' ? PopoverMode.JS_MODAL : PopoverMode.RN_MODAL
220
+ }
221
+ />
222
+ <RenameScript
223
+ automate={automate}
224
+ setAutomate={setAutomate}
225
+ isVisible={isShowRename}
226
+ setIsVisible={setIsShowRename}
227
+ />
228
+ <DeleteScript
229
+ automate={automate}
230
+ setIsVisible={setIsShowDelete}
231
+ isVisible={isShowDelete}
232
+ />
233
+ </View>
234
+ );
235
+ };
236
+
237
+ const Item = ({ item, index }) => {
238
+ return (
239
+ <View style={styles.wrapItem}>
240
+ <View style={styles.leftItem}>
241
+ <Text color={Colors.Gray9} type="H4" semibold>
242
+ {index + 1 < 10 ? '0' + (index + 1) : index + 1}
243
+ </Text>
244
+ </View>
245
+ <View style={styles.rightItem}>
246
+ <FImage
247
+ source={{ uri: item?.sensor_icon_kit }}
248
+ style={styles.iconItem}
249
+ />
250
+ <View style={styles.contentItem}>
251
+ <View style={styles.titleItem}>
252
+ <Text
253
+ numberOfLines={1}
254
+ semibold
255
+ type="Label"
256
+ color={Colors.Gray7}
257
+ style={styles.paddingRight4}
258
+ >
259
+ {item?.unit_name}
260
+ </Text>
261
+ <Text
262
+ numberOfLines={1}
263
+ type="Label"
264
+ color={Colors.Gray7}
265
+ style={styles.flex1}
266
+ >
267
+ {item?.station_name}
268
+ </Text>
269
+ </View>
270
+ <Text numberOfLines={1} type="H4" color={Colors.Gray9} semibold>
271
+ {item?.sensor_name}
272
+ </Text>
273
+ <Text numberOfLines={1} type="H4" color={Colors.Gray9}>
274
+ {item?.action_name}
275
+ </Text>
276
+ </View>
277
+ </View>
278
+ </View>
279
+ );
280
+ };
281
+
282
+ const ItemAdd = ({ automate, index }) => {
283
+ const t = useTranslations();
284
+ const { navigate } = useNavigation();
285
+ const { name: currentScreenName } = useRoute();
286
+
287
+ const onPressAddAction = useCallback(() => {
288
+ const navParams = {
289
+ unitId: automate.unit,
290
+ automateId: automate.id,
291
+ closeScreen: currentScreenName,
292
+ };
293
+
294
+ navigate(
295
+ automate.unit ? Routes.SelectControlDevices : Routes.SelectUnit,
296
+ navParams
297
+ );
298
+ }, [automate.unit, automate.id, currentScreenName, navigate]);
299
+
300
+ return (
301
+ <View style={styles.wrapItem}>
302
+ <View style={styles.leftItemAdd}>
303
+ <Text style={styles.number} type="H4" semibold color={Colors.Gray7}>
304
+ {index + 1 < 10 ? '0' + (index + 1) : index + 1}
305
+ </Text>
306
+ </View>
307
+ <TouchableOpacity
308
+ onPress={onPressAddAction}
309
+ style={[styles.rightItemAdd]}
310
+ accessibilityLabel={AccessibilityLabel.BUTTON_ADD_SCRIPT_ACTION}
311
+ >
312
+ <Add />
313
+ <Text type="H4" color={Colors.Gray8} style={styles.addAction}>
314
+ {t('add_action')}
315
+ </Text>
316
+ </TouchableOpacity>
317
+ </View>
318
+ );
319
+ };
320
+
321
+ const ButtonStar = ({ automate }) => {
322
+ const { isStarred, starScript, unstarScript } = useStarredScript(automate);
323
+ const onPressStar = useCallback(async () => {
324
+ if (isStarred) {
325
+ await unstarScript();
326
+ } else {
327
+ await starScript();
328
+ }
329
+ }, [isStarred, starScript, unstarScript]);
330
+
331
+ return (
332
+ <PreventDoubleTouch
333
+ style={[styles.buttonStar, styles.headerButton]}
334
+ onPress={onPressStar}
335
+ accessibilityLabel={AccessibilityLabel.HEADER_SCRIPT_DETAIL_BUTTON_STAR}
336
+ >
337
+ {isStarred ? (
338
+ <IconFill name="star" size={25} color={Colors.Yellow6} />
339
+ ) : (
340
+ <IconOutline name="star" size={25} />
341
+ )}
342
+ </PreventDoubleTouch>
343
+ );
344
+ };
345
+
346
+ export default ScriptDetail;