@eohjsc/react-native-smart-city 0.5.1 → 0.5.2

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/ActionGroup/OnOffTemplate/OnOffSimpleTemplateStyle.js +1 -0
  3. package/src/commons/ActionGroup/SliderRangeTemplate.js +10 -3
  4. package/src/commons/ActionGroup/__test__/SliderRangeTemplate.test.js +4 -0
  5. package/src/configs/AccessibilityLabel.js +8 -0
  6. package/src/navigations/AddMemberStack.js +8 -3
  7. package/src/screens/AddCommon/SelectUnit.js +1 -1
  8. package/src/screens/AddCommon/__test__/SelectUnit.test.js +1 -1
  9. package/src/screens/Sharing/Components/CheckBoxConfig.js +44 -0
  10. package/src/screens/Sharing/Components/CheckBoxCustom.js +2 -13
  11. package/src/screens/Sharing/Components/CheckBoxSubUnit.js +35 -0
  12. package/src/screens/Sharing/Components/EndDevice.js +93 -0
  13. package/src/screens/Sharing/Components/Styles/CheckBoxConfigStyles.js +18 -0
  14. package/src/screens/Sharing/Components/Styles/DeviceItemStyles.js +28 -35
  15. package/src/screens/Sharing/Components/index.js +1 -2
  16. package/src/screens/Sharing/InfoMemberUnit.js +1 -2
  17. package/src/screens/Sharing/SelectShareDevice.js +273 -0
  18. package/src/screens/Sharing/Styles/SelectPermissionStyles.js +2 -11
  19. package/src/screens/Sharing/UnitMemberList.js +1 -1
  20. package/src/screens/Sharing/UpdateShareDevice.js +322 -0
  21. package/src/screens/Sharing/__test__/SelectShareDevice.test.js +215 -0
  22. package/src/screens/Sharing/__test__/UnitMemberList.test.js +1 -1
  23. package/src/screens/Sharing/__test__/UpdateShareDevice.test.js +307 -0
  24. package/src/screens/SubUnit/AddSubUnit.js +2 -6
  25. package/src/screens/SubUnit/EditSubUnitStyles.js +2 -1
  26. package/src/screens/Unit/AddMenu.js +1 -1
  27. package/src/utils/Route/index.js +2 -1
  28. package/src/screens/Sharing/Components/DeviceItem.js +0 -146
  29. package/src/screens/Sharing/Components/__test__/DeviceItem.test.js +0 -48
  30. package/src/screens/Sharing/SharingSelectPermission.js +0 -409
  31. package/src/screens/Sharing/__test__/SharingSelectPermission.test.js +0 -292
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.5.01",
4
+ "version": "0.5.02",
5
5
  "description": "TODO",
6
6
  "main": "index.js",
7
7
  "files": [
@@ -6,6 +6,7 @@ export default StyleSheet.create({
6
6
  paddingVertical: 16,
7
7
  paddingHorizontal: 16,
8
8
  marginHorizontal: 16,
9
+ marginBottom: 16,
9
10
  borderWidth: 1,
10
11
  borderColor: Colors.Gray4,
11
12
  borderRadius: 10,
@@ -1,4 +1,4 @@
1
- import React, { memo, useCallback, useState, useEffect } from 'react';
1
+ import React, { memo, useCallback, useState, useEffect, useRef } from 'react';
2
2
  import { Slider } from '@miblanchard/react-native-slider';
3
3
 
4
4
  import { View } from 'react-native';
@@ -16,6 +16,7 @@ const SliderRangeTemplate = memo(
16
16
  const { config, min_value, max_value, action_data } = configuration;
17
17
  const [value, setValue] = useState();
18
18
  const [processing, setProcessing] = useState(false);
19
+ const timeout = useRef();
19
20
 
20
21
  const onSlidingStart = useCallback(() => {
21
22
  setProcessing(true);
@@ -27,11 +28,14 @@ const SliderRangeTemplate = memo(
27
28
 
28
29
  const onSlidingComplete = useCallback(
29
30
  async (number) => {
31
+ clearTimeout(timeout.current);
30
32
  await doAction(
31
33
  action_data,
32
34
  JSON.stringify({ value_brness: number[0], value: number[0] })
33
35
  );
34
- setProcessing(false);
36
+ timeout.current = setTimeout(() => {
37
+ setProcessing(false);
38
+ }, 3000);
35
39
  },
36
40
  [action_data, doAction]
37
41
  );
@@ -41,6 +45,7 @@ const SliderRangeTemplate = memo(
41
45
  }, []);
42
46
 
43
47
  const onEndEditing = useCallback(async () => {
48
+ clearTimeout(timeout.current);
44
49
  if (value) {
45
50
  const data = parseInt(value, 10);
46
51
  await doAction(
@@ -51,7 +56,9 @@ const SliderRangeTemplate = memo(
51
56
  })
52
57
  );
53
58
  }
54
- setProcessing(false);
59
+ timeout.current = setTimeout(() => {
60
+ setProcessing(false);
61
+ }, 3000);
55
62
  }, [action_data, doAction, value]);
56
63
 
57
64
  useEffect(() => {
@@ -56,6 +56,7 @@ describe('Test SliderRangeTemplate', () => {
56
56
  });
57
57
 
58
58
  it('render template SliderRangeTemplate', async () => {
59
+ jest.useFakeTimers();
59
60
  useConfigGlobalState.mockImplementation(() => [{}, jest.fn()]);
60
61
  const sensor = { is_managed_by_backend: true, name: 'Sensor' };
61
62
  await act(async () => {
@@ -72,6 +73,7 @@ describe('Test SliderRangeTemplate', () => {
72
73
  });
73
74
  await act(async () => {
74
75
  await sliderRange.props.onSlidingComplete([50]);
76
+ jest.runAllTimers();
75
77
  });
76
78
  expect(mockDoAction).toHaveBeenCalledWith(
77
79
  actionData,
@@ -124,6 +126,7 @@ describe('Test SliderRangeTemplate', () => {
124
126
  });
125
127
 
126
128
  it('test change input text called doAction', async () => {
129
+ jest.useFakeTimers();
127
130
  useConfigGlobalState.mockImplementation(() => [
128
131
  {
129
132
  5: {
@@ -147,6 +150,7 @@ describe('Test SliderRangeTemplate', () => {
147
150
  });
148
151
  await act(async () => {
149
152
  await textInput.props.onEndEditing('60');
153
+ jest.runAllTimers();
150
154
  });
151
155
  expect(mockDoAction).toHaveBeenCalledWith(
152
156
  actionData,
@@ -425,6 +425,14 @@ export default {
425
425
  ICON_UNIT: 'ICON_UNIT',
426
426
  FILTER_SHARING_ITEM: 'FILTER_SHARING_ITEM',
427
427
 
428
+ // Share device
429
+ SHARE_DEVICE: {
430
+ CHECK_BOX_CUSTOM: 'CHECK_BOX_CUSTOM',
431
+ CHECK_BOX_CONFIG: 'CHECK_BOX_CONFIG',
432
+ EXPAND_END_DEVICE: 'EXPAND_END_DEVICE',
433
+ CLICK_NAME_END_DEVICE: 'CLICK_NAME_END_DEVICE',
434
+ },
435
+
428
436
  // Select subunit
429
437
 
430
438
  SELECT_SUBUNIT_NAME: 'SELECT_SUBUNIT_NAME',
@@ -5,7 +5,8 @@ import AddCommonSelectUnit from '../screens/AddCommon/SelectUnit';
5
5
  import Route from '../utils/Route';
6
6
  import { screenOptions } from './utils';
7
7
  import SharingInviteMembers from '../screens/Sharing/SelectUser';
8
- import SharingSelectPermission from '../screens/Sharing/SharingSelectPermission';
8
+ import UpdateShareDevice from '../screens/Sharing/UpdateShareDevice';
9
+ import SelectShareDevice from '../screens/Sharing/SelectShareDevice';
9
10
 
10
11
  const Stack = createStackNavigator();
11
12
 
@@ -22,8 +23,12 @@ export const AddMemberStack = memo(() => {
22
23
  component={AddCommonSelectUnit}
23
24
  />
24
25
  <Stack.Screen
25
- name={Route.SharingSelectPermission}
26
- component={SharingSelectPermission}
26
+ name={Route.UpdateShareDevice}
27
+ component={UpdateShareDevice}
28
+ />
29
+ <Stack.Screen
30
+ name={Route.SelectShareDevice}
31
+ component={SelectShareDevice}
27
32
  />
28
33
  <Stack.Screen
29
34
  name={Route.SharingInviteMembers}
@@ -56,7 +56,7 @@ const AddCommonSelectUnit = ({ route }) => {
56
56
  });
57
57
  break;
58
58
  case 'AddMember':
59
- navigation.navigate(Routes.SharingSelectPermission, {
59
+ navigation.navigate(Routes.SelectShareDevice, {
60
60
  unit,
61
61
  });
62
62
  break;
@@ -131,7 +131,7 @@ describe('Test SelectUnit container', () => {
131
131
  });
132
132
  break;
133
133
  case 'AddMember':
134
- expect(mockedNavigate).toBeCalledWith('SharingSelectPermission', {
134
+ expect(mockedNavigate).toBeCalledWith('SelectShareDevice', {
135
135
  unit: { id: 1, name: 'Unit 1' },
136
136
  });
137
137
  break;
@@ -0,0 +1,44 @@
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,22 +1,11 @@
1
1
  import React, { memo } from 'react';
2
2
  import { TouchableOpacity, View, Image } from 'react-native';
3
- import AccessibilityLabel from '../../../configs/AccessibilityLabel';
4
3
  import Images from '../../../configs/Images';
5
4
  import styles from './Styles/CheckBoxCustomStyles';
6
5
 
7
- const CheckBoxCustom = ({
8
- isChecked,
9
- onPress,
10
- wrapStyle,
11
- wrapViewCustom,
12
- id,
13
- }) => {
6
+ const CheckBoxCustom = ({ isChecked, onPress, wrapStyle, wrapViewCustom }) => {
14
7
  return (
15
- <TouchableOpacity
16
- style={[styles.wrapBtn, wrapStyle]}
17
- onPress={onPress}
18
- accessibilityLabel={`${AccessibilityLabel.CHECK_BOX_CUSTOM}-${id}`}
19
- >
8
+ <TouchableOpacity style={[styles.wrapBtn, wrapStyle]} onPress={onPress}>
20
9
  <View
21
10
  style={[
22
11
  styles.wrapView,
@@ -0,0 +1,35 @@
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);
@@ -0,0 +1,93 @@
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);
@@ -0,0 +1,18 @@
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
+ });
@@ -3,16 +3,34 @@ import { Colors } from '../../../../configs';
3
3
  import { normalize } from '../../../../configs/Constants';
4
4
 
5
5
  export default StyleSheet.create({
6
+ wrapCheckBoxStyle: {
7
+ marginLeft: normalize(-10),
8
+ },
9
+ titleStyle: {
10
+ fontSize: 16,
11
+ fontWeight: 'normal',
12
+ width: 200,
13
+ },
14
+ wrapStyleTitle: {
15
+ justifyContent: 'space-between',
16
+ },
6
17
  wrap: {
7
18
  flexDirection: 'row',
8
- marginHorizontal: normalize(16),
19
+ marginHorizontal: normalize(10),
20
+ paddingBottom: 10,
21
+ },
22
+ isRenderSeparated: {
23
+ paddingBottom: normalize(16),
9
24
  },
10
25
  viewLeft: {
11
- marginRight: normalize(16),
26
+ marginRight: 16,
12
27
  width: normalize(24),
13
28
  height: normalize(24),
14
29
  marginTop: normalize(14),
15
30
  },
31
+ wrapRight: {
32
+ flex: 1,
33
+ },
16
34
  viewRight: {
17
35
  flexDirection: 'row',
18
36
  alignItems: 'center',
@@ -21,44 +39,19 @@ export default StyleSheet.create({
21
39
  },
22
40
  text: {
23
41
  color: Colors.Gray9,
24
- fontWeight: '400',
25
- fontSize: normalize(16),
26
- flex: 1,
27
- paddingRight: normalize(20),
28
- fontStyle: 'normal',
29
- },
30
- viewSeparated: {
31
- height: 1,
32
- backgroundColor: Colors.Gray4,
33
- marginTop: normalize(16),
34
- },
35
- wrapRight: {
36
42
  flex: 1,
37
43
  },
38
- isRenderSeparated: {
39
- paddingBottom: normalize(16),
40
- },
41
- wrapCheckBoxStyle: {
42
- marginLeft: normalize(-10),
43
- },
44
- wrapChild: {
45
- zIndex: -1,
46
- marginTop: normalize(10),
47
- marginRight: normalize(30),
48
- },
49
- titleStyle: {
50
- fontSize: 16,
51
- fontWeight: 'normal',
52
- width: 200,
53
- },
54
- wrapExpand: {
55
- marginTop: 10,
56
- },
57
44
  checkBox: {
58
45
  width: normalize(20),
59
46
  height: normalize(20),
60
47
  },
61
- wrapStyleTitle: {
62
- justifyContent: 'space-between',
48
+
49
+ wrapExpand: {
50
+ marginTop: 10,
51
+ },
52
+ viewSeparated: {
53
+ height: 1,
54
+ backgroundColor: Colors.Gray4,
55
+ marginTop: normalize(16),
63
56
  },
64
57
  });
@@ -1,5 +1,4 @@
1
1
  import CheckBoxCustom from './CheckBoxCustom';
2
2
  import TitleCheckBox from './TitleCheckBox';
3
- import DeviceItem from './DeviceItem';
4
3
 
5
- export { CheckBoxCustom, TitleCheckBox, DeviceItem };
4
+ export { CheckBoxCustom, TitleCheckBox };
@@ -154,10 +154,9 @@ const InfoMemberUnit = memo(({ route }) => {
154
154
  const handleShareDevice = useCallback(() => {
155
155
  if (isOwner && memberInfo?.identity === 'member') {
156
156
  navigate(Routes.AddMemberStack, {
157
- screen: Routes.SharingSelectPermission,
157
+ screen: Routes.UpdateShareDevice,
158
158
  params: {
159
159
  unit: { id: unit?.id },
160
- type: 'update_shared',
161
160
  member: memberInfo,
162
161
  },
163
162
  });