@eohjsc/react-native-smart-city 0.7.21 → 0.7.23
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/package.json +1 -1
- package/src/Images/Common/default_end_device.png +0 -0
- package/src/commons/ActionGroup/TerminalBoxTemplate.js +3 -0
- package/src/commons/ActionTemplate/OnOffButtonAction.js +38 -4
- package/src/commons/ActionTemplate/OnOffSimpleAction.js +55 -15
- package/src/commons/ActionTemplate/OnOffSmartLockAction.js +46 -8
- package/src/commons/ActionTemplate/SwitchButtonAction.js +35 -4
- package/src/commons/ActionTemplate/ThreeButtonAction.js +13 -3
- package/src/commons/ActionTemplate/__test__/OnOffButtonAction.test.js +46 -7
- package/src/commons/ActionTemplate/__test__/OnOffSimpleAction.test.js +66 -6
- package/src/commons/ActionTemplate/__test__/OnOffSmartLockAction.test.js +53 -13
- package/src/commons/ActionTemplate/__test__/SwitchButtonAction.test.js +46 -7
- package/src/commons/ActionTemplate/__test__/index.test.js +6 -2
- package/src/commons/ActionTemplate/index.js +65 -10
- package/src/commons/Dashboard/MyUnit/index.js +19 -20
- package/src/commons/DevMode/Search.js +1 -1
- package/src/commons/Device/RainningSensor/CurrentRainSensor.js +5 -5
- package/src/commons/MediaPlayerDetail/MediaPlayerFull.js +26 -32
- package/src/commons/OneTapTemplate/StatesGridActionTemplate.js +8 -6
- package/src/commons/SubUnit/OneTap/__test__/SubUnitAutomate.test.js +6 -0
- package/src/commons/SubUnit/OneTap/index.js +5 -0
- package/src/commons/UnitSummary/ConfigHistoryChart/index.js +9 -11
- package/src/commons/Widgets/IFrameWithConfig/IFrameWithConfig.js +2 -2
- package/src/commons/Widgets/IFrameWithConfig/__tests__/IFrameWithConfig.test.js +1 -1
- package/src/configs/API.js +10 -0
- package/src/configs/AccessibilityLabel.js +5 -1
- package/src/configs/Images.js +1 -0
- package/src/navigations/AddMemberStack.js +3 -3
- package/src/screens/ActivityLog/__test__/index.test.js +10 -0
- package/src/screens/ActivityLog/hooks/index.js +1 -1
- package/src/screens/AddCommon/SelectUnit.js +3 -2
- package/src/screens/AddLocationMaps/__test__/index.test.js +13 -13
- package/src/screens/Automate/AddNewAction/ChooseAction.js +15 -51
- package/src/screens/Automate/AddNewAction/SelectControlDevices.js +13 -3
- package/src/screens/Automate/AddNewAction/SetupConfigCondition.js +74 -54
- package/src/screens/Automate/AddNewAction/__test__/ChooseAction.test.js +114 -4
- package/src/screens/Automate/AddNewAction/__test__/ChooseConfig.test.js +9 -11
- package/src/screens/Automate/AddNewAction/__test__/SetupConfigCondition.test.js +37 -8
- package/src/screens/Automate/AddNewAutoSmart/AddTypeSmart.js +5 -0
- package/src/screens/Automate/AddNewAutoSmart/__test__/AddAutomationTypeSmart.test.js +31 -0
- package/src/screens/Automate/AddNewAutoSmart/__test__/AddNewAutoSmart.test.js +18 -2
- package/src/screens/Automate/Components/InputName.js +7 -6
- package/src/screens/Automate/Constants.js +12 -0
- package/src/screens/Automate/EditActionsList/UpdateActionScript.js +24 -55
- package/src/screens/Automate/EditActionsList/__tests__/UpdateActionScript.test.js +298 -41
- package/src/screens/Automate/EditActionsList/__tests__/index.test.js +2 -2
- package/src/screens/Automate/EditActionsList/index.js +26 -14
- package/src/screens/Automate/MultiUnits.js +9 -1
- package/src/screens/Automate/OneTap/__test__/AddNewOneTap.test.js +3 -3
- package/src/screens/Automate/ScriptDetail/Components/AddActionScript.js +4 -10
- package/src/screens/Automate/ScriptDetail/Components/DeleteScript.js +2 -4
- package/src/screens/Automate/ScriptDetail/__test__/index.test.js +78 -0
- package/src/screens/Automate/ScriptDetail/index.js +16 -10
- package/src/screens/Automate/ScriptDetail/utils.js +39 -35
- package/src/screens/Automate/SetSchedule/AddEditConditionSchedule.js +27 -160
- package/src/screens/Automate/SetSchedule/EditSchedule.js +269 -0
- package/src/screens/Automate/SetSchedule/__test__/AddEditConditionSchedule.test.js +327 -22
- package/src/screens/Automate/SetSchedule/__test__/index.test.js +35 -22
- package/src/screens/Automate/SetSchedule/components/RepeatOptionsPopup.js +2 -8
- package/src/screens/Automate/SetSchedule/index.js +15 -129
- package/src/screens/Automate/SetSchedule/styles/indexStyles.js +9 -0
- package/src/screens/Automate/__test__/MultiUnits.test.js +6 -1
- package/src/screens/Automate/hooks/useAction.js +222 -0
- package/src/screens/ConfirmUnitDeletion/__test__/ConfirmUnitDeletion.test.js +69 -13
- package/src/screens/ConfirmUnitDeletion/index.js +14 -14
- package/src/screens/Device/__test__/detail.test.js +48 -1
- package/src/screens/Device/detail.js +46 -3
- package/src/screens/PlayBackCamera/__test__/index.test.js +48 -13
- package/src/screens/PlayBackCamera/index.js +1 -1
- package/src/screens/Sharing/Components/ConfigItem.js +34 -0
- package/src/screens/Sharing/Components/DeviceItem.js +77 -0
- package/src/screens/Sharing/Components/ItemChangeRole.js +3 -4
- package/src/screens/Sharing/Components/ShareDeviceSelector.js +255 -0
- package/src/screens/Sharing/Components/Styles/CheckBoxCustomStyles.js +1 -1
- package/src/screens/Sharing/Components/Styles/DeviceItemStyles.js +11 -27
- package/src/screens/Sharing/{Styles/SelectPermissionStyles.js → Components/Styles/ShareDeviceSelectorStyles.js} +3 -11
- package/src/screens/Sharing/Components/SubUnitItem.js +28 -0
- package/src/screens/Sharing/Components/SubUnitTreeView.js +68 -0
- package/src/screens/Sharing/Components/TitleCheckBox.js +23 -41
- package/src/screens/Sharing/Components/__test__/ItemChangeRole.test.js +7 -7
- package/src/screens/Sharing/Components/__test__/ShareDeviceSelector.test.js +298 -0
- package/src/screens/Sharing/Components/index.js +14 -1
- package/src/screens/Sharing/InfoMemberUnit.js +20 -20
- package/src/screens/Sharing/SelectShareDevice.js +11 -255
- package/src/screens/Sharing/SelectUser.js +12 -12
- package/src/screens/Sharing/UpdateShareDevice.js +45 -301
- package/src/screens/Sharing/__test__/InfoMemberUnit.test.js +58 -11
- package/src/screens/Sharing/__test__/SelectShareDevice.test.js +51 -160
- package/src/screens/Sharing/__test__/SelectUser.test.js +72 -10
- package/src/screens/Sharing/__test__/UpdateShareDevice.test.js +49 -209
- package/src/utils/Apis/axios.js +6 -0
- package/src/utils/I18n/translations/en.js +9 -1
- package/src/utils/I18n/translations/vi.js +10 -2
- package/src/commons/Sharing/StationDevicePermissions.js +0 -204
- package/src/screens/Automate/constants.js +0 -0
- package/src/screens/Sharing/Components/CheckBoxConfig.js +0 -44
- package/src/screens/Sharing/Components/CheckBoxSubUnit.js +0 -35
- package/src/screens/Sharing/Components/EndDevice.js +0 -93
- package/src/screens/Sharing/Components/Styles/CheckBoxConfigStyles.js +0 -18
- package/src/screens/Sharing/Components/Styles/TitleCheckBoxStyles.js +0 -21
- package/src/screens/Sharing/Components/__test__/TitleCheckBox.test.js +0 -31
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import
|
|
1
|
+
import API from '../../../configs/API';
|
|
2
|
+
import AccessibilityLabel from '../../../configs/AccessibilityLabel';
|
|
3
|
+
import { Alert } from 'react-native';
|
|
4
|
+
import { IconOutline } from '@ant-design/icons-react-native';
|
|
2
5
|
import MockAdapter from 'axios-mock-adapter';
|
|
3
6
|
import React from 'react';
|
|
4
|
-
import { Alert } from 'react-native';
|
|
5
|
-
import { create } from 'react-test-renderer';
|
|
6
|
-
import { ViewButtonBottom } from '../../../commons';
|
|
7
|
-
import AccessibilityLabel from '../../../configs/AccessibilityLabel';
|
|
8
|
-
import API from '../../../configs/API';
|
|
9
7
|
import { SCProvider } from '../../../context';
|
|
10
|
-
import {
|
|
11
|
-
import api from '../../../utils/Apis/axios';
|
|
8
|
+
import { ShareDeviceSelector } from '../Components';
|
|
12
9
|
import UpdateShareDevice from '../UpdateShareDevice';
|
|
10
|
+
import { ViewButtonBottom } from '../../../commons';
|
|
11
|
+
import { act } from '@testing-library/react-hooks';
|
|
12
|
+
import api from '../../../utils/Apis/axios';
|
|
13
|
+
import { create } from 'react-test-renderer';
|
|
14
|
+
import { mockSCStore } from '../../../context/mockStore';
|
|
13
15
|
|
|
14
16
|
const mock = new MockAdapter(api.axiosInstance);
|
|
15
17
|
jest.spyOn(Alert, 'alert').mockImplementation(() => {});
|
|
@@ -39,256 +41,94 @@ describe('Test UpdateShareDevice', () => {
|
|
|
39
41
|
name: 'Sub unit',
|
|
40
42
|
devices: [
|
|
41
43
|
{
|
|
42
|
-
id:
|
|
43
|
-
actions: [{ id:
|
|
44
|
-
read_configs: [{ id:
|
|
44
|
+
id: 1,
|
|
45
|
+
actions: [{ id: 1, name: 'action 1' }],
|
|
46
|
+
read_configs: [{ id: 1, name: 'config 1' }],
|
|
45
47
|
name: 'child1',
|
|
46
48
|
},
|
|
47
49
|
{
|
|
48
|
-
id:
|
|
49
|
-
actions: [{ id:
|
|
50
|
-
read_configs: [{ id:
|
|
50
|
+
id: 2,
|
|
51
|
+
actions: [{ id: 2, name: 'action 2' }],
|
|
52
|
+
read_configs: [{ id: 2, name: 'config 2' }],
|
|
51
53
|
name: 'child2',
|
|
52
54
|
},
|
|
53
|
-
{
|
|
54
|
-
id: 8,
|
|
55
|
-
actions: [],
|
|
56
|
-
read_configs: [],
|
|
57
|
-
name: 'child3',
|
|
58
|
-
},
|
|
59
55
|
],
|
|
60
56
|
},
|
|
61
57
|
];
|
|
62
58
|
|
|
63
59
|
afterEach(() => {
|
|
64
|
-
Alert.alert.mockReset();
|
|
65
60
|
mock.resetHistory();
|
|
66
61
|
});
|
|
67
62
|
|
|
68
|
-
const
|
|
69
|
-
const
|
|
63
|
+
const clickChooseDevice = async (instance, deviceId, status) => {
|
|
64
|
+
const chooseDevice = instance.find(
|
|
70
65
|
(el) =>
|
|
71
66
|
el.props.accessibilityLabel ===
|
|
72
|
-
`${AccessibilityLabel.
|
|
67
|
+
`${AccessibilityLabel.SHARE_DEVICE.NAME_END_DEVICE}-device-${deviceId}`
|
|
73
68
|
);
|
|
74
|
-
expect(checkBoxAllDevice.props.isChecked).toEqual(statusCheckbox);
|
|
75
69
|
await act(async () => {
|
|
76
|
-
|
|
70
|
+
chooseDevice.props.onPress();
|
|
77
71
|
});
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const clickCheckBoxSubUnit = async (instance, statusCheckbox) => {
|
|
81
|
-
const checkBoxSubunit = instance.find(
|
|
72
|
+
const iconCheck = instance.findAll(
|
|
82
73
|
(el) =>
|
|
83
74
|
el.props.accessibilityLabel ===
|
|
84
|
-
|
|
75
|
+
`${AccessibilityLabel.SHARE_DEVICE.ICON_CHECK}-device-${deviceId}` &&
|
|
76
|
+
el.type === IconOutline
|
|
85
77
|
);
|
|
86
|
-
expect(
|
|
87
|
-
await act(async () => {
|
|
88
|
-
await checkBoxSubunit.props.onPress();
|
|
89
|
-
});
|
|
78
|
+
expect(iconCheck).toHaveLength(status ? 1 : 0);
|
|
90
79
|
};
|
|
91
|
-
|
|
92
|
-
const clickCheckBoxConfig = async (instance, configId, statusCheckbox) => {
|
|
93
|
-
let checkBoxConfig = instance.find(
|
|
94
|
-
(el) =>
|
|
95
|
-
el.props.accessibilityLabel ===
|
|
96
|
-
`${AccessibilityLabel.SHARE_DEVICE.CHECK_BOX_CONFIG}-${configId}`
|
|
97
|
-
);
|
|
98
|
-
expect(checkBoxConfig.props.isChecked).toEqual(statusCheckbox);
|
|
99
|
-
await act(async () => {
|
|
100
|
-
await checkBoxConfig.props.onPress();
|
|
101
|
-
});
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const clickExpandEndDevice = async (instance, indexEndDevice, statusIcon) => {
|
|
105
|
-
const expandEndDevice = instance.find(
|
|
106
|
-
(el) =>
|
|
107
|
-
el.props.accessibilityLabel ===
|
|
108
|
-
`${AccessibilityLabel.SHARE_DEVICE.EXPAND_END_DEVICE}-${indexEndDevice}`
|
|
109
|
-
);
|
|
110
|
-
expect(expandEndDevice.props.name).toEqual(statusIcon);
|
|
111
|
-
await act(async () => {
|
|
112
|
-
await expandEndDevice.props.onPress();
|
|
113
|
-
});
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
const clickNameEndDevice = async (instance, indexEndDevice) => {
|
|
117
|
-
const nameEndDevice = instance.find(
|
|
118
|
-
(el) =>
|
|
119
|
-
el.props.accessibilityLabel ===
|
|
120
|
-
`${AccessibilityLabel.SHARE_DEVICE.CLICK_NAME_END_DEVICE}-${indexEndDevice}`
|
|
121
|
-
);
|
|
122
|
-
await act(async () => {
|
|
123
|
-
await nameEndDevice.props.onPress();
|
|
124
|
-
});
|
|
125
|
-
};
|
|
126
|
-
|
|
127
80
|
it('test user update share device by phone', async () => {
|
|
128
|
-
mock.onGet(API.SHARE.
|
|
129
|
-
mock.onGet(API.SHARE.
|
|
130
|
-
|
|
81
|
+
mock.onGet(API.SHARE.UNIT_PERMISSIONS_v2(1)).reply(200, listDevices);
|
|
82
|
+
mock.onGet(API.SHARE.UNIT_MEMBER_SHARE_DEVICE_V2(1, 1)).reply(200, [
|
|
83
|
+
{
|
|
84
|
+
id: 1,
|
|
85
|
+
devices: [{ id: 2, read_configs: [{ id: 2 }], actions: [{ id: 2 }] }],
|
|
86
|
+
},
|
|
87
|
+
]);
|
|
88
|
+
mock.onPost(API.SHARE.SHARE_V2()).reply(200);
|
|
131
89
|
|
|
132
90
|
await act(async () => {
|
|
133
91
|
tree = await create(wrapComponent(route));
|
|
134
92
|
});
|
|
135
93
|
let instance = tree.root;
|
|
136
|
-
await
|
|
137
|
-
await clickNameEndDevice(instance, 0); // click again to remove all configs, and coverage expand end device
|
|
138
|
-
await clickCheckBoxConfig(instance, 3, false); // click to select action
|
|
139
|
-
await clickCheckBoxConfig(instance, 3, true); // click again to coverage case status reversal
|
|
140
|
-
await clickCheckBoxConfig(instance, 4, false); // click to select config
|
|
141
|
-
await clickCheckBoxConfig(instance, 4, true); // click again to coverage case status reversal
|
|
142
|
-
await clickExpandEndDevice(instance, 0, 'up');
|
|
143
|
-
await clickExpandEndDevice(instance, 0, 'down'); // click again to coverage case status reversal
|
|
144
|
-
|
|
145
|
-
await clickCheckBoxAllDevice(instance, false); // click to select all device
|
|
146
|
-
await clickCheckBoxSubUnit(instance, true); // click to remove all device in sub unit id 1
|
|
147
|
-
await clickNameEndDevice(instance, 1); // click to select all configs in end device index 1
|
|
148
|
-
await clickNameEndDevice(instance, 2); // click to select all configs in end device index 2
|
|
94
|
+
await clickChooseDevice(instance, 1, true);
|
|
149
95
|
|
|
150
|
-
const
|
|
96
|
+
const viewButtonBottom = instance.findByType(ViewButtonBottom);
|
|
151
97
|
await act(async () => {
|
|
152
|
-
|
|
98
|
+
viewButtonBottom.props.onRightClick();
|
|
153
99
|
});
|
|
100
|
+
expect(viewButtonBottom.props.rightTitle).toEqual('Done');
|
|
154
101
|
expect(global.mockedGoBack).toHaveBeenCalled();
|
|
155
102
|
expect(mock.history.post[0].data).toEqual(
|
|
156
103
|
JSON.stringify({
|
|
157
|
-
|
|
158
|
-
email: '',
|
|
104
|
+
user_ids: [1],
|
|
159
105
|
unit: 1,
|
|
160
106
|
permissions: {
|
|
161
107
|
read_permissions: [
|
|
162
|
-
{ id:
|
|
163
|
-
{ id:
|
|
108
|
+
{ id: 1, values: [1] },
|
|
109
|
+
{ id: 2, values: [2] },
|
|
110
|
+
],
|
|
111
|
+
control_permissions: [
|
|
112
|
+
{ id: 1, values: [1] },
|
|
113
|
+
{ id: 2, values: [2] },
|
|
164
114
|
],
|
|
165
|
-
control_permissions: [{ id: 5, values: [6] }],
|
|
166
|
-
},
|
|
167
|
-
is_remove_old_permission: true,
|
|
168
|
-
})
|
|
169
|
-
);
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
it('test user update share device by email', async () => {
|
|
173
|
-
mock.onGet(API.SHARE.UNIT_PERMISSIONS(1)).reply(200, listDevices);
|
|
174
|
-
mock.onGet(API.SHARE.UNIT_MEMBER_SHARE_DEVICE(1, 1)).reply(200, []);
|
|
175
|
-
mock.onPost(API.SHARE.SHARE()).reply(200);
|
|
176
|
-
|
|
177
|
-
route.params.member.phone_number = '';
|
|
178
|
-
await act(async () => {
|
|
179
|
-
tree = await create(wrapComponent(route));
|
|
180
|
-
});
|
|
181
|
-
const instance = tree.root;
|
|
182
|
-
await clickNameEndDevice(instance, 0); // click to select all configs in end device index 0
|
|
183
|
-
const ViewButtonBottomElement = instance.findAllByType(ViewButtonBottom);
|
|
184
|
-
expect(ViewButtonBottomElement).toHaveLength(1);
|
|
185
|
-
await act(async () => {
|
|
186
|
-
ViewButtonBottomElement[0].props.onRightClick();
|
|
187
|
-
});
|
|
188
|
-
expect(global.mockedGoBack).toHaveBeenCalled();
|
|
189
|
-
expect(mock.history.post[0].data).toEqual(
|
|
190
|
-
JSON.stringify({
|
|
191
|
-
phone: '',
|
|
192
|
-
email: 'email@gmail.com',
|
|
193
|
-
unit: 1,
|
|
194
|
-
permissions: {
|
|
195
|
-
read_permissions: [{ id: 2, values: [4] }],
|
|
196
|
-
control_permissions: [{ id: 2, values: [3] }],
|
|
197
|
-
},
|
|
198
|
-
is_remove_old_permission: true,
|
|
199
|
-
})
|
|
200
|
-
);
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
it('test user update share device not have phone and email', async () => {
|
|
204
|
-
mock.onGet(API.SHARE.UNIT_PERMISSIONS(1)).reply(200, listDevices);
|
|
205
|
-
mock.onGet(API.SHARE.UNIT_MEMBER_SHARE_DEVICE(1, 1)).reply(200, []);
|
|
206
|
-
mock.onPost(API.SHARE.SHARE()).reply(400);
|
|
207
|
-
|
|
208
|
-
route.params.member.phone_number = '';
|
|
209
|
-
route.params.member.email = '';
|
|
210
|
-
await act(async () => {
|
|
211
|
-
tree = await create(wrapComponent(route));
|
|
212
|
-
});
|
|
213
|
-
const instance = tree.root;
|
|
214
|
-
await clickNameEndDevice(instance, 0); // click to select all configs in end device index 0
|
|
215
|
-
const ViewButtonBottomElement = instance.findAllByType(ViewButtonBottom);
|
|
216
|
-
expect(ViewButtonBottomElement).toHaveLength(1);
|
|
217
|
-
await act(async () => {
|
|
218
|
-
ViewButtonBottomElement[0].props.onRightClick();
|
|
219
|
-
});
|
|
220
|
-
expect(global.mockedGoBack).not.toHaveBeenCalled();
|
|
221
|
-
expect(mock.history.post[0].data).toEqual(
|
|
222
|
-
JSON.stringify({
|
|
223
|
-
phone: '',
|
|
224
|
-
email: '',
|
|
225
|
-
unit: 1,
|
|
226
|
-
permissions: {
|
|
227
|
-
read_permissions: [{ id: 2, values: [4] }],
|
|
228
|
-
control_permissions: [{ id: 2, values: [3] }],
|
|
229
115
|
},
|
|
230
116
|
is_remove_old_permission: true,
|
|
231
117
|
})
|
|
232
118
|
);
|
|
233
119
|
});
|
|
234
120
|
|
|
235
|
-
it('test
|
|
236
|
-
mock.onGet(API.SHARE.
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
tree = await create(wrapComponent(route));
|
|
240
|
-
});
|
|
241
|
-
const instance = tree.root;
|
|
242
|
-
|
|
243
|
-
let text = instance.find(
|
|
244
|
-
(el) =>
|
|
245
|
-
el.props.accessibilityLabel === AccessibilityLabel.TEXT_NO_DATA_STATIONS
|
|
246
|
-
);
|
|
247
|
-
expect(text.props.children).toEqual('No data');
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
it('test api get UNIT_MEMBER_SHARE_DEVICE false', async () => {
|
|
251
|
-
mock.onGet(API.SHARE.UNIT_PERMISSIONS(1)).reply(200, listDevices);
|
|
252
|
-
mock.onGet(API.SHARE.UNIT_MEMBER_SHARE_DEVICE(1, 1)).reply(400);
|
|
121
|
+
it('test user update share device get unit member share device error', async () => {
|
|
122
|
+
mock.onGet(API.SHARE.UNIT_PERMISSIONS_v2(1)).reply(200, listDevices);
|
|
123
|
+
mock.onGet(API.SHARE.UNIT_MEMBER_SHARE_DEVICE_V2(1, 1)).reply(400);
|
|
124
|
+
mock.onPost(API.SHARE.SHARE_V2()).reply(200);
|
|
253
125
|
|
|
254
126
|
await act(async () => {
|
|
255
127
|
tree = await create(wrapComponent(route));
|
|
256
128
|
});
|
|
257
129
|
const instance = tree.root;
|
|
258
130
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
el.props.accessibilityLabel === AccessibilityLabel.TEXT_NO_DATA_STATIONS
|
|
262
|
-
);
|
|
263
|
-
expect(text).toEqual([]);
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
it('user not choose device click button back', async () => {
|
|
267
|
-
await act(async () => {
|
|
268
|
-
tree = await create(wrapComponent(route));
|
|
269
|
-
});
|
|
270
|
-
const instance = tree.root;
|
|
271
|
-
const ViewButtonBottomElement = instance.findAllByType(ViewButtonBottom);
|
|
272
|
-
expect(ViewButtonBottomElement).toHaveLength(1);
|
|
273
|
-
|
|
274
|
-
await act(async () => {
|
|
275
|
-
ViewButtonBottomElement[0].props.onLeftClick();
|
|
276
|
-
});
|
|
277
|
-
expect(global.mockedGoBack).toHaveBeenCalled();
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
it('user not choose device click button next', async () => {
|
|
281
|
-
await act(async () => {
|
|
282
|
-
tree = await create(wrapComponent(route));
|
|
283
|
-
});
|
|
284
|
-
const instance = tree.root;
|
|
285
|
-
const ViewButtonBottomElement = instance.findAllByType(ViewButtonBottom);
|
|
286
|
-
expect(ViewButtonBottomElement).toHaveLength(1);
|
|
287
|
-
await act(async () => {
|
|
288
|
-
ViewButtonBottomElement[0].props.onRightClick();
|
|
289
|
-
});
|
|
290
|
-
expect(Alert.alert.mock.calls[0][1]).toEqual(
|
|
291
|
-
'Please choose at least one sensor.'
|
|
292
|
-
);
|
|
131
|
+
const shareDeviceSelector = instance.findByType(ShareDeviceSelector);
|
|
132
|
+
expect(shareDeviceSelector.props.initialSelectedKeys).toEqual([]);
|
|
293
133
|
});
|
|
294
134
|
});
|
package/src/utils/Apis/axios.js
CHANGED
|
@@ -75,6 +75,12 @@ const parseErrorResponse = async (error) => {
|
|
|
75
75
|
if (message instanceof Array) {
|
|
76
76
|
message = message[0];
|
|
77
77
|
}
|
|
78
|
+
if (message instanceof Object) {
|
|
79
|
+
return await parseErrorResponse({
|
|
80
|
+
...error,
|
|
81
|
+
data: message,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
78
84
|
if (message?.message) {
|
|
79
85
|
message = message.message;
|
|
80
86
|
}
|
|
@@ -960,7 +960,7 @@ export default {
|
|
|
960
960
|
today: 'Today',
|
|
961
961
|
yesterday: 'Yesterday',
|
|
962
962
|
at: 'at',
|
|
963
|
-
choose_at_least_one: 'Please choose at least one
|
|
963
|
+
choose_at_least_one: 'Please choose at least one device.',
|
|
964
964
|
'transaction_is_unsuccessful_%{message}':
|
|
965
965
|
'Transaction is unsuccessful. %{message}',
|
|
966
966
|
emergency_resolved:
|
|
@@ -1083,6 +1083,13 @@ export default {
|
|
|
1083
1083
|
once: 'Once',
|
|
1084
1084
|
every_day: 'Everyday',
|
|
1085
1085
|
every_week: 'Every Week',
|
|
1086
|
+
time_range: 'Time Range',
|
|
1087
|
+
time_range_repeat: 'Time range repeat',
|
|
1088
|
+
repeat_every: 'Repeat every {interval} minutes',
|
|
1089
|
+
from_to: 'From {from} to {to} {weekdays}',
|
|
1090
|
+
on_weekday: 'on',
|
|
1091
|
+
interval: 'Interval',
|
|
1092
|
+
interval_repeat: 'Interval (minutes)',
|
|
1086
1093
|
button: 'Button',
|
|
1087
1094
|
create_smart: 'Create Smart',
|
|
1088
1095
|
update_smart: 'Update Smart',
|
|
@@ -1135,6 +1142,7 @@ export default {
|
|
|
1135
1142
|
mode: 'Mode',
|
|
1136
1143
|
text_on: 'On',
|
|
1137
1144
|
text_off: 'Off',
|
|
1145
|
+
toggle: 'Toggle',
|
|
1138
1146
|
set_temperature: 'Set temperature',
|
|
1139
1147
|
not_permission:
|
|
1140
1148
|
'There are some control commands you have not been authorized',
|
|
@@ -532,7 +532,7 @@ export default {
|
|
|
532
532
|
role: 'Vai trò',
|
|
533
533
|
change_role: 'Thay đổi vai trò',
|
|
534
534
|
identity: 'Xác thực',
|
|
535
|
-
share_devices: 'Chia
|
|
535
|
+
share_devices: 'Chia sẻ thiết bị',
|
|
536
536
|
no_member: 'Không có thành viên nào',
|
|
537
537
|
sharing_removed_user: 'Thành viên {name} đã được xóa.',
|
|
538
538
|
sharing_you_left: 'Bạn đã rời địa điểm.',
|
|
@@ -1093,6 +1093,13 @@ export default {
|
|
|
1093
1093
|
once: 'Một lần',
|
|
1094
1094
|
every_day: 'Hằng ngày',
|
|
1095
1095
|
every_week: 'Hằng tuần',
|
|
1096
|
+
time_range: 'Khoảng thời gian',
|
|
1097
|
+
time_range_repeat: 'Tần suất lặp lại',
|
|
1098
|
+
repeat_every: 'Lặp lại mỗi {interval} phút',
|
|
1099
|
+
from_to: 'Từ {from} đến {to} {weekdays}',
|
|
1100
|
+
on_weekday: 'vào',
|
|
1101
|
+
interval: 'Chu kỳ',
|
|
1102
|
+
interval_repeat: 'Chu kỳ (phút)',
|
|
1096
1103
|
create_smart: 'Tạo thông minh',
|
|
1097
1104
|
update_smart: 'Cập nhật thông minh',
|
|
1098
1105
|
automate: 'Tự động',
|
|
@@ -1143,6 +1150,7 @@ export default {
|
|
|
1143
1150
|
mode: 'Chế độ',
|
|
1144
1151
|
text_on: 'Bật',
|
|
1145
1152
|
text_off: 'Tắt',
|
|
1153
|
+
toggle: 'Đảo trạng thái',
|
|
1146
1154
|
set_temperature: 'Thiết lập nhiệt độ',
|
|
1147
1155
|
not_permission: 'Có một số lệnh điều khiển bạn chưa được cấp quyền',
|
|
1148
1156
|
you_do_not_have_permission_to_access:
|
|
@@ -1550,7 +1558,7 @@ export default {
|
|
|
1550
1558
|
bellow_widget_is_not_configured: 'Tiện ích bên dưới chưa được cấu hình',
|
|
1551
1559
|
bellow_widget_is_wrongly_configured: 'Tiện ích bên dưới được cấu hình sai',
|
|
1552
1560
|
widget_have_not_been_shared:
|
|
1553
|
-
'Tiện ích {widget} chưa được chia s
|
|
1561
|
+
'Tiện ích {widget} chưa được chia sẻ. Vui lòng liên hệ với chủ sở hữu',
|
|
1554
1562
|
customize: 'Tùy chỉnh điều kiện',
|
|
1555
1563
|
uri_invalid: 'URI không hợp lệ',
|
|
1556
1564
|
when_value_is: 'Kích hoạt khi giá trị "{config_name}"',
|
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
import React, { useState, useCallback } from 'react';
|
|
2
|
-
import { View, StyleSheet, TouchableOpacity } from 'react-native';
|
|
3
|
-
import { IconOutline } from '@ant-design/icons-react-native';
|
|
4
|
-
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
5
|
-
import { Colors } from '../../configs';
|
|
6
|
-
import Text from '../../commons/Text';
|
|
7
|
-
import SensorIcon from '../../../assets/images/Device/sensor.svg';
|
|
8
|
-
import BarrierIcon from '../../../assets/images/Device/barrier.svg';
|
|
9
|
-
import SvgDoor from '../../../assets/images/Device/door.svg';
|
|
10
|
-
import SensorInactive from '../../../assets/images/Device/sensor-inactive.svg';
|
|
11
|
-
import BarrierInactive from '../../../assets/images/Device/barrier-inactive.svg';
|
|
12
|
-
import DoorInactive from '../../../assets/images/Device/door-inactive.svg';
|
|
13
|
-
|
|
14
|
-
import DevicePermissionsCheckbox from './DevicePermissionsCheckbox';
|
|
15
|
-
|
|
16
|
-
const StationDevicePermissions = ({ dataStation, onselectSensor }) => {
|
|
17
|
-
const t = useTranslations();
|
|
18
|
-
const [listChosen, setListChosen] = useState({}); // { sensorId : indexConfigChoosen , ...}
|
|
19
|
-
const [expandedIndex, setExpandedIndex] = useState(-1);
|
|
20
|
-
|
|
21
|
-
const displayIconSensor = (svgMain, activated) => {
|
|
22
|
-
let svgResult;
|
|
23
|
-
switch (svgMain) {
|
|
24
|
-
case 'barrier':
|
|
25
|
-
svgResult = activated ? <BarrierIcon /> : <BarrierInactive />;
|
|
26
|
-
break;
|
|
27
|
-
case 'sensor':
|
|
28
|
-
svgResult = activated ? <SensorIcon /> : <SensorInactive />;
|
|
29
|
-
break;
|
|
30
|
-
default:
|
|
31
|
-
svgResult = activated ? <SvgDoor /> : <DoorInactive />;
|
|
32
|
-
break;
|
|
33
|
-
}
|
|
34
|
-
return svgResult;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const onPressExpand = useCallback(
|
|
38
|
-
(index) => () => {
|
|
39
|
-
setExpandedIndex(index === expandedIndex ? -1 : index);
|
|
40
|
-
},
|
|
41
|
-
[expandedIndex]
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
const onSelectIndexes = useCallback(
|
|
45
|
-
(sensor, selectionIndexes) => {
|
|
46
|
-
let readPermission = [];
|
|
47
|
-
let controlPermission = [];
|
|
48
|
-
if (selectionIndexes.indexOf(-1) > -1) {
|
|
49
|
-
//perrmision
|
|
50
|
-
readPermission = sensor.read_configs.map((item) => item.id);
|
|
51
|
-
controlPermission = sensor.actions.map((item) => item.id);
|
|
52
|
-
} else {
|
|
53
|
-
selectionIndexes.forEach((index) => {
|
|
54
|
-
if (index >= sensor.read_configs.length) {
|
|
55
|
-
//index of actions
|
|
56
|
-
controlPermission.push(
|
|
57
|
-
sensor.actions[index - sensor.read_configs.length].id
|
|
58
|
-
);
|
|
59
|
-
} else {
|
|
60
|
-
readPermission.push(sensor.read_configs[index].id);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
onselectSensor(sensor.id, readPermission, controlPermission);
|
|
65
|
-
|
|
66
|
-
const chosen = { ...listChosen };
|
|
67
|
-
chosen[sensor.id] = selectionIndexes;
|
|
68
|
-
setListChosen(chosen);
|
|
69
|
-
},
|
|
70
|
-
[listChosen, setListChosen, onselectSensor]
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
const RowDevice = ({ sensor, index }) => {
|
|
74
|
-
return (
|
|
75
|
-
<View>
|
|
76
|
-
<TouchableOpacity
|
|
77
|
-
style={styles.rowContainer}
|
|
78
|
-
onPress={onPressExpand(index)}
|
|
79
|
-
>
|
|
80
|
-
<View style={styles.iconContainer}>
|
|
81
|
-
{displayIconSensor(
|
|
82
|
-
sensor.icon || 'door',
|
|
83
|
-
!!listChosen[sensor.id] && listChosen[sensor.id].length > 0
|
|
84
|
-
)}
|
|
85
|
-
</View>
|
|
86
|
-
<View style={styles.infoContainer}>
|
|
87
|
-
<Text style={styles.text}>{sensor.name}</Text>
|
|
88
|
-
<View style={styles.rightImage}>
|
|
89
|
-
<IconOutline
|
|
90
|
-
name={expandedIndex === index ? 'up' : 'down'}
|
|
91
|
-
size={20}
|
|
92
|
-
color={Colors.Gray6}
|
|
93
|
-
/>
|
|
94
|
-
</View>
|
|
95
|
-
</View>
|
|
96
|
-
</TouchableOpacity>
|
|
97
|
-
<View
|
|
98
|
-
style={
|
|
99
|
-
expandedIndex === index
|
|
100
|
-
? styles.expandContainer
|
|
101
|
-
: styles.collapseContainer
|
|
102
|
-
}
|
|
103
|
-
>
|
|
104
|
-
<DevicePermissionsCheckbox
|
|
105
|
-
sensor={sensor}
|
|
106
|
-
selectedIndexes={listChosen[sensor.id] ?? []}
|
|
107
|
-
onSelectIndexes={onSelectIndexes}
|
|
108
|
-
/>
|
|
109
|
-
</View>
|
|
110
|
-
<View style={styles.lineSpace} />
|
|
111
|
-
</View>
|
|
112
|
-
);
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
return (
|
|
116
|
-
<>
|
|
117
|
-
<Text color={Colors.Gray8} style={styles.stationName}>
|
|
118
|
-
{dataStation.name}
|
|
119
|
-
</Text>
|
|
120
|
-
<View style={styles.box}>
|
|
121
|
-
{!dataStation.sensors.length && (
|
|
122
|
-
<Text style={styles.textEmpty}>{t('no_device')}</Text>
|
|
123
|
-
)}
|
|
124
|
-
{dataStation.sensors.map((device, index) => (
|
|
125
|
-
<RowDevice sensor={device} index={index} key={device.id} />
|
|
126
|
-
))}
|
|
127
|
-
</View>
|
|
128
|
-
</>
|
|
129
|
-
);
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
const styles = StyleSheet.create({
|
|
133
|
-
box: {
|
|
134
|
-
paddingBottom: 16,
|
|
135
|
-
borderRadius: 20,
|
|
136
|
-
backgroundColor: Colors.White,
|
|
137
|
-
borderWidth: 1,
|
|
138
|
-
borderColor: Colors.Gray4,
|
|
139
|
-
marginBottom: 16,
|
|
140
|
-
},
|
|
141
|
-
rowContainer: {
|
|
142
|
-
flexDirection: 'row',
|
|
143
|
-
alignItems: 'center',
|
|
144
|
-
paddingHorizontal: 16,
|
|
145
|
-
},
|
|
146
|
-
iconContainer: {
|
|
147
|
-
alignItems: 'center',
|
|
148
|
-
justifyContent: 'center',
|
|
149
|
-
marginRight: 16,
|
|
150
|
-
width: 40,
|
|
151
|
-
height: 40,
|
|
152
|
-
borderRadius: 20,
|
|
153
|
-
},
|
|
154
|
-
infoContainer: {
|
|
155
|
-
flex: 1,
|
|
156
|
-
paddingVertical: 16,
|
|
157
|
-
},
|
|
158
|
-
lineSpace: {
|
|
159
|
-
borderBottomWidth: 1,
|
|
160
|
-
borderColor: Colors.Gray4,
|
|
161
|
-
position: 'absolute',
|
|
162
|
-
bottom: 0,
|
|
163
|
-
left: 72,
|
|
164
|
-
right: 24,
|
|
165
|
-
height: 1,
|
|
166
|
-
},
|
|
167
|
-
text: {
|
|
168
|
-
fontSize: 16,
|
|
169
|
-
lineHeight: 24,
|
|
170
|
-
color: Colors.Gray9,
|
|
171
|
-
marginBottom: 0,
|
|
172
|
-
},
|
|
173
|
-
rightImage: {
|
|
174
|
-
position: 'absolute',
|
|
175
|
-
right: 0,
|
|
176
|
-
top: 10,
|
|
177
|
-
bottom: 10,
|
|
178
|
-
paddingHorizontal: 10,
|
|
179
|
-
justifyContent: 'center',
|
|
180
|
-
},
|
|
181
|
-
expandContainer: {
|
|
182
|
-
marginTop: -6,
|
|
183
|
-
marginRight: 24,
|
|
184
|
-
marginLeft: 72,
|
|
185
|
-
marginBottom: 10,
|
|
186
|
-
},
|
|
187
|
-
collapseContainer: {
|
|
188
|
-
height: 0,
|
|
189
|
-
overflow: 'hidden',
|
|
190
|
-
},
|
|
191
|
-
stationName: {
|
|
192
|
-
fontSize: 14,
|
|
193
|
-
lineHeight: 22,
|
|
194
|
-
paddingLeft: 16,
|
|
195
|
-
marginBottom: 8,
|
|
196
|
-
},
|
|
197
|
-
textEmpty: {
|
|
198
|
-
flex: 1,
|
|
199
|
-
textAlign: 'center',
|
|
200
|
-
marginTop: 16,
|
|
201
|
-
},
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
export default StationDevicePermissions;
|
|
File without changes
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import React, { memo } from 'react';
|
|
2
|
-
import { View, Text } from 'react-native';
|
|
3
|
-
import { CheckBoxCustom } from '.';
|
|
4
|
-
import styles from './Styles/CheckBoxConfigStyles';
|
|
5
|
-
import t from '../../../hooks/Common/useTranslations';
|
|
6
|
-
import AccessibilityLabel from '../../../configs/AccessibilityLabel';
|
|
7
|
-
|
|
8
|
-
const CheckBoxConfig = ({
|
|
9
|
-
isChecked,
|
|
10
|
-
onPress,
|
|
11
|
-
title,
|
|
12
|
-
indexSubUnit,
|
|
13
|
-
indexEndDevice,
|
|
14
|
-
configId,
|
|
15
|
-
isControl,
|
|
16
|
-
isConfig,
|
|
17
|
-
item,
|
|
18
|
-
}) => {
|
|
19
|
-
const handleOnPress = () => {
|
|
20
|
-
onPress(indexSubUnit, indexEndDevice, configId, item, isConfig, !isChecked);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<View style={styles.wrap}>
|
|
25
|
-
<View style={styles.wrapRow}>
|
|
26
|
-
<CheckBoxCustom
|
|
27
|
-
isChecked={isChecked}
|
|
28
|
-
onPress={handleOnPress}
|
|
29
|
-
wrapStyle={styles.wrapCheckBoxStyle}
|
|
30
|
-
accessibilityLabel={`${AccessibilityLabel.SHARE_DEVICE.CHECK_BOX_CONFIG}-${configId}`}
|
|
31
|
-
/>
|
|
32
|
-
<Text onPress={handleOnPress} style={styles.titleStyle}>
|
|
33
|
-
{title}
|
|
34
|
-
</Text>
|
|
35
|
-
</View>
|
|
36
|
-
<View>
|
|
37
|
-
{isControl && <Text>{t('can_control')}</Text>}
|
|
38
|
-
{isConfig && <Text>{t('view_only')}</Text>}
|
|
39
|
-
</View>
|
|
40
|
-
</View>
|
|
41
|
-
);
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export default memo(CheckBoxConfig);
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import React, { memo, useEffect, useState } from 'react';
|
|
2
|
-
import { View, Text } from 'react-native';
|
|
3
|
-
import { CheckBoxCustom } from '.';
|
|
4
|
-
import styles from './Styles/TitleCheckBoxStyles';
|
|
5
|
-
import AccessibilityLabel from '../../../configs/AccessibilityLabel';
|
|
6
|
-
|
|
7
|
-
const CheckBoxSubUnit = ({ isChecked, onPress, title, indexSubUnit }) => {
|
|
8
|
-
const [checked, setChecked] = useState(isChecked);
|
|
9
|
-
const handleOnPress = () => {
|
|
10
|
-
setChecked(!checked);
|
|
11
|
-
onPress(indexSubUnit, !checked);
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
if (isChecked !== checked) {
|
|
16
|
-
setChecked(isChecked);
|
|
17
|
-
}
|
|
18
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
19
|
-
}, [isChecked]);
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<View style={styles.wrap}>
|
|
23
|
-
<View style={styles.wrapRow}>
|
|
24
|
-
<CheckBoxCustom
|
|
25
|
-
isChecked={checked}
|
|
26
|
-
onPress={handleOnPress}
|
|
27
|
-
accessibilityLabel={`${AccessibilityLabel.SHARE_DEVICE.CHECK_BOX_CUSTOM}-${indexSubUnit}`}
|
|
28
|
-
/>
|
|
29
|
-
<Text onPress={handleOnPress}>{title}</Text>
|
|
30
|
-
</View>
|
|
31
|
-
</View>
|
|
32
|
-
);
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export default memo(CheckBoxSubUnit);
|