@eohjsc/react-native-smart-city 0.3.78 → 0.3.80

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/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.3.78",
4
+ "version": "0.3.80",
5
5
  "description": "TODO",
6
6
  "main": "index.js",
7
7
  "files": [
@@ -80,4 +80,16 @@ describe('Test SetupGeneratePasscode', () => {
80
80
  const wheelDateTimePicker = instance.findAllByType(WheelDateTimePicker);
81
81
  expect(wheelDateTimePicker).toHaveLength(3);
82
82
  });
83
+
84
+ it('Test onTimePicked', async () => {
85
+ await act(async () => {
86
+ tree = await create(wrapComponent());
87
+ });
88
+ const instance = tree.root;
89
+ const wheelDateTimePickers = instance.findAllByType(WheelDateTimePicker);
90
+ await act(async () => {
91
+ wheelDateTimePickers[0].props.onPicked(new Date(2022, 10, 10));
92
+ });
93
+ expect(wheelDateTimePickers[0].props.defaultValue).toBe(1668038400000);
94
+ });
83
95
  });
@@ -17,10 +17,10 @@ import SvgCurrentState from '../../../assets/images/Device/current-state.svg';
17
17
  import SvgWindStrength from '../../../assets/images/Device/wind-strength.svg';
18
18
 
19
19
  function getOptionValue(option, allow_config_store_value) {
20
- if (option.value_text && !allow_config_store_value) {
21
- return option.value_text;
20
+ if (option?.value_text && !allow_config_store_value) {
21
+ return option?.value_text;
22
22
  }
23
- return option.value_int;
23
+ return option?.value_int;
24
24
  }
25
25
 
26
26
  const OptionsDropdownActionTemplate = ({
@@ -29,7 +29,7 @@ const OptionsDropdownActionTemplate = ({
29
29
  sensor = {},
30
30
  }) => {
31
31
  const t = useTranslations();
32
- const { configuration = {}, title } = actionGroup;
32
+ const { configuration = {}, title = '' } = actionGroup;
33
33
  const {
34
34
  action_data,
35
35
  options = [],
@@ -105,7 +105,7 @@ const OptionsDropdownActionTemplate = ({
105
105
  if (!config) {
106
106
  return t('not_available');
107
107
  }
108
- return selectedOption.text;
108
+ return selectedOption?.text;
109
109
  }, [config, selectedOption?.text, t]);
110
110
 
111
111
  const iconSvg = useMemo(() => {
@@ -155,7 +155,7 @@ const OptionsDropdownActionTemplate = ({
155
155
  <AlertAction
156
156
  visible={stateAlert.visible}
157
157
  hideModal={hideAlertAction}
158
- title={stateAlert.title}
158
+ title={title}
159
159
  message={stateAlert.message}
160
160
  leftButtonTitle={stateAlert.leftButton}
161
161
  leftButtonClick={hideAlertAction}
@@ -190,7 +190,7 @@ const OptionsDropdownActionTemplate = ({
190
190
  setSelectedIndex(index);
191
191
  }}
192
192
  >
193
- <Text style={styles.text}>{item.text}</Text>
193
+ <Text style={styles.text}>{item?.text}</Text>
194
194
  </TouchableOpacity>
195
195
  </View>
196
196
  ))}
@@ -30,19 +30,14 @@ const SliderRangeTemplate = memo(({ actionGroup = {}, doAction, sensor }) => {
30
30
  const [valueBrightness, setValueBrightness] = useState(getPercent());
31
31
  const [isFirstTime, setIsFirstTime] = useState(true);
32
32
 
33
- // TODO Thinh: remove action_brightness_data
34
33
  const onChangeBrightness = useCallback(
35
34
  async (value) => {
36
35
  await doAction(
37
- configuration?.action_brightness_data || configuration?.action_data,
36
+ configuration?.action_data,
38
37
  JSON.stringify({ value_brness: value, value: value })
39
38
  );
40
39
  },
41
- [
42
- configuration?.action_brightness_data,
43
- configuration?.action_data,
44
- doAction,
45
- ]
40
+ [configuration?.action_data, doAction]
46
41
  );
47
42
 
48
43
  useEffect(() => {
@@ -250,7 +250,7 @@ describe('Test NumberUpDownActionTemplate', () => {
250
250
  });
251
251
 
252
252
  const text = instance.findByType(Text);
253
- expect(text.props.children).toEqual('24 *C'); // TODO should 24, configValues make changes again
253
+ expect(text.props.children).toEqual('24 *C');
254
254
  });
255
255
 
256
256
  it('action up with allow_config_store_value false', async () => {
@@ -276,7 +276,7 @@ describe('Test NumberUpDownActionTemplate', () => {
276
276
  });
277
277
 
278
278
  const text = instance.findByType(Text);
279
- expect(text.props.children).toEqual('26 *C'); // TODO should 26, configValues make changes again
279
+ expect(text.props.children).toEqual('26 *C');
280
280
  });
281
281
 
282
282
  it('action down limit ', async () => {
@@ -66,26 +66,6 @@ describe('Test SliderRangeTemplate', () => {
66
66
  );
67
67
  });
68
68
 
69
- it('render template SliderRangeTemplate with data backward compatible', async () => {
70
- actionGroup.configuration.action_data = undefined;
71
- actionGroup.configuration.action_brightness_data = action_data;
72
- useConfigGlobalState.mockImplementation(() => [{}, jest.fn()]);
73
- const sensor = { is_managed_by_backend: true, name: 'Sensor' };
74
- await act(async () => {
75
- wrapper = await create(wrapComponent(actionGroup, mockDoAction, sensor));
76
- });
77
- const instance = wrapper.root;
78
- const silderRange = instance.findAllByType(SliderRange);
79
- expect(silderRange).toHaveLength(1);
80
- await act(async () => {
81
- await silderRange[0].props.onSlidingComplete(50);
82
- });
83
- expect(mockDoAction).toHaveBeenCalledWith(
84
- action_data,
85
- JSON.stringify({ value_brness: 50, value: 50 })
86
- );
87
- });
88
-
89
69
  it('render template SliderRangeTemplate with config value not null', async () => {
90
70
  useConfigGlobalState.mockImplementation(() => [
91
71
  {
@@ -5,7 +5,6 @@ export const useDropdownAction = () => {
5
5
  const t = useTranslations();
6
6
  const [stateAlert, setStateAlert] = useState({
7
7
  visible: false,
8
- title: 'Fan Speed',
9
8
  message: '',
10
9
  leftButton: t('cancel'),
11
10
  rightButton: t('done'),
@@ -49,7 +49,7 @@ const FlatListItems = memo(({ data, style, title, offsetTitle }) => {
49
49
  key={item?.id}
50
50
  standard={item.standard}
51
51
  value={item.value}
52
- measure={item.measure}
52
+ measure={item.unit}
53
53
  evaluate={item.evaluate}
54
54
  style={styles.boxStatus}
55
55
  descriptionScreen={Routes.TDSGuide}
@@ -17,7 +17,7 @@ const ListQualityIndicator = ({ data, style }) => {
17
17
  standard={item.standard}
18
18
  value={getValue}
19
19
  evaluate={item.evaluate}
20
- measure={item.measure}
20
+ measure={item.unit}
21
21
  />
22
22
  );
23
23
  }, []);
@@ -122,7 +122,7 @@ const SelectGateway = ({
122
122
  onRightClick={onRightClickNext}
123
123
  accessibilityLabelPrefix={AccessibilityLabel.PREFIX.SELECT_UNIT}
124
124
  />
125
- <ModalCustom // todo Huy - make reused component
125
+ <ModalCustom // todo Nhat - make reused component
126
126
  onBackButtonPress={goBack}
127
127
  isVisible={showPopupGuide}
128
128
  style={styles.modal}
@@ -53,7 +53,7 @@ const API = {
53
53
  },
54
54
  DEVICE: {
55
55
  SENSOR_DETAIL: (id) => `/property_manager/sensors/${id}/`,
56
- DISPLAY: (id) => `/property_manager/sensors/${id}/display/`,
56
+ DISPLAY: (id) => `/property_manager/devices/${id}/display/`,
57
57
  SIDE_MENU_DETAIL: (id, side_menu_id) =>
58
58
  `/property_manager/devices/${id}/display/side_menu/${side_menu_id}/`,
59
59
  DISPLAY_VALUES_V2: (id) =>
@@ -260,6 +260,8 @@ export const NOTIFICATION_TYPES = {
260
260
  NOTIFY_REMOVE_SUB_UNIT: 'NOTIFY_REMOVE_SUB_UNIT',
261
261
  NOTIFY_REMOVE_DEVICE: 'NOTIFY_REMOVE_DEVICE',
262
262
  NOTIFY_EMERGENCY: 'NOTIFY_EMERGENCY',
263
+ NOTIFY_CHANGE_UNIT_OLD_OWNER: 'NOTIFY_CHANGE_UNIT_OLD_OWNER',
264
+ NOTIFY_CHANGE_UNIT_NEW_OWNER: 'NOTIFY_CHANGE_UNIT_NEW_OWNER',
263
265
  AIR_QUALITY: 'AIR_QUALITY',
264
266
  TURBIDITY: 'TURBIDITY',
265
267
  PH: 'PH',
@@ -283,3 +283,36 @@ export const STM32_ANALOG_WRITE = [
283
283
  { key: '73', value: 'PB14' },
284
284
  { key: '74', value: 'PB4' },
285
285
  ];
286
+
287
+ export const ESP8266_DIGITAL = [
288
+ { key: '0', value: 'GPIO 0 - D3' },
289
+ { key: '1', value: 'GPIO 1 - D10 - UART 0 TX' },
290
+ { key: '2', value: 'GPIO 2 - D4 - UART 0 TX2' },
291
+ { key: '3', value: 'GPIO 3 - D9 - UART 0 RX' },
292
+ { key: '4', value: 'GPIO 4 - D2' },
293
+ { key: '5', value: 'GPIO 5 - D1' },
294
+ { key: '12', value: 'GPIO 12 - D6' },
295
+ { key: '13', value: 'GPIO 13 - D7 - UART 1 RX' },
296
+ { key: '14', value: 'GPIO 14 - D5' },
297
+ { key: '15', value: 'GPIO 15 - D8 - UART 1 TX' },
298
+ { key: '16', value: 'GPIO 16 - D0' },
299
+ ];
300
+
301
+ export const ESP8266_ANALOG_READ = [{ key: '17', value: 'GPIO 17 - A0' }];
302
+
303
+ export const ESP8266_ANALOG_WRITE = [
304
+ { key: '0', value: 'GPIO 0 - D3' },
305
+ { key: '1', value: 'GPIO 1 - D10 - UART 0 TX' },
306
+ { key: '2', value: 'GPIO 2 - D4 - UART 0 TX2' },
307
+ { key: '3', value: 'GPIO 3 - D9 - UART 0 RX' },
308
+ { key: '4', value: 'GPIO 4 - D2' },
309
+ { key: '5', value: 'GPIO 5 - D1' },
310
+ { key: '12', value: 'GPIO 12 - D6' },
311
+ { key: '13', value: 'GPIO 13 - D7 - UART 1 RX' },
312
+ { key: '14', value: 'GPIO 14 - D5' },
313
+ { key: '15', value: 'GPIO 15 - D8 - UART 1 TX' },
314
+ ];
315
+
316
+ export const LANGUAGE = {
317
+ DEFAULT: 'vi',
318
+ };
@@ -169,7 +169,7 @@ const SelectAction = memo(({ route }) => {
169
169
  Alert.alert('', t('choose_only_one'));
170
170
  return;
171
171
  }
172
- if (isSelectSensor || isSetupEvent) {
172
+ if (isSelectSensor || sensorData?.length > 0) {
173
173
  await checkConditionToContinue();
174
174
  } else {
175
175
  if (automateId) {
@@ -441,7 +441,7 @@ const SelectAction = memo(({ route }) => {
441
441
  onSelectAction={handleOnSelectAction}
442
442
  accessibilityLabel={AccessibilityLabel.ACTION_ITEM}
443
443
  />
444
- {/* TODO: Huy - refactor/combine with value_change case */}
444
+ {/* TODO: Nhat - refactor/combine with value_change case */}
445
445
  {!!sensorData &&
446
446
  sensorData.map((item) => {
447
447
  const isHasValue = !!item?.value;
@@ -1,11 +1,11 @@
1
1
  export const getConfigControlFromDeviceDisplay = (deviceDisplay) => {
2
2
  const configIds = [];
3
- deviceDisplay?.items.map((item) => {
3
+ (deviceDisplay?.items || []).map((item) => {
4
4
  if (item.type !== 'action') {
5
5
  return;
6
6
  }
7
- const actionGroup = item.configuration;
8
- const { configuration } = actionGroup;
7
+ const actionGroup = item?.configuration || {};
8
+ const { configuration = {} } = actionGroup;
9
9
 
10
10
  switch (actionGroup.template) {
11
11
  case 'on_off_button_action_template':
@@ -21,7 +21,7 @@ export const getConfigControlFromDeviceDisplay = (deviceDisplay) => {
21
21
  }
22
22
  break;
23
23
  case 'StatesGridActionTemplate':
24
- configuration.options.forEach((option) => {
24
+ (configuration?.options || []).forEach((option) => {
25
25
  configIds.push(option.config);
26
26
  });
27
27
  break;
@@ -54,6 +54,7 @@ describe('test NotificationItem', () => {
54
54
  NOTIFICATION_TYPES.NOTIFY_MEMBER_LEAVE_UNIT,
55
55
  NOTIFICATION_TYPES.NOTIFY_REMOVE_SUB_UNIT,
56
56
  NOTIFICATION_TYPES.NOTIFY_REMOVE_DEVICE,
57
+ NOTIFICATION_TYPES.NOTIFY_CHANGE_UNIT_OLD_OWNER,
57
58
  ];
58
59
 
59
60
  for (const content_code of listCase2) {
@@ -76,6 +77,7 @@ describe('test NotificationItem', () => {
76
77
  NOTIFICATION_TYPES.NOTIFY_UPDATE_ADDRESS,
77
78
  NOTIFICATION_TYPES.NOTIFY_RENAME_SUB_UNIT,
78
79
  NOTIFICATION_TYPES.NOTIFY_INVITE_MEMBER,
80
+ NOTIFICATION_TYPES.NOTIFY_CHANGE_UNIT_NEW_OWNER,
79
81
  ];
80
82
 
81
83
  for (const content_code of listCaseUnitDetail) {
@@ -355,6 +355,29 @@ const NotificationItem = memo(({ item }) => {
355
355
  default:
356
356
  return null;
357
357
  }
358
+ case NOTIFICATION_TYPES.NOTIFY_CHANGE_UNIT_OLD_OWNER:
359
+ return {
360
+ content: customColorText(
361
+ t('text_notification_content_change_unit_for_old_owner')
362
+ ),
363
+ redirect: () => null,
364
+ iconContent: <Image source={Images.logo} style={styles.logo} />,
365
+ };
366
+ case NOTIFICATION_TYPES.NOTIFY_CHANGE_UNIT_NEW_OWNER:
367
+ return {
368
+ content: customColorText(
369
+ t('text_notification_content_change_unit_for_new_owner')
370
+ ),
371
+ redirect: () => {
372
+ navigation.navigate(Routes.UnitStack, {
373
+ screen: Routes.UnitDetail,
374
+ params: {
375
+ unitId,
376
+ },
377
+ });
378
+ },
379
+ iconContent: <Image source={Images.logo} style={styles.logo} />,
380
+ };
358
381
  default:
359
382
  return null;
360
383
  }
@@ -419,7 +419,7 @@ const ScriptDetail = ({ route }) => {
419
419
  [AUTOMATE_TYPE.EVENT, AUTOMATE_TYPE.EVENT_ACTION].includes(type)
420
420
  ) {
421
421
  const { action, end_device_name, config_name, sensor_type, value } =
422
- automate?.event;
422
+ automate?.event || automate?.event_action || automate?.event_sensor;
423
423
  let textEvent = '';
424
424
  if (config_name) {
425
425
  const stateConditionData = STATE_VALUE_SENSOR_TYPES.find(
@@ -35,7 +35,11 @@ jest.mock('@react-navigation/native', () => {
35
35
 
36
36
  describe('Test Detail', () => {
37
37
  useRoute.mockReturnValue({
38
- params: {},
38
+ params: {
39
+ item: {
40
+ id: 1,
41
+ },
42
+ },
39
43
  });
40
44
  let tree;
41
45
 
@@ -43,9 +47,9 @@ describe('Test Detail', () => {
43
47
  mock.onGet(API.DEV_MODE.DASHBOARD.GET_WIDGETS(1)).reply(200, [
44
48
  {
45
49
  id: 1,
46
- type: 'camera',
50
+ type: 'value',
47
51
  configuration: {
48
- uri: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
52
+ configs: [{ id: 1 }],
49
53
  },
50
54
  },
51
55
  ]);
@@ -81,8 +85,21 @@ describe('Test Detail', () => {
81
85
  await TouchableOpacities[1].props.onPress();
82
86
  });
83
87
  const menuActionMore = instance.findByType(MenuActionMore);
88
+ const mockDoAction = jest.fn();
89
+ const item = {
90
+ text: 'text',
91
+ doAction: mockDoAction,
92
+ };
93
+ await act(async () => {
94
+ await menuActionMore.props.onItemClick(item);
95
+ });
96
+ expect(mockDoAction).toBeCalled();
84
97
  const modalPopupCT = instance.findByType(ModalPopupCT);
85
98
  mock.onGet(API.DEV_MODE.DASHBOARD.DETAIL(1)).reply(200);
99
+ await act(async () => {
100
+ await menuActionMore.props.listMenuItem[0].doAction();
101
+ });
102
+ expect(mockNavigate).toHaveBeenCalled();
86
103
  await act(async () => {
87
104
  await menuActionMore.props.listMenuItem[3].doAction();
88
105
  });
@@ -690,6 +690,8 @@
690
690
  "text_notification_content_emergency": "The Emergency button has been activated at **unit_name**: **sub_unit_name**. Please check now!",
691
691
  "text_notification_content_emergency_resolve": "Emergency situation activated at **unit_name**: **sub_unit_name** has resolved.",
692
692
  "text_notification_content_invite_member": "**unit_owner_name** invited you to join **unit_name**.",
693
+ "text_notification_content_change_unit_for_old_owner": "Your ownership of **unit_name** has been assigned to **new_owner_name**.",
694
+ "text_notification_content_change_unit_for_new_owner": "You are now the owner of **unit_name**.",
693
695
  "this_spot_does_not_exsit": "This spot does not exist",
694
696
  "please_scan_again_or_contact_the_parking_manager": "Please scan again or contact the parking manager",
695
697
  "this_spot_does_not_support_to_scan": "This spot does not support to scan",
@@ -704,6 +704,8 @@
704
704
  "text_notification_content_emergency": "Một tình huống khẩn cấp vừa được kích hoạt tại **unit_name**: **sub_unit_name**. Vui lòng kiểm tra ngay!",
705
705
  "text_notification_content_emergency_resolve": "Tình huống khẩn cấp được kích hoạt tại **unit_name**: **sub_unit_name** đã được giải quyết.",
706
706
  "text_notification_content_invite_member": "**unit_owner_name** mời bạn đến địa điểm **unit_name**.",
707
+ "text_notification_content_change_unit_for_old_owner": "Quyền sở hữu **unit_name** của bạn đã được chỉ định cho **new_owner_name**.",
708
+ "text_notification_content_change_unit_for_new_owner": "Bạn hiện là chủ sở hữu của **unit_name**.",
707
709
  "this_spot_does_not_exsit": "Vị trí đỗ này không tồn tại",
708
710
  "please_scan_again_or_contact_the_parking_manager": "Vui lòng quét lại hoặc liên hệ với người quản lý bãi đậu xe",
709
711
  "this_spot_does_not_support_to_scan": "Vị trí đỗ này không hỗ trợ quét",
@@ -18,6 +18,9 @@ import {
18
18
  WRITE_DIGITAL_PIN_MODE,
19
19
  WRITE_ANALOG_PIN_MODE,
20
20
  LANGUAGE,
21
+ ESP8266_DIGITAL,
22
+ ESP8266_ANALOG_READ,
23
+ ESP8266_ANALOG_WRITE,
21
24
  } from '../configs/IOPinConstants';
22
25
 
23
26
  export const setAxiosDefaultAuthToken = (token) => {
@@ -150,8 +153,8 @@ export const notImplemented = (t) => {
150
153
  };
151
154
 
152
155
  export const roundNumber = (value, round = 2) => {
153
- if (!isNaN) {
154
- return Math.round((value || 0) * 10 ** round) / 10 ** round;
156
+ if (typeof value === 'string') {
157
+ return Math.round((isNaN(value) ? 0 : value) * 10 ** round) / 10 ** round;
155
158
  }
156
159
  return value;
157
160
  };
@@ -168,6 +171,16 @@ export const PIN_MODE_MAPPING = {
168
171
  };
169
172
 
170
173
  export const PIN_MAPPING = {
174
+ esp8266: {
175
+ read: {
176
+ boolean: ESP8266_DIGITAL,
177
+ integer: ESP8266_ANALOG_READ,
178
+ },
179
+ write: {
180
+ boolean: ESP8266_DIGITAL,
181
+ integer: ESP8266_ANALOG_WRITE,
182
+ },
183
+ },
171
184
  esp32: {
172
185
  read: {
173
186
  boolean: ESP32_DIGITAL,
@@ -19,6 +19,7 @@ import {
19
19
  ToastBottomHelper,
20
20
  objectIds,
21
21
  notImplemented,
22
+ roundNumber,
22
23
  } from '../Utils';
23
24
 
24
25
  describe('Test utils', () => {
@@ -50,6 +51,9 @@ describe('Test utils', () => {
50
51
  it('test setAxiosDefaultLanguage', () => {
51
52
  setAxiosDefaultLanguage('en');
52
53
  expect(api.headers['Accept-Language']).toBe('en');
54
+
55
+ setAxiosDefaultLanguage();
56
+ expect(api.headers['Accept-Language']).toBe('vi');
53
57
  });
54
58
 
55
59
  it('test setAxiosDefaultAuthToken', () => {
@@ -134,6 +138,7 @@ describe('Test utils', () => {
134
138
  configIds: [],
135
139
  });
136
140
  });
141
+
137
142
  it('test objectIds with devices', async () => {
138
143
  const data = await objectIds([
139
144
  {
@@ -166,4 +171,14 @@ describe('Test utils', () => {
166
171
  });
167
172
  expect(mockTranslate).toBeCalledWith('feature_under_development');
168
173
  });
174
+
175
+ it('Test roundNumber', async () => {
176
+ let result;
177
+ result = await roundNumber('abc');
178
+ expect(result).toBe(0);
179
+ result = await roundNumber('123.123');
180
+ expect(result).toBe(123.12);
181
+ result = await roundNumber(12.12);
182
+ expect(result).toBe(12.12);
183
+ });
169
184
  });