@eohjsc/react-native-smart-city 0.7.23 → 0.7.25

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/index.js CHANGED
@@ -14,6 +14,7 @@ import { initSCConfig } from './src/configs';
14
14
  import AutomateStack from './src/navigations/AutomateStack';
15
15
  import NotificationStack from './src/navigations/NotificationStack';
16
16
  import MyPinnedSharedUnit from './src/commons/Dashboard/MyPinnedSharedUnit';
17
+ import MyDashboardDevice from './src/commons/Dashboard/MyDashboardDevice';
17
18
  import MyUnit from './src/commons/Dashboard/MyUnit';
18
19
  import SharedUnit from './src/commons/Unit/SharedUnit';
19
20
  import { Action } from './src/context/actionType';
@@ -41,6 +42,7 @@ export {
41
42
  NotificationStack,
42
43
  MyPinnedSharedUnit,
43
44
  SharedUnit,
45
+ MyDashboardDevice,
44
46
  MyUnit,
45
47
  SCWrapper,
46
48
  Action,
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.7.23",
4
+ "version": "0.7.25",
5
5
  "description": "TODO",
6
6
  "main": "index.js",
7
7
  "files": [
@@ -0,0 +1,171 @@
1
+ import MockAdapter from 'axios-mock-adapter';
2
+ import React, { useContext } from 'react';
3
+ import renderer, { act } from 'react-test-renderer';
4
+
5
+ import { Action } from '../../../../context/actionType';
6
+ import { API } from '../../../../configs';
7
+ import { AccessibilityLabel } from '../../../../configs/Constants';
8
+ import { SCProvider } from '../../../../context';
9
+ import { mockSCStore } from '../../../../context/mockStore';
10
+ import { Section } from '../../../Section';
11
+ import ItemDevice from '../../../Device/ItemDevice';
12
+ import { DeviceTemplate } from '../../../SubUnit/DeviceTemplate/DeviceTemplate';
13
+ import api from '../../../../utils/Apis/axios';
14
+ import Routes from '../../../../utils/Route';
15
+ import MyDashboardDevice from '..';
16
+
17
+ const mock = new MockAdapter(api.axiosInstance);
18
+
19
+ const wrapComponent = () => (
20
+ <SCProvider initState={mockSCStore({})}>
21
+ <MyDashboardDevice refreshing={true} />
22
+ </SCProvider>
23
+ );
24
+
25
+ describe('Test MyDashboardDevice', () => {
26
+ let tree;
27
+ const data = [
28
+ {
29
+ id: 1,
30
+ name: 'EoH',
31
+ devices: [
32
+ {
33
+ id: 1,
34
+ name: 'LED',
35
+ is_managed_by_backend: true,
36
+ device_type: '',
37
+ station: {
38
+ id: 1,
39
+ name: 'Phòng họp',
40
+ },
41
+ quick_action: {
42
+ config_id: 1,
43
+ },
44
+ },
45
+ {
46
+ id: 2,
47
+ name: 'Presence',
48
+ is_managed_by_backend: true,
49
+ device_type: '',
50
+ station: {
51
+ id: 1,
52
+ name: 'Phòng họp',
53
+ },
54
+ station_items: [
55
+ {
56
+ configuration: {
57
+ config: 2,
58
+ },
59
+ },
60
+ ],
61
+ },
62
+ {
63
+ id: 3,
64
+ name: 'Switch',
65
+ is_managed_by_backend: false,
66
+ device_type: 'GOOGLE_HOME',
67
+ station: {
68
+ id: 1,
69
+ name: 'Phòng họp',
70
+ },
71
+ },
72
+ ],
73
+ },
74
+ ];
75
+ const mockSetAction = jest.fn();
76
+
77
+ beforeEach(async () => {
78
+ mock.reset();
79
+ useContext.mockReturnValue({
80
+ stateData: mockSCStore({
81
+ app: { isNeedUpdateCache: false },
82
+ }),
83
+ setAction: mockSetAction,
84
+ });
85
+ mockSetAction.mockClear();
86
+ });
87
+
88
+ it('Test dashboard no device', async () => {
89
+ await act(async () => {
90
+ tree = await renderer.create(wrapComponent());
91
+ });
92
+ const instance = tree.root;
93
+ const sectors = instance.findAllByType(Section);
94
+ expect(sectors).toHaveLength(0);
95
+ expect(mockSetAction).not.toHaveBeenCalled();
96
+ });
97
+
98
+ it('Test dashboard with devices and go to unit', async () => {
99
+ mock.onGet(API.UNIT.MY_DASHBOARD_DEVICES()).reply(200, data);
100
+ await act(async () => {
101
+ tree = await renderer.create(wrapComponent());
102
+ });
103
+ const instance = tree.root;
104
+ const devices = instance.findAllByType(ItemDevice);
105
+ expect(devices).toHaveLength(2);
106
+ const deviceTemplates = instance.findAllByType(DeviceTemplate);
107
+ expect(deviceTemplates).toHaveLength(1);
108
+
109
+ const goToUnit = instance.findByProps({
110
+ accessibilityLabel: `${AccessibilityLabel.UNIT_GO_TO_DETAIL}-0`,
111
+ });
112
+ await act(async () => {
113
+ await goToUnit.props.onPress();
114
+ });
115
+ expect(global.mockedNavigate).toHaveBeenCalledWith(Routes.UnitStack, {
116
+ params: {
117
+ unitId: 1,
118
+ },
119
+ screen: Routes.UnitDetail,
120
+ });
121
+ expect(mockSetAction).toHaveBeenCalledWith(
122
+ Action.SET_DEVICES_STATUS,
123
+ data[0].devices
124
+ );
125
+ });
126
+
127
+ it('Test dashboard with devices and go to device', async () => {
128
+ useContext.mockReturnValue({
129
+ stateData: mockSCStore({
130
+ app: { isNeedUpdateCache: true },
131
+ }),
132
+ setAction: mockSetAction,
133
+ });
134
+ mock.onGet(API.UNIT.MY_DASHBOARD_DEVICES()).reply(200, data);
135
+ await act(async () => {
136
+ tree = await renderer.create(wrapComponent());
137
+ });
138
+ const instance = tree.root;
139
+ const devices = instance.findAllByType(ItemDevice);
140
+ expect(devices).toHaveLength(2);
141
+ const deviceTemplates = instance.findAllByType(DeviceTemplate);
142
+ expect(deviceTemplates).toHaveLength(1);
143
+
144
+ await act(async () => {
145
+ await devices[0].props.goToDetail();
146
+ });
147
+ expect(global.mockedNavigate).toHaveBeenCalledWith(Routes.UnitStack, {
148
+ params: {
149
+ sensorId: 1,
150
+ station: {
151
+ id: 1,
152
+ name: 'Phòng họp',
153
+ },
154
+ title: 'LED',
155
+ unitId: 1,
156
+ },
157
+ screen: Routes.DeviceDetail,
158
+ });
159
+ expect(mockSetAction).toHaveBeenCalledTimes(2);
160
+ expect(mockSetAction).toHaveBeenNthCalledWith(
161
+ 1,
162
+ Action.IS_CHECK_CLEAR_CACHE_UNITS,
163
+ false
164
+ );
165
+ expect(mockSetAction).toHaveBeenNthCalledWith(
166
+ 2,
167
+ Action.SET_DEVICES_STATUS,
168
+ data[0].devices
169
+ );
170
+ });
171
+ });
@@ -0,0 +1,218 @@
1
+ import { API, Colors, Images } from '../../../configs';
2
+ import { AccessibilityLabel, DEVICE_TYPE } from '../../../configs/Constants';
3
+ import { Image, FlatList, TouchableOpacity, View } from 'react-native';
4
+ import React, {
5
+ memo,
6
+ useCallback,
7
+ useContext,
8
+ useMemo,
9
+ useEffect,
10
+ useState,
11
+ } from 'react';
12
+ import { SCContext, useSCContextSelector } from '../../../context';
13
+ import { axiosGet, fetchWithCache } from '../../../utils/Apis/axios';
14
+ import { useWatchConfigs } from '../../../hooks/IoT';
15
+ import { useIsFocused, useNavigation } from '@react-navigation/native';
16
+
17
+ import { Action } from '../../../context/actionType';
18
+ import Routes from '../../../utils/Route';
19
+ import { Section } from '../../Section';
20
+ import Text from '../../Text';
21
+ import { keyExtractor } from '../../../utils/Utils';
22
+ import ItemDevice from '../../Device/ItemDevice';
23
+ import { DeviceTemplate } from '../../SubUnit/DeviceTemplate/DeviceTemplate';
24
+ import { useTranslations } from '../../../hooks/Common/useTranslations';
25
+ import styles from './styles';
26
+
27
+ const MyDashboardDevice = ({ refreshing }) => {
28
+ const t = useTranslations();
29
+ const isFocused = useIsFocused();
30
+ const navigation = useNavigation();
31
+ const { setAction } = useContext(SCContext);
32
+ const isNeedUpdateCache = useSCContextSelector(
33
+ (state) => state.app.isNeedUpdateCache
34
+ );
35
+ const [myDashboardDevices, setMyDashboardDevices] = useState([]);
36
+
37
+ const configsNeedWatching = useMemo(() => {
38
+ const configIds = [];
39
+
40
+ myDashboardDevices.forEach(({ devices }) => {
41
+ devices
42
+ .filter((device) => device.device_type !== DEVICE_TYPE.GOOGLE_HOME)
43
+ .forEach((device) => {
44
+ const quickActionId = device.quick_action?.config_id;
45
+ quickActionId && configIds.push(quickActionId);
46
+
47
+ device.station_items?.forEach((item) => {
48
+ const stationConfigId = item.configuration?.config;
49
+ stationConfigId && configIds.push(stationConfigId);
50
+ });
51
+ });
52
+ });
53
+
54
+ return configIds;
55
+ }, [myDashboardDevices]);
56
+
57
+ useWatchConfigs(configsNeedWatching);
58
+
59
+ const fetchMyDashboardDevices = useCallback(async () => {
60
+ if (isNeedUpdateCache) {
61
+ setAction(Action.IS_CHECK_CLEAR_CACHE_UNITS, false);
62
+ const { success, data } = await axiosGet(
63
+ API.UNIT.MY_DASHBOARD_DEVICES(),
64
+ {},
65
+ true
66
+ );
67
+ if (success) {
68
+ setMyDashboardDevices(data);
69
+ data.forEach((dashboard) => {
70
+ setAction(Action.SET_DEVICES_STATUS, dashboard.devices);
71
+ });
72
+ }
73
+ } else {
74
+ await fetchWithCache(API.UNIT.MY_DASHBOARD_DEVICES(), {}, (response) => {
75
+ const { success, data } = response;
76
+ if (success) {
77
+ setMyDashboardDevices(data);
78
+ data.forEach((dashboard) => {
79
+ setAction(Action.SET_DEVICES_STATUS, dashboard.devices);
80
+ });
81
+ }
82
+ });
83
+ }
84
+ // eslint-disable-next-line react-hooks/exhaustive-deps
85
+ }, []);
86
+
87
+ const goToUnitDetail = useCallback(
88
+ (unit) => () => {
89
+ navigation.navigate(Routes.UnitStack, {
90
+ screen: Routes.UnitDetail,
91
+ params: {
92
+ unitId: unit.id,
93
+ },
94
+ });
95
+ },
96
+ [navigation]
97
+ );
98
+
99
+ const goToDeviceDetail = useCallback(
100
+ (unitId, device) => () => {
101
+ navigation.navigate(Routes.UnitStack, {
102
+ screen: Routes.DeviceDetail,
103
+ params: {
104
+ unitId: unitId,
105
+ station: device.station,
106
+ sensorId: device.id,
107
+ title: device.name,
108
+ },
109
+ });
110
+ },
111
+ [navigation]
112
+ );
113
+
114
+ const renderStationItem = useCallback(
115
+ (device, unitId, stationItem) => {
116
+ return (
117
+ <DeviceTemplate
118
+ device={device}
119
+ stationItem={stationItem}
120
+ unit={{ id: unitId }}
121
+ station={device.station}
122
+ goToDetail={goToDeviceDetail(unitId, device)}
123
+ key={`device-template-${stationItem.id}`}
124
+ />
125
+ );
126
+ },
127
+ [goToDeviceDetail]
128
+ );
129
+
130
+ const renderDisplayItem = useCallback(
131
+ (device, unitId) => {
132
+ let displays = [];
133
+ if (!device.station_items?.length || device.quick_action) {
134
+ displays.push(
135
+ <ItemDevice
136
+ description={device.value}
137
+ title={device.name}
138
+ sensor={device}
139
+ unit={{ id: unitId }}
140
+ station={device.station}
141
+ goToDetail={goToDeviceDetail(unitId, device)}
142
+ key={`device-${device.id}`}
143
+ />
144
+ );
145
+ }
146
+ if (device.station_items?.length) {
147
+ displays.push(
148
+ ...device.station_items.map((item) =>
149
+ renderStationItem(device, unitId, item)
150
+ )
151
+ );
152
+ }
153
+ return displays;
154
+ },
155
+ [goToDeviceDetail, renderStationItem]
156
+ );
157
+
158
+ const renderItem = useCallback(
159
+ ({ item, index }) => {
160
+ return (
161
+ <View style={styles.wrapItem}>
162
+ <View style={styles.titleItem}>
163
+ <Text type="H3" semibold>
164
+ {item.name}
165
+ </Text>
166
+ <TouchableOpacity
167
+ onPress={goToUnitDetail(item)}
168
+ style={styles.arrowRightButton}
169
+ accessibilityLabel={`${AccessibilityLabel.UNIT_GO_TO_DETAIL}-${index}`}
170
+ >
171
+ <Image source={Images.arrowBack} style={styles.arrowRight} />
172
+ </TouchableOpacity>
173
+ </View>
174
+ <View style={styles.wrapperDevices}>
175
+ {item.devices.map((device) => {
176
+ return renderDisplayItem(device, item.id);
177
+ })}
178
+ </View>
179
+ </View>
180
+ );
181
+ },
182
+ [goToUnitDetail, renderDisplayItem]
183
+ );
184
+
185
+ useEffect(() => {
186
+ if (isFocused || refreshing) {
187
+ fetchMyDashboardDevices();
188
+ }
189
+ }, [fetchMyDashboardDevices, isFocused, refreshing]);
190
+
191
+ return (
192
+ <>
193
+ {!!myDashboardDevices.length && (
194
+ <Section style={styles.wrapperDashboardDevice}>
195
+ <Text
196
+ style={styles.dashboardDevicesTitle}
197
+ type="H5"
198
+ color={Colors.Gray8}
199
+ >
200
+ {t('dashboard_devices')}
201
+ </Text>
202
+ <View style={styles.container}>
203
+ <FlatList
204
+ keyExtractor={keyExtractor}
205
+ data={myDashboardDevices}
206
+ extraData={myDashboardDevices}
207
+ renderItem={renderItem}
208
+ contentContainerStyle={styles.contentContainerStyle}
209
+ refreshing={false}
210
+ />
211
+ </View>
212
+ </Section>
213
+ )}
214
+ </>
215
+ );
216
+ };
217
+
218
+ export default memo(MyDashboardDevice);
@@ -0,0 +1,60 @@
1
+ import { StyleSheet } from 'react-native';
2
+ import { Colors } from '../../../configs';
3
+
4
+ const styles = StyleSheet.create({
5
+ contentContainerStyle: {
6
+ paddingLeft: 16,
7
+ paddingRight: 16,
8
+ },
9
+ wrapperDashboardDevice: {
10
+ padding: 0,
11
+ paddingBottom: 10,
12
+ backgroundColor: Colors.White,
13
+ },
14
+ dashboardDevicesTitle: {
15
+ flexDirection: 'row',
16
+ justifyContent: 'space-between',
17
+ alignItems: 'center',
18
+ paddingHorizontal: 16,
19
+ paddingBottom: 8,
20
+ paddingTop: 16,
21
+ },
22
+ container: {
23
+ flex: 1,
24
+ backgroundColor: Colors.White,
25
+ },
26
+ wrapperDevices: {
27
+ flexWrap: 'wrap',
28
+ flexDirection: 'row',
29
+ justifyContent: 'space-between',
30
+ marginTop: 10,
31
+ borderBottomColor: Colors.Gray4,
32
+ borderBottomWidth: 1,
33
+ },
34
+ arrowRightButton: {
35
+ width: 20,
36
+ height: 20,
37
+ justifyContent: 'center',
38
+ alignItems: 'center',
39
+ },
40
+ arrowRight: {
41
+ transform: [
42
+ {
43
+ rotate: '180deg',
44
+ },
45
+ ],
46
+ tintColor: Colors.Gray7,
47
+ width: 8,
48
+ height: 12,
49
+ },
50
+ wrapItem: {
51
+ marginBottom: 16,
52
+ },
53
+ titleItem: {
54
+ flexDirection: 'row',
55
+ justifyContent: 'space-between',
56
+ alignItems: 'center',
57
+ },
58
+ });
59
+
60
+ export default styles;
@@ -18,7 +18,7 @@ import IconComponent from '../IconComponent';
18
18
  import ItemDeviceWrapper from './ItemDeviceWrapper';
19
19
 
20
20
  const ItemDevice = memo(
21
- ({ description, title, sensor, unit, station, wrapStyle }) => {
21
+ ({ description, title, sensor, unit, station, goToDetail, wrapStyle }) => {
22
22
  const t = useTranslations();
23
23
  const navigation = useNavigation();
24
24
  const { is_managed_by_backend, device_type, icon_kit, icon, quick_action } =
@@ -44,6 +44,14 @@ const ItemDevice = memo(
44
44
  });
45
45
  }, [navigation, sensor, station, title, unit]);
46
46
 
47
+ const onPress = useCallback(() => {
48
+ if (goToDetail) {
49
+ goToDetail();
50
+ } else {
51
+ goToSensorDisplay();
52
+ }
53
+ }, [goToDetail, goToSensorDisplay]);
54
+
47
55
  const textConnected = useMemo(() => {
48
56
  if (is_managed_by_backend) {
49
57
  if (
@@ -80,10 +88,11 @@ const ItemDevice = memo(
80
88
  device={sensor}
81
89
  unit={unit}
82
90
  station={station}
91
+ goToDetail={goToDetail}
83
92
  wrapStyle={wrapStyle}
84
93
  >
85
94
  <View style={styles.boxIcon}>
86
- <TouchableOpacity onPress={goToSensorDisplay}>
95
+ <TouchableOpacity onPress={onPress}>
87
96
  <IconComponent icon={icon_kit || icon} />
88
97
  </TouchableOpacity>
89
98
  {canRenderQuickAction && (
@@ -94,7 +103,7 @@ const ItemDevice = memo(
94
103
  />
95
104
  )}
96
105
  </View>
97
- <TouchableOpacity onPress={goToSensorDisplay}>
106
+ <TouchableOpacity onPress={onPress}>
98
107
  <Text
99
108
  numberOfLines={1}
100
109
  semibold
@@ -17,7 +17,7 @@ import {
17
17
  } from '../../configs/Constants';
18
18
 
19
19
  const ItemDeviceWrapper = memo(
20
- ({ device, unit, station, wrapStyle, children }) => {
20
+ ({ device, unit, station, goToDetail, wrapStyle, children }) => {
21
21
  const navigation = useNavigation();
22
22
 
23
23
  const {
@@ -42,6 +42,14 @@ const ItemDeviceWrapper = memo(
42
42
  });
43
43
  }, [navigation, device, station, unit]);
44
44
 
45
+ const onPress = useCallback(() => {
46
+ if (goToDetail) {
47
+ goToDetail();
48
+ } else {
49
+ goToSensorDisplay();
50
+ }
51
+ }, [goToDetail, goToSensorDisplay]);
52
+
45
53
  const borderColor = useMemo(() => {
46
54
  if (!!device && device?.is_managed_by_backend) {
47
55
  if (device?.device_type === DEVICE_TYPE.LG_THINQ) {
@@ -73,7 +81,7 @@ const ItemDeviceWrapper = memo(
73
81
 
74
82
  return (
75
83
  <TouchableWithoutFeedback
76
- onPress={goToSensorDisplay}
84
+ onPress={onPress}
77
85
  accessibilityLabel={`${AccessibilityLabel.SENSOR_NAME}-${device?.id}`}
78
86
  >
79
87
  <View
@@ -3,14 +3,19 @@ import { getTemplate } from './';
3
3
  import ItemDeviceWrapper from '../../Device/ItemDeviceWrapper';
4
4
 
5
5
  export const DeviceTemplate = memo(
6
- ({ device, stationItem, unit, station, key }) => {
6
+ ({ device, stationItem, unit, station, goToDetail }) => {
7
7
  const Template = getTemplate(stationItem);
8
8
  if (!Template) {
9
9
  return null;
10
10
  }
11
11
  return (
12
- <ItemDeviceWrapper device={device} unit={unit} station={station}>
13
- <Template.Display device={device} stationItem={stationItem} key={key} />
12
+ <ItemDeviceWrapper
13
+ device={device}
14
+ unit={unit}
15
+ station={station}
16
+ goToDetail={goToDetail}
17
+ >
18
+ <Template.Display device={device} stationItem={stationItem} />
14
19
  </ItemDeviceWrapper>
15
20
  );
16
21
  }
@@ -23,7 +23,13 @@ export const useFetchConfigHistory = (
23
23
  ) => {
24
24
  const fetchDataDisplayHistory = useCallback(
25
25
  async (startDate, endDate, setProcessing = () => {}) => {
26
- if (!configs.length || !startDate || !endDate) {
26
+ if (
27
+ !configs ||
28
+ !Array.isArray(configs) ||
29
+ !configs.length ||
30
+ !startDate ||
31
+ !endDate
32
+ ) {
27
33
  return;
28
34
  }
29
35
 
@@ -27,6 +27,9 @@ const API = {
27
27
  END_DEVICES_STATUS: (id) =>
28
28
  `/property_manager/units/${id}/end_devices_status/`,
29
29
  CHANGE_OWNER: (id) => `/property_manager/units/${id}/change_owner/`,
30
+ MY_DASHBOARD_DEVICES: () => '/property_manager/units/my_dashboard_devices/',
31
+ DASHBOARD_DEVICES: (id) =>
32
+ `/property_manager/units/${id}/dashboard_devices/`,
30
33
  FAVOURITE_DEVICES: (id) =>
31
34
  `/property_manager/units/${id}/favourite_devices/`,
32
35
  DEVICES_NOT_FAVORITES: (id) =>
@@ -75,6 +78,10 @@ const API = {
75
78
  DISPLAY_ACTIONS: (id) => `/property_manager/devices/${id}/display_actions/`,
76
79
  CHANGE_SUB_UNIT: (unit_id, station_id, id) =>
77
80
  `/property_manager/${unit_id}/sub_units/${station_id}/devices/${id}/change_sub_unit/`,
81
+ ADD_TO_DASHBOARD: (id) =>
82
+ `/property_manager/devices/${id}/add_to_dashboard/`,
83
+ REMOVE_FROM_DASHBOARD: (id) =>
84
+ `/property_manager/devices/${id}/remove_from_dashboard/`,
78
85
  ADD_TO_FAVOURITES: (id) =>
79
86
  `/property_manager/devices/${id}/add_to_favourites/`,
80
87
  REMOVE_FROM_FAVOURITES: (id) =>
@@ -40,6 +40,7 @@ export default {
40
40
  MY_UNIT_GO_TO_DETAIL: 'MY_UNIT_GO_TO_DETAIL',
41
41
  MY_UNIT_NO_UNIT: 'MY_UNIT_NO_UNIT',
42
42
  ITEM_UNIT: 'ITEM_UNIT',
43
+ UNIT_GO_TO_DETAIL: 'UNIT_GO_TO_DETAIL',
43
44
 
44
45
  // ConfirmUnitDeletion
45
46
  CONFIRM_UNIT_DELETION_BUTTON: 'CONFIRM_UNIT_DELETION_BUTTON',
@@ -270,6 +271,7 @@ export default {
270
271
  PARKING_SPOT_TEXT_RESULT: 'PARKING_SPOT_TEXT_RESULT',
271
272
 
272
273
  // Header Device
274
+ HEADER_DEVICE_BUTTON_PIN: 'HEADER_DEVICE_BUTTON_PIN',
273
275
  HEADER_DEVICE_BUTTON_STAR: 'HEADER_DEVICE_BUTTON_STAR',
274
276
  HEADER_SCRIPT_DETAIL_BUTTON_STAR: 'HEADER_SCRIPT_DETAIL_BUTTON_STAR',
275
277
  HEADER_DEVICE_BUTTON_MORE: 'HEADER_DEVICE_BUTTON_MORE',
@@ -12,6 +12,9 @@ export const Action = {
12
12
  SET_NETWORK_CONNECTED: 'SET_NETWORK_CONNECTED',
13
13
  CAMERA_STATUS_CHANGE: 'CAMERA_STATUS_CHANGE',
14
14
  CLOSE_ALL_CAMERA: 'CLOSE_ALL_CAMERA',
15
+ SET_DASHBOARD_DEVICES: 'SET_DASHBOARD_DEVICES',
16
+ ADD_DEVICES_TO_DASHBOARD: 'ADD_DEVICE_TO_DASHBOARD',
17
+ REMOVE_DEVICES_FROM_DASHBOARD: 'REMOVE_DEVICE_FROM_DASHBOARD',
15
18
  SET_FAVORITE_DEVICES: 'SET_FAVORITE_DEVICES',
16
19
  ADD_DEVICES_TO_FAVORITES: 'ADD_DEVICE_TO_FAVORITES',
17
20
  REMOVE_DEVICES_FROM_FAVORITES: 'REMOVE_DEVICE_FROM_FAVORITES',
@@ -78,6 +81,7 @@ export type ListAction = {
78
81
  }[];
79
82
 
80
83
  export type UnitType = {
84
+ dashboardDeviceIds: [];
81
85
  favoriteDeviceIds: [];
82
86
  };
83
87
 
@@ -27,6 +27,7 @@ export const mockDataStore: ContextData = {
27
27
  listAction: [],
28
28
  myUnits: [],
29
29
  unit: {
30
+ dashboardDeviceIds: [],
30
31
  favoriteDeviceIds: [],
31
32
  },
32
33
  automate: {
@@ -103,6 +104,10 @@ export const mockSCStore = (data: ContextData): ContextData => {
103
104
  },
104
105
  myUnits: [...mockDataStore.myUnits, ...(data?.myUnits || [])],
105
106
  unit: {
107
+ dashboardDeviceIds: [
108
+ ...mockDataStore.unit.dashboardDeviceIds,
109
+ ...(data?.unit?.dashboardDeviceIds || []),
110
+ ],
106
111
  favoriteDeviceIds: [
107
112
  ...mockDataStore.unit.favoriteDeviceIds,
108
113
  ...(data?.unit?.favoriteDeviceIds || []),