@eohjsc/react-native-smart-city 0.4.0 → 0.4.2

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 (84) hide show
  1. package/package.json +2 -8
  2. package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +2 -1
  3. package/src/commons/ActionGroup/NumberUpDownActionTemplateStyle.js +4 -0
  4. package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +2 -1
  5. package/src/commons/ActionGroup/OptionsDropdownActionTemplateStyle.js +6 -0
  6. package/src/commons/ActionGroup/SliderRangeTemplate.js +4 -2
  7. package/src/commons/ActionGroup/SliderRangeTemplateStyles.js +1 -0
  8. package/src/commons/ActionGroup/StatesGridActionTemplate.js +2 -1
  9. package/src/commons/ActionGroup/StatesGridActionTemplateStyle.js +4 -0
  10. package/src/commons/ActionGroup/ThreeButtonTemplate/components/ThreeButtonDefault.js +7 -1
  11. package/src/commons/ActionGroup/ThreeButtonTemplate/components/ThreeButtonDefaultStyles.js +8 -0
  12. package/src/commons/ActionGroup/ThreeButtonTemplate/index.js +3 -1
  13. package/src/commons/ActionGroup/ThreeButtonTemplate/styles.js +3 -0
  14. package/src/commons/ActionGroup/__test__/OnOffTemplate.test.js +0 -5
  15. package/src/commons/ActionGroup/__test__/OneBigButtonTemplate.test.js +0 -5
  16. package/src/commons/Dashboard/MyUnit/__test__/MyUnit.test.js +24 -42
  17. package/src/commons/Dashboard/MyUnit/index.js +4 -2
  18. package/src/commons/DateTimeRangeChange/index.js +32 -4
  19. package/src/commons/Device/Emergency/EmergencyDetail.js +1 -1
  20. package/src/commons/Device/HistoryChart.js +52 -83
  21. package/src/commons/Device/PMSensor/PMSensorIndicator.js +3 -2
  22. package/src/commons/Device/PMSensor/PMSensorIndicatorStyles.js +3 -0
  23. package/src/commons/Device/ProgressBar/__test__/ProgressBar.test.js +0 -5
  24. package/src/commons/Device/ProgressBar/index.js +2 -2
  25. package/src/commons/Device/ProgressBar/styles.js +5 -0
  26. package/src/commons/Device/RainningSensor/CurrentRainSensor.js +5 -2
  27. package/src/commons/Device/WindDirection/Compass/index.js +9 -1
  28. package/src/commons/Device/WindSpeed/Anemometer/index.js +1 -4
  29. package/src/commons/FlatListDnD/index.js +31 -29
  30. package/src/commons/Form/TextInputPassword.js +2 -0
  31. package/src/commons/SelectActionCard/index.js +1 -1
  32. package/src/commons/SubUnit/OneTap/__test__/SubUnitAutomate.test.js +0 -7
  33. package/src/commons/Text/index.js +2 -2
  34. package/src/context/mockStore.ts +6 -1
  35. package/src/hooks/index.js +2 -1
  36. package/src/hooks/usePrevious.js +9 -0
  37. package/src/navigations/AddGatewayStack.js +0 -5
  38. package/src/screens/AQIGuide/__test__/AQIGuide.test.js +0 -5
  39. package/src/screens/ActivityLog/__test__/index.test.js +0 -9
  40. package/src/screens/AddNewGateway/SelectDeviceType.js +1 -1
  41. package/src/screens/Automate/AddNewAction/ChooseAction.js +19 -2
  42. package/src/screens/Automate/AddNewAction/Components/SelectDevices.js +2 -2
  43. package/src/screens/Automate/AddNewAction/NewActionWrapper.js +11 -7
  44. package/src/screens/Automate/AddNewAction/SelectControlDevices.js +4 -2
  45. package/src/screens/Automate/AddNewAutoSmart/__test__/AddNewAutoSmart.test.js +0 -7
  46. package/src/screens/Automate/EditActionsList/index.js +2 -2
  47. package/src/screens/Automate/OneTap/__test__/AddNewOneTap.test.js +0 -7
  48. package/src/screens/Automate/Scenario/__test__/AddNewOneTap.test.js +0 -7
  49. package/src/screens/Automate/ScriptDetail/__test__/index.test.js +17 -1
  50. package/src/screens/Automate/ScriptDetail/index.js +8 -6
  51. package/src/screens/ChangePosition/__test__/index.test.js +4 -1
  52. package/src/screens/ChangePosition/index.js +24 -21
  53. package/src/screens/ChangePosition/styles.js +19 -4
  54. package/src/screens/Device/__test__/detail.test.js +147 -89
  55. package/src/screens/Device/__test__/mqttDetail.test.js +2 -15
  56. package/src/screens/Device/components/ChartWrapper.js +32 -26
  57. package/src/screens/Device/components/SensorDisplayItem.js +33 -16
  58. package/src/screens/Device/components/VisualChart.js +12 -3
  59. package/src/screens/Device/components/__test__/VisualChart.test.js +0 -7
  60. package/src/screens/Device/detail.js +13 -12
  61. package/src/screens/Device/hooks/useDeviceWatchConfigControl.js +10 -6
  62. package/src/screens/Device/styles.js +1 -1
  63. package/src/screens/Notification/__test__/NotificationItem.test.js +2 -0
  64. package/src/screens/PlayBackCamera/Styles/index.js +1 -1
  65. package/src/screens/PlayBackCamera/index.js +7 -7
  66. package/src/screens/SharedUnit/__test__/ShareUnit.test.js +0 -5
  67. package/src/screens/Sharing/__test__/SelectUser.test.js +0 -7
  68. package/src/screens/SmartAccount/index.js +20 -11
  69. package/src/screens/SubUnit/EditSubUnit.js +1 -2
  70. package/src/screens/SubUnit/__test__/AddSubUnit.test.js +0 -9
  71. package/src/screens/SubUnit/__test__/Detail.test.js +0 -7
  72. package/src/screens/SubUnit/__test__/EditSubUnit.test.js +0 -12
  73. package/src/screens/TDSGuide/__test__/TDSGuide.test.js +0 -6
  74. package/src/screens/UVIndexGuide/__test__/UVIndexGuide.test.js +0 -6
  75. package/src/screens/Unit/__test__/CheckSendEmail.test.js +0 -11
  76. package/src/screens/Unit/__test__/Detail.test.js +0 -12
  77. package/src/screens/Unit/__test__/ManageUnit.test.js +0 -8
  78. package/src/screens/UnitSummary/components/PowerConsumption/index.js +4 -6
  79. package/src/screens/WaterQualityGuide/__test__/index.test.js +0 -5
  80. package/src/utils/I18n/translations/en.js +3 -1
  81. package/src/utils/I18n/translations/vi.js +3 -1
  82. package/src/utils/Route/index.js +0 -1
  83. package/src/screens/AddNewGateway/PlugAndPlay/ConnectRouterGuide.js +0 -49
  84. package/src/screens/AddNewGateway/PlugAndPlay/__test__/ConnectRouterGuide.test.js +0 -68
@@ -6,6 +6,9 @@ export default StyleSheet.create({
6
6
  paddingHorizontal: 16,
7
7
  marginBottom: 10,
8
8
  },
9
+ marginBottomZero: {
10
+ marginBottom: 0,
11
+ },
9
12
  centerItem: {
10
13
  flex: 1,
11
14
  justifyContent: 'center',
@@ -6,11 +6,6 @@ import Text from '../../../Text';
6
6
  import { SCProvider } from '../../../../context';
7
7
  import { mockSCStore } from '../../../../context/mockStore';
8
8
 
9
- jest.mock('react-redux', () => ({
10
- ...jest.requireActual('react-redux'),
11
- useSelector: jest.fn(),
12
- }));
13
-
14
9
  const wrapComponent = (item, data) => (
15
10
  <SCProvider initState={mockSCStore({})}>
16
11
  <ProgressBar item={item} data={data} />
@@ -7,7 +7,7 @@ import { useTranslations } from '../../../hooks/Common/useTranslations';
7
7
  import Text from '../../Text';
8
8
  import styles from './styles';
9
9
 
10
- const ProgressBar = memo(({ data = [], item }) => {
10
+ const ProgressBar = memo(({ data = [], item, isWidgetOrder }) => {
11
11
  const t = useTranslations();
12
12
 
13
13
  const maxValue = useMemo(() => {
@@ -17,7 +17,7 @@ const ProgressBar = memo(({ data = [], item }) => {
17
17
  const percent = value / maxValue; // a number between 0 and 1
18
18
  const isNotValue = ['', null, undefined, NaN].includes(value);
19
19
  return (
20
- <View style={styles.container}>
20
+ <View style={(isWidgetOrder && styles.wrapOrderItem) || styles.container}>
21
21
  <Text size={16} style={styles.textLabel}>
22
22
  {item?.label || 'Label'}
23
23
  </Text>
@@ -13,6 +13,11 @@ export default StyleSheet.create({
13
13
  borderColor: Colors.Gray4,
14
14
  marginBottom: 12,
15
15
  },
16
+ wrapOrderItem: {
17
+ flex: 1,
18
+ padding: 16,
19
+ flexDirection: 'column',
20
+ },
16
21
  textLabel: {
17
22
  marginLeft: 8,
18
23
  paddingTop: 8,
@@ -9,7 +9,7 @@ import IconComponent from '../../IconComponent';
9
9
  import images from '../../../configs/Images';
10
10
  import FImage from '../../FImage';
11
11
 
12
- const CurrentRainSensor = memo(({ data = [] }) => {
12
+ const CurrentRainSensor = memo(({ data = [], isWidgetOrder }) => {
13
13
  const item = data.length
14
14
  ? data[0]
15
15
  : {
@@ -19,7 +19,7 @@ const CurrentRainSensor = memo(({ data = [] }) => {
19
19
  item.evaluate || {};
20
20
 
21
21
  return (
22
- <View style={styles.standard}>
22
+ <View style={[styles.standard, isWidgetOrder && styles.marginBottomZero]}>
23
23
  <CircleView
24
24
  size={190}
25
25
  backgroundColor={backgroundColor}
@@ -55,6 +55,9 @@ const styles = StyleSheet.create({
55
55
  justifyContent: 'center',
56
56
  marginBottom: 16,
57
57
  },
58
+ marginBottomZero: {
59
+ marginBottom: 0,
60
+ },
58
61
  flatlistContent: {
59
62
  paddingHorizontal: 16,
60
63
  },
@@ -46,7 +46,12 @@ const Compass = memo(({ data = [], ...props }) => {
46
46
  }, [currentRotation, value]);
47
47
 
48
48
  return (
49
- <View style={styles.container}>
49
+ <View
50
+ style={[
51
+ styles.container,
52
+ props?.isWidgetOrder && styles.marginBottomZero,
53
+ ]}
54
+ >
50
55
  <View style={styles.boxCompass}>
51
56
  <Svg
52
57
  width={280}
@@ -570,6 +575,9 @@ const styles = StyleSheet.create({
570
575
  bottom: 50,
571
576
  alignItems: 'center',
572
577
  },
578
+ marginBottomZero: {
579
+ marginBottom: 0,
580
+ },
573
581
  txtTime: {
574
582
  fontSize: 12,
575
583
  color: Colors.Gray8,
@@ -33,7 +33,7 @@ const Anemometer = memo(
33
33
  return Number(item?.configuration?.max_value) || 60;
34
34
  }, [item?.configuration?.max_value]);
35
35
 
36
- const value = data.length ? data[0].value : 0;
36
+ const value = data.length && data[0]?.value ? data[0].value : 0;
37
37
  const measure = data.length ? data[0].unit || data[0].measure : 'm/s';
38
38
 
39
39
  const radius = (size - strokeWidth) / 2;
@@ -129,9 +129,6 @@ const Anemometer = memo(
129
129
  const handleShowToolTip = (value) => () => setIsShowToolTip(value);
130
130
 
131
131
  const valueSize = useMemo(() => {
132
- if ([null, undefined, NaN].includes(value)) {
133
- return [];
134
- }
135
132
  if (value.toString().length < 4) {
136
133
  return [56, 16];
137
134
  }
@@ -1,37 +1,39 @@
1
- import React from 'react';
1
+ import React, { memo } from 'react';
2
2
  import DraggableFlatList from 'react-native-draggable-flatlist';
3
3
 
4
4
  import styles from './styles';
5
5
 
6
- const FlatListDnD = ({
7
- renderItem,
8
- data,
9
- setData,
10
- onDragEnd,
11
- key,
12
- containerStyle,
13
- showsVerticalScrollIndicator = false,
14
- ...props
15
- }) => {
16
- const handleOnDragEnd = ({ data: dragData }) => {
17
- setData && setData(dragData);
18
- };
6
+ const FlatListDnD = memo(
7
+ ({
8
+ renderItem,
9
+ data,
10
+ setData,
11
+ onDragEnd,
12
+ key,
13
+ containerStyle,
14
+ showsVerticalScrollIndicator = false,
15
+ ...props
16
+ }) => {
17
+ const handleOnDragEnd = ({ data: dragData }) => {
18
+ setData && setData(dragData);
19
+ };
19
20
 
20
- const keyExtractor = (item) => {
21
- return `draggable-item-${item?.id}`;
22
- };
21
+ const keyExtractor = (item) => {
22
+ return `draggable-item-${item?.id}`;
23
+ };
23
24
 
24
- return (
25
- <DraggableFlatList
26
- showsVerticalScrollIndicator={showsVerticalScrollIndicator}
27
- data={data}
28
- renderItem={renderItem}
29
- keyExtractor={keyExtractor}
30
- onDragEnd={onDragEnd || handleOnDragEnd}
31
- containerStyle={styles.containerStyle}
32
- {...props}
33
- />
34
- );
35
- };
25
+ return (
26
+ <DraggableFlatList
27
+ showsVerticalScrollIndicator={showsVerticalScrollIndicator}
28
+ data={data}
29
+ renderItem={renderItem}
30
+ keyExtractor={keyExtractor}
31
+ onDragEnd={onDragEnd || handleOnDragEnd}
32
+ containerStyle={styles.containerStyle}
33
+ {...props}
34
+ />
35
+ );
36
+ }
37
+ );
36
38
 
37
39
  export default FlatListDnD;
@@ -31,6 +31,7 @@ const _TextInputPassword = ({
31
31
  autoFocus,
32
32
  multiline,
33
33
  accessibilityLabel,
34
+ setRef,
34
35
  }) => {
35
36
  const errorStyle = !!errorText && styles.errorWrap;
36
37
 
@@ -65,6 +66,7 @@ const _TextInputPassword = ({
65
66
  editable={editable}
66
67
  keyboardType={keyboardType}
67
68
  multiline={multiline}
69
+ ref={setRef}
68
70
  {...(value ? { value } : {})}
69
71
  />
70
72
 
@@ -13,7 +13,7 @@ const SelectActionCard = memo(({ title, action, onPress }) => {
13
13
  <TouchableOpacity onPress={onPress}>
14
14
  <View style={styles.wrapcontent}>
15
15
  <View>
16
- <Text type="Body" color={Colors.Gray7}>
16
+ <Text type="Body" color={Colors.Gray7} ucfirst>
17
17
  {title}
18
18
  </Text>
19
19
  <Text bold type="H4" style={styles.mt4}>
@@ -27,13 +27,6 @@ const wrapComponent = (data, storeData = {}) => (
27
27
  </SCProvider>
28
28
  );
29
29
 
30
- jest.mock('react-redux', () => {
31
- return {
32
- ...jest.requireActual('react-redux'),
33
- useSelector: () => 'vi',
34
- };
35
- });
36
-
37
30
  let tree;
38
31
  let data;
39
32
 
@@ -34,7 +34,7 @@ export default ({
34
34
  color = '#000',
35
35
  size,
36
36
  style: _style,
37
- hilight,
37
+ highlight,
38
38
  ucfirst,
39
39
  uppercase,
40
40
  lowercase,
@@ -145,7 +145,7 @@ export default ({
145
145
  style={[
146
146
  {
147
147
  fontFamily: FONT_PREFIX + '-' + fontStyle,
148
- color: hilight ? Colors.Primary : color,
148
+ color: highlight ? Colors.Primary : color,
149
149
  fontSize: textSize,
150
150
  lineHeight: lineHeight,
151
151
  textAlign: textAlign,
@@ -73,7 +73,10 @@ export const mockSCStore = (data: ContextData): ContextData => {
73
73
  auth: {
74
74
  account: {
75
75
  ...mockDataStore.auth.account,
76
- ...data.auth?.account,
76
+ user: {
77
+ ...mockDataStore.auth.account.user,
78
+ ...data.auth?.account?.user,
79
+ },
77
80
  },
78
81
  },
79
82
  language: data.language ? data.language : mockDataStore.language,
@@ -94,6 +97,8 @@ export const mockSCStore = (data: ContextData): ContextData => {
94
97
  isNetworkConnected: true,
95
98
  isLockWhenPickColor: false,
96
99
  appState: 'active',
100
+ isNeedUpdateCache: false,
101
+ isDeleteUnitSuccessFully: false,
97
102
  ...data.app,
98
103
  },
99
104
  myUnits: [...mockDataStore.myUnits, ...(data?.myUnits || [])],
@@ -1,3 +1,4 @@
1
+ import usePrevious from './usePrevious';
1
2
  import useReceiveNotifications from './useReceiveNotifications';
2
3
 
3
- export { useReceiveNotifications };
4
+ export { useReceiveNotifications, usePrevious };
@@ -0,0 +1,9 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ export default (value) => {
4
+ const ref = useRef();
5
+ useEffect(() => {
6
+ ref.current = value;
7
+ }, [value]);
8
+ return ref.current;
9
+ };
@@ -19,7 +19,6 @@ import ShareWifiPassword from '../screens/AddNewGateway/ShareWifiPassword';
19
19
  import ScanGatewayQR from '../screens/AddNewGateway/ScanGatewayQR';
20
20
  import RenameNewDevices from '../screens/AddNewGateway/RenameNewDevices';
21
21
  import ConnectingWifiGuide from '../screens/AddNewGateway/ConnectingWifiGuide';
22
- import ConnectRouterGuide from '../screens/AddNewGateway/PlugAndPlay/ConnectRouterGuide';
23
22
  import ZigbeeDeviceConnectGuide from '../screens/AddNewGateway/PlugAndPlay/ZigbeeDeviceConnectGuide';
24
23
 
25
24
  const Stack = createStackNavigator();
@@ -84,10 +83,6 @@ export const AddGatewayStack = memo(() => {
84
83
  name={Route.ConnectingWifiGuide}
85
84
  component={ConnectingWifiGuide}
86
85
  />
87
- <Stack.Screen
88
- name={Route.ConnectRouterGuide}
89
- component={ConnectRouterGuide}
90
- />
91
86
  <Stack.Screen
92
87
  name={Route.ZigbeeDeviceConnectGuide}
93
88
  component={ZigbeeDeviceConnectGuide}
@@ -12,11 +12,6 @@ const wrapComponent = () => (
12
12
  </SCProvider>
13
13
  );
14
14
 
15
- jest.mock('react-redux', () => ({
16
- ...jest.requireActual('react-redux'),
17
- useSelector: jest.fn(),
18
- }));
19
-
20
15
  jest.mock('react', () => ({
21
16
  ...jest.requireActual('react'),
22
17
  useLayoutEffect: jest.fn(),
@@ -15,15 +15,6 @@ import Modal from 'react-native-modal';
15
15
  import { AUTOMATE_TYPE, AccessibilityLabel } from '../../../configs/Constants';
16
16
  import api from '../../../utils/Apis/axios';
17
17
 
18
- const mockUseSelector = jest.fn();
19
-
20
- jest.mock('react-redux', () => {
21
- return {
22
- ...jest.requireActual('react-redux'),
23
- useDispatch: jest.fn(),
24
- useSelector: () => mockUseSelector,
25
- };
26
- });
27
18
  jest.mock('react', () => {
28
19
  return {
29
20
  ...jest.requireActual('react'),
@@ -122,7 +122,7 @@ const SelectDeviceType = ({ route }) => {
122
122
  id: 'zigbee',
123
123
  image: <AddZigbeeDeviceIcon width={60} height={60} />,
124
124
  route: subUnit?.id
125
- ? Routes.ConnectRouterGuide
125
+ ? Routes.SelectZigbeeGateway
126
126
  : Routes.SelectDeviceSubUnit,
127
127
  data: {
128
128
  unit,
@@ -12,6 +12,7 @@ import { API } from '../../../configs';
12
12
  import Routes from '../../../utils/Route';
13
13
  import NewActionWrapper from './NewActionWrapper';
14
14
  import moment from 'moment';
15
+ import { ToastBottomHelper } from '../../../utils/Utils';
15
16
 
16
17
  const RenderActionItem = ({ device, item, handleOnSelectAction }) => {
17
18
  switch (item.template) {
@@ -63,7 +64,13 @@ const RenderActionItem = ({ device, item, handleOnSelectAction }) => {
63
64
  const ChooseAction = ({ route }) => {
64
65
  const t = useTranslations();
65
66
  const { navigate } = useNavigation();
66
- const { unitId, device, automateId, index = -1 } = route?.params || {};
67
+ const {
68
+ unitId,
69
+ device,
70
+ automateId,
71
+ index = -1,
72
+ numberActionCanAdd,
73
+ } = route?.params || {};
67
74
  const [data, setData] = useState([]);
68
75
  const [actions, setActions] = useState([]);
69
76
 
@@ -78,6 +85,16 @@ const ChooseAction = ({ route }) => {
78
85
  }, [device.id]);
79
86
 
80
87
  const onSave = useCallback(async () => {
88
+ if (actions.length > numberActionCanAdd) {
89
+ ToastBottomHelper.error(
90
+ `${t('you_can_only_add_more', { number: numberActionCanAdd })} ${t(
91
+ numberActionCanAdd > 1 ? 'actions' : 'action'
92
+ )}`,
93
+ null,
94
+ 3000
95
+ );
96
+ return;
97
+ }
81
98
  let list_action = [...actions];
82
99
  list_action = list_action.map((item) => ({
83
100
  action: item.action,
@@ -97,7 +114,7 @@ const ChooseAction = ({ route }) => {
97
114
  merge: true,
98
115
  params: { saveAt: moment().valueOf() },
99
116
  });
100
- }, [actions, navigate, unitId, automateId]);
117
+ }, [actions, numberActionCanAdd, automateId, unitId, navigate, t]);
101
118
 
102
119
  const handleOnSelectAction = (action) => {
103
120
  let newActions = [...actions];
@@ -57,14 +57,14 @@ const SelectDevices = ({
57
57
 
58
58
  <View style={styles.boxDevices}>
59
59
  {stations[indexStation]?.sensors &&
60
- stations[indexStation].sensors.map((sensor) => (
60
+ stations[indexStation].sensors.map((sensor, index) => (
61
61
  <Device
62
62
  svgMain={sensor.icon || 'sensor'}
63
63
  title={sensor.name}
64
64
  sensor={sensor}
65
65
  isSelectDevice={selectedDevice && selectedDevice.id === sensor.id}
66
66
  onPress={onPressDevice}
67
- key={sensor.id}
67
+ key={(sensor.id + index).toString()}
68
68
  />
69
69
  ))}
70
70
  </View>
@@ -8,6 +8,7 @@ import { Colors } from '../../../configs';
8
8
  import { useNavigation, useRoute } from '@react-navigation/native';
9
9
  import BottomButtonView from '../../../commons/BottomButtonView';
10
10
  import { AccessibilityLabel } from '../../../configs/Constants';
11
+ import { KeyboardAwareScrollView } from '@eohjsc/react-native-keyboard-aware-scroll-view';
11
12
 
12
13
  const NewActionWrapper = ({ name, children, canNext, onNext, nextTitle }) => {
13
14
  const { navigate } = useNavigation();
@@ -33,13 +34,16 @@ const NewActionWrapper = ({ name, children, canNext, onNext, nextTitle }) => {
33
34
 
34
35
  return (
35
36
  <View style={styles.wrap}>
36
- <WrapHeaderScrollable
37
- title={name}
38
- headerAniStyle={styles.headerAniStyle}
39
- rightComponent={rightComponent}
40
- >
41
- {children}
42
- </WrapHeaderScrollable>
37
+ <KeyboardAwareScrollView enableOnAndroid extraScrollHeight={100}>
38
+ <WrapHeaderScrollable
39
+ title={name}
40
+ headerAniStyle={styles.headerAniStyle}
41
+ rightComponent={rightComponent}
42
+ >
43
+ {children}
44
+ </WrapHeaderScrollable>
45
+ </KeyboardAwareScrollView>
46
+
43
47
  <BottomButtonView
44
48
  style={styles.bottomButtonView}
45
49
  mainTitle={nextTitle}
@@ -8,7 +8,8 @@ import { useTranslations } from '../../../hooks/Common/useTranslations';
8
8
 
9
9
  const SelectControlDevices = ({ route }) => {
10
10
  const t = useTranslations();
11
- const { unitId, closeScreen, automateId } = route?.params || {};
11
+ const { unitId, closeScreen, automateId, numberActionCanAdd } =
12
+ route?.params || {};
12
13
 
13
14
  const [stations, setStations] = useState([]);
14
15
  const [listStation, setListStation] = useState([]);
@@ -46,9 +47,10 @@ const SelectControlDevices = ({ route }) => {
46
47
  automateId,
47
48
  device: selectedDevice,
48
49
  closeScreen,
50
+ numberActionCanAdd,
49
51
  });
50
52
  },
51
- [navigate, unitId, automateId, closeScreen]
53
+ [navigate, unitId, automateId, closeScreen, numberActionCanAdd]
52
54
  );
53
55
 
54
56
  if (loading) {
@@ -15,13 +15,6 @@ const wrapComponent = (route) => (
15
15
  </SCProvider>
16
16
  );
17
17
 
18
- jest.mock('react-redux', () => {
19
- return {
20
- ...jest.requireActual('react-redux'),
21
- useSelector: () => 'vi',
22
- };
23
- });
24
-
25
18
  describe('test AddNewAutoSmart', () => {
26
19
  let tree;
27
20
  let route = {
@@ -154,7 +154,7 @@ const EditActionsList = memo(() => {
154
154
  onPress={onCancel}
155
155
  accessibilityLabel={AccessibilityLabel.BUTTON_CANCEL_EDIT_ACTION_LIST}
156
156
  >
157
- <Text type="H4" hilight semibold>
157
+ <Text type="H4" highlight semibold>
158
158
  {t('cancel')}
159
159
  </Text>
160
160
  </TouchableOpacity>
@@ -162,7 +162,7 @@ const EditActionsList = memo(() => {
162
162
  onPress={onPressSave}
163
163
  accessibilityLabel={AccessibilityLabel.BUTTON_SAVE_EDIT_ACTION_LIST}
164
164
  >
165
- <Text type="H4" hilight semibold>
165
+ <Text type="H4" highlight semibold>
166
166
  {t('save')}
167
167
  </Text>
168
168
  </TouchableOpacity>
@@ -22,13 +22,6 @@ const wrapComponent = (route) => {
22
22
  };
23
23
  const mock = new MockAdapter(api.axiosInstance);
24
24
 
25
- jest.mock('react-redux', () => {
26
- return {
27
- ...jest.requireActual('react-redux'),
28
- useSelector: () => 'vi',
29
- };
30
- });
31
-
32
25
  let tree;
33
26
 
34
27
  describe('test OneTap', () => {
@@ -22,13 +22,6 @@ const wrapComponent = (route) => {
22
22
  };
23
23
  const mock = new MockAdapter(api.axiosInstance);
24
24
 
25
- jest.mock('react-redux', () => {
26
- return {
27
- ...jest.requireActual('react-redux'),
28
- useSelector: () => 'vi',
29
- };
30
- });
31
-
32
25
  let tree;
33
26
 
34
27
  describe('test OneTap', () => {
@@ -221,9 +221,24 @@ describe('Test ScriptDetail', () => {
221
221
  });
222
222
 
223
223
  it('test press add action', async () => {
224
+ data = [
225
+ {
226
+ id: 1,
227
+ unit: 1,
228
+ },
229
+ ];
224
230
  mock.onGet(API.AUTOMATE.SCRIPT(1)).reply(200, data);
231
+ const auth = {
232
+ account: {
233
+ user: {
234
+ permissions: {
235
+ max_actions_per_automation: 2,
236
+ },
237
+ },
238
+ },
239
+ };
225
240
  await act(async () => {
226
- tree = await create(wrapComponent(route));
241
+ tree = await create(wrapComponent(route, { auth }));
227
242
  });
228
243
  const instance = tree.root;
229
244
  const button = instance.find(
@@ -238,6 +253,7 @@ describe('Test ScriptDetail', () => {
238
253
  expect(mockNavigate).toHaveBeenCalledWith(Routes.SelectControlDevices, {
239
254
  unitId: route.params.preAutomate.unit,
240
255
  automateId: route.params.preAutomate.id,
256
+ numberActionCanAdd: 2,
241
257
  });
242
258
  });
243
259
 
@@ -208,7 +208,7 @@ const ScriptDetail = ({ route }) => {
208
208
  AccessibilityLabel.BUTTON_EDIT_SCRIPT_ACTION
209
209
  }
210
210
  >
211
- <Text type="Label" hilight>
211
+ <Text type="Label" highlight>
212
212
  {t('edit')}
213
213
  </Text>
214
214
  </TouchableOpacity>
@@ -218,7 +218,7 @@ const ScriptDetail = ({ route }) => {
218
218
  <Item key={item?.id} item={item} index={index} />
219
219
  ))}
220
220
  {!!automate?.can_edit && (
221
- <ItemAdd automate={automate} index={data.length} />
221
+ <ItemAdd automate={automate} numberActionAdded={data.length} />
222
222
  )}
223
223
  </View>
224
224
  </WrapHeaderScrollable>
@@ -294,14 +294,14 @@ const Item = ({ item, index }) => {
294
294
  );
295
295
  };
296
296
 
297
- const ItemAdd = ({ automate, index }) => {
297
+ const ItemAdd = ({ automate, numberActionAdded }) => {
298
298
  const t = useTranslations();
299
299
  const { navigate } = useNavigation();
300
300
  const permissions = useBackendPermission();
301
301
  const { name: currentScreenName } = useRoute();
302
302
 
303
303
  const onPressAddAction = useCallback(() => {
304
- if (permissions?.max_actions_per_automation <= index) {
304
+ if (numberActionAdded >= permissions?.max_actions_per_automation) {
305
305
  ToastBottomHelper.error(
306
306
  t('reach_max_actions_per_automation', {
307
307
  length: permissions?.max_actions_per_automation,
@@ -315,6 +315,8 @@ const ItemAdd = ({ automate, index }) => {
315
315
  unitId: automate.unit,
316
316
  automateId: automate.id,
317
317
  closeScreen: currentScreenName,
318
+ numberActionCanAdd:
319
+ permissions?.max_actions_per_automation - numberActionAdded,
318
320
  };
319
321
 
320
322
  navigate(
@@ -322,8 +324,8 @@ const ItemAdd = ({ automate, index }) => {
322
324
  navParams
323
325
  );
324
326
  }, [
327
+ numberActionAdded,
325
328
  permissions?.max_actions_per_automation,
326
- index,
327
329
  automate.unit,
328
330
  automate.id,
329
331
  currentScreenName,
@@ -335,7 +337,7 @@ const ItemAdd = ({ automate, index }) => {
335
337
  <View style={styles.wrapItem}>
336
338
  <View style={styles.leftItemAdd}>
337
339
  <Text style={styles.number} type="H4" semibold color={Colors.Gray7}>
338
- {index + 1 < 10 ? '0' + (index + 1) : index + 1}
340
+ {(numberActionAdded + 1 < 10 ? '0' : '') + (numberActionAdded + 1)}
339
341
  </Text>
340
342
  </View>
341
343
  <TouchableOpacity
@@ -14,6 +14,7 @@ import BottomButtonView from '../../../commons/BottomButtonView';
14
14
 
15
15
  const mock = new MockAdapter(api.axiosInstance);
16
16
  const mockGoBack = jest.fn();
17
+ const mockSetDisplay = jest.fn();
17
18
 
18
19
  jest.mock('@react-navigation/native', () => {
19
20
  return {
@@ -46,7 +47,8 @@ describe('Test ChangePosition', () => {
46
47
  useRoute.mockReturnValue({
47
48
  params: {
48
49
  sensor: { id: 1, name: 'device' },
49
- displayItems: [{ id: 1 }, { id: 2 }],
50
+ display: { items: [{ id: 1 }, { id: 2 }] },
51
+ setDisplay: mockSetDisplay,
50
52
  station: { id: 1, name: 'station' },
51
53
  evaluate: {},
52
54
  fetchDataDeviceDetail: mockFetchData,
@@ -70,6 +72,7 @@ describe('Test ChangePosition', () => {
70
72
  });
71
73
  expect(mockGoBack).toHaveBeenCalled();
72
74
  expect(mockFetchData).toHaveBeenCalled();
75
+ expect(mockSetDisplay).toHaveBeenCalled();
73
76
  expect(spyToastSuccess).toBeCalledWith('Updated widget successfully');
74
77
  });
75
78
  });