@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.
- package/README.md +9 -0
- package/index.js +6 -0
- package/package.json +23 -3
- package/src/Images/Common/logo.png +0 -0
- package/src/Images/Common/logo@2x.png +0 -0
- package/src/Images/Common/logo@3x.png +0 -0
- package/src/commons/ActionTemplate/index.js +40 -25
- package/src/commons/Automate/ItemAutomate.js +2 -2
- package/src/commons/Dashboard/MyPinnedSharedUnit/index.js +82 -0
- package/src/commons/Dashboard/MyPinnedSharedUnit/styles.js +78 -0
- package/src/commons/Dashboard/MyUnit/__test__/MyUnit.test.js +60 -0
- package/src/commons/Dashboard/MyUnit/index.js +111 -0
- package/src/commons/Dashboard/MyUnit/styles.js +61 -0
- package/src/commons/Device/ConnectedViewHeader.js +4 -1
- package/src/commons/Form/TextInput.js +1 -1
- package/src/commons/MediaPlayer/index.js +6 -1
- package/src/commons/OneTapTemplate/OptionsDropdownActionTemplate.js +3 -3
- package/src/{screens/Unit/components → commons}/SearchLocation/RowLocation.js +2 -2
- package/src/{screens/Unit/components → commons}/SearchLocation/RowLocationStyles.js +1 -1
- package/src/{screens/Unit/components → commons}/SearchLocation/SearchBarLocationStyles.js +1 -1
- package/src/{screens/Unit/components → commons}/SearchLocation/__test__/RowLocation.test.js +2 -2
- package/src/{screens/Unit/components → commons}/SearchLocation/index.js +2 -2
- package/src/commons/SubUnit/OneTap/ItemOneTap.js +3 -1
- package/src/commons/SubUnit/OneTap/__test__/SubUnitAutomate.test.js +2 -0
- package/src/commons/SubUnit/ShortDetail.js +1 -1
- package/src/commons/Unit/SharedUnit.js +2 -2
- package/src/configs/API.js +11 -4
- package/src/configs/Constants.js +19 -6
- package/src/configs/Images.js +1 -0
- package/src/iot/RemoteControl/Bluetooth.js +10 -1
- package/src/iot/RemoteControl/Internet.js +0 -2
- package/src/navigations/AddDeviceStack.js +5 -0
- package/src/navigations/AddUnitStack.js +2 -0
- package/src/navigations/UnitStack.js +8 -0
- package/src/screens/ActivityLog/FilterPopup.js +24 -17
- package/src/screens/ActivityLog/ItemLog.js +26 -22
- package/src/screens/ActivityLog/__test__/FilterPopup.test.js +1 -0
- package/src/screens/ActivityLog/__test__/ItemLog.test.js +0 -20
- package/src/screens/ActivityLog/__test__/index.test.js +3 -0
- package/src/screens/ActivityLog/hooks/__test__/index.test.js +8 -0
- package/src/screens/ActivityLog/hooks/index.js +5 -9
- package/src/screens/ActivityLog/index.js +4 -4
- package/src/screens/ActivityLog/styles/filterPopupStyles.js +3 -0
- package/src/screens/AddCommon/SelectSubUnit.js +10 -1
- package/src/screens/AddCommon/SelectUnit.js +11 -0
- package/src/screens/AddLocationMaps/index.js +124 -74
- package/src/screens/AddLocationMaps/indexStyle.js +58 -0
- package/src/screens/AddNewAction/SelectAction.js +59 -4
- package/src/screens/AddNewAction/SelectSensorDevices.js +27 -5
- package/src/screens/AddNewAction/SetupSensor.js +1 -6
- package/src/screens/AddNewAction/__test__/SelectAction.test.js +6 -4
- package/src/screens/AddNewAutoSmart/__test__/AddNewAutoSmart.test.js +11 -1
- package/src/screens/AddNewAutoSmart/index.js +24 -13
- package/src/screens/AddNewDevice/ConnectingDevices.js +3 -0
- package/src/screens/AddNewGateway/ConnectingGatewayStyles.js +10 -1
- package/src/screens/AddNewOneTap/__test__/AddNewOneTap.test.js +9 -1
- package/src/screens/AddNewOneTap/index.js +11 -6
- package/src/screens/Automate/MultiUnits.js +14 -53
- package/src/screens/Automate/__test__/MultiUnits.test.js +5 -246
- package/src/screens/Automate/__test__/index.test.js +1 -0
- package/src/screens/Automate/index.js +1 -0
- package/src/screens/Device/__test__/detail.test.js +14 -0
- package/src/screens/Device/components/DetailHistoryChart.js +63 -0
- package/src/screens/Device/components/EmergencyCountdown.js +29 -0
- package/src/screens/Device/components/SensorConnectStatusViewHeader.js +57 -0
- package/src/screens/Device/components/SensorDisplayItem.js +127 -0
- package/src/screens/Device/detail.js +81 -294
- package/src/screens/Device/hooks/useDisconnectedDevice.js +63 -0
- package/src/screens/Device/styles.js +0 -10
- package/src/screens/GuestInfo/components/RecurringDetail.js +2 -2
- package/src/screens/Notification/components/NotificationItem.js +31 -14
- package/src/screens/Notification/styles/NotificationItemStyles.js +5 -0
- package/src/screens/ScanChipQR/__test__/ScanChipQR.test.js +12 -3
- package/src/screens/ScanChipQR/components/QRScan/__test__/QRScan.test.js +11 -2
- package/src/screens/ScanSensorQR/__test__/ScanSensorQR.test.js +12 -3
- package/src/screens/ScriptDetail/__test__/index.test.js +83 -3
- package/src/screens/ScriptDetail/hooks/index.js +4 -0
- package/src/screens/ScriptDetail/index.js +65 -4
- package/src/screens/SetSchedule/__test__/SelectWeekday.test.js +2 -2
- package/src/screens/SetSchedule/__test__/index.test.js +8 -0
- package/src/screens/SetSchedule/components/SelectWeekday.js +13 -7
- package/src/screens/SetSchedule/index.js +28 -6
- package/src/screens/Sharing/Components/__test__/TitleCheckBox.test.js +38 -0
- package/src/screens/SubUnit/AddSubUnit.js +113 -29
- package/src/screens/SubUnit/AddSubUnitStyles.js +10 -0
- package/src/screens/SubUnit/__test__/AddSubUnit.test.js +1 -0
- package/src/screens/TDSGuide/index.js +15 -19
- package/src/screens/Unit/MoreMenu.js +6 -1
- package/src/screens/Unit/SelectLocation.js +2 -3
- package/src/screens/Unit/SmartAccount.js +141 -0
- package/src/screens/Unit/SmartAccountItem.js +51 -0
- package/src/screens/Unit/SmartAccountStyles.js +46 -0
- package/src/screens/Unit/__test__/SmartAccount.test.js +58 -0
- package/src/screens/Unit/hook/useStateAlertRemove.js +36 -0
- package/src/utils/I18n/translations/en.json +26 -2
- package/src/utils/I18n/translations/vi.json +38 -14
- package/src/utils/Route/index.js +4 -0
- package/src/utils/Validation.js +3 -1
|
@@ -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 '
|
|
6
|
-
import { mockSCStore } from '
|
|
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 '
|
|
4
|
+
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
5
5
|
|
|
6
|
-
import { Colors } from '
|
|
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 () => {
|
|
@@ -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>
|
package/src/configs/API.js
CHANGED
|
@@ -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
|
-
|
|
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;
|
package/src/configs/Constants.js
CHANGED
|
@@ -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: '
|
|
107
|
-
explanation: '
|
|
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: '
|
|
113
|
-
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: '
|
|
119
|
-
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
|
};
|
package/src/configs/Images.js
CHANGED
|
@@ -106,7 +106,7 @@ export const getDeviceByName = (name) => {
|
|
|
106
106
|
};
|
|
107
107
|
|
|
108
108
|
export const isDeviceConnected = (deviceName) => {
|
|
109
|
-
return
|
|
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
|
|
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
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
<
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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
|
|
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
|
|
35
|
-
|
|
36
|
-
|
|
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']:
|
|
46
|
+
['action']: DetailLog,
|
|
43
47
|
['emergency_event']: DetailEmergencyEventLog,
|
|
44
|
-
['automate']:
|
|
45
|
-
[`automate.${AUTOMATE_TYPE.ONE_TAP}`]:
|
|
48
|
+
['automate']: DetailLog,
|
|
49
|
+
[`automate.${AUTOMATE_TYPE.ONE_TAP}`]: DetailLog,
|
|
46
50
|
};
|
|
47
51
|
|
|
48
52
|
const ItemLog = ({ item, type, length, index }) => {
|
|
@@ -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 = {
|
|
@@ -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 (!
|
|
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
|
)}
|
|
@@ -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
|
}
|