@eohjsc/react-native-smart-city 0.4.84 → 0.4.86
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/assets/images/Notify.svg +9 -0
- package/package.json +1 -1
- package/src/commons/Automate/ItemAutomate.js +6 -1
- package/src/commons/Device/PMSensor/PMSensorIndicator.js +15 -8
- package/src/commons/Device/WaterQualitySensor/ListQualityIndicator.js +23 -15
- package/src/commons/Device/WaterQualitySensor/QualityIndicatorsItem.js +10 -9
- package/src/commons/MenuActionAddnew/index.js +6 -0
- package/src/commons/Sharing/WrapHeaderScrollable.js +1 -1
- package/src/commons/SubUnit/DeviceTemplate/ConfigValue/ConfigValue.js +2 -8
- package/src/commons/SubUnit/DeviceTemplate/EvaluationOverConfig/EvaluationOverConfig.js +2 -10
- package/src/commons/SubUnit/OneTap/ItemOneTap.js +4 -3
- package/src/commons/SubUnit/OneTap/__test__/SubUnitAutomate.test.js +14 -1
- package/src/commons/SubUnit/ShortDetail.js +14 -4
- package/src/configs/API.js +10 -0
- package/src/configs/AccessibilityLabel.js +3 -0
- package/src/navigations/UnitStack.js +10 -2
- package/src/screens/Automate/AddNewAction/SetupScriptNotify.js +92 -0
- package/src/screens/Automate/AddNewAction/Styles/SetupScriptNotifyStyles.js +57 -0
- package/src/screens/Automate/AddNewAction/__test__/SetupConfigCondition.test.js +13 -0
- package/src/screens/Automate/AddNewAction/__test__/SetupScriptNotify.test.js +84 -0
- package/src/screens/Automate/EditActionsList/__tests__/index.test.js +15 -4
- package/src/screens/Automate/EditActionsList/index.js +130 -72
- package/src/screens/Automate/ScriptDetail/Components/AddActionScript.js +168 -0
- package/src/screens/Automate/ScriptDetail/__test__/index.test.js +75 -6
- package/src/screens/Automate/ScriptDetail/index.js +147 -84
- package/src/screens/Device/__test__/mqttDetail.test.js +20 -20
- package/src/screens/Device/detail.js +1 -3
- package/src/screens/Sharing/{MemberList.js → UnitMemberList.js} +4 -4
- package/src/screens/Sharing/__test__/{MemberList.test.js → UnitMemberList.test.js} +2 -2
- package/src/screens/UnitSummary/__test__/index.test.js +2 -1
- package/src/screens/UnitSummary/components/3PPowerConsumption/__test__/3PPowerConsumption.test.js +37 -30
- package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +105 -166
- package/src/screens/UnitSummary/components/AirQuality/SegmentedRoundChart.js +32 -0
- package/src/{commons/UnitSummary → screens/UnitSummary/components}/AirQuality/__test__/index.test.js +25 -15
- package/src/{commons/UnitSummary → screens/UnitSummary/components}/AirQuality/index.js +55 -71
- package/src/{commons/UnitSummary → screens/UnitSummary/components}/AirQuality/styles.js +1 -2
- package/src/screens/UnitSummary/components/PowerConsumption/__test__/PowerConsumption.test.js +26 -20
- package/src/screens/UnitSummary/components/PowerConsumption/index.js +59 -87
- package/src/screens/UnitSummary/components/RunningDevices/index.js +27 -23
- package/src/screens/UnitSummary/components/Temperature/ItemTemperature/index.js +33 -20
- package/src/screens/UnitSummary/components/Temperature/index.js +52 -79
- package/src/screens/UnitSummary/components/UvIndex/SegmentedRoundChart.js +36 -0
- package/src/screens/UnitSummary/components/UvIndex/__test__/index.test.js +8 -0
- package/src/screens/UnitSummary/components/UvIndex/index.js +16 -72
- package/src/screens/UnitSummary/components/UvIndex/styles.js +48 -0
- package/src/screens/UnitSummary/components/WaterQuality/Item/index.js +6 -4
- package/src/screens/UnitSummary/components/WaterQuality/__test__/index.test.js +26 -12
- package/src/screens/UnitSummary/components/WaterQuality/index.js +93 -3
- package/src/screens/UnitSummary/index.js +1 -9
- package/src/utils/I18n/translations/en.js +16 -1
- package/src/utils/I18n/translations/vi.js +15 -1
- package/src/utils/Route/index.js +1 -0
- package/src/screens/UnitSummary/components/PowerConsumption/ItemPower/index.js +0 -53
- package/src/screens/UnitSummary/components/PowerConsumption/__test__/ItemPower.test.js +0 -20
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<svg width="28" height="33" viewBox="0 0 28 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M14.0003 32.6666C15.8337 32.6666 17.3337 31.1666 17.3337 29.3333H10.667C10.667 31.1666 12.1503 32.6666 14.0003 32.6666ZM24.0003 22.6666V14.3333C24.0003 9.21663 21.267 4.93329 16.5003 3.79996V2.66663C16.5003 1.28329 15.3837 0.166626 14.0003 0.166626C12.617 0.166626 11.5003 1.28329 11.5003 2.66663V3.79996C6.71699 4.93329 4.00033 9.19996 4.00033 14.3333V22.6666L0.666992 26V27.6666H27.3337V26L24.0003 22.6666Z" fill="url(#paint0_linear_2168_1847)"/>
|
|
3
|
+
<defs>
|
|
4
|
+
<linearGradient id="paint0_linear_2168_1847" x1="0.666992" y1="0.166626" x2="32.5129" y2="26.3255" gradientUnits="userSpaceOnUse">
|
|
5
|
+
<stop stop-color="#2B6B9F"/>
|
|
6
|
+
<stop offset="1" stop-color="#D5FFCB"/>
|
|
7
|
+
</linearGradient>
|
|
8
|
+
</defs>
|
|
9
|
+
</svg>
|
package/package.json
CHANGED
|
@@ -15,6 +15,7 @@ const ItemAutomate = ({
|
|
|
15
15
|
index,
|
|
16
16
|
setSelectedIndex,
|
|
17
17
|
onPress,
|
|
18
|
+
enableScript = true,
|
|
18
19
|
}) => {
|
|
19
20
|
const t = useTranslations();
|
|
20
21
|
const item = AUTOMATES[automate?.type];
|
|
@@ -57,7 +58,11 @@ const ItemAutomate = ({
|
|
|
57
58
|
<View style={styles.row}>
|
|
58
59
|
<View style={styles.wrapIcon}>{!!Icon && <Icon />}</View>
|
|
59
60
|
<View style={styles.wrapTitle}>
|
|
60
|
-
<Text
|
|
61
|
+
<Text
|
|
62
|
+
type="H4"
|
|
63
|
+
bold
|
|
64
|
+
color={enableScript ? Colors.Black : Colors.Gray7}
|
|
65
|
+
>
|
|
61
66
|
{t(item?.title)}
|
|
62
67
|
</Text>
|
|
63
68
|
<Text type="Label" color={Colors.Gray8} numberOfLines={1}>
|
|
@@ -4,25 +4,32 @@ import { FlatList } from 'react-native';
|
|
|
4
4
|
import QualityIndicatorItem from '../WaterQualitySensor/QualityIndicatorsItem';
|
|
5
5
|
import styles from './PMSensorIndicatorStyles';
|
|
6
6
|
import { keyExtractor, roundNumber } from '../../../utils/Utils';
|
|
7
|
+
import { useConfigGlobalState } from '../../../iot/states';
|
|
7
8
|
|
|
8
9
|
const PMSensorIndicator = memo(({ data = [], style, isWidgetOrder }) => {
|
|
10
|
+
const [configValues] = useConfigGlobalState('configValues');
|
|
11
|
+
|
|
9
12
|
const renderItem = useCallback(
|
|
10
13
|
({ item }) => {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
const { id, color, title, standard, evaluate, unit } = item || {};
|
|
15
|
+
const getValue =
|
|
16
|
+
configValues?.[id]?.value === undefined
|
|
17
|
+
? '--'
|
|
18
|
+
: `${roundNumber(configValues[id].value)}`;
|
|
19
|
+
|
|
14
20
|
return (
|
|
15
21
|
<QualityIndicatorItem
|
|
16
|
-
|
|
17
|
-
|
|
22
|
+
key={id?.toString()}
|
|
23
|
+
color={color}
|
|
24
|
+
standard={title || standard}
|
|
18
25
|
value={getValue}
|
|
19
|
-
evaluate={
|
|
20
|
-
measure={
|
|
26
|
+
evaluate={evaluate}
|
|
27
|
+
measure={unit}
|
|
21
28
|
style={style}
|
|
22
29
|
/>
|
|
23
30
|
);
|
|
24
31
|
},
|
|
25
|
-
[style]
|
|
32
|
+
[configValues, style]
|
|
26
33
|
);
|
|
27
34
|
|
|
28
35
|
const isScrollMode = data.length > 3;
|
|
@@ -2,25 +2,33 @@ import React, { useCallback } from 'react';
|
|
|
2
2
|
import { View, StyleSheet, FlatList } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import QualityIndicatorItem from './QualityIndicatorsItem';
|
|
5
|
+
import { useConfigGlobalState } from '../../../iot/states';
|
|
5
6
|
|
|
6
7
|
//using for Water quality sensor , power meter SENSOR, INdoor air sensor
|
|
7
8
|
const ListQualityIndicator = ({ data, style }) => {
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
const [configValues] = useConfigGlobalState('configValues');
|
|
10
|
+
const renderItem = useCallback(
|
|
11
|
+
({ item }) => {
|
|
12
|
+
const { id, measure, color, title, standard, evaluate, unit } =
|
|
13
|
+
item || {};
|
|
14
|
+
const getValue =
|
|
15
|
+
configValues?.[id]?.value === undefined
|
|
16
|
+
? '--'
|
|
17
|
+
: `${configValues[id].value} ${measure}`;
|
|
12
18
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
return (
|
|
20
|
+
<QualityIndicatorItem
|
|
21
|
+
key={id?.toString()}
|
|
22
|
+
color={color}
|
|
23
|
+
standard={title || standard}
|
|
24
|
+
value={getValue}
|
|
25
|
+
evaluate={evaluate}
|
|
26
|
+
measure={unit}
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
29
|
+
},
|
|
30
|
+
[configValues]
|
|
31
|
+
);
|
|
24
32
|
return (
|
|
25
33
|
<View style={styles.standard}>
|
|
26
34
|
<FlatList
|
|
@@ -22,14 +22,14 @@ const QualityIndicatorItem = memo(
|
|
|
22
22
|
backgroundColor: color,
|
|
23
23
|
};
|
|
24
24
|
const navigation = useNavigation();
|
|
25
|
+
const measureText =
|
|
26
|
+
measure && measure.length ? `${value} ${measure}` : `${value}`;
|
|
25
27
|
|
|
26
28
|
return (
|
|
27
29
|
<View style={[styles.container, style, color && styles.containerPadding]}>
|
|
28
30
|
<View style={[styles.line, styleColor]} />
|
|
29
31
|
<View style={styles.rowFlex}>
|
|
30
|
-
<Text
|
|
31
|
-
{standard}
|
|
32
|
-
</Text>
|
|
32
|
+
<Text style={styles.txtMeasure}>{standard}</Text>
|
|
33
33
|
{type === 'machine_status' && (
|
|
34
34
|
<TouchableOpacity
|
|
35
35
|
onPress={() => navigation.navigate(descriptionScreen)}
|
|
@@ -43,13 +43,9 @@ const QualityIndicatorItem = memo(
|
|
|
43
43
|
</TouchableOpacity>
|
|
44
44
|
)}
|
|
45
45
|
</View>
|
|
46
|
-
<Text
|
|
47
|
-
{measure && measure.length ? `${value} ${measure}` : `${value}`}
|
|
48
|
-
</Text>
|
|
46
|
+
<Text style={styles.txtValue}>{measureText}</Text>
|
|
49
47
|
{!!evaluate?.color && (
|
|
50
|
-
<Text
|
|
51
|
-
{evaluate.text}
|
|
52
|
-
</Text>
|
|
48
|
+
<Text style={styles.txtEvaluate}>{evaluate.text}</Text>
|
|
53
49
|
)}
|
|
54
50
|
</View>
|
|
55
51
|
);
|
|
@@ -82,14 +78,19 @@ const styles = StyleSheet.create({
|
|
|
82
78
|
txtMeasure: {
|
|
83
79
|
lineHeight: 22,
|
|
84
80
|
marginTop: 8,
|
|
81
|
+
fontSize: 14,
|
|
82
|
+
color: Colors.Gray8,
|
|
85
83
|
},
|
|
86
84
|
txtValue: {
|
|
87
85
|
lineHeight: 32,
|
|
88
86
|
marginTop: 16,
|
|
87
|
+
fontSize: 24,
|
|
88
|
+
color: Colors.Gray9,
|
|
89
89
|
},
|
|
90
90
|
txtEvaluate: {
|
|
91
91
|
lineHeight: 20,
|
|
92
92
|
marginTop: 8,
|
|
93
|
+
fontSize: 12,
|
|
93
94
|
},
|
|
94
95
|
iconInfo: {
|
|
95
96
|
width: 40,
|
|
@@ -6,6 +6,7 @@ import { Colors } from '../../configs';
|
|
|
6
6
|
import Text from '../Text';
|
|
7
7
|
import ImageButton from '../ImageButton';
|
|
8
8
|
import { ModalCustom } from '../Modal';
|
|
9
|
+
import packageJson from '../../../package.json';
|
|
9
10
|
|
|
10
11
|
const keyExtractor = (item) => item.id.toString();
|
|
11
12
|
const MenuActionAddnew = memo(
|
|
@@ -61,6 +62,11 @@ const MenuActionAddnew = memo(
|
|
|
61
62
|
renderItem={renderItem}
|
|
62
63
|
scrollIndicatorInsets={{ right: 1 }}
|
|
63
64
|
/>
|
|
65
|
+
<View style={styles.modalHeader}>
|
|
66
|
+
<Text
|
|
67
|
+
style={styles.modalHeaderText}
|
|
68
|
+
>{`v ${packageJson.version}`}</Text>
|
|
69
|
+
</View>
|
|
64
70
|
</View>
|
|
65
71
|
</View>
|
|
66
72
|
</ModalCustom>
|
|
@@ -1,22 +1,16 @@
|
|
|
1
|
-
import React, { memo
|
|
1
|
+
import React, { memo } from 'react';
|
|
2
2
|
import styles from '../styles/ConfigValueStyles';
|
|
3
3
|
import { Platform, View } from 'react-native';
|
|
4
4
|
import Text from '../../../Text';
|
|
5
5
|
import { useConfigGlobalState } from '../../../../iot/states';
|
|
6
|
-
import { useWatchConfigs } from '../../../../hooks/IoT';
|
|
7
6
|
import LastUpdatedText from '../../../Device/LastUpdatedText';
|
|
8
7
|
import IconComponent from '../../../IconComponent';
|
|
9
8
|
import { IconOutline } from '@ant-design/icons-react-native';
|
|
10
9
|
|
|
11
10
|
const ConfigValue = ({ device, stationItem }) => {
|
|
12
|
-
|
|
13
|
-
const [configValues, _] = useConfigGlobalState('configValues');
|
|
11
|
+
const [configValues] = useConfigGlobalState('configValues');
|
|
14
12
|
const configValue = configValues[stationItem.configuration?.config];
|
|
15
|
-
const configIds = useMemo(() => {
|
|
16
|
-
return [stationItem.configuration?.config];
|
|
17
|
-
}, [stationItem.configuration?.config]);
|
|
18
13
|
const { icon_kit, icon } = device || {};
|
|
19
|
-
useWatchConfigs(configIds);
|
|
20
14
|
|
|
21
15
|
return (
|
|
22
16
|
<>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { memo
|
|
1
|
+
import React, { memo } from 'react';
|
|
2
2
|
import styles from '../styles/ConfigValueStyles';
|
|
3
3
|
import { Platform, View } from 'react-native';
|
|
4
4
|
import Text from '../../../Text';
|
|
@@ -7,22 +7,14 @@ import {
|
|
|
7
7
|
useEvaluateValue,
|
|
8
8
|
useValueEvaluation,
|
|
9
9
|
} from '../../../../screens/Device/hooks/useEvaluateValue';
|
|
10
|
-
import { useWatchConfigs } from '../../../../hooks/IoT';
|
|
11
10
|
import LastUpdatedText from '../../../Device/LastUpdatedText';
|
|
12
11
|
import IconComponent from '../../../IconComponent';
|
|
13
12
|
import { IconOutline } from '@ant-design/icons-react-native';
|
|
14
13
|
|
|
15
14
|
export const EvaluationConfigWrapper = memo(
|
|
16
15
|
({ device, stationItem, Child }) => {
|
|
17
|
-
|
|
18
|
-
const [configValues, _] = useConfigGlobalState('configValues');
|
|
16
|
+
const [configValues] = useConfigGlobalState('configValues');
|
|
19
17
|
const configValue = configValues[stationItem.configuration?.config];
|
|
20
|
-
const configIds = useMemo(() => {
|
|
21
|
-
return [stationItem.configuration?.config];
|
|
22
|
-
}, [stationItem.configuration?.config]);
|
|
23
|
-
|
|
24
|
-
useWatchConfigs(configIds);
|
|
25
|
-
|
|
26
18
|
const valueEvaluationObject = useValueEvaluation(
|
|
27
19
|
stationItem.configuration?.config,
|
|
28
20
|
device.unit_id,
|
|
@@ -22,6 +22,7 @@ import { AccessibilityLabel, AUTOMATE_TYPE } from '../../../configs/Constants';
|
|
|
22
22
|
const ItemOneTap = memo(({ automate = {}, wrapSyles, onPressItem }) => {
|
|
23
23
|
const { navigate } = useNavigation();
|
|
24
24
|
const { id, type, script, activate_at, author = '' } = automate;
|
|
25
|
+
const { enable } = script;
|
|
25
26
|
const t = useTranslations();
|
|
26
27
|
|
|
27
28
|
const goToDetail = useCallback(() => {
|
|
@@ -69,7 +70,7 @@ const ItemOneTap = memo(({ automate = {}, wrapSyles, onPressItem }) => {
|
|
|
69
70
|
<View style={[styles.container, wrapSyles]}>
|
|
70
71
|
<View style={styles.boxIcon}>
|
|
71
72
|
{displayIcon()}
|
|
72
|
-
{type === AUTOMATE_TYPE.ONE_TAP && (
|
|
73
|
+
{type === AUTOMATE_TYPE.ONE_TAP && enable && (
|
|
73
74
|
<TouchableOpacity
|
|
74
75
|
accessibilityLabel={AccessibilityLabel.AUTOMATE_SCRIPT_ACTION}
|
|
75
76
|
onPress={handleScriptAction}
|
|
@@ -86,7 +87,7 @@ const ItemOneTap = memo(({ automate = {}, wrapSyles, onPressItem }) => {
|
|
|
86
87
|
numberOfLines={1}
|
|
87
88
|
semibold
|
|
88
89
|
size={14}
|
|
89
|
-
color={Colors.Gray9}
|
|
90
|
+
color={enable ? Colors.Gray9 : Colors.Gray}
|
|
90
91
|
type="Body"
|
|
91
92
|
style={styles.name}
|
|
92
93
|
accessibilityLabel={AccessibilityLabel.TEXT_AUTOMATE_NAME}
|
|
@@ -101,7 +102,7 @@ const ItemOneTap = memo(({ automate = {}, wrapSyles, onPressItem }) => {
|
|
|
101
102
|
numberOfLines={1}
|
|
102
103
|
semibold
|
|
103
104
|
size={12}
|
|
104
|
-
color={Colors.Gray8}
|
|
105
|
+
color={enable ? Colors.Gray8 : Colors.Gray}
|
|
105
106
|
type="Label"
|
|
106
107
|
>
|
|
107
108
|
{activateAt && t('activated_time', { time: activateAt })}
|
|
@@ -49,6 +49,19 @@ describe('test Item', () => {
|
|
|
49
49
|
name: 'Joshua Ray',
|
|
50
50
|
icon: '',
|
|
51
51
|
icon_kit: '',
|
|
52
|
+
enable: true,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: 2,
|
|
57
|
+
user: 6,
|
|
58
|
+
type: 'one_tap',
|
|
59
|
+
activate_at: '2021-09-17T05:30:00Z',
|
|
60
|
+
script: {
|
|
61
|
+
name: 'Test',
|
|
62
|
+
icon: '',
|
|
63
|
+
icon_kit: '',
|
|
64
|
+
enable: false,
|
|
52
65
|
},
|
|
53
66
|
},
|
|
54
67
|
],
|
|
@@ -89,7 +102,7 @@ describe('test Item', () => {
|
|
|
89
102
|
el.props.accessibilityLabel === AccessibilityLabel.GO_DETAIL &&
|
|
90
103
|
el.type === TouchableOpacity
|
|
91
104
|
);
|
|
92
|
-
expect(goDetail).toHaveLength(
|
|
105
|
+
expect(goDetail).toHaveLength(2);
|
|
93
106
|
await act(async () => {
|
|
94
107
|
await goDetail[0].props.onPress();
|
|
95
108
|
});
|
|
@@ -29,12 +29,22 @@ const ShortDetailSubUnit = ({ unit, station, isOwner }) => {
|
|
|
29
29
|
useDevicesStatus(unit, station?.devices);
|
|
30
30
|
|
|
31
31
|
const configsNeedWatching = useMemo(() => {
|
|
32
|
-
const configIds = []
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
const configIds = (station?.devices || []).flatMap((device) => {
|
|
33
|
+
const ids = [];
|
|
34
|
+
|
|
35
|
+
if (device?.quick_action?.config_id && device.is_managed_by_backend) {
|
|
36
|
+
ids.push(device.quick_action.config_id);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (device?.station_items?.length) {
|
|
40
|
+
ids.push(
|
|
41
|
+
...device.station_items.map((item) => item.configuration.config)
|
|
42
|
+
);
|
|
36
43
|
}
|
|
44
|
+
|
|
45
|
+
return ids;
|
|
37
46
|
});
|
|
47
|
+
|
|
38
48
|
return configIds;
|
|
39
49
|
}, [station]);
|
|
40
50
|
|
package/src/configs/API.js
CHANGED
|
@@ -87,16 +87,26 @@ const API = {
|
|
|
87
87
|
AUTOMATE: {
|
|
88
88
|
ACTION_ONE_TAP: (id) => `/property_manager/automate/${id}/action_one_tap/`,
|
|
89
89
|
SCRIPT: (id) => `/property_manager/automate/${id}/script/`,
|
|
90
|
+
SCRIPT_ITEMS: (id) => `/property_manager/automate/${id}/script_items/`,
|
|
90
91
|
ORDER_SCRIPT_ACTION: (id) =>
|
|
91
92
|
`/property_manager/automate/${id}/order_script_action/`,
|
|
93
|
+
ORDER_SCRIPT_ITEMS: (id) =>
|
|
94
|
+
`/property_manager/automate/${id}/order_script_items/`,
|
|
92
95
|
DELETE_SCRIPT_ACTION: (automateId, actionId) =>
|
|
93
96
|
`/property_manager/automate/${automateId}/script_action/${actionId}/`,
|
|
97
|
+
DELETE_SCRIPT_ITEM: (automateId, itemId) =>
|
|
98
|
+
`/property_manager/automate/${automateId}/script_item/${itemId}/`,
|
|
94
99
|
ADD_SCRIPT_ACTION: (id) =>
|
|
95
100
|
`/property_manager/automate/${id}/add_script_action/`,
|
|
101
|
+
ADD_SCRIPT_NOTIFY: (id) =>
|
|
102
|
+
`/property_manager/automate/${id}/add_script_notify/`,
|
|
103
|
+
|
|
96
104
|
FETCH_AUTOMATE: (automateId) => `/property_manager/automate/${automateId}/`,
|
|
97
105
|
CREATE_AUTOMATE: () => '/property_manager/automate/',
|
|
98
106
|
UPDATE_AUTOMATE: (automateId) =>
|
|
99
107
|
`/property_manager/automate/${automateId}/`,
|
|
108
|
+
ENABLE_SCRIPT: (automateId) =>
|
|
109
|
+
`/property_manager/automate/${automateId}/enable_script/`,
|
|
100
110
|
STAR_SCRIPT: (id) => `/property_manager/automate/${id}/star_script/`,
|
|
101
111
|
UNSTAR_SCRIPT: (id) => `/property_manager/automate/${id}/unstar_script/`,
|
|
102
112
|
GET_SMART: () => '/property_manager/automate/smart/',
|
|
@@ -241,6 +241,9 @@ export default {
|
|
|
241
241
|
ICON_MORE: 'ICON_MORE',
|
|
242
242
|
ICON_ARROW_RIGHT: 'ICON_ARROW_RIGHT',
|
|
243
243
|
TEXT_AUTOMATE_NAME: 'TEXT_AUTOMATE_NAME',
|
|
244
|
+
AUTOMATE_LIST_SCRIPT_ACTION: 'AUTOMATE_LIST_SCRIPT_ACTION',
|
|
245
|
+
AUTOMATE_TITLE_NOTIFY: 'AUTOMATE_TITLE_NOTIFY',
|
|
246
|
+
AUTOMATE_MESSAGE_NOTIFY: 'AUTOMATE_MESSAGE_NOTIFY',
|
|
244
247
|
|
|
245
248
|
// Parking input maunaly spot
|
|
246
249
|
PARKING_SPOT_INFO_BUTTON: 'PARKING_SPOT_INFO_BUTTON',
|
|
@@ -19,7 +19,7 @@ import { Action } from '../context/actionType';
|
|
|
19
19
|
import AQIGuide from '../screens/AQIGuide';
|
|
20
20
|
import DeviceDetail from '../screens/Device/detail';
|
|
21
21
|
import ChangePosition from '../screens/ChangePosition';
|
|
22
|
-
import
|
|
22
|
+
import UnitMemberList from '../screens/Sharing/UnitMemberList';
|
|
23
23
|
import ManageSubUnit from '../screens/SubUnit/ManageSubUnit';
|
|
24
24
|
import SelectAddress from '../screens/Unit/SelectAddress';
|
|
25
25
|
import ChooseLocation from '../screens/Unit/ChooseLocation';
|
|
@@ -66,6 +66,7 @@ import ChooseAction from '../screens/Automate/AddNewAction/ChooseAction';
|
|
|
66
66
|
import ScenarioName from '../screens/Automate/Scenario/ScenarioName';
|
|
67
67
|
import ValueChangeName from '../screens/Automate/ValueChange/ValueChangeName';
|
|
68
68
|
import AddAutomationTypeSmart from '../screens/Automate/AddNewAutoSmart/AddAutomationTypeSmart';
|
|
69
|
+
import SetupScriptNotify from '../screens/Automate/AddNewAction/SetupScriptNotify';
|
|
69
70
|
|
|
70
71
|
const Stack = createStackNavigator();
|
|
71
72
|
|
|
@@ -331,7 +332,7 @@ export const UnitStack = memo((props) => {
|
|
|
331
332
|
/>
|
|
332
333
|
<Stack.Screen
|
|
333
334
|
name={Route.UnitMemberList}
|
|
334
|
-
component={
|
|
335
|
+
component={UnitMemberList}
|
|
335
336
|
options={{
|
|
336
337
|
headerShown: false,
|
|
337
338
|
}}
|
|
@@ -406,6 +407,13 @@ export const UnitStack = memo((props) => {
|
|
|
406
407
|
headerShown: false,
|
|
407
408
|
}}
|
|
408
409
|
/>
|
|
410
|
+
<Stack.Screen
|
|
411
|
+
name={Route.SetupScriptNotify}
|
|
412
|
+
component={SetupScriptNotify}
|
|
413
|
+
options={{
|
|
414
|
+
headerShown: false,
|
|
415
|
+
}}
|
|
416
|
+
/>
|
|
409
417
|
<Stack.Screen
|
|
410
418
|
name={Route.AddAutomationTypeSmart}
|
|
411
419
|
component={AddAutomationTypeSmart}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import React, { useCallback, useMemo, useState } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { useNavigation } from '@react-navigation/native';
|
|
4
|
+
import styles from './Styles/SetupScriptNotifyStyles';
|
|
5
|
+
import { HeaderCustom } from '../../../commons';
|
|
6
|
+
import { useTranslations } from '../../../hooks/Common/useTranslations';
|
|
7
|
+
|
|
8
|
+
import _TextInput from '../../../commons/Form/TextInput';
|
|
9
|
+
import AccessibilityLabel from '../../../configs/AccessibilityLabel';
|
|
10
|
+
import BottomButtonView from '../../../commons/BottomButtonView';
|
|
11
|
+
import { axiosPost } from '../../../utils/Apis/axios';
|
|
12
|
+
import { API } from '../../../configs';
|
|
13
|
+
import { ToastBottomHelper } from '../../../utils/Utils';
|
|
14
|
+
import Routes from '../../../utils/Route';
|
|
15
|
+
import moment from 'moment';
|
|
16
|
+
|
|
17
|
+
const SetupScriptNotify = ({ route }) => {
|
|
18
|
+
const t = useTranslations();
|
|
19
|
+
const { goBack, navigate } = useNavigation();
|
|
20
|
+
const { automate = {}, unitId } = route?.params || {};
|
|
21
|
+
const { id: automateId } = automate;
|
|
22
|
+
const [notify, setNotify] = useState({ unit: unitId });
|
|
23
|
+
|
|
24
|
+
const onChangeTitle = (value) => {
|
|
25
|
+
setNotify((state) => ({
|
|
26
|
+
...state,
|
|
27
|
+
title: value,
|
|
28
|
+
}));
|
|
29
|
+
};
|
|
30
|
+
const onChangeMessage = (value) => {
|
|
31
|
+
setNotify((state) => ({
|
|
32
|
+
...state,
|
|
33
|
+
message: value,
|
|
34
|
+
}));
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const onNext = useCallback(async () => {
|
|
38
|
+
const { success } = await axiosPost(
|
|
39
|
+
API.AUTOMATE.ADD_SCRIPT_NOTIFY(automateId),
|
|
40
|
+
notify
|
|
41
|
+
);
|
|
42
|
+
if (success) {
|
|
43
|
+
ToastBottomHelper.success(t('text_done'));
|
|
44
|
+
navigate({
|
|
45
|
+
name: Routes.ScriptDetail,
|
|
46
|
+
merge: true,
|
|
47
|
+
params: { saveAt: moment().valueOf() },
|
|
48
|
+
});
|
|
49
|
+
} else {
|
|
50
|
+
ToastBottomHelper.error(t('text_done'));
|
|
51
|
+
}
|
|
52
|
+
}, [automateId, navigate, notify, t]);
|
|
53
|
+
|
|
54
|
+
const canSave = useMemo(() => {
|
|
55
|
+
const { title, message } = notify || {};
|
|
56
|
+
return !!title && !!message;
|
|
57
|
+
}, [notify]);
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<View style={styles.wrap}>
|
|
61
|
+
<HeaderCustom isShowClose onClose={goBack} title={t('notification')} />
|
|
62
|
+
<View style={styles.container}>
|
|
63
|
+
<_TextInput
|
|
64
|
+
placeholder={t('title_notification')}
|
|
65
|
+
onChange={onChangeTitle}
|
|
66
|
+
textInputStyle={styles.textTitle}
|
|
67
|
+
value={notify?.title}
|
|
68
|
+
accessibilityLabel={AccessibilityLabel.AUTOMATE_TITLE_NOTIFY}
|
|
69
|
+
autoFocus
|
|
70
|
+
/>
|
|
71
|
+
<_TextInput
|
|
72
|
+
placeholder={t('message_notification')}
|
|
73
|
+
onChange={onChangeMessage}
|
|
74
|
+
textInputStyle={styles.textMessage}
|
|
75
|
+
value={notify?.message}
|
|
76
|
+
accessibilityLabel={AccessibilityLabel.AUTOMATE_MESSAGE_NOTIFY}
|
|
77
|
+
multiline={true}
|
|
78
|
+
maxLength={255}
|
|
79
|
+
/>
|
|
80
|
+
|
|
81
|
+
<BottomButtonView
|
|
82
|
+
style={styles.bottomButtonView}
|
|
83
|
+
mainTitle={t('save')}
|
|
84
|
+
onPressMain={onNext}
|
|
85
|
+
typeMain={canSave ? 'primary' : 'disabled'}
|
|
86
|
+
/>
|
|
87
|
+
</View>
|
|
88
|
+
</View>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export default SetupScriptNotify;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
import { Colors } from '../../../../configs';
|
|
3
|
+
import { getBottomSpace } from 'react-native-iphone-x-helper';
|
|
4
|
+
|
|
5
|
+
export default StyleSheet.create({
|
|
6
|
+
wrap: {
|
|
7
|
+
flex: 1,
|
|
8
|
+
backgroundColor: Colors.White,
|
|
9
|
+
},
|
|
10
|
+
titleCreate: {
|
|
11
|
+
fontStyle: 'normal',
|
|
12
|
+
fontWeight: '600',
|
|
13
|
+
color: Colors.Gray9,
|
|
14
|
+
},
|
|
15
|
+
titleChoose: {
|
|
16
|
+
fontStyle: 'normal',
|
|
17
|
+
fontWeight: '400',
|
|
18
|
+
color: Colors.Gray8,
|
|
19
|
+
},
|
|
20
|
+
container: {
|
|
21
|
+
flex: 1,
|
|
22
|
+
paddingHorizontal: 16,
|
|
23
|
+
paddingTop: 10,
|
|
24
|
+
paddingBottom: getBottomSpace() + 10,
|
|
25
|
+
},
|
|
26
|
+
textTitle: {
|
|
27
|
+
borderWidth: 1,
|
|
28
|
+
borderColor: Colors.Gray4,
|
|
29
|
+
borderStyle: 'solid',
|
|
30
|
+
borderRadius: 10,
|
|
31
|
+
},
|
|
32
|
+
textMessage: {
|
|
33
|
+
height: 500,
|
|
34
|
+
borderWidth: 1,
|
|
35
|
+
borderColor: Colors.Gray4,
|
|
36
|
+
borderStyle: 'solid',
|
|
37
|
+
borderRadius: 10,
|
|
38
|
+
},
|
|
39
|
+
bottomButtonView: {
|
|
40
|
+
paddingTop: 24,
|
|
41
|
+
paddingBottom: 32,
|
|
42
|
+
|
|
43
|
+
backgroundColor: Colors.White,
|
|
44
|
+
borderColor: Colors.ShadownTransparent,
|
|
45
|
+
borderTopWidth: 1,
|
|
46
|
+
},
|
|
47
|
+
bottomButton: {
|
|
48
|
+
borderWidth: 0,
|
|
49
|
+
borderColor: Colors.Gray4,
|
|
50
|
+
paddingTop: 24,
|
|
51
|
+
paddingBottom: 24,
|
|
52
|
+
borderTopWidth: 1,
|
|
53
|
+
borderStyle: 'solid',
|
|
54
|
+
position: 'absolute',
|
|
55
|
+
bottom: 0,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
@@ -62,6 +62,7 @@ describe('Test SetupConfigCondition', () => {
|
|
|
62
62
|
sensor_type: 'air_quality',
|
|
63
63
|
value_evaluations: [
|
|
64
64
|
{
|
|
65
|
+
id: 1,
|
|
65
66
|
template: 'range',
|
|
66
67
|
configuration: {
|
|
67
68
|
ranges: [
|
|
@@ -83,6 +84,18 @@ describe('Test SetupConfigCondition', () => {
|
|
|
83
84
|
],
|
|
84
85
|
},
|
|
85
86
|
},
|
|
87
|
+
{
|
|
88
|
+
id: 2,
|
|
89
|
+
template: 'boolean',
|
|
90
|
+
configuration: {
|
|
91
|
+
on: {
|
|
92
|
+
text: 'On',
|
|
93
|
+
},
|
|
94
|
+
off: {
|
|
95
|
+
text: 'Off',
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
86
99
|
],
|
|
87
100
|
},
|
|
88
101
|
sensorData: [],
|