@eohjsc/react-native-smart-city 0.2.61 → 0.2.65
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 +115 -68
- package/package.json +2 -2
- package/src/commons/ActionGroup/CurtainButtonTemplate.js +10 -2
- package/src/commons/ActionGroup/__test__/CurtainButtonTemplate.test.js +1 -1
- package/src/commons/ActionGroup/__test__/MenuActionAddSchedule.test.js +71 -0
- package/src/commons/ActionGroup/hooks/AccessScheduleDetailStyles.js +41 -0
- package/src/commons/ActionGroup/hooks/MenuActionAddSchedule.js +110 -0
- package/src/commons/ActionGroup/hooks/MenuActionAddScheduleStyle.js +69 -0
- package/src/commons/ActionGroup/hooks/RecurringDetail.js +97 -0
- package/src/commons/DateTimeRangeChange/DateTimeButton.js +6 -1
- package/src/commons/Device/HistoryChart.js +2 -1
- package/src/commons/Device/HorizontalBarChart.js +2 -1
- package/src/commons/Device/LinearChart.js +28 -1
- package/src/commons/Form/CurrencyInput.js +1 -0
- package/src/commons/SubUnit/OneTap/OneTapStyles.js +20 -1
- package/src/commons/SubUnit/OneTap/__test__/SubUnitAutomate.test.js +151 -40
- package/src/commons/SubUnit/OneTap/index.js +64 -12
- package/src/configs/Constants.js +9 -0
- package/src/iot/RemoteControl/Bluetooth.js +6 -3
- package/src/iot/RemoteControl/GoogleHome.js +5 -2
- package/src/iot/RemoteControl/Internet.js +1 -0
- package/src/iot/RemoteControl/LG.js +2 -1
- package/src/iot/RemoteControl/index.js +13 -6
- package/src/navigations/SharedStack.js +8 -4
- package/src/navigations/UnitStack.js +10 -2
- package/src/screens/ActivityLog/hooks/index.js +1 -1
- package/src/screens/AddNewAction/SelectSensorDevices.js +18 -11
- package/src/screens/AddNewAction/Styles/SelectSensorDevicesStyles.js +5 -1
- package/src/screens/AddNewAction/__test__/SelectSensorDevices.test.js +6 -1
- package/src/screens/AddNewGateway/AddNewGatewayStyles.js +6 -1
- package/src/screens/AllCamera/index.js +27 -5
- package/src/screens/Automate/MultiUnits.js +7 -4
- package/src/screens/Automate/__test__/MultiUnits.test.js +1 -1
- package/src/screens/Automate/__test__/index.test.js +12 -0
- package/src/screens/ConfirmUnitDeletion/__test__/ConfirmUnitDeletion.test.js +61 -0
- package/src/screens/ConfirmUnitDeletion/index.js +64 -0
- package/src/screens/ConfirmUnitDeletion/styles.js +37 -0
- package/src/screens/EmergencySetting/index.js +2 -0
- package/src/screens/EmergencySetting/styles.js +8 -2
- package/src/screens/ScriptDetail/Styles/indexStyles.js +3 -0
- package/src/screens/ScriptDetail/index.js +7 -1
- package/src/screens/SubUnit/AddSubUnit.js +13 -2
- package/src/screens/SubUnit/EditSubUnit.js +8 -1
- package/src/screens/SubUnit/EditSubUnitStyles.js +2 -3
- package/src/screens/SubUnit/__test__/AddSubUnit.test.js +2 -1
- package/src/screens/TDSGuide/index.js +1 -1
- package/src/screens/Unit/Detail.js +20 -7
- package/src/screens/Unit/ManageUnit.js +9 -12
- package/src/screens/Unit/SmartAccount.js +25 -41
- package/src/screens/Unit/SmartAccountItem.js +2 -1
- package/src/screens/Unit/SmartAccountStyles.js +0 -1
- package/src/screens/Unit/__test__/ManageUnit.test.js +0 -6
- package/src/screens/Unit/__test__/SmartAccount.test.js +24 -0
- package/src/screens/Unit/__test__/SmartAccountItem.test.js +72 -0
- package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +2 -1
- package/src/screens/UnitSummary/components/PowerConsumption/index.js +1 -1
- package/src/screens/UnitSummary/components/Temperature/ItemTemperature/index.js +2 -2
- package/src/screens/WaterQualityGuide/index.js +2 -2
- package/src/utils/I18n/translations/en.json +15 -3
- package/src/utils/I18n/translations/vi.json +15 -3
- package/src/utils/Route/index.js +1 -0
- package/src/utils/Utils.js +4 -0
|
@@ -30,7 +30,9 @@ import { AUTOMATE_TYPE } from '../../configs/Constants';
|
|
|
30
30
|
|
|
31
31
|
const UnitDetail = ({ route }) => {
|
|
32
32
|
const t = useTranslations();
|
|
33
|
+
|
|
33
34
|
const { unitId, unitData, isOneTap, routeName, isAddSubUnit } = route.params;
|
|
35
|
+
|
|
34
36
|
const isFocused = useIsFocused();
|
|
35
37
|
const { stateData, setAction } = useContext(SCContext);
|
|
36
38
|
const { navigate } = useNavigation();
|
|
@@ -39,7 +41,7 @@ const UnitDetail = ({ route }) => {
|
|
|
39
41
|
const [appState, setAppState] = useState(AppState.currentState);
|
|
40
42
|
const [listMenuItem, setListMenuItem] = useState([]);
|
|
41
43
|
const [listStation, setListStation] = useState([]);
|
|
42
|
-
const [
|
|
44
|
+
const [listAutomate, setListAutomate] = useState([]);
|
|
43
45
|
const [favorites, setFavorites] = useState({
|
|
44
46
|
devices: [],
|
|
45
47
|
automates: [],
|
|
@@ -106,12 +108,23 @@ const UnitDetail = ({ route }) => {
|
|
|
106
108
|
await fetchWithCache(
|
|
107
109
|
API.UNIT.AUTOMATE(unitId),
|
|
108
110
|
{
|
|
109
|
-
params: { type: AUTOMATE_TYPE.
|
|
111
|
+
params: { type: AUTOMATE_TYPE.ALL },
|
|
110
112
|
},
|
|
111
113
|
(response) => {
|
|
112
114
|
const { success, data } = response;
|
|
113
115
|
if (success) {
|
|
114
|
-
|
|
116
|
+
setListAutomate([
|
|
117
|
+
{
|
|
118
|
+
text: t(AUTOMATE_TYPE.SCENARIO),
|
|
119
|
+
data: data.filter((item) => item.type === AUTOMATE_TYPE.ONE_TAP),
|
|
120
|
+
type: AUTOMATE_TYPE.ONE_TAP,
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
text: t(AUTOMATE_TYPE.AUTOMATION),
|
|
124
|
+
data: data.filter((item) => item.type !== AUTOMATE_TYPE.ONE_TAP),
|
|
125
|
+
type: AUTOMATE_TYPE.AUTOMATION,
|
|
126
|
+
},
|
|
127
|
+
]);
|
|
115
128
|
setFavorites((prevData) => ({
|
|
116
129
|
...prevData,
|
|
117
130
|
automates: data.filter((item) => item.script.is_star),
|
|
@@ -119,7 +132,7 @@ const UnitDetail = ({ route }) => {
|
|
|
119
132
|
}
|
|
120
133
|
}
|
|
121
134
|
);
|
|
122
|
-
}, [unitId]);
|
|
135
|
+
}, [t, unitId]);
|
|
123
136
|
|
|
124
137
|
const onRefresh = useCallback(() => {
|
|
125
138
|
fetchDetails();
|
|
@@ -242,13 +255,14 @@ const UnitDetail = ({ route }) => {
|
|
|
242
255
|
};
|
|
243
256
|
|
|
244
257
|
const renderDetailSubUnit = () => {
|
|
245
|
-
if (station
|
|
258
|
+
if (station?.isFavorites) {
|
|
246
259
|
return (
|
|
247
260
|
<SubUnitFavorites
|
|
248
261
|
unit={unit}
|
|
249
262
|
isOwner={isOwner}
|
|
250
263
|
favorites={favorites}
|
|
251
264
|
wrapItemStyle={styles.wrapItemStyle}
|
|
265
|
+
isGGHomeConnected={isGGHomeConnected}
|
|
252
266
|
/>
|
|
253
267
|
);
|
|
254
268
|
}
|
|
@@ -264,8 +278,7 @@ const UnitDetail = ({ route }) => {
|
|
|
264
278
|
return (
|
|
265
279
|
<SubUnitAutomate
|
|
266
280
|
isOwner={isOwner}
|
|
267
|
-
|
|
268
|
-
automates={oneTap}
|
|
281
|
+
listAutomate={listAutomate}
|
|
269
282
|
unit={unit}
|
|
270
283
|
wrapItemStyle={styles.wrapItemStyle}
|
|
271
284
|
/>
|
|
@@ -6,11 +6,7 @@ import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
|
6
6
|
import { Colors, API, Images } from '../../configs';
|
|
7
7
|
import Routes from '../../utils/Route';
|
|
8
8
|
import { ToastBottomHelper } from '../../utils/Utils';
|
|
9
|
-
import {
|
|
10
|
-
createFormData,
|
|
11
|
-
axiosPatch,
|
|
12
|
-
axiosDelete,
|
|
13
|
-
} from '../../utils/Apis/axios';
|
|
9
|
+
import { createFormData, axiosPatch } from '../../utils/Apis/axios';
|
|
14
10
|
import useBoolean from '../../hooks/Common/useBoolean';
|
|
15
11
|
import useKeyboardAnimated from '../../hooks/Explore/useKeyboardAnimated';
|
|
16
12
|
|
|
@@ -128,13 +124,14 @@ const ManageUnit = ({ route }) => {
|
|
|
128
124
|
|
|
129
125
|
const [showRemove, setshowRemove, setHideRemove] = useBoolean();
|
|
130
126
|
const goRemove = useCallback(async () => {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
|
|
127
|
+
navigation.navigate(Routes.UnitStack, {
|
|
128
|
+
screen: Routes.ConfirmUnitDeletion,
|
|
129
|
+
params: {
|
|
130
|
+
unit,
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
setHideRemove(true);
|
|
134
|
+
}, [setHideRemove, navigation, unit]);
|
|
138
135
|
|
|
139
136
|
const goToManageSubUnit = useCallback(() => {
|
|
140
137
|
navigation.navigate(Routes.UnitStack, {
|
|
@@ -7,17 +7,16 @@ import React, {
|
|
|
7
7
|
useState,
|
|
8
8
|
memo,
|
|
9
9
|
} from 'react';
|
|
10
|
-
import { View } from 'react-native';
|
|
10
|
+
import { TouchableOpacity, View } from 'react-native';
|
|
11
11
|
import styles from './SmartAccountStyles';
|
|
12
12
|
import { API, Colors } from '../../configs';
|
|
13
13
|
import Routes from '../../utils/Route';
|
|
14
14
|
import { useNavigation } from '@react-navigation/native';
|
|
15
15
|
import { axiosDelete, axiosGet } from '../../utils/Apis/axios';
|
|
16
16
|
import { SmartAccountItem } from './SmartAccountItem';
|
|
17
|
-
import { usePopover
|
|
18
|
-
import {
|
|
17
|
+
import { usePopover } from '../../hooks/Common';
|
|
18
|
+
import { MenuActionMore } from '../../commons';
|
|
19
19
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
20
|
-
import { useStateAlertRemove } from '../Unit/hook/useStateAlertRemove';
|
|
21
20
|
|
|
22
21
|
const ListSmartAccount = ({ route }) => {
|
|
23
22
|
const { unitId } = route?.params || {};
|
|
@@ -38,10 +37,6 @@ const ListSmartAccount = ({ route }) => {
|
|
|
38
37
|
const { childRef, showingPopover, showPopoverWithRef, hidePopover } =
|
|
39
38
|
usePopover();
|
|
40
39
|
|
|
41
|
-
const [lockShowing, acquireLockShowing, releaseLockShowing] = useBoolean();
|
|
42
|
-
const { stateAlertRemove, onShowRemoveAlert, hideAlertAction } =
|
|
43
|
-
useStateAlertRemove();
|
|
44
|
-
|
|
45
40
|
useEffect(() => {
|
|
46
41
|
getAllSmartAccounts();
|
|
47
42
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -55,21 +50,7 @@ const ListSmartAccount = ({ route }) => {
|
|
|
55
50
|
[showPopoverWithRef]
|
|
56
51
|
);
|
|
57
52
|
|
|
58
|
-
const onItemClick = useCallback(
|
|
59
|
-
(item) => {
|
|
60
|
-
if (!smartAccountRef?.current) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
if (item.action === 'delete') {
|
|
64
|
-
acquireLockShowing();
|
|
65
|
-
onShowRemoveAlert(smartAccountRef.current.brand)();
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
[acquireLockShowing, onShowRemoveAlert]
|
|
69
|
-
);
|
|
70
|
-
|
|
71
53
|
const deleteSmartAccount = useCallback(async () => {
|
|
72
|
-
hideAlertAction();
|
|
73
54
|
if (!smartAccountRef?.current) {
|
|
74
55
|
return;
|
|
75
56
|
}
|
|
@@ -78,10 +59,22 @@ const ListSmartAccount = ({ route }) => {
|
|
|
78
59
|
API.SMART_ACCOUNT.REMOVE_SMART_ACCOUNT(id)
|
|
79
60
|
);
|
|
80
61
|
success && getAllSmartAccounts();
|
|
81
|
-
}, [
|
|
62
|
+
}, [getAllSmartAccounts]);
|
|
63
|
+
|
|
64
|
+
const onItemClick = useCallback(
|
|
65
|
+
(item) => {
|
|
66
|
+
if (!smartAccountRef?.current) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (item.action === 'remove') {
|
|
70
|
+
deleteSmartAccount();
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
[deleteSmartAccount]
|
|
74
|
+
);
|
|
82
75
|
|
|
83
76
|
const listMenuItem = useMemo(() => {
|
|
84
|
-
return [{ action: '
|
|
77
|
+
return [{ action: 'remove', text: t('remove_account') }];
|
|
85
78
|
}, [t]);
|
|
86
79
|
|
|
87
80
|
const gotoSmartAccountDetail = useCallback(
|
|
@@ -104,33 +97,24 @@ const ListSmartAccount = ({ route }) => {
|
|
|
104
97
|
headerAniStyle={styles.headerAniStyle}
|
|
105
98
|
>
|
|
106
99
|
<View style={styles.wrapContent}>
|
|
107
|
-
{data.map((item) => {
|
|
100
|
+
{data.map((item, index) => {
|
|
108
101
|
return (
|
|
109
|
-
<
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
102
|
+
<TouchableOpacity key={index}>
|
|
103
|
+
<SmartAccountItem
|
|
104
|
+
gotoSmartAccountDetail={gotoSmartAccountDetail}
|
|
105
|
+
item={item}
|
|
106
|
+
onShowMenuMore={onShowMenuMore}
|
|
107
|
+
/>
|
|
108
|
+
</TouchableOpacity>
|
|
114
109
|
);
|
|
115
110
|
})}
|
|
116
111
|
</View>
|
|
117
|
-
<AlertAction
|
|
118
|
-
visible={stateAlertRemove.visible && !lockShowing}
|
|
119
|
-
hideModal={hideAlertAction}
|
|
120
|
-
title={stateAlertRemove.title}
|
|
121
|
-
message={stateAlertRemove.message}
|
|
122
|
-
leftButtonTitle={stateAlertRemove.leftButton}
|
|
123
|
-
leftButtonClick={hideAlertAction}
|
|
124
|
-
rightButtonTitle={stateAlertRemove.rightButton}
|
|
125
|
-
rightButtonClick={deleteSmartAccount}
|
|
126
|
-
/>
|
|
127
112
|
<MenuActionMore
|
|
128
113
|
isVisible={showingPopover}
|
|
129
114
|
hideMore={hidePopover}
|
|
130
115
|
listMenuItem={listMenuItem}
|
|
131
116
|
childRef={childRef}
|
|
132
117
|
onItemClick={onItemClick}
|
|
133
|
-
hideComplete={releaseLockShowing}
|
|
134
118
|
/>
|
|
135
119
|
</WrapHeaderScrollable>
|
|
136
120
|
</View>
|
|
@@ -23,6 +23,7 @@ export const SmartAccountItem = memo(
|
|
|
23
23
|
<TouchableOpacity
|
|
24
24
|
style={styles.wrapText}
|
|
25
25
|
onPress={onPressGotoSmartAccountDetail}
|
|
26
|
+
testID={TESTID.SMART_ACCOUNT_ITEM}
|
|
26
27
|
>
|
|
27
28
|
<FImage
|
|
28
29
|
source={{ uri: item?.logo }}
|
|
@@ -39,7 +40,7 @@ export const SmartAccountItem = memo(
|
|
|
39
40
|
</View>
|
|
40
41
|
</TouchableOpacity>
|
|
41
42
|
<TouchableOpacity
|
|
42
|
-
testID={TESTID.
|
|
43
|
+
testID={TESTID.SMART_ACCOUNT_ITEM_PRESSMORE}
|
|
43
44
|
onPress={onPressMore}
|
|
44
45
|
ref={buttonMoreRef}
|
|
45
46
|
>
|
|
@@ -3,7 +3,6 @@ import { act, create } from 'react-test-renderer';
|
|
|
3
3
|
import axios from 'axios';
|
|
4
4
|
|
|
5
5
|
import { ToastBottomHelper } from '../../../utils/Utils';
|
|
6
|
-
import API from '../../../configs/API';
|
|
7
6
|
import { TESTID } from '../../../configs/Constants';
|
|
8
7
|
|
|
9
8
|
import ManageUnit from '../ManageUnit';
|
|
@@ -131,7 +130,6 @@ describe('Test Manage Unit', () => {
|
|
|
131
130
|
});
|
|
132
131
|
|
|
133
132
|
test('remove Unit success', async () => {
|
|
134
|
-
const spyToast = jest.spyOn(ToastBottomHelper, 'success');
|
|
135
133
|
await act(async () => {
|
|
136
134
|
tree = create(wrapComponent(route));
|
|
137
135
|
});
|
|
@@ -165,11 +163,7 @@ describe('Test Manage Unit', () => {
|
|
|
165
163
|
await bottomButton.props.onPress();
|
|
166
164
|
});
|
|
167
165
|
|
|
168
|
-
expect(axios.delete).toBeCalledWith(API.UNIT.MANAGE_UNIT(1));
|
|
169
166
|
expect(mockedDispatch).not.toBeCalled();
|
|
170
|
-
expect(spyToast).toBeCalled();
|
|
171
|
-
spyToast.mockReset();
|
|
172
|
-
spyToast.mockRestore();
|
|
173
167
|
});
|
|
174
168
|
|
|
175
169
|
test('rename Unit sucess', async () => {
|
|
@@ -6,6 +6,7 @@ import { SCProvider } from '../../../context';
|
|
|
6
6
|
import { mockSCStore } from '../../../context/mockStore';
|
|
7
7
|
import ListSmartAccount from '../SmartAccount';
|
|
8
8
|
import { SmartAccountItem } from '../SmartAccountItem';
|
|
9
|
+
import { MenuActionMore } from '../../../commons';
|
|
9
10
|
|
|
10
11
|
const wrapComponent = (route, navigation) => (
|
|
11
12
|
<SCProvider initState={mockSCStore({})}>
|
|
@@ -13,6 +14,17 @@ const wrapComponent = (route, navigation) => (
|
|
|
13
14
|
</SCProvider>
|
|
14
15
|
);
|
|
15
16
|
|
|
17
|
+
const mockedNavigate = jest.fn();
|
|
18
|
+
|
|
19
|
+
jest.mock('@react-navigation/native', () => {
|
|
20
|
+
return {
|
|
21
|
+
...jest.requireActual('@react-navigation/native'),
|
|
22
|
+
useNavigation: () => ({
|
|
23
|
+
goBack: mockedNavigate,
|
|
24
|
+
}),
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
|
|
16
28
|
jest.mock('react', () => {
|
|
17
29
|
return {
|
|
18
30
|
...jest.requireActual('react'),
|
|
@@ -55,4 +67,16 @@ describe('Test SmartAccount', () => {
|
|
|
55
67
|
const smartAccountItem = instance.findAllByType(SmartAccountItem);
|
|
56
68
|
expect(smartAccountItem.length).toEqual(3);
|
|
57
69
|
});
|
|
70
|
+
|
|
71
|
+
test('test render SmartAccountItem', async () => {
|
|
72
|
+
await act(async () => {
|
|
73
|
+
tree = await renderer.create(wrapComponent());
|
|
74
|
+
});
|
|
75
|
+
const instance = tree.root;
|
|
76
|
+
const menuActionMore = instance.findByType(MenuActionMore);
|
|
77
|
+
await act(async () => {
|
|
78
|
+
menuActionMore.props.onItemClick();
|
|
79
|
+
});
|
|
80
|
+
expect(menuActionMore.props.isVisible).toEqual(false);
|
|
81
|
+
});
|
|
58
82
|
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import renderer, { act } from 'react-test-renderer';
|
|
3
|
+
|
|
4
|
+
import { SCProvider } from '../../../context';
|
|
5
|
+
import { mockSCStore } from '../../../context/mockStore';
|
|
6
|
+
import { SmartAccountItem } from '../SmartAccountItem';
|
|
7
|
+
import { TouchableOpacity } from 'react-native';
|
|
8
|
+
import { TESTID } from '../../../configs/Constants';
|
|
9
|
+
|
|
10
|
+
const mockedOnShowMenuMore = jest.fn();
|
|
11
|
+
const mockedGotoSmartAccountDetail = jest.fn();
|
|
12
|
+
|
|
13
|
+
const wrapComponent = (route) => (
|
|
14
|
+
<SCProvider initState={mockSCStore({})}>
|
|
15
|
+
<SmartAccountItem
|
|
16
|
+
onShowMenuMore={mockedOnShowMenuMore}
|
|
17
|
+
gotoSmartAccountDetail={mockedGotoSmartAccountDetail}
|
|
18
|
+
/>
|
|
19
|
+
</SCProvider>
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
const mockedNavigate = jest.fn();
|
|
23
|
+
|
|
24
|
+
jest.mock('@react-navigation/native', () => {
|
|
25
|
+
return {
|
|
26
|
+
...jest.requireActual('@react-navigation/native'),
|
|
27
|
+
useNavigation: () => ({
|
|
28
|
+
goBack: mockedNavigate,
|
|
29
|
+
}),
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
jest.mock('react', () => {
|
|
34
|
+
return {
|
|
35
|
+
...jest.requireActual('react'),
|
|
36
|
+
memo: (x) => x,
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
jest.mock('axios');
|
|
41
|
+
describe('Test SmartAccountItem', () => {
|
|
42
|
+
let tree;
|
|
43
|
+
test('test render SmartAccountItem', async () => {
|
|
44
|
+
await act(async () => {
|
|
45
|
+
tree = await renderer.create(wrapComponent());
|
|
46
|
+
});
|
|
47
|
+
const instance = tree.root;
|
|
48
|
+
|
|
49
|
+
const onPressGotoSmartAccountDetail = instance.find(
|
|
50
|
+
(el) =>
|
|
51
|
+
el.props.testID === TESTID.SMART_ACCOUNT_ITEM &&
|
|
52
|
+
el.type === TouchableOpacity
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
await act(async () => {
|
|
56
|
+
onPressGotoSmartAccountDetail.props.onPress();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
expect(mockedGotoSmartAccountDetail).toHaveBeenCalled();
|
|
60
|
+
|
|
61
|
+
const onPressMore = instance.find(
|
|
62
|
+
(el) =>
|
|
63
|
+
el.props.testID === TESTID.SMART_ACCOUNT_ITEM_PRESSMORE &&
|
|
64
|
+
el.type === TouchableOpacity
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
await act(async () => {
|
|
68
|
+
onPressMore.props.onPress();
|
|
69
|
+
});
|
|
70
|
+
expect(mockedOnShowMenuMore).toHaveBeenCalled();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -189,7 +189,7 @@ const ThreePhasePowerConsumption = memo(({ summaryDetail }) => {
|
|
|
189
189
|
}, [listConfigs]);
|
|
190
190
|
|
|
191
191
|
const [startDate, setStartDate] = useState(
|
|
192
|
-
moment().subtract(
|
|
192
|
+
moment().subtract(6, 'days').valueOf()
|
|
193
193
|
);
|
|
194
194
|
const [endDate, setEndDate] = useState(moment().valueOf());
|
|
195
195
|
const [groupBy, setGroupBy] = useState('date');
|
|
@@ -251,6 +251,7 @@ const ThreePhasePowerConsumption = memo(({ summaryDetail }) => {
|
|
|
251
251
|
startDate={startDate}
|
|
252
252
|
setEndDate={setEndDate}
|
|
253
253
|
setStartDate={setStartDate}
|
|
254
|
+
groupBy={groupBy}
|
|
254
255
|
setGroupBy={setGroupBy}
|
|
255
256
|
configuration={{
|
|
256
257
|
type: 'horizontal_bar_chart',
|
|
@@ -78,7 +78,7 @@ const PowerConsumption = memo(({ summaryDetail }) => {
|
|
|
78
78
|
dataTotal.push(totalPower);
|
|
79
79
|
|
|
80
80
|
const [startDate, setStartDate] = useState(
|
|
81
|
-
moment().subtract(
|
|
81
|
+
moment().subtract(6, 'days').valueOf()
|
|
82
82
|
);
|
|
83
83
|
const [endDate, setEndDate] = useState(moment().valueOf());
|
|
84
84
|
const [groupBy, setGroupBy] = useState('date');
|
|
@@ -10,13 +10,13 @@ const ItemTemperature = memo((props) => {
|
|
|
10
10
|
const { svgMain, title, des, value } = props;
|
|
11
11
|
return (
|
|
12
12
|
<View style={styles.container}>
|
|
13
|
-
<Text
|
|
13
|
+
<Text type="H4" color={Colors.Gray8} style={styles.textTitle}>
|
|
14
14
|
{title}
|
|
15
15
|
</Text>
|
|
16
16
|
<Text size={24} color={Colors.Gray9} style={styles.textValue}>
|
|
17
17
|
{value}
|
|
18
18
|
</Text>
|
|
19
|
-
<Text
|
|
19
|
+
<Text type="H4" color={Colors.Gray8}>
|
|
20
20
|
{des}
|
|
21
21
|
</Text>
|
|
22
22
|
<View style={styles.boxSvg}>{svgMain}</View>
|
|
@@ -471,7 +471,7 @@
|
|
|
471
471
|
"scan_qr_code_at_%{spot}": "Scan QR code at spot %{spot}",
|
|
472
472
|
"extend": "Extend",
|
|
473
473
|
"verify_qr_code": "Verifying code...",
|
|
474
|
-
"
|
|
474
|
+
"tds_information": "TDS Information",
|
|
475
475
|
"what_is_tds_title": "What is TDS?",
|
|
476
476
|
"what_is_tds_text": "TDS: is the total dissolved solids present in a certain amount of water - (the total number of charged ions, including salts, minerals or metals) that exist in a certain volume of water. High TDS is also responsible for turbidity and sedimentation in water. TDS is expressed in mg / L or parts per million (parts per million).",
|
|
477
477
|
"tds_guidlines_title": "TDS guidlines for drinking water",
|
|
@@ -744,7 +744,7 @@
|
|
|
744
744
|
"rssi_node": "RSSI Node",
|
|
745
745
|
"edit_actions_list": "Edit Actions List",
|
|
746
746
|
"des_edit_actions_list": "Hold and hover to rearrange actions order",
|
|
747
|
-
"please_add_your_phone_number_and_chip_name": "Please add
|
|
747
|
+
"please_add_your_phone_number_and_chip_name": "Please add your phone number and chip name",
|
|
748
748
|
"phone_number_of_data_sim": "Phone number of data sim",
|
|
749
749
|
"select_a_sub_unit": "Select a sub-unit that you want to add this gateway",
|
|
750
750
|
"all_camera": "All Cameras",
|
|
@@ -781,6 +781,8 @@
|
|
|
781
781
|
"Script": "Script",
|
|
782
782
|
"One-Tap": "One-Tap",
|
|
783
783
|
"Scenario": "Scenario",
|
|
784
|
+
"one_tap": "One-Tap",
|
|
785
|
+
"scenario": "Scenario",
|
|
784
786
|
"automation": "Automation",
|
|
785
787
|
"set_schedule": "Set schedule",
|
|
786
788
|
"select_date": "Select date",
|
|
@@ -854,5 +856,15 @@
|
|
|
854
856
|
"volume": "Volume",
|
|
855
857
|
"this_notification_will_be_updated_soon": "This notification will be updated soon",
|
|
856
858
|
"text_submit": "Submit",
|
|
857
|
-
"
|
|
859
|
+
"remove_account": "Remove Account",
|
|
860
|
+
"text_sub_unit_not_have_device": "You don't have sub-unit with a device to control",
|
|
861
|
+
"tap_to_add_new_schedule": "Tap + to add new schedule",
|
|
862
|
+
"confirmation": "Confirmation",
|
|
863
|
+
"enter_yes_to_perform": "You need to enter 'YES' to perform this action",
|
|
864
|
+
"please_enter_correct":"Please enter correct",
|
|
865
|
+
"add_schedule": "Add Schedule",
|
|
866
|
+
"curtain_opens": "Curtain opens",
|
|
867
|
+
"curtain_closes": "Curtain closes",
|
|
868
|
+
"schedule_name": "Schedule name",
|
|
869
|
+
"enter_name": "Enter name"
|
|
858
870
|
}
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"%{number}_filter_need_to_be_replaced": "%{number} lõi lọc cần được thay thế.",
|
|
58
58
|
"replace_all_filters": "Tất cả lõi lọc cần được thay thế.",
|
|
59
59
|
"auth_already_have_an_account": "Bạn đã có tài khoản? ",
|
|
60
|
-
"
|
|
60
|
+
"tds_information": "Chỉ số TDS",
|
|
61
61
|
"what_is_tds_title": "TDS là gì?",
|
|
62
62
|
"set_a_number": "Đặt một số",
|
|
63
63
|
"add_action": "Thêm hành động",
|
|
@@ -747,7 +747,7 @@
|
|
|
747
747
|
"request_fail": "Request fail",
|
|
748
748
|
"modbus_fail": "Modbus failrate",
|
|
749
749
|
"rssi_node": "RSSI Node",
|
|
750
|
-
"please_add_your_phone_number_and_chip_name": "Vui lòng thêm tên
|
|
750
|
+
"please_add_your_phone_number_and_chip_name": "Vui lòng thêm số điện thoại và tên chip của bạn",
|
|
751
751
|
"phone_number_of_data_sim": "Số điện thoại của dữ liệu sim",
|
|
752
752
|
"select_a_sub_unit": "Lựa chọn một khu vực mà bạn muốn thêm gateway",
|
|
753
753
|
"all_camera": "All Cameras",
|
|
@@ -783,6 +783,8 @@
|
|
|
783
783
|
"Script": "Kịch bản",
|
|
784
784
|
"One-Tap": "Một chạm",
|
|
785
785
|
"Scenario": "Kịch bản",
|
|
786
|
+
"one_tap": "Một chạm",
|
|
787
|
+
"scenario": "Kịch bản",
|
|
786
788
|
"automation": "Tự động",
|
|
787
789
|
"set_schedule": "Đặt lịch",
|
|
788
790
|
"select_date": "Chọn ngày",
|
|
@@ -856,5 +858,15 @@
|
|
|
856
858
|
"this_notification_will_be_updated_soon": "Thông báo này sẽ sớm được cập nhật",
|
|
857
859
|
"text_submit": "Xác nhận",
|
|
858
860
|
"tap_to_add_new_schedule": "Nhấn + để thêm lịch trình mới",
|
|
859
|
-
"
|
|
861
|
+
"remove_account": "Xóa tài khoản",
|
|
862
|
+
"text_subunit_not_have_device": "Bạn không có khu vực nào có thiết bị để điều khiển",
|
|
863
|
+
"choose_at_least_one": "Vui lòng chọn ít nhất 1 thiết bị.",
|
|
864
|
+
"confirmation": "Xác Nhận",
|
|
865
|
+
"enter_yes_to_perform": "Bạn cần nhập 'YES' để thực hiện hành động này",
|
|
866
|
+
"please_enter_correct":"Vui lòng nhập đúng",
|
|
867
|
+
"add_schedule": "Thêm lịch trình",
|
|
868
|
+
"curtain_opens": "Rèm mở",
|
|
869
|
+
"curtain_closes": "Rèm đóng",
|
|
870
|
+
"schedule_name": "Tên lịch trình",
|
|
871
|
+
"enter_name": "Nhập tên"
|
|
860
872
|
}
|
package/src/utils/Route/index.js
CHANGED
package/src/utils/Utils.js
CHANGED
|
@@ -120,6 +120,10 @@ export const removeFromString = (str, index) => {
|
|
|
120
120
|
return str.substr(0, index) + str.substr(index + 1);
|
|
121
121
|
};
|
|
122
122
|
|
|
123
|
+
export const arePropsEqual = (prevProps, nextProps) => {
|
|
124
|
+
return JSON.stringify(prevProps) === JSON.stringify(nextProps);
|
|
125
|
+
};
|
|
126
|
+
|
|
123
127
|
export default {
|
|
124
128
|
validateEmail,
|
|
125
129
|
isObjectEmpty,
|