@eohjsc/react-native-smart-city 0.2.45 → 0.2.46

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 (35) hide show
  1. package/package.json +1 -1
  2. package/src/Images/Common/logo.png +0 -0
  3. package/src/Images/Common/logo@2x.png +0 -0
  4. package/src/Images/Common/logo@3x.png +0 -0
  5. package/src/commons/SubUnit/OneTap/ItemOneTap.js +3 -1
  6. package/src/commons/SubUnit/OneTap/__test__/SubUnitAutomate.test.js +2 -0
  7. package/src/commons/SubUnit/ShortDetail.js +1 -1
  8. package/src/configs/Constants.js +7 -0
  9. package/src/configs/Images.js +1 -0
  10. package/src/screens/AddNewAction/SelectAction.js +52 -4
  11. package/src/screens/AddNewAction/SelectSensorDevices.js +27 -5
  12. package/src/screens/AddNewAction/SetupSensor.js +1 -6
  13. package/src/screens/AddNewAutoSmart/__test__/AddNewAutoSmart.test.js +11 -1
  14. package/src/screens/AddNewAutoSmart/index.js +24 -13
  15. package/src/screens/AddNewOneTap/__test__/AddNewOneTap.test.js +9 -1
  16. package/src/screens/AddNewOneTap/index.js +3 -0
  17. package/src/screens/Automate/MultiUnits.js +3 -52
  18. package/src/screens/Automate/__test__/MultiUnits.test.js +3 -246
  19. package/src/screens/Automate/__test__/index.test.js +1 -0
  20. package/src/screens/Automate/index.js +1 -0
  21. package/src/screens/Notification/components/NotificationItem.js +31 -14
  22. package/src/screens/Notification/styles/NotificationItemStyles.js +5 -0
  23. package/src/screens/ScanChipQR/__test__/ScanChipQR.test.js +12 -3
  24. package/src/screens/ScanChipQR/components/QRScan/__test__/QRScan.test.js +11 -2
  25. package/src/screens/ScanSensorQR/__test__/ScanSensorQR.test.js +12 -3
  26. package/src/screens/ScriptDetail/__test__/index.test.js +71 -0
  27. package/src/screens/ScriptDetail/index.js +56 -4
  28. package/src/screens/SetSchedule/__test__/index.test.js +8 -0
  29. package/src/screens/SetSchedule/index.js +28 -6
  30. package/src/screens/Sharing/Components/__test__/TitleCheckBox.test.js +38 -0
  31. package/src/screens/SyncLGDevice/AddLGDevice.js +1 -1
  32. package/src/screens/TDSGuide/index.js +15 -19
  33. package/src/utils/I18n/translations/en.json +8 -0
  34. package/src/utils/I18n/translations/vi.json +20 -12
  35. package/src/utils/Route/index.js +1 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@eohjsc/react-native-smart-city",
3
3
  "title": "React Native Smart Home",
4
- "version": "0.2.45",
4
+ "version": "0.2.46",
5
5
  "description": "TODO",
6
6
  "main": "index.js",
7
7
  "files": [
Binary file
Binary file
Binary file
@@ -20,7 +20,7 @@ import { useGetIdUser } from '../../../hooks/Common';
20
20
  import { AUTOMATE_TYPE, TESTID } from '../../../configs/Constants';
21
21
 
22
22
  const ItemOneTap = memo(
23
- ({ isOwner, automate, unit, wrapSyles, onPressItem }) => {
23
+ ({ isOwner, automate = {}, unit, wrapSyles, onPressItem }) => {
24
24
  const { navigate } = useNavigation();
25
25
  const {
26
26
  id,
@@ -54,6 +54,7 @@ const ItemOneTap = memo(
54
54
  const goToDetail = useCallback(() => {
55
55
  navigate(Routes.ScriptDetail, {
56
56
  id,
57
+ automate,
57
58
  name: script?.name,
58
59
  type: type,
59
60
  havePermission: isOwner || user === idUser,
@@ -61,6 +62,7 @@ const ItemOneTap = memo(
61
62
  textCondition,
62
63
  });
63
64
  }, [
65
+ automate,
64
66
  isOwner,
65
67
  user,
66
68
  idUser,
@@ -100,6 +100,7 @@ describe('test Item', () => {
100
100
  type: 'one_tap',
101
101
  unit: undefined,
102
102
  textCondition: null,
103
+ automate: data.automates[0],
103
104
  });
104
105
 
105
106
  const handleScriptAction = instance.findAll(
@@ -196,6 +197,7 @@ describe('test Item', () => {
196
197
  type: 'value_change',
197
198
  unit: undefined,
198
199
  textCondition: 'Temperature higher than 29',
200
+ automate: data.automates[0],
199
201
  });
200
202
  });
201
203
  test('render SubUnitAutomate script schedule', async () => {
@@ -80,7 +80,7 @@ const ShortDetailSubUnit = ({ unit, station, isGGHomeConnected }) => {
80
80
  ? 'add_to_favorites'
81
81
  : station?.name === SubUnitName.scenario
82
82
  ? 'add_script'
83
- : 'add_new_device'
83
+ : 'add_new'
84
84
  );
85
85
 
86
86
  return (
@@ -100,6 +100,12 @@ export const AUTOMATE_SELECT = {
100
100
  SELECT_SENSOR: 'select_sensor',
101
101
  };
102
102
 
103
+ export const CONDITION_TYPES = {
104
+ IS: 'IS',
105
+ IS_BELOW: 'IS_BELOW',
106
+ IS_ABOVE: 'IS_ABOVE',
107
+ };
108
+
103
109
  export const AUTOMATES = {
104
110
  one_tap: {
105
111
  value: AUTOMATE_TYPE.ONE_TAP,
@@ -580,4 +586,5 @@ export const NOTIFICATION_TYPES = {
580
586
  STOP_VIOLATION_FREE_PARKING_ZONE: 'STOP_VIOLATION_FREE_PARKING_ZONE',
581
587
  PARKING_COMPLETED_DUE_TO_CAR_LEAVE: 'PARKING_COMPLETED_DUE_TO_CAR_LEAVE',
582
588
  NOTIFY_INVITE_MEMBER: 'NOTIFY_INVITE_MEMBER',
589
+ REMINDER: 'REMINDER',
583
590
  };
@@ -6,4 +6,5 @@ export default {
6
6
  fullscreen: require('../Images/Common/fullscreen.png'),
7
7
  file: require('../Images/Common/file.png'),
8
8
  activeButton: require('../Images/Common/ActiveButton.png'),
9
+ logo: require('../Images/Common/logo.png'),
9
10
  };
@@ -12,7 +12,7 @@ import OptionsDropdownActionTemplate from '../../commons/OneTapTemplate/OptionsD
12
12
  import StatesGridActionTemplate from '../../commons/OneTapTemplate/StatesGridActionTemplate';
13
13
  import { axiosGet, axiosPost } from '../../utils/Apis/axios';
14
14
  import { API, Images } from '../../configs';
15
- import { TESTID } from '../../configs/Constants';
15
+ import { CONDITION_TYPES, TESTID } from '../../configs/Constants';
16
16
  import Routes from '../../utils/Route';
17
17
  import styles from './Styles/SelectActionStyles';
18
18
  import moment from 'moment';
@@ -30,6 +30,7 @@ const SelectAction = memo(({ route }) => {
30
30
  unit,
31
31
  device,
32
32
  automateId,
33
+ automate = {},
33
34
  scriptName,
34
35
  isSelectSensor = false,
35
36
  type,
@@ -42,9 +43,11 @@ const SelectAction = memo(({ route }) => {
42
43
  const [sensorData, setSensorData] = useState([]);
43
44
  const [checkedItem, setCheckedItem] = useState({});
44
45
  const [isLoading, setIsLoading] = useState(false);
46
+ const [isfetched, setIsfetched] = useState(true);
45
47
 
46
48
  const fetchData = useCallback(async () => {
47
49
  isSelectSensor && setIsLoading(true);
50
+ setIsfetched(true);
48
51
  const { success, data } = await axiosGet(
49
52
  isSelectSensor
50
53
  ? API.AUTOMATE.GET_SENSOR_CONFIG(device.id)
@@ -53,13 +56,51 @@ const SelectAction = memo(({ route }) => {
53
56
  isSelectSensor && true
54
57
  );
55
58
  if (success) {
56
- isSelectSensor ? setSensorData(data) : setData(data);
59
+ if (isSelectSensor) {
60
+ if (automate?.config_id) {
61
+ const conditionType = [
62
+ {
63
+ title: `${t('is_below')} (<)`,
64
+ type: CONDITION_TYPES.IS_BELOW,
65
+ conditionValue: '<',
66
+ },
67
+ {
68
+ title: `${t('is')} (=)`,
69
+ type: CONDITION_TYPES.IS,
70
+ conditionValue: '=',
71
+ },
72
+ {
73
+ title: `${t('is_above')} (>)`,
74
+ type: CONDITION_TYPES.IS_ABOVE,
75
+ conditionValue: '>',
76
+ },
77
+ ];
78
+ const condition = conditionType.find((item) => {
79
+ return item.conditionValue === automate.condition;
80
+ });
81
+ const updateSensorData = data.map((obj) =>
82
+ obj.id === automate.config_id
83
+ ? { ...obj, value: automate.value, ...condition }
84
+ : obj
85
+ );
86
+ let selectSensor = data.find((config) => {
87
+ return config.id === automate.config_id;
88
+ });
89
+ setSensorData(updateSensorData);
90
+ setCheckedItem(selectSensor);
91
+ } else {
92
+ setSensorData(data);
93
+ }
94
+ } else {
95
+ setData(data);
96
+ }
57
97
  }
98
+ setIsfetched(false);
58
99
  const to = setTimeout(() => {
59
100
  setIsLoading(false);
60
101
  clearTimeout(to);
61
102
  }, 1000);
62
- }, [device.id, isSelectSensor]);
103
+ }, [automate, device.id, isSelectSensor, t]);
63
104
 
64
105
  const checkConditionToContinue = useCallback(() => {
65
106
  const itemTemp = sensorData?.find((i) => i.id === checkedItem?.id);
@@ -76,6 +117,13 @@ const SelectAction = memo(({ route }) => {
76
117
  isSelectSensor,
77
118
  isMultiUnits,
78
119
  automateId,
120
+ automate: {
121
+ ...automate,
122
+ condition: itemTemp?.conditionValue || '<',
123
+ value: itemTemp?.value,
124
+ config_id: itemTemp?.id,
125
+ config_name: itemTemp?.name,
126
+ },
79
127
  scriptName,
80
128
  });
81
129
  } else {
@@ -302,7 +350,7 @@ const SelectAction = memo(({ route }) => {
302
350
  testID={TESTID.ACTION_ITEM}
303
351
  />
304
352
  )}
305
- {data?.length === 0 && (
353
+ {data?.length === 0 && sensorData?.length === 0 && !isfetched && (
306
354
  <View style={styles.noneData}>
307
355
  <Text center>
308
356
  {t('you_do_not_have_the_device_or_have_share_control_device')}
@@ -21,6 +21,7 @@ const SelectSensorDevices = memo(({ route }) => {
21
21
  const {
22
22
  unit,
23
23
  automateId,
24
+ automate = {},
24
25
  title = AUTOMATE_SELECT.SELECT_DEVICE,
25
26
  type,
26
27
  scriptName,
@@ -59,13 +60,29 @@ const SelectSensorDevices = memo(({ route }) => {
59
60
  station: item,
60
61
  index: index,
61
62
  }));
63
+ if (isSelectSensor) {
64
+ if (automate.sensor_id) {
65
+ let selectSensor = {};
66
+ data.map((item) => {
67
+ item.sensors.map((sensor) => {
68
+ if (sensor.id === automate.sensor_id) {
69
+ selectSensor = sensor;
70
+ return;
71
+ } else if (selectSensor) {
72
+ return;
73
+ }
74
+ });
75
+ });
76
+ setSelectedDevice(selectSensor);
77
+ }
78
+ }
62
79
  setStation(data);
63
80
  setListMenuItem(listMenu);
64
81
  setListStation(listMenu.concat([{ text: '' }]));
65
82
  }
66
83
  }
67
84
  );
68
- }, [isSelectSensor, unit.id]);
85
+ }, [automate.sensor_id, isSelectSensor, unit]);
69
86
 
70
87
  useEffect(() => {
71
88
  fetchDetails();
@@ -84,6 +101,10 @@ const SelectSensorDevices = memo(({ route }) => {
84
101
  unit,
85
102
  device: selectedDevice,
86
103
  automateId: automateId,
104
+ automate: {
105
+ ...automate,
106
+ sensor_id: selectedDevice?.id ? selectedDevice.id : automate.sensor_id,
107
+ },
87
108
  stationName: station[indexStation]?.name,
88
109
  isSelectSensor,
89
110
  type,
@@ -93,18 +114,19 @@ const SelectSensorDevices = memo(({ route }) => {
93
114
  isMultiUnits,
94
115
  });
95
116
  }, [
117
+ navigate,
118
+ unit,
96
119
  selectedDevice,
97
120
  automateId,
121
+ automate,
98
122
  station,
99
123
  indexStation,
100
- navigate,
101
- unit,
102
- type,
103
124
  isSelectSensor,
125
+ type,
104
126
  scriptName,
105
- isMultiUnits,
106
127
  isAutomateTab,
107
128
  isCreateNewAction,
129
+ isMultiUnits,
108
130
  ]);
109
131
 
110
132
  const onPressClose = useCallback(() => {
@@ -13,12 +13,7 @@ import BottomButtonView from '../../commons/BottomButtonView';
13
13
  import { HorizontalPicker } from '../../commons';
14
14
  import { popAction } from '../../navigations/utils';
15
15
  import { useStatusBarPreview } from '../../hooks/Common/useStatusBar';
16
-
17
- const CONDITION_TYPES = {
18
- IS: 'IS',
19
- IS_BELOW: 'IS_BELOW',
20
- IS_ABOVE: 'IS_ABOVE',
21
- };
16
+ import { CONDITION_TYPES } from '../../configs/Constants';
22
17
 
23
18
  const SetUpSensor = () => {
24
19
  const t = useTranslations();
@@ -39,6 +39,10 @@ describe('test AddNewAutoSmart', () => {
39
39
  },
40
40
  };
41
41
 
42
+ beforeEach(() => {
43
+ mockNavigate.mockClear();
44
+ });
45
+
42
46
  test('AddNewAutoSmart select sensor device', async () => {
43
47
  await act(async () => {
44
48
  tree = await create(wrapComponent(route));
@@ -62,8 +66,11 @@ describe('test AddNewAutoSmart', () => {
62
66
  });
63
67
 
64
68
  expect(mockNavigate).toBeCalledWith(Routes.SelectSensorDevices, {
69
+ automate: {},
70
+ automateId: undefined,
65
71
  title: 'select_sensor',
66
72
  type: 'value_change',
73
+ scriptName: undefined,
67
74
  unit: { id: 1 },
68
75
  isAutomateTab: undefined,
69
76
  isMultiUnits: undefined,
@@ -92,11 +99,14 @@ describe('test AddNewAutoSmart', () => {
92
99
  await bottomButton.props.onPress();
93
100
  });
94
101
  expect(mockNavigate).toHaveBeenCalledWith(Routes.SetSchedule, {
102
+ automate: {},
103
+ automateId: undefined,
95
104
  type: 'schedule',
105
+ routeName: 'SetSchedule',
106
+ scriptName: undefined,
96
107
  unit: route.params.unit,
97
108
  isAutomateTab: undefined,
98
109
  isMultiUnits: undefined,
99
- routeName: 'SetSchedule',
100
110
  });
101
111
  });
102
112
  });
@@ -17,8 +17,14 @@ import Routes from '../../utils/Route';
17
17
  const AddNewAutoSmart = memo(({ route }) => {
18
18
  const t = useTranslations();
19
19
  const { navigate, goBack } = useNavigation();
20
- const { type, unit, isAutomateTab, isMultiUnits, automateId, scriptName } =
21
- route.params;
20
+ const {
21
+ type,
22
+ unit,
23
+ isAutomateTab,
24
+ isMultiUnits,
25
+ automate = {},
26
+ scriptName,
27
+ } = route.params;
22
28
  const typeAutoSmart = {
23
29
  [AUTOMATE_TYPE.AUTOMATE]: [
24
30
  {
@@ -57,26 +63,31 @@ const AddNewAutoSmart = memo(({ route }) => {
57
63
  },
58
64
  ],
59
65
  };
60
- const [data] = useState(typeAutoSmart[type]);
61
- const [selectedIndex, setSelectedIndex] = useState(-1);
66
+ const [data] = useState(
67
+ automate?.id ? typeAutoSmart[AUTOMATE_TYPE.AUTOMATE] : typeAutoSmart[type]
68
+ );
69
+ const [selectedIndex, setSelectedIndex] = useState(
70
+ automate?.id ? data.findIndex((obj) => obj.type === type) : -1
71
+ );
62
72
 
63
73
  const handleOnContinue = useCallback(() => {
64
- const automate = data[selectedIndex];
74
+ const dataAutomate = data[selectedIndex];
65
75
  const params = {
66
- type: automate?.type,
76
+ type: dataAutomate?.type,
67
77
  unit: unit,
68
- ...(automate?.data || {}),
78
+ ...(dataAutomate?.data || {}),
69
79
  isAutomateTab,
70
80
  isMultiUnits,
71
- routeName: automate?.route,
72
- automateId,
81
+ automateId: automate?.id,
82
+ routeName: dataAutomate?.route,
83
+ automate,
73
84
  scriptName,
74
85
  };
75
86
 
76
- if (automate.type === AUTOMATE_TYPE.VALUE_CHANGE && isMultiUnits) {
87
+ if (dataAutomate.type === AUTOMATE_TYPE.VALUE_CHANGE && isMultiUnits) {
77
88
  navigate(Routes.SelectUnit, params);
78
89
  } else {
79
- navigate(automate.route, params);
90
+ navigate(dataAutomate.route, params);
80
91
  }
81
92
  }, [
82
93
  navigate,
@@ -85,7 +96,7 @@ const AddNewAutoSmart = memo(({ route }) => {
85
96
  unit,
86
97
  isAutomateTab,
87
98
  isMultiUnits,
88
- automateId,
99
+ automate,
89
100
  scriptName,
90
101
  ]);
91
102
 
@@ -107,7 +118,7 @@ const AddNewAutoSmart = memo(({ route }) => {
107
118
  <HeaderCustom isShowClose onClose={onClose} />
108
119
  <View style={styles.container}>
109
120
  <Text semibold type={'H2'} style={styles.titleCreate}>
110
- {automateId ? t('update_smart') : t('create_smart')}
121
+ {automate?.id ? t('update_smart') : t('create_smart')}
111
122
  </Text>
112
123
  <Text type={'Body'} style={styles.titleChoose}>
113
124
  {t('choose_the_automation_method_you_want')}
@@ -52,7 +52,12 @@ describe('test AddNewOneTap', () => {
52
52
  test('create AddNewOneTap success', async () => {
53
53
  Platform.OS = 'ios';
54
54
  let route = {
55
- params: { type: 'one_tap', unit: { id: 1 } },
55
+ params: {
56
+ type: 'one_tap',
57
+ unit: { id: 1 },
58
+ isMultiUnits: false,
59
+ isAutomateTab: false,
60
+ },
56
61
  };
57
62
 
58
63
  const response = {
@@ -103,6 +108,9 @@ describe('test AddNewOneTap', () => {
103
108
  id: 1,
104
109
  },
105
110
  isCreateScriptSuccess: true,
111
+ automate: {},
112
+ isAutomateTab: false,
113
+ isMultiUnits: false,
106
114
  });
107
115
  });
108
116
  test('create AddNewOneTap fail', async () => {
@@ -20,6 +20,7 @@ const AddNewOneTap = memo(({ route }) => {
20
20
  type,
21
21
  unit,
22
22
  automateData = {},
23
+ automate = {},
23
24
  isAutomateTab,
24
25
  isMultiUnits,
25
26
  automateId,
@@ -45,6 +46,7 @@ const AddNewOneTap = memo(({ route }) => {
45
46
  id: data.id,
46
47
  name: name,
47
48
  type: type,
49
+ automate,
48
50
  havePermission: true,
49
51
  isCreateScriptSuccess: true,
50
52
  isAutomateTab: automateId ? false : isAutomateTab,
@@ -60,6 +62,7 @@ const AddNewOneTap = memo(({ route }) => {
60
62
  name,
61
63
  automateData,
62
64
  automateId,
65
+ automate,
63
66
  navigate,
64
67
  isAutomateTab,
65
68
  t,
@@ -17,7 +17,6 @@ import ItemOneTap from '../../commons/SubUnit/OneTap/ItemOneTap';
17
17
  import Routes from '../../utils/Route';
18
18
  import { useGetIdUser } from '../../hooks/Common';
19
19
  import ItemAddNew from '../../commons/Device/ItemAddNew';
20
- import { REPEAT_OPTIONS } from '../SetSchedule/components/RepeatOptionsPopup';
21
20
 
22
21
  const MultiUnits = () => {
23
22
  const t = useTranslations();
@@ -53,55 +52,6 @@ const MultiUnits = () => {
53
52
  setTabActive(tab);
54
53
  };
55
54
 
56
- const textCondition = useCallback(
57
- (item) => {
58
- const {
59
- type,
60
- condition,
61
- config,
62
- value,
63
- repeat,
64
- date_repeat,
65
- time_repeat,
66
- weekday_repeat,
67
- } = item;
68
-
69
- if (type === AUTOMATE_TYPE.VALUE_CHANGE) {
70
- let _condition;
71
- if (condition === '>') {
72
- _condition = 'higher_than';
73
- } else if (condition === '<') {
74
- _condition = 'lower_than';
75
- } else if (condition === '=') {
76
- _condition = 'equal';
77
- }
78
- return `${config} ${t(_condition)} ${value}`;
79
- } else if (type === AUTOMATE_TYPE.SCHEDULE) {
80
- const time = time_repeat.substring(0, time_repeat.length - 3);
81
- const date = date_repeat.split('-').reverse().join('/');
82
- const weekday = {
83
- 0: 'Mon',
84
- 1: 'Tue',
85
- 2: 'Wed',
86
- 3: 'Thu',
87
- 4: 'Fri',
88
- 5: 'Sat',
89
- 6: 'Sun',
90
- };
91
-
92
- if (repeat === REPEAT_OPTIONS.ONCE) {
93
- return `${time} ${date}`;
94
- } else if (repeat === REPEAT_OPTIONS.EVERYDAY) {
95
- return `${t('every_day_at', { time })}`;
96
- } else if (repeat === REPEAT_OPTIONS.EVERYWEEK) {
97
- return weekday_repeat.map((item) => weekday[item]).join(', ');
98
- }
99
- }
100
- return null;
101
- },
102
- [t]
103
- );
104
-
105
55
  const onPressItem = (item) => () => {
106
56
  navigate(Routes.UnitStack, {
107
57
  screen: Routes.ScriptDetail,
@@ -112,7 +62,7 @@ const MultiUnits = () => {
112
62
  havePermission: idUser === item?.user,
113
63
  unit,
114
64
  isMultiUnits,
115
- textCondition: textCondition(item),
65
+ automate: item,
116
66
  },
117
67
  });
118
68
  };
@@ -125,8 +75,9 @@ const MultiUnits = () => {
125
75
  tabActive === t('Scenario')
126
76
  ? AUTOMATE_TYPE.ONE_TAP_ONLY
127
77
  : AUTOMATE_TYPE.VALUE_CHANGE,
78
+ unit: { id: unit?.id },
128
79
  isAutomateTab: true,
129
- isMultiUnits: true,
80
+ isMultiUnits,
130
81
  },
131
82
  });
132
83
  // eslint-disable-next-line react-hooks/exhaustive-deps