@eohjsc/react-native-smart-city 0.7.21 → 0.7.22

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 (48) hide show
  1. package/package.json +1 -1
  2. package/src/Images/Common/default_end_device.png +0 -0
  3. package/src/commons/Dashboard/MyUnit/index.js +19 -20
  4. package/src/commons/DevMode/Search.js +1 -1
  5. package/src/commons/Device/RainningSensor/CurrentRainSensor.js +5 -5
  6. package/src/commons/Widgets/IFrameWithConfig/IFrameWithConfig.js +1 -3
  7. package/src/commons/Widgets/IFrameWithConfig/__tests__/IFrameWithConfig.test.js +1 -1
  8. package/src/configs/API.js +4 -0
  9. package/src/configs/AccessibilityLabel.js +3 -1
  10. package/src/configs/Images.js +1 -0
  11. package/src/navigations/AddMemberStack.js +3 -3
  12. package/src/screens/AddCommon/SelectUnit.js +3 -2
  13. package/src/screens/AddLocationMaps/__test__/index.test.js +13 -13
  14. package/src/screens/Automate/AddNewAction/__test__/ChooseConfig.test.js +9 -11
  15. package/src/screens/Automate/AddNewAutoSmart/__test__/AddAutomationTypeSmart.test.js +31 -0
  16. package/src/screens/Automate/ScriptDetail/utils.js +0 -20
  17. package/src/screens/ConfirmUnitDeletion/__test__/ConfirmUnitDeletion.test.js +69 -13
  18. package/src/screens/ConfirmUnitDeletion/index.js +14 -14
  19. package/src/screens/Sharing/Components/ConfigItem.js +34 -0
  20. package/src/screens/Sharing/Components/DeviceItem.js +77 -0
  21. package/src/screens/Sharing/Components/ItemChangeRole.js +3 -4
  22. package/src/screens/Sharing/Components/ShareDeviceSelector.js +255 -0
  23. package/src/screens/Sharing/Components/Styles/CheckBoxCustomStyles.js +1 -1
  24. package/src/screens/Sharing/Components/Styles/DeviceItemStyles.js +11 -27
  25. package/src/screens/Sharing/{Styles/SelectPermissionStyles.js → Components/Styles/ShareDeviceSelectorStyles.js} +3 -11
  26. package/src/screens/Sharing/Components/SubUnitItem.js +28 -0
  27. package/src/screens/Sharing/Components/SubUnitTreeView.js +68 -0
  28. package/src/screens/Sharing/Components/TitleCheckBox.js +23 -41
  29. package/src/screens/Sharing/Components/__test__/ItemChangeRole.test.js +7 -7
  30. package/src/screens/Sharing/Components/__test__/ShareDeviceSelector.test.js +298 -0
  31. package/src/screens/Sharing/Components/index.js +14 -1
  32. package/src/screens/Sharing/InfoMemberUnit.js +20 -20
  33. package/src/screens/Sharing/SelectShareDevice.js +11 -255
  34. package/src/screens/Sharing/SelectUser.js +12 -12
  35. package/src/screens/Sharing/UpdateShareDevice.js +45 -301
  36. package/src/screens/Sharing/__test__/InfoMemberUnit.test.js +58 -11
  37. package/src/screens/Sharing/__test__/SelectShareDevice.test.js +51 -160
  38. package/src/screens/Sharing/__test__/SelectUser.test.js +72 -10
  39. package/src/screens/Sharing/__test__/UpdateShareDevice.test.js +49 -209
  40. package/src/utils/I18n/translations/en.js +1 -1
  41. package/src/utils/I18n/translations/vi.js +2 -2
  42. package/src/commons/Sharing/StationDevicePermissions.js +0 -204
  43. package/src/screens/Sharing/Components/CheckBoxConfig.js +0 -44
  44. package/src/screens/Sharing/Components/CheckBoxSubUnit.js +0 -35
  45. package/src/screens/Sharing/Components/EndDevice.js +0 -93
  46. package/src/screens/Sharing/Components/Styles/CheckBoxConfigStyles.js +0 -18
  47. package/src/screens/Sharing/Components/Styles/TitleCheckBoxStyles.js +0 -21
  48. package/src/screens/Sharing/Components/__test__/TitleCheckBox.test.js +0 -31
@@ -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:
@@ -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.',
@@ -1550,7 +1550,7 @@ export default {
1550
1550
  bellow_widget_is_not_configured: 'Tiện ích bên dưới chưa được cấu hình',
1551
1551
  bellow_widget_is_wrongly_configured: 'Tiện ích bên dưới được cấu hình sai',
1552
1552
  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',
1553
+ 'Tiện ích {widget} chưa được chia sẻ. Vui lòng liên hệ với chủ sở hữu',
1554
1554
  customize: 'Tùy chỉnh điều kiện',
1555
1555
  uri_invalid: 'URI không hợp lệ',
1556
1556
  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;
@@ -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);
@@ -1,93 +0,0 @@
1
- import React, { memo, useMemo, useState } from 'react';
2
- import { View, Text, TouchableOpacity } from 'react-native';
3
- import { IconOutline } from '@ant-design/icons-react-native';
4
- import { Colors } from '../../../configs';
5
- import styles from './Styles/DeviceItemStyles';
6
- import { AccessibilityLabel } from '../../../configs/Constants';
7
- import IconComponent from '../../../commons/IconComponent';
8
- import CheckBoxConfig from './CheckBoxConfig';
9
-
10
- const EndDevice = ({
11
- item,
12
- onTickedChild,
13
- onTickEndDevice,
14
- isItemExpanded,
15
- toggleExpandEndDevice,
16
- indexSubUnit,
17
- indexEndDevice,
18
- expandEndDevice,
19
- }) => {
20
- const { name, actions, read_configs, icon_kit, icon, isChecked } = item;
21
- const [checked, setChecked] = useState(isChecked);
22
-
23
- const dataConfig = useMemo(() => {
24
- return [
25
- ...actions.map((i) => ({ ...i, isControl: true })),
26
- ...read_configs.map((i) => ({ ...i, isConfig: true })),
27
- ];
28
- }, [actions, read_configs]);
29
-
30
- const onPressItem = () => {
31
- expandEndDevice();
32
- onTickEndDevice(indexSubUnit, indexEndDevice, item, !checked);
33
- setChecked(!checked);
34
- };
35
-
36
- const renderData = useMemo(() => {
37
- return dataConfig.map((i) => (
38
- <CheckBoxConfig
39
- key={i.id}
40
- item={item}
41
- title={i.name}
42
- configId={i.id}
43
- isConfig={i.isConfig}
44
- isControl={i.isControl}
45
- onPress={onTickedChild}
46
- isChecked={i.isChecked}
47
- indexSubUnit={indexSubUnit}
48
- indexEndDevice={indexEndDevice}
49
- />
50
- ));
51
- // eslint-disable-next-line react-hooks/exhaustive-deps
52
- }, [dataConfig]);
53
-
54
- return (
55
- <View style={styles.wrap}>
56
- <TouchableOpacity onPress={onPressItem}>
57
- <IconComponent
58
- icon={icon_kit || icon}
59
- size={20}
60
- style={styles.viewLeft}
61
- />
62
- </TouchableOpacity>
63
- <View style={styles.wrapRight}>
64
- <View style={styles.viewRight}>
65
- <Text
66
- numberOfLines={1}
67
- style={styles.text}
68
- onPress={onPressItem}
69
- accessibilityLabel={`${AccessibilityLabel.SHARE_DEVICE.CLICK_NAME_END_DEVICE}-${indexEndDevice}`}
70
- >
71
- {name}
72
- </Text>
73
- {checked && (
74
- <IconOutline name={'check'} color={Colors.Primary} size={20} />
75
- )}
76
-
77
- {dataConfig.length > 0 && (
78
- <IconOutline
79
- onPress={() => toggleExpandEndDevice()}
80
- name={isItemExpanded ? 'up' : 'down'}
81
- size={20}
82
- color={Colors.Gray6}
83
- accessibilityLabel={`${AccessibilityLabel.SHARE_DEVICE.EXPAND_END_DEVICE}-${indexEndDevice}`}
84
- />
85
- )}
86
- </View>
87
- {isItemExpanded && <View style={styles.wrapExpand}>{renderData}</View>}
88
- </View>
89
- </View>
90
- );
91
- };
92
-
93
- export default memo(EndDevice);
@@ -1,18 +0,0 @@
1
- import { StyleSheet } from 'react-native';
2
-
3
- export default StyleSheet.create({
4
- wrap: {
5
- flexDirection: 'row',
6
- alignItems: 'center',
7
- },
8
- wrapRow: {
9
- flexDirection: 'row',
10
- alignItems: 'center',
11
- },
12
- wrapCheckBoxStyle: {
13
- marginLeft: -10,
14
- },
15
- titleStyle: {
16
- width: 200,
17
- },
18
- });
@@ -1,21 +0,0 @@
1
- import { StyleSheet } from 'react-native';
2
- import { Colors } from '../../../../configs';
3
- import { normalize } from '../../../../configs/Constants';
4
-
5
- export default StyleSheet.create({
6
- wrap: {
7
- flexDirection: 'row',
8
- alignItems: 'center',
9
- },
10
- title: {
11
- color: Colors.Gray8,
12
- fontSize: normalize(14),
13
- lineHeight: normalize(22),
14
- fontWeight: '600',
15
- fontStyle: 'normal',
16
- },
17
- wrapRow: {
18
- flexDirection: 'row',
19
- alignItems: 'center',
20
- },
21
- });
@@ -1,31 +0,0 @@
1
- import React from 'react';
2
- import { create, act } from 'react-test-renderer';
3
-
4
- import { SCProvider } from '../../../../context';
5
- import { mockSCStore } from '../../../../context/mockStore';
6
- import TitleCheckBox from '../TitleCheckBox';
7
- import { CheckBoxCustom } from '..';
8
-
9
- const mockOnPress = jest.fn();
10
- const wrapComponent = (idGroup, id) => (
11
- <SCProvider initState={mockSCStore({})}>
12
- <TitleCheckBox idGroup={idGroup} id={id} onPress={mockOnPress} />
13
- </SCProvider>
14
- );
15
-
16
- describe('test TitleCheckBox', () => {
17
- it('test handleOnPress', async () => {
18
- let tree;
19
- await act(async () => {
20
- tree = await create(wrapComponent(1, 2));
21
- });
22
- const instance = tree.root;
23
- const checkBoxCustom = instance.findByType(CheckBoxCustom);
24
- await act(async () => {
25
- checkBoxCustom.props.onPress();
26
- });
27
-
28
- expect(checkBoxCustom.props.isChecked).toBe(true);
29
- expect(mockOnPress).toHaveBeenLastCalledWith(1, true, 2);
30
- });
31
- });