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 new file mode 100644 index 00000000000..c466b6825b0 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/AddDevice.js @@ -0,0 +1,66 @@ +import React from 'react'; +import {Button, Form, Row, Col, Card, Steps, Input, message, Modal, notification, Typography} from "antd"; +import axios from "axios"; +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, + }) + }; + + openAddDeviceModal = () =>{ + this.setState({ + isAddDeviceModalVisible : true, + }) + }; + + render() { + const {loading, current, isError, supportedOsVersions, errorText, forbiddenErrors} = this.state; + const { getFieldDecorator } = this.props.form; + return ( +
+ + + + + + + + + + + +
+ +
+
+ +
+ +
+
+
+ +
+ +
+ ); + } +} + +export default withConfigContext(Form.create({name: 'add-device'})(AddDevice)); \ No newline at end of file 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 new file mode 100644 index 00000000000..627998a5339 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/DeviceType.js @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2019, 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 axios from "axios"; +import {Card, Col, Icon, message, notification, Row, Typography} 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"; + +const {Text} = Typography; + +let config = null; +let apiUrl; + +class DeviceType extends React.Component { + constructor(props) { + super(props); + config = this.props.context; + TimeAgo.addLocale(en); + this.state = { + data: [], + 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}); + + // get current page + const currentPage = (params.hasOwnProperty("page")) ? params.page : 1; + + const extraParams = { + offset: 10 * (currentPage - 1), //calculate the offset + limit: 10, + }; + + const encodedExtraParams = Object.keys(extraParams) + .map(key => key + '=' + extraParams[key]).join('&'); + + 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() { + + const {data, pagination, loading, selectedRows} = this.state; + const { Meta } = Card; + const itemCard = data.map((data) => + + } + > + + + + + ); + return ( +
+ + {itemCard} + +
+ ); + } +} + +export default withConfigContext(DeviceType); \ No newline at end of file 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/EnrollAgent.js new file mode 100644 index 00000000000..bb710853ea4 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/EnrollAgent.js @@ -0,0 +1,87 @@ +import React from 'react'; +import {Collapse, Button, Divider, message, notification , Select} 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"; +const { Option } = Select; + +class EnrollAgent 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'} + }) + }; + + getConfigData = () =>{ + axios.get( + window.location.origin + this.config.serverConfig.invoker.uri + + "/device-mgt/android/v1.0/configuration" + ).then(res => { + let data = res.data.data; + }).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() { + 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. + +
+

Your device can be enrolled with Entgra IoTS automatically via QR code. + To enroll first download agent as mentioned in Step 1 then proceed with the ENROLL WITH + QR option from the device setup activity. Thereafter select the ownership configuration + and scan the generated QR to complete the process.

+
+
+ +
+
+ ); + } +} + +export default withConfigContext(EnrollAgent); \ No newline at end of file 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 8eeca9f07c2..8c89a821a7f 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 @@ -31,6 +31,7 @@ import Users from "./pages/Dashboard/Users/Users"; import Policies from "./pages/Dashboard/Policies/Policies"; import Roles from "./pages/Dashboard/Roles/Roles"; import DeviceTypes from "./pages/Dashboard/DeviceTypes/DeviceTypes"; +import DeviceEnroll from "./pages/Dashboard/Devices/DeviceEnroll"; const routes = [ { @@ -48,6 +49,11 @@ const routes = [ 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.css b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.css index 7923d0a9fc9..5d0adb92cb3 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.css +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.css @@ -35,13 +35,7 @@ } .layout .logo-image { - position: relative; - height: 64px; - padding-left: 8px; - overflow: hidden; - line-height: 64px; - background: #001529; - transition: all .3s; + float: left; } .layout .brand{ @@ -54,7 +48,7 @@ } .layout .logo-image img { - height: 55px; + height: 45px; margin-top: 5px; margin-left: 16px; margin-right: 16px; 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 138d70e0940..c8262018677 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 @@ -56,97 +56,91 @@ class Dashboard extends React.Component { return (
+ +
+
+ logo +
- - -
- logo -
- - - - - Devices - - - + + + Devices + } + > + + + View + + + + + Enroll + + + + Geo } - > - - - Single Device View + > + + + Single Device View + + + + + Device Group View + + + + + + + Reports - - - Device Group View + + + + Groups + + + + + + Users + + + + + + Policies + + + + + + Roles + + + + + + Device Types - - - - - Reports - - - - - - Groups - - - - - - Users - - - - - - Policies - - - - - - Roles - - - - - - Device Types - - - - -
- - -
-
- -
- -
- + {this.state.routes.map((route) => ( diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/DeviceEnroll.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/DeviceEnroll.js new file mode 100644 index 00000000000..9d21aeda79b --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/DeviceEnroll.js @@ -0,0 +1,50 @@ +import React from 'react'; +import { + PageHeader, + Typography, + Breadcrumb, + Icon, + Button, Select +} from "antd"; +import {Link} from "react-router-dom"; +import AddDevice from "../../../components/Devices/AddDevice"; + +const {Paragraph} = Typography; + +class DeviceEnroll extends React.Component { + routes; + + constructor(props) { + super(props); + this.routes = props.routes; + } + + render() { + return ( +
+ + + + Home + + Devices + Enroll Device + +
+

Devices

+ All enrolled devices +
+
+ +
+
+
+ +
+ +
+ ); + } +} + +export default DeviceEnroll; \ No newline at end of file