@eohjsc/react-native-smart-city 0.2.45 → 0.2.49

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 (98) hide show
  1. package/README.md +9 -0
  2. package/index.js +6 -0
  3. package/package.json +23 -3
  4. package/src/Images/Common/logo.png +0 -0
  5. package/src/Images/Common/logo@2x.png +0 -0
  6. package/src/Images/Common/logo@3x.png +0 -0
  7. package/src/commons/ActionTemplate/index.js +40 -25
  8. package/src/commons/Automate/ItemAutomate.js +2 -2
  9. package/src/commons/Dashboard/MyPinnedSharedUnit/index.js +82 -0
  10. package/src/commons/Dashboard/MyPinnedSharedUnit/styles.js +78 -0
  11. package/src/commons/Dashboard/MyUnit/__test__/MyUnit.test.js +60 -0
  12. package/src/commons/Dashboard/MyUnit/index.js +111 -0
  13. package/src/commons/Dashboard/MyUnit/styles.js +61 -0
  14. package/src/commons/Device/ConnectedViewHeader.js +4 -1
  15. package/src/commons/Form/TextInput.js +1 -1
  16. package/src/commons/MediaPlayer/index.js +6 -1
  17. package/src/commons/OneTapTemplate/OptionsDropdownActionTemplate.js +3 -3
  18. package/src/{screens/Unit/components → commons}/SearchLocation/RowLocation.js +2 -2
  19. package/src/{screens/Unit/components → commons}/SearchLocation/RowLocationStyles.js +1 -1
  20. package/src/{screens/Unit/components → commons}/SearchLocation/SearchBarLocationStyles.js +1 -1
  21. package/src/{screens/Unit/components → commons}/SearchLocation/__test__/RowLocation.test.js +2 -2
  22. package/src/{screens/Unit/components → commons}/SearchLocation/index.js +2 -2
  23. package/src/commons/SubUnit/OneTap/ItemOneTap.js +3 -1
  24. package/src/commons/SubUnit/OneTap/__test__/SubUnitAutomate.test.js +2 -0
  25. package/src/commons/SubUnit/ShortDetail.js +1 -1
  26. package/src/commons/Unit/SharedUnit.js +2 -2
  27. package/src/configs/API.js +11 -4
  28. package/src/configs/Constants.js +19 -6
  29. package/src/configs/Images.js +1 -0
  30. package/src/iot/RemoteControl/Bluetooth.js +10 -1
  31. package/src/iot/RemoteControl/Internet.js +0 -2
  32. package/src/navigations/AddDeviceStack.js +5 -0
  33. package/src/navigations/AddUnitStack.js +2 -0
  34. package/src/navigations/UnitStack.js +8 -0
  35. package/src/screens/ActivityLog/FilterPopup.js +24 -17
  36. package/src/screens/ActivityLog/ItemLog.js +26 -22
  37. package/src/screens/ActivityLog/__test__/FilterPopup.test.js +1 -0
  38. package/src/screens/ActivityLog/__test__/ItemLog.test.js +0 -20
  39. package/src/screens/ActivityLog/__test__/index.test.js +3 -0
  40. package/src/screens/ActivityLog/hooks/__test__/index.test.js +8 -0
  41. package/src/screens/ActivityLog/hooks/index.js +5 -9
  42. package/src/screens/ActivityLog/index.js +4 -4
  43. package/src/screens/ActivityLog/styles/filterPopupStyles.js +3 -0
  44. package/src/screens/AddCommon/SelectSubUnit.js +10 -1
  45. package/src/screens/AddCommon/SelectUnit.js +11 -0
  46. package/src/screens/AddLocationMaps/index.js +124 -74
  47. package/src/screens/AddLocationMaps/indexStyle.js +58 -0
  48. package/src/screens/AddNewAction/SelectAction.js +59 -4
  49. package/src/screens/AddNewAction/SelectSensorDevices.js +27 -5
  50. package/src/screens/AddNewAction/SetupSensor.js +1 -6
  51. package/src/screens/AddNewAction/__test__/SelectAction.test.js +6 -4
  52. package/src/screens/AddNewAutoSmart/__test__/AddNewAutoSmart.test.js +11 -1
  53. package/src/screens/AddNewAutoSmart/index.js +24 -13
  54. package/src/screens/AddNewDevice/ConnectingDevices.js +3 -0
  55. package/src/screens/AddNewGateway/ConnectingGatewayStyles.js +10 -1
  56. package/src/screens/AddNewOneTap/__test__/AddNewOneTap.test.js +9 -1
  57. package/src/screens/AddNewOneTap/index.js +11 -6
  58. package/src/screens/Automate/MultiUnits.js +14 -53
  59. package/src/screens/Automate/__test__/MultiUnits.test.js +5 -246
  60. package/src/screens/Automate/__test__/index.test.js +1 -0
  61. package/src/screens/Automate/index.js +1 -0
  62. package/src/screens/Device/__test__/detail.test.js +14 -0
  63. package/src/screens/Device/components/DetailHistoryChart.js +63 -0
  64. package/src/screens/Device/components/EmergencyCountdown.js +29 -0
  65. package/src/screens/Device/components/SensorConnectStatusViewHeader.js +57 -0
  66. package/src/screens/Device/components/SensorDisplayItem.js +127 -0
  67. package/src/screens/Device/detail.js +81 -294
  68. package/src/screens/Device/hooks/useDisconnectedDevice.js +63 -0
  69. package/src/screens/Device/styles.js +0 -10
  70. package/src/screens/GuestInfo/components/RecurringDetail.js +2 -2
  71. package/src/screens/Notification/components/NotificationItem.js +31 -14
  72. package/src/screens/Notification/styles/NotificationItemStyles.js +5 -0
  73. package/src/screens/ScanChipQR/__test__/ScanChipQR.test.js +12 -3
  74. package/src/screens/ScanChipQR/components/QRScan/__test__/QRScan.test.js +11 -2
  75. package/src/screens/ScanSensorQR/__test__/ScanSensorQR.test.js +12 -3
  76. package/src/screens/ScriptDetail/__test__/index.test.js +83 -3
  77. package/src/screens/ScriptDetail/hooks/index.js +4 -0
  78. package/src/screens/ScriptDetail/index.js +65 -4
  79. package/src/screens/SetSchedule/__test__/SelectWeekday.test.js +2 -2
  80. package/src/screens/SetSchedule/__test__/index.test.js +8 -0
  81. package/src/screens/SetSchedule/components/SelectWeekday.js +13 -7
  82. package/src/screens/SetSchedule/index.js +28 -6
  83. package/src/screens/Sharing/Components/__test__/TitleCheckBox.test.js +38 -0
  84. package/src/screens/SubUnit/AddSubUnit.js +113 -29
  85. package/src/screens/SubUnit/AddSubUnitStyles.js +10 -0
  86. package/src/screens/SubUnit/__test__/AddSubUnit.test.js +1 -0
  87. package/src/screens/TDSGuide/index.js +15 -19
  88. package/src/screens/Unit/MoreMenu.js +6 -1
  89. package/src/screens/Unit/SelectLocation.js +2 -3
  90. package/src/screens/Unit/SmartAccount.js +141 -0
  91. package/src/screens/Unit/SmartAccountItem.js +51 -0
  92. package/src/screens/Unit/SmartAccountStyles.js +46 -0
  93. package/src/screens/Unit/__test__/SmartAccount.test.js +58 -0
  94. package/src/screens/Unit/hook/useStateAlertRemove.js +36 -0
  95. package/src/utils/I18n/translations/en.json +26 -2
  96. package/src/utils/I18n/translations/vi.json +38 -14
  97. package/src/utils/Route/index.js +4 -0
  98. package/src/utils/Validation.js +3 -1
@@ -1,5 +1,5 @@
1
1
  import { StyleSheet } from 'react-native';
2
- import { Colors, Fonts } from '../../../../configs';
2
+ import { Colors, Fonts } from '../../configs';
3
3
 
4
4
  export default StyleSheet.create({
5
5
  container: {
@@ -2,8 +2,8 @@ import React from 'react';
2
2
  import { TouchableOpacity } from 'react-native';
3
3
  import { act, create } from 'react-test-renderer';
4
4
  import RowLocation from '../RowLocation';
5
- import { SCProvider } from '../../../../../context';
6
- import { mockSCStore } from '../../../../../context/mockStore';
5
+ import { SCProvider } from '../../../context';
6
+ import { mockSCStore } from '../../../context/mockStore';
7
7
 
8
8
  const mockFunc = jest.fn();
9
9
 
@@ -1,9 +1,9 @@
1
1
  import React, { memo } from 'react';
2
2
  import { View, TextInput } from 'react-native';
3
3
  import { IconOutline } from '@ant-design/icons-react-native';
4
- import { useTranslations } from '../../../../hooks/Common/useTranslations';
4
+ import { useTranslations } from '../../hooks/Common/useTranslations';
5
5
 
6
- import { Colors } from '../../../../configs';
6
+ import { Colors } from '../../configs';
7
7
  import styles from './SearchBarLocationStyles';
8
8
 
9
9
  const SearchBarLocation = memo(({ input, onTextInput }) => {
@@ -20,7 +20,7 @@ import { useGetIdUser } from '../../../hooks/Common';
20
20
  import { AUTOMATE_TYPE, TESTID } from '../../../configs/Constants';
21
21
 
22
22
  const ItemOneTap = memo(
23
- ({ isOwner, automate, unit, wrapSyles, onPressItem }) => {
23
+ ({ isOwner, automate = {}, unit, wrapSyles, onPressItem }) => {
24
24
  const { navigate } = useNavigation();
25
25
  const {
26
26
  id,
@@ -54,6 +54,7 @@ const ItemOneTap = memo(
54
54
  const goToDetail = useCallback(() => {
55
55
  navigate(Routes.ScriptDetail, {
56
56
  id,
57
+ automate,
57
58
  name: script?.name,
58
59
  type: type,
59
60
  havePermission: isOwner || user === idUser,
@@ -61,6 +62,7 @@ const ItemOneTap = memo(
61
62
  textCondition,
62
63
  });
63
64
  }, [
65
+ automate,
64
66
  isOwner,
65
67
  user,
66
68
  idUser,
@@ -100,6 +100,7 @@ describe('test Item', () => {
100
100
  type: 'one_tap',
101
101
  unit: undefined,
102
102
  textCondition: null,
103
+ automate: data.automates[0],
103
104
  });
104
105
 
105
106
  const handleScriptAction = instance.findAll(
@@ -196,6 +197,7 @@ describe('test Item', () => {
196
197
  type: 'value_change',
197
198
  unit: undefined,
198
199
  textCondition: 'Temperature higher than 29',
200
+ automate: data.automates[0],
199
201
  });
200
202
  });
201
203
  test('render SubUnitAutomate script schedule', async () => {
@@ -80,7 +80,7 @@ const ShortDetailSubUnit = ({ unit, station, isGGHomeConnected }) => {
80
80
  ? 'add_to_favorites'
81
81
  : station?.name === SubUnitName.scenario
82
82
  ? 'add_script'
83
- : 'add_new_device'
83
+ : 'add_new'
84
84
  );
85
85
 
86
86
  return (
@@ -18,8 +18,8 @@ const SharedUnit = ({
18
18
  index,
19
19
  isOptions = true,
20
20
  }) => {
21
- const t = useTranslations();
22
21
  const { unit } = item;
22
+ const t = useTranslations();
23
23
  const goToDetail = useCallback(() => {
24
24
  navigation.navigate(Routes.UnitStack, {
25
25
  screen: Routes.UnitDetail,
@@ -76,7 +76,7 @@ const SharedUnit = ({
76
76
  <View style={styles.ownerContainer}>
77
77
  <Text style={styles.name}>{unit.name}</Text>
78
78
  {unit.owner_name ? (
79
- <Text style={styles.textBy}>
79
+ <Text style={styles.textBy} testID={TESTID.SHARED_UNIT_OWN_BY}>
80
80
  {t('text_by')}
81
81
  <Text style={styles.textOwner}>{unit.owner_name}</Text>
82
82
  </Text>
@@ -2,6 +2,9 @@ import { SCConfig } from './SCConfig';
2
2
 
3
3
  const API = {
4
4
  UNIT: {
5
+ MY_UNITS: () => SCConfig.apiRoot + '/property_manager/units/mine/',
6
+ SHARED_UNITS: () => SCConfig.apiRoot + '/property_manager/shared_units/',
7
+ CREATE_UNIT: () => SCConfig.apiRoot + '/property_manager/units/',
5
8
  UNIT_DETAIL: (id) => SCConfig.apiRoot + `/property_manager/units/${id}/`,
6
9
  UNIT_NEAR_ME: (lat, lon, page) =>
7
10
  SCConfig.apiRoot +
@@ -172,10 +175,8 @@ const API = {
172
175
  },
173
176
  NOTIFICATION: {
174
177
  LIST_ALL_NOTIFICATIONS: (page, type) =>
175
- SCConfig.apiRoot +
176
- `/notifications/notifications/?page=${page}&type=${type}`,
177
- SET_READ: (id) =>
178
- SCConfig.apiRoot + `/notifications/notifications/${id}/set_read/`,
178
+ SCConfig.apiRoot + `/notifications/root/?page=${page}&type=${type}`,
179
+ SET_READ: (id) => SCConfig.apiRoot + `/notifications/root/${id}/set_read/`,
179
180
  },
180
181
  EXTERNAL: {
181
182
  GOOGLE_MAP: {
@@ -185,6 +186,12 @@ const API = {
185
186
  'https://maps.googleapis.com/maps/api/place/details/json',
186
187
  },
187
188
  },
189
+ SMART_ACCOUNT: {
190
+ LIST_SMART_ACCOUNT: () =>
191
+ SCConfig.apiRoot + '/smart_account/smart_accounts/',
192
+ REMOVE_SMART_ACCOUNT: (id) =>
193
+ SCConfig.apiRoot + `/smart_account/smart_accounts/${id}/`,
194
+ },
188
195
  };
189
196
 
190
197
  export default API;
@@ -100,23 +100,29 @@ export const AUTOMATE_SELECT = {
100
100
  SELECT_SENSOR: 'select_sensor',
101
101
  };
102
102
 
103
+ export const CONDITION_TYPES = {
104
+ IS: 'IS',
105
+ IS_BELOW: 'IS_BELOW',
106
+ IS_ABOVE: 'IS_ABOVE',
107
+ };
108
+
103
109
  export const AUTOMATES = {
104
110
  one_tap: {
105
111
  value: AUTOMATE_TYPE.ONE_TAP,
106
- title: 'Launch One-Tap',
107
- explanation: 'Do everything with just one button',
112
+ title: 'launch_one_tap',
113
+ explanation: 'explanation',
108
114
  icon: OneTap,
109
115
  },
110
116
  value_change: {
111
117
  value: AUTOMATE_TYPE.VALUE_CHANGE,
112
- title: 'Value change',
113
- explanation: 'Short Explanation',
118
+ title: 'value_change',
119
+ explanation: 'short_explanation',
114
120
  icon: ValueChange,
115
121
  },
116
122
  schedule: {
117
123
  value: AUTOMATE_TYPE.SCHEDULE,
118
- title: 'Schedule',
119
- explanation: 'Short Explanation',
124
+ title: 'schedule',
125
+ explanation: 'short_explanation',
120
126
  icon: Schedule,
121
127
  },
122
128
  };
@@ -580,4 +586,11 @@ export const NOTIFICATION_TYPES = {
580
586
  STOP_VIOLATION_FREE_PARKING_ZONE: 'STOP_VIOLATION_FREE_PARKING_ZONE',
581
587
  PARKING_COMPLETED_DUE_TO_CAR_LEAVE: 'PARKING_COMPLETED_DUE_TO_CAR_LEAVE',
582
588
  NOTIFY_INVITE_MEMBER: 'NOTIFY_INVITE_MEMBER',
589
+ REMINDER: 'REMINDER',
590
+ };
591
+
592
+ export const ACTIVITY_LOG_TYPES = {
593
+ AUTO_ACTIVATED: 'AUTO_ACTIVATED',
594
+ ACTIVATED_BY: 'ACTIVATED_BY',
595
+ SCRIPT_UPDATED_BY: 'SCRIPT_UPDATED_BY',
583
596
  };
@@ -6,4 +6,5 @@ export default {
6
6
  fullscreen: require('../Images/Common/fullscreen.png'),
7
7
  file: require('../Images/Common/file.png'),
8
8
  activeButton: require('../Images/Common/ActiveButton.png'),
9
+ logo: require('../Images/Common/logo.png'),
9
10
  };
@@ -106,7 +106,7 @@ export const getDeviceByName = (name) => {
106
106
  };
107
107
 
108
108
  export const isDeviceConnected = (deviceName) => {
109
- return needToScanDevices.some((i) => i === deviceName);
109
+ return !!bluetoothDevices[deviceName];
110
110
  };
111
111
 
112
112
  export const subcribeCharacteristicNotify = async (device, onListener) => {
@@ -159,3 +159,12 @@ export const sendDataOverBluetooth = async (
159
159
 
160
160
  await device.cancelConnection();
161
161
  };
162
+
163
+ export const isBluetoothEnabled = async () => {
164
+ const state = await bleManager.state();
165
+ return state === 'PoweredOn';
166
+ };
167
+
168
+ export const enableBluetoothForAndroid = async () => {
169
+ await bleManager.enable();
170
+ };
@@ -18,7 +18,5 @@ export const sendCommandOverInternet = async (sensor, action, data, source) => {
18
18
  });
19
19
  if (success) {
20
20
  ToastBottomHelper.success(t('Command is sent to device via internet'));
21
- } else {
22
- ToastBottomHelper.error(t('Command is fail to send via internet'));
23
21
  }
24
22
  };
@@ -2,6 +2,7 @@ import { createStackNavigator } from '@react-navigation/stack';
2
2
  import React, { memo } from 'react';
3
3
 
4
4
  import AddCommonSelectUnit from '../screens/AddCommon/SelectUnit';
5
+ import AddCommonSelectSubUnit from '../screens/AddCommon/SelectSubUnit';
5
6
  import AddNewDevice from '../screens/AddNewDevice';
6
7
  import ConnectDevices from '../screens/AddNewDevice/ConnectDevices';
7
8
  import ConnectingDevices from '../screens/AddNewDevice/ConnectingDevices';
@@ -21,6 +22,10 @@ export const AddDeviceStack = memo(() => {
21
22
  name={Route.AddCommonSelectUnit}
22
23
  component={AddCommonSelectUnit}
23
24
  />
25
+ <Stack.Screen
26
+ name={Route.AddCommonSelectSubUnit}
27
+ component={AddCommonSelectSubUnit}
28
+ />
24
29
  <Stack.Screen name={Route.AddNewDevice} component={AddNewDevice} />
25
30
  <Stack.Screen name={Route.ScanSensorQR} component={ScanSensorQR} />
26
31
  <Stack.Screen
@@ -2,6 +2,7 @@ import { createStackNavigator } from '@react-navigation/stack';
2
2
  import React, { memo } from 'react';
3
3
 
4
4
  import AddLocationMaps from '../screens/AddLocationMaps'; //containers/AddLocationMaps
5
+ import AddSubUnit from '../screens/SubUnit/AddSubUnit';
5
6
  import Route from '../utils/Route'; // utils/Route
6
7
 
7
8
  const Stack = createStackNavigator();
@@ -13,6 +14,7 @@ export const AddUnitStack = memo(() => {
13
14
  headerShown: false,
14
15
  }}
15
16
  >
17
+ <Stack.Screen name={Route.AddSubUnit} component={AddSubUnit} />
16
18
  <Stack.Screen
17
19
  name={Route.AddLocationMaps}
18
20
  component={AddLocationMaps}
@@ -15,6 +15,7 @@ import SharingMemberList from '../screens/Sharing/MemberList';
15
15
  import ManageSubUnit from '../screens/SubUnit/ManageSubUnit';
16
16
  import SelectLocation from '../screens/Unit/SelectLocation';
17
17
  import ManageUnit from '../screens/Unit/ManageUnit';
18
+ import ListSmartAccount from '../screens/Unit/SmartAccount';
18
19
  import MyAllUnit from '../screens/Unit/MyAllUnit';
19
20
  import SubUnitDetail from '../screens/SubUnit/Detail';
20
21
  import UnitDetail from '../screens/Unit/Detail';
@@ -82,6 +83,13 @@ export const UnitStack = memo((props) => {
82
83
  headerShown: false,
83
84
  }}
84
85
  />
86
+ <Stack.Screen
87
+ name={Route.ListSmartAccount}
88
+ component={ListSmartAccount}
89
+ options={{
90
+ headerShown: false,
91
+ }}
92
+ />
85
93
  <Stack.Screen
86
94
  name={Route.EditDevice}
87
95
  component={EditDevice}
@@ -45,6 +45,7 @@ const FilterPopup = ({
45
45
  onShow,
46
46
  members,
47
47
  filters,
48
+ userFilterEnabled,
48
49
  onApply,
49
50
  }) => {
50
51
  const t = useTranslations();
@@ -193,7 +194,9 @@ const FilterPopup = ({
193
194
  animationOut={'zoomOut'}
194
195
  style={styles.wrapPopup}
195
196
  >
196
- <View style={styles.popup}>
197
+ <View
198
+ style={[styles.popup, !userFilterEnabled && styles.heigh50percent]}
199
+ >
197
200
  <>
198
201
  <Text type="H4" style={styles.title} bold>
199
202
  {t('filters')}
@@ -210,22 +213,26 @@ const FilterPopup = ({
210
213
  formatType="date"
211
214
  inline={false}
212
215
  />
213
- <Text type="H4" style={styles.sectionTitle} bold>
214
- {t('by_user')}
215
- </Text>
216
- <ScrollView>
217
- {members.map((member, index) => (
218
- <RowMember
219
- key={index}
220
- member={member}
221
- isSelected={
222
- selectedUsers.includes(member.id) ||
223
- (member.id === 0 && selectedUsers.length === 0)
224
- }
225
- onSelect={handleOnSelectUser}
226
- />
227
- ))}
228
- </ScrollView>
216
+ {userFilterEnabled && (
217
+ <>
218
+ <Text type="H4" style={styles.sectionTitle} bold>
219
+ {t('by_user')}
220
+ </Text>
221
+ <ScrollView>
222
+ {members.map((member, index) => (
223
+ <RowMember
224
+ key={index}
225
+ member={member}
226
+ isSelected={
227
+ selectedUsers.includes(member.id) ||
228
+ (member.id === 0 && selectedUsers.length === 0)
229
+ }
230
+ onSelect={handleOnSelectUser}
231
+ />
232
+ ))}
233
+ </ScrollView>
234
+ </>
235
+ )}
229
236
  <View style={styles.separator} />
230
237
  </>
231
238
  <BottomButtonView
@@ -1,22 +1,10 @@
1
1
  import React from 'react';
2
- import { View, Text } from 'react-native';
2
+ import { View } from 'react-native';
3
3
  import moment from 'moment';
4
+ import Text from '../../commons/Text';
4
5
  import t from '../../hooks/Common/useTranslations';
5
6
  import styles from './styles/itemLogStyles';
6
- import { AUTOMATE_TYPE } from '../../configs/Constants';
7
-
8
- const DetailManualActivatedLog = ({ item }) => (
9
- <Text style={styles.text}>
10
- {item.action_name
11
- ? `${item.action_name} ${t('by')} `
12
- : `${t('activated_by')} `}
13
- <Text style={styles.name}>{item.name || item.params?.username}</Text>
14
- </Text>
15
- );
16
-
17
- const DetailAutoActivatedLog = () => (
18
- <Text style={styles.text}>{t('auto_activated')}</Text>
19
- );
7
+ import { AUTOMATE_TYPE, ACTIVITY_LOG_TYPES } from '../../configs/Constants';
20
8
 
21
9
  const DetailEmergencyEventLog = ({ item }) => (
22
10
  <Text style={styles.text}>
@@ -31,18 +19,34 @@ const DetailEmergencyEventLog = ({ item }) => (
31
19
  </Text>
32
20
  );
33
21
 
34
- const DetailAutomateLog = ({ item }) => {
35
- if (item.content_code === 'AUTO_ACTIVATED') {
36
- return <DetailAutoActivatedLog />;
22
+ const DetailLog = ({ item }) => {
23
+ switch (item.content_code) {
24
+ case ACTIVITY_LOG_TYPES.AUTO_ACTIVATED:
25
+ return <Text style={styles.text}>{t('auto_activated')}</Text>;
26
+ case ACTIVITY_LOG_TYPES.ACTIVATED_BY:
27
+ return (
28
+ <Text style={styles.text}>
29
+ {item.action_name
30
+ ? `${item.action_name} ${t('by')} `
31
+ : `${t('activated_by')} `}
32
+ <Text style={styles.name}>{item.name || item.params?.username}</Text>
33
+ </Text>
34
+ );
35
+ case ACTIVITY_LOG_TYPES.SCRIPT_UPDATED_BY:
36
+ return (
37
+ <Text style={styles.text}>
38
+ {`${t('script_updated_by')} `}
39
+ <Text style={styles.name}>{item.name || item.params?.username}</Text>
40
+ </Text>
41
+ );
37
42
  }
38
- return <DetailManualActivatedLog item={item} />;
39
43
  };
40
44
 
41
45
  const itemDetailMaps = {
42
- ['action']: DetailManualActivatedLog,
46
+ ['action']: DetailLog,
43
47
  ['emergency_event']: DetailEmergencyEventLog,
44
- ['automate']: DetailAutomateLog,
45
- [`automate.${AUTOMATE_TYPE.ONE_TAP}`]: DetailAutomateLog,
48
+ ['automate']: DetailLog,
49
+ [`automate.${AUTOMATE_TYPE.ONE_TAP}`]: DetailLog,
46
50
  };
47
51
 
48
52
  const ItemLog = ({ item, type, length, index }) => {
@@ -39,6 +39,7 @@ test('test FilterPopup', async () => {
39
39
  filters: {
40
40
  users: [],
41
41
  },
42
+ userFilterEnabled: true,
42
43
  onHide: mockOnHide,
43
44
  onApply: mockOnApply,
44
45
  };
@@ -19,26 +19,6 @@ jest.mock('react', () => {
19
19
  };
20
20
  });
21
21
 
22
- test('test ItemLog action', () => {
23
- let tree;
24
- let props = {
25
- item: {
26
- action_name: 'action',
27
- name: 'name',
28
- created_at: '2021-07-02T15:48:24.917932Z',
29
- },
30
- type: 'action',
31
- length: 1,
32
- index: 0,
33
- };
34
- act(() => {
35
- tree = create(wrapComponent(props));
36
- });
37
- const instance = tree.root;
38
- const texts = instance.findAllByType(Text);
39
- expect(texts[2].props.children).toBe(props.item.name);
40
- });
41
-
42
22
  test('test ItemLog smart assistant', () => {
43
23
  let tree;
44
24
  let props = {
@@ -44,6 +44,9 @@ describe('Test Activity log', () => {
44
44
  params: {
45
45
  id: 1,
46
46
  type: `automate.${AUTOMATE_TYPE.ONE_TAP}`,
47
+ filterEnabled: {
48
+ user: 'user',
49
+ },
47
50
  },
48
51
  };
49
52
  Date.now = jest.fn(() => new Date('2021-07-02T15:48:24.917932Z'));
@@ -65,6 +65,10 @@ describe('Test useActivityLog', () => {
65
65
  props = {
66
66
  id: 1,
67
67
  type: 'action',
68
+ filterEnabled: {
69
+ date: false,
70
+ user: false,
71
+ },
68
72
  };
69
73
  });
70
74
 
@@ -113,6 +117,7 @@ describe('Test useActivityLog', () => {
113
117
 
114
118
  it('Test onRefresh activity log of automate one tap', async () => {
115
119
  props.type = `automate.${AUTOMATE_TYPE.ONE_TAP}`;
120
+ props.filterEnabled.date = true;
116
121
  const { result } = renderHook(() => useActivityLog(props));
117
122
  axios.get.mockImplementation(() => ({
118
123
  status: 200,
@@ -178,6 +183,7 @@ describe('Test useActivityLog', () => {
178
183
  it('Test fetchMembers', async () => {
179
184
  props.type = `automate.${AUTOMATE_TYPE.ONE_TAP}`;
180
185
  props.share = { id: 2 };
186
+ props.filterEnabled.user = true;
181
187
  const { result } = renderHook(() => useActivityLog(props));
182
188
  axios.get.mockImplementation(() => ({
183
189
  status: 200,
@@ -202,6 +208,8 @@ describe('Test useActivityLog', () => {
202
208
 
203
209
  it('Test filter by users', async () => {
204
210
  props.type = `automate.${AUTOMATE_TYPE.ONE_TAP}`;
211
+ props.filterEnabled.date = true;
212
+ props.filterEnabled.user = true;
205
213
  const { result } = renderHook(() => useActivityLog(props));
206
214
 
207
215
  const userIds = [1, 2];
@@ -12,26 +12,22 @@ const apiMaps = {
12
12
  url: () => API.SENSOR.ACTIVITY_LOG(),
13
13
  params: (id) => ({ id: id }),
14
14
  standardizeData: getDataForList,
15
- filterEnabled: false,
16
15
  },
17
16
  ['emergency_event']: {
18
17
  url: () => API.EMERGENCY_BUTTON.ACTIVITY_LOG(),
19
18
  params: (id) => ({ device_id: id }),
20
19
  standardizeData: getEmergencyEventDataForList,
21
- filterEnabled: false,
22
20
  },
23
21
  ['automate']: {
24
22
  url: (id) => API.AUTOMATE.ACTIVITY_LOG(id),
25
23
  params: () => ({}),
26
24
  standardizeData: getDataForList,
27
- filterEnabled: false,
28
25
  },
29
26
  [`automate.${AUTOMATE_TYPE.ONE_TAP}`]: {
30
27
  url: (id) => API.AUTOMATE.ACTIVITY_LOG(id),
31
28
  params: () => ({}),
32
29
  standardizeData: getDataForList,
33
30
  memberUrl: (id) => API.SHARE.UNITS_MEMBERS(id),
34
- filterEnabled: true,
35
31
  },
36
32
  };
37
33
 
@@ -42,7 +38,7 @@ String.prototype.capitalize = function () {
42
38
 
43
39
  let dataTemp = [];
44
40
 
45
- export default ({ id, type, share }) => {
41
+ export default ({ id, type, share, filterEnabled }) => {
46
42
  const [data, setData] = useState([]);
47
43
  const [isLoading, setIsLoading] = useState(false);
48
44
  const [page, setPage] = useState(1);
@@ -55,7 +51,6 @@ export default ({ id, type, share }) => {
55
51
  date_to: moment().valueOf(),
56
52
  });
57
53
  const api = apiMaps[type];
58
- const { filterEnabled } = api;
59
54
 
60
55
  const fetchData = async (filters) => {
61
56
  const { page } = filters;
@@ -69,10 +64,12 @@ export default ({ id, type, share }) => {
69
64
  setIsLoading(true);
70
65
  }
71
66
  const params = new URLSearchParams();
72
- if (filterEnabled) {
67
+ if (filterEnabled.user) {
73
68
  filters.users.map((id) => {
74
69
  params.append('users', id);
75
70
  });
71
+ }
72
+ if (filterEnabled.date) {
76
73
  params.append(
77
74
  'date_from',
78
75
  moment(filters.date_from).format('YYYY-MM-DD')
@@ -102,7 +99,7 @@ export default ({ id, type, share }) => {
102
99
 
103
100
  const fetchMembers = async () => {
104
101
  const api = apiMaps[type];
105
- if (!api.memberUrl) {
102
+ if (!filterEnabled.user) {
106
103
  return;
107
104
  }
108
105
  const { success, data } = await axiosGet(api.memberUrl(share.id));
@@ -124,7 +121,6 @@ export default ({ id, type, share }) => {
124
121
  onLoadMore,
125
122
  members,
126
123
  fetchMembers,
127
- filterEnabled,
128
124
  filters,
129
125
  setFilters,
130
126
  };
@@ -23,7 +23,7 @@ const keyExtractor = (item) => item.id;
23
23
 
24
24
  const ActivityLogScreen = ({ route }) => {
25
25
  const t = useTranslations();
26
- const { id, type, share } = route.params;
26
+ const { id, type, share, filterEnabled } = route.params;
27
27
  const {
28
28
  data,
29
29
  isLoading,
@@ -32,10 +32,9 @@ const ActivityLogScreen = ({ route }) => {
32
32
  onRefresh,
33
33
  members,
34
34
  fetchMembers,
35
- filterEnabled,
36
35
  filters,
37
36
  setFilters,
38
- } = useActivityLog({ id, type, share });
37
+ } = useActivityLog({ id, type, share, filterEnabled });
39
38
  const [showFilterPopup, setShowFilterPopup, setHideFilterPopup] =
40
39
  useBoolean();
41
40
 
@@ -117,13 +116,14 @@ const ActivityLogScreen = ({ route }) => {
117
116
  contentContainerStyle={styles.contentContainerStyle}
118
117
  />
119
118
  </View>
120
- {filterEnabled && (
119
+ {(filterEnabled.user || filterEnabled.date) && (
121
120
  <FilterPopup
122
121
  isVisible={showFilterPopup}
123
122
  onHide={setHideFilterPopup}
124
123
  onShow={setShowFilterPopup}
125
124
  members={members}
126
125
  filters={filters}
126
+ userFilterEnabled={filterEnabled.user}
127
127
  onApply={setFilters}
128
128
  />
129
129
  )}
@@ -13,6 +13,9 @@ export default StyleSheet.create({
13
13
  paddingBottom: 100,
14
14
  borderRadius: 10,
15
15
  },
16
+ heigh50percent: {
17
+ height: (Constants.height * 50) / 100,
18
+ },
16
19
  title: {
17
20
  marginBottom: 16,
18
21
  },
@@ -1,6 +1,6 @@
1
+ import React, { useCallback, useEffect, useState, useMemo } from 'react';
1
2
  import { useIsFocused, useNavigation } from '@react-navigation/native';
2
3
  import { useTranslations } from '../../hooks/Common/useTranslations';
3
- import React, { useCallback, useEffect, useState, useMemo } from 'react';
4
4
  import { SafeAreaView, ScrollView, TouchableOpacity, View } from 'react-native';
5
5
 
6
6
  import { API } from '../../configs';
@@ -28,6 +28,9 @@ const AddCommonSelectSubUnit = ({ route }) => {
28
28
  setTitle(t('add_new_gateway'));
29
29
  setSubTitle(t('select_a_sub_unit'));
30
30
  break;
31
+ case 'AddHassiDevice':
32
+ setTitle(t('select_a_sub_unit'));
33
+ break;
31
34
  default:
32
35
  setTitle(t('add_new_gateway'));
33
36
  setSubTitle(t('select_a_sub_unit'));
@@ -61,6 +64,12 @@ const AddCommonSelectSubUnit = ({ route }) => {
61
64
  ...route.params,
62
65
  });
63
66
  break;
67
+ case 'AddHassiDevice':
68
+ navigation.navigate(Routes.SmartAccountConnecting, {
69
+ listSensorIds: route.params.listSensorIds,
70
+ station: subUnits[selectedIndex]?.id,
71
+ });
72
+ break;
64
73
  default:
65
74
  break;
66
75
  }