Device enrollment on new devicemgt react app See merge request entgra/carbon-device-mgt!443merge-requests/444/head
commit
b3e0fcd192
After Width: | Height: | Size: 2.7 MiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 804 KiB |
After Width: | Height: | Size: 798 KiB |
After Width: | Height: | Size: 794 KiB |
@ -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),
|
||||
);
|
@ -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);
|
Loading…
Reference in new issue