diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/install_agent.png b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/install_agent.png new file mode 100644 index 00000000000..2686c87b5d9 Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/install_agent.png differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/qr-code.png b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/qr-code.png new file mode 100644 index 00000000000..00c8544c198 Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/qr-code.png differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/register.png b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/register.png new file mode 100644 index 00000000000..f7e4bfedfec Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/register.png differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/registration.png b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/registration.png new file mode 100644 index 00000000000..f7a3bad6b67 Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/registration.png differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/set_profile.png b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/set_profile.png new file mode 100644 index 00000000000..81de7a59933 Binary files /dev/null and b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/set_profile.png differ diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js index fb01bb034cd..91594d90351 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js @@ -89,12 +89,8 @@ class App extends React.Component { if (lastURLSegment === 'login') { window.location.href = window.location.origin + '/entgra/'; } else { - this.setState({ - loading: false, - config: config, - }); + this.getDeviceTypes(config); } - this.getDeviceTypes(config); }) .catch(error => { if (error.hasOwnProperty('response') && error.response.status === 401) { diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/AddDevice.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/AddDevice.js deleted file mode 100644 index a8a407d0bca..00000000000 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/AddDevice.js +++ /dev/null @@ -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 ( -
- - - - - - - - - - -
- -
-
- -
- -
-
- -
-
- ); - } -} - -export default withConfigContext( - Form.create({ name: 'add-device' })(AddDevice), -); diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/DeviceType.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/DeviceType.js index ece71df1166..1f6347d2a83 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/DeviceType.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/DeviceType.js @@ -17,90 +17,27 @@ */ import React from 'react'; -import axios from 'axios'; -import { Card, Col, Icon, message, notification, Row } from 'antd'; +import { Card, Col, Icon, Row } from 'antd'; import TimeAgo from 'javascript-time-ago'; // Load locale-specific relative date/time formatting rules. import en from 'javascript-time-ago/locale/en'; import { withConfigContext } from '../../context/ConfigContext'; -let apiUrl; - class DeviceType extends React.Component { constructor(props) { super(props); TimeAgo.addLocale(en); + this.config = this.props.context; this.state = { - data: [], + data: this.config.deviceTypes, pagination: {}, loading: false, selectedRows: [], }; } - componentDidMount() { - this.fetchUsers(); - } - - 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, - }); + onClickCard = (e, deviceType) => { + this.props.getDeviceType(deviceType); }; render() { @@ -112,7 +49,7 @@ class DeviceType extends React.Component { size="default" style={{ width: 150 }} bordered={true} - onClick={this.onClickCard} + onClick={e => this.onClickCard(e, data.name)} cover={ { + 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 ( +
+ + + + + + + + + + + +
+ +
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+ ); + } +} + +export default withConfigContext( + Form.create({ name: 'add-device' })(AddDevice), +); diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/Enroll-Device/DownloadAgent.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/Enroll-Device/DownloadAgent.js new file mode 100644 index 00000000000..fa7148f1a8c --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/Enroll-Device/DownloadAgent.js @@ -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 ( +
+ Step 01 - Get your Android Agent. +
+

+ 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. +

+
+
+ Scan to get the Android Agent. +
+ + + +
+ OR +
+ +
+

+ Need help? Read  + + Entgra IoT Server documentation. + +

+
+
+ + +
+
+ ); + } +} + +export default withConfigContext(SelectEnrollmentType); diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/Enroll-Device/EnrollDevice.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/Enroll-Device/EnrollDevice.js new file mode 100644 index 00000000000..add28e35337 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/Enroll-Device/EnrollDevice.js @@ -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 ( +
+
+ + +

Step 1

+

+ {/* 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. +

+ + + +

Step 2

+

Tap Skip to proceed with the default enrollment process.

+ + + +

Step 3

+

+ Enter the server address based on your environment, in the text + box provided. +

+ + + +

Step 4

+

Enter your:

+
+

Organization: carbon.super

+

Username: admin

+

Password: Your password

+
+ + +
+
+ +
+ Generate QR code to QR based Provisioning. +
+
+ +
+ +
+ + + +
+
+ + + +
+
+
+
+
+ +
+
+ ); + } +} + +export default withConfigContext(EnrollDevice); diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/EnrollAgent.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/Enroll-Device/SelectEnrollmentType.js similarity index 52% rename from components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/EnrollAgent.js rename to components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/Enroll-Device/SelectEnrollmentType.js index 5707d9ccb63..34a0904afb4 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/EnrollAgent.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/Enroll-Device/SelectEnrollmentType.js @@ -17,73 +17,38 @@ */ 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 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) { super(props); this.config = this.props.context; TimeAgo.addLocale(en); this.state = { - data: [], pagination: {}, loading: false, selectedRows: [], - visibleSelector: { display: 'none' }, }; } - componentDidMount() { - this.getConfigData(); - } - onGetEnrollmentQR = () => { - this.setState({ - visibleSelector: { display: 'block' }, - }); + onEnrollWithQR = () => { + this.props.getEnrollmentData('qr'); + }; + + onEnrollManually = () => { + this.props.getEnrollmentData('manual'); }; - getConfigData = () => { - axios - .get( - window.location.origin + - this.config.serverConfig.invoker.uri + - '/device-mgt/android/v1.0/configuration', - ) - .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.', - }); - } - }); + onClick = () => { + this.props.goBack(); }; render() { return (
- Step 01 - Get your Android Agent. -
-

- 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. -

-
-
- -
Step 02 - Enroll the Android Agent. @@ -102,14 +67,28 @@ class EnrollAgent extends React.Component { + + +
+
+
); } } -export default withConfigContext(EnrollAgent); +export default withConfigContext(SelectEnrollmentType); diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js index acbd25f60e6..e37a4cc94f4 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js @@ -32,6 +32,8 @@ import DeviceStatusReport from './components/Reports/Templates/DeviceStatusRepor import PolicyReportHome from './pages/Dashboard/Reports/PolicyReportHome'; import ReportDurationItemList from './pages/Dashboard/Reports/ReportDurationItemList'; import AppNotInstalledDevicesReport from './components/Reports/Templates/AppNotInstalledDevicesReport'; +import Devices from './pages/Dashboard/Devices/Devices'; +import DeviceEnroll from './pages/Dashboard/Devices/DeviceEnroll'; const routes = [ { @@ -44,16 +46,16 @@ const routes = [ exact: false, component: Dashboard, routes: [ - // { - // path: '/entgra/devices', - // component: Devices, - // exact: true, - // }, - // { - // path: '/entgra/devices/enroll', - // component: DeviceEnroll, - // exact: true, - // }, + { + path: '/entgra/devices', + component: Devices, + exact: true, + }, + { + path: '/entgra/devices/enroll', + component: DeviceEnroll, + exact: true, + }, { path: '/entgra/geo', component: Geo, diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.js index da03b3126a0..697e3aec7cb 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.js @@ -72,26 +72,26 @@ class Dashboard extends React.Component { marginRight: 110, }} > - {/* */} - {/* */} - {/* Devices*/} - {/* */} - {/* }*/} - {/* >*/} - {/* */} - {/* */} - {/* View*/} - {/* */} - {/* */} - {/* */} - {/* */} - {/* Enroll*/} - {/* */} - {/* */} - {/* */} + + + Devices + + } + > + + + View + + + + + Enroll + + +