@eohjsc/react-native-smart-city 0.3.28 → 0.3.31

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 (123) hide show
  1. package/package.json +1 -1
  2. package/src/Images/DevMode/close.png +0 -0
  3. package/src/Images/DevMode/close@2x.png +0 -0
  4. package/src/Images/DevMode/close@3x.png +0 -0
  5. package/src/Images/DevMode/plus.png +0 -0
  6. package/src/Images/DevMode/plus@2x.png +0 -0
  7. package/src/Images/DevMode/plus@3x.png +0 -0
  8. package/src/Images/DevMode/remove_circle.png +0 -0
  9. package/src/Images/DevMode/remove_circle@2x.png +0 -0
  10. package/src/Images/DevMode/remove_circle@3x.png +0 -0
  11. package/src/commons/Action/ItemQuickAction.js +1 -0
  12. package/src/commons/ActionGroup/ColorPickerTemplate.js +36 -17
  13. package/src/commons/ActionGroup/CurtainButtonTemplate.js +1 -2
  14. package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +13 -8
  15. package/src/commons/ActionGroup/OnOffSmartLock/OnOffSmartLock.js +37 -44
  16. package/src/commons/ActionGroup/OnOffSmartLock/OnOffSmartLockStyle.js +1 -0
  17. package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +7 -4
  18. package/src/commons/ActionGroup/OnOffTemplate/index.js +2 -2
  19. package/src/commons/ActionGroup/OneBigButtonTemplate.js +4 -4
  20. package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +28 -18
  21. package/src/commons/ActionGroup/SliderRangeTemplate.js +24 -16
  22. package/src/commons/ActionGroup/ThreeButtonTemplate.js +48 -58
  23. package/src/commons/ActionGroup/TwoButtonTemplate/index.js +134 -132
  24. package/src/commons/ActionGroup/__test__/index.test.js +2 -2
  25. package/src/commons/ActionGroup/index.js +35 -10
  26. package/src/commons/ActionTemplate/CurtainAction.js +60 -0
  27. package/src/commons/ActionTemplate/CurtainActionStyles.js +11 -0
  28. package/src/commons/ActionTemplate/OnOffSmartLockAction.js +44 -0
  29. package/src/commons/ActionTemplate/OnOffSmartLockActionStyles.js +11 -0
  30. package/src/commons/ActionTemplate/index.js +18 -0
  31. package/src/commons/BottomButtonView/index.js +1 -0
  32. package/src/commons/Button/index.js +2 -0
  33. package/src/commons/DevMode/CardDevMode.js +42 -0
  34. package/src/commons/DevMode/EmptyComponent.js +18 -0
  35. package/src/commons/DevMode/Item.js +21 -0
  36. package/src/commons/DevMode/Styles/CardStyles.js +40 -0
  37. package/src/commons/DevMode/Styles/EmptyComponentStyles.js +15 -0
  38. package/src/commons/DevMode/Styles/ItemStyles.js +27 -0
  39. package/src/commons/DevMode/Styles/TextWithLabelStyles.js +36 -0
  40. package/src/commons/DevMode/TextWithLabel.js +30 -0
  41. package/src/commons/DevMode/index.js +5 -1
  42. package/src/commons/Device/DeviceAlertStatus.js +1 -1
  43. package/src/commons/Device/Emergency/EmergencyDetail.js +1 -1
  44. package/src/commons/Device/ItemAddNew/index.js +5 -1
  45. package/src/commons/Device/ItemDevice.js +12 -9
  46. package/src/commons/Device/PMSensor/PMSensorIndicatior.js +1 -1
  47. package/src/commons/Device/RainningSensor/CurrentRainSensor.js +1 -1
  48. package/src/commons/Device/WindDirection/Compass/index.js +1 -1
  49. package/src/commons/Device/WindSpeed/Anemometer/index.js +1 -1
  50. package/src/commons/Header/HeaderCustom.js +8 -2
  51. package/src/commons/HeaderAni/index.js +1 -0
  52. package/src/commons/MenuActionMore/index.js +14 -2
  53. package/src/commons/NavBar/index.js +13 -1
  54. package/src/commons/Popover/index.js +7 -6
  55. package/src/commons/Sharing/WrapHeaderScrollable.js +4 -2
  56. package/src/commons/SubUnit/OneTap/ItemOneTap.js +4 -1
  57. package/src/commons/SubUnit/ShortDetail.js +1 -0
  58. package/src/commons/SummaryItem/index.js +2 -1
  59. package/src/commons/Unit/HeaderUnit/index.js +2 -0
  60. package/src/commons/Unit/SharedUnit.js +1 -0
  61. package/src/commons/WrapParallaxScrollView/index.js +16 -2
  62. package/src/configs/API.js +6 -0
  63. package/src/configs/Colors.js +4 -0
  64. package/src/configs/Constants.js +16 -0
  65. package/src/configs/Images.js +3 -0
  66. package/src/context/actionType.ts +12 -0
  67. package/src/context/mockStore.ts +12 -0
  68. package/src/context/reducer.ts +43 -1
  69. package/src/hooks/Common/useDevicesStatus.js +1 -1
  70. package/src/hooks/IoT/useValueEvaluation.js +10 -19
  71. package/src/iot/RemoteControl/GoogleHome.js +6 -6
  72. package/src/navigations/Main.js +26 -2
  73. package/src/navigations/UnitStack.js +5 -8
  74. package/src/screens/AddNewAction/Device/index.js +5 -1
  75. package/src/screens/AddNewAction/SelectAction.js +36 -15
  76. package/src/screens/AddNewAction/__test__/SelectAction.test.js +1 -0
  77. package/src/screens/AddNewAutoSmart/index.js +2 -0
  78. package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +13 -1
  79. package/src/screens/AddNewGateway/hooks/__Tests__/index.test.js +27 -0
  80. package/src/screens/Device/components/DetailHistoryChart.js +7 -5
  81. package/src/screens/Device/components/SensorConnectStatusViewHeader.js +10 -11
  82. package/src/screens/Device/components/SensorDisplayItem.js +49 -24
  83. package/src/screens/Device/detail.js +38 -17
  84. package/src/screens/Device/hooks/useFavoriteDevice.js +4 -2
  85. package/src/screens/Drawer/index.js +9 -4
  86. package/src/screens/EmergencyContacts/EmergencyContactsAddNew.js +3 -3
  87. package/src/screens/EmergencyContacts/EmergencyContactsSelectContacts.js +4 -7
  88. package/src/screens/Notification/__test__/NotificationItem.test.js +74 -104
  89. package/src/screens/Notification/components/NotificationItem.js +40 -239
  90. package/src/screens/ScriptDetail/__test__/index.test.js +40 -1
  91. package/src/screens/ScriptDetail/index.js +2 -1
  92. package/src/screens/Sharing/Components/SensorItem.js +4 -1
  93. package/src/screens/Sharing/Components/Styles/SensorItemStyles.js +4 -0
  94. package/src/screens/Sharing/Components/Styles/TitleCheckBoxStyles.js +4 -0
  95. package/src/screens/Sharing/Components/TitleCheckBox.js +17 -8
  96. package/src/screens/Template/EditTemplate.js +151 -0
  97. package/src/screens/Template/GatewayList.js +51 -0
  98. package/src/screens/Template/Information.js +41 -0
  99. package/src/screens/Template/Styles/EditTemplateStyle.js +109 -0
  100. package/src/screens/Template/Styles/GatewayStyles.js +46 -0
  101. package/src/screens/Template/Styles/InformationStyles.js +16 -0
  102. package/src/screens/Template/Styles/detailStyles.js +35 -0
  103. package/src/screens/Template/Styles/indexStyles.js +2 -33
  104. package/src/screens/Template/__test__/EditTemplate.test.js +89 -0
  105. package/src/screens/Template/__test__/GatewayList.test.js +26 -0
  106. package/src/screens/Template/__test__/Information.test.js +16 -0
  107. package/src/screens/Template/__test__/detail.test.js +60 -0
  108. package/src/screens/Template/__test__/index.test.js +26 -1
  109. package/src/screens/Template/detail.js +154 -0
  110. package/src/screens/Template/index.js +39 -32
  111. package/src/screens/Unit/Detail.js +11 -1
  112. package/src/screens/Unit/MoreMenu.js +16 -1
  113. package/src/screens/Unit/SelectAddToFavorites.js +11 -1
  114. package/src/screens/Unit/SmartAccount.js +1 -1
  115. package/src/screens/Unit/Station/__test__/index.test.js +18 -2
  116. package/src/screens/Unit/Station/index.js +0 -1
  117. package/src/screens/Unit/Summaries.js +6 -1
  118. package/src/screens/Unit/__test__/Detail.test.js +73 -43
  119. package/src/screens/Unit/__test__/SmartAccount.test.js +42 -25
  120. package/src/screens/Unit/components/AutomateScript/index.js +5 -2
  121. package/src/utils/I18n/translations/en.json +37 -42
  122. package/src/utils/I18n/translations/vi.json +35 -44
  123. package/src/utils/Route/index.js +6 -0
@@ -1,15 +1,12 @@
1
1
  import React, { memo, useCallback, useState } from 'react';
2
2
  import { TouchableOpacity, View, Switch } from 'react-native';
3
3
  import { Icon } from '@ant-design/react-native';
4
- import { useTranslations } from '../../hooks/Common/useTranslations';
5
4
  import styles from './ThreeButtonTemplateStyle';
6
5
  import Text from '../Text';
7
6
  import { TESTID } from '../../configs/Constants';
8
7
  import { Colors } from '../../configs';
9
- import { Card } from '../../commons/CardShadow';
10
8
 
11
- const ThreeButtonTemplate = memo(({ actionGroup, doAction, sensor }) => {
12
- const t = useTranslations();
9
+ const ThreeButtonTemplate = memo(({ actionGroup, doAction }) => {
13
10
  const { configuration } = actionGroup;
14
11
  const {
15
12
  text1,
@@ -20,7 +17,12 @@ const ThreeButtonTemplate = memo(({ actionGroup, doAction, sensor }) => {
20
17
  action3_data,
21
18
  action_off_data,
22
19
  action_on_data,
23
- } = configuration;
20
+ icon1,
21
+ icon2,
22
+ icon3,
23
+ text_door_lock,
24
+ is_display_lock,
25
+ } = configuration || {};
24
26
  const [lock, setLock] = useState(false);
25
27
  const iconCustom = (icon) => {
26
28
  return icon === 'stop' ? (
@@ -60,7 +62,7 @@ const ThreeButtonTemplate = memo(({ actionGroup, doAction, sensor }) => {
60
62
  style={styles.textLockDoor}
61
63
  testID={TESTID.TEXT_DOOR_LOOK_ON_OFF}
62
64
  >
63
- {configuration.text_door_lock}{' '}
65
+ {`${text_door_lock} `}
64
66
  </Text>
65
67
  </View>
66
68
  <Switch
@@ -75,60 +77,48 @@ const ThreeButtonTemplate = memo(({ actionGroup, doAction, sensor }) => {
75
77
  };
76
78
  return (
77
79
  <>
78
- <Card title={actionGroup.title ? actionGroup.title : t('controller')}>
79
- <View style={styles.wrap}>
80
- <TouchableOpacity
81
- testID={TESTID.BUTTON_TEMPLATE_1}
82
- style={styles.buttonActionDoor}
83
- onPress={onButton1Press}
84
- underlayColor={Colors.Gray2}
85
- >
86
- <View style={styles.imageButton}>
87
- <Icon
88
- name={configuration.icon1}
89
- size={30}
90
- color={Colors.Primary}
91
- />
92
- </View>
93
- <Text style={styles.text}>{text1}</Text>
94
- </TouchableOpacity>
80
+ <View style={styles.wrap}>
81
+ <TouchableOpacity
82
+ testID={TESTID.BUTTON_TEMPLATE_1}
83
+ style={styles.buttonActionDoor}
84
+ onPress={onButton1Press}
85
+ underlayColor={Colors.Gray2}
86
+ >
87
+ <View style={styles.imageButton}>
88
+ <Icon name={icon1} size={30} color={Colors.Primary} />
89
+ </View>
90
+ <Text style={styles.text}>{text1}</Text>
91
+ </TouchableOpacity>
95
92
 
96
- <TouchableOpacity
97
- testID={TESTID.BUTTON_TEMPLATE_2}
98
- style={styles.buttonActionDoor}
99
- onPress={onButton2Press}
100
- underlayColor={Colors.Gray2}
101
- >
102
- <View style={styles.imageButton}>
103
- {iconCustom(configuration.icon2)}
104
- </View>
105
- <Text style={styles.text}>{text2}</Text>
106
- </TouchableOpacity>
93
+ <TouchableOpacity
94
+ testID={TESTID.BUTTON_TEMPLATE_2}
95
+ style={styles.buttonActionDoor}
96
+ onPress={onButton2Press}
97
+ underlayColor={Colors.Gray2}
98
+ >
99
+ <View style={styles.imageButton}>{iconCustom(icon2)}</View>
100
+ <Text style={styles.text}>{text2}</Text>
101
+ </TouchableOpacity>
107
102
 
108
- <TouchableOpacity
109
- testID={TESTID.BUTTON_TEMPLATE_3}
110
- style={styles.buttonActionDoor}
111
- onPress={onButton3Press}
112
- underlayColor={Colors.Gray2}
113
- >
114
- <View style={styles.imageButton}>
115
- <Icon
116
- name={configuration.icon3}
117
- size={30}
118
- color={Colors.Primary}
119
- />
120
- </View>
121
- <Text style={styles.text}>{text3}</Text>
122
- </TouchableOpacity>
123
- </View>
124
- <View style={styles.lockSwitch}>
125
- {configuration.is_display_lock &&
126
- itemLock(
127
- lock ? 'lock' : 'unlock',
128
- lock ? Colors.Primary : Colors.Gray6
129
- )}
130
- </View>
131
- </Card>
103
+ <TouchableOpacity
104
+ testID={TESTID.BUTTON_TEMPLATE_3}
105
+ style={styles.buttonActionDoor}
106
+ onPress={onButton3Press}
107
+ underlayColor={Colors.Gray2}
108
+ >
109
+ <View style={styles.imageButton}>
110
+ <Icon name={icon3} size={30} color={Colors.Primary} />
111
+ </View>
112
+ <Text style={styles.text}>{text3}</Text>
113
+ </TouchableOpacity>
114
+ </View>
115
+ <View style={styles.lockSwitch}>
116
+ {is_display_lock &&
117
+ itemLock(
118
+ lock ? 'lock' : 'unlock',
119
+ lock ? Colors.Primary : Colors.Gray6
120
+ )}
121
+ </View>
132
122
  </>
133
123
  );
134
124
  });
@@ -10,149 +10,151 @@ import { useUnwatchLGDeviceConfigControl } from '../../../hooks/IoT';
10
10
  import Text from '../../Text';
11
11
  import styles from './TwoButtonTemplateStyles';
12
12
 
13
- const TwoButtonTemplate = memo(({ actionGroup, doAction, sensor }) => {
14
- const { configuration } = actionGroup;
15
- const { button1, button2 } = configuration;
16
- const [isOn, setIsOn] = useState(true);
17
- const [isStart, setIsStart] = useState(true);
18
- const [configValues] = useConfigGlobalState('configValues');
19
- const isLight = false;
13
+ const TwoButtonTemplate = memo(
14
+ ({ actionGroup = {}, doAction, sensor = {} }) => {
15
+ const { configuration = {} } = actionGroup;
16
+ const { button1, button2 } = configuration;
17
+ const [isOn, setIsOn] = useState(true);
18
+ const [isStart, setIsStart] = useState(true);
19
+ const [configValues] = useConfigGlobalState('configValues');
20
+ const isLight = false;
20
21
 
21
- const triggerAction1 = useCallback(async () => {
22
- if (button1?.action_on_data && button1?.action_off_data) {
23
- if (isOn) {
24
- await doAction(button1?.action_off_data, null);
25
- } else {
26
- await doAction(button1?.action_on_data, null);
22
+ const triggerAction1 = useCallback(async () => {
23
+ if (button1?.action_on_data && button1?.action_off_data) {
24
+ if (isOn) {
25
+ await doAction(button1?.action_off_data, null);
26
+ } else {
27
+ await doAction(button1?.action_on_data, null);
28
+ }
27
29
  }
28
- }
29
- if (sensor?.is_managed_by_backend) {
30
- configuration.config &&
31
- sensor.device_type === DEVICE_TYPE.LG_THINQ &&
32
- watchMultiConfigs([configuration.config]);
33
- }
34
- }, [
35
- button1,
36
- configuration.config,
37
- doAction,
38
- isOn,
39
- sensor?.is_managed_by_backend,
40
- sensor.device_type,
41
- ]);
30
+ if (sensor?.is_managed_by_backend) {
31
+ configuration.config &&
32
+ sensor.device_type === DEVICE_TYPE.LG_THINQ &&
33
+ watchMultiConfigs([configuration.config]);
34
+ }
35
+ }, [
36
+ button1,
37
+ configuration.config,
38
+ doAction,
39
+ isOn,
40
+ sensor?.is_managed_by_backend,
41
+ sensor.device_type,
42
+ ]);
42
43
 
43
- const triggerAction2 = useCallback(async () => {
44
- if (button2?.action_on_data && button2?.action_off_data) {
45
- if (isStart) {
46
- await doAction(button2?.action_off_data, null);
47
- } else {
48
- await doAction(button2?.action_on_data, null);
44
+ const triggerAction2 = useCallback(async () => {
45
+ if (button2?.action_on_data && button2?.action_off_data) {
46
+ if (isStart) {
47
+ await doAction(button2?.action_off_data, null);
48
+ } else {
49
+ await doAction(button2?.action_on_data, null);
50
+ }
51
+ }
52
+ if (
53
+ sensor?.is_managed_by_backend &&
54
+ sensor.device_type === DEVICE_TYPE.LG_THINQ
55
+ ) {
56
+ configuration.config && watchMultiConfigs([configuration.config]);
49
57
  }
50
- }
51
- if (
52
- sensor?.is_managed_by_backend &&
53
- sensor.device_type === DEVICE_TYPE.LG_THINQ
54
- ) {
55
- configuration.config && watchMultiConfigs([configuration.config]);
56
- }
57
- }, [
58
- button2?.action_off_data,
59
- button2?.action_on_data,
60
- configuration.config,
61
- doAction,
62
- isStart,
63
- sensor?.is_managed_by_backend,
64
- sensor.device_type,
65
- ]);
58
+ }, [
59
+ button2?.action_off_data,
60
+ button2?.action_on_data,
61
+ configuration.config,
62
+ doAction,
63
+ isStart,
64
+ sensor?.is_managed_by_backend,
65
+ sensor.device_type,
66
+ ]);
67
+
68
+ useUnwatchLGDeviceConfigControl(sensor, [configuration.config]);
66
69
 
67
- useUnwatchLGDeviceConfigControl(sensor, [configuration.config]);
70
+ useEffect(() => {
71
+ const configValue1 = configValues[button1?.config];
72
+ const configValue2 = configValues[button2?.config];
73
+ if (button1?.is_on_value && button1?.is_on_value.length > 0) {
74
+ setIsOn(button1?.is_on_value.includes(configValue1?.value));
75
+ return;
76
+ }
77
+ if (button2?.is_on_value && button2?.is_on_value.length > 0) {
78
+ setIsStart(button2?.is_on_value.includes(configValue2?.value));
79
+ return;
80
+ }
68
81
 
69
- useEffect(() => {
70
- const configValue1 = configValues[button1?.config];
71
- const configValue2 = configValues[button2?.config];
72
- if (button1?.is_on_value && button1?.is_on_value.length > 0) {
73
- setIsOn(button1?.is_on_value.includes(configValue1?.value));
74
- return;
75
- }
76
- if (button2?.is_on_value && button2?.is_on_value.length > 0) {
77
- setIsStart(button2?.is_on_value.includes(configValue2?.value));
78
- return;
79
- }
82
+ setIsOn(configValue1?.value);
83
+ setIsStart(configValue2?.value);
84
+ }, [
85
+ configuration.config,
86
+ configValues,
87
+ configuration.is_on_value,
88
+ configuration,
89
+ button1?.config,
90
+ button1?.is_on_value,
91
+ button2?.config,
92
+ button2?.is_on_value,
93
+ ]);
80
94
 
81
- setIsOn(configValue1?.value);
82
- setIsStart(configValue2?.value);
83
- }, [
84
- configuration.config,
85
- configValues,
86
- configuration.is_on_value,
87
- configuration,
88
- button1?.config,
89
- button1?.is_on_value,
90
- button2?.config,
91
- button2?.is_on_value,
92
- ]);
95
+ const RenderTwoButtonAction = () => {
96
+ const buttons = [
97
+ {
98
+ icon_on: button1?.icon_on,
99
+ icon_off: button1?.icon_off,
100
+ text_on: button1?.text_on,
101
+ text_off: button1?.text_off,
102
+ onPress: triggerAction1,
103
+ isCheckOnOff: isOn,
104
+ testID: TESTID.BUTTON_TEMPLATE_1,
105
+ },
106
+ {
107
+ icon_on: button2?.icon_on,
108
+ icon_off: button2?.icon_off,
109
+ text_on: button2?.text_on,
110
+ text_off: button2?.text_off,
111
+ onPress: triggerAction2,
112
+ isCheckOnOff: isStart,
113
+ testID: TESTID.BUTTON_TEMPLATE_1,
114
+ },
115
+ ];
116
+ return (
117
+ <>
118
+ {buttons.map((item, index) => (
119
+ <TouchableOpacity
120
+ testID={item.testID}
121
+ style={styles.bigCircle}
122
+ onPress={item.onPress}
123
+ >
124
+ <View style={styles.smallCircle}>
125
+ <Icon
126
+ name={item?.isCheckOnOff ? item?.icon_on : item?.icon_off}
127
+ size={44}
128
+ color={item?.isCheckOnOff ? Colors.Green7 : Colors.Gray6}
129
+ />
130
+ <Text
131
+ style={[
132
+ styles.textBig,
133
+ { color: item?.isCheckOnOff ? Colors.Gray8 : Colors.Gray6 },
134
+ ]}
135
+ >
136
+ {item?.isCheckOnOff ? item?.text_on : item?.text_off}
137
+ </Text>
138
+ </View>
139
+ </TouchableOpacity>
140
+ ))}
141
+ </>
142
+ );
143
+ };
93
144
 
94
- const RenderTwoButtonAction = () => {
95
- const buttons = [
96
- {
97
- icon_on: button1?.icon_on,
98
- icon_off: button1?.icon_off,
99
- text_on: button1?.text_on,
100
- text_off: button1?.text_off,
101
- onPress: triggerAction1,
102
- isCheckOnOff: isOn,
103
- testID: TESTID.BUTTON_TEMPLATE_1,
104
- },
105
- {
106
- icon_on: button2?.icon_on,
107
- icon_off: button2?.icon_off,
108
- text_on: button2?.text_on,
109
- text_off: button2?.text_off,
110
- onPress: triggerAction2,
111
- isCheckOnOff: isStart,
112
- testID: TESTID.BUTTON_TEMPLATE_1,
113
- },
114
- ];
115
145
  return (
116
146
  <>
117
- {buttons.map((item, index) => (
118
- <TouchableOpacity
119
- testID={item.testID}
120
- style={styles.bigCircle}
121
- onPress={item.onPress}
122
- >
123
- <View style={styles.smallCircle}>
124
- <Icon
125
- name={item?.isCheckOnOff ? item?.icon_on : item?.icon_off}
126
- size={44}
127
- color={item?.isCheckOnOff ? Colors.Green7 : Colors.Gray6}
128
- />
129
- <Text
130
- style={[
131
- styles.textBig,
132
- { color: item?.isCheckOnOff ? Colors.Gray8 : Colors.Gray6 },
133
- ]}
134
- >
135
- {item?.isCheckOnOff ? item?.text_on : item?.text_off}
136
- </Text>
137
- </View>
138
- </TouchableOpacity>
139
- ))}
147
+ <View style={styles.wrap}>
148
+ <RenderTwoButtonAction />
149
+ </View>
150
+ {!!actionGroup.title && !isLight && (
151
+ <Text size={20} semibold center>
152
+ {actionGroup.title}
153
+ </Text>
154
+ )}
140
155
  </>
141
156
  );
142
- };
143
-
144
- return (
145
- <>
146
- <View style={styles.wrap}>
147
- <RenderTwoButtonAction />
148
- </View>
149
- {!!actionGroup.title && !isLight && (
150
- <Text size={20} semibold center>
151
- {actionGroup.title}
152
- </Text>
153
- )}
154
- </>
155
- );
156
- });
157
+ }
158
+ );
157
159
 
158
160
  export default TwoButtonTemplate;
@@ -174,7 +174,7 @@ describe('Test ActionGroup', () => {
174
174
  const TextDoorLock = instance.find(
175
175
  (el) => el.props.testID === TESTID.TEXT_DOOR_LOOK_ON_OFF
176
176
  );
177
- expect(TextDoorLock.props.children).toEqual(['Door lock', ' ']);
177
+ expect(TextDoorLock.props.children).toEqual('Door lock ');
178
178
  expect(switchOnOff.length).toEqual(1);
179
179
  expect(buttons.length).toEqual(3);
180
180
  act(() => {
@@ -245,7 +245,7 @@ describe('Test ActionGroup', () => {
245
245
  const TextDoorLock = instance.find(
246
246
  (el) => el.props.testID === TESTID.TEXT_DOOR_LOOK_ON_OFF
247
247
  );
248
- expect(TextDoorLock.props.children).toEqual(['Door lock', ' ']);
248
+ expect(TextDoorLock.props.children).toEqual('Door lock ');
249
249
  expect(switchOnOff.length).toEqual(1);
250
250
  expect(buttons.length).toEqual(3);
251
251
  act(() => {
@@ -1,6 +1,5 @@
1
+ import React, { memo, useCallback, useMemo } from 'react';
1
2
  import Text from '../Text';
2
- import React, { memo, useMemo } from 'react';
3
-
4
3
  import OneBigButtonTemplate from './OneBigButtonTemplate';
5
4
  import ThreeButtonTemplate from './ThreeButtonTemplate';
6
5
  import StatesGridActionTemplate from './StatesGridActionTemplate';
@@ -14,6 +13,9 @@ import ColorPickerTemplate from './ColorPickerTemplate';
14
13
  import SliderRangeTemplate from './SliderRangeTemplate';
15
14
  import OnOffSmartLock from './OnOffSmartLock/OnOffSmartLock';
16
15
  import TwoButtonTemplate from './TwoButtonTemplate';
16
+ import { CardDevMode } from '../DevMode';
17
+ import t from '../../hooks/Common/useTranslations';
18
+ import { useSCContextSelector } from '../../context';
17
19
 
18
20
  export const getActionComponent = (template) => {
19
21
  switch (template) {
@@ -52,23 +54,46 @@ export const getActionComponent = (template) => {
52
54
  }
53
55
  };
54
56
 
55
- const ActionGroup = memo((params) => {
56
- const { actionGroup } = params;
57
+ const isWrap = (template) => {
58
+ switch (template) {
59
+ case 'OnOffSmartLockActionTemplate':
60
+ return true;
61
+ default:
62
+ return false;
63
+ }
64
+ };
65
+
66
+ const ActionGroup = (params = {}) => {
67
+ const { actionGroup = {}, id } = params;
68
+ const { template } = actionGroup;
69
+ const { isEditingTemplate } = useSCContextSelector((state) => state.devMode);
70
+
71
+ const getTitle = useCallback(() => {
72
+ switch (template) {
73
+ case 'OnOffSmartLockActionTemplate':
74
+ return isEditingTemplate ? 'label' : 'controller';
75
+ default:
76
+ return 'label';
77
+ }
78
+ }, [template, isEditingTemplate]);
79
+
57
80
  const ButtonGroupComponent = useMemo(() => {
58
- return getActionComponent(actionGroup.template);
59
- }, [actionGroup]);
81
+ return getActionComponent(template);
82
+ }, [template]);
60
83
 
61
84
  return (
62
85
  <>
63
86
  {ButtonGroupComponent ? (
64
- <ButtonGroupComponent {...params} />
87
+ <CardDevMode title={t(getTitle())} id={id} isWrap={isWrap(template)}>
88
+ <ButtonGroupComponent {...params} />
89
+ </CardDevMode>
65
90
  ) : (
66
91
  <Text
67
92
  center
68
- >{`Invalid action template '${actionGroup.template}'`}</Text>
93
+ >{`Invalid action template '${actionGroup?.template}'`}</Text>
69
94
  )}
70
95
  </>
71
96
  );
72
- });
97
+ };
73
98
 
74
- export default ActionGroup;
99
+ export default memo(ActionGroup);
@@ -0,0 +1,60 @@
1
+ import React, { memo, useCallback } from 'react';
2
+ import { TouchableOpacity } from 'react-native';
3
+ import Text from '../Text';
4
+ import styles from './CurtainActionStyles';
5
+
6
+ const CurtainAction = ({ configuration, onPress, template }) => {
7
+ const { open_action, close_action, stop_action, text1, text2, text3 } =
8
+ configuration || {};
9
+
10
+ const onPressActionClose = useCallback(() => {
11
+ onPress &&
12
+ onPress({
13
+ name: text1,
14
+ action: close_action,
15
+ template,
16
+ });
17
+ }, [onPress, text1, close_action, template]);
18
+
19
+ const onPressActionStop = useCallback(() => {
20
+ onPress &&
21
+ onPress({
22
+ name: text2,
23
+ action: stop_action,
24
+ template,
25
+ });
26
+ }, [onPress, text2, stop_action, template]);
27
+
28
+ const onPressActionOpen = useCallback(() => {
29
+ onPress &&
30
+ onPress({
31
+ name: text3,
32
+ action: open_action,
33
+ template,
34
+ });
35
+ }, [onPress, text3, open_action, template]);
36
+
37
+ return (
38
+ <>
39
+ <TouchableOpacity onPress={onPressActionClose}>
40
+ <Text type="H4" style={styles.textwithline}>
41
+ {text1}
42
+ </Text>
43
+ </TouchableOpacity>
44
+
45
+ <TouchableOpacity onPress={onPressActionStop}>
46
+ <Text type="H4" style={styles.textwithline}>
47
+ {text2}
48
+ </Text>
49
+ </TouchableOpacity>
50
+
51
+ <TouchableOpacity onPress={onPressActionOpen}>
52
+ <Text type="H4" style={styles.textwithline}>
53
+ {text3}
54
+ </Text>
55
+ </TouchableOpacity>
56
+ </>
57
+ );
58
+ };
59
+
60
+ export default memo(CurtainAction);
@@ -0,0 +1,11 @@
1
+ import { StyleSheet } from 'react-native';
2
+ import { Colors } from '../../configs';
3
+
4
+ export default StyleSheet.create({
5
+ textwithline: {
6
+ paddingBottom: 16,
7
+ paddingTop: 16,
8
+ borderBottomWidth: 1,
9
+ borderColor: Colors.Gray4,
10
+ },
11
+ });
@@ -0,0 +1,44 @@
1
+ import React, { memo, useCallback } from 'react';
2
+ import { TouchableOpacity } from 'react-native';
3
+ import Text from '../Text';
4
+ import styles from './OnOffSmartLockActionStyles';
5
+
6
+ const OnOffSmartLockAction = ({ configuration, onPress, template }) => {
7
+ const { action_off, action_on, text_off, text_on } = configuration || {};
8
+
9
+ const onPressActionClose = useCallback(() => {
10
+ onPress &&
11
+ onPress({
12
+ name: text_off,
13
+ action: action_off,
14
+ template,
15
+ });
16
+ }, [onPress, text_off, action_off, template]);
17
+
18
+ const onPressActionOpen = useCallback(() => {
19
+ onPress &&
20
+ onPress({
21
+ name: text_on,
22
+ action: action_on,
23
+ template,
24
+ });
25
+ }, [onPress, text_on, action_on, template]);
26
+
27
+ return (
28
+ <>
29
+ <TouchableOpacity onPress={onPressActionClose}>
30
+ <Text type="H4" style={styles.textwithline}>
31
+ {text_off}
32
+ </Text>
33
+ </TouchableOpacity>
34
+
35
+ <TouchableOpacity onPress={onPressActionOpen}>
36
+ <Text type="H4" style={styles.textwithline}>
37
+ {text_on}
38
+ </Text>
39
+ </TouchableOpacity>
40
+ </>
41
+ );
42
+ };
43
+
44
+ export default memo(OnOffSmartLockAction);
@@ -0,0 +1,11 @@
1
+ import { StyleSheet } from 'react-native';
2
+ import { Colors } from '../../configs';
3
+
4
+ export default StyleSheet.create({
5
+ textwithline: {
6
+ paddingBottom: 16,
7
+ paddingTop: 16,
8
+ borderBottomWidth: 1,
9
+ borderColor: Colors.Gray4,
10
+ },
11
+ });
@@ -9,6 +9,8 @@ import ThreeButtonAction from './ThreeButtonAction';
9
9
  import OnOffSimpleAction from './OnOffSimpleAction';
10
10
  import SelectActionCard from '../SelectActionCard';
11
11
  import { ModalCustom } from '../Modal';
12
+ import CurtainAction from './CurtainAction';
13
+ import OnOffSmartLockAction from './OnOffSmartLockAction';
12
14
 
13
15
  const ActionTemplate = memo(({ data, onSelectAction }) => {
14
16
  const t = useTranslations();
@@ -66,6 +68,22 @@ const ActionTemplate = memo(({ data, onSelectAction }) => {
66
68
  key={index}
67
69
  />
68
70
  );
71
+ case 'curtain_action_template':
72
+ return (
73
+ <CurtainAction
74
+ {...item}
75
+ onPress={onPressSelectAction}
76
+ key={index}
77
+ />
78
+ );
79
+ case 'OnOffSmartLockActionTemplate':
80
+ return (
81
+ <OnOffSmartLockAction
82
+ {...item}
83
+ onPress={onPressSelectAction}
84
+ key={index}
85
+ />
86
+ );
69
87
  }
70
88
  });
71
89
  }, [data, onPressSelectAction]);