@eohjsc/react-native-smart-city 0.7.5 → 0.7.8
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 +3 -3
- package/src/commons/Device/LabelValue/__test__/LabelValue.test.js +74 -0
- package/src/commons/Device/LabelValue/index.js +49 -0
- package/src/commons/Device/LabelValue/styles.js +33 -0
- package/src/screens/Automate/ScriptDetail/index.js +17 -17
- package/src/screens/Device/__test__/sensorDisplayItem.test.js +22 -0
- package/src/screens/Device/components/SensorDisplayItem.js +10 -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.7.
|
|
4
|
+
"version": "0.7.8",
|
|
5
5
|
"description": "TODO",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"files": [
|
|
@@ -118,8 +118,8 @@
|
|
|
118
118
|
"lint-staged": "^12.4.1",
|
|
119
119
|
"lodash": "^4.17.19",
|
|
120
120
|
"lottie-react-native": "^6.7.2",
|
|
121
|
-
"metro-react-native-babel-preset": "0.73.9",
|
|
122
121
|
"md5": "^2.3.0",
|
|
122
|
+
"metro-react-native-babel-preset": "0.73.9",
|
|
123
123
|
"moment": "^2.27.0",
|
|
124
124
|
"moment-timezone": "^0.5.32",
|
|
125
125
|
"node-html-parser": "^2.0.2",
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
"react-native-geocoder": "^0.5.0",
|
|
156
156
|
"react-native-gesture-handler": "^2.17.1",
|
|
157
157
|
"react-native-get-location": "^2.0.0",
|
|
158
|
-
"react-native-image-crop-picker": "^0.
|
|
158
|
+
"react-native-image-crop-picker": "^0.41.4",
|
|
159
159
|
"react-native-image-resizer": "^1.4.5",
|
|
160
160
|
"react-native-input-credit-card": "^0.5.5",
|
|
161
161
|
"react-native-iphone-x-helper": "^1.2.1",
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import renderer, { act } from 'react-test-renderer';
|
|
3
|
+
import * as Progress from 'react-native-progress';
|
|
4
|
+
import LabelValue from '..';
|
|
5
|
+
import Text from '../../../Text';
|
|
6
|
+
|
|
7
|
+
describe('Test LabelValue', () => {
|
|
8
|
+
let tree;
|
|
9
|
+
let item;
|
|
10
|
+
let data;
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
item = {
|
|
13
|
+
label: 'Distance',
|
|
14
|
+
configuration: {
|
|
15
|
+
align: 'align_left',
|
|
16
|
+
color: '#eb144c',
|
|
17
|
+
min_value: 0,
|
|
18
|
+
max_value: 100,
|
|
19
|
+
status_bar: true,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
data = [{ value: 10, unit: 'm' }];
|
|
23
|
+
});
|
|
24
|
+
it('render LabelValue', async () => {
|
|
25
|
+
await act(async () => {
|
|
26
|
+
tree = await renderer.create(
|
|
27
|
+
<LabelValue item={item} data={data} isWidgetOrder={false} />
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
const instance = tree.root;
|
|
31
|
+
const texts = instance.findAllByType(Text);
|
|
32
|
+
const progressBar = instance.findByType(Progress.Bar);
|
|
33
|
+
|
|
34
|
+
expect(texts[0].props.children).toEqual('Distance');
|
|
35
|
+
expect(texts[1].props.children).toEqual('10 m');
|
|
36
|
+
expect(texts[1].props.style.alignSelf).toEqual('flex-start');
|
|
37
|
+
expect(progressBar.props.color).toEqual('#eb144c');
|
|
38
|
+
expect(progressBar.props.progress).toEqual(0.1);
|
|
39
|
+
});
|
|
40
|
+
it('render LabelValue with invalid data, align right', async () => {
|
|
41
|
+
item.configuration.align = 'align_right';
|
|
42
|
+
await act(async () => {
|
|
43
|
+
tree = await renderer.create(
|
|
44
|
+
<LabelValue item={item} isWidgetOrder={false} />
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
const instance = tree.root;
|
|
48
|
+
const texts = instance.findAllByType(Text);
|
|
49
|
+
const progressBar = instance.findByType(Progress.Bar);
|
|
50
|
+
|
|
51
|
+
expect(texts[0].props.children).toEqual('Distance');
|
|
52
|
+
expect(texts[1].props.children).toEqual('-- ');
|
|
53
|
+
expect(texts[1].props.style.alignSelf).toEqual('flex-end');
|
|
54
|
+
expect(progressBar.props.color).toEqual('#eb144c');
|
|
55
|
+
expect(progressBar.props.progress).toEqual(0);
|
|
56
|
+
});
|
|
57
|
+
it('render LabelValue with status bar false, align middle', async () => {
|
|
58
|
+
item.configuration.status_bar = false;
|
|
59
|
+
item.configuration.align = 'align_middle';
|
|
60
|
+
await act(async () => {
|
|
61
|
+
tree = await renderer.create(
|
|
62
|
+
<LabelValue item={item} data={data} isWidgetOrder={true} />
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
const instance = tree.root;
|
|
66
|
+
const texts = instance.findAllByType(Text);
|
|
67
|
+
const progressBar = instance.findAllByType(Progress.Bar);
|
|
68
|
+
|
|
69
|
+
expect(texts[0].props.children).toEqual('Distance');
|
|
70
|
+
expect(texts[1].props.children).toEqual('10 m');
|
|
71
|
+
expect(texts[1].props.style.alignSelf).toEqual('center');
|
|
72
|
+
expect(progressBar.length).toEqual(0);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React, { memo } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import * as Progress from 'react-native-progress';
|
|
4
|
+
|
|
5
|
+
import { Colors } from '../../../configs';
|
|
6
|
+
import Text from '../../Text';
|
|
7
|
+
import styles from './styles';
|
|
8
|
+
|
|
9
|
+
const LabelValue = memo(({ data = [], item, isWidgetOrder }) => {
|
|
10
|
+
const {
|
|
11
|
+
configuration: { align, color, max_value, min_value, status_bar },
|
|
12
|
+
label,
|
|
13
|
+
} = item;
|
|
14
|
+
const { value, unit = '' } = data.length ? data[0] : {};
|
|
15
|
+
const percent = ((value ?? min_value) - min_value) / (max_value - min_value);
|
|
16
|
+
const alignValueText =
|
|
17
|
+
align === 'align_middle'
|
|
18
|
+
? 'center'
|
|
19
|
+
: align === 'align_left'
|
|
20
|
+
? 'flex-start'
|
|
21
|
+
: 'flex-end';
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<View style={[styles.container, isWidgetOrder && styles.wrapOrderItem]}>
|
|
25
|
+
<Text type="H3" semibold color={Colors.Gray9} style={styles.textLabel}>
|
|
26
|
+
{label}
|
|
27
|
+
</Text>
|
|
28
|
+
<Text
|
|
29
|
+
bold
|
|
30
|
+
type="H1"
|
|
31
|
+
style={{ ...styles.textValue, alignSelf: alignValueText }}
|
|
32
|
+
>
|
|
33
|
+
{`${value ?? '--'} ${unit}`}
|
|
34
|
+
</Text>
|
|
35
|
+
{!!status_bar && (
|
|
36
|
+
<Progress.Bar
|
|
37
|
+
style={styles.progressBar}
|
|
38
|
+
width={null}
|
|
39
|
+
height={8}
|
|
40
|
+
unfilledColor={Colors.Gray4}
|
|
41
|
+
progress={percent}
|
|
42
|
+
color={color}
|
|
43
|
+
/>
|
|
44
|
+
)}
|
|
45
|
+
</View>
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export default LabelValue;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
|
|
3
|
+
import { Colors } from '../../../configs';
|
|
4
|
+
|
|
5
|
+
export default StyleSheet.create({
|
|
6
|
+
container: {
|
|
7
|
+
flexDirection: 'column',
|
|
8
|
+
justifyContent: 'center',
|
|
9
|
+
marginLeft: 15,
|
|
10
|
+
marginRight: 15,
|
|
11
|
+
marginBottom: 10,
|
|
12
|
+
padding: 5,
|
|
13
|
+
borderRadius: 10,
|
|
14
|
+
borderWidth: 1,
|
|
15
|
+
borderColor: Colors.Gray4,
|
|
16
|
+
borderStyle: 'solid',
|
|
17
|
+
},
|
|
18
|
+
wrapOrderItem: {
|
|
19
|
+
marginBottom: 0,
|
|
20
|
+
},
|
|
21
|
+
textLabel: {
|
|
22
|
+
marginLeft: 8,
|
|
23
|
+
marginTop: 8,
|
|
24
|
+
},
|
|
25
|
+
textValue: {
|
|
26
|
+
margin: 8,
|
|
27
|
+
},
|
|
28
|
+
progressBar: {
|
|
29
|
+
borderWidth: 0,
|
|
30
|
+
borderRadius: 10,
|
|
31
|
+
marginHorizontal: 8,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
@@ -91,6 +91,23 @@ const ScriptDetail = ({ route }) => {
|
|
|
91
91
|
});
|
|
92
92
|
}, [navigate, automateId, type, unit]);
|
|
93
93
|
|
|
94
|
+
const handleUpdateAutomate = useCallback(async () => {
|
|
95
|
+
if (!can_edit) {
|
|
96
|
+
ToastBottomHelper.error(
|
|
97
|
+
t('only_owner_has_permission_to_edit_this_script')
|
|
98
|
+
);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (!enableScript) {
|
|
102
|
+
ToastBottomHelper.error(t('this_script_has_been_disabled'));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
navigate(Routes.AddUnknownTypeSmart, {
|
|
106
|
+
automate,
|
|
107
|
+
closeScreen: route.name,
|
|
108
|
+
});
|
|
109
|
+
}, [automate, can_edit, enableScript, navigate, route.name, t]);
|
|
110
|
+
|
|
94
111
|
const listMenuItem = useMemo(
|
|
95
112
|
() => [
|
|
96
113
|
{ text: t('rename'), doAction: () => setIsShowRename(true) },
|
|
@@ -175,23 +192,6 @@ const ScriptDetail = ({ route }) => {
|
|
|
175
192
|
}
|
|
176
193
|
}, [automateId, t]);
|
|
177
194
|
|
|
178
|
-
const handleUpdateAutomate = useCallback(async () => {
|
|
179
|
-
if (!can_edit) {
|
|
180
|
-
ToastBottomHelper.error(
|
|
181
|
-
t('only_owner_has_permission_to_edit_this_script')
|
|
182
|
-
);
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
if (!enableScript) {
|
|
186
|
-
ToastBottomHelper.error(t('this_script_has_been_disabled'));
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
navigate(Routes.AddUnknownTypeSmart, {
|
|
190
|
-
automate,
|
|
191
|
-
closeScreen: route.name,
|
|
192
|
-
});
|
|
193
|
-
}, [automate, can_edit, enableScript, navigate, route.name, t]);
|
|
194
|
-
|
|
195
195
|
const handleGoBack = useCallback(async () => {
|
|
196
196
|
if (closeScreen === Routes.UnitDetail) {
|
|
197
197
|
navigate(closeScreen, { unitId: unit });
|
|
@@ -17,6 +17,7 @@ import DeviceAlertStatus from '../../../commons/Device/DeviceAlertStatus';
|
|
|
17
17
|
import MockAdapter from 'axios-mock-adapter';
|
|
18
18
|
import api from '../../../utils/Apis/axios';
|
|
19
19
|
import CurrentRainSensor from '../../../commons/Device/RainningSensor/CurrentRainSensor';
|
|
20
|
+
import LabelValue from '../../../commons/Device/LabelValue';
|
|
20
21
|
|
|
21
22
|
jest.mock('../../../iot/states', () => ({
|
|
22
23
|
useConfigGlobalState: () => [{}, null],
|
|
@@ -410,4 +411,25 @@ describe('Test SensorDisplayItem', () => {
|
|
|
410
411
|
isWidgetOrder: undefined,
|
|
411
412
|
});
|
|
412
413
|
});
|
|
414
|
+
it('test render LabelValue', async () => {
|
|
415
|
+
const item = {
|
|
416
|
+
id: 10452,
|
|
417
|
+
order: 0,
|
|
418
|
+
template: 'LabelValue',
|
|
419
|
+
configuration: {},
|
|
420
|
+
is_configuration_ready: true,
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
const sensor = {
|
|
424
|
+
name: 'Sensor name',
|
|
425
|
+
is_managed_by_backend: false,
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
await act(async () => {
|
|
429
|
+
tree = await renderer.create(wrapComponent({ item, sensor }));
|
|
430
|
+
});
|
|
431
|
+
const instance = tree.root;
|
|
432
|
+
const displayItems = instance.findAllByType(LabelValue);
|
|
433
|
+
expect(displayItems).toHaveLength(1);
|
|
434
|
+
});
|
|
413
435
|
});
|
|
@@ -8,6 +8,7 @@ import FlatListItems from '../../../commons/Device/FlatListItems';
|
|
|
8
8
|
import FooterInfo from '../../../commons/Device/FooterInfo';
|
|
9
9
|
import PMSensorIndicator from '../../../commons/Device/PMSensor/PMSensorIndicator';
|
|
10
10
|
import ProgressBar from '../../../commons/Device/ProgressBar';
|
|
11
|
+
import LabelValue from '../../../commons/Device/LabelValue';
|
|
11
12
|
import CurrentRainSensor from '../../../commons/Device/RainningSensor/CurrentRainSensor';
|
|
12
13
|
import ListQualityIndicator from '../../../commons/Device/WaterQualitySensor/ListQualityIndicator';
|
|
13
14
|
import Compass from '../../../commons/Device/WindDirection/Compass';
|
|
@@ -216,6 +217,15 @@ export const SensorDisplayItem = ({
|
|
|
216
217
|
isWidgetOrder={isWidgetOrder}
|
|
217
218
|
/>
|
|
218
219
|
);
|
|
220
|
+
// use the same method to get data for circle_mini
|
|
221
|
+
case 'LabelValue':
|
|
222
|
+
return (
|
|
223
|
+
<LabelValue
|
|
224
|
+
data={getDataCircleMini(item)}
|
|
225
|
+
item={item}
|
|
226
|
+
isWidgetOrder={isWidgetOrder}
|
|
227
|
+
/>
|
|
228
|
+
);
|
|
219
229
|
case 'value':
|
|
220
230
|
switch (type || template) {
|
|
221
231
|
case 'circle':
|