@eohjsc/react-native-smart-city 0.4.48 → 0.4.50

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 (31) hide show
  1. package/package.json +1 -1
  2. package/src/commons/Action/ItemQuickAction.js +2 -4
  3. package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +4 -7
  4. package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +1 -1
  5. package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +4 -4
  6. package/src/commons/ActionGroup/StatesGridActionTemplate.js +1 -1
  7. package/src/commons/ActionGroup/__test__/NumberUpDownTemplate.test.js +4 -1
  8. package/src/commons/ActionGroup/__test__/OptionsDropdownTemplate.test.js +1 -1
  9. package/src/commons/Dashboard/MyUnit/index.js +8 -6
  10. package/src/commons/Device/HorizontalBarChart.js +3 -0
  11. package/src/commons/IconComponent/index.js +3 -7
  12. package/src/commons/Modal/ModalCustom.js +2 -2
  13. package/src/configs/API.js +1 -0
  14. package/src/screens/AddNewGateway/ConnectingWifiDevice.js +5 -4
  15. package/src/screens/AddNewGateway/ConnectingWifiGuide.js +47 -12
  16. package/src/screens/AddNewGateway/RenameNewDevices.js +126 -10
  17. package/src/screens/AddNewGateway/RenameNewDevicesStyles.js +26 -5
  18. package/src/screens/AddNewGateway/ShareWifiPassword.js +39 -7
  19. package/src/screens/AddNewGateway/__test__/ConnectingWifiDevice.test.js +36 -7
  20. package/src/screens/AddNewGateway/__test__/ConnectingWifiGuide.test.js +41 -32
  21. package/src/screens/AddNewGateway/__test__/RenameNewDevices.test.js +106 -2
  22. package/src/screens/AddNewGateway/__test__/ShareWifiPassword.test.js +35 -2
  23. package/src/screens/Device/__test__/detail.test.js +67 -8
  24. package/src/screens/Device/detail.js +17 -27
  25. package/src/screens/Sharing/Components/CheckBoxCustom.js +14 -2
  26. package/src/screens/Sharing/InfoMemberUnit.js +3 -1
  27. package/src/screens/Sharing/__test__/InfoMemberUnit.test.js +2 -0
  28. package/src/screens/SmartAccount/Connecting/index.js +0 -1
  29. package/src/screens/SmartAccount/__test__/Connecting.test.js +92 -0
  30. package/src/utils/I18n/translations/en.js +19 -5
  31. package/src/utils/I18n/translations/vi.js +19 -5
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@eohjsc/react-native-smart-city",
3
3
  "title": "React Native Smart Home",
4
- "version": "0.4.48",
4
+ "version": "0.4.50",
5
5
  "description": "TODO",
6
6
  "main": "index.js",
7
7
  "files": [
@@ -7,8 +7,7 @@ import { useConfigGlobalState } from '../../iot/states';
7
7
  import IconComponent from '../IconComponent';
8
8
 
9
9
  const ItemQuickAction = memo(
10
- ({ sensor, wrapperStyle, setStatus, iconSize = 40 }) => {
11
- const [isSendingCommand, setIsSendingCommand] = useState(false);
10
+ ({ sensor, wrapperStyle, setStatus, iconSize = 30 }) => {
12
11
  const [action, setAction] = useState(sensor.action);
13
12
  // eslint-disable-next-line no-unused-vars
14
13
  const [configValues, _] = useConfigGlobalState('configValues');
@@ -64,7 +63,6 @@ const ItemQuickAction = memo(
64
63
  data = JSON.stringify(data);
65
64
  }
66
65
  await sendRemoteCommand(sensor, action, data, userId);
67
- setIsSendingCommand(true);
68
66
 
69
67
  if (!sensor.quick_action.will_auto_update_status) {
70
68
  setTimeout(() => {
@@ -86,7 +84,7 @@ const ItemQuickAction = memo(
86
84
  <View style={wrapperStyle}>
87
85
  <IconComponent
88
86
  icon={action?.icon_kit || action?.icon || 'PoweroffOutlined'}
89
- isSendingCommand={isSendingCommand}
87
+ isOn={isOn}
90
88
  iconSize={iconSize}
91
89
  size={iconSize}
92
90
  />
@@ -49,13 +49,10 @@ const NumberUpDownActionTemplate = ({
49
49
 
50
50
  const doActionAndWatchConfig = useCallback(
51
51
  async (actionData, actionValue) => {
52
- let data = actionValue;
53
- if (device_type !== DEVICE_TYPE.GOOGLE_HOME) {
54
- data = { temperature: actionValue };
55
- if (allow_config_store_value && config) {
56
- data.config_id = config;
57
- data.config_value = actionValue;
58
- }
52
+ let data = { value: actionValue, temperature: actionValue };
53
+ if (allow_config_store_value && config) {
54
+ data.config_id = config;
55
+ data.config_value = actionValue;
59
56
  }
60
57
  await doAction(actionData, data);
61
58
  if (!is_managed_by_backend) {
@@ -36,7 +36,7 @@ const OnOffButtonTemplate = memo(
36
36
  <IconComponent
37
37
  icon={icon}
38
38
  iconSize={30}
39
- active={isOn}
39
+ isOn={isOn}
40
40
  colorInActive={Colors.Gray6}
41
41
  color={Colors.Green7}
42
42
  />
@@ -28,15 +28,16 @@ const OptionsDropdownActionTemplate = ({
28
28
  isWidgetOrder,
29
29
  }) => {
30
30
  const t = useTranslations();
31
- const { configuration = {}, title = '' } = item;
32
31
  const {
32
+ title,
33
33
  action_data,
34
34
  options = [],
35
35
  icon_kit_data,
36
36
  icon,
37
37
  config,
38
38
  allow_config_store_value,
39
- } = configuration;
39
+ } = item?.configuration || {};
40
+
40
41
  // eslint-disable-next-line no-unused-vars
41
42
  const [configValues, setConfigValues] = useConfigGlobalState('configValues');
42
43
  const checkIcon = /\d/.test(icon); // to do check icon svg and icon antDesign
@@ -96,7 +97,7 @@ const OptionsDropdownActionTemplate = ({
96
97
  hideAlertAction,
97
98
  ]);
98
99
 
99
- useUnwatchLGDeviceConfigControl(sensor, [configuration.config]);
100
+ useUnwatchLGDeviceConfigControl(sensor, [config]);
100
101
 
101
102
  const iconKit = !!icon_kit_data && icon_kit_data.icon;
102
103
 
@@ -117,7 +118,6 @@ const OptionsDropdownActionTemplate = ({
117
118
  {!checkIcon && (
118
119
  <IconComponent
119
120
  icon={iconKit || icon}
120
- isSendingCommand={false}
121
121
  iconSize={27}
122
122
  size={27}
123
123
  style={styles.marginRight}
@@ -79,7 +79,7 @@ const GridItem = ({ item, doAction, sensor }) => {
79
79
  {!checkIcon && (
80
80
  <IconComponent
81
81
  icon={iconKit || icon}
82
- active={active}
82
+ isOn={active}
83
83
  color={Colors.White}
84
84
  style={styles.iconComponent}
85
85
  />
@@ -400,7 +400,10 @@ describe('Test NumberUpDownTemplate', () => {
400
400
  id: 20,
401
401
  key: '5ed1d4dc-a905-47cd-b0c9-f979644bd21a',
402
402
  },
403
- 26
403
+ {
404
+ value: 26,
405
+ temperature: 26,
406
+ }
404
407
  );
405
408
  });
406
409
 
@@ -56,8 +56,8 @@ describe('Test OptionsDropdownActionTemplate', () => {
56
56
  beforeEach(() => {
57
57
  watchMultiConfigs.mockClear();
58
58
  displayItem = {
59
- title: 'Fan Speed',
60
59
  configuration: {
60
+ title: 'Fan Speed',
61
61
  action_data: actionData,
62
62
  config: 5,
63
63
  action: 'e5d23347-ee31-4fe3-9fb5-bbce05bf4b61',
@@ -189,13 +189,15 @@ const MyUnit = ({ refreshing }) => {
189
189
 
190
190
  useEffect(() => {
191
191
  if (isDeleteUnitSuccessFully || previousMyUnits?.length > myUnits?.length) {
192
- const to = setTimeout(() => {
193
- carouselRef?.current?.snapToItem();
194
- setAction(Action.RESET_DELETE_UNIT_ACTION);
195
- }, 60);
196
- return () => clearTimeout(to);
192
+ carouselRef?.current?.snapToItem(0, true);
193
+ setAction(Action.RESET_DELETE_UNIT_ACTION);
197
194
  }
198
- }, [isDeleteUnitSuccessFully, setAction, previousMyUnits, myUnits]);
195
+ }, [
196
+ isDeleteUnitSuccessFully,
197
+ setAction,
198
+ previousMyUnits?.length,
199
+ myUnits?.length,
200
+ ]);
199
201
 
200
202
  return (
201
203
  <>
@@ -49,6 +49,9 @@ const HorizontalBarChart = memo(({ datas, config }) => {
49
49
  enabled: false,
50
50
  followTouchMove: false,
51
51
  },
52
+ exporting: {
53
+ enabled: false,
54
+ },
52
55
  plotOptions: {
53
56
  bar: {
54
57
  dataLabels: {
@@ -8,14 +8,13 @@ import FImage from '../FImage';
8
8
  const IconComponent = memo(
9
9
  ({
10
10
  icon,
11
- isSendingCommand = false,
11
+ isOn = false,
12
12
  size = 30,
13
13
  iconSize = 30,
14
14
  style,
15
15
  antIconStyle,
16
16
  color,
17
17
  colorInActive,
18
- active,
19
18
  }) => {
20
19
  let extraStyle = {
21
20
  width: size,
@@ -49,11 +48,8 @@ const IconComponent = memo(
49
48
  }, [icon]);
50
49
 
51
50
  const colorIcon = useMemo(() => {
52
- if (isSendingCommand || !active) {
53
- return colorInActive || Colors.TextGray;
54
- }
55
- return color || Colors.Green7;
56
- }, [active, color, colorInActive, isSendingCommand]);
51
+ return isOn ? color || Colors.Green7 : colorInActive || Colors.TextGray;
52
+ }, [color, colorInActive, isOn]);
57
53
 
58
54
  if (!icon) {
59
55
  return null;
@@ -16,8 +16,8 @@ const ModalCustom = (props) => {
16
16
  useNativeDriver
17
17
  animationIn={'slideInUp'}
18
18
  animationOut={'slideOutDown'}
19
- animationInTiming={500}
20
- animationOutTiming={500}
19
+ animationInTiming={400}
20
+ animationOutTiming={400}
21
21
  backdropColor={Colors.BlackTransparent5}
22
22
  hideModalContentWhileAnimating
23
23
  {...props}
@@ -76,6 +76,7 @@ const API = {
76
76
  END_DEVICE_DETAIL: (id) => `/property_manager/devices/${id}/`,
77
77
  ORDER_DISPLAY_ITEMS: (id) =>
78
78
  `/property_manager/devices/${id}/display/order_display_items/`,
79
+ DELETE_END_DEVICES: () => '/chip_manager/end_devices/delete_end_devices/',
79
80
  },
80
81
  SHARED_SENSOR: {
81
82
  ACCESS: (id) => `/property_manager/shared_sensors/${id}/access/`,
@@ -50,10 +50,10 @@ const ConnectingWifiDevice = ({ route }) => {
50
50
  channel_name: channelName,
51
51
  }
52
52
  );
53
- if (!success) {
54
- addingWifiDeviceFail(JSON.stringify(problem || data));
55
- } else {
53
+ if (success) {
56
54
  setChipId(data.id);
55
+ } else {
56
+ addingWifiDeviceFail(JSON.stringify(problem || data));
57
57
  }
58
58
  clearTimeout(timeout);
59
59
  isCallingAPI = false;
@@ -75,7 +75,8 @@ const ConnectingWifiDevice = ({ route }) => {
75
75
 
76
76
  useEffect(() => {
77
77
  const unsubscribe = NetInfo.addEventListener((state) => {
78
- if (state.isConnected) {
78
+ const { isConnected, isInternetReachable } = state || {};
79
+ if (isConnected && isInternetReachable) {
79
80
  channelName && onReady(channelName);
80
81
  }
81
82
  });
@@ -7,7 +7,6 @@ import LottieView from 'lottie-react-native';
7
7
  import WifiManager from 'react-native-wifi-reborn';
8
8
 
9
9
  import { useTranslations } from '../../hooks/Common/useTranslations';
10
- import { ToastBottomHelper } from '../../utils/Utils';
11
10
  import { HeaderCustom } from '../../commons/Header';
12
11
  import Text from '../../commons/Text';
13
12
  import Routes from '../../utils/Route';
@@ -40,6 +39,7 @@ const ConnectingWifiGuide = ({ route }) => {
40
39
  const [currentState, setCurrentState] = useState(0);
41
40
  const [isDisabled, setIsDisabled] = useState(false);
42
41
  const [isPressButton, setIsPressButton] = useState(false);
42
+ const [wifiDevice, setWifiDevice] = useState();
43
43
 
44
44
  const buttons = useMemo(
45
45
  () => [
@@ -74,9 +74,10 @@ const ConnectingWifiGuide = ({ route }) => {
74
74
  }
75
75
  setIsDisabled(false);
76
76
  setCurrentState(1);
77
+ setWifiDevice(wifiSsid);
77
78
  } catch (e) {
78
79
  Alert.alert(
79
- t('cannot_connect_to_device_wifi'),
80
+ t('cannot_connect_to_device_wifi', { wifiDevice: wifiSsid }),
80
81
  t('try_to_turn_on_device_or_try_again'),
81
82
  buttons
82
83
  );
@@ -105,7 +106,7 @@ const ConnectingWifiGuide = ({ route }) => {
105
106
  if (!wifi) {
106
107
  phoneWifiList = null;
107
108
  Alert.alert(
108
- t('cannot_find_device_wifi'),
109
+ t('cannot_find_device_wifi', { wifiDevice: wifiPrefix }),
109
110
  t('try_to_turn_on_device_or_try_again'),
110
111
  buttons
111
112
  );
@@ -132,7 +133,13 @@ const ConnectingWifiGuide = ({ route }) => {
132
133
  });
133
134
 
134
135
  socket.on('error', () => {
135
- ToastBottomHelper.error(t('fail_trigger_scan_wifi_on_device'));
136
+ socket?.close(); // Close here to stop receiving error events
137
+ socket = null;
138
+ Alert.alert(
139
+ t('fail_trigger_scan_wifi_on_device', { wifiDevice }),
140
+ t('try_to_turn_on_device_or_try_again'),
141
+ buttons
142
+ );
136
143
  });
137
144
 
138
145
  intervalSend = setInterval(() => {
@@ -148,11 +155,19 @@ const ConnectingWifiGuide = ({ route }) => {
148
155
  // eslint-disable-next-line no-empty
149
156
  } catch (error) {}
150
157
  setIsPressButton(false);
151
- }, [buttons, connectWifiSsid, qrData?.org_slug, qrData?.prefix, t]);
158
+ }, [
159
+ buttons,
160
+ connectWifiSsid,
161
+ qrData?.org_slug,
162
+ qrData?.prefix,
163
+ t,
164
+ wifiDevice,
165
+ ]);
152
166
 
153
167
  useEffect(() => {
154
168
  if (isFocused) {
155
169
  if (isBackFromOtherScreen) {
170
+ setCurrentState(0);
156
171
  const currentConnectingWifi = getCurrentWifiSSID();
157
172
  disconnectWifi(currentConnectingWifi);
158
173
  }
@@ -179,9 +194,21 @@ const ConnectingWifiGuide = ({ route }) => {
179
194
  qrData: qrData,
180
195
  addDeviceType,
181
196
  stationId,
197
+ wifiDevice: wifiDevice,
198
+ reconnectWifiSSID: connectWifiSsid,
182
199
  });
183
200
  }
184
- }, [addDeviceType, navigate, qrData, stationId, subUnit, unit, wifiList]);
201
+ }, [
202
+ addDeviceType,
203
+ connectWifiSsid,
204
+ navigate,
205
+ qrData,
206
+ stationId,
207
+ subUnit,
208
+ unit,
209
+ wifiDevice,
210
+ wifiList,
211
+ ]);
185
212
 
186
213
  return (
187
214
  <View style={styles.container}>
@@ -211,12 +238,20 @@ const ConnectingWifiGuide = ({ route }) => {
211
238
  />
212
239
  </>
213
240
  ) : (
214
- <LottieView
215
- source={LoadingCircle}
216
- autoPlay
217
- loop
218
- style={styles.loading}
219
- />
241
+ <>
242
+ <LottieView
243
+ source={LoadingCircle}
244
+ autoPlay
245
+ loop
246
+ style={styles.loading}
247
+ />
248
+ <Text style={styles.txtContent}>
249
+ {t('connecting_to_wifi_device', {
250
+ appName: SCConfig.appName,
251
+ wifiDevice: wifiDevice,
252
+ })}
253
+ </Text>
254
+ </>
220
255
  )}
221
256
  </View>
222
257
  {isDisabled && isPressButton && (
@@ -16,6 +16,7 @@ import { HeaderCustom } from '../../commons/Header';
16
16
  import IconComponent from '../../commons/IconComponent';
17
17
  import FullLoading from '../../commons/FullLoading';
18
18
  import { ToastBottomHelper } from '../../utils/Utils';
19
+ import { CheckBoxCustom } from '../Sharing/Components';
19
20
 
20
21
  const RenameNewDevices = memo(({ route }) => {
21
22
  const t = useTranslations();
@@ -29,6 +30,9 @@ const RenameNewDevices = memo(({ route }) => {
29
30
  const [loading, setLoading] = useState(false);
30
31
  const [isChangedName, setIsChangedName] = useState(false);
31
32
  const [isDisabled, setIsDisabled] = useState(false);
33
+ const [selectedDevice, setSelectedDevice] = useState([]);
34
+ const [originalDevices, setOriginalDevices] = useState([]);
35
+ const [isAutoFocus, setIsAutoFocus] = useState(true);
32
36
 
33
37
  const renameLabel = AccessibilityLabel.CONNECTED_DEVICE_RENAME_DEVICE;
34
38
 
@@ -94,14 +98,60 @@ const RenameNewDevices = memo(({ route }) => {
94
98
  return;
95
99
  }
96
100
  setLoading(true);
97
- const { success } = await axiosPost(API.CHIP.RENAME_DEVICES(info.id), info);
98
- if (success) {
99
- goBackUnitDetail();
101
+
102
+ let filteredInfo;
103
+ let devicesToDelete;
104
+ if (selectedDevice.length === 0) {
105
+ filteredInfo = info;
106
+ devicesToDelete = [];
100
107
  } else {
108
+ filteredInfo = {
109
+ ...info,
110
+ sensors: info.sensors.map((sensor) => ({
111
+ ...sensor,
112
+ end_devices: sensor.end_devices.filter((device) =>
113
+ selectedDevice.includes(device.id)
114
+ ),
115
+ })),
116
+ };
117
+
118
+ devicesToDelete = originalDevices.filter(
119
+ (device) => !selectedDevice.includes(device)
120
+ );
121
+ }
122
+
123
+ let response, success1, success2;
124
+ response = await axiosPost(
125
+ API.CHIP.RENAME_DEVICES(filteredInfo.id),
126
+ filteredInfo
127
+ );
128
+ success1 = response.success;
129
+
130
+ if (devicesToDelete?.length > 0) {
131
+ response = await axiosPost(API.DEVICE.DELETE_END_DEVICES(), {
132
+ list_device: devicesToDelete,
133
+ });
134
+ success2 = response.success;
135
+ }
136
+
137
+ if (success1 || success2) {
138
+ goBackUnitDetail();
139
+ }
140
+ if (!success1) {
101
141
  ToastBottomHelper.error(t('rename_device_fail'));
102
142
  }
143
+ if (!success2) {
144
+ ToastBottomHelper.error(t('select_device_failed'));
145
+ }
103
146
  setLoading(false);
104
- }, [goBackUnitDetail, info, isChangedName, t]);
147
+ }, [
148
+ goBackUnitDetail,
149
+ info,
150
+ isChangedName,
151
+ originalDevices,
152
+ selectedDevice,
153
+ t,
154
+ ]);
105
155
 
106
156
  useEffect(() => {
107
157
  (async () => {
@@ -117,6 +167,11 @@ const RenameNewDevices = memo(({ route }) => {
117
167
  );
118
168
  if (success) {
119
169
  setInfo(data);
170
+ const listIdDevice = data?.sensors?.flatMap((sensor) =>
171
+ sensor?.end_devices?.map((device) => device?.id)
172
+ );
173
+ setSelectedDevice(listIdDevice || []);
174
+ setOriginalDevices(listIdDevice || []);
120
175
  }
121
176
  })();
122
177
  }, [chipId, sensorId, subUnit]);
@@ -140,6 +195,32 @@ const RenameNewDevices = memo(({ route }) => {
140
195
  });
141
196
  };
142
197
 
198
+ const handleSetSelectedDevice = useCallback(
199
+ (value) => () => {
200
+ setIsAutoFocus(false);
201
+ const index = selectedDevice.indexOf(value);
202
+ if (index !== -1) {
203
+ setSelectedDevice([
204
+ ...selectedDevice.slice(0, index),
205
+ ...selectedDevice.slice(index + 1),
206
+ ]);
207
+ } else {
208
+ setSelectedDevice((oldArray) => [...oldArray, value]);
209
+ }
210
+ },
211
+ [selectedDevice]
212
+ );
213
+
214
+ const onSetSelectAllDevice = () => {
215
+ setIsAutoFocus(false);
216
+ if (selectedDevice?.length >= 0) {
217
+ setSelectedDevice([...originalDevices]);
218
+ }
219
+ if (selectedDevice?.length === originalDevices?.length) {
220
+ setSelectedDevice([]);
221
+ }
222
+ };
223
+
143
224
  const ItemDevice = useCallback(
144
225
  ({
145
226
  item,
@@ -149,16 +230,25 @@ const RenameNewDevices = memo(({ route }) => {
149
230
  accessibilityLabelTextInput,
150
231
  onChange,
151
232
  onSubmitEditing,
233
+ isSelected,
234
+ onSetSelectedDevice,
152
235
  }) => {
153
236
  const isCanRenameItem = isGateway
154
237
  ? item?.can_rename && isCanRename
155
238
  : isFocus;
239
+
156
240
  return (
157
241
  <TouchableOpacity
158
242
  style={[styles.boxDevice, isGateway && styles.marginTop16]}
159
243
  accessibilityLabel={`${renameLabel}-button-${item?.id}`}
160
244
  onPress={onPress}
161
245
  >
246
+ <CheckBoxCustom
247
+ isChecked={isSelected}
248
+ onPress={onSetSelectedDevice}
249
+ wrapStyle={styles.checkBox}
250
+ wrapViewCustom={styles.wrapViewCustom}
251
+ />
162
252
  {isGateway ? (
163
253
  <GatewayIcon width={43} height={43} />
164
254
  ) : (
@@ -198,6 +288,7 @@ const RenameNewDevices = memo(({ route }) => {
198
288
 
199
289
  const handleOnPressDeviceItem = useCallback(
200
290
  (item) => () => {
291
+ setIsAutoFocus(true);
201
292
  setSelectedItem(item);
202
293
  },
203
294
  []
@@ -229,13 +320,15 @@ const RenameNewDevices = memo(({ route }) => {
229
320
  key={`${end_device?.id}`}
230
321
  item={end_device}
231
322
  onPress={handleOnPressDeviceItem(end_device)}
232
- isFocus={end_device?.id === selectedItem?.id}
323
+ isFocus={isAutoFocus && end_device?.id === selectedItem?.id}
233
324
  accessibilityLabelTextInput={`${renameLabel}-end_device-${end_device?.id}`}
234
325
  onChange={updateItemName(
235
326
  'end_device',
236
327
  sensor_index,
237
328
  end_device_index
238
329
  )}
330
+ isSelected={selectedDevice.includes(end_device?.id)}
331
+ onSetSelectedDevice={handleSetSelectedDevice(end_device?.id)}
239
332
  />
240
333
  ))
241
334
  )}
@@ -245,11 +338,14 @@ const RenameNewDevices = memo(({ route }) => {
245
338
  }, [
246
339
  addDeviceType,
247
340
  scrollViewHeight,
341
+ renameLabel,
248
342
  info,
249
343
  handleOnPressGatewayItem,
250
- renameLabel,
251
344
  handleOnPressDeviceItem,
252
- selectedItem,
345
+ isAutoFocus,
346
+ selectedItem?.id,
347
+ selectedDevice,
348
+ handleSetSelectedDevice,
253
349
  ]);
254
350
 
255
351
  return (
@@ -273,10 +369,30 @@ const RenameNewDevices = memo(({ route }) => {
273
369
  <Text size={14} color={Colors.Gray9}>
274
370
  {[unit?.name, subUnit?.name].filter(Boolean).join(' - ')}
275
371
  </Text>
276
- {renderListItem}
277
- <Text size={16} color={Colors.Gray8} style={styles.textRename}>
278
- {t('click_on_box_to_rename_device')}
372
+ <Text size={14} color={Colors.Gray7} style={styles.textClickBox}>
373
+ {t('click_on_the_box_to_rename')}
279
374
  </Text>
375
+ {originalDevices?.length > 0 && (
376
+ <View style={styles.wrapHeaderDeviceAdd}>
377
+ <View style={styles.wrapCheckBox}>
378
+ <CheckBoxCustom
379
+ isChecked={selectedDevice?.length === originalDevices?.length}
380
+ onPress={onSetSelectAllDevice}
381
+ wrapStyle={styles.checkBoxSelectAll}
382
+ wrapViewCustom={styles.wrapViewCustom}
383
+ />
384
+ <Text size={12} color={Colors.Gray9}>
385
+ {t('select_all')}
386
+ </Text>
387
+ </View>
388
+ <Text size={12} color={Colors.Gray9}>
389
+ {`${selectedDevice?.length} / ${originalDevices?.length} ${t(
390
+ 'end_devices_added'
391
+ )}`}
392
+ </Text>
393
+ </View>
394
+ )}
395
+ {renderListItem}
280
396
  </View>
281
397
  </View>
282
398
  {loading && <FullLoading />}
@@ -1,5 +1,6 @@
1
1
  import { StyleSheet } from 'react-native';
2
2
  import { Colors } from '../../configs';
3
+ import { normalize } from '../../configs/Constants';
3
4
 
4
5
  const styles = StyleSheet.create({
5
6
  container: {
@@ -56,9 +57,6 @@ const styles = StyleSheet.create({
56
57
  textAlign: 'left',
57
58
  paddingLeft: 16,
58
59
  },
59
- textRename: {
60
- marginTop: 16,
61
- },
62
60
  devicesWrapper: {
63
61
  marginTop: 16,
64
62
  paddingHorizontal: 16,
@@ -70,10 +68,9 @@ const styles = StyleSheet.create({
70
68
  marginTop: 0,
71
69
  },
72
70
  viewIconSuccess: {
73
- flex: 1,
74
71
  alignItems: 'center',
75
72
  justifyContent: 'center',
76
- paddingTop: 32,
73
+ paddingTop: 100,
77
74
  },
78
75
  marginTop16: {
79
76
  marginTop: 16,
@@ -85,6 +82,30 @@ const styles = StyleSheet.create({
85
82
  alignItems: 'flex-start',
86
83
  justifyContent: 'flex-start',
87
84
  },
85
+ textClickBox: {
86
+ lineHeight: 24,
87
+ marginTop: 17,
88
+ marginBottom: 16,
89
+ paddingHorizontal: 60,
90
+ textAlign: 'center',
91
+ },
92
+ wrapHeaderDeviceAdd: {
93
+ width: 275,
94
+ flexDirection: 'row',
95
+ justifyContent: 'space-between',
96
+ alignItems: 'center',
97
+ },
98
+ wrapCheckBox: {
99
+ flexDirection: 'row',
100
+ justifyContent: 'center',
101
+ alignItems: 'center',
102
+ },
103
+ checkBoxSelectAll: {
104
+ marginLeft: 17,
105
+ },
106
+ wrapViewCustom: {
107
+ borderRadius: normalize(0),
108
+ },
88
109
  });
89
110
 
90
111
  export default styles;