@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.
Files changed (101) hide show
  1. package/package.json +1 -1
  2. package/src/Images/Common/default_end_device.png +0 -0
  3. package/src/commons/ActionGroup/TerminalBoxTemplate.js +3 -0
  4. package/src/commons/ActionTemplate/OnOffButtonAction.js +38 -4
  5. package/src/commons/ActionTemplate/OnOffSimpleAction.js +55 -15
  6. package/src/commons/ActionTemplate/OnOffSmartLockAction.js +46 -8
  7. package/src/commons/ActionTemplate/SwitchButtonAction.js +35 -4
  8. package/src/commons/ActionTemplate/ThreeButtonAction.js +13 -3
  9. package/src/commons/ActionTemplate/__test__/OnOffButtonAction.test.js +46 -7
  10. package/src/commons/ActionTemplate/__test__/OnOffSimpleAction.test.js +66 -6
  11. package/src/commons/ActionTemplate/__test__/OnOffSmartLockAction.test.js +53 -13
  12. package/src/commons/ActionTemplate/__test__/SwitchButtonAction.test.js +46 -7
  13. package/src/commons/ActionTemplate/__test__/index.test.js +6 -2
  14. package/src/commons/ActionTemplate/index.js +65 -10
  15. package/src/commons/Dashboard/MyUnit/index.js +19 -20
  16. package/src/commons/DevMode/Search.js +1 -1
  17. package/src/commons/Device/RainningSensor/CurrentRainSensor.js +5 -5
  18. package/src/commons/MediaPlayerDetail/MediaPlayerFull.js +26 -32
  19. package/src/commons/OneTapTemplate/StatesGridActionTemplate.js +8 -6
  20. package/src/commons/SubUnit/OneTap/__test__/SubUnitAutomate.test.js +6 -0
  21. package/src/commons/SubUnit/OneTap/index.js +5 -0
  22. package/src/commons/UnitSummary/ConfigHistoryChart/index.js +9 -11
  23. package/src/commons/Widgets/IFrameWithConfig/IFrameWithConfig.js +2 -2
  24. package/src/commons/Widgets/IFrameWithConfig/__tests__/IFrameWithConfig.test.js +1 -1
  25. package/src/configs/API.js +10 -0
  26. package/src/configs/AccessibilityLabel.js +5 -1
  27. package/src/configs/Images.js +1 -0
  28. package/src/navigations/AddMemberStack.js +3 -3
  29. package/src/screens/ActivityLog/__test__/index.test.js +10 -0
  30. package/src/screens/ActivityLog/hooks/index.js +1 -1
  31. package/src/screens/AddCommon/SelectUnit.js +3 -2
  32. package/src/screens/AddLocationMaps/__test__/index.test.js +13 -13
  33. package/src/screens/Automate/AddNewAction/ChooseAction.js +15 -51
  34. package/src/screens/Automate/AddNewAction/SelectControlDevices.js +13 -3
  35. package/src/screens/Automate/AddNewAction/SetupConfigCondition.js +74 -54
  36. package/src/screens/Automate/AddNewAction/__test__/ChooseAction.test.js +114 -4
  37. package/src/screens/Automate/AddNewAction/__test__/ChooseConfig.test.js +9 -11
  38. package/src/screens/Automate/AddNewAction/__test__/SetupConfigCondition.test.js +37 -8
  39. package/src/screens/Automate/AddNewAutoSmart/AddTypeSmart.js +5 -0
  40. package/src/screens/Automate/AddNewAutoSmart/__test__/AddAutomationTypeSmart.test.js +31 -0
  41. package/src/screens/Automate/AddNewAutoSmart/__test__/AddNewAutoSmart.test.js +18 -2
  42. package/src/screens/Automate/Components/InputName.js +7 -6
  43. package/src/screens/Automate/Constants.js +12 -0
  44. package/src/screens/Automate/EditActionsList/UpdateActionScript.js +24 -55
  45. package/src/screens/Automate/EditActionsList/__tests__/UpdateActionScript.test.js +298 -41
  46. package/src/screens/Automate/EditActionsList/__tests__/index.test.js +2 -2
  47. package/src/screens/Automate/EditActionsList/index.js +26 -14
  48. package/src/screens/Automate/MultiUnits.js +9 -1
  49. package/src/screens/Automate/OneTap/__test__/AddNewOneTap.test.js +3 -3
  50. package/src/screens/Automate/ScriptDetail/Components/AddActionScript.js +4 -10
  51. package/src/screens/Automate/ScriptDetail/Components/DeleteScript.js +2 -4
  52. package/src/screens/Automate/ScriptDetail/__test__/index.test.js +78 -0
  53. package/src/screens/Automate/ScriptDetail/index.js +16 -10
  54. package/src/screens/Automate/ScriptDetail/utils.js +39 -35
  55. package/src/screens/Automate/SetSchedule/AddEditConditionSchedule.js +27 -160
  56. package/src/screens/Automate/SetSchedule/EditSchedule.js +269 -0
  57. package/src/screens/Automate/SetSchedule/__test__/AddEditConditionSchedule.test.js +327 -22
  58. package/src/screens/Automate/SetSchedule/__test__/index.test.js +35 -22
  59. package/src/screens/Automate/SetSchedule/components/RepeatOptionsPopup.js +2 -8
  60. package/src/screens/Automate/SetSchedule/index.js +15 -129
  61. package/src/screens/Automate/SetSchedule/styles/indexStyles.js +9 -0
  62. package/src/screens/Automate/__test__/MultiUnits.test.js +6 -1
  63. package/src/screens/Automate/hooks/useAction.js +222 -0
  64. package/src/screens/ConfirmUnitDeletion/__test__/ConfirmUnitDeletion.test.js +69 -13
  65. package/src/screens/ConfirmUnitDeletion/index.js +14 -14
  66. package/src/screens/Device/__test__/detail.test.js +48 -1
  67. package/src/screens/Device/detail.js +46 -3
  68. package/src/screens/PlayBackCamera/__test__/index.test.js +48 -13
  69. package/src/screens/PlayBackCamera/index.js +1 -1
  70. package/src/screens/Sharing/Components/ConfigItem.js +34 -0
  71. package/src/screens/Sharing/Components/DeviceItem.js +77 -0
  72. package/src/screens/Sharing/Components/ItemChangeRole.js +3 -4
  73. package/src/screens/Sharing/Components/ShareDeviceSelector.js +255 -0
  74. package/src/screens/Sharing/Components/Styles/CheckBoxCustomStyles.js +1 -1
  75. package/src/screens/Sharing/Components/Styles/DeviceItemStyles.js +11 -27
  76. package/src/screens/Sharing/{Styles/SelectPermissionStyles.js → Components/Styles/ShareDeviceSelectorStyles.js} +3 -11
  77. package/src/screens/Sharing/Components/SubUnitItem.js +28 -0
  78. package/src/screens/Sharing/Components/SubUnitTreeView.js +68 -0
  79. package/src/screens/Sharing/Components/TitleCheckBox.js +23 -41
  80. package/src/screens/Sharing/Components/__test__/ItemChangeRole.test.js +7 -7
  81. package/src/screens/Sharing/Components/__test__/ShareDeviceSelector.test.js +298 -0
  82. package/src/screens/Sharing/Components/index.js +14 -1
  83. package/src/screens/Sharing/InfoMemberUnit.js +20 -20
  84. package/src/screens/Sharing/SelectShareDevice.js +11 -255
  85. package/src/screens/Sharing/SelectUser.js +12 -12
  86. package/src/screens/Sharing/UpdateShareDevice.js +45 -301
  87. package/src/screens/Sharing/__test__/InfoMemberUnit.test.js +58 -11
  88. package/src/screens/Sharing/__test__/SelectShareDevice.test.js +51 -160
  89. package/src/screens/Sharing/__test__/SelectUser.test.js +72 -10
  90. package/src/screens/Sharing/__test__/UpdateShareDevice.test.js +49 -209
  91. package/src/utils/Apis/axios.js +6 -0
  92. package/src/utils/I18n/translations/en.js +9 -1
  93. package/src/utils/I18n/translations/vi.js +10 -2
  94. package/src/commons/Sharing/StationDevicePermissions.js +0 -204
  95. package/src/screens/Automate/constants.js +0 -0
  96. package/src/screens/Sharing/Components/CheckBoxConfig.js +0 -44
  97. package/src/screens/Sharing/Components/CheckBoxSubUnit.js +0 -35
  98. package/src/screens/Sharing/Components/EndDevice.js +0 -93
  99. package/src/screens/Sharing/Components/Styles/CheckBoxConfigStyles.js +0 -18
  100. package/src/screens/Sharing/Components/Styles/TitleCheckBoxStyles.js +0 -21
  101. package/src/screens/Sharing/Components/__test__/TitleCheckBox.test.js +0 -31
@@ -1,15 +1,17 @@
1
- import { act } from '@testing-library/react-hooks';
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 { mockSCStore } from '../../../context/mockStore';
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: 2,
43
- actions: [{ id: 3, name: 'action 1' }],
44
- read_configs: [{ id: 4, name: 'config 1' }],
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: 5,
49
- actions: [{ id: 6, name: 'action 2' }],
50
- read_configs: [{ id: 7, name: 'config 2' }],
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 clickCheckBoxAllDevice = async (instance, statusCheckbox) => {
69
- const checkBoxAllDevice = instance.find(
63
+ const clickChooseDevice = async (instance, deviceId, status) => {
64
+ const chooseDevice = instance.find(
70
65
  (el) =>
71
66
  el.props.accessibilityLabel ===
72
- `${AccessibilityLabel.CHECK_BOX_CUSTOM}-undefined`
67
+ `${AccessibilityLabel.SHARE_DEVICE.NAME_END_DEVICE}-device-${deviceId}`
73
68
  );
74
- expect(checkBoxAllDevice.props.isChecked).toEqual(statusCheckbox);
75
69
  await act(async () => {
76
- await checkBoxAllDevice.props.onPress();
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
- `${AccessibilityLabel.CHECK_BOX_CUSTOM}-0`
75
+ `${AccessibilityLabel.SHARE_DEVICE.ICON_CHECK}-device-${deviceId}` &&
76
+ el.type === IconOutline
85
77
  );
86
- expect(checkBoxSubunit.props.isChecked).toEqual(statusCheckbox);
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.UNIT_PERMISSIONS(1)).reply(200, listDevices);
129
- mock.onGet(API.SHARE.UNIT_MEMBER_SHARE_DEVICE(1, 1)).reply(200, []);
130
- mock.onPost(API.SHARE.SHARE()).reply(200);
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 clickNameEndDevice(instance, 0); // click to select all configs in end device index 0
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 ViewButtonBottomElement = instance.findAllByType(ViewButtonBottom);
96
+ const viewButtonBottom = instance.findByType(ViewButtonBottom);
151
97
  await act(async () => {
152
- ViewButtonBottomElement[0].props.onRightClick();
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
- phone: '0901234567',
158
- email: '',
104
+ user_ids: [1],
159
105
  unit: 1,
160
106
  permissions: {
161
107
  read_permissions: [
162
- { id: 5, values: [7] },
163
- { id: 8, values: [] },
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 no data, api get UNIT_PERMISSIONS false', async () => {
236
- mock.onGet(API.SHARE.UNIT_PERMISSIONS(1)).reply(400);
237
-
238
- await act(async () => {
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
- let text = instance.findAll(
260
- (el) =>
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
  });
@@ -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 sensor.',
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 sẽ thiết bị',
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ẽ. Vui lòng liên hệ với chủ sở hữu',
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);