mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
Merge branch 'devicemgt-reactapp' into 'master'
Device enrollment on new devicemgt react app See merge request entgra/carbon-device-mgt!443
This commit is contained in:
commit
b3e0fcd192
Binary file not shown.
|
After Width: | Height: | Size: 2.7 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 804 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 798 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 794 KiB |
@ -89,12 +89,8 @@ class App extends React.Component {
|
|||||||
if (lastURLSegment === 'login') {
|
if (lastURLSegment === 'login') {
|
||||||
window.location.href = window.location.origin + '/entgra/';
|
window.location.href = window.location.origin + '/entgra/';
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
|
||||||
loading: false,
|
|
||||||
config: config,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.getDeviceTypes(config);
|
this.getDeviceTypes(config);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
if (error.hasOwnProperty('response') && error.response.status === 401) {
|
if (error.hasOwnProperty('response') && error.response.status === 401) {
|
||||||
|
|||||||
@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
|
|
||||||
* Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import { Form, Row, Col, Card, Steps } from 'antd';
|
|
||||||
import { withConfigContext } from '../../context/ConfigContext';
|
|
||||||
import DeviceType from './DeviceType';
|
|
||||||
import EnrollAgent from './EnrollAgent';
|
|
||||||
const { Step } = Steps;
|
|
||||||
|
|
||||||
class AddDevice extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.config = this.props.context;
|
|
||||||
this.state = {
|
|
||||||
isAddDeviceModalVisible: false,
|
|
||||||
current: 0,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onClickType = () => {
|
|
||||||
this.setState({
|
|
||||||
current: 1,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { current } = this.state;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Row>
|
|
||||||
<Col span={16} offset={4}>
|
|
||||||
<Steps style={{ minHeight: 32 }} current={current}>
|
|
||||||
<Step key="DeviceType" title="Device Type" />
|
|
||||||
<Step key="EnrollAgent" title="Enroll Agent" />
|
|
||||||
<Step key="Result" title="Result" />
|
|
||||||
</Steps>
|
|
||||||
</Col>
|
|
||||||
<Col span={16} offset={4}>
|
|
||||||
<Card style={{ marginTop: 24 }}>
|
|
||||||
<div style={{ display: current === 0 ? 'unset' : 'none' }}>
|
|
||||||
<DeviceType onClickType={this.onClickType} />
|
|
||||||
</div>
|
|
||||||
<div style={{ display: current === 1 ? 'unset' : 'none' }}>
|
|
||||||
<EnrollAgent />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style={{ display: current === 2 ? 'unset' : 'none' }}></div>
|
|
||||||
</Card>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default withConfigContext(
|
|
||||||
Form.create({ name: 'add-device' })(AddDevice),
|
|
||||||
);
|
|
||||||
@ -17,90 +17,27 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import axios from 'axios';
|
import { Card, Col, Icon, Row } from 'antd';
|
||||||
import { Card, Col, Icon, message, notification, Row } from 'antd';
|
|
||||||
import TimeAgo from 'javascript-time-ago';
|
import TimeAgo from 'javascript-time-ago';
|
||||||
// Load locale-specific relative date/time formatting rules.
|
// Load locale-specific relative date/time formatting rules.
|
||||||
import en from 'javascript-time-ago/locale/en';
|
import en from 'javascript-time-ago/locale/en';
|
||||||
import { withConfigContext } from '../../context/ConfigContext';
|
import { withConfigContext } from '../../context/ConfigContext';
|
||||||
|
|
||||||
let apiUrl;
|
|
||||||
|
|
||||||
class DeviceType extends React.Component {
|
class DeviceType extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
TimeAgo.addLocale(en);
|
TimeAgo.addLocale(en);
|
||||||
|
this.config = this.props.context;
|
||||||
this.state = {
|
this.state = {
|
||||||
data: [],
|
data: this.config.deviceTypes,
|
||||||
pagination: {},
|
pagination: {},
|
||||||
loading: false,
|
loading: false,
|
||||||
selectedRows: [],
|
selectedRows: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
onClickCard = (e, deviceType) => {
|
||||||
this.fetchUsers();
|
this.props.getDeviceType(deviceType);
|
||||||
}
|
|
||||||
|
|
||||||
onClickCard = data => {
|
|
||||||
console.log(data);
|
|
||||||
this.props.onClickType();
|
|
||||||
};
|
|
||||||
|
|
||||||
// fetch data from api
|
|
||||||
fetchUsers = (params = {}) => {
|
|
||||||
const config = this.props.context;
|
|
||||||
this.setState({ loading: true });
|
|
||||||
|
|
||||||
apiUrl =
|
|
||||||
window.location.origin +
|
|
||||||
config.serverConfig.invoker.uri +
|
|
||||||
config.serverConfig.invoker.deviceMgt +
|
|
||||||
'/device-types';
|
|
||||||
|
|
||||||
// send request to the invokerss
|
|
||||||
axios
|
|
||||||
.get(apiUrl)
|
|
||||||
.then(res => {
|
|
||||||
if (res.status === 200) {
|
|
||||||
const pagination = { ...this.state.pagination };
|
|
||||||
this.setState({
|
|
||||||
loading: false,
|
|
||||||
data: JSON.parse(res.data.data),
|
|
||||||
pagination,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
if (error.hasOwnProperty('response') && error.response.status === 401) {
|
|
||||||
// todo display a popop with error
|
|
||||||
message.error('You are not logged in');
|
|
||||||
window.location.href = window.location.origin + '/entgra/login';
|
|
||||||
} else {
|
|
||||||
notification.error({
|
|
||||||
message: 'There was a problem',
|
|
||||||
duration: 0,
|
|
||||||
description: 'Error occurred while trying to load device types.',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({ loading: false });
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
handleTableChange = (pagination, filters, sorter) => {
|
|
||||||
const pager = { ...this.state.pagination };
|
|
||||||
pager.current = pagination.current;
|
|
||||||
this.setState({
|
|
||||||
pagination: pager,
|
|
||||||
});
|
|
||||||
this.fetch({
|
|
||||||
results: pagination.pageSize,
|
|
||||||
page: pagination.current,
|
|
||||||
sortField: sorter.field,
|
|
||||||
sortOrder: sorter.order,
|
|
||||||
...filters,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -112,7 +49,7 @@ class DeviceType extends React.Component {
|
|||||||
size="default"
|
size="default"
|
||||||
style={{ width: 150 }}
|
style={{ width: 150 }}
|
||||||
bordered={true}
|
bordered={true}
|
||||||
onClick={this.onClickCard}
|
onClick={e => this.onClickCard(e, data.name)}
|
||||||
cover={
|
cover={
|
||||||
<Icon
|
<Icon
|
||||||
type="android"
|
type="android"
|
||||||
|
|||||||
@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
|
||||||
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { Form, Row, Col, Card, Steps } from 'antd';
|
||||||
|
import { withConfigContext } from '../../../context/ConfigContext';
|
||||||
|
import DeviceType from '../DeviceType';
|
||||||
|
import SelectEnrollmentType from './SelectEnrollmentType';
|
||||||
|
import EnrollDevice from './EnrollDevice';
|
||||||
|
import DownloadAgent from './DownloadAgent';
|
||||||
|
const { Step } = Steps;
|
||||||
|
|
||||||
|
class AddDevice extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.config = this.props.context;
|
||||||
|
this.state = {
|
||||||
|
isAddDeviceModalVisible: false,
|
||||||
|
current: 0,
|
||||||
|
deviceType: 'android',
|
||||||
|
enrollmentType: 'qr',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getDeviceType = deviceType => {
|
||||||
|
this.setState({
|
||||||
|
current: 1,
|
||||||
|
deviceType: deviceType,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
goNext = () => {
|
||||||
|
this.setState({
|
||||||
|
current: 2,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
goBackToDeviceType = () => {
|
||||||
|
this.setState({
|
||||||
|
current: 0,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
goBackToDownloadAgent = () => {
|
||||||
|
this.setState({
|
||||||
|
current: 1,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
goBackToEnrollmentType = () => {
|
||||||
|
this.setState({
|
||||||
|
current: 2,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
getEnrollmentData = enrollmentType => {
|
||||||
|
this.setState({
|
||||||
|
current: 3,
|
||||||
|
enrollmentType: enrollmentType,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { current, deviceType, enrollmentType } = this.state;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Row>
|
||||||
|
<Col span={16} offset={4}>
|
||||||
|
<Steps style={{ minHeight: 32 }} current={current}>
|
||||||
|
<Step key="DeviceType" title="Select Device Type" />
|
||||||
|
<Step key="DownloadAgent" title="Download Agent" />
|
||||||
|
<Step key="EnrollmentType" title="Enrollment Type" />
|
||||||
|
<Step key="EnrollDevice" title="Enroll Device" />
|
||||||
|
</Steps>
|
||||||
|
</Col>
|
||||||
|
<Col span={16} offset={4}>
|
||||||
|
<Card style={{ marginTop: 24 }}>
|
||||||
|
<div style={{ display: current === 0 ? 'unset' : 'none' }}>
|
||||||
|
<DeviceType getDeviceType={this.getDeviceType} />
|
||||||
|
</div>
|
||||||
|
<div style={{ display: current === 1 ? 'unset' : 'none' }}>
|
||||||
|
<DownloadAgent
|
||||||
|
deviceType={deviceType}
|
||||||
|
goNext={this.goNext}
|
||||||
|
goBack={this.goBackToDeviceType}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style={{ display: current === 2 ? 'unset' : 'none' }}>
|
||||||
|
<SelectEnrollmentType
|
||||||
|
deviceType={deviceType}
|
||||||
|
getEnrollmentData={this.getEnrollmentData}
|
||||||
|
goBack={this.goBackToDownloadAgent}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ display: current === 3 ? 'unset' : 'none' }}>
|
||||||
|
<EnrollDevice
|
||||||
|
deviceType={deviceType}
|
||||||
|
enrollmentType={enrollmentType}
|
||||||
|
goBack={this.goBackToEnrollmentType}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(
|
||||||
|
Form.create({ name: 'add-device' })(AddDevice),
|
||||||
|
);
|
||||||
@ -0,0 +1,173 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
|
||||||
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { Button, Card, Divider, message, notification } from 'antd';
|
||||||
|
import TimeAgo from 'javascript-time-ago/modules/JavascriptTimeAgo';
|
||||||
|
import en from 'javascript-time-ago/locale/en';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { withConfigContext } from '../../../context/ConfigContext';
|
||||||
|
import QRCode from 'qrcode.react';
|
||||||
|
|
||||||
|
class SelectEnrollmentType extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.config = this.props.context;
|
||||||
|
TimeAgo.addLocale(en);
|
||||||
|
this.state = {
|
||||||
|
pagination: {},
|
||||||
|
loading: false,
|
||||||
|
selectedRows: [],
|
||||||
|
buttonTitle: 'Download Agent',
|
||||||
|
skipButtonTitle: 'Skip',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickSkip = () => {
|
||||||
|
this.props.goNext();
|
||||||
|
};
|
||||||
|
|
||||||
|
onClickGoBack = () => {
|
||||||
|
this.props.goBack();
|
||||||
|
};
|
||||||
|
|
||||||
|
onClickDownloadAgent = () => {
|
||||||
|
this.downloadAgent();
|
||||||
|
};
|
||||||
|
|
||||||
|
// fetch data from api
|
||||||
|
downloadAgent = () => {
|
||||||
|
const { deviceType } = this.props;
|
||||||
|
this.setState({ loading: true, buttonTitle: 'Downloading..' });
|
||||||
|
|
||||||
|
const apiUrl =
|
||||||
|
window.location.origin +
|
||||||
|
'/api/application-mgt/v1.0/artifact/' +
|
||||||
|
deviceType +
|
||||||
|
'/agent/-1234';
|
||||||
|
|
||||||
|
// send request to the invokerss
|
||||||
|
axios
|
||||||
|
.get(apiUrl)
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
// Download file in same window
|
||||||
|
const url = window.URL.createObjectURL(new Blob([res.data]));
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = url;
|
||||||
|
link.setAttribute('download', 'android-agent.apk'); // or any other extension
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
buttonTitle: 'Download Agent',
|
||||||
|
skipButtonTitle: 'Next',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
if (error.hasOwnProperty('response') && error.response.status === 401) {
|
||||||
|
// todo display a popop with error
|
||||||
|
message.error('You are not logged in');
|
||||||
|
window.location.href = window.location.origin + '/entgra/login';
|
||||||
|
} else {
|
||||||
|
notification.error({
|
||||||
|
message: 'There was a problem',
|
||||||
|
duration: 0,
|
||||||
|
description:
|
||||||
|
'Error occurred while trying to download Entgra Android Agent',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ loading: false });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { loading, buttonTitle, skipButtonTitle } = this.state;
|
||||||
|
const { deviceType } = this.props;
|
||||||
|
|
||||||
|
const apiUrl =
|
||||||
|
window.location.origin +
|
||||||
|
'/api/application-mgt/v1.0/artifact/' +
|
||||||
|
deviceType +
|
||||||
|
'/agent/-1234';
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Divider orientation="left">Step 01 - Get your Android Agent.</Divider>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
The Android agent can be downloaded by using following QR. The
|
||||||
|
generated QR code can be scanned, and the agent APK downloaded from
|
||||||
|
the link, and transferred to the device and then installed.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div style={{ margin: '30px', textAlign: 'center' }}>
|
||||||
|
<Divider>Scan to get the Android Agent.</Divider>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
marginBottm: 10,
|
||||||
|
display: 'inline-block',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Card hoverable>
|
||||||
|
<QRCode size={200} value={apiUrl} />
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
<Divider>OR</Divider>
|
||||||
|
<div style={{ textAlign: 'center', marginTop: 10, marginBottom: 10 }}>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
size={'default'}
|
||||||
|
onClick={this.onClickDownloadAgent}
|
||||||
|
loading={loading}
|
||||||
|
>
|
||||||
|
{buttonTitle}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Need help? Read
|
||||||
|
<a
|
||||||
|
href={
|
||||||
|
'https://entgra-documentation.gitlab.io/v3.8.0/docs/guide-to-work-with-the-product/' +
|
||||||
|
'enrollment-guide/enroll-android/'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Entgra IoT Server documentation.
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div style={{ textAlign: 'right' }}>
|
||||||
|
<Button type="primary" size={'default'} onClick={this.onClickSkip}>
|
||||||
|
{skipButtonTitle}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
style={{ marginLeft: 10 }}
|
||||||
|
type="default"
|
||||||
|
size={'default'}
|
||||||
|
onClick={this.onClickGoBack}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(SelectEnrollmentType);
|
||||||
@ -0,0 +1,217 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
|
||||||
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Divider,
|
||||||
|
message,
|
||||||
|
notification,
|
||||||
|
Select,
|
||||||
|
Card,
|
||||||
|
Spin,
|
||||||
|
Button,
|
||||||
|
Row,
|
||||||
|
Col,
|
||||||
|
} from 'antd';
|
||||||
|
import TimeAgo from 'javascript-time-ago/modules/JavascriptTimeAgo';
|
||||||
|
import en from 'javascript-time-ago/locale/en';
|
||||||
|
import { withConfigContext } from '../../../context/ConfigContext';
|
||||||
|
import axios from 'axios';
|
||||||
|
import QRCode from 'qrcode.react';
|
||||||
|
import QRPlaceholder from '../../../../public/images/qr-code.png';
|
||||||
|
import installAgent from '../../../../public/images/install_agent.png';
|
||||||
|
import register from '../../../../public/images/register.png';
|
||||||
|
import registration from '../../../../public/images/registration.png';
|
||||||
|
import setProfile from '../../../../public/images/set_profile.png';
|
||||||
|
|
||||||
|
const { Option } = Select;
|
||||||
|
|
||||||
|
class EnrollDevice extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.config = this.props.context;
|
||||||
|
TimeAgo.addLocale(en);
|
||||||
|
this.state = {
|
||||||
|
isSelected: false,
|
||||||
|
loading: false,
|
||||||
|
payload: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetch data from api
|
||||||
|
generateQRCode = ownershipType => {
|
||||||
|
const { deviceType } = this.props;
|
||||||
|
this.setState({ loading: true });
|
||||||
|
|
||||||
|
let apiUrl =
|
||||||
|
window.location.origin +
|
||||||
|
this.config.serverConfig.invoker.uri +
|
||||||
|
'/device-mgt/' +
|
||||||
|
deviceType +
|
||||||
|
'/v1.0/configuration/enrollment-qr-config/' +
|
||||||
|
ownershipType;
|
||||||
|
|
||||||
|
// send request to the invokerss
|
||||||
|
axios
|
||||||
|
.get(apiUrl)
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
payload: res.data.data,
|
||||||
|
isSelected: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
if (error.hasOwnProperty('response') && error.response.status === 401) {
|
||||||
|
// todo display a popop with error
|
||||||
|
message.error('You are not logged in');
|
||||||
|
window.location.href = window.location.origin + '/entgra/login';
|
||||||
|
} else {
|
||||||
|
notification.error({
|
||||||
|
message: 'There was a problem',
|
||||||
|
duration: 0,
|
||||||
|
description: 'Error occurred while trying to get QR code payload.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ loading: false });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onChange = value => {
|
||||||
|
this.generateQRCode(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
onClick = () => {
|
||||||
|
this.props.goBack();
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { payload, isSelected, loading } = this.state;
|
||||||
|
const { enrollmentType } = this.props;
|
||||||
|
return (
|
||||||
|
<div style={{ textAlign: 'center', fontSize: 12 }}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: enrollmentType === 'manual' ? 'inline-block' : 'none',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Row gutter={[16, 16]}>
|
||||||
|
<Col span={6}>
|
||||||
|
<h1>Step 1</h1>
|
||||||
|
<p>
|
||||||
|
{/* eslint-disable-next-line react/no-unescaped-entities */}
|
||||||
|
Let's start by installing the Android agent on your device. Open
|
||||||
|
the downloaded file, and tap INSTALL.
|
||||||
|
</p>
|
||||||
|
<img src={installAgent} />
|
||||||
|
</Col>
|
||||||
|
<Col span={6}>
|
||||||
|
<h1>Step 2</h1>
|
||||||
|
<p>Tap Skip to proceed with the default enrollment process.</p>
|
||||||
|
<img src={setProfile} />
|
||||||
|
</Col>
|
||||||
|
<Col span={6}>
|
||||||
|
<h1>Step 3</h1>
|
||||||
|
<p>
|
||||||
|
Enter the server address based on your environment, in the text
|
||||||
|
box provided.
|
||||||
|
</p>
|
||||||
|
<img src={registration} />
|
||||||
|
</Col>
|
||||||
|
<Col span={6}>
|
||||||
|
<h1>Step 4</h1>
|
||||||
|
<p>Enter your:</p>
|
||||||
|
<div>
|
||||||
|
<p>Organization: carbon.super</p>
|
||||||
|
<p>Username: admin</p>
|
||||||
|
<p>Password: Your password</p>
|
||||||
|
</div>
|
||||||
|
<img src={register} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: enrollmentType === 'qr' ? 'inline-block' : 'none',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Divider>Generate QR code to QR based Provisioning.</Divider>
|
||||||
|
<div style={{ textAlign: 'center' }}>
|
||||||
|
<div style={{ marginBottom: 10 }}>
|
||||||
|
<Select
|
||||||
|
showSearch
|
||||||
|
style={{ width: 200, textAlign: 'center' }}
|
||||||
|
placeholder="Select device ownership"
|
||||||
|
optionFilterProp="children"
|
||||||
|
onChange={this.onChange}
|
||||||
|
filterOption={(input, option) =>
|
||||||
|
option.props.children
|
||||||
|
.toLowerCase()
|
||||||
|
.indexOf(input.toLowerCase()) >= 0
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Option key={'byod'} value={'BYOD'}>
|
||||||
|
{'BYOD'}
|
||||||
|
</Option>
|
||||||
|
<Option key={'cope'} value={'COPE'}>
|
||||||
|
{'COPE'}
|
||||||
|
</Option>
|
||||||
|
<Option key={'COSU'} value={'COSU'}>
|
||||||
|
{'COSU (KIOSK)'}
|
||||||
|
</Option>
|
||||||
|
<Option key={'WORK PROFILE'} value={'WORK_PROFILE'}>
|
||||||
|
{'WORK PROFILE'}
|
||||||
|
</Option>
|
||||||
|
<Option key={'GOOGLE_ENTERPRISE'} value={'GOOGLE_ENTERPRISE'}>
|
||||||
|
{'GOOGLE_WORK_PROFILE'}
|
||||||
|
</Option>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<Spin spinning={loading}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: isSelected ? 'inline-block' : 'none',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Card hoverable>
|
||||||
|
<QRCode size={300} value={JSON.stringify(payload)} />
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
<div style={{ display: !isSelected ? 'inline-block' : 'none' }}>
|
||||||
|
<Card hoverable>
|
||||||
|
<img src={QRPlaceholder} />
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</Spin>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style={{ textAlign: 'right', marginTop: 10 }}>
|
||||||
|
<Button type="default" size={'default'} onClick={this.onClick}>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(EnrollDevice);
|
||||||
@ -17,73 +17,38 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Button, Divider, message, notification } from 'antd';
|
import { Button, Divider } from 'antd';
|
||||||
import TimeAgo from 'javascript-time-ago/modules/JavascriptTimeAgo';
|
import TimeAgo from 'javascript-time-ago/modules/JavascriptTimeAgo';
|
||||||
import en from 'javascript-time-ago/locale/en';
|
import en from 'javascript-time-ago/locale/en';
|
||||||
import axios from 'axios';
|
import { withConfigContext } from '../../../context/ConfigContext';
|
||||||
import { withConfigContext } from '../../context/ConfigContext';
|
|
||||||
|
|
||||||
class EnrollAgent extends React.Component {
|
class SelectEnrollmentType extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.config = this.props.context;
|
this.config = this.props.context;
|
||||||
TimeAgo.addLocale(en);
|
TimeAgo.addLocale(en);
|
||||||
this.state = {
|
this.state = {
|
||||||
data: [],
|
|
||||||
pagination: {},
|
pagination: {},
|
||||||
loading: false,
|
loading: false,
|
||||||
selectedRows: [],
|
selectedRows: [],
|
||||||
visibleSelector: { display: 'none' },
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
componentDidMount() {
|
|
||||||
this.getConfigData();
|
|
||||||
}
|
|
||||||
|
|
||||||
onGetEnrollmentQR = () => {
|
onEnrollWithQR = () => {
|
||||||
this.setState({
|
this.props.getEnrollmentData('qr');
|
||||||
visibleSelector: { display: 'block' },
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
getConfigData = () => {
|
onEnrollManually = () => {
|
||||||
axios
|
this.props.getEnrollmentData('manual');
|
||||||
.get(
|
};
|
||||||
window.location.origin +
|
|
||||||
this.config.serverConfig.invoker.uri +
|
onClick = () => {
|
||||||
'/device-mgt/android/v1.0/configuration',
|
this.props.goBack();
|
||||||
)
|
|
||||||
.catch(error => {
|
|
||||||
if (error.hasOwnProperty('response') && error.response.status === 401) {
|
|
||||||
// todo display a popop with error
|
|
||||||
message.error('You are not logged in');
|
|
||||||
window.location.href = window.location.origin + '/entgra/login';
|
|
||||||
} else {
|
|
||||||
notification.error({
|
|
||||||
message: 'There was a problem',
|
|
||||||
duration: 0,
|
|
||||||
description: 'Error occurred while retrieving device groups.',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Divider orientation="left">Step 01 - Get your Android Agent.</Divider>
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
The Android agent can be downloaded by using following QR. The
|
|
||||||
generated QR code can be scanned, and the agent APK downloaded from
|
|
||||||
the link, and transferred to the device and then installed.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div style={{ margin: '30px' }}>
|
|
||||||
<Button type="primary" size={'default'}>
|
|
||||||
Get Android Agent
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<Divider orientation="left">
|
<Divider orientation="left">
|
||||||
Step 02 - Enroll the Android Agent.
|
Step 02 - Enroll the Android Agent.
|
||||||
</Divider>
|
</Divider>
|
||||||
@ -102,14 +67,28 @@ class EnrollAgent extends React.Component {
|
|||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
size={'default'}
|
size={'default'}
|
||||||
onClick={this.onGetEnrollmentQR}
|
onClick={this.onEnrollWithQR}
|
||||||
|
style={{ marginRight: 10 }}
|
||||||
>
|
>
|
||||||
Enroll Using QR
|
Enroll Using QR
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
size={'default'}
|
||||||
|
onClick={this.onEnrollManually}
|
||||||
|
>
|
||||||
|
Enroll Manually
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div style={{ textAlign: 'right' }}>
|
||||||
|
<Button type="default" size={'default'} onClick={this.onClick}>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withConfigContext(EnrollAgent);
|
export default withConfigContext(SelectEnrollmentType);
|
||||||
@ -32,6 +32,8 @@ import DeviceStatusReport from './components/Reports/Templates/DeviceStatusRepor
|
|||||||
import PolicyReportHome from './pages/Dashboard/Reports/PolicyReportHome';
|
import PolicyReportHome from './pages/Dashboard/Reports/PolicyReportHome';
|
||||||
import ReportDurationItemList from './pages/Dashboard/Reports/ReportDurationItemList';
|
import ReportDurationItemList from './pages/Dashboard/Reports/ReportDurationItemList';
|
||||||
import AppNotInstalledDevicesReport from './components/Reports/Templates/AppNotInstalledDevicesReport';
|
import AppNotInstalledDevicesReport from './components/Reports/Templates/AppNotInstalledDevicesReport';
|
||||||
|
import Devices from './pages/Dashboard/Devices/Devices';
|
||||||
|
import DeviceEnroll from './pages/Dashboard/Devices/DeviceEnroll';
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
@ -44,16 +46,16 @@ const routes = [
|
|||||||
exact: false,
|
exact: false,
|
||||||
component: Dashboard,
|
component: Dashboard,
|
||||||
routes: [
|
routes: [
|
||||||
// {
|
{
|
||||||
// path: '/entgra/devices',
|
path: '/entgra/devices',
|
||||||
// component: Devices,
|
component: Devices,
|
||||||
// exact: true,
|
exact: true,
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// path: '/entgra/devices/enroll',
|
path: '/entgra/devices/enroll',
|
||||||
// component: DeviceEnroll,
|
component: DeviceEnroll,
|
||||||
// exact: true,
|
exact: true,
|
||||||
// },
|
},
|
||||||
{
|
{
|
||||||
path: '/entgra/geo',
|
path: '/entgra/geo',
|
||||||
component: Geo,
|
component: Geo,
|
||||||
|
|||||||
@ -72,26 +72,26 @@ class Dashboard extends React.Component {
|
|||||||
marginRight: 110,
|
marginRight: 110,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* <SubMenu*/}
|
<SubMenu
|
||||||
{/* key="devices"*/}
|
key="devices"
|
||||||
{/* title={*/}
|
title={
|
||||||
{/* <span>*/}
|
<span>
|
||||||
{/* <Icon type="appstore" />*/}
|
<Icon type="appstore" />
|
||||||
{/* <span>Devices</span>*/}
|
<span>Devices</span>
|
||||||
{/* </span>*/}
|
</span>
|
||||||
{/* }*/}
|
}
|
||||||
{/* >*/}
|
>
|
||||||
{/* <Menu.Item key="devices">*/}
|
<Menu.Item key="devices">
|
||||||
{/* <Link to="/entgra/devices">*/}
|
<Link to="/entgra/devices">
|
||||||
{/* <span>View</span>*/}
|
<span>View</span>
|
||||||
{/* </Link>*/}
|
</Link>
|
||||||
{/* </Menu.Item>*/}
|
</Menu.Item>
|
||||||
{/* <Menu.Item key="deviceEnroll">*/}
|
<Menu.Item key="deviceEnroll">
|
||||||
{/* <Link to="/entgra/devices/enroll">*/}
|
<Link to="/entgra/devices/enroll">
|
||||||
{/* <span>Enroll</span>*/}
|
<span>Enroll</span>
|
||||||
{/* </Link>*/}
|
</Link>
|
||||||
{/* </Menu.Item>*/}
|
</Menu.Item>
|
||||||
{/* </SubMenu>*/}
|
</SubMenu>
|
||||||
<SubMenu
|
<SubMenu
|
||||||
key="geo"
|
key="geo"
|
||||||
title={
|
title={
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { PageHeader, Typography, Breadcrumb, Icon } from 'antd';
|
import { PageHeader, Typography, Breadcrumb, Icon } from 'antd';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import AddDevice from '../../../components/Devices/AddDevice';
|
import AddDevice from '../../../components/Devices/Enroll-Device/AddDevice';
|
||||||
|
|
||||||
const { Paragraph } = Typography;
|
const { Paragraph } = Typography;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user