@eohjsc/react-native-smart-city 0.5.5 → 0.5.7-rc1
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 +2 -1
- package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +27 -3
- package/src/commons/ActionGroup/OnOffTemplate/index.js +47 -32
- package/src/commons/ActionGroup/__test__/index.test.js +40 -1
- package/src/commons/ActionTemplate/OnOffButtonAction.js +8 -2
- package/src/commons/ActionTemplate/OneButtonAction.js +5 -1
- package/src/configs/API.js +6 -0
- package/src/configs/AccessibilityLabel.js +7 -0
- package/src/configs/Constants.js +5 -0
- package/src/navigations/UnitStack.js +6 -0
- package/src/screens/Automate/AddNewAction/ChooseAction.js +1 -89
- package/src/screens/Automate/AddNewAction/NewActionWrapper.js +10 -2
- package/src/screens/Automate/AddNewAction/RenderActionItem.js +92 -0
- package/src/screens/Automate/AddNewAction/SetupConfigCondition.js +23 -11
- package/src/screens/Automate/AddNewAction/SetupScriptDelay.js +2 -2
- package/src/screens/Automate/AddNewAction/Styles/SetupSensorStyles.js +3 -3
- package/src/screens/Automate/AddNewAction/__test__/SetupConfigCondition.test.js +10 -17
- package/src/screens/Automate/EditActionsList/Styles/indexStyles.js +32 -6
- package/src/screens/Automate/EditActionsList/UpdateActionScript.js +141 -0
- package/src/screens/Automate/EditActionsList/UpdateDelayScript.js +94 -0
- package/src/screens/Automate/EditActionsList/UpdateNotifyScript.js +115 -0
- package/src/screens/Automate/EditActionsList/__tests__/UpdateActionScript.test.js +174 -0
- package/src/screens/Automate/EditActionsList/__tests__/UpdateDelayScript.test.js +119 -0
- package/src/screens/Automate/EditActionsList/__tests__/UpdateNotifyScript.test.js +138 -0
- package/src/screens/Automate/EditActionsList/__tests__/index.test.js +121 -50
- package/src/screens/Automate/EditActionsList/index.js +276 -167
- package/src/screens/Automate/ScriptDetail/index.js +11 -6
- package/src/screens/ChangePosition/index.js +1 -1
- package/src/screens/ChangePosition/styles.js +4 -0
- package/src/utils/I18n/translations/en.js +17 -4
- package/src/utils/I18n/translations/vi.js +17 -4
- package/src/utils/Route/index.js +2 -0
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.
|
|
4
|
+
"version": "0.5.7-rc1",
|
|
5
5
|
"description": "TODO",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"files": [
|
|
@@ -161,6 +161,7 @@
|
|
|
161
161
|
"react-native-bootsplash": "^2.2.5",
|
|
162
162
|
"react-native-calendars": "^1.1266.0",
|
|
163
163
|
"react-native-chart-kit": "^6.5.0",
|
|
164
|
+
"react-native-charts-wrapper": "^0.6.0",
|
|
164
165
|
"react-native-credit-card-input": "^0.4.1",
|
|
165
166
|
"react-native-crypto-aes-cbc": "^1.1.1",
|
|
166
167
|
"react-native-dash": "^0.0.11",
|
|
@@ -4,11 +4,19 @@ import React, { memo, useMemo } from 'react';
|
|
|
4
4
|
import { TouchableOpacity, View } from 'react-native';
|
|
5
5
|
import { Colors } from '../../../configs';
|
|
6
6
|
import styles from './OnOffButtonTemplateStyle';
|
|
7
|
-
import { AccessibilityLabel } from '../../../configs/Constants';
|
|
7
|
+
import { AccessibilityLabel, BUTTON_TYPE } from '../../../configs/Constants';
|
|
8
8
|
import IconComponent from '../../IconComponent';
|
|
9
9
|
|
|
10
10
|
const OnOffButtonTemplate = memo(
|
|
11
|
-
({
|
|
11
|
+
({
|
|
12
|
+
isOn,
|
|
13
|
+
triggerAction,
|
|
14
|
+
triggerOnAction,
|
|
15
|
+
triggerOffAction,
|
|
16
|
+
actionGroup = {},
|
|
17
|
+
isLight = false,
|
|
18
|
+
item,
|
|
19
|
+
}) => {
|
|
12
20
|
const {
|
|
13
21
|
icon_on,
|
|
14
22
|
icon_off,
|
|
@@ -16,7 +24,9 @@ const OnOffButtonTemplate = memo(
|
|
|
16
24
|
icon_kit_off_data,
|
|
17
25
|
text_on,
|
|
18
26
|
text_off,
|
|
27
|
+
button_type,
|
|
19
28
|
} = actionGroup;
|
|
29
|
+
|
|
20
30
|
const icon = useMemo(() => {
|
|
21
31
|
if (isOn) {
|
|
22
32
|
return icon_kit_on_data?.icon || icon_on;
|
|
@@ -24,12 +34,26 @@ const OnOffButtonTemplate = memo(
|
|
|
24
34
|
return icon_kit_off_data?.icon || icon_off;
|
|
25
35
|
}, [isOn, icon_on, icon_off, icon_kit_on_data, icon_kit_off_data]);
|
|
26
36
|
|
|
37
|
+
const attrs = useMemo(() => {
|
|
38
|
+
if (button_type === BUTTON_TYPE.PUSH_BUTTON) {
|
|
39
|
+
return {
|
|
40
|
+
onPressIn: triggerOnAction,
|
|
41
|
+
onPressOut: triggerOffAction,
|
|
42
|
+
activeOpacity: 0.7,
|
|
43
|
+
};
|
|
44
|
+
} else {
|
|
45
|
+
return {
|
|
46
|
+
onPress: triggerAction,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}, [button_type, triggerAction, triggerOffAction, triggerOnAction]);
|
|
50
|
+
|
|
27
51
|
return (
|
|
28
52
|
<>
|
|
29
53
|
<View style={styles.barrierControlContainer}>
|
|
30
54
|
<TouchableOpacity
|
|
31
55
|
style={styles.bigCircle}
|
|
32
|
-
|
|
56
|
+
{...attrs}
|
|
33
57
|
accessibilityLabel={`${AccessibilityLabel.ON_OFF_BUTTON}-${item?.id}`}
|
|
34
58
|
>
|
|
35
59
|
<View style={styles.smallCircle}>
|
|
@@ -50,40 +50,53 @@ const OnOffTemplate = memo(({ item = {}, doAction, sensor = {} }) => {
|
|
|
50
50
|
|
|
51
51
|
const [isOn, setIsOn] = useState(false);
|
|
52
52
|
|
|
53
|
+
const realTrigger = useCallback(
|
|
54
|
+
async (action_data, config_value) => {
|
|
55
|
+
if (!action_data) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
let data;
|
|
59
|
+
if (
|
|
60
|
+
allow_config_store_value &&
|
|
61
|
+
config &&
|
|
62
|
+
device_type !== DEVICE_TYPE.GOOGLE_HOME
|
|
63
|
+
) {
|
|
64
|
+
data = {
|
|
65
|
+
config_id: config,
|
|
66
|
+
config_value: config_value,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
await doAction(action_data, data);
|
|
70
|
+
if (
|
|
71
|
+
is_managed_by_backend &&
|
|
72
|
+
config &&
|
|
73
|
+
device_type === DEVICE_TYPE.LG_THINQ
|
|
74
|
+
) {
|
|
75
|
+
watchMultiConfigs([config]);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
[
|
|
79
|
+
allow_config_store_value,
|
|
80
|
+
config,
|
|
81
|
+
device_type,
|
|
82
|
+
doAction,
|
|
83
|
+
is_managed_by_backend,
|
|
84
|
+
]
|
|
85
|
+
);
|
|
86
|
+
|
|
53
87
|
const triggerAction = useCallback(async () => {
|
|
54
88
|
const action_data = isOn ? action_off_data : action_on_data;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
config_value: isOn ? 0 : 1,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
await doAction(action_data, data);
|
|
70
|
-
if (
|
|
71
|
-
is_managed_by_backend &&
|
|
72
|
-
config &&
|
|
73
|
-
device_type === DEVICE_TYPE.LG_THINQ
|
|
74
|
-
) {
|
|
75
|
-
watchMultiConfigs([config]);
|
|
76
|
-
}
|
|
77
|
-
}, [
|
|
78
|
-
isOn,
|
|
79
|
-
action_off_data,
|
|
80
|
-
action_on_data,
|
|
81
|
-
allow_config_store_value,
|
|
82
|
-
config,
|
|
83
|
-
device_type,
|
|
84
|
-
doAction,
|
|
85
|
-
is_managed_by_backend,
|
|
86
|
-
]);
|
|
89
|
+
const config_value = isOn ? 0 : 1;
|
|
90
|
+
realTrigger(action_data, config_value);
|
|
91
|
+
}, [isOn, action_off_data, action_on_data, realTrigger]);
|
|
92
|
+
|
|
93
|
+
const triggerOnAction = useCallback(async () => {
|
|
94
|
+
realTrigger(action_on_data, 1);
|
|
95
|
+
}, [action_on_data, realTrigger]);
|
|
96
|
+
|
|
97
|
+
const triggerOffAction = useCallback(async () => {
|
|
98
|
+
realTrigger(action_off_data, 0);
|
|
99
|
+
}, [action_off_data, realTrigger]);
|
|
87
100
|
|
|
88
101
|
useUnwatchLGDeviceConfigControl(sensor, [config]);
|
|
89
102
|
|
|
@@ -100,6 +113,8 @@ const OnOffTemplate = memo(({ item = {}, doAction, sensor = {} }) => {
|
|
|
100
113
|
<Component
|
|
101
114
|
isOn={isOn}
|
|
102
115
|
triggerAction={triggerAction}
|
|
116
|
+
triggerOnAction={triggerOnAction}
|
|
117
|
+
triggerOffAction={triggerOffAction}
|
|
103
118
|
actionGroup={configuration}
|
|
104
119
|
disabled={!action_on_data && !action_off_data}
|
|
105
120
|
item={item}
|
|
@@ -11,7 +11,7 @@ import moment from 'moment';
|
|
|
11
11
|
|
|
12
12
|
import ActionGroup from '..';
|
|
13
13
|
import Text from '../../Text';
|
|
14
|
-
import { AccessibilityLabel } from '../../../configs/Constants';
|
|
14
|
+
import { AccessibilityLabel, BUTTON_TYPE } from '../../../configs/Constants';
|
|
15
15
|
import { SCProvider } from '../../../context';
|
|
16
16
|
import { mockSCStore } from '../../../context/mockStore';
|
|
17
17
|
import { Slider } from '@miblanchard/react-native-slider';
|
|
@@ -347,6 +347,45 @@ describe('Test ActionGroup', () => {
|
|
|
347
347
|
expect(mockDoAction).toHaveBeenCalledTimes(1);
|
|
348
348
|
});
|
|
349
349
|
|
|
350
|
+
it('render ActionGroup on_off_button_action_template button type push button', async () => {
|
|
351
|
+
const mockDoAction = jest.fn();
|
|
352
|
+
const actionGroup = {
|
|
353
|
+
template: 'on_off_button_action_template',
|
|
354
|
+
configuration: {
|
|
355
|
+
action_on_data: 'action_on_data',
|
|
356
|
+
action_off_data: 'action_off_data',
|
|
357
|
+
icon_on: 'caret-up',
|
|
358
|
+
text_on: 'ON',
|
|
359
|
+
icon_off: 'caret-up',
|
|
360
|
+
text_off: 'OFF',
|
|
361
|
+
button_type: BUTTON_TYPE.PUSH_BUTTON,
|
|
362
|
+
},
|
|
363
|
+
title: 'Power',
|
|
364
|
+
};
|
|
365
|
+
await act(async () => {
|
|
366
|
+
wrapper = renderer.create(
|
|
367
|
+
wrapComponent(actionGroup, mockDoAction, sensor)
|
|
368
|
+
);
|
|
369
|
+
});
|
|
370
|
+
const instance = wrapper.root;
|
|
371
|
+
const buttons = instance.findAllByType(TouchableOpacity);
|
|
372
|
+
expect(buttons.length).toEqual(1);
|
|
373
|
+
await act(async () => {
|
|
374
|
+
buttons[0].props.onPressIn();
|
|
375
|
+
});
|
|
376
|
+
expect(mockDoAction).toHaveBeenCalledWith(
|
|
377
|
+
actionGroup.configuration.action_on_data,
|
|
378
|
+
undefined
|
|
379
|
+
);
|
|
380
|
+
await act(async () => {
|
|
381
|
+
buttons[0].props.onPressOut();
|
|
382
|
+
});
|
|
383
|
+
expect(mockDoAction).toHaveBeenCalledWith(
|
|
384
|
+
actionGroup.configuration.action_off_data,
|
|
385
|
+
undefined
|
|
386
|
+
);
|
|
387
|
+
});
|
|
388
|
+
|
|
350
389
|
it('render ActionGroup NumberUpDownActionTemplate watch config value null', async () => {
|
|
351
390
|
const mockDoAction = jest.fn();
|
|
352
391
|
const actionGroup = {
|
|
@@ -30,7 +30,10 @@ const OnOffButtonAction = ({ title, configuration, onPress, template }) => {
|
|
|
30
30
|
|
|
31
31
|
return (
|
|
32
32
|
<>
|
|
33
|
-
<TouchableOpacity
|
|
33
|
+
<TouchableOpacity
|
|
34
|
+
onPress={onPressActionOn}
|
|
35
|
+
accessibilityLabel={AccessibilityLabel.ON_BUTTON}
|
|
36
|
+
>
|
|
34
37
|
<Text
|
|
35
38
|
type="H4"
|
|
36
39
|
style={styles.textWithLine}
|
|
@@ -39,7 +42,10 @@ const OnOffButtonAction = ({ title, configuration, onPress, template }) => {
|
|
|
39
42
|
{title} {text_on}
|
|
40
43
|
</Text>
|
|
41
44
|
</TouchableOpacity>
|
|
42
|
-
<TouchableOpacity
|
|
45
|
+
<TouchableOpacity
|
|
46
|
+
onPress={onPressActionOff}
|
|
47
|
+
accessibilityLabel={AccessibilityLabel.OFF_BUTTON}
|
|
48
|
+
>
|
|
43
49
|
<Text
|
|
44
50
|
type="H4"
|
|
45
51
|
style={styles.textWithLine}
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { TouchableOpacity } from 'react-native';
|
|
3
3
|
import Text from '../Text';
|
|
4
4
|
import styles from './OneButtonActionStyles';
|
|
5
|
+
import AccessibilityLabel from '../../configs/AccessibilityLabel';
|
|
5
6
|
|
|
6
7
|
const OneButtonAction = ({ configuration, onPress, template }) => {
|
|
7
8
|
const { text, action } = configuration;
|
|
@@ -16,7 +17,10 @@ const OneButtonAction = ({ configuration, onPress, template }) => {
|
|
|
16
17
|
|
|
17
18
|
return (
|
|
18
19
|
<>
|
|
19
|
-
<TouchableOpacity
|
|
20
|
+
<TouchableOpacity
|
|
21
|
+
onPress={onPressAction}
|
|
22
|
+
accessibilityLabel={AccessibilityLabel.ONE_BUTTON}
|
|
23
|
+
>
|
|
20
24
|
<Text type="H4" style={styles.textWithLine}>
|
|
21
25
|
{text}
|
|
22
26
|
</Text>
|
package/src/configs/API.js
CHANGED
|
@@ -97,6 +97,12 @@ const API = {
|
|
|
97
97
|
`/property_manager/automate/${automateId}/script_action/${actionId}/`,
|
|
98
98
|
DELETE_SCRIPT_ITEM: (automateId, itemId) =>
|
|
99
99
|
`/property_manager/automate/${automateId}/script_item/${itemId}/`,
|
|
100
|
+
UPDATE_SCRIPT_DELAY: (automateId) =>
|
|
101
|
+
`/property_manager/automate/${automateId}/update_script_delay/`,
|
|
102
|
+
UPDATE_SCRIPT_NOTIFY: (automateId) =>
|
|
103
|
+
`/property_manager/automate/${automateId}/update_script_notify/`,
|
|
104
|
+
UPDATE_SCRIPT_ACTION: (automateId) =>
|
|
105
|
+
`/property_manager/automate/${automateId}/update_script_action/`,
|
|
100
106
|
ADD_SCRIPT_ACTION: (id) =>
|
|
101
107
|
`/property_manager/automate/${id}/add_script_action/`,
|
|
102
108
|
ADD_SCRIPT_NOTIFY: (id) =>
|
|
@@ -287,6 +287,9 @@ export default {
|
|
|
287
287
|
BUTTON_TEMPLATE_3: 'BUTTON_TEMPLATE_3',
|
|
288
288
|
TEXT_DOOR_LOOK_ON_OFF: 'TEXT_DOOR_LOOK_ON_OFF',
|
|
289
289
|
BUTTON_ON_OFF: 'BUTTON_ON_OFF',
|
|
290
|
+
ONE_BUTTON: 'ONE_BUTTON',
|
|
291
|
+
ON_BUTTON: 'ON_BUTTON',
|
|
292
|
+
OFF_BUTTON: 'OFF_BUTTON',
|
|
290
293
|
|
|
291
294
|
// Device Detail
|
|
292
295
|
DEVICE_DETAIL_MEDIA_PLAYER: 'DEVICE_DETAIL_MEDIA_PLAYER',
|
|
@@ -681,6 +684,10 @@ export default {
|
|
|
681
684
|
BUTTON_CANCEL_EDIT_ACTION_LIST: 'BUTTON_CANCEL_EDIT_ACTION_LIST',
|
|
682
685
|
BUTTON_SAVE_EDIT_ACTION_LIST: 'BUTTON_SAVE_EDIT_ACTION_LIST',
|
|
683
686
|
BUTTON_REMOVE_EDIT_ACTION_LIST: 'BUTTON_REMOVE_EDIT_ACTION_LIST',
|
|
687
|
+
BUTTON_UPDATE_SCRIPT_ITEM: 'BUTTON_UPDATE_SCRIPT_ITEM',
|
|
688
|
+
SCRIPT_ITEM: 'SCRIPT_ITEM',
|
|
689
|
+
MODAL_CUSTOM: 'MODAL_CUSTOM',
|
|
690
|
+
BUTTON_UPDATE: 'BUTTON_UPDATE',
|
|
684
691
|
// GATEWAY
|
|
685
692
|
LIST_GATEWAY: 'LIST_GATEWAY',
|
|
686
693
|
GATEWAY_INFO_ALERT: 'GATEWAY_INFO_ALERT',
|
package/src/configs/Constants.js
CHANGED
|
@@ -68,6 +68,7 @@ import ValueChangeName from '../screens/Automate/ValueChange/ValueChangeName';
|
|
|
68
68
|
import AddAutomationTypeSmart from '../screens/Automate/AddNewAutoSmart/AddAutomationTypeSmart';
|
|
69
69
|
import SetupScriptNotify from '../screens/Automate/AddNewAction/SetupScriptNotify';
|
|
70
70
|
import SetupScriptDelay from '../screens/Automate/AddNewAction/SetupScriptDelay';
|
|
71
|
+
import UpdateActionScript from '../screens/Automate/EditActionsList/UpdateActionScript';
|
|
71
72
|
|
|
72
73
|
const Stack = createStackNavigator();
|
|
73
74
|
|
|
@@ -487,6 +488,11 @@ export const UnitStack = memo((props) => {
|
|
|
487
488
|
component={ChooseAction}
|
|
488
489
|
options={{ headerShown: false }}
|
|
489
490
|
/>
|
|
491
|
+
<Stack.Screen
|
|
492
|
+
name={Route.UpdateActionScript}
|
|
493
|
+
component={UpdateActionScript}
|
|
494
|
+
options={{ headerShown: false }}
|
|
495
|
+
/>
|
|
490
496
|
<Stack.Screen
|
|
491
497
|
name={Route.SetSchedule}
|
|
492
498
|
component={SetSchedule}
|
|
@@ -3,100 +3,13 @@ import { View } from 'react-native';
|
|
|
3
3
|
import { useNavigation } from '@react-navigation/native';
|
|
4
4
|
|
|
5
5
|
import { useTranslations } from '../../../hooks/Common/useTranslations';
|
|
6
|
-
import ActionTemplate from '../../../commons/ActionTemplate';
|
|
7
|
-
import NumberUpDownActionTemplate from '../../../commons/OneTapTemplate/NumberUpDownActionTemplate';
|
|
8
|
-
import OptionsDropdownActionTemplate from '../../../commons/OneTapTemplate/OptionsDropdownActionTemplate';
|
|
9
|
-
import StatesGridActionTemplate from '../../../commons/OneTapTemplate/StatesGridActionTemplate';
|
|
10
6
|
import { axiosGet, axiosPost } from '../../../utils/Apis/axios';
|
|
11
7
|
import { API } from '../../../configs';
|
|
12
8
|
import Routes from '../../../utils/Route';
|
|
13
9
|
import NewActionWrapper from './NewActionWrapper';
|
|
14
10
|
import moment from 'moment';
|
|
15
11
|
import { ToastBottomHelper } from '../../../utils/Utils';
|
|
16
|
-
import
|
|
17
|
-
import SliderRangeActionTemplate from '../../../commons/OneTapTemplate/SliderRangeActionTemplate';
|
|
18
|
-
import TerminalBoxActionTemplate from '../../../commons/OneTapTemplate/TerminalBoxActionTemplate';
|
|
19
|
-
|
|
20
|
-
const RenderActionItem = ({ device, item, handleOnSelectAction, index, t }) => {
|
|
21
|
-
item.index = index;
|
|
22
|
-
switch (item.template) {
|
|
23
|
-
case 'on_off_button_action_template':
|
|
24
|
-
case 'one_button_action_template':
|
|
25
|
-
case 'three_button_action_template':
|
|
26
|
-
case 'OnOffSimpleActionTemplate':
|
|
27
|
-
case 'curtain_action_template':
|
|
28
|
-
case 'OnOffSmartLockActionTemplate':
|
|
29
|
-
case 'switch_button_action_template':
|
|
30
|
-
return (
|
|
31
|
-
<ActionTemplate
|
|
32
|
-
device={device}
|
|
33
|
-
item={item}
|
|
34
|
-
onSelectAction={handleOnSelectAction}
|
|
35
|
-
/>
|
|
36
|
-
);
|
|
37
|
-
case 'OptionsDropdownActionTemplate':
|
|
38
|
-
return (
|
|
39
|
-
<OptionsDropdownActionTemplate
|
|
40
|
-
key={item.id}
|
|
41
|
-
device={device}
|
|
42
|
-
item={item}
|
|
43
|
-
onSelectAction={handleOnSelectAction}
|
|
44
|
-
/>
|
|
45
|
-
);
|
|
46
|
-
case 'NumberUpDownActionTemplate':
|
|
47
|
-
return (
|
|
48
|
-
<NumberUpDownActionTemplate
|
|
49
|
-
key={item.id}
|
|
50
|
-
device={device}
|
|
51
|
-
item={item}
|
|
52
|
-
onSelectAction={handleOnSelectAction}
|
|
53
|
-
/>
|
|
54
|
-
);
|
|
55
|
-
case 'StatesGridActionTemplate':
|
|
56
|
-
return (
|
|
57
|
-
<StatesGridActionTemplate
|
|
58
|
-
key={item.id}
|
|
59
|
-
device={device}
|
|
60
|
-
item={item}
|
|
61
|
-
onSelectAction={handleOnSelectAction}
|
|
62
|
-
/>
|
|
63
|
-
);
|
|
64
|
-
case 'slider_range_template':
|
|
65
|
-
return (
|
|
66
|
-
<SliderRangeActionTemplate
|
|
67
|
-
key={item.id}
|
|
68
|
-
device={device}
|
|
69
|
-
item={item}
|
|
70
|
-
onSelectAction={handleOnSelectAction}
|
|
71
|
-
/>
|
|
72
|
-
);
|
|
73
|
-
case 'TextBoxTemplate':
|
|
74
|
-
return (
|
|
75
|
-
<TextBoxActionTemplate
|
|
76
|
-
key={item.id}
|
|
77
|
-
device={device}
|
|
78
|
-
item={item}
|
|
79
|
-
onSelectAction={handleOnSelectAction}
|
|
80
|
-
/>
|
|
81
|
-
);
|
|
82
|
-
case 'TerminalBoxTemplate':
|
|
83
|
-
return (
|
|
84
|
-
<TerminalBoxActionTemplate
|
|
85
|
-
key={item.id}
|
|
86
|
-
device={device}
|
|
87
|
-
item={item}
|
|
88
|
-
onSelectAction={handleOnSelectAction}
|
|
89
|
-
/>
|
|
90
|
-
);
|
|
91
|
-
default:
|
|
92
|
-
ToastBottomHelper.error(
|
|
93
|
-
t('template_not_supported', { template: item.template }),
|
|
94
|
-
'',
|
|
95
|
-
3000
|
|
96
|
-
);
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
};
|
|
12
|
+
import RenderActionItem from './RenderActionItem';
|
|
100
13
|
|
|
101
14
|
const ChooseAction = ({ route }) => {
|
|
102
15
|
const t = useTranslations();
|
|
@@ -171,7 +84,6 @@ const ChooseAction = ({ route }) => {
|
|
|
171
84
|
canNext={actions.length}
|
|
172
85
|
onNext={onSave}
|
|
173
86
|
nextTitle={t('save')}
|
|
174
|
-
title={t('choose_action')}
|
|
175
87
|
name={t('set_up {name}', { name: device?.name })}
|
|
176
88
|
>
|
|
177
89
|
<View>
|
|
@@ -8,9 +8,16 @@ import { Colors } from '../../../configs';
|
|
|
8
8
|
import { useNavigation, useRoute } from '@react-navigation/native';
|
|
9
9
|
import BottomButtonView from '../../../commons/BottomButtonView';
|
|
10
10
|
import { AccessibilityLabel } from '../../../configs/Constants';
|
|
11
|
-
import { HeaderCustom } from '../../../commons';
|
|
11
|
+
import { FullLoading, HeaderCustom } from '../../../commons';
|
|
12
12
|
|
|
13
|
-
const NewActionWrapper = ({
|
|
13
|
+
const NewActionWrapper = ({
|
|
14
|
+
name,
|
|
15
|
+
children,
|
|
16
|
+
canNext,
|
|
17
|
+
onNext,
|
|
18
|
+
nextTitle,
|
|
19
|
+
showLoading,
|
|
20
|
+
}) => {
|
|
14
21
|
const hasNext =
|
|
15
22
|
canNext !== undefined || onNext !== undefined || nextTitle !== undefined;
|
|
16
23
|
const { navigate } = useNavigation();
|
|
@@ -43,6 +50,7 @@ const NewActionWrapper = ({ name, children, canNext, onNext, nextTitle }) => {
|
|
|
43
50
|
isShowSeparator
|
|
44
51
|
wrapTitleStyle={styles.wrapTitleStyle}
|
|
45
52
|
/>
|
|
53
|
+
{showLoading && <FullLoading />}
|
|
46
54
|
<KeyboardAwareScrollView contentContainerStyle={styles.scroll}>
|
|
47
55
|
{children}
|
|
48
56
|
</KeyboardAwareScrollView>
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import React, { memo } from 'react';
|
|
2
|
+
import OptionsDropdownActionTemplate from '../../../commons/OneTapTemplate/OptionsDropdownActionTemplate';
|
|
3
|
+
import NumberUpDownActionTemplate from '../../../commons/OneTapTemplate/NumberUpDownActionTemplate';
|
|
4
|
+
import StatesGridActionTemplate from '../../../commons/OneTapTemplate/StatesGridActionTemplate';
|
|
5
|
+
import SliderRangeActionTemplate from '../../../commons/OneTapTemplate/SliderRangeActionTemplate';
|
|
6
|
+
import TextBoxActionTemplate from '../../../commons/OneTapTemplate/TextBoxActionTemplate';
|
|
7
|
+
import TerminalBoxActionTemplate from '../../../commons/OneTapTemplate/TerminalBoxActionTemplate';
|
|
8
|
+
import { ToastBottomHelper } from '../../../utils/Utils';
|
|
9
|
+
import ActionTemplate from '../../../commons/ActionTemplate';
|
|
10
|
+
|
|
11
|
+
const RenderActionItem = ({ device, item, handleOnSelectAction, index, t }) => {
|
|
12
|
+
item.index = index;
|
|
13
|
+
switch (item.template) {
|
|
14
|
+
case 'on_off_button_action_template':
|
|
15
|
+
case 'one_button_action_template':
|
|
16
|
+
case 'three_button_action_template':
|
|
17
|
+
case 'OnOffSimpleActionTemplate':
|
|
18
|
+
case 'curtain_action_template':
|
|
19
|
+
case 'OnOffSmartLockActionTemplate':
|
|
20
|
+
case 'switch_button_action_template':
|
|
21
|
+
return (
|
|
22
|
+
<ActionTemplate
|
|
23
|
+
device={device}
|
|
24
|
+
item={item}
|
|
25
|
+
onSelectAction={handleOnSelectAction}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
28
|
+
case 'OptionsDropdownActionTemplate':
|
|
29
|
+
return (
|
|
30
|
+
<OptionsDropdownActionTemplate
|
|
31
|
+
key={item.id}
|
|
32
|
+
device={device}
|
|
33
|
+
item={item}
|
|
34
|
+
onSelectAction={handleOnSelectAction}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
case 'NumberUpDownActionTemplate':
|
|
38
|
+
return (
|
|
39
|
+
<NumberUpDownActionTemplate
|
|
40
|
+
key={item.id}
|
|
41
|
+
device={device}
|
|
42
|
+
item={item}
|
|
43
|
+
onSelectAction={handleOnSelectAction}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
case 'StatesGridActionTemplate':
|
|
47
|
+
return (
|
|
48
|
+
<StatesGridActionTemplate
|
|
49
|
+
key={item.id}
|
|
50
|
+
device={device}
|
|
51
|
+
item={item}
|
|
52
|
+
onSelectAction={handleOnSelectAction}
|
|
53
|
+
/>
|
|
54
|
+
);
|
|
55
|
+
case 'slider_range_template':
|
|
56
|
+
return (
|
|
57
|
+
<SliderRangeActionTemplate
|
|
58
|
+
key={item.id}
|
|
59
|
+
device={device}
|
|
60
|
+
item={item}
|
|
61
|
+
onSelectAction={handleOnSelectAction}
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
case 'TextBoxTemplate':
|
|
65
|
+
return (
|
|
66
|
+
<TextBoxActionTemplate
|
|
67
|
+
key={item.id}
|
|
68
|
+
device={device}
|
|
69
|
+
item={item}
|
|
70
|
+
onSelectAction={handleOnSelectAction}
|
|
71
|
+
/>
|
|
72
|
+
);
|
|
73
|
+
case 'TerminalBoxTemplate':
|
|
74
|
+
return (
|
|
75
|
+
<TerminalBoxActionTemplate
|
|
76
|
+
key={item.id}
|
|
77
|
+
device={device}
|
|
78
|
+
item={item}
|
|
79
|
+
onSelectAction={handleOnSelectAction}
|
|
80
|
+
/>
|
|
81
|
+
);
|
|
82
|
+
default:
|
|
83
|
+
ToastBottomHelper.error(
|
|
84
|
+
t('template_not_supported', { template: item.template }),
|
|
85
|
+
'',
|
|
86
|
+
3000
|
|
87
|
+
);
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export default memo(RenderActionItem);
|
|
@@ -17,11 +17,10 @@ import Routes from '../../../utils/Route';
|
|
|
17
17
|
import ModalCustom from '../../../commons/Modal/ModalCustom';
|
|
18
18
|
import { ToastBottomHelper } from '../../../utils/Utils';
|
|
19
19
|
|
|
20
|
-
const valueEvaluationToOptions = (valueEvaluation
|
|
20
|
+
const valueEvaluationToOptions = (valueEvaluation) => {
|
|
21
21
|
if (valueEvaluation.template === 'range') {
|
|
22
22
|
return valueEvaluation.configuration.ranges.map((range, index) => ({
|
|
23
|
-
|
|
24
|
-
title: `${range.evaluate?.text} (${range.start} ${range.start_condition} "${config.name}" ${range.end_condition} ${range.end})`,
|
|
23
|
+
title: range.evaluate?.text,
|
|
25
24
|
condition: 'value_evaluation',
|
|
26
25
|
value: [valueEvaluation.id, index],
|
|
27
26
|
}));
|
|
@@ -29,12 +28,12 @@ const valueEvaluationToOptions = (valueEvaluation, config, t) => {
|
|
|
29
28
|
if (valueEvaluation.template === 'boolean') {
|
|
30
29
|
return [
|
|
31
30
|
{
|
|
32
|
-
title:
|
|
31
|
+
title: valueEvaluation.configuration?.off?.text,
|
|
33
32
|
condition: 'value_evaluation',
|
|
34
33
|
value: [valueEvaluation.id, 0],
|
|
35
34
|
},
|
|
36
35
|
{
|
|
37
|
-
title:
|
|
36
|
+
title: valueEvaluation.configuration?.on?.text,
|
|
38
37
|
condition: 'value_evaluation',
|
|
39
38
|
value: [valueEvaluation.id, 1],
|
|
40
39
|
},
|
|
@@ -70,15 +69,17 @@ const SetupConfigCondition = () => {
|
|
|
70
69
|
if (config?.value_evaluations?.length) {
|
|
71
70
|
const options = [];
|
|
72
71
|
config.value_evaluations.forEach((valueEvaluation) => {
|
|
73
|
-
options.push(...valueEvaluationToOptions(valueEvaluation
|
|
72
|
+
options.push(...valueEvaluationToOptions(valueEvaluation));
|
|
74
73
|
});
|
|
75
74
|
return options;
|
|
76
75
|
}
|
|
77
76
|
|
|
78
77
|
return [];
|
|
79
|
-
}, [config
|
|
78
|
+
}, [config?.value_evaluations]);
|
|
79
|
+
|
|
80
80
|
const setupCustomCondition = () => {
|
|
81
81
|
setSelectedCondition('custom');
|
|
82
|
+
automate.value = null;
|
|
82
83
|
setIsShowModal(true);
|
|
83
84
|
};
|
|
84
85
|
|
|
@@ -92,6 +93,13 @@ const SetupConfigCondition = () => {
|
|
|
92
93
|
});
|
|
93
94
|
};
|
|
94
95
|
|
|
96
|
+
const resetCustomizeCondition = () => {
|
|
97
|
+
automate.condition = null;
|
|
98
|
+
automate.value = null;
|
|
99
|
+
setCustomCondition(undefined);
|
|
100
|
+
setIsShowModal(false);
|
|
101
|
+
};
|
|
102
|
+
|
|
95
103
|
return (
|
|
96
104
|
<NewActionWrapper name={t('set_up {name}', { name: config?.name })}>
|
|
97
105
|
<View style={styles.boxDevices}>
|
|
@@ -121,7 +129,7 @@ const SetupConfigCondition = () => {
|
|
|
121
129
|
</GridItem>
|
|
122
130
|
</View>
|
|
123
131
|
<ModalCustom
|
|
124
|
-
onBackdropPress={() =>
|
|
132
|
+
onBackdropPress={() => resetCustomizeCondition()}
|
|
125
133
|
isVisible={isShowModal}
|
|
126
134
|
style={styles.modal}
|
|
127
135
|
>
|
|
@@ -145,7 +153,7 @@ const SetupConfigCondition = () => {
|
|
|
145
153
|
);
|
|
146
154
|
})}
|
|
147
155
|
</List>
|
|
148
|
-
<List renderHeader={t('value')}>
|
|
156
|
+
<List renderHeader={t('value')} style={styles.inputValue}>
|
|
149
157
|
<InputItem
|
|
150
158
|
keyboardType="decimal-pad"
|
|
151
159
|
type="number"
|
|
@@ -160,8 +168,12 @@ const SetupConfigCondition = () => {
|
|
|
160
168
|
<AntButton
|
|
161
169
|
type={'primary'}
|
|
162
170
|
onPress={() => {
|
|
163
|
-
if (
|
|
164
|
-
|
|
171
|
+
if (
|
|
172
|
+
!automate.value ||
|
|
173
|
+
automate.condition === 'value_evaluation'
|
|
174
|
+
) {
|
|
175
|
+
ToastBottomHelper.error(t('please_enter_a_number'), '', 3000);
|
|
176
|
+
return;
|
|
165
177
|
}
|
|
166
178
|
setIsShowModal(false);
|
|
167
179
|
navigate(Routes.ValueChangeName, { automate, closeScreen });
|
|
@@ -21,7 +21,7 @@ const SetupScriptDelay = ({ route }) => {
|
|
|
21
21
|
const { id: automateId } = automate;
|
|
22
22
|
const [delay, setDelay] = useState();
|
|
23
23
|
|
|
24
|
-
const
|
|
24
|
+
const onChangeDelay = (value) => {
|
|
25
25
|
setDelay(value);
|
|
26
26
|
};
|
|
27
27
|
|
|
@@ -63,7 +63,7 @@ const SetupScriptDelay = ({ route }) => {
|
|
|
63
63
|
keyboardType="numeric"
|
|
64
64
|
textInputStyle={styles.inputNumber}
|
|
65
65
|
value={delay}
|
|
66
|
-
onChange={
|
|
66
|
+
onChange={onChangeDelay}
|
|
67
67
|
maxLength={4}
|
|
68
68
|
accessibilityLabel={AccessibilityLabel.AUTOMATE_INPUT_DELAY}
|
|
69
69
|
autoFocus
|