@eohjsc/react-native-smart-city 0.3.30 → 0.3.31

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 (75) hide show
  1. package/package.json +1 -1
  2. package/src/Images/DevMode/close.png +0 -0
  3. package/src/Images/DevMode/close@2x.png +0 -0
  4. package/src/Images/DevMode/close@3x.png +0 -0
  5. package/src/Images/DevMode/plus.png +0 -0
  6. package/src/Images/DevMode/plus@2x.png +0 -0
  7. package/src/Images/DevMode/plus@3x.png +0 -0
  8. package/src/Images/DevMode/remove_circle.png +0 -0
  9. package/src/Images/DevMode/remove_circle@2x.png +0 -0
  10. package/src/Images/DevMode/remove_circle@3x.png +0 -0
  11. package/src/commons/ActionGroup/ColorPickerTemplate.js +36 -17
  12. package/src/commons/ActionGroup/NumberUpDownActionTemplate.js +13 -8
  13. package/src/commons/ActionGroup/OnOffSmartLock/OnOffSmartLock.js +37 -44
  14. package/src/commons/ActionGroup/OnOffSmartLock/OnOffSmartLockStyle.js +1 -0
  15. package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +5 -4
  16. package/src/commons/ActionGroup/OnOffTemplate/index.js +2 -2
  17. package/src/commons/ActionGroup/OneBigButtonTemplate.js +4 -4
  18. package/src/commons/ActionGroup/OptionsDropdownActionTemplate.js +28 -18
  19. package/src/commons/ActionGroup/SliderRangeTemplate.js +2 -2
  20. package/src/commons/ActionGroup/ThreeButtonTemplate.js +48 -58
  21. package/src/commons/ActionGroup/TwoButtonTemplate/index.js +134 -132
  22. package/src/commons/ActionGroup/__test__/index.test.js +2 -2
  23. package/src/commons/ActionGroup/index.js +35 -10
  24. package/src/commons/DevMode/CardDevMode.js +42 -0
  25. package/src/commons/DevMode/EmptyComponent.js +18 -0
  26. package/src/commons/DevMode/Item.js +21 -0
  27. package/src/commons/DevMode/Styles/CardStyles.js +40 -0
  28. package/src/commons/DevMode/Styles/EmptyComponentStyles.js +15 -0
  29. package/src/commons/DevMode/Styles/ItemStyles.js +27 -0
  30. package/src/commons/DevMode/Styles/TextWithLabelStyles.js +36 -0
  31. package/src/commons/DevMode/TextWithLabel.js +30 -0
  32. package/src/commons/DevMode/index.js +5 -1
  33. package/src/commons/Device/DeviceAlertStatus.js +1 -1
  34. package/src/commons/Device/Emergency/EmergencyDetail.js +1 -1
  35. package/src/commons/Device/PMSensor/PMSensorIndicatior.js +1 -1
  36. package/src/commons/Device/RainningSensor/CurrentRainSensor.js +1 -1
  37. package/src/commons/Device/WindDirection/Compass/index.js +1 -1
  38. package/src/commons/Device/WindSpeed/Anemometer/index.js +1 -1
  39. package/src/commons/Header/HeaderCustom.js +8 -2
  40. package/src/commons/MenuActionMore/index.js +3 -1
  41. package/src/commons/Sharing/WrapHeaderScrollable.js +4 -2
  42. package/src/configs/API.js +6 -0
  43. package/src/configs/Colors.js +4 -0
  44. package/src/configs/Images.js +3 -0
  45. package/src/context/actionType.ts +12 -0
  46. package/src/context/mockStore.ts +12 -0
  47. package/src/context/reducer.ts +43 -1
  48. package/src/navigations/Main.js +26 -2
  49. package/src/screens/AddNewGateway/hooks/__Tests__/index.test.js +27 -0
  50. package/src/screens/Device/components/DetailHistoryChart.js +7 -5
  51. package/src/screens/Device/components/SensorDisplayItem.js +49 -24
  52. package/src/screens/Device/detail.js +3 -1
  53. package/src/screens/Drawer/index.js +9 -4
  54. package/src/screens/Template/EditTemplate.js +151 -0
  55. package/src/screens/Template/GatewayList.js +51 -0
  56. package/src/screens/Template/Information.js +41 -0
  57. package/src/screens/Template/Styles/EditTemplateStyle.js +109 -0
  58. package/src/screens/Template/Styles/GatewayStyles.js +46 -0
  59. package/src/screens/Template/Styles/InformationStyles.js +16 -0
  60. package/src/screens/Template/Styles/detailStyles.js +35 -0
  61. package/src/screens/Template/Styles/indexStyles.js +2 -33
  62. package/src/screens/Template/__test__/EditTemplate.test.js +89 -0
  63. package/src/screens/Template/__test__/GatewayList.test.js +26 -0
  64. package/src/screens/Template/__test__/Information.test.js +16 -0
  65. package/src/screens/Template/__test__/detail.test.js +60 -0
  66. package/src/screens/Template/__test__/index.test.js +26 -1
  67. package/src/screens/Template/detail.js +154 -0
  68. package/src/screens/Template/index.js +39 -32
  69. package/src/screens/Unit/SmartAccount.js +1 -1
  70. package/src/screens/Unit/Station/__test__/index.test.js +18 -2
  71. package/src/screens/Unit/__test__/Detail.test.js +73 -43
  72. package/src/screens/Unit/__test__/SmartAccount.test.js +42 -25
  73. package/src/utils/I18n/translations/en.json +11 -1
  74. package/src/utils/I18n/translations/vi.json +9 -1
  75. package/src/utils/Route/index.js +6 -0
@@ -15,7 +15,7 @@ const AnimatedPath = Animated.createAnimatedComponent(Path);
15
15
 
16
16
  const Anemometer = memo(
17
17
  ({
18
- data,
18
+ data = [],
19
19
  maxValue,
20
20
  width = 240,
21
21
  size = 170,
@@ -21,6 +21,9 @@ const HeaderCustom = ({
21
21
  rightComponent,
22
22
  onGoBack,
23
23
  onClose,
24
+ iconLeft,
25
+ wrapTitleStyle,
26
+ iconBackStyle,
24
27
  }) => {
25
28
  const t = useTranslations();
26
29
  const { goBack } = useNavigation();
@@ -41,9 +44,12 @@ const HeaderCustom = ({
41
44
  return (
42
45
  <View style={[styles.wrap, isShowSeparator && styles.separator]}>
43
46
  <TouchableOpacity style={styles.buttonBack} onPress={handleGoback}>
44
- <Image source={Images.arrowBack} style={styles.iconBack} />
47
+ <Image
48
+ source={iconLeft || Images.arrowBack}
49
+ style={[styles.iconBack, iconBackStyle]}
50
+ />
45
51
  </TouchableOpacity>
46
- <View style={styles.wrapTitle}>
52
+ <View style={[styles.wrapTitle, wrapTitleStyle]}>
47
53
  <Text
48
54
  style={[styles.title, titleStyles, !isShowRight && styles.title2]}
49
55
  numberOfLines={1}
@@ -71,7 +71,9 @@ const MenuActionMore = memo(
71
71
  }`}
72
72
  disabled={isDisable}
73
73
  >
74
- <Text style={styles.modalHeaderText}>{item.text}</Text>
74
+ <Text style={[styles.modalHeaderText, item?.textStyle]}>
75
+ {item?.text}
76
+ </Text>
75
77
  </TouchableOpacity>
76
78
  );
77
79
  })}
@@ -29,9 +29,12 @@ const WrapHeaderScrollable = ({
29
29
  headerAniCenterStyle,
30
30
  onGoBack,
31
31
  disableLoadMore = false,
32
+ scrollEnabled = true,
32
33
  }) => {
33
34
  const animatedScrollYValue = useRef(new Animated.Value(0)).current;
34
35
  const [loadingMore, setLoadingMore] = useState(false);
36
+ const [contentHeight, setContentHeight] = useState(0);
37
+
35
38
  const loadMore = useCallback(() => {
36
39
  if (onLoadMore) {
37
40
  setLoadingMore(true);
@@ -39,8 +42,6 @@ const WrapHeaderScrollable = ({
39
42
  }
40
43
  }, [onLoadMore]);
41
44
 
42
- const [contentHeight, setContentHeight] = useState(0);
43
-
44
45
  const onContentSizeChange = useCallback(
45
46
  (_, height) => {
46
47
  setContentHeight(height);
@@ -61,6 +62,7 @@ const WrapHeaderScrollable = ({
61
62
  />
62
63
  <Animated.ScrollView
63
64
  testID={TESTID.ANIMATED_SCROLL}
65
+ scrollEnabled={scrollEnabled}
64
66
  scrollEventThrottle={16}
65
67
  onScroll={Animated.event(
66
68
  [{ nativeEvent: { contentOffset: { y: animatedScrollYValue } } }],
@@ -200,6 +200,12 @@ const API = {
200
200
  PUSHER: {
201
201
  AUTH: () => '/smart_parking/pusher/auth/',
202
202
  },
203
+ // NOTE: DEV MODE
204
+ DEV_MODE: {
205
+ GET_TEMPLATES: '/property_manager/iot_dashboard/dev_mode/templates/',
206
+ GET_WIDGETS: (templateId) =>
207
+ `/property_manager/iot_dashboard/dev_mode/templates/${templateId}/list_widgets/`,
208
+ },
203
209
  };
204
210
 
205
211
  export default API;
@@ -135,6 +135,10 @@ export const Colors = {
135
135
  BlueTransparent5: 'rgba(230, 247, 255, 0.5)',
136
136
  Neutral: {
137
137
  Neutral3: '#E6E6E6',
138
+ Neutral4: '#B3B3B3',
138
139
  Neutral5: '#595959',
139
140
  },
141
+ BlackRussian: '#1D2129',
142
+ Salem: '#008040',
143
+ LightGreen: '#8AE699',
140
144
  };
@@ -19,4 +19,7 @@ export default {
19
19
  gateway: require('../Images/DevMode/gateway.png'),
20
20
  menu: require('../Images/DevMode/menu.png'),
21
21
  search: require('../Images/DevMode/search.png'),
22
+ close: require('../Images/DevMode/close.png'),
23
+ plus: require('../Images/DevMode/plus.png'),
24
+ removeCircle: require('../Images/DevMode/remove_circle.png'),
22
25
  };
@@ -24,6 +24,11 @@ export const Action = {
24
24
  ON_RECEIVE_NOTIFICATION: 'ON_RECEIVE_NOTIFICATION',
25
25
  SET_DEVICES_STATUS: 'SET_DEVICES_STATUS',
26
26
  SET_POPOVER_ANIMATING: 'SET_POPOVER_ANIMATING',
27
+ SET_LOCK_VIEW_PICK_COLOR: 'SET_LOCK_VIEW_PICK_COLOR',
28
+ // NOTE: DEV MODE
29
+ SET_WIDGET_DRAGGING: 'SET_WIDGET_DRAGGING',
30
+ SET_IS_EDITING_TEMPLATE: 'SET_IS_EDITING_TEMPLATE',
31
+ SET_IS_IN_EDIT_TEMPLATE_SCREEN: 'SET_IS_IN_EDIT_TEMPLATE_SCREEN',
27
32
  };
28
33
 
29
34
  export type AuthData = {
@@ -82,6 +87,7 @@ export type AppType = {
82
87
  camera_opened: any[];
83
88
  notificationData: any;
84
89
  popoverAnimating: boolean;
90
+ isLockWhenPickColor: boolean;
85
91
  };
86
92
 
87
93
  export type IoTType = {
@@ -92,3 +98,9 @@ export type IoTType = {
92
98
  statuses: {};
93
99
  };
94
100
  };
101
+
102
+ export type DevModeType = {
103
+ itemDraggingId: any;
104
+ isEditingTemplate: boolean;
105
+ isInEditTemplateScreen: boolean;
106
+ };
@@ -38,6 +38,7 @@ export const mockDataStore: ContextData = {
38
38
  isBluetoothEnabled: true,
39
39
  isNetworkConnected: true,
40
40
  camera_opened: [],
41
+ isLockWhenPickColor: false,
41
42
  },
42
43
  iot: {
43
44
  googlehome: {
@@ -49,6 +50,11 @@ export const mockDataStore: ContextData = {
49
50
  },
50
51
  valueEvaluations: {},
51
52
  fetchedValueEvaluationUnits: [],
53
+ devMode: {
54
+ itemDraggingId: null,
55
+ isEditingTemplate: false,
56
+ isInEditTemplateScreen: false,
57
+ },
52
58
  };
53
59
 
54
60
  export const mockSCStore = (data: ContextData): ContextData => {
@@ -76,6 +82,7 @@ export const mockSCStore = (data: ContextData): ContextData => {
76
82
  isConnectWifiGateway: false,
77
83
  isBluetoothEnabled: true,
78
84
  isNetworkConnected: true,
85
+ isLockWhenPickColor: false,
79
86
  },
80
87
  unit: {
81
88
  favoriteDeviceIds: [
@@ -104,5 +111,10 @@ export const mockSCStore = (data: ContextData): ContextData => {
104
111
  ...data.valueEvaluations,
105
112
  },
106
113
  fetchedValueEvaluationUnits: [],
114
+ devMode: {
115
+ itemDraggingId: null,
116
+ isEditingTemplate: false,
117
+ isInEditTemplateScreen: false,
118
+ },
107
119
  };
108
120
  };
@@ -11,6 +11,7 @@ import {
11
11
  AutomateType,
12
12
  AppType,
13
13
  IoTType,
14
+ DevModeType,
14
15
  } from './actionType';
15
16
  import { uniq, reduce } from 'lodash';
16
17
 
@@ -26,6 +27,7 @@ export type ContextData = {
26
27
  iot: IoTType;
27
28
  valueEvaluations: {};
28
29
  fetchedValueEvaluationUnits: Array<number>;
30
+ devMode: DevModeType;
29
31
  };
30
32
 
31
33
  export type Action = {
@@ -61,6 +63,7 @@ export const initialState = {
61
63
  camera_opened: [],
62
64
  notificationData: null,
63
65
  popoverAnimating: false,
66
+ isLockWhenPickColor: false,
64
67
  },
65
68
  iot: {
66
69
  googlehome: {
@@ -72,6 +75,11 @@ export const initialState = {
72
75
  },
73
76
  valueEvaluations: {},
74
77
  fetchedValueEvaluationUnits: [],
78
+ devMode: {
79
+ itemDraggingId: null,
80
+ isEditingTemplate: false,
81
+ isInEditTemplateScreen: false,
82
+ },
75
83
  };
76
84
 
77
85
  export const reducer = (currentState: ContextData, action: Action) => {
@@ -317,7 +325,6 @@ export const reducer = (currentState: ContextData, action: Action) => {
317
325
  valueEvaluations: reduce(
318
326
  data,
319
327
  (dict, item) => {
320
- // eslint-disable-next-line no-param-reassign
321
328
  dict[item.config] = item;
322
329
  return dict;
323
330
  },
@@ -351,6 +358,41 @@ export const reducer = (currentState: ContextData, action: Action) => {
351
358
  popoverAnimating: payload,
352
359
  },
353
360
  };
361
+ case Action.SET_LOCK_VIEW_PICK_COLOR:
362
+ return {
363
+ ...currentState,
364
+ app: {
365
+ ...currentState.app,
366
+ isLockWhenPickColor: payload,
367
+ },
368
+ };
369
+ // NOTE: DEV MODE
370
+ case Action.SET_WIDGET_DRAGGING:
371
+ return {
372
+ ...currentState,
373
+ devMode: {
374
+ ...currentState.devMode,
375
+ itemDraggingId: payload,
376
+ },
377
+ };
378
+
379
+ case Action.SET_IS_EDITING_TEMPLATE:
380
+ return {
381
+ ...currentState,
382
+ devMode: {
383
+ ...currentState.devMode,
384
+ isEditingTemplate: payload,
385
+ },
386
+ };
387
+
388
+ case Action.SET_IS_IN_EDIT_TEMPLATE_SCREEN:
389
+ return {
390
+ ...currentState,
391
+ devMode: {
392
+ ...currentState.devMode,
393
+ isInEditTemplateScreen: payload,
394
+ },
395
+ };
354
396
 
355
397
  default:
356
398
  return currentState;
@@ -10,6 +10,7 @@ import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
10
10
  import { createDrawerNavigator } from '@react-navigation/drawer';
11
11
  import { useNavigation } from '@react-navigation/native';
12
12
  import { getStatusBarHeight } from 'react-native-iphone-x-helper';
13
+ import { createStackNavigator } from '@react-navigation/stack';
13
14
 
14
15
  import Tabbar from '../commons/Tabbar';
15
16
  import { Colors, Constants, Images } from '../configs';
@@ -21,9 +22,15 @@ import TemplateStack from './TemplateStack';
21
22
  import DrawerContainer from '../screens/Drawer';
22
23
  import { TESTID } from '../configs/Constants';
23
24
  import Text from '../commons/Text';
25
+ import { screenOptions } from './utils';
26
+ import TemplateDetail from '../screens/Template/detail';
27
+ import Information from '../screens/Template/Information';
28
+ import GatewayList from '../screens/Template/GatewayList';
29
+ import EditTemplate from '../screens/Template/EditTemplate';
24
30
 
25
31
  const Tab = createBottomTabNavigator();
26
32
  const Drawer = createDrawerNavigator();
33
+ const Stack = createStackNavigator();
27
34
 
28
35
  const getWidth = () => {
29
36
  const Width = Constants.width - 12;
@@ -103,18 +110,35 @@ const MainDevMode = () => {
103
110
  );
104
111
  };
105
112
 
106
- const DevModeStack = () => {
113
+ const DrawerScreen = () => {
107
114
  return (
108
115
  <Drawer.Navigator
109
116
  backBehavior="none"
110
117
  drawerContent={(props) => <DrawerContainer {...props} />}
111
118
  drawerStyle={{ paddingTop: getStatusBarHeight() }}
112
119
  >
113
- <Drawer.Screen name={Routes.DrawerMain} component={MainDevMode} />
120
+ <Drawer.Screen name={Routes.MainDevMode} component={MainDevMode} />
114
121
  </Drawer.Navigator>
115
122
  );
116
123
  };
117
124
 
125
+ const DevModeStack = () => {
126
+ return (
127
+ <Stack.Navigator
128
+ screenOptions={{
129
+ ...screenOptions,
130
+ headerShown: false,
131
+ }}
132
+ >
133
+ <Stack.Screen component={DrawerScreen} name={Routes.DrawerScreen} />
134
+ <Stack.Screen component={TemplateDetail} name={Routes.TemplateDetail} />
135
+ <Stack.Screen component={Information} name={Routes.Information} />
136
+ <Stack.Screen component={GatewayList} name={Routes.GatewayList} />
137
+ <Stack.Screen component={EditTemplate} name={Routes.EditTemplate} />
138
+ </Stack.Navigator>
139
+ );
140
+ };
141
+
118
142
  export default DevModeStack;
119
143
 
120
144
  const styles = StyleSheet.create({
@@ -0,0 +1,27 @@
1
+ import { act, renderHook } from '@testing-library/react-hooks';
2
+ import MockAdapter from 'axios-mock-adapter';
3
+ import api from '../../../../utils/Apis/axios';
4
+ import { useConnectGateway } from '..';
5
+
6
+ import { API } from '../../../../configs';
7
+
8
+ const mock = new MockAdapter(api.axiosInstance);
9
+ jest.mock('@react-navigation/native', () => {
10
+ return {
11
+ ...jest.requireActual('@react-navigation/native'),
12
+ useNavigation: () => ({
13
+ dangerouslyGetParent: () => ({
14
+ dangerouslyGetState: jest.fn(),
15
+ }),
16
+ }),
17
+ };
18
+ });
19
+ describe('Test useGGHomeConnection', () => {
20
+ it('test connectGoogleHome all connected', async () => {
21
+ const { result } = renderHook(() => useConnectGateway(1));
22
+ await act(async () => {
23
+ await result.current.onPressDone();
24
+ });
25
+ mock.onGet(API.UNIT.UNIT_DETAIL(1)).reply(200, {});
26
+ });
27
+ });
@@ -5,8 +5,10 @@ import HistoryChart from '../../../commons/Device/HistoryChart';
5
5
  import { API } from '../../../configs';
6
6
  import { axiosGet } from '../../../utils/Apis/axios';
7
7
 
8
- export const DetailHistoryChart = ({ item, sensor }) => {
9
- const [chartData, setChartData] = useState(item.configuration.configs);
8
+ export const DetailHistoryChart = ({ item = {}, sensor = {} }) => {
9
+ const { configuration = {} } = item;
10
+ const { configs = [] } = configuration;
11
+ const [chartData, setChartData] = useState(configs);
10
12
  const [startDate, setStartDate] = useState(
11
13
  moment().subtract(1, 'days').valueOf()
12
14
  );
@@ -14,7 +16,7 @@ export const DetailHistoryChart = ({ item, sensor }) => {
14
16
  useEffect(() => {
15
17
  const fetchData = async () => {
16
18
  let params = new URLSearchParams();
17
- item.configuration.configs.map((config) => {
19
+ configs.map((config) => {
18
20
  params.append('config', config.id);
19
21
  });
20
22
  params.append('date_from', startDate / 1000);
@@ -30,7 +32,7 @@ export const DetailHistoryChart = ({ item, sensor }) => {
30
32
  }
31
33
  }
32
34
 
33
- const formatData = item.configuration.configs.map((config) => {
35
+ const formatData = configs.map((config) => {
34
36
  const dataChart = data.find((k) => k.config === config.id) || {
35
37
  data: [],
36
38
  };
@@ -40,7 +42,7 @@ export const DetailHistoryChart = ({ item, sensor }) => {
40
42
  }
41
43
  };
42
44
  fetchData();
43
- }, [startDate, endDate, item, sensor]);
45
+ }, [startDate, endDate, sensor, configs]);
44
46
  if (!chartData.length) {
45
47
  return false;
46
48
  }
@@ -1,7 +1,7 @@
1
1
  import React, { useCallback } from 'react';
2
2
  import { View } from 'react-native';
3
3
  import ActionGroup from '../../../commons/ActionGroup';
4
- import { Card } from '../../../commons/CardShadow';
4
+ import { CardDevMode } from '../../../commons/DevMode';
5
5
  import { TESTID } from '../../../configs/Constants';
6
6
  import { useTranslations } from '../../../hooks/Common/useTranslations';
7
7
  import { DetailHistoryChart } from './DetailHistoryChart';
@@ -28,7 +28,7 @@ const { standardizeWidth, standardizeHeight } = standardizeCameraScreenSize(
28
28
  );
29
29
 
30
30
  export const SensorDisplayItem = ({
31
- item,
31
+ item = {},
32
32
  sensor,
33
33
  emergency,
34
34
  getData,
@@ -40,6 +40,8 @@ export const SensorDisplayItem = ({
40
40
  }) => {
41
41
  const t = useTranslations();
42
42
  const userId = useSCContextSelector((state) => state.auth.account.user.id);
43
+ const { configuration = {}, id: idTemplate } = item;
44
+ const { type, uri, id, name, title } = configuration;
43
45
 
44
46
  const sendRemoteCommand = useRemoteControl();
45
47
 
@@ -50,42 +52,47 @@ export const SensorDisplayItem = ({
50
52
  [sensor, userId, sendRemoteCommand]
51
53
  );
52
54
 
53
- if (item.configuration.type === 'compass') {
54
- setShowWindDirection(true);
55
+ if (type === 'compass') {
56
+ setShowWindDirection && setShowWindDirection(true);
55
57
  }
56
58
  switch (item.type) {
57
59
  case 'camera':
58
60
  return (
59
- <Card title={t('camera')}>
61
+ <CardDevMode title={t('camera')} id={idTemplate} isWrap>
60
62
  <View style={styles.mediaContainer}>
61
63
  <MediaPlayerDetail
62
- uri={item.configuration.uri}
64
+ uri={uri}
63
65
  thumbnail={{
64
66
  uri: background,
65
67
  }}
66
- key={`camera-device-${item.configuration.id}`}
67
- cameraName={item.configuration.name}
68
+ key={`camera-device-${id}`}
69
+ cameraName={name}
68
70
  width={standardizeWidth - 32}
69
71
  height={standardizeHeight - 16}
70
72
  />
71
73
  </View>
72
- </Card>
74
+ </CardDevMode>
73
75
  );
74
76
  case 'action':
75
77
  return (
76
78
  <ActionGroup
77
79
  testID={TESTID.DEVICE_DETAIL_ACTION_GROUP}
78
- actionGroup={item.configuration}
80
+ actionGroup={configuration}
79
81
  doAction={doAction}
80
82
  sensor={sensor}
83
+ id={idTemplate}
81
84
  />
82
85
  );
83
86
  case 'history':
84
87
  return <DetailHistoryChart item={item} sensor={sensor} />;
85
88
  case 'value':
86
- switch (item.configuration.type) {
89
+ switch (type) {
87
90
  case 'circle':
88
- return <CurrentRainSensor data={getData(item)} />;
91
+ return (
92
+ <CardDevMode id={idTemplate}>
93
+ <CurrentRainSensor data={getData(item)} />
94
+ </CardDevMode>
95
+ );
89
96
  case 'simple_list':
90
97
  return (
91
98
  <PMSensorIndicatior
@@ -94,22 +101,32 @@ export const SensorDisplayItem = ({
94
101
  />
95
102
  );
96
103
  case 'gauge':
97
- return <Anemometer data={getData(item)} maxValue={maxValue} />;
104
+ return (
105
+ <CardDevMode id={idTemplate}>
106
+ <Anemometer data={getData(item)} maxValue={maxValue} />
107
+ </CardDevMode>
108
+ );
98
109
  case 'compass':
99
- return <Compass data={getData(item)} />;
110
+ return (
111
+ <CardDevMode id={idTemplate}>
112
+ <Compass data={getData(item)} />
113
+ </CardDevMode>
114
+ );
100
115
  case 'alert_status':
101
116
  return (
102
- <DeviceAlertStatus
103
- data={getData(item)}
104
- style={styles.marginLeft}
105
- offsetTitle={offsetTitle}
106
- setOffsetTitle={setOffsetTitle}
107
- />
117
+ <CardDevMode id={idTemplate}>
118
+ <DeviceAlertStatus
119
+ data={getData(item)}
120
+ style={styles.marginLeft}
121
+ offsetTitle={offsetTitle}
122
+ setOffsetTitle={setOffsetTitle}
123
+ />
124
+ </CardDevMode>
108
125
  );
109
126
  case 'flat_list':
110
127
  return (
111
128
  <FlatListItems
112
- title={item.configuration.title}
129
+ title={title}
113
130
  data={getData(item)}
114
131
  style={[styles.marginLeft, styles.marginVertical]}
115
132
  offsetTitle={offsetTitle}
@@ -119,14 +136,22 @@ export const SensorDisplayItem = ({
119
136
  return <ListQualityIndicator data={getData(item)} />;
120
137
  }
121
138
  case 'emergency':
122
- switch (item.configuration.type) {
139
+ switch (type) {
123
140
  case 'detail':
124
- return <EmergencyDetail item={item} />;
141
+ return (
142
+ <CardDevMode id={idTemplate}>
143
+ <EmergencyDetail item={item} />
144
+ </CardDevMode>
145
+ );
125
146
  default:
126
147
  return <EmergencyButton emergency={emergency} />;
127
148
  }
128
149
  case 'info':
129
- return <FooterInfo data={item.configuration} />;
150
+ return (
151
+ <CardDevMode id={idTemplate}>
152
+ <FooterInfo data={configuration} />
153
+ </CardDevMode>
154
+ );
130
155
  case 'smart_ir':
131
156
  return <SmartIr item={item} />;
132
157
  default:
@@ -6,7 +6,7 @@ import React, {
6
6
  useRef,
7
7
  useContext,
8
8
  } from 'react';
9
- import { View, TouchableOpacity } from 'react-native';
9
+ import { View, TouchableOpacity, Platform } from 'react-native';
10
10
  import { useTranslations } from '../../hooks/Common/useTranslations';
11
11
  import moment from 'moment';
12
12
  import { get } from 'lodash';
@@ -63,6 +63,7 @@ const DeviceDetail = ({ route }) => {
63
63
  const t = useTranslations();
64
64
  const navigation = useNavigation();
65
65
  const token = useSCContextSelector((state) => state.auth.account.token);
66
+ const { isLockWhenPickColor } = useSCContextSelector((state) => state.app);
66
67
  const { setAction } = useContext(SCContext);
67
68
  const [offsetTitle, setOffsetTitle] = useState(1);
68
69
  const [display, setDisplay] = useState({ items: [] });
@@ -736,6 +737,7 @@ const DeviceDetail = ({ route }) => {
736
737
  headerAniStyle={styles.header}
737
738
  rightComponent={HeaderRight}
738
739
  onRefresh={onRefresh}
740
+ scrollEnabled={!(Platform.OS === 'ios' && isLockWhenPickColor)}
739
741
  >
740
742
  <View style={styles.wrapTemplate}>
741
743
  {loading.displayTemplate === false &&
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useCallback, useContext } from 'react';
2
2
  import {
3
3
  View,
4
4
  Image,
@@ -15,19 +15,24 @@ import { Images, Colors } from '../../configs';
15
15
  import Text from '../../commons/Text';
16
16
  import Routes from '../../utils/Route';
17
17
  import { TESTID } from '../../configs/Constants';
18
- import { useSCContextSelector } from '../../context';
18
+ import { SCContext, useSCContextSelector } from '../../context';
19
19
  import { CommonActions, useNavigation } from '@react-navigation/native';
20
+ import { Action } from '../../context/actionType';
20
21
 
21
22
  const DrawerContainer = ({ navigation }) => {
22
23
  const user = useSCContextSelector((state) => state.auth.account.user);
23
24
  const { dispatch } = useNavigation();
24
- const doLogout = () => {
25
+ const { setAction } = useContext(SCContext);
26
+
27
+ const doLogout = useCallback(() => {
25
28
  const resetAction = CommonActions.reset({
26
29
  index: 0,
27
30
  routes: [{ name: Routes.Main }],
28
31
  });
29
32
  dispatch(resetAction);
30
- };
33
+ setAction(Action.SET_IS_EDITING_TEMPLATE);
34
+ // eslint-disable-next-line react-hooks/exhaustive-deps
35
+ }, []);
31
36
 
32
37
  const goToHelp = () => {};
33
38