@eohjsc/react-native-smart-city 0.2.96 → 0.2.99
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 +35 -14
- package/package.json +16 -4
- package/src/commons/Action/ItemQuickAction.js +5 -2
- package/src/commons/ActionGroup/ColorPickerTemplate.js +1 -1
- package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +12 -4
- package/src/commons/ActionGroup/OnOffSmartLock/OnOffSmartLock.js +7 -4
- package/src/commons/ActionGroup/OnOffSmartLock/SetupGeneratePasscode/index.js +1 -0
- package/src/commons/ActionGroup/OnOffTemplate/OnOffSimpleTemplate.js +10 -10
- package/src/commons/ActionGroup/OnOffTemplate/index.js +18 -15
- package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +8 -2
- package/src/commons/ActionGroup/SliderRangeTemplate.js +1 -1
- package/src/commons/ActionGroup/SmartTiviActionTemplate/SmartTiviActionTemplate.js +4 -1
- package/src/commons/ActionGroup/StatesGridActionTemplate.js +14 -4
- package/src/commons/ActionGroup/TimerActionTemplate.js +9 -1
- package/src/commons/ActionGroup/TwoButtonTemplate/index.js +13 -9
- package/src/commons/ActionGroup/__test__/OnOffButtonTemplate.test.js +14 -14
- package/src/commons/ActionGroup/__test__/OnOffTemplate.test.js +53 -78
- package/src/commons/ActionGroup/__test__/OneBigButtonTemplate.test.js +36 -20
- package/src/commons/Auth/AccountList.js +1 -1
- package/src/commons/{Connecting → Connecting}/__test__/Connecting.test.js +0 -0
- package/src/commons/{Connecting → Connecting}/index.js +0 -0
- package/src/commons/{Connecting → Connecting}/styles.js +0 -0
- package/src/commons/ConnectingProcess/index.js +1 -1
- package/src/commons/Device/HistoryChart.js +6 -2
- package/src/commons/Device/PMSensor/PMSensorIndicatior.js +16 -12
- package/src/commons/Device/PMSensor/PMSensorIndicatorStyles.js +3 -0
- package/src/commons/Device/WaterQualitySensor/ListQualityIndicator.js +1 -0
- package/src/commons/FieldTemplate/ChooseUserField/ChooseFieldStyles.js +25 -0
- package/src/commons/FieldTemplate/ChooseUserField/ChoosePopup.js +96 -0
- package/src/commons/FieldTemplate/ChooseUserField/ChoosePopupStyles.js +39 -0
- package/src/commons/FieldTemplate/ChooseUserField/__test__/index.test.js +113 -0
- package/src/commons/FieldTemplate/ChooseUserField/index.js +62 -0
- package/src/commons/FieldTemplate/PasscodeField/PasscodeFieldStyles.js +30 -0
- package/src/commons/FieldTemplate/PasscodeField/__test__/index.test.js +93 -0
- package/src/commons/FieldTemplate/PasscodeField/index.js +43 -0
- package/src/commons/FieldTemplate/ScheduleField/ScheduleFieldStyles.js +13 -0
- package/src/commons/FieldTemplate/ScheduleField/__test__/index.test.js +182 -0
- package/src/commons/FieldTemplate/ScheduleField/index.js +176 -0
- package/src/commons/FullLoading/index.js +2 -1
- package/src/commons/MenuActionAddnew/index.js +1 -0
- package/src/commons/MenuActionList/index.js +1 -0
- package/src/commons/MenuActionMore/index.js +1 -1
- package/src/commons/PreventAccess/__test__/PreventAccess.test.js +62 -0
- package/src/commons/PreventAccess/index.js +67 -0
- package/src/commons/PreventAccess/styles.js +33 -0
- package/src/commons/WheelDateTimePicker/index.js +2 -1
- package/src/configs/API.js +3 -0
- package/src/configs/Constants.js +16 -1
- package/src/iot/RemoteControl/GoogleHome.js +24 -11
- package/src/iot/RemoteControl/__test__/GoogleHome.test.js +32 -0
- package/src/navigations/UnitStack.js +8 -0
- package/src/screens/AQIGuide/index.js +1 -1
- package/src/screens/ActivityLog/FilterPopup.js +2 -0
- package/src/screens/AddCommon/SelectSubUnit.js +1 -0
- package/src/screens/AddCommon/SelectUnit.js +1 -0
- package/src/screens/AddLocationMaps/index.js +4 -1
- package/src/screens/AddNewAction/SelectSensorDevices.js +14 -3
- package/src/screens/AddNewAction/__test__/SelectSensorDevices.test.js +34 -92
- package/src/screens/AddNewAutoSmart/__test__/AddNewAutoSmart.test.js +3 -1
- package/src/screens/AddNewAutoSmart/index.js +5 -2
- package/src/screens/AddNewDevice/index.js +1 -0
- package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +1 -1
- package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +4 -1
- package/src/screens/AddNewGateway/SelectGateway.js +1 -0
- package/src/screens/AddNewGateway/SetupGatewayWifi.js +1 -0
- package/src/screens/AddNewGateway/index.js +1 -0
- package/src/screens/AddNewOneTap/__test__/AddNewOneTap.test.js +1 -1
- package/src/screens/AddNewOneTap/index.js +3 -2
- package/src/screens/Automate/index.js +2 -0
- package/src/screens/Device/__test__/detail.test.js +4 -4
- package/src/screens/Device/detail.js +44 -6
- package/src/screens/EmergencyContacts/EmergencyContactsSelectContacts.js +5 -2
- package/src/screens/EmergencyContacts/__test__/EmergencyContactList.test.js +14 -0
- package/src/screens/EmergencyContacts/__test__/EmergencyContactsSelectContacts.test.js +19 -1
- package/src/screens/EmergencySetting/index.js +4 -1
- package/src/screens/Explore/index.js +2 -0
- package/src/screens/GuestInfo/__test__/index.test.js +1 -1
- package/src/screens/GuestInfo/components/RecurringDetail.js +1 -0
- package/src/screens/GuestInfo/components/TemporaryDetail.js +2 -2
- package/src/screens/ManageAccess/index.js +1 -0
- package/src/screens/MoveToAnotherSubUnit/index.js +1 -1
- package/src/screens/ScanChipQR/components/QRScan/index.js +1 -0
- package/src/screens/ScriptDetail/index.js +3 -3
- package/src/screens/SelectUnit/__test__/index.test.js +1 -1
- package/src/screens/SelectUnit/index.js +5 -2
- package/src/screens/SetSchedule/index.js +6 -2
- package/src/screens/SharedUnit/index.js +2 -0
- package/src/screens/Sharing/MemberList.js +12 -11
- package/src/screens/Sharing/SelectPermission.js +1 -1
- package/src/screens/Sharing/hooks/index.js +3 -0
- package/src/screens/SideMenuDetail/SideMenuDetailStyles.js +28 -0
- package/src/screens/SideMenuDetail/__test__/index.test.js +165 -0
- package/src/screens/SideMenuDetail/index.js +149 -0
- package/src/screens/SmartIr/components/SelectBrand.js +1 -1
- package/src/screens/SubUnit/ManageSubUnit.js +1 -0
- package/src/screens/SyncLGDevice/AddLGDevice.js +1 -0
- package/src/screens/TDSGuide/index.js +4 -1
- package/src/screens/UVIndexGuide/index.js +1 -1
- package/src/screens/Unit/Detail.js +18 -5
- package/src/screens/Unit/SelectAddress.js +4 -1
- package/src/screens/Unit/Station/index.js +1 -0
- package/src/screens/Unit/Summaries.js +1 -1
- package/src/screens/Unit/__test__/Detail.test.js +25 -5
- package/src/screens/UnitSummary/__test__/index.test.js +32 -0
- package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +1 -1
- package/src/screens/WaterQualityGuide/index.js +1 -1
- package/src/utils/I18n/translations/en.json +5 -1
- package/src/utils/I18n/translations/vi.json +5 -1
- package/src/utils/Route/index.js +1 -0
|
@@ -28,6 +28,7 @@ const SelectSensorDevices = memo(({ route }) => {
|
|
|
28
28
|
isAutomateTab,
|
|
29
29
|
isCreateNewAction,
|
|
30
30
|
isMultiUnits,
|
|
31
|
+
oldType,
|
|
31
32
|
} = route.params;
|
|
32
33
|
|
|
33
34
|
const [listStation, setListStation] = useState([]);
|
|
@@ -37,6 +38,7 @@ const SelectSensorDevices = memo(({ route }) => {
|
|
|
37
38
|
const [selectedDevice, setSelectedDevice] = useState();
|
|
38
39
|
const { navigate, dispatch, goBack } = useNavigation();
|
|
39
40
|
const isSelectSensor = title === AUTOMATE_SELECT.SELECT_SENSOR;
|
|
41
|
+
const [loading, setLoading] = useState(true);
|
|
40
42
|
|
|
41
43
|
const onSnapToItem = useCallback(
|
|
42
44
|
(item, index) => {
|
|
@@ -83,6 +85,7 @@ const SelectSensorDevices = memo(({ route }) => {
|
|
|
83
85
|
}
|
|
84
86
|
}
|
|
85
87
|
);
|
|
88
|
+
setLoading(false);
|
|
86
89
|
}, [automate.sensor_id, isSelectSensor, unit]);
|
|
87
90
|
|
|
88
91
|
useEffect(() => {
|
|
@@ -135,7 +138,7 @@ const SelectSensorDevices = memo(({ route }) => {
|
|
|
135
138
|
navigate(Routes.ScriptDetail, {
|
|
136
139
|
id: automateId,
|
|
137
140
|
name: scriptName,
|
|
138
|
-
type:
|
|
141
|
+
type: oldType,
|
|
139
142
|
havePermission: true,
|
|
140
143
|
unit,
|
|
141
144
|
isMultiUnits,
|
|
@@ -162,6 +165,9 @@ const SelectSensorDevices = memo(({ route }) => {
|
|
|
162
165
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
163
166
|
[route.params]
|
|
164
167
|
);
|
|
168
|
+
if (loading) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
165
171
|
|
|
166
172
|
return (
|
|
167
173
|
<View style={styles.wrap}>
|
|
@@ -170,12 +176,13 @@ const SelectSensorDevices = memo(({ route }) => {
|
|
|
170
176
|
<ScrollView
|
|
171
177
|
style={styles.wrap}
|
|
172
178
|
contentContainerStyle={styles.contentContainerStyle}
|
|
179
|
+
scrollIndicatorInsets={{ right: 1 }}
|
|
173
180
|
>
|
|
174
181
|
<Text bold type="H2" style={styles.title}>
|
|
175
182
|
{t(title)}
|
|
176
183
|
</Text>
|
|
177
184
|
|
|
178
|
-
{listStation ? (
|
|
185
|
+
{listStation.length ? (
|
|
179
186
|
<NavBar
|
|
180
187
|
listStation={listStation}
|
|
181
188
|
listMenuItem={listMenuItem}
|
|
@@ -211,7 +218,11 @@ const SelectSensorDevices = memo(({ route }) => {
|
|
|
211
218
|
style={styles.bottomButtonView}
|
|
212
219
|
mainTitle={t('continue')}
|
|
213
220
|
onPressMain={onPressContinue}
|
|
214
|
-
typeMain={
|
|
221
|
+
typeMain={
|
|
222
|
+
Object.keys(selectedDevice || {}).length === 0
|
|
223
|
+
? 'disabled'
|
|
224
|
+
: 'primary'
|
|
225
|
+
}
|
|
215
226
|
/>
|
|
216
227
|
</View>
|
|
217
228
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import renderer, { act } from 'react-test-renderer';
|
|
3
3
|
import axios from 'axios';
|
|
4
4
|
|
|
@@ -25,12 +25,10 @@ jest.mock('@react-navigation/native', () => {
|
|
|
25
25
|
};
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
-
const mockSetState = jest.fn();
|
|
29
28
|
jest.mock('react', () => {
|
|
30
29
|
return {
|
|
31
30
|
...jest.requireActual('react'),
|
|
32
31
|
memo: (x) => x,
|
|
33
|
-
useState: jest.fn((init) => [init, mockSetState]),
|
|
34
32
|
};
|
|
35
33
|
});
|
|
36
34
|
|
|
@@ -49,28 +47,27 @@ describe('Test SelectSensorDevices', () => {
|
|
|
49
47
|
scriptName: 'scriptName test',
|
|
50
48
|
},
|
|
51
49
|
};
|
|
50
|
+
const response = {
|
|
51
|
+
status: 200,
|
|
52
|
+
success: true,
|
|
53
|
+
data: [
|
|
54
|
+
{
|
|
55
|
+
id: 1,
|
|
56
|
+
name: 'Device 1',
|
|
57
|
+
sensors: [
|
|
58
|
+
{ id: 1, name: 'sensor' },
|
|
59
|
+
{ id: 2, name: 'sensor' },
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
52
64
|
|
|
53
65
|
beforeEach(() => {
|
|
54
66
|
axios.get.mockClear();
|
|
55
67
|
mockedNavigate.mockClear();
|
|
56
|
-
mockSetState.mockClear();
|
|
57
68
|
});
|
|
58
69
|
|
|
59
70
|
test('fetch Device success', async () => {
|
|
60
|
-
const response = {
|
|
61
|
-
status: 200,
|
|
62
|
-
success: true,
|
|
63
|
-
data: [
|
|
64
|
-
{
|
|
65
|
-
id: 1,
|
|
66
|
-
name: 'Device 1',
|
|
67
|
-
sensors: [
|
|
68
|
-
{ id: 1, name: 'sensor' },
|
|
69
|
-
{ id: 2, name: 'sensor' },
|
|
70
|
-
],
|
|
71
|
-
},
|
|
72
|
-
],
|
|
73
|
-
};
|
|
74
71
|
axios.get.mockImplementation(async () => {
|
|
75
72
|
return response;
|
|
76
73
|
});
|
|
@@ -78,12 +75,17 @@ describe('Test SelectSensorDevices', () => {
|
|
|
78
75
|
await act(async () => {
|
|
79
76
|
tree = renderer.create(wrapComponent(route));
|
|
80
77
|
});
|
|
78
|
+
const instance = tree.root;
|
|
79
|
+
const navBar = instance.findByType(NavBar);
|
|
81
80
|
|
|
82
81
|
expect(axios.get).toHaveBeenCalledWith(API.UNIT.DEVICE_CONTROL(1), {});
|
|
83
|
-
expect(
|
|
82
|
+
expect(navBar.props.listStation).toHaveLength(1);
|
|
84
83
|
});
|
|
85
84
|
|
|
86
85
|
test('onPress continue', async () => {
|
|
86
|
+
axios.get.mockImplementation(async () => {
|
|
87
|
+
return response;
|
|
88
|
+
});
|
|
87
89
|
await act(async () => {
|
|
88
90
|
tree = renderer.create(wrapComponent(route));
|
|
89
91
|
});
|
|
@@ -97,23 +99,9 @@ describe('Test SelectSensorDevices', () => {
|
|
|
97
99
|
});
|
|
98
100
|
|
|
99
101
|
test('test onPressDevice', async () => {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
name: 'Device 1',
|
|
104
|
-
sensors: [
|
|
105
|
-
{ id: 1, name: 'sensor' },
|
|
106
|
-
{ id: 2, name: 'sensor' },
|
|
107
|
-
],
|
|
108
|
-
},
|
|
109
|
-
];
|
|
110
|
-
const mockSetSelectedDevice = jest.fn();
|
|
111
|
-
useState.mockImplementationOnce((init) => [init, mockSetState]);
|
|
112
|
-
useState.mockImplementationOnce((init) => [init, mockSetState]);
|
|
113
|
-
useState.mockImplementationOnce((init) => [init, mockSetState]);
|
|
114
|
-
useState.mockImplementationOnce((init) => [data, mockSetState]);
|
|
115
|
-
useState.mockImplementationOnce((init) => [false, mockSetSelectedDevice]);
|
|
116
|
-
|
|
102
|
+
axios.get.mockImplementation(async () => {
|
|
103
|
+
return response;
|
|
104
|
+
});
|
|
117
105
|
await act(async () => {
|
|
118
106
|
tree = renderer.create(wrapComponent(route));
|
|
119
107
|
});
|
|
@@ -124,67 +112,18 @@ describe('Test SelectSensorDevices', () => {
|
|
|
124
112
|
act(() => {
|
|
125
113
|
device[0].props.onPress({ id: 1, name: 'sensor' });
|
|
126
114
|
});
|
|
127
|
-
expect(
|
|
128
|
-
id: 1,
|
|
129
|
-
name: 'sensor',
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
test('test onPressDevice false', async () => {
|
|
134
|
-
const data = [
|
|
135
|
-
{
|
|
136
|
-
id: 1,
|
|
137
|
-
name: 'Device 1',
|
|
138
|
-
sensors: [
|
|
139
|
-
{ id: 1, name: 'sensor' },
|
|
140
|
-
{ id: 2, name: 'sensor' },
|
|
141
|
-
],
|
|
142
|
-
},
|
|
143
|
-
];
|
|
144
|
-
const mockSetSelectedDevice = jest.fn();
|
|
145
|
-
useState.mockImplementationOnce((init) => [init, mockSetState]);
|
|
146
|
-
useState.mockImplementationOnce((init) => [init, mockSetState]);
|
|
147
|
-
useState.mockImplementationOnce((init) => [init, mockSetState]);
|
|
148
|
-
useState.mockImplementationOnce((init) => [data, mockSetState]);
|
|
149
|
-
useState.mockImplementationOnce((init) => [
|
|
150
|
-
{ id: 1, name: 'sensor' },
|
|
151
|
-
mockSetSelectedDevice,
|
|
152
|
-
]);
|
|
153
|
-
|
|
154
|
-
await act(async () => {
|
|
155
|
-
tree = renderer.create(wrapComponent(route));
|
|
156
|
-
});
|
|
157
|
-
const instance = tree.root;
|
|
158
|
-
const device = instance.findAllByType(Device);
|
|
159
|
-
expect(device).toHaveLength(2);
|
|
115
|
+
expect(device[0].props.isSelectDevice).toEqual(true);
|
|
160
116
|
|
|
161
117
|
act(() => {
|
|
162
118
|
device[0].props.onPress({ id: 1, name: 'sensor' });
|
|
163
119
|
});
|
|
164
|
-
expect(
|
|
120
|
+
expect(device[0].props.isSelectDevice).toEqual(false);
|
|
165
121
|
});
|
|
166
122
|
|
|
167
123
|
test('test onSnapItem', async () => {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
name: 'Device 1',
|
|
172
|
-
sensors: [
|
|
173
|
-
{ id: 1, name: 'sensor' },
|
|
174
|
-
{ id: 2, name: 'sensor' },
|
|
175
|
-
],
|
|
176
|
-
},
|
|
177
|
-
];
|
|
178
|
-
const listMenu = data.map((item, index) => ({
|
|
179
|
-
text: item.name,
|
|
180
|
-
station: item,
|
|
181
|
-
index: index,
|
|
182
|
-
}));
|
|
183
|
-
const mockSetIndexStation = jest.fn();
|
|
184
|
-
useState.mockImplementationOnce((init) => [listMenu, mockSetState]);
|
|
185
|
-
useState.mockImplementationOnce((init) => [init, mockSetState]);
|
|
186
|
-
useState.mockImplementationOnce((init) => [init, mockSetIndexStation]);
|
|
187
|
-
useState.mockImplementationOnce((init) => [data, mockSetState]);
|
|
124
|
+
axios.get.mockImplementation(async () => {
|
|
125
|
+
return response;
|
|
126
|
+
});
|
|
188
127
|
|
|
189
128
|
await act(async () => {
|
|
190
129
|
tree = renderer.create(wrapComponent(route));
|
|
@@ -195,10 +134,13 @@ describe('Test SelectSensorDevices', () => {
|
|
|
195
134
|
act(() => {
|
|
196
135
|
navBar.props.onSnapToItem({ id: 1, name: 'sensor' }, 0);
|
|
197
136
|
});
|
|
198
|
-
|
|
199
|
-
expect(mockSetIndexStation).toBeCalledWith(0);
|
|
137
|
+
expect(navBar.props.indexStation).toEqual(0);
|
|
200
138
|
});
|
|
139
|
+
|
|
201
140
|
test('test onPressClose user already has an automateId', async () => {
|
|
141
|
+
axios.get.mockImplementation(async () => {
|
|
142
|
+
return response;
|
|
143
|
+
});
|
|
202
144
|
await act(async () => {
|
|
203
145
|
tree = renderer.create(wrapComponent(route));
|
|
204
146
|
});
|
|
@@ -69,12 +69,13 @@ describe('test AddNewAutoSmart', () => {
|
|
|
69
69
|
automate: {},
|
|
70
70
|
automateId: undefined,
|
|
71
71
|
title: 'select_sensor',
|
|
72
|
-
|
|
72
|
+
oldType: 'value_change',
|
|
73
73
|
scriptName: undefined,
|
|
74
74
|
unit: { id: 1 },
|
|
75
75
|
isAutomateTab: undefined,
|
|
76
76
|
isMultiUnits: undefined,
|
|
77
77
|
routeName: 'SelectSensorDevices',
|
|
78
|
+
type: 'value_change',
|
|
78
79
|
});
|
|
79
80
|
});
|
|
80
81
|
|
|
@@ -102,6 +103,7 @@ describe('test AddNewAutoSmart', () => {
|
|
|
102
103
|
automate: {},
|
|
103
104
|
automateId: undefined,
|
|
104
105
|
type: 'schedule',
|
|
106
|
+
oldType: 'value_change',
|
|
105
107
|
routeName: 'SetSchedule',
|
|
106
108
|
scriptName: undefined,
|
|
107
109
|
unit: route.params.unit,
|
|
@@ -25,6 +25,7 @@ const AddNewAutoSmart = memo(({ route }) => {
|
|
|
25
25
|
automate = {},
|
|
26
26
|
scriptName,
|
|
27
27
|
} = route.params;
|
|
28
|
+
|
|
28
29
|
const typeAutoSmart = {
|
|
29
30
|
[AUTOMATE_TYPE.AUTOMATE]: [
|
|
30
31
|
{
|
|
@@ -96,6 +97,7 @@ const AddNewAutoSmart = memo(({ route }) => {
|
|
|
96
97
|
routeName: dataAutomate?.route,
|
|
97
98
|
automate,
|
|
98
99
|
scriptName,
|
|
100
|
+
oldType: type,
|
|
99
101
|
};
|
|
100
102
|
|
|
101
103
|
if (
|
|
@@ -107,14 +109,15 @@ const AddNewAutoSmart = memo(({ route }) => {
|
|
|
107
109
|
navigate(dataAutomate.route, params);
|
|
108
110
|
}
|
|
109
111
|
}, [
|
|
110
|
-
navigate,
|
|
111
|
-
selectedIndex,
|
|
112
112
|
data,
|
|
113
|
+
selectedIndex,
|
|
113
114
|
unit,
|
|
114
115
|
isAutomateTab,
|
|
115
116
|
isMultiUnits,
|
|
116
117
|
automate,
|
|
117
118
|
scriptName,
|
|
119
|
+
type,
|
|
120
|
+
navigate,
|
|
118
121
|
]);
|
|
119
122
|
|
|
120
123
|
const handleSelectIndex = (index) => {
|
|
@@ -90,6 +90,7 @@ const AddNewDevice = memo(({ route }) => {
|
|
|
90
90
|
<ScrollView
|
|
91
91
|
style={styles.scrollContainer}
|
|
92
92
|
showsVerticalScrollIndicator={false}
|
|
93
|
+
scrollIndicatorInsets={{ right: 1 }}
|
|
93
94
|
>
|
|
94
95
|
<Section type={'border'}>
|
|
95
96
|
<GroupCheckBox data={stations} onSelect={handleOnSelect} />
|
|
@@ -26,7 +26,7 @@ import Routes from '../../../utils/Route';
|
|
|
26
26
|
import { SCContext } from '../../../context';
|
|
27
27
|
import { Action } from '../../../context/actionType';
|
|
28
28
|
import { TESTID } from '../../../configs/Constants';
|
|
29
|
-
import Connecting from '../../../commons/Connecting
|
|
29
|
+
import Connecting from '../../../commons/Connecting';
|
|
30
30
|
|
|
31
31
|
const isIos = Platform.OS === 'ios';
|
|
32
32
|
const isAndroid = Platform.OS === 'android';
|
|
@@ -224,7 +224,10 @@ const GatewayWifiList = memo(({ route }) => {
|
|
|
224
224
|
{t('select_wifi')}
|
|
225
225
|
</Text>
|
|
226
226
|
|
|
227
|
-
<ScrollView
|
|
227
|
+
<ScrollView
|
|
228
|
+
style={styles.listContainer}
|
|
229
|
+
scrollIndicatorInsets={{ right: 1 }}
|
|
230
|
+
>
|
|
228
231
|
{!!list_wifi.length &&
|
|
229
232
|
list_wifi.map((item, index) => (
|
|
230
233
|
<TouchableOpacity
|
|
@@ -147,6 +147,7 @@ const SetupGatewayWifi = memo(({ route }) => {
|
|
|
147
147
|
<ScrollView
|
|
148
148
|
style={styles.scrollContainer}
|
|
149
149
|
showsVerticalScrollIndicator={false}
|
|
150
|
+
scrollIndicatorInsets={{ right: 1 }}
|
|
150
151
|
>
|
|
151
152
|
<Section type={'border'}>
|
|
152
153
|
<Text style={styles.textWifi} bold color={Colors.Primary}>
|
|
@@ -165,7 +165,7 @@ describe('test AddNewOneTap', () => {
|
|
|
165
165
|
expect(mockedNavigate).toHaveBeenCalledWith(Routes.ScriptDetail, {
|
|
166
166
|
id: 1,
|
|
167
167
|
name: 'script test',
|
|
168
|
-
type:
|
|
168
|
+
type: undefined,
|
|
169
169
|
havePermission: true,
|
|
170
170
|
unit: { id: 1 },
|
|
171
171
|
isMultiUnits: false,
|
|
@@ -25,6 +25,7 @@ const AddNewOneTap = memo(({ route }) => {
|
|
|
25
25
|
isMultiUnits,
|
|
26
26
|
automateId,
|
|
27
27
|
scriptName,
|
|
28
|
+
oldType,
|
|
28
29
|
} = route.params;
|
|
29
30
|
const t = useTranslations();
|
|
30
31
|
const { navigate, dispatch, goBack } = useNavigation();
|
|
@@ -91,7 +92,7 @@ const AddNewOneTap = memo(({ route }) => {
|
|
|
91
92
|
navigate(Routes.ScriptDetail, {
|
|
92
93
|
id: automateId,
|
|
93
94
|
name: scriptName,
|
|
94
|
-
type:
|
|
95
|
+
type: oldType,
|
|
95
96
|
havePermission: true,
|
|
96
97
|
unit,
|
|
97
98
|
isMultiUnits,
|
|
@@ -120,7 +121,7 @@ const AddNewOneTap = memo(({ route }) => {
|
|
|
120
121
|
}
|
|
121
122
|
>
|
|
122
123
|
<HeaderCustom isShowClose onClose={onClose} />
|
|
123
|
-
<ScrollView>
|
|
124
|
+
<ScrollView scrollIndicatorInsets={{ right: 1 }}>
|
|
124
125
|
<Text
|
|
125
126
|
testID={TESTID.ADD_NEW_DEVICE_ADD}
|
|
126
127
|
semibold
|
|
@@ -147,6 +147,7 @@ const Automate = () => {
|
|
|
147
147
|
showsHorizontalScrollIndicator={false}
|
|
148
148
|
contentContainerStyle={styles.contentContainerStyle2}
|
|
149
149
|
ListFooterComponent={renderListFooterComponent(type, unit_id)}
|
|
150
|
+
scrollIndicatorInsets={{ right: 1 }}
|
|
150
151
|
/>
|
|
151
152
|
</View>
|
|
152
153
|
);
|
|
@@ -189,6 +190,7 @@ const Automate = () => {
|
|
|
189
190
|
contentContainerStyle={styles.contentContainerStyle}
|
|
190
191
|
refreshing={false}
|
|
191
192
|
onRefresh={getAutomates}
|
|
193
|
+
scrollIndicatorInsets={{ right: 1 }}
|
|
192
194
|
/>
|
|
193
195
|
</View>
|
|
194
196
|
);
|
|
@@ -192,6 +192,7 @@ describe('test DeviceDetail', () => {
|
|
|
192
192
|
type: 'action',
|
|
193
193
|
},
|
|
194
194
|
],
|
|
195
|
+
side_menu_items: [{ id: 1, order: 1, name: 'Setup generate passcode' }],
|
|
195
196
|
};
|
|
196
197
|
test('render DeviceDetail render SensorDisplayItem', async () => {
|
|
197
198
|
const responseDisplay = {
|
|
@@ -227,10 +228,9 @@ describe('test DeviceDetail', () => {
|
|
|
227
228
|
const instance = tree.root;
|
|
228
229
|
expect(axios.get).toHaveBeenCalledTimes(4);
|
|
229
230
|
expect(axios.get).toHaveBeenCalledWith(API.SENSOR.DISPLAY(1), {});
|
|
230
|
-
expect(axios.get).toHaveBeenCalledWith(
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
);
|
|
231
|
+
expect(axios.get).toHaveBeenCalledWith(API.SENSOR.DISPLAY_VALUES_V2(1), {
|
|
232
|
+
params: new URLSearchParams(),
|
|
233
|
+
});
|
|
234
234
|
const sensorDisplayItem = instance.findAll(
|
|
235
235
|
(el) => el.props.testID === TESTID.SENSOR_DISPLAY_ITEM
|
|
236
236
|
);
|
|
@@ -12,7 +12,7 @@ import { get } from 'lodash';
|
|
|
12
12
|
import { useSelector } from 'react-redux';
|
|
13
13
|
import { IconFill, IconOutline } from '@ant-design/icons-react-native';
|
|
14
14
|
import { Icon } from '@ant-design/react-native';
|
|
15
|
-
|
|
15
|
+
import Routes from '../../utils/Route';
|
|
16
16
|
import { useCountUp } from './hooks/useCountUp';
|
|
17
17
|
import { getData as getLocalData } from '../../utils/Storage';
|
|
18
18
|
import { API, Colors } from '../../configs';
|
|
@@ -35,7 +35,7 @@ import Text from '../../commons/Text';
|
|
|
35
35
|
import { transformDatetime } from '../../utils/Converter/time';
|
|
36
36
|
import { AlertAction, ButtonPopup, MenuActionMore } from '../../commons';
|
|
37
37
|
import { TESTID } from '../../configs/Constants';
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
import { usePopover } from '../../hooks/Common';
|
|
40
40
|
import { useConfigGlobalState } from '../../iot/states';
|
|
41
41
|
import { useNavigation } from '@react-navigation/native';
|
|
@@ -47,6 +47,7 @@ import { EmergencyCountdown } from './components/EmergencyCountdown';
|
|
|
47
47
|
import { SensorConnectStatusViewHeader } from './components/SensorConnectStatusViewHeader';
|
|
48
48
|
import { useDisconnectedDevice } from './hooks/useDisconnectedDevice';
|
|
49
49
|
import { Card } from '../../commons/CardShadow';
|
|
50
|
+
import PreventAccess from '../../commons/PreventAccess';
|
|
50
51
|
|
|
51
52
|
const DeviceDetail = ({ route }) => {
|
|
52
53
|
const t = useTranslations();
|
|
@@ -73,13 +74,15 @@ const DeviceDetail = ({ route }) => {
|
|
|
73
74
|
const { isOwner } = useIsOwnerOfUnit(unit?.user_id);
|
|
74
75
|
const [sensorName, setSensorName] = useState(sensor?.name);
|
|
75
76
|
const [lockShowing, acquireLockShowing, releaseLockShowing] = useBoolean();
|
|
77
|
+
const [showPreventAccess, setShowPreventAccess, setHidePreventAccess] =
|
|
78
|
+
useBoolean(false);
|
|
76
79
|
const [showWindDirection, setShowWindDirection] = useState(false);
|
|
77
80
|
const [loading, setLoading] = useState({
|
|
78
81
|
isConnected: true,
|
|
79
82
|
displayTemplate: true,
|
|
80
83
|
});
|
|
81
84
|
const [serverDown, setServerDown] = useState(false);
|
|
82
|
-
|
|
85
|
+
const [sideMenu, setSideMenu] = useState([]);
|
|
83
86
|
const isNetworkConnected = useSCContextSelector(
|
|
84
87
|
(state) => state.app.isNetworkConnected
|
|
85
88
|
);
|
|
@@ -142,7 +145,9 @@ const DeviceDetail = ({ route }) => {
|
|
|
142
145
|
}, [currentUserId, unit]);
|
|
143
146
|
|
|
144
147
|
const fetchUnitDetail = useCallback(async () => {
|
|
145
|
-
const { success, data } = await axiosGet(API.UNIT.UNIT_DETAIL(unitId)
|
|
148
|
+
const { success, data } = await axiosGet(API.UNIT.UNIT_DETAIL(unitId), {
|
|
149
|
+
headers: { 'Cache-Control': 'no-cache' },
|
|
150
|
+
});
|
|
146
151
|
if (success) {
|
|
147
152
|
setUnit(data);
|
|
148
153
|
}
|
|
@@ -155,15 +160,17 @@ const DeviceDetail = ({ route }) => {
|
|
|
155
160
|
}, [fetchUnitDetail, unitId, unitData]);
|
|
156
161
|
|
|
157
162
|
const fetchSensorDetail = useCallback(async () => {
|
|
158
|
-
const { success, data } = await axiosGet(
|
|
163
|
+
const { success, data, resp_status } = await axiosGet(
|
|
159
164
|
API.SENSOR.SENSOR_DETAIL(sensorId)
|
|
160
165
|
);
|
|
161
166
|
if (success) {
|
|
162
167
|
setSensor(data);
|
|
163
168
|
setSensorName(data.name);
|
|
164
169
|
setStation(data.station);
|
|
170
|
+
} else if (resp_status === 404) {
|
|
171
|
+
setShowPreventAccess();
|
|
165
172
|
}
|
|
166
|
-
}, [sensorId]);
|
|
173
|
+
}, [sensorId, setShowPreventAccess]);
|
|
167
174
|
|
|
168
175
|
useEffect(() => {
|
|
169
176
|
if (sensorId && !sensorData) {
|
|
@@ -184,6 +191,7 @@ const DeviceDetail = ({ route }) => {
|
|
|
184
191
|
{},
|
|
185
192
|
true
|
|
186
193
|
);
|
|
194
|
+
|
|
187
195
|
if (success) {
|
|
188
196
|
setDisplay(data);
|
|
189
197
|
setServerDown(false);
|
|
@@ -203,6 +211,9 @@ const DeviceDetail = ({ route }) => {
|
|
|
203
211
|
}
|
|
204
212
|
}
|
|
205
213
|
}
|
|
214
|
+
if (data.side_menu_items.length) {
|
|
215
|
+
setSideMenu(data.side_menu_items);
|
|
216
|
+
}
|
|
206
217
|
}
|
|
207
218
|
setLoading((preState) => ({ ...preState, displayTemplate: false }));
|
|
208
219
|
|
|
@@ -298,6 +309,19 @@ const DeviceDetail = ({ route }) => {
|
|
|
298
309
|
text: t('activity_log'),
|
|
299
310
|
});
|
|
300
311
|
}
|
|
312
|
+
|
|
313
|
+
sideMenu.forEach((el) => {
|
|
314
|
+
menuItems.push({
|
|
315
|
+
route: Routes.SideMenuDetail,
|
|
316
|
+
data: {
|
|
317
|
+
unit,
|
|
318
|
+
sensor,
|
|
319
|
+
side_menu: el,
|
|
320
|
+
},
|
|
321
|
+
text: el.name,
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
|
|
301
325
|
menuItems.push({
|
|
302
326
|
route: Routes.DeviceInfo,
|
|
303
327
|
text: t('device_info'),
|
|
@@ -314,6 +338,13 @@ const DeviceDetail = ({ route }) => {
|
|
|
314
338
|
text: t('auto_lock'),
|
|
315
339
|
});
|
|
316
340
|
}
|
|
341
|
+
menuItems.push({
|
|
342
|
+
route: Routes.SmartLockStack,
|
|
343
|
+
data: {
|
|
344
|
+
screen: Routes.SetupGeneratePasscode,
|
|
345
|
+
},
|
|
346
|
+
text: t('setup_generate_passcode'),
|
|
347
|
+
});
|
|
317
348
|
if (isOwner && isShowSetUpSmartLock) {
|
|
318
349
|
menuItems.push({
|
|
319
350
|
route: Routes.SmartLockStack,
|
|
@@ -354,6 +385,7 @@ const DeviceDetail = ({ route }) => {
|
|
|
354
385
|
sensor,
|
|
355
386
|
unit,
|
|
356
387
|
sensorName,
|
|
388
|
+
sideMenu,
|
|
357
389
|
station,
|
|
358
390
|
emergencyDeviceId,
|
|
359
391
|
addToFavorites,
|
|
@@ -500,6 +532,7 @@ const DeviceDetail = ({ route }) => {
|
|
|
500
532
|
return isFlag;
|
|
501
533
|
}, [display]);
|
|
502
534
|
// replace isConnected=True to see template
|
|
535
|
+
|
|
503
536
|
const renderSensorConnected = () => {
|
|
504
537
|
return (
|
|
505
538
|
<SensorConnectStatusViewHeader
|
|
@@ -691,6 +724,11 @@ const DeviceDetail = ({ route }) => {
|
|
|
691
724
|
unit={unit}
|
|
692
725
|
station={sensor?.station}
|
|
693
726
|
/>
|
|
727
|
+
<PreventAccess
|
|
728
|
+
visible={showPreventAccess}
|
|
729
|
+
hidePreventAccess={setHidePreventAccess}
|
|
730
|
+
headerBodyText={'device'}
|
|
731
|
+
/>
|
|
694
732
|
</WrapHeaderScrollable>
|
|
695
733
|
{isShowEmergencyResolve && (
|
|
696
734
|
<BottomButtonView
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
|
-
import { SafeAreaView, StyleSheet, View } from 'react-native';
|
|
2
|
+
import { SafeAreaView, StyleSheet, View, Platform } from 'react-native';
|
|
3
3
|
import { IconOutline } from '@ant-design/icons-react-native';
|
|
4
4
|
import { useNavigation } from '@react-navigation/native';
|
|
5
5
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
@@ -71,7 +71,7 @@ export const EmergencyContactsSelectContacts = ({ route }) => {
|
|
|
71
71
|
return (
|
|
72
72
|
<SafeAreaView style={styles.container}>
|
|
73
73
|
<WrapHeaderScrollable title={t('select_contacts')} loading={loading}>
|
|
74
|
-
<Section type={'border'}>
|
|
74
|
+
<Section type={'border'} style={styles.section}>
|
|
75
75
|
{dataContact.map((contact, index) => (
|
|
76
76
|
<RowUser
|
|
77
77
|
key={contact.id.toString()}
|
|
@@ -116,6 +116,9 @@ const styles = StyleSheet.create({
|
|
|
116
116
|
flex: 1,
|
|
117
117
|
backgroundColor: Colors.Gray2,
|
|
118
118
|
},
|
|
119
|
+
section: {
|
|
120
|
+
marginTop: Platform.OS === 'ios' ? 40 : 0,
|
|
121
|
+
},
|
|
119
122
|
buttonRemove: {
|
|
120
123
|
height: 40,
|
|
121
124
|
width: 40,
|
|
@@ -2,6 +2,9 @@ import React from 'react';
|
|
|
2
2
|
import { TouchableOpacity } from 'react-native';
|
|
3
3
|
import { act, create } from 'react-test-renderer';
|
|
4
4
|
import Routes from '../../../utils/Route';
|
|
5
|
+
import axios from 'axios';
|
|
6
|
+
import { API } from '../../../configs';
|
|
7
|
+
|
|
5
8
|
import { AlertAction } from '../../../commons';
|
|
6
9
|
import { EmergencyContactsList } from '../EmergencyContactsList';
|
|
7
10
|
import { TESTID } from '../../../configs/Constants';
|
|
@@ -27,6 +30,8 @@ jest.mock('@react-navigation/native', () => {
|
|
|
27
30
|
};
|
|
28
31
|
});
|
|
29
32
|
|
|
33
|
+
jest.mock('axios');
|
|
34
|
+
|
|
30
35
|
describe('test EmergencyContactList', () => {
|
|
31
36
|
let route;
|
|
32
37
|
|
|
@@ -37,6 +42,7 @@ describe('test EmergencyContactList', () => {
|
|
|
37
42
|
group: 1,
|
|
38
43
|
},
|
|
39
44
|
};
|
|
45
|
+
axios.delete.mockClear();
|
|
40
46
|
});
|
|
41
47
|
let tree;
|
|
42
48
|
|
|
@@ -51,11 +57,19 @@ describe('test EmergencyContactList', () => {
|
|
|
51
57
|
const instance = tree.root;
|
|
52
58
|
const alertAction = instance.findByType(AlertAction);
|
|
53
59
|
|
|
60
|
+
const response = { status: 204 };
|
|
61
|
+
axios.delete.mockImplementation(async () => {
|
|
62
|
+
return response;
|
|
63
|
+
});
|
|
64
|
+
|
|
54
65
|
act(() => {
|
|
55
66
|
alertAction.props.rightButtonClick();
|
|
56
67
|
});
|
|
57
68
|
|
|
58
69
|
expect(alertAction.props.visible).toBe(false);
|
|
70
|
+
expect(axios.delete).toHaveBeenCalledWith(
|
|
71
|
+
API.EMERGENCY_BUTTON.REMOVE_CONTACTS()
|
|
72
|
+
);
|
|
59
73
|
});
|
|
60
74
|
|
|
61
75
|
test('onAddNew', async () => {
|