@eohjsc/react-native-smart-city 0.3.80 → 0.3.81
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 +1 -1
- package/src/commons/ActionGroup/OnOffTemplate/SwitchButtonTemplate.js +63 -0
- package/src/commons/ActionGroup/__test__/SwitchButtonTemplate.test.js +93 -0
- package/src/commons/ActionGroup/index.js +3 -0
- package/src/utils/Utils.js +5 -1
- package/src/utils/__test__/Utils.test.js +4 -4
package/package.json
CHANGED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React, { memo, useCallback, useState } from 'react';
|
|
2
|
+
import { Switch, View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import Text from '../../Text';
|
|
5
|
+
import { Colors } from '../../../configs';
|
|
6
|
+
import styles from './OnOffButtonTemplateStyle';
|
|
7
|
+
import AccessibilityLabel from '../../../configs/AccessibilityLabel';
|
|
8
|
+
|
|
9
|
+
const SwitchButtonTemplate = memo(
|
|
10
|
+
({ isOn, triggerAction, actionGroup = {}, isLight = false, doAction }) => {
|
|
11
|
+
const [_isOn, setIsOn] = useState(isOn);
|
|
12
|
+
|
|
13
|
+
const { configuration = {}, id } = actionGroup;
|
|
14
|
+
const {
|
|
15
|
+
action_off_data,
|
|
16
|
+
action_on_data,
|
|
17
|
+
text_on,
|
|
18
|
+
text_off,
|
|
19
|
+
color_on,
|
|
20
|
+
color_off,
|
|
21
|
+
} = configuration;
|
|
22
|
+
|
|
23
|
+
const onChangeSwitch = useCallback(() => {
|
|
24
|
+
if (_isOn) {
|
|
25
|
+
setIsOn(false);
|
|
26
|
+
doAction(action_off_data, null);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
doAction(action_on_data, null);
|
|
30
|
+
setIsOn(true);
|
|
31
|
+
}, [action_off_data, action_on_data, doAction, _isOn]);
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<>
|
|
35
|
+
<View style={styles.barrierControlContainer}>
|
|
36
|
+
<Switch
|
|
37
|
+
trackColor={{ false: color_off, true: color_on }}
|
|
38
|
+
ios_backgroundColor={_isOn ? color_on : color_off}
|
|
39
|
+
onValueChange={onChangeSwitch}
|
|
40
|
+
value={_isOn}
|
|
41
|
+
/>
|
|
42
|
+
<Text
|
|
43
|
+
style={[
|
|
44
|
+
styles.textBig,
|
|
45
|
+
{ color: _isOn ? Colors.Gray8 : Colors.Gray6 },
|
|
46
|
+
]}
|
|
47
|
+
accessibilityLabel={`${AccessibilityLabel.SENSOR_STATUS}-${id}`}
|
|
48
|
+
>
|
|
49
|
+
{_isOn ? text_on : text_off}
|
|
50
|
+
</Text>
|
|
51
|
+
</View>
|
|
52
|
+
|
|
53
|
+
{!!actionGroup.title && !isLight && (
|
|
54
|
+
<Text type="H3" semibold center>
|
|
55
|
+
{actionGroup.title}
|
|
56
|
+
</Text>
|
|
57
|
+
)}
|
|
58
|
+
</>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
export default SwitchButtonTemplate;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { act, create } from 'react-test-renderer';
|
|
3
|
+
|
|
4
|
+
import { mockSCStore } from '../../../context/mockStore';
|
|
5
|
+
import { SCProvider } from '../../../context';
|
|
6
|
+
import SwitchButtonTemplate from '../OnOffTemplate/SwitchButtonTemplate';
|
|
7
|
+
|
|
8
|
+
const wrapComponent = (actionGroup, mockDoAction) => (
|
|
9
|
+
<SCProvider initState={mockSCStore({})}>
|
|
10
|
+
<SwitchButtonTemplate actionGroup={actionGroup} doAction={mockDoAction} />
|
|
11
|
+
</SCProvider>
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
jest.mock('@react-navigation/native', () => {
|
|
15
|
+
return {
|
|
16
|
+
...jest.requireActual('@react-navigation/native'),
|
|
17
|
+
useFocusEffect: jest.fn(),
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('Test SwitchButtonTemplate', () => {
|
|
22
|
+
const action_on_data = {
|
|
23
|
+
color: '#00979D',
|
|
24
|
+
command_prefer_over_bluetooth: true,
|
|
25
|
+
command_prefer_over_googlehome: false,
|
|
26
|
+
command_prefer_over_internet: false,
|
|
27
|
+
googlehome_actions: [],
|
|
28
|
+
icon: 'caret-up',
|
|
29
|
+
id: 20,
|
|
30
|
+
key: '5ed1d4dc-a905-47cd-b0c9-f979644bd21a',
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const action_off_data = {
|
|
34
|
+
color: '#00979D',
|
|
35
|
+
command_prefer_over_bluetooth: true,
|
|
36
|
+
command_prefer_over_googlehome: false,
|
|
37
|
+
command_prefer_over_internet: false,
|
|
38
|
+
googlehome_actions: [],
|
|
39
|
+
icon: 'caret-up',
|
|
40
|
+
id: 20,
|
|
41
|
+
key: '5ed1d4dc-a905-47cd-b0c9-f979644bd21a',
|
|
42
|
+
};
|
|
43
|
+
const actionGroup = {
|
|
44
|
+
configuration: {
|
|
45
|
+
action_on: '5ed1d4dc-a905-47cd-b0c9-f979644bd21a',
|
|
46
|
+
action_on_data: action_on_data,
|
|
47
|
+
icon_on: 'caret-up',
|
|
48
|
+
text_on: 'ON',
|
|
49
|
+
action_off: '5ed1d4dc-a905-47cd-b0c9-f979644bd21b',
|
|
50
|
+
action_off_data: action_off_data,
|
|
51
|
+
icon_off: 'caret-up',
|
|
52
|
+
text_off: 'OFF',
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
let wrapper;
|
|
56
|
+
|
|
57
|
+
const assertRender = async () => {
|
|
58
|
+
const mockDoAction = jest.fn();
|
|
59
|
+
|
|
60
|
+
await act(async () => {
|
|
61
|
+
wrapper = create(wrapComponent(actionGroup, mockDoAction));
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const renderJson = wrapper.toJSON();
|
|
65
|
+
expect(renderJson[1].props?.visible).toEqual(false);
|
|
66
|
+
expect(renderJson[1]?.type).toEqual('Modal');
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
it('render state on', async () => {
|
|
70
|
+
await assertRender(true, 'ON');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('render state off', async () => {
|
|
74
|
+
await assertRender(false, 'OFF');
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const assertActionCall = async (state, action_data) => {
|
|
78
|
+
const mockDoAction = jest.fn();
|
|
79
|
+
await act(async () => {
|
|
80
|
+
wrapper = create(wrapComponent(actionGroup, mockDoAction));
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
expect(mockDoAction).not.toHaveBeenCalled();
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
it('action state on', async () => {
|
|
87
|
+
await assertActionCall(true, action_off_data);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('action state off', async () => {
|
|
91
|
+
await assertActionCall(false, action_on_data);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -13,6 +13,7 @@ import ColorPickerTemplate from './ColorPickerTemplate';
|
|
|
13
13
|
import SliderRangeTemplate from './SliderRangeTemplate';
|
|
14
14
|
import OnOffSmartLock from './OnOffSmartLock/OnOffSmartLock';
|
|
15
15
|
import TwoButtonTemplate from './TwoButtonTemplate';
|
|
16
|
+
import SwitchButtonTemplate from './OnOffTemplate/SwitchButtonTemplate';
|
|
16
17
|
|
|
17
18
|
export const getActionComponent = (template) => {
|
|
18
19
|
switch (template) {
|
|
@@ -46,6 +47,8 @@ export const getActionComponent = (template) => {
|
|
|
46
47
|
return SliderRangeTemplate;
|
|
47
48
|
case 'two_button_action_template':
|
|
48
49
|
return TwoButtonTemplate;
|
|
50
|
+
case 'switch_button_action_template':
|
|
51
|
+
return SwitchButtonTemplate;
|
|
49
52
|
default:
|
|
50
53
|
return null;
|
|
51
54
|
}
|
package/src/utils/Utils.js
CHANGED
|
@@ -154,7 +154,11 @@ export const notImplemented = (t) => {
|
|
|
154
154
|
|
|
155
155
|
export const roundNumber = (value, round = 2) => {
|
|
156
156
|
if (typeof value === 'string') {
|
|
157
|
-
|
|
157
|
+
const temp = value.split(' ');
|
|
158
|
+
return (
|
|
159
|
+
Math.round((isNaN(temp[0]) ? 0 : temp[0]) * 10 ** round) / 10 ** round +
|
|
160
|
+
` ${temp[1] || ''}`
|
|
161
|
+
);
|
|
158
162
|
}
|
|
159
163
|
return value;
|
|
160
164
|
};
|
|
@@ -174,10 +174,10 @@ describe('Test utils', () => {
|
|
|
174
174
|
|
|
175
175
|
it('Test roundNumber', async () => {
|
|
176
176
|
let result;
|
|
177
|
-
result = await roundNumber('
|
|
178
|
-
expect(result).toBe(0);
|
|
179
|
-
result = await roundNumber('123.123');
|
|
180
|
-
expect(result).toBe(123.12);
|
|
177
|
+
result = await roundNumber('NaN kwh');
|
|
178
|
+
expect(result).toBe('0 kwh');
|
|
179
|
+
result = await roundNumber('123.123 kwh');
|
|
180
|
+
expect(result).toBe('123.12 kwh');
|
|
181
181
|
result = await roundNumber(12.12);
|
|
182
182
|
expect(result).toBe(12.12);
|
|
183
183
|
});
|