@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.
Files changed (32) hide show
  1. package/package.json +2 -1
  2. package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +27 -3
  3. package/src/commons/ActionGroup/OnOffTemplate/index.js +47 -32
  4. package/src/commons/ActionGroup/__test__/index.test.js +40 -1
  5. package/src/commons/ActionTemplate/OnOffButtonAction.js +8 -2
  6. package/src/commons/ActionTemplate/OneButtonAction.js +5 -1
  7. package/src/configs/API.js +6 -0
  8. package/src/configs/AccessibilityLabel.js +7 -0
  9. package/src/configs/Constants.js +5 -0
  10. package/src/navigations/UnitStack.js +6 -0
  11. package/src/screens/Automate/AddNewAction/ChooseAction.js +1 -89
  12. package/src/screens/Automate/AddNewAction/NewActionWrapper.js +10 -2
  13. package/src/screens/Automate/AddNewAction/RenderActionItem.js +92 -0
  14. package/src/screens/Automate/AddNewAction/SetupConfigCondition.js +23 -11
  15. package/src/screens/Automate/AddNewAction/SetupScriptDelay.js +2 -2
  16. package/src/screens/Automate/AddNewAction/Styles/SetupSensorStyles.js +3 -3
  17. package/src/screens/Automate/AddNewAction/__test__/SetupConfigCondition.test.js +10 -17
  18. package/src/screens/Automate/EditActionsList/Styles/indexStyles.js +32 -6
  19. package/src/screens/Automate/EditActionsList/UpdateActionScript.js +141 -0
  20. package/src/screens/Automate/EditActionsList/UpdateDelayScript.js +94 -0
  21. package/src/screens/Automate/EditActionsList/UpdateNotifyScript.js +115 -0
  22. package/src/screens/Automate/EditActionsList/__tests__/UpdateActionScript.test.js +174 -0
  23. package/src/screens/Automate/EditActionsList/__tests__/UpdateDelayScript.test.js +119 -0
  24. package/src/screens/Automate/EditActionsList/__tests__/UpdateNotifyScript.test.js +138 -0
  25. package/src/screens/Automate/EditActionsList/__tests__/index.test.js +121 -50
  26. package/src/screens/Automate/EditActionsList/index.js +276 -167
  27. package/src/screens/Automate/ScriptDetail/index.js +11 -6
  28. package/src/screens/ChangePosition/index.js +1 -1
  29. package/src/screens/ChangePosition/styles.js +4 -0
  30. package/src/utils/I18n/translations/en.js +17 -4
  31. package/src/utils/I18n/translations/vi.js +17 -4
  32. package/src/utils/Route/index.js +2 -0
@@ -1,4 +1,4 @@
1
- import React, { memo, useState, useCallback } from 'react';
1
+ import React, { useState, useCallback, useMemo, useEffect } from 'react';
2
2
  import { View, TouchableOpacity } from 'react-native';
3
3
  import DraggableFlatList from 'react-native-draggable-flatlist';
4
4
  import { useNavigation, useRoute } from '@react-navigation/native';
@@ -15,35 +15,43 @@ import Notify from '../../../../assets/images/Notify.svg';
15
15
  import Delay from '../../../../assets/images/Delay.svg';
16
16
  import Close from '../../../../assets/images/Close.svg';
17
17
  import { axiosDelete, axiosPut } from '../../../utils/Apis/axios';
18
- import { ModalBottom } from '../../../commons/Modal';
18
+ import { ModalBottom, ModalCustom } from '../../../commons/Modal';
19
19
  import { ToastBottomHelper } from '../../../utils/Utils';
20
20
  import { AccessibilityLabel } from '../../../configs/Constants';
21
21
  import Routes from '../../../utils/Route';
22
+ import UpdateDelayScript from './UpdateDelayScript';
23
+ import UpdateNotifyScript from './UpdateNotifyScript';
24
+ import { FullLoading } from '../../../commons';
22
25
 
23
- const EditActionsList = memo(() => {
26
+ const EditActionsList = () => {
24
27
  const t = useTranslations();
25
28
  const { navigate } = useNavigation();
26
29
  const { params = {} } = useRoute() || {};
27
- const { data = [], id, unit } = params;
30
+ const { data, id, unitId } = params;
28
31
  const [itemRemove, setItemRemove] = useState({});
29
32
  const [isVisible, setIsVisible] = useState(false);
30
- const [actionsList, setActionList] = useState(data);
33
+ const [actionsList, setActionList] = useState([]);
34
+ const [showPopupUpdate, setShowPopupUpdate] = useState(false);
35
+ const [scriptItem, setScriptItem] = useState({});
36
+ const [updateIndex, setUpdateIndex] = useState();
37
+ const [needRefresh, setNeedRefresh] = useState(false);
38
+ const [processing, setProcessing] = useState(false);
39
+ const onClosePopup = () => setShowPopupUpdate(false);
31
40
 
32
- const onPressSave = useCallback(async () => {
33
- const { success } = await axiosPut(API.AUTOMATE.ORDER_SCRIPT_ITEMS(id), {
34
- id_script_items: actionsList.map((i) => i.id),
35
- });
36
- if (success) {
37
- ToastBottomHelper.success(t('text_done'));
38
- navigate({
39
- name: Routes.ScriptDetail,
40
- merge: true,
41
- params: {
42
- newActionsList: actionsList,
43
- },
41
+ useEffect(() => {
42
+ setActionList(data);
43
+ }, [data]);
44
+
45
+ const onPressSave = useCallback(
46
+ async (dragData) => {
47
+ const { success } = await axiosPut(API.AUTOMATE.ORDER_SCRIPT_ITEMS(id), {
48
+ id_script_items: dragData.map((i) => i.id),
44
49
  });
45
- }
46
- }, [actionsList, id, navigate, t]);
50
+ success && ToastBottomHelper.success(t('updated_action_order'));
51
+ setProcessing(false);
52
+ },
53
+ [id, t]
54
+ );
47
55
 
48
56
  const onCancel = useCallback(() => {
49
57
  navigate({
@@ -79,6 +87,12 @@ const EditActionsList = memo(() => {
79
87
  // eslint-disable-next-line react-hooks/exhaustive-deps
80
88
  }, [id, itemRemove, actionsList]);
81
89
 
90
+ const onShowPopupUpdate = useCallback((item, index) => {
91
+ setShowPopupUpdate(true);
92
+ setScriptItem(item);
93
+ setUpdateIndex(index);
94
+ }, []);
95
+
82
96
  const CommonItem = ({
83
97
  paddedIndex,
84
98
  icon,
@@ -86,19 +100,27 @@ const EditActionsList = memo(() => {
86
100
  onPress,
87
101
  isActive,
88
102
  drag,
103
+ onPressUpdate,
89
104
  }) => (
90
- <TouchableOpacity
91
- style={[styles.wrapItem, isActive ? styles.isDragging : {}]}
92
- onPressIn={drag}
93
- disabled={isActive}
94
- >
95
- <View style={styles.leftItem}>
96
- <Text color={Colors.Gray9} type="H4" semibold>
97
- {paddedIndex}
98
- </Text>
99
- <Rearrange />
100
- </View>
101
- <View style={styles.rightItem}>
105
+ <View style={[styles.wrapItem, isActive ? styles.isDragging : {}]}>
106
+ <TouchableOpacity
107
+ onPressIn={drag}
108
+ disabled={isActive}
109
+ accessibilityLabel={AccessibilityLabel.SCRIPT_ITEM}
110
+ >
111
+ <View style={styles.leftItem}>
112
+ <Text color={Colors.Gray9} type="H4" semibold>
113
+ {paddedIndex}
114
+ </Text>
115
+ <Rearrange />
116
+ </View>
117
+ </TouchableOpacity>
118
+ <TouchableOpacity
119
+ style={styles.rightItem}
120
+ delayLongPress={1100}
121
+ onLongPress={onPressUpdate}
122
+ accessibilityLabel={AccessibilityLabel.BUTTON_UPDATE}
123
+ >
102
124
  {icon}
103
125
  <View style={styles.contentItem}>{content}</View>
104
126
  <TouchableOpacity
@@ -108,109 +130,228 @@ const EditActionsList = memo(() => {
108
130
  >
109
131
  <Close />
110
132
  </TouchableOpacity>
111
- </View>
112
- </TouchableOpacity>
133
+ </TouchableOpacity>
134
+ </View>
113
135
  );
114
- const renderItem = useCallback(({ item, index, drag, isActive }) => {
115
- const paddedIndex = (index + 1).toString().padStart(2, '0');
116
- const { action_script, notify_script, delay_script } = item;
117
- if (action_script) {
118
- const { sensor_icon_kit, station_name, sensor_name, action_name } =
119
- action_script;
136
+ const renderItem = useCallback(
137
+ ({ item, index, drag, isActive }) => {
138
+ const paddedIndex = (index + 1).toString().padStart(2, '0');
139
+ const { action_script, notify_script, delay_script } = item;
140
+ if (action_script) {
141
+ const {
142
+ sensor_icon_kit,
143
+ station_name,
144
+ sensor_name,
145
+ action_name,
146
+ data: data_action,
147
+ } = action_script;
120
148
 
121
- return (
122
- <CommonItem
123
- paddedIndex={paddedIndex}
124
- icon={
125
- <FImage source={{ uri: sensor_icon_kit }} style={styles.iconItem} />
126
- }
127
- content={
128
- <>
129
- <View style={styles.titleItem}>
130
- <Text
131
- numberOfLines={1}
132
- semibold
133
- type="Label"
134
- color={Colors.Gray7}
135
- style={styles.paddingRight4}
136
- >
137
- {unit?.name}
149
+ return (
150
+ <CommonItem
151
+ paddedIndex={paddedIndex}
152
+ icon={
153
+ <FImage
154
+ source={{ uri: sensor_icon_kit }}
155
+ style={styles.iconItem}
156
+ />
157
+ }
158
+ content={
159
+ <>
160
+ <View style={styles.titleItem}>
161
+ <Text numberOfLines={1} type="Label" color={Colors.Gray7}>
162
+ {station_name}
163
+ </Text>
164
+ </View>
165
+ <Text numberOfLines={1} type="H4" color={Colors.Gray9} semibold>
166
+ {sensor_name}
138
167
  </Text>
139
- <Text numberOfLines={1} type="Label" color={Colors.Gray7}>
140
- {station_name}
168
+ <Text numberOfLines={1} type="H4" color={Colors.Gray9}>
169
+ {action_name} {data_action}
141
170
  </Text>
171
+ </>
172
+ }
173
+ onPress={() => onPressRemove(item)}
174
+ onPressUpdate={() => onShowPopupUpdate(item, index)}
175
+ isActive={isActive}
176
+ drag={drag}
177
+ />
178
+ );
179
+ }
180
+
181
+ if (notify_script) {
182
+ const { title, message } = notify_script;
183
+
184
+ return (
185
+ <CommonItem
186
+ paddedIndex={paddedIndex}
187
+ icon={
188
+ <View style={styles.iconItem}>
189
+ <Notify />
142
190
  </View>
143
- <Text numberOfLines={1} type="H4" color={Colors.Gray9} semibold>
144
- {sensor_name}
145
- </Text>
146
- <Text numberOfLines={1} type="H4" color={Colors.Gray9}>
147
- {action_name}
148
- </Text>
149
- </>
150
- }
151
- onPress={() => onPressRemove(item)}
152
- isActive={isActive}
153
- drag={drag}
191
+ }
192
+ content={
193
+ <>
194
+ <Text numberOfLines={1} type="H4" color={Colors.Gray9} semibold>
195
+ {title}
196
+ </Text>
197
+ <Text numberOfLines={1} type="H4" color={Colors.Gray9}>
198
+ {message}
199
+ </Text>
200
+ </>
201
+ }
202
+ onPress={() => onPressRemove(item)}
203
+ onPressUpdate={() => onShowPopupUpdate(item, index)}
204
+ isActive={isActive}
205
+ drag={drag}
206
+ />
207
+ );
208
+ }
209
+ if (delay_script) {
210
+ const { delay } = delay_script;
211
+
212
+ return (
213
+ <CommonItem
214
+ paddedIndex={paddedIndex}
215
+ icon={
216
+ <View style={styles.iconItem}>
217
+ <Delay />
218
+ </View>
219
+ }
220
+ content={
221
+ <>
222
+ <Text numberOfLines={1} type="H4" color={Colors.Gray9} semibold>
223
+ {t('wait')}
224
+ </Text>
225
+ <Text numberOfLines={1} type="H4" color={Colors.Gray9}>
226
+ {t('wait_time_seconds', { delay })}
227
+ </Text>
228
+ </>
229
+ }
230
+ onPress={() => onPressRemove(item)}
231
+ onPressUpdate={() => onShowPopupUpdate(item, index)}
232
+ isActive={isActive}
233
+ drag={drag}
234
+ />
235
+ );
236
+ }
237
+ },
238
+ // eslint-disable-next-line react-hooks/exhaustive-deps
239
+ [needRefresh]
240
+ );
241
+
242
+ const renderAction = useMemo(() => {
243
+ const {
244
+ action_script,
245
+ notify_script,
246
+ delay_script,
247
+ id: scriptItemId,
248
+ } = scriptItem;
249
+
250
+ if (action_script) {
251
+ onClosePopup();
252
+ setScriptItem({});
253
+ navigate(Routes.UpdateActionScript, {
254
+ unitId,
255
+ automateId: id,
256
+ device: {
257
+ id: action_script.end_device_id,
258
+ },
259
+ numberActionAdded: actionsList.length,
260
+ scriptItemId: scriptItemId,
261
+ closeScreen: Routes.EditActionsList,
262
+ });
263
+ }
264
+ if (notify_script) {
265
+ return (
266
+ <UpdateNotifyScript
267
+ unitId={unitId}
268
+ automateId={id}
269
+ scriptItemId={scriptItemId}
270
+ notify_script={notify_script}
271
+ t={t}
272
+ onClosePopup={onClosePopup}
273
+ actionsList={actionsList}
274
+ updateIndex={updateIndex}
275
+ setActionList={setActionList}
276
+ setNeedRefresh={setNeedRefresh}
154
277
  />
155
278
  );
156
279
  }
280
+ if (delay_script) {
281
+ return (
282
+ <UpdateDelayScript
283
+ automateId={id}
284
+ scriptItemId={scriptItemId}
285
+ delay_script={delay_script}
286
+ t={t}
287
+ onClosePopup={onClosePopup}
288
+ actionsList={actionsList}
289
+ updateIndex={updateIndex}
290
+ setActionList={setActionList}
291
+ setNeedRefresh={setNeedRefresh}
292
+ />
293
+ );
294
+ }
295
+ }, [actionsList, id, navigate, scriptItem, t, unitId, updateIndex]);
157
296
 
158
- if (notify_script) {
159
- const { title, message } = notify_script;
297
+ const onDragEnd = useCallback(
298
+ ({ data: dragData, from, to }) => {
299
+ if (from === to) {
300
+ return;
301
+ }
302
+ setProcessing(true);
303
+ setActionList(dragData);
304
+ onPressSave(dragData);
305
+ },
306
+ [onPressSave]
307
+ );
160
308
 
309
+ const renderMessageRemove = useMemo(() => {
310
+ const { action_script, notify_script, delay_script } = itemRemove;
311
+ if (action_script) {
161
312
  return (
162
- <CommonItem
163
- paddedIndex={paddedIndex}
164
- icon={
165
- <View style={styles.iconItem}>
166
- <Notify />
167
- </View>
168
- }
169
- content={
170
- <>
171
- <Text numberOfLines={1} type="H4" color={Colors.Gray9} semibold>
172
- {title}
173
- </Text>
174
- <Text numberOfLines={1} type="H4" color={Colors.Gray9}>
175
- {message}
176
- </Text>
177
- </>
178
- }
179
- onPress={() => onPressRemove(item)}
180
- isActive={isActive}
181
- drag={drag}
182
- />
313
+ <ParsedText
314
+ style={styles.messageDelete}
315
+ parse={[
316
+ {
317
+ pattern: new RegExp(itemRemove.action_script.action_name),
318
+ style: styles.textHighlight,
319
+ },
320
+ {
321
+ pattern: new RegExp(itemRemove.action_script.station_name),
322
+ style: styles.textHighlight,
323
+ },
324
+ ]}
325
+ childrenProps={{ allowFontScaling: false }}
326
+ >
327
+ {t('message_delete_action', {
328
+ actionName: itemRemove.action_script.action_name,
329
+ stationName: itemRemove.action_script.station_name,
330
+ })}
331
+ </ParsedText>
332
+ );
333
+ }
334
+ if (notify_script) {
335
+ return (
336
+ <ParsedText
337
+ style={styles.messageDelete}
338
+ childrenProps={{ allowFontScaling: false }}
339
+ >
340
+ {t('message_delete_notify', { title: notify_script.title })}
341
+ </ParsedText>
183
342
  );
184
343
  }
185
344
  if (delay_script) {
186
- const { delay } = delay_script;
187
-
188
345
  return (
189
- <CommonItem
190
- paddedIndex={paddedIndex}
191
- icon={
192
- <View style={styles.iconItem}>
193
- <Delay />
194
- </View>
195
- }
196
- content={
197
- <>
198
- <Text numberOfLines={1} type="H4" color={Colors.Gray9} semibold>
199
- {t('wait')}
200
- </Text>
201
- <Text numberOfLines={1} type="H4" color={Colors.Gray9}>
202
- {t('wait_time_seconds', { delay })}
203
- </Text>
204
- </>
205
- }
206
- onPress={() => onPressRemove(item)}
207
- isActive={isActive}
208
- drag={drag}
209
- />
346
+ <ParsedText
347
+ style={styles.messageDelete}
348
+ childrenProps={{ allowFontScaling: false }}
349
+ >
350
+ {t('message_delete_delay', { delay: delay_script.delay })}
351
+ </ParsedText>
210
352
  );
211
353
  }
212
- // eslint-disable-next-line react-hooks/exhaustive-deps
213
- }, []);
354
+ }, [itemRemove, t]);
214
355
 
215
356
  return (
216
357
  <View style={styles.wrap}>
@@ -219,73 +360,41 @@ const EditActionsList = memo(() => {
219
360
  <Text type="Body" color={Colors.Gray8}>
220
361
  {t('des_edit_actions_list')}
221
362
  </Text>
363
+ <Text type="Body" color={Colors.Gray8}>
364
+ {t('hold_longer_than_1s')}
365
+ </Text>
366
+
222
367
  <DraggableFlatList
223
368
  showsVerticalScrollIndicator={false}
224
369
  data={actionsList}
225
370
  renderItem={renderItem}
226
371
  keyExtractor={(item) => `draggable-item-${item.id}`}
227
- onDragEnd={({ data: dragData }) => setActionList(dragData)}
372
+ onDragEnd={onDragEnd}
228
373
  extraData={actionsList}
229
374
  containerStyle={styles.containerStyle}
230
375
  />
231
376
  </View>
232
- <View style={styles.wrapBottom}>
233
- <TouchableOpacity
234
- onPress={onCancel}
235
- accessibilityLabel={AccessibilityLabel.BUTTON_CANCEL_EDIT_ACTION_LIST}
236
- >
237
- <Text type="H4" highlight semibold>
238
- {t('cancel')}
239
- </Text>
240
- </TouchableOpacity>
241
- <TouchableOpacity
242
- onPress={onPressSave}
243
- accessibilityLabel={AccessibilityLabel.BUTTON_SAVE_EDIT_ACTION_LIST}
244
- >
245
- <Text type="H4" highlight semibold>
246
- {t('save')}
247
- </Text>
248
- </TouchableOpacity>
249
- </View>
377
+ {processing && <FullLoading />}
250
378
  <ModalBottom
251
379
  isVisible={isVisible}
252
380
  title={t('delete_action')}
253
381
  onClose={onClose}
254
382
  onRemove={onRemove}
255
383
  >
256
- <View style={styles.wrapChildModal}>
257
- {itemRemove?.action_script ? (
258
- <ParsedText
259
- style={styles.messageDelete}
260
- parse={[
261
- {
262
- pattern: new RegExp(itemRemove?.action_script.action_name),
263
- style: styles.textHighlight,
264
- },
265
- {
266
- pattern: new RegExp(itemRemove?.action_script.station_name),
267
- style: styles.textHighlight,
268
- },
269
- ]}
270
- childrenProps={{ allowFontScaling: false }}
271
- >
272
- {t('message_delete_action', {
273
- actionName: itemRemove?.action_script.action_name,
274
- stationName: itemRemove?.action_script.station_name,
275
- })}
276
- </ParsedText>
277
- ) : (
278
- <ParsedText
279
- style={styles.messageDelete}
280
- childrenProps={{ allowFontScaling: false }}
281
- >
282
- {t('message_delete_notify')}
283
- </ParsedText>
284
- )}
285
- </View>
384
+ <View style={styles.wrapChildModal}>{renderMessageRemove}</View>
286
385
  </ModalBottom>
386
+ <ModalCustom
387
+ isVisible={showPopupUpdate}
388
+ onBackButtonPress={onClosePopup}
389
+ onBackdropPress={onClosePopup}
390
+ accessibilityLabel={AccessibilityLabel.MODAL_CUSTOM}
391
+ >
392
+ <View style={styles.popoverStyle}>
393
+ <View style={styles.modalHeader}>{renderAction}</View>
394
+ </View>
395
+ </ModalCustom>
287
396
  </View>
288
397
  );
289
- });
398
+ };
290
399
 
291
400
  export default EditActionsList;
@@ -21,7 +21,7 @@ import MenuActionMore from '../../../commons/MenuActionMore';
21
21
  import Add from '../../../../assets/images/Add.svg';
22
22
  import Notify from '../../../../assets/images/Notify.svg';
23
23
  import Delay from '../../../../assets/images/Delay.svg';
24
- import { useNavigation } from '@react-navigation/native';
24
+ import { useIsFocused, useNavigation } from '@react-navigation/native';
25
25
  import { axiosGet, axiosPost } from '../../../utils/Apis/axios';
26
26
  import Routes from '../../../utils/Route';
27
27
  import { ToastBottomHelper } from '../../../utils/Utils';
@@ -52,6 +52,7 @@ const ScriptDetail = ({ route }) => {
52
52
  newActionsList, // updated actions list
53
53
  } = params;
54
54
  const [automate, setAutomate] = useState(preAutomate);
55
+ const isFocused = useIsFocused();
55
56
  const [data, setData] = useState([]);
56
57
  const [isShowRename, setIsShowRename] = useState(false);
57
58
  const [isShowDelete, setIsShowDelete] = useState(false);
@@ -129,7 +130,7 @@ const ScriptDetail = ({ route }) => {
129
130
  id,
130
131
  unitId: automate.unit,
131
132
  });
132
- }, [data, id, navigate, automate.unit]);
133
+ }, [navigate, data, id, automate.unit]);
133
134
 
134
135
  const handleScriptAction = useCallback(async () => {
135
136
  const { success } = await axiosPost(API.AUTOMATE.ACTION_ONE_TAP(id));
@@ -172,8 +173,10 @@ const ScriptDetail = ({ route }) => {
172
173
  );
173
174
 
174
175
  useEffect(() => {
175
- fetchAutomate();
176
- }, [fetchAutomate]);
176
+ if (isFocused) {
177
+ fetchAutomate();
178
+ }
179
+ }, [fetchAutomate, isFocused]);
177
180
 
178
181
  useEffect(() => {
179
182
  newActionsList && setData(newActionsList);
@@ -198,8 +201,10 @@ const ScriptDetail = ({ route }) => {
198
201
  );
199
202
 
200
203
  useEffect(() => {
201
- fetchAutomateActions();
202
- }, [fetchAutomateActions]);
204
+ if (isFocused) {
205
+ fetchAutomateActions();
206
+ }
207
+ }, [fetchAutomateActions, isFocused]);
203
208
 
204
209
  useEffect(() => {
205
210
  saveAt && fetchAutomateActions();
@@ -52,7 +52,7 @@ const ChangePosition = () => {
52
52
  const renderItem = ({ item, index, drag, isActive }) => {
53
53
  return (
54
54
  <View style={styles.widgetItem}>
55
- <View style={styles.itemOrder}>
55
+ <View style={[styles.itemOrder, isActive ? styles.isDragging : {}]}>
56
56
  <TouchableOpacity style={styles.indexOrder} onPressIn={drag}>
57
57
  <Text type="H4">{index + 1}</Text>
58
58
  <ReOrder />
@@ -99,4 +99,8 @@ export default StyleSheet.create({
99
99
  backgroundColor: Colors.White,
100
100
  marginBottom: getBottomSpace() || 16,
101
101
  },
102
+ isDragging: {
103
+ borderBottomWidth: 1,
104
+ borderColor: Colors.Red,
105
+ },
102
106
  });
@@ -722,6 +722,10 @@ export default {
722
722
  notification: 'Notification',
723
723
  send_notification: 'Send Notification',
724
724
  title_notification: 'Subject: “Warning”',
725
+ update_title_notification: 'Update title',
726
+ update_message_notification: 'Update warning content',
727
+ update_action: 'Update action',
728
+ updated_action_order: 'Updated action order',
725
729
  message_notification:
726
730
  'Warning content: "The temperature in the office is high, please check."',
727
731
  promotions: 'Promotions',
@@ -987,7 +991,10 @@ export default {
987
991
  modbus_fail: 'Modbus failrate',
988
992
  rssi_node: 'RSSI Node',
989
993
  edit_actions_list: 'Edit Actions List',
990
- des_edit_actions_list: 'Hold and hover to rearrange actions order',
994
+ des_edit_actions_list:
995
+ 'Press and hold the number and drag to rearrange the order of the actions.',
996
+ hold_longer_than_1s:
997
+ 'Press and hold the action name for more than 1 second to update the action.',
991
998
  please_add_your_phone_number_and_chip_name:
992
999
  'Please add your phone number and chip name',
993
1000
  Please_add_gateway_name: 'Please add gateway name',
@@ -1012,6 +1019,7 @@ export default {
1012
1019
  tap_to_run: 'Tap to run',
1013
1020
  how_to_start: 'How to start',
1014
1021
  'set_up {name}': 'Setup {name}',
1022
+ choose_action: 'Choose action',
1015
1023
  action: 'action',
1016
1024
  power: 'Power',
1017
1025
  actions_list: 'Actions list',
@@ -1019,7 +1027,9 @@ export default {
1019
1027
  message_delete_action:
1020
1028
  'Are you sure you want to delete action of \n{actionName} in {stationName}?',
1021
1029
  message_delete_notify:
1022
- 'Are you sure you want to remove sending notifications?',
1030
+ 'Are you sure you want to remove this "{title}" message?',
1031
+ message_delete_delay:
1032
+ 'Are you sure you want to remove this "{delay} seconds" delay?',
1023
1033
  add_script: 'Add Script',
1024
1034
  delete_script: 'Delete Script',
1025
1035
  title_delete_script: 'Delete script "{scriptName}"?',
@@ -1054,6 +1064,8 @@ export default {
1054
1064
  delay_the_action: 'Delay the action',
1055
1065
  wait: 'Wait',
1056
1066
  set_timeout_seconds: 'Set timeout (seconds)',
1067
+ update_waiting_time: 'Update waiting time (seconds)',
1068
+ update_successfully: 'Update successfully',
1057
1069
  maximum_3600_seconds: 'Maximum 3600 seconds',
1058
1070
  wait_time_seconds: 'Wait {delay} seconds',
1059
1071
  end_device_not_support_script:
@@ -1418,7 +1430,8 @@ export default {
1418
1430
  io_method: 'Input/Output method',
1419
1431
  change_position: 'Change position',
1420
1432
  updated_widget_successfully: 'Updated widget successfully',
1421
- sub_text_change_position: 'Hold and hover to rearrange the widgets',
1433
+ sub_text_change_position:
1434
+ 'Press and hold the number and drag to rearrange the widgets.',
1422
1435
  transfer_ownership: 'Transfer ownership',
1423
1436
  text_change_owner:
1424
1437
  'Ownership permissions of this unit to the user you have selected.',
@@ -1428,7 +1441,7 @@ export default {
1428
1441
  'To provide a better user experience, [Era] will perform a system upgrade.The upgrade will take about 10 ' +
1429
1442
  'minutes.\n\n Some device control functions will be interrupted during the upgrade.[Era] would like to ask ' +
1430
1443
  'for your understanding for this inconvenience.\n\nBest regards.',
1431
- please_enter_a_number: 'Please enter a number',
1444
+ please_enter_a_number: 'Please enter a number and select a condition',
1432
1445
  not_support_plug_and_play: 'Not support plug and play',
1433
1446
  reach_max_stations_per_unit:
1434
1447
  'You have reached the maximum number of {length} sub-unit per unit.',