@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.
- package/package.json +1 -1
- package/src/commons/Action/ItemQuickAction.js +2 -4
- package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +4 -7
- package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +1 -1
- package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +4 -4
- package/src/commons/ActionGroup/StatesGridActionTemplate.js +1 -1
- package/src/commons/ActionGroup/__test__/NumberUpDownTemplate.test.js +4 -1
- package/src/commons/ActionGroup/__test__/OptionsDropdownTemplate.test.js +1 -1
- package/src/commons/Dashboard/MyUnit/index.js +8 -6
- package/src/commons/Device/HorizontalBarChart.js +3 -0
- package/src/commons/IconComponent/index.js +3 -7
- package/src/commons/Modal/ModalCustom.js +2 -2
- package/src/configs/API.js +1 -0
- package/src/screens/AddNewGateway/ConnectingWifiDevice.js +5 -4
- package/src/screens/AddNewGateway/ConnectingWifiGuide.js +47 -12
- package/src/screens/AddNewGateway/RenameNewDevices.js +126 -10
- package/src/screens/AddNewGateway/RenameNewDevicesStyles.js +26 -5
- package/src/screens/AddNewGateway/ShareWifiPassword.js +39 -7
- package/src/screens/AddNewGateway/__test__/ConnectingWifiDevice.test.js +36 -7
- package/src/screens/AddNewGateway/__test__/ConnectingWifiGuide.test.js +41 -32
- package/src/screens/AddNewGateway/__test__/RenameNewDevices.test.js +106 -2
- package/src/screens/AddNewGateway/__test__/ShareWifiPassword.test.js +35 -2
- package/src/screens/Device/__test__/detail.test.js +67 -8
- package/src/screens/Device/detail.js +17 -27
- package/src/screens/Sharing/Components/CheckBoxCustom.js +14 -2
- package/src/screens/Sharing/InfoMemberUnit.js +3 -1
- package/src/screens/Sharing/__test__/InfoMemberUnit.test.js +2 -0
- package/src/screens/SmartAccount/Connecting/index.js +0 -1
- package/src/screens/SmartAccount/__test__/Connecting.test.js +92 -0
- package/src/utils/I18n/translations/en.js +19 -5
- package/src/utils/I18n/translations/vi.js +19 -5
package/package.json
CHANGED
|
@@ -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 =
|
|
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
|
-
|
|
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 (
|
|
54
|
-
data =
|
|
55
|
-
|
|
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) {
|
|
@@ -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, [
|
|
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}
|
|
@@ -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
|
-
|
|
193
|
-
|
|
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
|
-
}, [
|
|
195
|
+
}, [
|
|
196
|
+
isDeleteUnitSuccessFully,
|
|
197
|
+
setAction,
|
|
198
|
+
previousMyUnits?.length,
|
|
199
|
+
myUnits?.length,
|
|
200
|
+
]);
|
|
199
201
|
|
|
200
202
|
return (
|
|
201
203
|
<>
|
|
@@ -8,14 +8,13 @@ import FImage from '../FImage';
|
|
|
8
8
|
const IconComponent = memo(
|
|
9
9
|
({
|
|
10
10
|
icon,
|
|
11
|
-
|
|
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
|
-
|
|
53
|
-
|
|
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={
|
|
20
|
-
animationOutTiming={
|
|
19
|
+
animationInTiming={400}
|
|
20
|
+
animationOutTiming={400}
|
|
21
21
|
backdropColor={Colors.BlackTransparent5}
|
|
22
22
|
hideModalContentWhileAnimating
|
|
23
23
|
{...props}
|
package/src/configs/API.js
CHANGED
|
@@ -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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
}, [
|
|
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
|
-
}, [
|
|
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
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
-
}, [
|
|
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
|
-
|
|
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
|
-
{
|
|
277
|
-
|
|
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:
|
|
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;
|