@eohjsc/react-native-smart-city 0.7.15 → 0.7.17

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 (25) hide show
  1. package/assets/images/Sms.svg +9 -0
  2. package/package.json +1 -1
  3. package/src/commons/Automate/ItemConditionScriptDetailStyles.js +1 -0
  4. package/src/commons/Unit/__test__/SharedUnit.test.js +57 -0
  5. package/src/configs/API.js +6 -1
  6. package/src/configs/AccessibilityLabel.js +4 -0
  7. package/src/hooks/Common/useBlockBack.js +10 -2
  8. package/src/navigations/UnitStack.js +24 -0
  9. package/src/screens/Automate/AddNewAction/SetupScriptReceiverSms.js +167 -0
  10. package/src/screens/Automate/AddNewAction/SetupScriptSms.js +73 -0
  11. package/src/screens/Automate/AddNewAction/Styles/SetupScriptEmailStyles.js +5 -0
  12. package/src/screens/Automate/AddNewAction/__test__/SetupScriptReceiverSms.test.js +105 -0
  13. package/src/screens/Automate/AddNewAction/__test__/SetupScriptSms.test.js +70 -0
  14. package/src/screens/Automate/EditActionsList/UpdateReceiverSmsScript.js +178 -0
  15. package/src/screens/Automate/EditActionsList/UpdateSmsScript.js +66 -0
  16. package/src/screens/Automate/EditActionsList/__tests__/UpdateReceiverSmsScript.test.js +82 -0
  17. package/src/screens/Automate/EditActionsList/__tests__/UpdateSmsScript.test.js +71 -0
  18. package/src/screens/Automate/EditActionsList/index.js +50 -1
  19. package/src/screens/Automate/ScriptDetail/Components/AddActionScript.js +52 -19
  20. package/src/screens/Automate/ScriptDetail/Styles/indexStyles.js +39 -2
  21. package/src/screens/Automate/ScriptDetail/__test__/index.test.js +295 -57
  22. package/src/screens/Automate/ScriptDetail/index.js +234 -32
  23. package/src/utils/I18n/translations/en.js +10 -0
  24. package/src/utils/I18n/translations/vi.js +10 -0
  25. package/src/utils/Route/index.js +3 -0
@@ -19,6 +19,7 @@ import Add from '../../../../assets/images/Add.svg';
19
19
  import Delay from '../../../../assets/images/Delay.svg';
20
20
  import Notify from '../../../../assets/images/Notify.svg';
21
21
  import Email from '../../../../assets/images/Email.svg';
22
+ import Sms from '../../../../assets/images/Sms.svg';
22
23
  import IconComponent from '../../../commons/IconComponent';
23
24
  import MenuActionMore from '../../../commons/MenuActionMore';
24
25
  import WrapHeaderScrollable from '../../../commons/Sharing/WrapHeaderScrollable';
@@ -39,11 +40,13 @@ import RenameScript from './Components/RenameScript';
39
40
  import { useStarredScript } from './hooks/useStarredScript';
40
41
  import styles from './Styles/indexStyles';
41
42
  import ItemConditionScriptDetail from '../../../commons/Automate/ItemConditionScriptDetail';
43
+ import { ModalCustom } from '../../../commons/Modal';
44
+ import { Card } from '../../../commons/CardShadow';
42
45
 
43
46
  const PreventDoubleTouch = withPreventDoubleClick(TouchableOpacity);
44
47
 
45
48
  const ScriptDetail = ({ route }) => {
46
- const { dispatch, navigate, goBack } = useNavigation();
49
+ const { dispatch, navigate, goBack, getState } = useNavigation();
47
50
  const { params = {} } = route;
48
51
  const refMenuAction = useRef();
49
52
  const { childRef, showingPopover, showPopoverWithRef, hidePopover } =
@@ -68,7 +71,8 @@ const ScriptDetail = ({ route }) => {
68
71
  const [isShowRename, setIsShowRename] = useState(false);
69
72
  const [isShowDelete, setIsShowDelete] = useState(false);
70
73
  const [isShowAddAction, setIsShowAddAction] = useState(false);
71
-
74
+ const [isShowLocalControl, setIsShowLocalControl] = useState(false);
75
+ const [listChipShared, setListChipShared] = useState([]);
72
76
  const {
73
77
  script,
74
78
  type,
@@ -79,7 +83,18 @@ const ScriptDetail = ({ route }) => {
79
83
  value_change,
80
84
  } = automate;
81
85
  const { end_device_id, unit_id } = value_change || {};
82
- const { enable } = script || {};
86
+ const {
87
+ enable,
88
+ chip_local_control,
89
+ is_local_control,
90
+ chip_id_local_control,
91
+ } = script || {};
92
+
93
+ const [local_control, setLocalControl] = useState({
94
+ is_local_control,
95
+ chip_local_control,
96
+ chip_id_local_control,
97
+ });
83
98
  const [enableScript, setEnableScript] = useState(enable);
84
99
  const refMenuAction1 = useRef();
85
100
  const onShowActivityLog = useCallback(() => {
@@ -97,20 +112,9 @@ const ScriptDetail = ({ route }) => {
97
112
  });
98
113
  }, [navigate, automateId, type, unit]);
99
114
 
100
- const handleUpdateAutomate = useCallback(async () => {
101
- if (!can_edit) {
102
- ToastBottomHelper.error(
103
- t('only_owner_has_permission_to_edit_this_script')
104
- );
105
- return;
106
- }
107
- if (!enableScript) {
108
- ToastBottomHelper.error(t('this_script_has_been_disabled'));
109
- return;
110
- }
111
-
112
- // Reset stack and navigate to AddUnknownTypeSmart
113
- dispatch((state) => {
115
+ const handleNavigate = useCallback(
116
+ (screen, screenParams) => {
117
+ const state = getState();
114
118
  const index = state.routes.findIndex((r) => r.name === closeScreen);
115
119
  let routes = [];
116
120
  if (!closeScreen) {
@@ -130,20 +134,41 @@ const ScriptDetail = ({ route }) => {
130
134
  }
131
135
 
132
136
  routes.push({
133
- name: Routes.AddUnknownTypeSmart,
134
- params: {
135
- automate,
136
- closeScreen: route.name,
137
- },
137
+ name: screen,
138
+ params: screenParams,
138
139
  });
139
140
 
140
- return CommonActions.reset({
141
- ...state,
142
- routes: routes,
143
- index: routes.length - 1,
144
- });
141
+ setTimeout(() => {
142
+ dispatch(
143
+ CommonActions.reset({
144
+ routes: routes,
145
+ index: routes.length - 1,
146
+ })
147
+ );
148
+ }, 500); // Workaround: Fix crash on iOS when resetting the stack with dispatch.
149
+ // Delay added to ensure navigation state updates before dispatching reset.
150
+ },
151
+ [closeScreen, dispatch, getState, route.params]
152
+ );
153
+
154
+ const handleUpdateAutomate = useCallback(async () => {
155
+ if (!can_edit) {
156
+ ToastBottomHelper.error(
157
+ t('only_owner_has_permission_to_edit_this_script')
158
+ );
159
+ return;
160
+ }
161
+ if (!enableScript) {
162
+ ToastBottomHelper.error(t('this_script_has_been_disabled'));
163
+ return;
164
+ }
165
+
166
+ // Reset stack and navigate to AddUnknownTypeSmart
167
+ handleNavigate(Routes.AddUnknownTypeSmart, {
168
+ automate,
169
+ closeScreen: route.name,
145
170
  });
146
- }, [automate, can_edit, closeScreen, enableScript, dispatch, route, t]);
171
+ }, [automate, can_edit, enableScript, route.name, t, handleNavigate]);
147
172
 
148
173
  const listMenuItem = useMemo(
149
174
  () => [
@@ -245,7 +270,10 @@ const ScriptDetail = ({ route }) => {
245
270
  closeScreen === Routes.MultiUnits ||
246
271
  closeScreen === Routes.Automate
247
272
  ) {
248
- navigate(closeScreen, {});
273
+ navigate({
274
+ name: closeScreen,
275
+ merge: true,
276
+ });
249
277
  } else {
250
278
  goBack();
251
279
  }
@@ -309,6 +337,90 @@ const ScriptDetail = ({ route }) => {
309
337
  showPopoverWithRef1(refMenuAction1);
310
338
  }, [showPopoverWithRef1, refMenuAction1]);
311
339
 
340
+ const onCloseLocalControl = () => setIsShowLocalControl(false);
341
+
342
+ const fetchChipShared = useCallback(async () => {
343
+ const { success, data: listChip } = await axiosGet(
344
+ API.DEV_MODE.GATEWAY.SHARED(),
345
+ {
346
+ unit: unit_id,
347
+ },
348
+ true
349
+ );
350
+ if (success) {
351
+ setListChipShared(listChip);
352
+ }
353
+ }, [unit_id]);
354
+
355
+ const onShowLocalControl = useCallback(async () => {
356
+ setIsShowLocalControl(true);
357
+ }, []);
358
+
359
+ useEffect(() => {
360
+ fetchChipShared();
361
+ }, [fetchChipShared]);
362
+
363
+ const onPressSelectChip = useCallback(
364
+ async (enable_local_control, item) => {
365
+ if (!item.id) {
366
+ setIsShowLocalControl(false);
367
+ return;
368
+ }
369
+ const { success } = await axiosPost(
370
+ API.AUTOMATE.ENABLE_LOCAL_CONTROL(automateId),
371
+ {
372
+ is_local_control: enable_local_control,
373
+ chip_local_control: item.id,
374
+ }
375
+ );
376
+ setIsShowLocalControl(false);
377
+ if (success) {
378
+ setLocalControl({
379
+ is_local_control: enable_local_control,
380
+ chip_local_control: item.name,
381
+ chip_id_local_control: item.id,
382
+ });
383
+ }
384
+ },
385
+ [automateId]
386
+ );
387
+
388
+ const renderLocalControl = useMemo(() => {
389
+ if (!!can_edit && type !== AUTOMATE_TYPE.ONE_TAP) {
390
+ return (
391
+ <View style={styles.row}>
392
+ <Text type="H3" semibold style={styles.width50}>
393
+ {t('local_control')}
394
+ </Text>
395
+ <Card style={styles.card}>
396
+ <TouchableOpacity
397
+ style={styles.localControl}
398
+ onPress={onShowLocalControl}
399
+ accessibilityLabel={
400
+ AccessibilityLabel.AUTOMATE_SHOW_LOCAL_CONTROL
401
+ }
402
+ >
403
+ <Text numberOfLines={1}>
404
+ {local_control.is_local_control
405
+ ? local_control.chip_local_control
406
+ : t('disable')}
407
+ </Text>
408
+
409
+ <IconOutline name="down" size={15} style={styles.marginLeft5} />
410
+ </TouchableOpacity>
411
+ </Card>
412
+ </View>
413
+ );
414
+ }
415
+ }, [
416
+ can_edit,
417
+ local_control.chip_local_control,
418
+ local_control.is_local_control,
419
+ onShowLocalControl,
420
+ t,
421
+ type,
422
+ ]);
423
+
312
424
  return (
313
425
  <View style={styles.wrap}>
314
426
  <WrapHeaderScrollable
@@ -326,6 +438,7 @@ const ScriptDetail = ({ route }) => {
326
438
  <Switch value={enableScript} onValueChange={onChangeSwitch} />
327
439
  </View>
328
440
  )}
441
+ {renderLocalControl}
329
442
  <Text type="H3" semibold>
330
443
  {t('how_to_start')}
331
444
  </Text>
@@ -370,6 +483,7 @@ const ScriptDetail = ({ route }) => {
370
483
  index={index}
371
484
  enableScript={enableScript}
372
485
  t={t}
486
+ local_control={local_control}
373
487
  />
374
488
  ))}
375
489
  {!!can_edit && !!enableScript && (
@@ -414,6 +528,8 @@ const ScriptDetail = ({ route }) => {
414
528
  numberActionAdded={data.length}
415
529
  isVisible={isShowAddAction}
416
530
  setIsVisible={setIsShowAddAction}
531
+ type={type}
532
+ navigate={handleNavigate}
417
533
  />
418
534
  <RenameScript
419
535
  automate={automate}
@@ -426,14 +542,68 @@ const ScriptDetail = ({ route }) => {
426
542
  setIsVisible={setIsShowDelete}
427
543
  isVisible={isShowDelete}
428
544
  />
545
+ <ModalCustom
546
+ isVisible={isShowLocalControl}
547
+ onBackButtonPress={onCloseLocalControl}
548
+ onBackdropPress={onCloseLocalControl}
549
+ >
550
+ <View key={'localControl'} style={styles.popoverStyle}>
551
+ <TouchableOpacity
552
+ style={styles.textDisable}
553
+ key={'listChip'}
554
+ onPress={() => {
555
+ onPressSelectChip(false, {
556
+ id: local_control.chip_id_local_control,
557
+ name: local_control.chip_local_control,
558
+ });
559
+ }}
560
+ accessibilityLabel={
561
+ AccessibilityLabel.AUTOMATE_DISABLE_LOCAL_CONTROL
562
+ }
563
+ >
564
+ <Text>{t('disable')}</Text>
565
+ {!local_control.is_local_control && (
566
+ <IconOutline style={styles.checked} name={'check'} size={20} />
567
+ )}
568
+ </TouchableOpacity>
569
+ {listChipShared.map((item, index) => (
570
+ <TouchableOpacity
571
+ key={'listChip' + index} // Add key fix warning
572
+ style={styles.listChip}
573
+ onPress={() => {
574
+ onPressSelectChip(true, item);
575
+ }}
576
+ accessibilityLabel={
577
+ AccessibilityLabel.AUTOMATE_ENABLE_LOCAL_CONTROL
578
+ }
579
+ >
580
+ <Text>{item.name}</Text>
581
+ {local_control.chip_id_local_control === item.id &&
582
+ local_control.is_local_control && (
583
+ <IconOutline
584
+ style={styles.checked}
585
+ name={'check'}
586
+ size={20}
587
+ />
588
+ )}
589
+ </TouchableOpacity>
590
+ ))}
591
+ </View>
592
+ </ModalCustom>
429
593
  </View>
430
594
  );
431
595
  };
432
596
 
433
- const Item = ({ item, index, enableScript, t }) => {
434
- const color = enableScript ? Colors.Gray9 : Colors.Gray7;
597
+ const Item = ({ item, index, enableScript, t, local_control }) => {
598
+ let color = enableScript ? Colors.Gray9 : Colors.Gray7;
435
599
  const paddedIndex = (index + 1).toString().padStart(2, '0');
436
- const { action_script, notify_script, delay_script, email_script } = item;
600
+ const {
601
+ action_script,
602
+ notify_script,
603
+ delay_script,
604
+ email_script,
605
+ sms_script,
606
+ } = item;
437
607
  if (action_script) {
438
608
  const {
439
609
  sensor_icon_kit,
@@ -564,6 +734,38 @@ const Item = ({ item, index, enableScript, t }) => {
564
734
  </View>
565
735
  </View>
566
736
  );
737
+ } else if (sms_script) {
738
+ const { message, str_phone_numbers } = sms_script;
739
+ color = local_control.is_local_control ? color : Colors.Gray7;
740
+ return (
741
+ <View style={styles.wrapItem}>
742
+ <View style={styles.leftItem}>
743
+ <Text color={color} type="H4" semibold>
744
+ {paddedIndex}
745
+ </Text>
746
+ </View>
747
+ <View style={styles.rightItem}>
748
+ <View style={styles.insideItemRight}>
749
+ <View style={styles.iconEndDevice}>
750
+ <Sms />
751
+ </View>
752
+ <View style={styles.contentItem}>
753
+ <Text numberOfLines={1} type="H4" color={color} semibold>
754
+ {message}
755
+ </Text>
756
+ <Text numberOfLines={1} type="H4" color={color}>
757
+ {str_phone_numbers}
758
+ </Text>
759
+ </View>
760
+ </View>
761
+ {!local_control.is_local_control && (
762
+ <Text numberOfLines={1} type="H4" color={Colors.Red}>
763
+ {t('only_in_local_control')}
764
+ </Text>
765
+ )}
766
+ </View>
767
+ </View>
768
+ );
567
769
  }
568
770
  };
569
771
 
@@ -727,10 +727,13 @@ export default {
727
727
  update_title_notification: 'Update title',
728
728
  update_message_notification: 'Update warning content',
729
729
  email_content: 'E-mail content',
730
+ sms_content: 'SMS content',
730
731
  email_to: 'E-mail to',
732
+ sms_to: 'SMS to',
731
733
  subject: 'Subject',
732
734
  message: 'Message...',
733
735
  no_email: 'No email address',
736
+ no_phone_number: 'No phone number',
734
737
  update_title_email: 'Update title',
735
738
  update_message_email: 'Update warning content',
736
739
  update_action: 'Update action',
@@ -1068,9 +1071,16 @@ export default {
1068
1071
  automate: 'Automate',
1069
1072
  smart: 'Smart',
1070
1073
  enable_this_script: 'Enable this script',
1074
+ local_control: 'Local control',
1075
+ choose_gateway: 'Choose gateway',
1071
1076
  this_script_has_been_disabled: 'This script has been disabled',
1077
+ disable: 'Disable',
1072
1078
  control_device: 'Control device',
1073
1079
  send_email: 'Send e-mail',
1080
+ sms_alarm: 'SMS Alarm',
1081
+ message_sms:
1082
+ 'Warning content: "There is a fire alarm from the 1st floor, please check."',
1083
+ only_in_local_control: 'Operates only in local control mode',
1074
1084
  send_app_notification: 'Send app notification',
1075
1085
  delay_the_action: 'Delay the action',
1076
1086
  email_the_action: 'Send e-mail',
@@ -750,10 +750,13 @@ export default {
750
750
  update_title_notification: 'Cập nhật tiêu đề',
751
751
  update_message_notification: 'Cập nhật nội dung cảnh báo',
752
752
  email_content: 'Nội dung E-mail',
753
+ sms_content: 'Nội dung SMS',
753
754
  email_to: 'Gửi E-mail tới',
755
+ sms_to: 'SMS tới',
754
756
  subject: 'Tiêu đè',
755
757
  message: 'Tin nhắn...',
756
758
  no_email: 'Không có địa chỉ email',
759
+ no_phone_number: 'Không có số điện thoại',
757
760
  update_action: 'Cập nhật hành động',
758
761
  updated_action_order: 'Đã cập nhật thứ tự hành động',
759
762
  message_notification:
@@ -1078,9 +1081,16 @@ export default {
1078
1081
  automate: 'Tự động',
1079
1082
  smart: 'Thông minh',
1080
1083
  enable_this_script: 'Kích hoạt kịch bản này',
1084
+ local_control: 'Điều khiển tại biên',
1085
+ choose_gateway: 'Chọn gateway',
1081
1086
  this_script_has_been_disabled: 'Kịch bản này đã bị vô hiệu hoá',
1087
+ disable: 'Vô hiệu hóa',
1082
1088
  control_device: 'Thiết bị điều khiển',
1083
1089
  send_email: 'Gửi e-mail',
1090
+ sms_alarm: 'Cảnh báo SMS',
1091
+ message_sms:
1092
+ 'Nội dung cảnh báo: “Đang có tín hiệu báo cháy từ lầu 1, vui lòng kiểm tra.”',
1093
+ only_in_local_control: 'Chỉ hoạt động ở chế độ điều khiển tại biên',
1084
1094
  send_app_notification: 'Gửi thông báo qua ứng dụng',
1085
1095
  delay_the_action: 'Trì hoãn hành động',
1086
1096
  wait: 'Chờ đợi',
@@ -139,8 +139,11 @@ const Routes = {
139
139
  SetupScriptNotify: 'SetupScriptNotify',
140
140
  SetupScriptDelay: 'SetupScriptDelay',
141
141
  SetupScriptEmail: 'SetupScriptEmail',
142
+ SetupScriptSms: 'SetupScriptSms',
142
143
  SetupScriptReceiverEmail: 'SetupScriptReceiverEmail',
143
144
  UpdateReceiverEmailScript: 'UpdateReceiverEmailScript',
145
+ SetupScriptReceiverSms: 'SetupScriptReceiverSms',
146
+ UpdateReceiverSmsScript: 'UpdateReceiverSmsScript',
144
147
  ScenarioName: 'ScenarioName',
145
148
  ValueChangeName: 'ValueChangeName',
146
149
  AllCamera: 'AllCamera',