@eohjsc/react-native-smart-city 0.4.85 → 0.4.87
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/Action/ItemQuickAction.js +105 -124
- package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +1 -1
- package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +0 -1
- package/src/commons/ActionGroup/ThreeButtonTemplate/components/ThreeButtonDefault.js +2 -2
- package/src/commons/ActionGroup/ThreeButtonTemplate/index.js +1 -1
- package/src/commons/Automate/ItemAutomate.js +6 -1
- package/src/commons/Device/RainningSensor/CurrentRainSensor.js +1 -5
- package/src/commons/IconComponent/index.js +2 -3
- package/src/commons/MenuActionAddnew/index.js +6 -0
- package/src/commons/SubUnit/OneTap/ItemOneTap.js +4 -3
- package/src/commons/SubUnit/OneTap/__test__/SubUnitAutomate.test.js +14 -1
- package/src/configs/API.js +10 -0
- package/src/configs/AccessibilityLabel.js +3 -0
- package/src/configs/Constants.js +1 -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/Automate/ScriptDetail/utils.js +12 -11
- package/src/screens/Device/detail.js +0 -2
- package/src/screens/Notification/__test__/Notification.test.js +25 -0
- package/src/screens/Notification/components/NotificationItem.js +58 -36
- 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/utils/I18n/translations/en.js +14 -1
- package/src/utils/I18n/translations/vi.js +13 -1
- package/src/utils/Route/index.js +1 -0
|
@@ -23,6 +23,8 @@ import api from '../../../../utils/Apis/axios';
|
|
|
23
23
|
import Text from '../../../../commons/Text';
|
|
24
24
|
import { ToastBottomHelper } from '../../../../utils/Utils';
|
|
25
25
|
import { getTranslate } from '../../../../utils/I18n';
|
|
26
|
+
import AddActionScript from '../Components/AddActionScript';
|
|
27
|
+
import { Switch } from '@ant-design/react-native';
|
|
26
28
|
|
|
27
29
|
const wrapComponent = (route, storeData = {}) => (
|
|
28
30
|
<SCProvider initState={mockSCStore(storeData)}>
|
|
@@ -60,18 +62,29 @@ describe('Test ScriptDetail', () => {
|
|
|
60
62
|
sensor_id: 73,
|
|
61
63
|
value: 35,
|
|
62
64
|
},
|
|
65
|
+
script: {
|
|
66
|
+
name: 'name',
|
|
67
|
+
enable: true,
|
|
68
|
+
},
|
|
63
69
|
},
|
|
64
70
|
},
|
|
65
71
|
};
|
|
66
72
|
data = {
|
|
67
73
|
is_star: false,
|
|
68
|
-
|
|
74
|
+
script_items: [
|
|
69
75
|
{
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
76
|
+
action_script: {
|
|
77
|
+
id: 1,
|
|
78
|
+
sensor_icon_kit: 'icon',
|
|
79
|
+
station_name: 'station',
|
|
80
|
+
sensor_name: 'sensor',
|
|
81
|
+
action_name: 'action',
|
|
82
|
+
},
|
|
83
|
+
notify_script: null,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
action_script: null,
|
|
87
|
+
notify_script: { title: 'title' },
|
|
75
88
|
},
|
|
76
89
|
],
|
|
77
90
|
};
|
|
@@ -243,6 +256,7 @@ describe('Test ScriptDetail', () => {
|
|
|
243
256
|
{
|
|
244
257
|
id: 1,
|
|
245
258
|
unit: 1,
|
|
259
|
+
script_items: null,
|
|
246
260
|
},
|
|
247
261
|
];
|
|
248
262
|
mock.onGet(API.AUTOMATE.SCRIPT(1)).reply(200, data);
|
|
@@ -268,11 +282,62 @@ describe('Test ScriptDetail', () => {
|
|
|
268
282
|
await act(async () => {
|
|
269
283
|
await button.props.onPress();
|
|
270
284
|
});
|
|
285
|
+
const texts = instance.findByType(AddActionScript);
|
|
286
|
+
expect(texts.props.isVisible).toBeTruthy();
|
|
287
|
+
|
|
288
|
+
const listScriptActions = instance.findAll(
|
|
289
|
+
(el) =>
|
|
290
|
+
el.props.accessibilityLabel ===
|
|
291
|
+
AccessibilityLabel.AUTOMATE_LIST_SCRIPT_ACTION &&
|
|
292
|
+
el.type === TouchableOpacity
|
|
293
|
+
);
|
|
294
|
+
expect(listScriptActions).toHaveLength(2);
|
|
295
|
+
await act(async () => {
|
|
296
|
+
await listScriptActions[0].props.onPress();
|
|
297
|
+
});
|
|
298
|
+
|
|
271
299
|
expect(mockNavigate).toHaveBeenCalledWith(Routes.SelectControlDevices, {
|
|
272
300
|
unitId: route.params.preAutomate.unit,
|
|
273
301
|
automateId: route.params.preAutomate.id,
|
|
274
302
|
numberActionCanAdd: 2,
|
|
275
303
|
});
|
|
304
|
+
mockNavigate.mockClear();
|
|
305
|
+
await act(async () => {
|
|
306
|
+
await listScriptActions[1].props.onPress();
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
expect(mockNavigate).toHaveBeenCalledWith(Routes.SetupScriptNotify, {
|
|
310
|
+
automate: route.params.preAutomate,
|
|
311
|
+
unitId: route.params.preAutomate.unit,
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
it('test press disable script', async () => {
|
|
316
|
+
mock.onGet(API.AUTOMATE.SCRIPT(1)).reply(200, data);
|
|
317
|
+
mock.onPost(API.AUTOMATE.ENABLE_SCRIPT(1)).reply(200, data);
|
|
318
|
+
await act(async () => {
|
|
319
|
+
tree = await create(wrapComponent(route));
|
|
320
|
+
});
|
|
321
|
+
const instance = tree.root;
|
|
322
|
+
const switchButton = instance.findByType(Switch);
|
|
323
|
+
await act(async () => {
|
|
324
|
+
await switchButton.props.onChange(false);
|
|
325
|
+
});
|
|
326
|
+
const buttonAddScript = instance.findAll(
|
|
327
|
+
(el) =>
|
|
328
|
+
el.props.accessibilityLabel ===
|
|
329
|
+
AccessibilityLabel.BUTTON_ADD_SCRIPT_ACTION &&
|
|
330
|
+
el.type === TouchableOpacity
|
|
331
|
+
);
|
|
332
|
+
expect(buttonAddScript).toHaveLength(0);
|
|
333
|
+
|
|
334
|
+
const buttonEditScript = instance.findAll(
|
|
335
|
+
(el) =>
|
|
336
|
+
el.props.accessibilityLabel ===
|
|
337
|
+
AccessibilityLabel.BUTTON_EDIT_SCRIPT_ACTION &&
|
|
338
|
+
el.type === TouchableOpacity
|
|
339
|
+
);
|
|
340
|
+
expect(buttonEditScript).toHaveLength(0);
|
|
276
341
|
});
|
|
277
342
|
|
|
278
343
|
it('test press add action reach limit', async () => {
|
|
@@ -392,6 +457,10 @@ describe('Test ScriptDetail', () => {
|
|
|
392
457
|
value: 3,
|
|
393
458
|
condition: '>',
|
|
394
459
|
},
|
|
460
|
+
script: {
|
|
461
|
+
name: 'name',
|
|
462
|
+
enable: true,
|
|
463
|
+
},
|
|
395
464
|
},
|
|
396
465
|
};
|
|
397
466
|
await act(async () => {
|
|
@@ -8,7 +8,7 @@ import React, {
|
|
|
8
8
|
import { Image, Platform, TouchableOpacity, View } from 'react-native';
|
|
9
9
|
import { PopoverMode } from 'react-native-popover-view';
|
|
10
10
|
import { IconFill, IconOutline } from '@ant-design/icons-react-native';
|
|
11
|
-
import { Icon } from '@ant-design/react-native';
|
|
11
|
+
import { Icon, Switch } from '@ant-design/react-native';
|
|
12
12
|
|
|
13
13
|
import { useTranslations } from '../../../hooks/Common/useTranslations';
|
|
14
14
|
import styles from './Styles/indexStyles';
|
|
@@ -19,7 +19,8 @@ import { usePopover } from '../../../hooks/Common';
|
|
|
19
19
|
import { useStarredScript } from './hooks/useStarredScript';
|
|
20
20
|
import MenuActionMore from '../../../commons/MenuActionMore';
|
|
21
21
|
import Add from '../../../../assets/images/Add.svg';
|
|
22
|
-
import
|
|
22
|
+
import Notify from '../../../../assets/images/Notify.svg';
|
|
23
|
+
import { useNavigation } from '@react-navigation/native';
|
|
23
24
|
import { axiosGet, axiosPost } from '../../../utils/Apis/axios';
|
|
24
25
|
import Routes from '../../../utils/Route';
|
|
25
26
|
import { ToastBottomHelper } from '../../../utils/Utils';
|
|
@@ -31,6 +32,7 @@ import DeleteScript from './Components/DeleteScript';
|
|
|
31
32
|
import Images from '../../../configs/Images';
|
|
32
33
|
import { useBackendPermission } from '../../../utils/Permission/backend';
|
|
33
34
|
import IconComponent from '../../../commons/IconComponent';
|
|
35
|
+
import AddActionScript from './Components/AddActionScript';
|
|
34
36
|
|
|
35
37
|
const PreventDoubleTouch = withPreventDoubleClick(TouchableOpacity);
|
|
36
38
|
|
|
@@ -48,26 +50,29 @@ const ScriptDetail = ({ route }) => {
|
|
|
48
50
|
newAutomate, // updated automate data
|
|
49
51
|
newActionsList, // updated actions list
|
|
50
52
|
} = params;
|
|
51
|
-
|
|
52
53
|
const [automate, setAutomate] = useState(preAutomate);
|
|
53
54
|
const [data, setData] = useState([]);
|
|
54
55
|
const [isShowRename, setIsShowRename] = useState(false);
|
|
55
56
|
const [isShowDelete, setIsShowDelete] = useState(false);
|
|
57
|
+
const [isShowAddAction, setIsShowAddAction] = useState(false);
|
|
56
58
|
|
|
59
|
+
const { script, type, name, unit, can_edit, id: automateId } = automate;
|
|
60
|
+
const { enable } = script || {};
|
|
61
|
+
const [enableScript, setEnableScript] = useState(enable);
|
|
57
62
|
const onShowActivityLog = useCallback(() => {
|
|
58
63
|
navigate(Routes.ActivityLog, {
|
|
59
64
|
id: id,
|
|
60
65
|
type:
|
|
61
|
-
|
|
66
|
+
type === AUTOMATE_TYPE.ONE_TAP
|
|
62
67
|
? `automate.${AUTOMATE_TYPE.ONE_TAP}`
|
|
63
68
|
: 'automate',
|
|
64
|
-
share:
|
|
69
|
+
share: unit,
|
|
65
70
|
filterEnabled: {
|
|
66
71
|
date: true,
|
|
67
|
-
user: Boolean(
|
|
72
|
+
user: Boolean(unit),
|
|
68
73
|
},
|
|
69
74
|
});
|
|
70
|
-
}, [navigate, id,
|
|
75
|
+
}, [navigate, id, type, unit]);
|
|
71
76
|
|
|
72
77
|
const listMenuItem = useMemo(
|
|
73
78
|
() => [
|
|
@@ -85,14 +90,14 @@ const ScriptDetail = ({ route }) => {
|
|
|
85
90
|
);
|
|
86
91
|
|
|
87
92
|
const handleShowMenuAction = useCallback(() => {
|
|
88
|
-
if (!
|
|
93
|
+
if (!can_edit) {
|
|
89
94
|
ToastBottomHelper.error(
|
|
90
95
|
t('only_owner_has_permission_to_edit_this_script')
|
|
91
96
|
);
|
|
92
97
|
return;
|
|
93
98
|
}
|
|
94
99
|
showPopoverWithRef(refMenuAction);
|
|
95
|
-
}, [
|
|
100
|
+
}, [can_edit, showPopoverWithRef, t]);
|
|
96
101
|
|
|
97
102
|
const onItemClick = useCallback((item) => {
|
|
98
103
|
item.doAction();
|
|
@@ -100,9 +105,11 @@ const ScriptDetail = ({ route }) => {
|
|
|
100
105
|
|
|
101
106
|
const fetchAutomateActions = useCallback(async () => {
|
|
102
107
|
const { success, data: automateData } = await axiosGet(
|
|
103
|
-
API.AUTOMATE.
|
|
108
|
+
API.AUTOMATE.SCRIPT_ITEMS(id)
|
|
104
109
|
);
|
|
105
|
-
|
|
110
|
+
if (success) {
|
|
111
|
+
setData(automateData.script_items || []);
|
|
112
|
+
}
|
|
106
113
|
}, [id]);
|
|
107
114
|
|
|
108
115
|
const fetchAutomate = useCallback(async () => {
|
|
@@ -130,17 +137,35 @@ const ScriptDetail = ({ route }) => {
|
|
|
130
137
|
}, [id, t]);
|
|
131
138
|
|
|
132
139
|
const handleUpdateAutomate = useCallback(async () => {
|
|
133
|
-
if (!
|
|
140
|
+
if (!can_edit) {
|
|
134
141
|
ToastBottomHelper.error(
|
|
135
142
|
t('only_owner_has_permission_to_edit_this_script')
|
|
136
143
|
);
|
|
137
144
|
return;
|
|
138
145
|
}
|
|
146
|
+
if (!enableScript) {
|
|
147
|
+
ToastBottomHelper.error(t('this_script_has_been_disabled'));
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
139
150
|
navigate(Routes.AddUnknownTypeSmart, {
|
|
140
151
|
automate,
|
|
141
152
|
closeScreen: route.name,
|
|
142
153
|
});
|
|
143
|
-
}, [automate, navigate, route.name, t]);
|
|
154
|
+
}, [automate, can_edit, enableScript, navigate, route.name, t]);
|
|
155
|
+
|
|
156
|
+
const onChangeSwitch = useCallback(
|
|
157
|
+
async (checked) => {
|
|
158
|
+
setEnableScript(checked);
|
|
159
|
+
const { success } = await axiosPost(
|
|
160
|
+
API.AUTOMATE.ENABLE_SCRIPT(automateId),
|
|
161
|
+
{
|
|
162
|
+
enable: checked,
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
success && setEnableScript(checked);
|
|
166
|
+
},
|
|
167
|
+
[automateId]
|
|
168
|
+
);
|
|
144
169
|
|
|
145
170
|
useEffect(() => {
|
|
146
171
|
fetchAutomate();
|
|
@@ -183,17 +208,27 @@ const ScriptDetail = ({ route }) => {
|
|
|
183
208
|
return (
|
|
184
209
|
<View style={styles.wrap}>
|
|
185
210
|
<WrapHeaderScrollable
|
|
186
|
-
title={
|
|
211
|
+
title={name}
|
|
187
212
|
headerAniStyle={styles.headerAniStyle}
|
|
188
213
|
rightComponent={rightComponent}
|
|
189
214
|
onGoBack={goBack}
|
|
190
215
|
>
|
|
191
216
|
<View style={styles.wrapContent}>
|
|
217
|
+
<View style={styles.row}>
|
|
218
|
+
<Text type="H3" semibold>
|
|
219
|
+
{t('enable_this_script')}
|
|
220
|
+
</Text>
|
|
221
|
+
<Switch checked={enableScript} onChange={onChangeSwitch} />
|
|
222
|
+
</View>
|
|
192
223
|
<Text type="H3" semibold>
|
|
193
224
|
{t('how_to_start')}
|
|
194
225
|
</Text>
|
|
195
|
-
<ItemAutomate
|
|
196
|
-
|
|
226
|
+
<ItemAutomate
|
|
227
|
+
automate={automate}
|
|
228
|
+
enableScript={enableScript}
|
|
229
|
+
onPress={handleUpdateAutomate}
|
|
230
|
+
/>
|
|
231
|
+
{type === AUTOMATE_TYPE.ONE_TAP && enableScript && (
|
|
197
232
|
<TouchableOpacity
|
|
198
233
|
onPress={handleScriptAction}
|
|
199
234
|
style={styles.activeButton}
|
|
@@ -207,7 +242,7 @@ const ScriptDetail = ({ route }) => {
|
|
|
207
242
|
<Text type="H3" color={Colors.Gray9} semibold>
|
|
208
243
|
{t('active_list')}
|
|
209
244
|
</Text>
|
|
210
|
-
{data.length > 0 && !!
|
|
245
|
+
{data.length > 0 && !!can_edit && !!enableScript && (
|
|
211
246
|
<TouchableOpacity
|
|
212
247
|
onPress={onPressEdit}
|
|
213
248
|
style={styles.editButton}
|
|
@@ -222,10 +257,20 @@ const ScriptDetail = ({ route }) => {
|
|
|
222
257
|
)}
|
|
223
258
|
</View>
|
|
224
259
|
{data.map((item, index) => (
|
|
225
|
-
<Item
|
|
260
|
+
<Item
|
|
261
|
+
key={item?.id}
|
|
262
|
+
item={item}
|
|
263
|
+
index={index}
|
|
264
|
+
enableScript={enableScript}
|
|
265
|
+
t={t}
|
|
266
|
+
/>
|
|
226
267
|
))}
|
|
227
|
-
{!!
|
|
228
|
-
<ItemAdd
|
|
268
|
+
{!!can_edit && !!enableScript && (
|
|
269
|
+
<ItemAdd
|
|
270
|
+
automate={automate}
|
|
271
|
+
numberActionAdded={data.length}
|
|
272
|
+
setIsShowAddAction={setIsShowAddAction}
|
|
273
|
+
/>
|
|
229
274
|
)}
|
|
230
275
|
</View>
|
|
231
276
|
</WrapHeaderScrollable>
|
|
@@ -241,6 +286,12 @@ const ScriptDetail = ({ route }) => {
|
|
|
241
286
|
Platform.OS === 'ios' ? PopoverMode.JS_MODAL : PopoverMode.RN_MODAL
|
|
242
287
|
}
|
|
243
288
|
/>
|
|
289
|
+
<AddActionScript
|
|
290
|
+
automate={automate}
|
|
291
|
+
numberActionAdded={data.length}
|
|
292
|
+
isVisible={isShowAddAction}
|
|
293
|
+
setIsVisible={setIsShowAddAction}
|
|
294
|
+
/>
|
|
244
295
|
<RenameScript
|
|
245
296
|
automate={automate}
|
|
246
297
|
setAutomate={setAutomate}
|
|
@@ -256,95 +307,107 @@ const ScriptDetail = ({ route }) => {
|
|
|
256
307
|
);
|
|
257
308
|
};
|
|
258
309
|
|
|
259
|
-
const Item = ({ item, index }) => {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
310
|
+
const Item = ({ item, index, enableScript, t }) => {
|
|
311
|
+
const color = enableScript ? Colors.Gray9 : Colors.Gray7;
|
|
312
|
+
const paddedIndex = (index + 1).toString().padStart(2, '0');
|
|
313
|
+
const { action_script, notify_script } = item;
|
|
314
|
+
if (action_script) {
|
|
315
|
+
const {
|
|
316
|
+
sensor_icon_kit,
|
|
317
|
+
unit_name,
|
|
318
|
+
station_name,
|
|
319
|
+
sensor_name,
|
|
320
|
+
action_name,
|
|
321
|
+
} = action_script;
|
|
322
|
+
return (
|
|
323
|
+
<View style={styles.wrapItem}>
|
|
324
|
+
<View style={styles.leftItem}>
|
|
325
|
+
<Text color={color} type="H4" semibold>
|
|
326
|
+
{paddedIndex}
|
|
327
|
+
</Text>
|
|
328
|
+
</View>
|
|
329
|
+
<View style={styles.rightItem}>
|
|
330
|
+
<IconComponent icon={sensor_icon_kit} style={styles.iconEndDevice} />
|
|
331
|
+
<View style={styles.contentItem}>
|
|
332
|
+
<View style={styles.titleItem}>
|
|
333
|
+
<Text
|
|
334
|
+
numberOfLines={1}
|
|
335
|
+
semibold
|
|
336
|
+
type="Label"
|
|
337
|
+
color={Colors.Gray7}
|
|
338
|
+
style={styles.paddingRight4}
|
|
339
|
+
>
|
|
340
|
+
{unit_name}
|
|
341
|
+
</Text>
|
|
342
|
+
<Text
|
|
343
|
+
numberOfLines={1}
|
|
344
|
+
type="Label"
|
|
345
|
+
color={Colors.Gray7}
|
|
346
|
+
style={styles.flex1}
|
|
347
|
+
>
|
|
348
|
+
{station_name}
|
|
349
|
+
</Text>
|
|
350
|
+
</View>
|
|
351
|
+
<Text numberOfLines={1} type="H4" color={color} semibold>
|
|
352
|
+
{sensor_name}
|
|
282
353
|
</Text>
|
|
283
|
-
<Text
|
|
284
|
-
|
|
285
|
-
type="Label"
|
|
286
|
-
color={Colors.Gray7}
|
|
287
|
-
style={styles.flex1}
|
|
288
|
-
>
|
|
289
|
-
{item?.station_name}
|
|
354
|
+
<Text numberOfLines={1} type="H4" color={color}>
|
|
355
|
+
{action_name}
|
|
290
356
|
</Text>
|
|
291
357
|
</View>
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
358
|
+
</View>
|
|
359
|
+
</View>
|
|
360
|
+
);
|
|
361
|
+
} else if (notify_script) {
|
|
362
|
+
const { title } = notify_script;
|
|
363
|
+
return (
|
|
364
|
+
<View style={styles.wrapItem}>
|
|
365
|
+
<View style={styles.leftItem}>
|
|
366
|
+
<Text color={color} type="H4" semibold>
|
|
367
|
+
{paddedIndex}
|
|
297
368
|
</Text>
|
|
298
369
|
</View>
|
|
370
|
+
<View style={styles.rightItem}>
|
|
371
|
+
<Notify style={styles.iconEndDevice} />
|
|
372
|
+
<View style={styles.contentItem}>
|
|
373
|
+
<Text numberOfLines={1} type="H4" color={color} semibold>
|
|
374
|
+
{t('send_notification')}
|
|
375
|
+
</Text>
|
|
376
|
+
<Text numberOfLines={1} type="H4" color={color}>
|
|
377
|
+
{title}
|
|
378
|
+
</Text>
|
|
379
|
+
</View>
|
|
380
|
+
</View>
|
|
299
381
|
</View>
|
|
300
|
-
|
|
301
|
-
|
|
382
|
+
);
|
|
383
|
+
}
|
|
302
384
|
};
|
|
303
385
|
|
|
304
|
-
const ItemAdd = ({ automate, numberActionAdded }) => {
|
|
386
|
+
const ItemAdd = ({ automate, numberActionAdded, setIsShowAddAction }) => {
|
|
305
387
|
const t = useTranslations();
|
|
306
|
-
const { navigate } = useNavigation();
|
|
307
388
|
const permissions = useBackendPermission();
|
|
308
|
-
const {
|
|
389
|
+
const { max_actions_per_automation } = permissions || {};
|
|
390
|
+
const paddedIndex = (numberActionAdded + 1).toString().padStart(2, '0');
|
|
309
391
|
|
|
310
392
|
const onPressAddAction = useCallback(() => {
|
|
311
|
-
if (numberActionAdded >=
|
|
393
|
+
if (numberActionAdded >= max_actions_per_automation) {
|
|
312
394
|
ToastBottomHelper.error(
|
|
313
395
|
t('reach_max_actions_per_automation', {
|
|
314
|
-
length:
|
|
396
|
+
length: max_actions_per_automation,
|
|
315
397
|
}),
|
|
316
398
|
'',
|
|
317
399
|
7000
|
|
318
400
|
);
|
|
319
401
|
return;
|
|
320
402
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
automateId: automate.id,
|
|
324
|
-
closeScreen: currentScreenName,
|
|
325
|
-
numberActionCanAdd:
|
|
326
|
-
permissions?.max_actions_per_automation - numberActionAdded,
|
|
327
|
-
};
|
|
328
|
-
|
|
329
|
-
navigate(
|
|
330
|
-
automate.unit ? Routes.SelectControlDevices : Routes.SelectUnit,
|
|
331
|
-
navParams
|
|
332
|
-
);
|
|
333
|
-
}, [
|
|
334
|
-
numberActionAdded,
|
|
335
|
-
permissions?.max_actions_per_automation,
|
|
336
|
-
automate.unit,
|
|
337
|
-
automate.id,
|
|
338
|
-
currentScreenName,
|
|
339
|
-
navigate,
|
|
340
|
-
t,
|
|
341
|
-
]);
|
|
403
|
+
setIsShowAddAction(true);
|
|
404
|
+
}, [numberActionAdded, max_actions_per_automation, setIsShowAddAction, t]);
|
|
342
405
|
|
|
343
406
|
return (
|
|
344
407
|
<View style={styles.wrapItem}>
|
|
345
408
|
<View style={styles.leftItemAdd}>
|
|
346
409
|
<Text style={styles.number} type="H4" semibold color={Colors.Gray7}>
|
|
347
|
-
{
|
|
410
|
+
{paddedIndex}
|
|
348
411
|
</Text>
|
|
349
412
|
</View>
|
|
350
413
|
<TouchableOpacity
|
|
@@ -22,12 +22,14 @@ export const generateAutomationDataConditionText = (
|
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
export const getAutomationData = (automate) => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return
|
|
29
|
-
} else if (
|
|
30
|
-
return
|
|
25
|
+
const { type, event_sensor, event_action, schedule, event, value_change } =
|
|
26
|
+
automate;
|
|
27
|
+
if ([AUTOMATE_TYPE.VALUE_CHANGE].includes(type)) {
|
|
28
|
+
return value_change || event_sensor;
|
|
29
|
+
} else if (type === AUTOMATE_TYPE.SCHEDULE) {
|
|
30
|
+
return schedule;
|
|
31
|
+
} else if ([AUTOMATE_TYPE.EVENT].includes(type)) {
|
|
32
|
+
return event || event_action || event_sensor;
|
|
31
33
|
}
|
|
32
34
|
return null;
|
|
33
35
|
};
|
|
@@ -58,8 +60,7 @@ const generateAutomationConditionValueEvaluation = (
|
|
|
58
60
|
}
|
|
59
61
|
let textEvent = '';
|
|
60
62
|
if (config_name) {
|
|
61
|
-
|
|
62
|
-
textEvent = `${config_name} - ${t(stateConditionData?.stateValue[value])}`;
|
|
63
|
+
textEvent = config_name;
|
|
63
64
|
} else {
|
|
64
65
|
textEvent = `${end_device_name} - ${action}`;
|
|
65
66
|
}
|
|
@@ -75,8 +76,8 @@ export const generateAutomationConditionText = (
|
|
|
75
76
|
if (!automateData) {
|
|
76
77
|
return;
|
|
77
78
|
}
|
|
78
|
-
|
|
79
|
-
if ([AUTOMATE_TYPE.VALUE_CHANGE].includes(
|
|
79
|
+
const { type } = automate;
|
|
80
|
+
if ([AUTOMATE_TYPE.VALUE_CHANGE].includes(type)) {
|
|
80
81
|
const { condition, config_name, value } = automateData;
|
|
81
82
|
if (condition === 'value_evaluation') {
|
|
82
83
|
return generateAutomationConditionValueEvaluation(
|
|
@@ -95,7 +96,7 @@ export const generateAutomationConditionText = (
|
|
|
95
96
|
text = 'equal';
|
|
96
97
|
}
|
|
97
98
|
return `${config_name} ${t(text)} ${value}`;
|
|
98
|
-
} else if (
|
|
99
|
+
} else if (type === AUTOMATE_TYPE.SCHEDULE) {
|
|
99
100
|
const { repeat, time_repeat, date_repeat, weekday_repeat } = automateData;
|
|
100
101
|
const time =
|
|
101
102
|
time_repeat?.length >= 8
|
|
@@ -603,9 +603,7 @@ const DeviceDetail = ({ route }) => {
|
|
|
603
603
|
sensor?.is_managed_by_backend &&
|
|
604
604
|
sensor?.device_type !== DEVICE_TYPE.LG_THINQ
|
|
605
605
|
) {
|
|
606
|
-
const updateInterval = setInterval(() => fetchValues(), 5000);
|
|
607
606
|
fetchValues();
|
|
608
|
-
return () => clearInterval(updateInterval);
|
|
609
607
|
} else {
|
|
610
608
|
Object.keys(sensor).length > 1 &&
|
|
611
609
|
setLoading((preState) => ({ ...preState, isConnected: false }));
|
|
@@ -13,6 +13,7 @@ import api from '../../../utils/Apis/axios';
|
|
|
13
13
|
import { WrapHeaderScrollable } from '../../../commons';
|
|
14
14
|
|
|
15
15
|
import { getPusher } from '../../../utils/Pusher';
|
|
16
|
+
import { NOTIFICATION_TYPES } from '../../../configs/Constants';
|
|
16
17
|
|
|
17
18
|
const wrapComponent = () => (
|
|
18
19
|
<SCProvider initState={mockSCStore({})}>
|
|
@@ -164,4 +165,28 @@ describe('test Notification', () => {
|
|
|
164
165
|
});
|
|
165
166
|
expect(getPusher().unsubscribe).toBeCalledWith('private-user-1');
|
|
166
167
|
});
|
|
168
|
+
it('test render trigger script notification', async () => {
|
|
169
|
+
const response = {
|
|
170
|
+
results: [
|
|
171
|
+
{
|
|
172
|
+
content_code: NOTIFICATION_TYPES.TRIGGER_SCRIPT_NOTIFY,
|
|
173
|
+
created_at: '2021-10-07T08:57:09.370286Z',
|
|
174
|
+
id: 12905,
|
|
175
|
+
is_read: true,
|
|
176
|
+
params: "{'unit_id': 1, 'content': 'EoH Office'}",
|
|
177
|
+
type: 'NEWS',
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
};
|
|
181
|
+
mock
|
|
182
|
+
.onGet(API.NOTIFICATION.LIST_EOH_NOTIFICATIONS(1, ''))
|
|
183
|
+
.reply(200, response);
|
|
184
|
+
await act(async () => {
|
|
185
|
+
tree = await create(wrapComponent());
|
|
186
|
+
});
|
|
187
|
+
const instance = tree.root;
|
|
188
|
+
const notificationItem = instance.findAllByType(NotificationItem);
|
|
189
|
+
|
|
190
|
+
expect(notificationItem).toHaveLength(1);
|
|
191
|
+
});
|
|
167
192
|
});
|