@eohjsc/react-native-smart-city 0.7.21 → 0.7.23
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/Images/Common/default_end_device.png +0 -0
- package/src/commons/ActionGroup/TerminalBoxTemplate.js +3 -0
- package/src/commons/ActionTemplate/OnOffButtonAction.js +38 -4
- package/src/commons/ActionTemplate/OnOffSimpleAction.js +55 -15
- package/src/commons/ActionTemplate/OnOffSmartLockAction.js +46 -8
- package/src/commons/ActionTemplate/SwitchButtonAction.js +35 -4
- package/src/commons/ActionTemplate/ThreeButtonAction.js +13 -3
- package/src/commons/ActionTemplate/__test__/OnOffButtonAction.test.js +46 -7
- package/src/commons/ActionTemplate/__test__/OnOffSimpleAction.test.js +66 -6
- package/src/commons/ActionTemplate/__test__/OnOffSmartLockAction.test.js +53 -13
- package/src/commons/ActionTemplate/__test__/SwitchButtonAction.test.js +46 -7
- package/src/commons/ActionTemplate/__test__/index.test.js +6 -2
- package/src/commons/ActionTemplate/index.js +65 -10
- package/src/commons/Dashboard/MyUnit/index.js +19 -20
- package/src/commons/DevMode/Search.js +1 -1
- package/src/commons/Device/RainningSensor/CurrentRainSensor.js +5 -5
- package/src/commons/MediaPlayerDetail/MediaPlayerFull.js +26 -32
- package/src/commons/OneTapTemplate/StatesGridActionTemplate.js +8 -6
- package/src/commons/SubUnit/OneTap/__test__/SubUnitAutomate.test.js +6 -0
- package/src/commons/SubUnit/OneTap/index.js +5 -0
- package/src/commons/UnitSummary/ConfigHistoryChart/index.js +9 -11
- package/src/commons/Widgets/IFrameWithConfig/IFrameWithConfig.js +2 -2
- package/src/commons/Widgets/IFrameWithConfig/__tests__/IFrameWithConfig.test.js +1 -1
- package/src/configs/API.js +10 -0
- package/src/configs/AccessibilityLabel.js +5 -1
- package/src/configs/Images.js +1 -0
- package/src/navigations/AddMemberStack.js +3 -3
- package/src/screens/ActivityLog/__test__/index.test.js +10 -0
- package/src/screens/ActivityLog/hooks/index.js +1 -1
- package/src/screens/AddCommon/SelectUnit.js +3 -2
- package/src/screens/AddLocationMaps/__test__/index.test.js +13 -13
- package/src/screens/Automate/AddNewAction/ChooseAction.js +15 -51
- package/src/screens/Automate/AddNewAction/SelectControlDevices.js +13 -3
- package/src/screens/Automate/AddNewAction/SetupConfigCondition.js +74 -54
- package/src/screens/Automate/AddNewAction/__test__/ChooseAction.test.js +114 -4
- package/src/screens/Automate/AddNewAction/__test__/ChooseConfig.test.js +9 -11
- package/src/screens/Automate/AddNewAction/__test__/SetupConfigCondition.test.js +37 -8
- package/src/screens/Automate/AddNewAutoSmart/AddTypeSmart.js +5 -0
- package/src/screens/Automate/AddNewAutoSmart/__test__/AddAutomationTypeSmart.test.js +31 -0
- package/src/screens/Automate/AddNewAutoSmart/__test__/AddNewAutoSmart.test.js +18 -2
- package/src/screens/Automate/Components/InputName.js +7 -6
- package/src/screens/Automate/Constants.js +12 -0
- package/src/screens/Automate/EditActionsList/UpdateActionScript.js +24 -55
- package/src/screens/Automate/EditActionsList/__tests__/UpdateActionScript.test.js +298 -41
- package/src/screens/Automate/EditActionsList/__tests__/index.test.js +2 -2
- package/src/screens/Automate/EditActionsList/index.js +26 -14
- package/src/screens/Automate/MultiUnits.js +9 -1
- package/src/screens/Automate/OneTap/__test__/AddNewOneTap.test.js +3 -3
- package/src/screens/Automate/ScriptDetail/Components/AddActionScript.js +4 -10
- package/src/screens/Automate/ScriptDetail/Components/DeleteScript.js +2 -4
- package/src/screens/Automate/ScriptDetail/__test__/index.test.js +78 -0
- package/src/screens/Automate/ScriptDetail/index.js +16 -10
- package/src/screens/Automate/ScriptDetail/utils.js +39 -35
- package/src/screens/Automate/SetSchedule/AddEditConditionSchedule.js +27 -160
- package/src/screens/Automate/SetSchedule/EditSchedule.js +269 -0
- package/src/screens/Automate/SetSchedule/__test__/AddEditConditionSchedule.test.js +327 -22
- package/src/screens/Automate/SetSchedule/__test__/index.test.js +35 -22
- package/src/screens/Automate/SetSchedule/components/RepeatOptionsPopup.js +2 -8
- package/src/screens/Automate/SetSchedule/index.js +15 -129
- package/src/screens/Automate/SetSchedule/styles/indexStyles.js +9 -0
- package/src/screens/Automate/__test__/MultiUnits.test.js +6 -1
- package/src/screens/Automate/hooks/useAction.js +222 -0
- package/src/screens/ConfirmUnitDeletion/__test__/ConfirmUnitDeletion.test.js +69 -13
- package/src/screens/ConfirmUnitDeletion/index.js +14 -14
- package/src/screens/Device/__test__/detail.test.js +48 -1
- package/src/screens/Device/detail.js +46 -3
- package/src/screens/PlayBackCamera/__test__/index.test.js +48 -13
- package/src/screens/PlayBackCamera/index.js +1 -1
- package/src/screens/Sharing/Components/ConfigItem.js +34 -0
- package/src/screens/Sharing/Components/DeviceItem.js +77 -0
- package/src/screens/Sharing/Components/ItemChangeRole.js +3 -4
- package/src/screens/Sharing/Components/ShareDeviceSelector.js +255 -0
- package/src/screens/Sharing/Components/Styles/CheckBoxCustomStyles.js +1 -1
- package/src/screens/Sharing/Components/Styles/DeviceItemStyles.js +11 -27
- package/src/screens/Sharing/{Styles/SelectPermissionStyles.js → Components/Styles/ShareDeviceSelectorStyles.js} +3 -11
- package/src/screens/Sharing/Components/SubUnitItem.js +28 -0
- package/src/screens/Sharing/Components/SubUnitTreeView.js +68 -0
- package/src/screens/Sharing/Components/TitleCheckBox.js +23 -41
- package/src/screens/Sharing/Components/__test__/ItemChangeRole.test.js +7 -7
- package/src/screens/Sharing/Components/__test__/ShareDeviceSelector.test.js +298 -0
- package/src/screens/Sharing/Components/index.js +14 -1
- package/src/screens/Sharing/InfoMemberUnit.js +20 -20
- package/src/screens/Sharing/SelectShareDevice.js +11 -255
- package/src/screens/Sharing/SelectUser.js +12 -12
- package/src/screens/Sharing/UpdateShareDevice.js +45 -301
- package/src/screens/Sharing/__test__/InfoMemberUnit.test.js +58 -11
- package/src/screens/Sharing/__test__/SelectShareDevice.test.js +51 -160
- package/src/screens/Sharing/__test__/SelectUser.test.js +72 -10
- package/src/screens/Sharing/__test__/UpdateShareDevice.test.js +49 -209
- package/src/utils/Apis/axios.js +6 -0
- package/src/utils/I18n/translations/en.js +9 -1
- package/src/utils/I18n/translations/vi.js +10 -2
- package/src/commons/Sharing/StationDevicePermissions.js +0 -204
- package/src/screens/Automate/constants.js +0 -0
- package/src/screens/Sharing/Components/CheckBoxConfig.js +0 -44
- package/src/screens/Sharing/Components/CheckBoxSubUnit.js +0 -35
- package/src/screens/Sharing/Components/EndDevice.js +0 -93
- package/src/screens/Sharing/Components/Styles/CheckBoxConfigStyles.js +0 -18
- package/src/screens/Sharing/Components/Styles/TitleCheckBoxStyles.js +0 -21
- package/src/screens/Sharing/Components/__test__/TitleCheckBox.test.js +0 -31
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AccessibilityLabel,
|
|
3
|
+
Constants,
|
|
4
|
+
normalize,
|
|
5
|
+
} from '../../../configs/Constants';
|
|
6
|
+
import { FlatList, Text, View } from 'react-native';
|
|
7
|
+
|
|
8
|
+
import React from 'react';
|
|
9
|
+
import { StyleSheet } from 'react-native';
|
|
10
|
+
import SubUnitItem from './SubUnitItem';
|
|
11
|
+
import { useTranslations } from '../../../hooks/Common/useTranslations';
|
|
12
|
+
|
|
13
|
+
const SubUnitTreeNode = ({ dataNode, render }) => {
|
|
14
|
+
return (
|
|
15
|
+
<View>
|
|
16
|
+
{render &&
|
|
17
|
+
render({
|
|
18
|
+
item: dataNode,
|
|
19
|
+
childrenRender: (dataNode?.children || []).map((child) => (
|
|
20
|
+
<SubUnitTreeNode key={child.key} dataNode={child} render={render} />
|
|
21
|
+
)),
|
|
22
|
+
})}
|
|
23
|
+
</View>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const SubUnitTreeView = ({ data, render, selectedKeys, onSelect }) => {
|
|
28
|
+
const t = useTranslations();
|
|
29
|
+
const { key, children: subUnitsData } = data[0];
|
|
30
|
+
return (
|
|
31
|
+
<View>
|
|
32
|
+
<FlatList
|
|
33
|
+
data={subUnitsData}
|
|
34
|
+
renderItem={({ item }) => (
|
|
35
|
+
<SubUnitTreeNode dataNode={item} render={render} />
|
|
36
|
+
)}
|
|
37
|
+
extraData={subUnitsData}
|
|
38
|
+
keyExtractor={(item) => item.key}
|
|
39
|
+
ListHeaderComponent={
|
|
40
|
+
subUnitsData.length && (
|
|
41
|
+
<SubUnitItem
|
|
42
|
+
isChecked={selectedKeys.includes(key)}
|
|
43
|
+
item={data[0]}
|
|
44
|
+
onSelect={onSelect}
|
|
45
|
+
/>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
ListEmptyComponent={() => (
|
|
49
|
+
<Text
|
|
50
|
+
style={styles.textNodata}
|
|
51
|
+
accessibilityLabel={AccessibilityLabel.TEXT_NO_DATA_STATIONS}
|
|
52
|
+
>
|
|
53
|
+
{t('no_data')}
|
|
54
|
+
</Text>
|
|
55
|
+
)}
|
|
56
|
+
/>
|
|
57
|
+
</View>
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const styles = StyleSheet.create({
|
|
62
|
+
textNodata: {
|
|
63
|
+
alignSelf: 'center',
|
|
64
|
+
marginTop: normalize(Constants.height * 0.3),
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
export default SubUnitTreeView;
|
|
@@ -1,51 +1,33 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { View, Text } from 'react-native';
|
|
1
|
+
import AccessibilityLabel from '../../../configs/AccessibilityLabel';
|
|
3
2
|
import { CheckBoxCustom } from '.';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { StyleSheet } from 'react-native';
|
|
5
|
+
import { Text } from '../../../commons';
|
|
6
|
+
import { View } from 'react-native';
|
|
6
7
|
|
|
7
|
-
const TitleCheckBox = ({
|
|
8
|
-
|
|
9
|
-
onPress,
|
|
10
|
-
title = '',
|
|
11
|
-
id,
|
|
12
|
-
wrapCheckBoxStyle,
|
|
13
|
-
wrapStyle,
|
|
14
|
-
titleStyle,
|
|
15
|
-
idGroup,
|
|
16
|
-
isConfig,
|
|
17
|
-
isControl,
|
|
18
|
-
}) => {
|
|
19
|
-
const [checked, setChecked] = useState(isChecked);
|
|
8
|
+
const TitleCheckBox = ({ isChecked, item, onSelect, checkBoxStyle }) => {
|
|
9
|
+
const { label, key } = item;
|
|
20
10
|
const handleOnPress = () => {
|
|
21
|
-
|
|
22
|
-
onPress && onPress(idGroup, !checked, id);
|
|
11
|
+
onSelect(item, !isChecked);
|
|
23
12
|
};
|
|
24
|
-
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
isChecked !== checked && setChecked(isChecked);
|
|
27
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
28
|
-
}, [isChecked]);
|
|
29
|
-
|
|
30
13
|
return (
|
|
31
|
-
<View style={
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
<Text onPress={handleOnPress} style={[styles.title, titleStyle]}>
|
|
40
|
-
{title}
|
|
41
|
-
</Text>
|
|
42
|
-
</View>
|
|
43
|
-
<View>
|
|
44
|
-
{isControl && <Text>{t('can_control')}</Text>}
|
|
45
|
-
{isConfig && <Text>{t('view_only')}</Text>}
|
|
46
|
-
</View>
|
|
14
|
+
<View style={styles.wrapRow}>
|
|
15
|
+
<CheckBoxCustom
|
|
16
|
+
isChecked={isChecked}
|
|
17
|
+
onPress={handleOnPress}
|
|
18
|
+
wrapStyle={checkBoxStyle}
|
|
19
|
+
accessibilityLabel={`${AccessibilityLabel.SHARE_DEVICE.CHECK_BOX_CUSTOM}-${key}`}
|
|
20
|
+
/>
|
|
21
|
+
<Text onPress={handleOnPress}>{label}</Text>
|
|
47
22
|
</View>
|
|
48
23
|
);
|
|
49
24
|
};
|
|
50
25
|
|
|
26
|
+
const styles = StyleSheet.create({
|
|
27
|
+
wrapRow: {
|
|
28
|
+
flexDirection: 'row',
|
|
29
|
+
alignItems: 'center',
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
51
33
|
export default TitleCheckBox;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { create, act } from 'react-test-renderer';
|
|
1
|
+
import { act, create } from 'react-test-renderer';
|
|
3
2
|
|
|
4
|
-
import { SCProvider } from '../../../../context';
|
|
5
|
-
import { mockSCStore } from '../../../../context/mockStore';
|
|
6
3
|
import ItemChangeRole from '../ItemChangeRole';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { SCProvider } from '../../../../context';
|
|
7
6
|
import { TouchableOpacity } from 'react-native';
|
|
7
|
+
import { mockSCStore } from '../../../../context/mockStore';
|
|
8
8
|
|
|
9
9
|
const mockOnPress = jest.fn();
|
|
10
|
-
const wrapComponent = () => (
|
|
10
|
+
const wrapComponent = (disabled) => (
|
|
11
11
|
<SCProvider initState={mockSCStore({})}>
|
|
12
|
-
<ItemChangeRole onPress={mockOnPress} />
|
|
12
|
+
<ItemChangeRole onPress={mockOnPress} disabled={disabled} />
|
|
13
13
|
</SCProvider>
|
|
14
14
|
);
|
|
15
15
|
|
|
@@ -17,7 +17,7 @@ describe('test ItemChangeRole', () => {
|
|
|
17
17
|
it('test ItemChangeRole', async () => {
|
|
18
18
|
let tree;
|
|
19
19
|
await act(async () => {
|
|
20
|
-
tree = await create(wrapComponent());
|
|
20
|
+
tree = await create(wrapComponent(true));
|
|
21
21
|
});
|
|
22
22
|
const instance = tree.root;
|
|
23
23
|
const touchableOpacity = instance.findAllByType(TouchableOpacity);
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import API from '../../../../configs/API';
|
|
2
|
+
import AccessibilityLabel from '../../../../configs/AccessibilityLabel';
|
|
3
|
+
import { Alert } from 'react-native';
|
|
4
|
+
import ConfigItem from '../ConfigItem';
|
|
5
|
+
import DeviceItem from '../DeviceItem';
|
|
6
|
+
import { IconOutline } from '@ant-design/icons-react-native';
|
|
7
|
+
import MockAdapter from 'axios-mock-adapter';
|
|
8
|
+
import React from 'react';
|
|
9
|
+
import { SCProvider } from '../../../../context';
|
|
10
|
+
import ShareDeviceSelector from '../ShareDeviceSelector';
|
|
11
|
+
import SubUnitItem from '../SubUnitItem';
|
|
12
|
+
import SubUnitTreeView from '../SubUnitTreeView';
|
|
13
|
+
import { ViewButtonBottom } from '../../../../commons';
|
|
14
|
+
import { act } from '@testing-library/react-hooks';
|
|
15
|
+
import api from '../../../../utils/Apis/axios';
|
|
16
|
+
import { create } from 'react-test-renderer';
|
|
17
|
+
import { mockSCStore } from '../../../../context/mockStore';
|
|
18
|
+
import { useNavigation } from '@react-navigation/native';
|
|
19
|
+
|
|
20
|
+
jest.spyOn(Alert, 'alert').mockImplementation(() => {});
|
|
21
|
+
const mock = new MockAdapter(api.axiosInstance);
|
|
22
|
+
const mockOnRightClick = jest.fn();
|
|
23
|
+
|
|
24
|
+
const wrapComponent = (unitId, initKeys = undefined) => (
|
|
25
|
+
<SCProvider initState={mockSCStore({})}>
|
|
26
|
+
<ShareDeviceSelector
|
|
27
|
+
unitId={unitId}
|
|
28
|
+
onRightClick={mockOnRightClick}
|
|
29
|
+
rightTitle={'done'}
|
|
30
|
+
initialSelectedKeys={initKeys}
|
|
31
|
+
/>
|
|
32
|
+
</SCProvider>
|
|
33
|
+
);
|
|
34
|
+
describe('test ShareDeviceSelector', () => {
|
|
35
|
+
const unitId = 1;
|
|
36
|
+
let listDevices = [];
|
|
37
|
+
let tree;
|
|
38
|
+
beforeEach(() => {
|
|
39
|
+
mockOnRightClick.mockClear();
|
|
40
|
+
Alert.alert.mockClear();
|
|
41
|
+
listDevices = [
|
|
42
|
+
{
|
|
43
|
+
id: 1,
|
|
44
|
+
name: 'Sub unit 1',
|
|
45
|
+
devices: [
|
|
46
|
+
{
|
|
47
|
+
id: 1,
|
|
48
|
+
icon_kit: 'https://xxx.png',
|
|
49
|
+
actions: [{ id: 1, name: 'action 1' }],
|
|
50
|
+
read_configs: [{ id: 1, name: 'config 1' }],
|
|
51
|
+
name: 'child1',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 2,
|
|
55
|
+
actions: [{ id: 2, name: 'action 2' }],
|
|
56
|
+
read_configs: [{ id: 2, name: 'config 2' }],
|
|
57
|
+
name: 'child2',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: 3,
|
|
61
|
+
actions: [],
|
|
62
|
+
read_configs: [],
|
|
63
|
+
name: 'child3',
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
id: 2,
|
|
69
|
+
name: 'Sub unit 2',
|
|
70
|
+
devices: [
|
|
71
|
+
{
|
|
72
|
+
id: 4,
|
|
73
|
+
icon: 'acb.png',
|
|
74
|
+
actions: [{ id: 3, name: 'action 3' }],
|
|
75
|
+
read_configs: [{ id: 3, name: 'config 3' }],
|
|
76
|
+
name: 'child1',
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
];
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const clickChooseAllDevices = async (instance, status) => {
|
|
84
|
+
const chooseAllDevices = instance.find(
|
|
85
|
+
(el) =>
|
|
86
|
+
el.props.accessibilityLabel ===
|
|
87
|
+
`${AccessibilityLabel.CHECK_BOX_CUSTOM}-all`
|
|
88
|
+
);
|
|
89
|
+
await act(async () => {
|
|
90
|
+
chooseAllDevices.props.onPress();
|
|
91
|
+
});
|
|
92
|
+
expect(chooseAllDevices.props.isChecked).toEqual(status);
|
|
93
|
+
};
|
|
94
|
+
const clickChooseDevice = async (instance, deviceId, status) => {
|
|
95
|
+
const chooseDevice = instance.find(
|
|
96
|
+
(el) =>
|
|
97
|
+
el.props.accessibilityLabel ===
|
|
98
|
+
`${AccessibilityLabel.SHARE_DEVICE.NAME_END_DEVICE}-device-${deviceId}`
|
|
99
|
+
);
|
|
100
|
+
await act(async () => {
|
|
101
|
+
chooseDevice.props.onPress();
|
|
102
|
+
});
|
|
103
|
+
const iconCheck = instance.findAll(
|
|
104
|
+
(el) =>
|
|
105
|
+
el.props.accessibilityLabel ===
|
|
106
|
+
`${AccessibilityLabel.SHARE_DEVICE.ICON_CHECK}-device-${deviceId}` &&
|
|
107
|
+
el.type === IconOutline
|
|
108
|
+
);
|
|
109
|
+
expect(iconCheck).toHaveLength(status ? 1 : 0);
|
|
110
|
+
};
|
|
111
|
+
const clickChooseConfig = async (instance, configId, status) => {
|
|
112
|
+
const chooseConfig = instance.find(
|
|
113
|
+
(el) =>
|
|
114
|
+
el.props.accessibilityLabel ===
|
|
115
|
+
`${AccessibilityLabel.CHECK_BOX_CUSTOM}-config-${configId}`
|
|
116
|
+
);
|
|
117
|
+
await act(async () => {
|
|
118
|
+
chooseConfig.props.onPress();
|
|
119
|
+
});
|
|
120
|
+
expect(chooseConfig.props.isChecked).toEqual(status);
|
|
121
|
+
};
|
|
122
|
+
const clickChooseAction = async (instance, actionId, status) => {
|
|
123
|
+
const chooseAction = instance.find(
|
|
124
|
+
(el) =>
|
|
125
|
+
el.props.accessibilityLabel ===
|
|
126
|
+
`${AccessibilityLabel.CHECK_BOX_CUSTOM}-action-${actionId}`
|
|
127
|
+
);
|
|
128
|
+
await act(async () => {
|
|
129
|
+
chooseAction.props.onPress();
|
|
130
|
+
});
|
|
131
|
+
expect(chooseAction.props.isChecked).toEqual(status);
|
|
132
|
+
};
|
|
133
|
+
const clickExpandDevice = async (instance, deviceId, status) => {
|
|
134
|
+
const expandDevice = instance.find(
|
|
135
|
+
(el) =>
|
|
136
|
+
el.props.accessibilityLabel ===
|
|
137
|
+
`${AccessibilityLabel.SHARE_DEVICE.EXPAND_END_DEVICE}-device-${deviceId}`
|
|
138
|
+
);
|
|
139
|
+
await act(async () => {
|
|
140
|
+
expandDevice.props.onPress();
|
|
141
|
+
});
|
|
142
|
+
expect(expandDevice.props.name).toEqual(status);
|
|
143
|
+
};
|
|
144
|
+
const clickSubmitSharePermission = async (instance, dataSubmit = null) => {
|
|
145
|
+
const submitSharePermission = instance.findByType(ViewButtonBottom);
|
|
146
|
+
await act(async () => {
|
|
147
|
+
submitSharePermission.props.onRightClick();
|
|
148
|
+
});
|
|
149
|
+
if (!dataSubmit) {
|
|
150
|
+
expect(mockOnRightClick).not.toHaveBeenCalled();
|
|
151
|
+
expect(Alert.alert.mock.calls[0][1]).toEqual(
|
|
152
|
+
'Please choose at least one device.'
|
|
153
|
+
);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
expect(mockOnRightClick).toHaveBeenCalledTimes(1);
|
|
157
|
+
expect(mockOnRightClick).toHaveBeenCalledWith(dataSubmit);
|
|
158
|
+
};
|
|
159
|
+
test('render all devices', async () => {
|
|
160
|
+
mock.onGet(API.SHARE.UNIT_PERMISSIONS_v2(unitId)).reply(200, listDevices);
|
|
161
|
+
await act(async () => {
|
|
162
|
+
tree = await create(wrapComponent(unitId));
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const instance = tree.root;
|
|
166
|
+
expect(instance.findAllByType(ShareDeviceSelector)).toHaveLength(1);
|
|
167
|
+
expect(instance.findAllByType(ViewButtonBottom)).toHaveLength(1);
|
|
168
|
+
expect(instance.findAllByType(SubUnitTreeView)).toHaveLength(1);
|
|
169
|
+
await clickChooseAllDevices(instance, true);
|
|
170
|
+
await clickExpandDevice(instance, 1, 'up');
|
|
171
|
+
await clickExpandDevice(instance, 2, 'up');
|
|
172
|
+
await clickExpandDevice(instance, 4, 'up');
|
|
173
|
+
expect(instance.findAllByType(SubUnitItem)).toHaveLength(3); //All + 2 subunits
|
|
174
|
+
expect(instance.findAllByType(DeviceItem)).toHaveLength(4);
|
|
175
|
+
expect(instance.findAllByType(ConfigItem)).toHaveLength(6);
|
|
176
|
+
const dataSubmit = {
|
|
177
|
+
read_permissions: [
|
|
178
|
+
{ id: 1, values: [1] },
|
|
179
|
+
{ id: 2, values: [2] },
|
|
180
|
+
{ id: 3, values: [] },
|
|
181
|
+
{ id: 4, values: [3] },
|
|
182
|
+
],
|
|
183
|
+
control_permissions: [
|
|
184
|
+
{ id: 1, values: [1] },
|
|
185
|
+
{ id: 2, values: [2] },
|
|
186
|
+
{ id: 4, values: [3] },
|
|
187
|
+
],
|
|
188
|
+
};
|
|
189
|
+
await clickSubmitSharePermission(instance, dataSubmit);
|
|
190
|
+
});
|
|
191
|
+
test('render empty subunit', async () => {
|
|
192
|
+
mock.onGet(API.SHARE.UNIT_PERMISSIONS_v2(unitId)).reply(200, []);
|
|
193
|
+
await act(async () => {
|
|
194
|
+
tree = await create(wrapComponent(unitId));
|
|
195
|
+
});
|
|
196
|
+
const instance = tree.root;
|
|
197
|
+
const noDataText = instance.find(
|
|
198
|
+
(el) =>
|
|
199
|
+
el.props.accessibilityLabel === AccessibilityLabel.TEXT_NO_DATA_STATIONS
|
|
200
|
+
);
|
|
201
|
+
expect(noDataText).toBeDefined();
|
|
202
|
+
expect(instance.findAllByType(SubUnitItem)).toHaveLength(0);
|
|
203
|
+
expect(instance.findAllByType(DeviceItem)).toHaveLength(0);
|
|
204
|
+
expect(instance.findAllByType(ConfigItem)).toHaveLength(0);
|
|
205
|
+
await clickSubmitSharePermission(instance);
|
|
206
|
+
});
|
|
207
|
+
test('click choose end device and config', async () => {
|
|
208
|
+
mock.onGet(API.SHARE.UNIT_PERMISSIONS_v2(unitId)).reply(200, listDevices);
|
|
209
|
+
await act(async () => {
|
|
210
|
+
tree = await create(wrapComponent(unitId));
|
|
211
|
+
});
|
|
212
|
+
const instance = tree.root;
|
|
213
|
+
expect(instance.findAllByType(SubUnitItem)).toHaveLength(3); //All + 2 subunits
|
|
214
|
+
expect(instance.findAllByType(DeviceItem)).toHaveLength(4);
|
|
215
|
+
await clickChooseDevice(instance, 1, true);
|
|
216
|
+
await clickExpandDevice(instance, 1, 'up');
|
|
217
|
+
expect(instance.findAllByType(ConfigItem)).toHaveLength(2);
|
|
218
|
+
const dataSubmit = {
|
|
219
|
+
read_permissions: [{ id: 1, values: [1] }],
|
|
220
|
+
control_permissions: [{ id: 1, values: [1] }],
|
|
221
|
+
};
|
|
222
|
+
await clickSubmitSharePermission(instance, dataSubmit);
|
|
223
|
+
});
|
|
224
|
+
test('render with init keys and go back', async () => {
|
|
225
|
+
mock.onGet(API.SHARE.UNIT_PERMISSIONS_v2(unitId)).reply(200, listDevices);
|
|
226
|
+
await act(async () => {
|
|
227
|
+
tree = await create(wrapComponent(unitId, ['config-3', 'action-3']));
|
|
228
|
+
});
|
|
229
|
+
const instance = tree.root;
|
|
230
|
+
expect(instance.findAllByType(SubUnitItem)).toHaveLength(3); //All + 2 subunits
|
|
231
|
+
expect(instance.findAllByType(DeviceItem)).toHaveLength(4);
|
|
232
|
+
const iconCheck = instance.findAll(
|
|
233
|
+
(el) =>
|
|
234
|
+
el.props.accessibilityLabel ===
|
|
235
|
+
`${AccessibilityLabel.SHARE_DEVICE.ICON_CHECK}-device-4` &&
|
|
236
|
+
el.type === IconOutline
|
|
237
|
+
);
|
|
238
|
+
expect(iconCheck).toHaveLength(1);
|
|
239
|
+
await clickExpandDevice(instance, 4, 'up');
|
|
240
|
+
const config = instance.find(
|
|
241
|
+
(el) =>
|
|
242
|
+
el.props.accessibilityLabel ===
|
|
243
|
+
`${AccessibilityLabel.CHECK_BOX_CUSTOM}-config-3`
|
|
244
|
+
);
|
|
245
|
+
const action = instance.find(
|
|
246
|
+
(el) =>
|
|
247
|
+
el.props.accessibilityLabel ===
|
|
248
|
+
`${AccessibilityLabel.CHECK_BOX_CUSTOM}-action-3`
|
|
249
|
+
);
|
|
250
|
+
expect(config.props.isChecked).toEqual(true);
|
|
251
|
+
expect(action.props.isChecked).toEqual(true);
|
|
252
|
+
await clickChooseDevice(instance, 4, false);
|
|
253
|
+
|
|
254
|
+
const mockGoBack = useNavigation().goBack;
|
|
255
|
+
const viewButtonBottom = instance.findByType(ViewButtonBottom);
|
|
256
|
+
await act(() => {
|
|
257
|
+
viewButtonBottom.props.onLeftClick();
|
|
258
|
+
});
|
|
259
|
+
expect(mockGoBack).toHaveBeenCalledTimes(1);
|
|
260
|
+
});
|
|
261
|
+
test('test 1 config id in 2 device', async () => {
|
|
262
|
+
listDevices[0].devices[1].actions.push({ id: 3, name: 'action-3' });
|
|
263
|
+
mock.onGet(API.SHARE.UNIT_PERMISSIONS_v2(unitId)).reply(200, listDevices);
|
|
264
|
+
await act(async () => {
|
|
265
|
+
tree = await create(wrapComponent(unitId));
|
|
266
|
+
});
|
|
267
|
+
const instance = tree.root;
|
|
268
|
+
expect(instance.findAllByType(SubUnitItem)).toHaveLength(3); //All + 2 subunits
|
|
269
|
+
expect(instance.findAllByType(DeviceItem)).toHaveLength(4);
|
|
270
|
+
|
|
271
|
+
await clickExpandDevice(instance, 1, 'up');
|
|
272
|
+
await clickChooseConfig(instance, 1, true);
|
|
273
|
+
await clickChooseAction(instance, 1, true);
|
|
274
|
+
|
|
275
|
+
await clickExpandDevice(instance, 2, 'up');
|
|
276
|
+
await clickExpandDevice(instance, 4, 'up');
|
|
277
|
+
|
|
278
|
+
const actions = instance.findAll(
|
|
279
|
+
(el) =>
|
|
280
|
+
el.props.accessibilityLabel ===
|
|
281
|
+
`${AccessibilityLabel.CHECK_BOX_CUSTOM}-action-3`
|
|
282
|
+
);
|
|
283
|
+
expect(actions).toHaveLength(2);
|
|
284
|
+
await act(async () => {
|
|
285
|
+
actions[0].props.onPress();
|
|
286
|
+
});
|
|
287
|
+
expect(actions[0].props.isChecked).toEqual(true);
|
|
288
|
+
|
|
289
|
+
const dataSubmit = {
|
|
290
|
+
read_permissions: [{ id: 1, values: [1] }],
|
|
291
|
+
control_permissions: [
|
|
292
|
+
{ id: 1, values: [1] },
|
|
293
|
+
{ id: 4, values: [3] },
|
|
294
|
+
],
|
|
295
|
+
};
|
|
296
|
+
await clickSubmitSharePermission(instance, dataSubmit);
|
|
297
|
+
});
|
|
298
|
+
});
|
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import CheckBoxCustom from './CheckBoxCustom';
|
|
2
|
+
import ConfigItem from './ConfigItem';
|
|
3
|
+
import DeviceItem from './DeviceItem';
|
|
4
|
+
import ShareDeviceSelector from './ShareDeviceSelector';
|
|
5
|
+
import SubUnitItem from './SubUnitItem';
|
|
6
|
+
import SubUnitTreeView from './SubUnitTreeView';
|
|
2
7
|
import TitleCheckBox from './TitleCheckBox';
|
|
3
8
|
|
|
4
|
-
export {
|
|
9
|
+
export {
|
|
10
|
+
CheckBoxCustom,
|
|
11
|
+
TitleCheckBox,
|
|
12
|
+
ConfigItem,
|
|
13
|
+
DeviceItem,
|
|
14
|
+
SubUnitItem,
|
|
15
|
+
SubUnitTreeView,
|
|
16
|
+
ShareDeviceSelector,
|
|
17
|
+
};
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { API, Colors, Images, SCConfig } from '../../configs';
|
|
2
|
+
import { ActivityIndicator, Image, TouchableOpacity, View } from 'react-native';
|
|
3
|
+
import { AlertAction, ViewButtonBottom } from '../../commons';
|
|
4
|
+
import React, { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
|
5
|
+
import { useDataMember, useStateAlertAction } from './hooks';
|
|
6
|
+
import { useIsFocused, useNavigation } from '@react-navigation/native';
|
|
7
|
+
|
|
8
|
+
import { AccessibilityLabel } from '../../configs/Constants';
|
|
4
9
|
import { CircleView } from '../../commons/CircleView';
|
|
5
|
-
import Text from '../../commons/Text';
|
|
6
|
-
import { shortEmailName } from '../../utils/Utils';
|
|
7
|
-
import { Colors, Images, API, SCConfig } from '../../configs';
|
|
8
10
|
import { HeaderCustom } from '../../commons/Header';
|
|
9
|
-
import RowMemberInfo from '../GuestInfo/components/RowGuestInfo';
|
|
10
|
-
import { useIsOwnerOfUnit } from '../../hooks/Common';
|
|
11
|
-
import { axiosGet } from '../../utils/Apis/axios';
|
|
12
|
-
import { AlertAction, ViewButtonBottom } from '../../commons';
|
|
13
|
-
import { useStateAlertAction, useDataMember } from './hooks';
|
|
14
11
|
import ItemChangeRole from './Components/ItemChangeRole';
|
|
15
12
|
import MemberSvg from '../../Images/Common/member.svg';
|
|
13
|
+
import ModalPopupCT from '../../commons/ModalPopupCT';
|
|
16
14
|
import OwnerSvg from '../../Images/Common/owner.svg';
|
|
17
|
-
import styles from './Styles/inforMemberUnitStyles';
|
|
18
|
-
import { useNavigation, useIsFocused } from '@react-navigation/native';
|
|
19
15
|
import Routes from '../../utils/Route';
|
|
20
|
-
import
|
|
21
|
-
import
|
|
16
|
+
import RowMemberInfo from '../GuestInfo/components/RowGuestInfo';
|
|
17
|
+
import Text from '../../commons/Text';
|
|
18
|
+
import { axiosGet } from '../../utils/Apis/axios';
|
|
19
|
+
import { shortEmailName } from '../../utils/Utils';
|
|
20
|
+
import styles from './Styles/inforMemberUnitStyles';
|
|
21
|
+
import { useIsOwnerOfUnit } from '../../hooks/Common';
|
|
22
|
+
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
22
23
|
|
|
23
24
|
const InfoMemberUnit = memo(({ route }) => {
|
|
24
25
|
const t = useTranslations();
|
|
25
|
-
const { member, unit } = route?.params ||
|
|
26
|
-
{}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
};
|
|
26
|
+
const { member, unit } = route?.params || {
|
|
27
|
+
member: {},
|
|
28
|
+
unit: {},
|
|
29
|
+
};
|
|
30
30
|
const { navigate } = useNavigation();
|
|
31
31
|
const [isLoading, setIsLoading] = useState(true);
|
|
32
32
|
const [isShowWarning, setIsShowWarning] = useState(false);
|