@eohjsc/react-native-smart-city 0.2.61 → 0.2.62
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 +1 -1
- 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 +11 -9
- 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/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/index.js +1 -0
- package/src/screens/SubUnit/EditSubUnit.js +8 -1
- package/src/screens/SubUnit/EditSubUnitStyles.js +2 -3
- package/src/screens/TDSGuide/index.js +1 -1
- package/src/screens/Unit/Detail.js +16 -6
- 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/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
|
@@ -43,6 +43,7 @@ import EditSubUnit from '../screens/SubUnit/EditSubUnit';
|
|
|
43
43
|
import SetUpSensor from '../screens/AddNewAction/SetupSensor';
|
|
44
44
|
import EditDevice from '../screens/Device/EditDevice/index';
|
|
45
45
|
import EmergencySetting from '../screens/EmergencySetting';
|
|
46
|
+
import ConfirmUnitDeletion from '../screens/ConfirmUnitDeletion';
|
|
46
47
|
|
|
47
48
|
const Stack = createStackNavigator();
|
|
48
49
|
|
|
@@ -158,7 +159,7 @@ export const UnitStack = memo((props) => {
|
|
|
158
159
|
component={DeviceDetail}
|
|
159
160
|
options={{
|
|
160
161
|
headerShown: false,
|
|
161
|
-
animationEnabled:
|
|
162
|
+
animationEnabled: Platform.OS === 'ios',
|
|
162
163
|
}}
|
|
163
164
|
/>
|
|
164
165
|
<Stack.Screen
|
|
@@ -172,7 +173,7 @@ export const UnitStack = memo((props) => {
|
|
|
172
173
|
name={Route.TDSGuide}
|
|
173
174
|
component={TDSGuide}
|
|
174
175
|
options={{
|
|
175
|
-
title: t('
|
|
176
|
+
title: t('tds_information'),
|
|
176
177
|
}}
|
|
177
178
|
/>
|
|
178
179
|
<Stack.Screen
|
|
@@ -307,6 +308,13 @@ export const UnitStack = memo((props) => {
|
|
|
307
308
|
headerShown: false,
|
|
308
309
|
}}
|
|
309
310
|
/>
|
|
311
|
+
<Stack.Screen
|
|
312
|
+
name={Route.ConfirmUnitDeletion}
|
|
313
|
+
component={ConfirmUnitDeletion}
|
|
314
|
+
options={{
|
|
315
|
+
headerShown: false,
|
|
316
|
+
}}
|
|
317
|
+
/>
|
|
310
318
|
</Stack.Navigator>
|
|
311
319
|
);
|
|
312
320
|
});
|
|
@@ -55,7 +55,8 @@ const SelectSensorDevices = memo(({ route }) => {
|
|
|
55
55
|
(response) => {
|
|
56
56
|
const { success, data } = response;
|
|
57
57
|
if (success) {
|
|
58
|
-
const
|
|
58
|
+
const newData = data.filter((item) => item.sensors.length > 0);
|
|
59
|
+
const listMenu = newData.map((item, index) => ({
|
|
59
60
|
text: item.name,
|
|
60
61
|
station: item,
|
|
61
62
|
index: index,
|
|
@@ -63,7 +64,7 @@ const SelectSensorDevices = memo(({ route }) => {
|
|
|
63
64
|
if (isSelectSensor) {
|
|
64
65
|
if (automate.sensor_id) {
|
|
65
66
|
let selectSensor = {};
|
|
66
|
-
|
|
67
|
+
newData.map((item) => {
|
|
67
68
|
item.sensors.map((sensor) => {
|
|
68
69
|
if (sensor.id === automate.sensor_id) {
|
|
69
70
|
selectSensor = sensor;
|
|
@@ -76,9 +77,9 @@ const SelectSensorDevices = memo(({ route }) => {
|
|
|
76
77
|
setSelectedDevice(selectSensor);
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
|
-
setStation(
|
|
80
|
+
setStation(newData);
|
|
80
81
|
setListMenuItem(listMenu);
|
|
81
|
-
setListStation(listMenu
|
|
82
|
+
setListStation(listMenu);
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
);
|
|
@@ -174,13 +175,19 @@ const SelectSensorDevices = memo(({ route }) => {
|
|
|
174
175
|
{t(title)}
|
|
175
176
|
</Text>
|
|
176
177
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
178
|
+
{!!listStation.length > 0 ? (
|
|
179
|
+
<NavBar
|
|
180
|
+
listStation={listStation}
|
|
181
|
+
listMenuItem={listMenuItem}
|
|
182
|
+
onSnapToItem={onSnapToItem}
|
|
183
|
+
indexStation={indexStation}
|
|
184
|
+
style={styles.navbar}
|
|
185
|
+
/>
|
|
186
|
+
) : (
|
|
187
|
+
<View style={styles.noneData}>
|
|
188
|
+
<Text center>{t('text_sub_unit_not_have_device')}</Text>
|
|
189
|
+
</View>
|
|
190
|
+
)}
|
|
184
191
|
|
|
185
192
|
<View style={styles.boxDevices}>
|
|
186
193
|
{station[indexStation]?.sensors &&
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { StyleSheet } from 'react-native';
|
|
2
2
|
import { getBottomSpace } from 'react-native-iphone-x-helper';
|
|
3
|
-
import { Colors } from '../../../configs';
|
|
3
|
+
import { Colors, Constants } from '../../../configs';
|
|
4
4
|
|
|
5
5
|
export default StyleSheet.create({
|
|
6
6
|
wrap: {
|
|
@@ -33,4 +33,8 @@ export default StyleSheet.create({
|
|
|
33
33
|
borderColor: Colors.ShadownTransparent,
|
|
34
34
|
borderTopWidth: 1,
|
|
35
35
|
},
|
|
36
|
+
noneData: {
|
|
37
|
+
paddingHorizontal: 16,
|
|
38
|
+
marginTop: Constants.height * 0.3,
|
|
39
|
+
},
|
|
36
40
|
});
|
|
@@ -175,8 +175,13 @@ describe('Test SelectSensorDevices', () => {
|
|
|
175
175
|
],
|
|
176
176
|
},
|
|
177
177
|
];
|
|
178
|
+
const listMenu = data.map((item, index) => ({
|
|
179
|
+
text: item.name,
|
|
180
|
+
station: item,
|
|
181
|
+
index: index,
|
|
182
|
+
}));
|
|
178
183
|
const mockSetIndexStation = jest.fn();
|
|
179
|
-
useState.mockImplementationOnce((init) => [
|
|
184
|
+
useState.mockImplementationOnce((init) => [listMenu, mockSetState]);
|
|
180
185
|
useState.mockImplementationOnce((init) => [init, mockSetState]);
|
|
181
186
|
useState.mockImplementationOnce((init) => [init, mockSetIndexStation]);
|
|
182
187
|
useState.mockImplementationOnce((init) => [data, mockSetState]);
|
|
@@ -26,8 +26,11 @@ const MultiUnits = () => {
|
|
|
26
26
|
const { params = {} } = useRoute();
|
|
27
27
|
const { isMultiUnits = false, unitName = '', unit, isOwner } = params;
|
|
28
28
|
const [data, setData] = useState([]);
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
const tabName = useMemo(
|
|
30
|
+
() => [t(AUTOMATE_TYPE.SCENARIO), t(AUTOMATE_TYPE.AUTOMATION)],
|
|
31
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
32
|
+
[]
|
|
33
|
+
);
|
|
31
34
|
const [tabActive, setTabActive] = useState(tabName[0]);
|
|
32
35
|
|
|
33
36
|
const getData = useCallback(
|
|
@@ -72,7 +75,7 @@ const MultiUnits = () => {
|
|
|
72
75
|
screen: Routes.AddNewAutoSmart,
|
|
73
76
|
params: {
|
|
74
77
|
type:
|
|
75
|
-
tabActive === t(
|
|
78
|
+
tabActive === t(AUTOMATE_TYPE.SCENARIO)
|
|
76
79
|
? AUTOMATE_TYPE.ONE_TAP_ONLY
|
|
77
80
|
: AUTOMATE_TYPE.VALUE_CHANGE,
|
|
78
81
|
unit: { id: unit?.id },
|
|
@@ -109,7 +112,7 @@ const MultiUnits = () => {
|
|
|
109
112
|
|
|
110
113
|
const renderContent = useMemo(() => {
|
|
111
114
|
const listItems = data.filter((item) =>
|
|
112
|
-
tabActive === t(
|
|
115
|
+
tabActive === t(AUTOMATE_TYPE.SCENARIO)
|
|
113
116
|
? item?.type === AUTOMATE_TYPE.ONE_TAP
|
|
114
117
|
: item?.type !== AUTOMATE_TYPE.ONE_TAP
|
|
115
118
|
);
|
|
@@ -201,7 +201,7 @@ describe('Test MultiUnits', () => {
|
|
|
201
201
|
});
|
|
202
202
|
useState.mockImplementationOnce(() => [response.data, mockSetState]);
|
|
203
203
|
useState.mockImplementationOnce(() => [
|
|
204
|
-
getTranslate('en', '
|
|
204
|
+
getTranslate('en', 'Scenario'),
|
|
205
205
|
mockSetState,
|
|
206
206
|
]);
|
|
207
207
|
await act(() => {
|
|
@@ -70,6 +70,18 @@ describe('Test Automate', () => {
|
|
|
70
70
|
icon_kit: undefined,
|
|
71
71
|
},
|
|
72
72
|
},
|
|
73
|
+
{
|
|
74
|
+
id: 2,
|
|
75
|
+
user: 2,
|
|
76
|
+
type: 'one_tap',
|
|
77
|
+
activate_at: '2021-09-17T05:30:00Z',
|
|
78
|
+
script: {
|
|
79
|
+
id: 1,
|
|
80
|
+
name: 'script2',
|
|
81
|
+
icon: undefined,
|
|
82
|
+
icon_kit: undefined,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
73
85
|
],
|
|
74
86
|
},
|
|
75
87
|
],
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import renderer, { act } from 'react-test-renderer';
|
|
3
|
+
import axios from 'axios';
|
|
4
|
+
|
|
5
|
+
import { SCProvider } from '../../../context';
|
|
6
|
+
import { mockSCStore } from '../../../context/mockStore';
|
|
7
|
+
import ConfirmUnitDeletion from '../index';
|
|
8
|
+
import _TextInput from '../../../commons/Form/TextInput';
|
|
9
|
+
|
|
10
|
+
const wrapComponent = (route, navigation) => (
|
|
11
|
+
<SCProvider initState={mockSCStore({})}>
|
|
12
|
+
<ConfirmUnitDeletion route={route} />
|
|
13
|
+
</SCProvider>
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const mockedNavigate = jest.fn();
|
|
17
|
+
|
|
18
|
+
jest.mock('@react-navigation/native', () => {
|
|
19
|
+
return {
|
|
20
|
+
...jest.requireActual('@react-navigation/native'),
|
|
21
|
+
useNavigation: () => ({
|
|
22
|
+
goBack: mockedNavigate,
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
jest.mock('react', () => {
|
|
28
|
+
return {
|
|
29
|
+
...jest.requireActual('react'),
|
|
30
|
+
memo: (x) => x,
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
jest.mock('axios');
|
|
35
|
+
describe('Test ConfirmUnitDeletion', () => {
|
|
36
|
+
let tree;
|
|
37
|
+
let route;
|
|
38
|
+
|
|
39
|
+
beforeAll(() => {
|
|
40
|
+
axios.get.mockClear();
|
|
41
|
+
route = {
|
|
42
|
+
params: {
|
|
43
|
+
unit: {
|
|
44
|
+
id: 10,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('test render ConfirmUnitDeletion', async () => {
|
|
51
|
+
await act(async () => {
|
|
52
|
+
tree = await renderer.create(wrapComponent(route));
|
|
53
|
+
});
|
|
54
|
+
const instance = tree.root;
|
|
55
|
+
|
|
56
|
+
const textInput = instance.findByType(_TextInput);
|
|
57
|
+
await act(async () => {
|
|
58
|
+
textInput.props.onChange('new_name');
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React, { useCallback, useState } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { useNavigation } from '@react-navigation/native';
|
|
4
|
+
|
|
5
|
+
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
6
|
+
import styles from './styles';
|
|
7
|
+
import WrapHeaderScrollable from '../../commons/Sharing/WrapHeaderScrollable';
|
|
8
|
+
import Text from '../../commons/Text';
|
|
9
|
+
import { API, Colors } from '../../configs';
|
|
10
|
+
import _TextInput from '../../commons/Form/TextInput';
|
|
11
|
+
import { Button } from '../../commons';
|
|
12
|
+
import Routes from '../../utils/Route';
|
|
13
|
+
import { axiosDelete } from '../../utils/Apis/axios';
|
|
14
|
+
import { ToastBottomHelper } from '../../utils/Utils';
|
|
15
|
+
|
|
16
|
+
const ConfirmUnitDeletion = ({ route }) => {
|
|
17
|
+
const t = useTranslations();
|
|
18
|
+
const { unit } = route.params;
|
|
19
|
+
const navigation = useNavigation();
|
|
20
|
+
const [confirm, setConfrim] = useState('');
|
|
21
|
+
const [errorText, setErrorText] = useState();
|
|
22
|
+
|
|
23
|
+
const onChangePassword = useCallback((value) => {
|
|
24
|
+
setConfrim(value);
|
|
25
|
+
}, []);
|
|
26
|
+
|
|
27
|
+
const onSendPress = useCallback(async () => {
|
|
28
|
+
if (confirm === 'YES') {
|
|
29
|
+
const { success } = await axiosDelete(API.UNIT.MANAGE_UNIT(unit.id));
|
|
30
|
+
if (success) {
|
|
31
|
+
navigation.navigate(Routes.Dashboard);
|
|
32
|
+
ToastBottomHelper.success(t('unit_deleted_successfully'));
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
setErrorText(t('please_enter_correct'));
|
|
36
|
+
}
|
|
37
|
+
}, [confirm, navigation, t, unit.id]);
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<WrapHeaderScrollable
|
|
41
|
+
styleScrollView={styles.scrollView}
|
|
42
|
+
headerAniStyle={styles.headerAniStyle}
|
|
43
|
+
>
|
|
44
|
+
<Text semibold style={styles.txtForgot}>
|
|
45
|
+
{t('confirmation')}
|
|
46
|
+
</Text>
|
|
47
|
+
<Text type="H4" color={Colors.Gray9} style={styles.txtForgotHint}>
|
|
48
|
+
{t('enter_yes_to_perform')}
|
|
49
|
+
</Text>
|
|
50
|
+
<_TextInput
|
|
51
|
+
placeholder={t('text_password')}
|
|
52
|
+
onChange={onChangePassword}
|
|
53
|
+
errorText={errorText}
|
|
54
|
+
wrapStyle={styles.noMarginTop}
|
|
55
|
+
textInputStyle={styles.textInput}
|
|
56
|
+
/>
|
|
57
|
+
<View style={styles.buttonWrap}>
|
|
58
|
+
<Button type="auth" title={t('done')} onPress={onSendPress} />
|
|
59
|
+
</View>
|
|
60
|
+
</WrapHeaderScrollable>
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export default ConfirmUnitDeletion;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
import { Colors } from '../../configs';
|
|
3
|
+
|
|
4
|
+
export default StyleSheet.create({
|
|
5
|
+
scrollView: {
|
|
6
|
+
backgroundColor: Colors.White,
|
|
7
|
+
},
|
|
8
|
+
headerAniStyle: { borderBottomWidth: 0 },
|
|
9
|
+
txtForgot: {
|
|
10
|
+
color: Colors.Black,
|
|
11
|
+
fontSize: 24,
|
|
12
|
+
marginLeft: 16,
|
|
13
|
+
marginTop: 0,
|
|
14
|
+
fontWeight: 'bold',
|
|
15
|
+
},
|
|
16
|
+
txtForgotHint: {
|
|
17
|
+
marginLeft: 16,
|
|
18
|
+
marginTop: 30,
|
|
19
|
+
},
|
|
20
|
+
noMarginTop: {
|
|
21
|
+
margin: 16,
|
|
22
|
+
backgroundColor: Colors.White,
|
|
23
|
+
},
|
|
24
|
+
textInput: {
|
|
25
|
+
marginTop: 0,
|
|
26
|
+
borderWidth: 0,
|
|
27
|
+
borderBottomWidth: 1,
|
|
28
|
+
borderBottomColor: Colors.Gray4,
|
|
29
|
+
paddingLeft: 0,
|
|
30
|
+
backgroundColor: Colors.White,
|
|
31
|
+
},
|
|
32
|
+
buttonWrap: {
|
|
33
|
+
flexDirection: 'row',
|
|
34
|
+
marginTop: 24,
|
|
35
|
+
marginHorizontal: 16,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
@@ -8,6 +8,7 @@ import DropDownItem from './components/DropDownItem';
|
|
|
8
8
|
import _TextInput from '../../commons/Form/TextInput';
|
|
9
9
|
|
|
10
10
|
import styles from './styles';
|
|
11
|
+
import Text from '../../commons/Text';
|
|
11
12
|
|
|
12
13
|
const EmergencySetting = () => {
|
|
13
14
|
const t = useTranslations();
|
|
@@ -74,6 +75,7 @@ const EmergencySetting = () => {
|
|
|
74
75
|
/>
|
|
75
76
|
))}
|
|
76
77
|
|
|
78
|
+
<Text style={styles.duration}>{t('duration')}</Text>
|
|
77
79
|
<_TextInput
|
|
78
80
|
wrapStyle={styles.wrapInput}
|
|
79
81
|
textInputStyle={styles.textInputStyle}
|
|
@@ -11,9 +11,15 @@ export default StyleSheet.create({
|
|
|
11
11
|
},
|
|
12
12
|
wrapInput: {
|
|
13
13
|
paddingHorizontal: 16,
|
|
14
|
+
marginTop: 0,
|
|
14
15
|
},
|
|
15
16
|
textInputStyle: {
|
|
16
|
-
paddingTop:
|
|
17
|
-
paddingBottom:
|
|
17
|
+
paddingTop: 7,
|
|
18
|
+
paddingBottom: 7,
|
|
19
|
+
},
|
|
20
|
+
duration: {
|
|
21
|
+
marginTop: 14,
|
|
22
|
+
marginBottom: 10,
|
|
23
|
+
marginLeft: 16,
|
|
18
24
|
},
|
|
19
25
|
});
|
|
@@ -233,7 +233,14 @@ const EditSubUnit = ({ route }) => {
|
|
|
233
233
|
onPress={onPressRemove}
|
|
234
234
|
style={styles.removeButton}
|
|
235
235
|
>
|
|
236
|
-
<Text
|
|
236
|
+
<Text
|
|
237
|
+
type={'H4'}
|
|
238
|
+
semibold
|
|
239
|
+
color={Colors.Red}
|
|
240
|
+
style={styles.removeText}
|
|
241
|
+
>
|
|
242
|
+
{t('remove_sub_unit')}
|
|
243
|
+
</Text>
|
|
237
244
|
</TouchableOpacity>
|
|
238
245
|
</View>
|
|
239
246
|
</View>
|
|
@@ -46,9 +46,8 @@ export default StyleSheet.create({
|
|
|
46
46
|
paddingBottom: 16 + getBottomSpace(),
|
|
47
47
|
},
|
|
48
48
|
removeText: {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
color: Colors.Gray6,
|
|
49
|
+
borderBottomWidth: 1,
|
|
50
|
+
borderBottomColor: Colors.Red,
|
|
52
51
|
},
|
|
53
52
|
backgroundContainer: {
|
|
54
53
|
alignItems: 'center',
|
|
@@ -39,7 +39,7 @@ const UnitDetail = ({ route }) => {
|
|
|
39
39
|
const [appState, setAppState] = useState(AppState.currentState);
|
|
40
40
|
const [listMenuItem, setListMenuItem] = useState([]);
|
|
41
41
|
const [listStation, setListStation] = useState([]);
|
|
42
|
-
const [
|
|
42
|
+
const [listAutomate, setListAutomate] = useState([]);
|
|
43
43
|
const [favorites, setFavorites] = useState({
|
|
44
44
|
devices: [],
|
|
45
45
|
automates: [],
|
|
@@ -106,12 +106,23 @@ const UnitDetail = ({ route }) => {
|
|
|
106
106
|
await fetchWithCache(
|
|
107
107
|
API.UNIT.AUTOMATE(unitId),
|
|
108
108
|
{
|
|
109
|
-
params: { type: AUTOMATE_TYPE.
|
|
109
|
+
params: { type: AUTOMATE_TYPE.ALL },
|
|
110
110
|
},
|
|
111
111
|
(response) => {
|
|
112
112
|
const { success, data } = response;
|
|
113
113
|
if (success) {
|
|
114
|
-
|
|
114
|
+
setListAutomate([
|
|
115
|
+
{
|
|
116
|
+
text: t(AUTOMATE_TYPE.SCENARIO),
|
|
117
|
+
data: data.filter((item) => item.type === AUTOMATE_TYPE.ONE_TAP),
|
|
118
|
+
type: AUTOMATE_TYPE.ONE_TAP,
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
text: t(AUTOMATE_TYPE.AUTOMATION),
|
|
122
|
+
data: data.filter((item) => item.type !== AUTOMATE_TYPE.ONE_TAP),
|
|
123
|
+
type: AUTOMATE_TYPE.AUTOMATION,
|
|
124
|
+
},
|
|
125
|
+
]);
|
|
115
126
|
setFavorites((prevData) => ({
|
|
116
127
|
...prevData,
|
|
117
128
|
automates: data.filter((item) => item.script.is_star),
|
|
@@ -119,7 +130,7 @@ const UnitDetail = ({ route }) => {
|
|
|
119
130
|
}
|
|
120
131
|
}
|
|
121
132
|
);
|
|
122
|
-
}, [unitId]);
|
|
133
|
+
}, [t, unitId]);
|
|
123
134
|
|
|
124
135
|
const onRefresh = useCallback(() => {
|
|
125
136
|
fetchDetails();
|
|
@@ -264,8 +275,7 @@ const UnitDetail = ({ route }) => {
|
|
|
264
275
|
return (
|
|
265
276
|
<SubUnitAutomate
|
|
266
277
|
isOwner={isOwner}
|
|
267
|
-
|
|
268
|
-
automates={oneTap}
|
|
278
|
+
listAutomate={listAutomate}
|
|
269
279
|
unit={unit}
|
|
270
280
|
wrapItemStyle={styles.wrapItemStyle}
|
|
271
281
|
/>
|
|
@@ -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
|
>
|