From 02a8fd35dcff0100cf5fba560141931abbbcf392 Mon Sep 17 00:00:00 2001 From: shamalka Date: Sat, 19 Oct 2019 23:59:11 +0530 Subject: [PATCH 1/9] Add main devicemgt features to dashboard --- .../react-app/public/conf/config.json | 2 +- .../react-app/public/images/logo.svg | 799 +++++++++++++++++- .../react-app/src/App.js | 45 +- .../DeviceTypes/DeviceTypesTable.js | 135 +++ .../src/components/Devices/DevicesTable.js | 6 +- .../components/Devices/ReportDevicesTable.js | 13 +- .../src/components/Groups/GroupsTable.js | 174 ++++ .../src/components/Roles/RolesTable.js | 147 ++++ .../src/components/Users/UsersTable.js | 134 +++ .../react-app/src/index.js | 30 + .../src/pages/Dashboard/Dashboard.css | 7 +- .../src/pages/Dashboard/Dashboard.js | 40 +- .../Dashboard/DeviceTypes/DeviceTypes.js | 66 ++ .../src/pages/Dashboard/Devices/Devices.js | 2 +- .../src/pages/Dashboard/Groups/Groups.js | 63 ++ .../src/pages/Dashboard/Policies/Policies.js | 62 ++ .../src/pages/Dashboard/Roles/Roles.js | 63 ++ .../src/pages/Dashboard/Users/Users.js | 63 ++ 18 files changed, 1821 insertions(+), 30 deletions(-) create mode 100644 components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/DeviceTypes/DeviceTypesTable.js create mode 100644 components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Groups/GroupsTable.js create mode 100644 components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Roles/RolesTable.js create mode 100644 components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersTable.js create mode 100644 components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/DeviceTypes/DeviceTypes.js create mode 100644 components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Groups/Groups.js create mode 100644 components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Policies/Policies.js create mode 100644 components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Roles/Roles.js create mode 100644 components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Users/Users.js diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/conf/config.json b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/conf/config.json index aa72ba06e44..916421e377a 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/conf/config.json +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/conf/config.json @@ -1,6 +1,6 @@ { "theme": { - "logo" : "https://localhost:9443/entgra/public/images/logo.svg", + "logo" : "https://entgra.io/assets/images/svg/logo.svg", "primaryColor": "rgb(24, 144, 255)" }, "serverConfig": { diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/logo.svg b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/logo.svg index 05eb79a8117..7986a8d1b47 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/logo.svg +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/public/images/logo.svg @@ -1 +1,798 @@ -logo \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 68f8823e1a1..5f8f429e8e4 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 @@ -67,11 +67,8 @@ class App extends React.Component { axios.get( window.location.origin + "/entgra/public/conf/config.json", ).then(res => { - console.log(res); - this.setState({ - loading: false, - config: res.data - }) + const config = res.data; + this.checkUserLoggedIn(config); }).catch((error) => { this.setState({ loading: false, @@ -80,6 +77,44 @@ class App extends React.Component { }); } + checkUserLoggedIn = (config) => { + axios.post( + window.location.origin + "/entgra-ui-request-handler/user", + "platform=entgra" + ).then(res => { + config.user = res.data.data; + const pageURL = window.location.pathname; + const lastURLSegment = pageURL.substr(pageURL.lastIndexOf('/') + 1); + if (lastURLSegment === "login") { + window.location.href = window.location.origin + `/entgra/`; + } else { + this.setState({ + loading: false, + config: config + }); + } + }).catch((error) => { + if (error.hasOwnProperty("response") && error.response.status === 401) { + const redirectUrl = encodeURI(window.location.href); + const pageURL = window.location.pathname; + const lastURLSegment = pageURL.substr(pageURL.lastIndexOf('/') + 1); + if (lastURLSegment !== "login") { + window.location.href = window.location.origin + `/entgra/login?redirect=${redirectUrl}`; + } else { + this.setState({ + loading: false, + config: config + }) + } + } else { + this.setState({ + loading: false, + error: true + }) + } + }); + }; + render() { const {loading, error} = this.state; diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/DeviceTypes/DeviceTypesTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/DeviceTypes/DeviceTypesTable.js new file mode 100644 index 00000000000..ee5bed41296 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/DeviceTypes/DeviceTypesTable.js @@ -0,0 +1,135 @@ +/* + * 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 {Tag, message, notification, Table, Typography, Tooltip, Icon, Divider, Card, Col, Row, Select} 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 DeviceTypesTable extends React.Component { + constructor(props) { + super(props); + config = this.props.context; + TimeAgo.addLocale(en); + this.state = { + data: [], + pagination: {}, + loading: false, + selectedRows: [] + }; + } + + componentDidMount() { + this.fetchUsers(); + } + + //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, + }); + } + console.log(JSON.parse(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 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 itemCard = data.map((data) => + + + {data.name} + + + ); + return ( +
+ + {itemCard} + +
+ ); + } +} + +export default withConfigContext(DeviceTypesTable); \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/DevicesTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/DevicesTable.js index 62cb0c9f148..21fe449b480 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/DevicesTable.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/DevicesTable.js @@ -176,7 +176,7 @@ class DeviceTable extends React.Component { this.setState({ loading: false, data: res.data.data.devices, - pagination, + pagination }); } @@ -253,7 +253,7 @@ class DeviceTable extends React.Component { message: "Done", duration: 4, description: - "Successfully disenrolled the device.", + "Successfully dis-enrolled the device.", }); } }).catch((error) => { @@ -266,7 +266,7 @@ class DeviceTable extends React.Component { message: "There was a problem", duration: 0, description: - "Error occurred while trying to disenroll devices.", + "Error occurred while trying to dis-enroll devices.", }); } diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/ReportDevicesTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/ReportDevicesTable.js index d71f141e96f..5d24e85986a 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/ReportDevicesTable.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/ReportDevicesTable.js @@ -112,18 +112,7 @@ const columns = [ return {timeAgoString}; } // todo add filtering options - }, - { - title: 'Action', - key: 'action', - render: () => ( - - - - - - ), - }, + } ]; const getTimeAgo = (time) => { diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Groups/GroupsTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Groups/GroupsTable.js new file mode 100644 index 00000000000..f411c0782ac --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Groups/GroupsTable.js @@ -0,0 +1,174 @@ +/* + * 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 {Tag, message, notification, Table, Typography, Tooltip, Icon, Divider} 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; + +const columns = [ + { + title: 'Group Name', + dataIndex: 'name', + width: 100, + }, + { + title: 'Owner', + dataIndex: 'owner', + key: 'owner', + // render: enrolmentInfo => enrolmentInfo.owner + // todo add filtering options + }, + { + title: 'Description', + dataIndex: 'description', + key: 'description', + // render: enrolmentInfo => enrolmentInfo.ownership + // todo add filtering options + } +]; + +const getTimeAgo = (time) => { + const timeAgo = new TimeAgo('en-US'); + return timeAgo.format(time); +}; + +class GroupsTable extends React.Component { + constructor(props) { + super(props); + config = this.props.context; + TimeAgo.addLocale(en); + this.state = { + data: [], + pagination: {}, + loading: false, + selectedRows: [] + }; + } + + rowSelection = { + onChange: (selectedRowKeys, selectedRows) => { + this.setState({ + selectedRows: selectedRows + }) + } + }; + + componentDidMount() { + this.fetchGroups(); + } + + //fetch data from api + fetchGroups = (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 + + "/admin/groups?" + encodedExtraParams; + + //send request to the invokerss + axios.get(apiUrl).then(res => { + if (res.status === 200) { + const pagination = {...this.state.pagination}; + this.setState({ + loading: false, + data: res.data.data.deviceGroups, + 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 groups.", + }); + } + + 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; + return ( +
+ (record.id)} + dataSource={data} + pagination={{ + ...pagination, + size: "small", + // position: "top", + showTotal: (total, range) => `showing ${range[0]}-${range[1]} of ${total} groups` + // showQuickJumper: true + }} + loading={loading} + onChange={this.handleTableChange} + rowSelection={this.rowSelection} + scroll={{x: 1000}} + /> + + ); + } +} + +export default withConfigContext(GroupsTable); \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Roles/RolesTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Roles/RolesTable.js new file mode 100644 index 00000000000..68083506463 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Roles/RolesTable.js @@ -0,0 +1,147 @@ +/* + * 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 {Tag, message, notification, Table, Typography, Tooltip, Icon, Divider, Card, Col, Row, Select} 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; + +const columns = [ + { + title: 'User Name', + dataIndex: 'username', + width: 100, + } +]; + +const getTimeAgo = (time) => { + const timeAgo = new TimeAgo('en-US'); + return timeAgo.format(time); +}; + +class RolesTable extends React.Component { + constructor(props) { + super(props); + config = this.props.context; + TimeAgo.addLocale(en); + this.state = { + data: [], + pagination: {}, + loading: false, + selectedRows: [] + }; + } + + componentDidMount() { + this.fetchUsers(); + } + + //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 + + "/roles"; + + //send request to the invokerss + axios.get(apiUrl).then(res => { + if (res.status === 200) { + const pagination = {...this.state.pagination}; + this.setState({ + loading: false, + data: res.data.data.roles, + 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 users.", + }); + } + + 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 itemCard = data.map((data) => + + + {data} + + + ); + return ( +
+ + {itemCard} + +
+ ); + } +} + +export default withConfigContext(RolesTable); \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersTable.js new file mode 100644 index 00000000000..beb34a94d6a --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersTable.js @@ -0,0 +1,134 @@ +/* + * 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 {Tag, message, notification, Table, Typography, Tooltip, Icon, Divider, Card, Col, Row, Select} 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 UsersTable extends React.Component { + constructor(props) { + super(props); + config = this.props.context; + TimeAgo.addLocale(en); + this.state = { + data: [], + pagination: {}, + loading: false, + selectedRows: [] + }; + } + + componentDidMount() { + this.fetchUsers(); + } + + //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 + + "/users"; + + //send request to the invokerss + axios.get(apiUrl).then(res => { + if (res.status === 200) { + const pagination = {...this.state.pagination}; + this.setState({ + loading: false, + data: res.data.data.users, + 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 users.", + }); + } + + 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 itemCard = data.map((data) => + + + {data.username} + + + ); + return ( +
+ + {itemCard} + +
+ ); + } +} + +export default withConfigContext(UsersTable); \ 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 b8206d16d77..8eeca9f07c2 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 @@ -26,6 +26,11 @@ import './index.css'; import Devices from "./pages/Dashboard/Devices/Devices"; import Reports from "./pages/Dashboard/Reports/Reports"; import Geo from "./pages/Dashboard/Geo/Geo"; +import Groups from "./pages/Dashboard/Groups/Groups"; +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"; const routes = [ { @@ -52,6 +57,31 @@ const routes = [ path: '/entgra/reports', component: Reports, exact: true + }, + { + path: '/entgra/groups', + component: Groups, + exact: true + }, + { + path: '/entgra/users', + component: Users, + exact: true + }, + { + path: '/entgra/policies', + component: Policies, + exact: true + }, + { + path: '/entgra/roles', + component: Roles, + exact: true + }, + { + path: '/entgra/devicetypes', + component: DeviceTypes, + exact: true } ] } 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 edb16b4c685..7923d0a9fc9 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 @@ -54,8 +54,11 @@ } .layout .logo-image img { - height: 32px; - margin: 16px; + height: 55px; + margin-top: 5px; + margin-left: 16px; + margin-right: 16px; + margin-bottom: 5px; } @media only screen and (min-width: 760px) { 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 9a20fb39a83..0ab9a856196 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 @@ -42,9 +42,11 @@ class Dashboard extends React.Component { mobileWidth }; this.logo = this.props.context.theme.logo; + this.config = this.props.context; } toggle = () => { + console.log(this.config) this.setState({ isNavBarCollapsed: !this.state.isNavBarCollapsed, }); @@ -63,8 +65,7 @@ class Dashboard extends React.Component { >
- logo - Entgra + logo
@@ -85,6 +86,36 @@ class Dashboard extends React.Component { Reports + + + + Groups + + + + + + Users + + + + + + Policies + + + + + + Roles + + + + + + Device Types + + @@ -109,9 +140,8 @@ class Dashboard extends React.Component { title={ - - } - > + {this.config.user} + }> diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/DeviceTypes/DeviceTypes.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/DeviceTypes/DeviceTypes.js new file mode 100644 index 00000000000..0f3b92aba3c --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/DeviceTypes/DeviceTypes.js @@ -0,0 +1,66 @@ +/* + * 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 { + PageHeader, + Typography, + Breadcrumb, + Icon +} from "antd"; +import {Link} from "react-router-dom"; +import DeviceTypesTable from "../../../components/DeviceTypes/DeviceTypesTable"; + +const {Paragraph} = Typography; + +class DeviceTypes extends React.Component { + routes; + + constructor(props) { + super(props); + this.routes = props.routes; + } + + render() { + return ( +
+ + + + Home + + Device Types + +
+

Device Types

+ Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an + illud incorrupte nam. +
+
+ +
+
+
+ +
+
+ ); + } +} + +export default DeviceTypes; diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/Devices.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/Devices.js index f78f1c89f97..7b0eadcc0ff 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/Devices.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/Devices.js @@ -48,7 +48,7 @@ class Devices extends React.Component { Devices
-

Devices

+

Devicessss

Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an illud incorrupte nam.
diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Groups/Groups.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Groups/Groups.js new file mode 100644 index 00000000000..8e3c6390a4c --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Groups/Groups.js @@ -0,0 +1,63 @@ +/* + * 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 { + PageHeader, + Typography, + Breadcrumb, + Icon +} from "antd"; +import {Link} from "react-router-dom"; +import GroupsTable from "../../../components/Groups/GroupsTable"; + +const {Paragraph} = Typography; + +class Groups extends React.Component { + routes; + + constructor(props) { + super(props); + this.routes = props.routes; + } + + render() { + return ( +
+ + + + Home + + Groups + +
+

Groups

+ Lorem ipsum dolordd sit amet, est similique constituto at, quot inermis id mel, an + illud incorrupte nam. +
+
+ +
+
+
+ ); + } +} + +export default Groups; diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Policies/Policies.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Policies/Policies.js new file mode 100644 index 00000000000..228468579a3 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Policies/Policies.js @@ -0,0 +1,62 @@ +/* + * 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 { + PageHeader, + Typography, + Breadcrumb, + Icon +} from "antd"; +import {Link} from "react-router-dom"; + +const {Paragraph} = Typography; + +class Policies extends React.Component { + routes; + + constructor(props) { + super(props); + this.routes = props.routes; + } + + render() { + return ( +
+ + + + Home + + Policies + +
+

Policies

+ Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an + illud incorrupte nam. +
+
+ +
+
+
+ ); + } +} + +export default Policies; diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Roles/Roles.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Roles/Roles.js new file mode 100644 index 00000000000..39119bbf569 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Roles/Roles.js @@ -0,0 +1,63 @@ +/* + * 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 { + PageHeader, + Typography, + Breadcrumb, + Icon +} from "antd"; +import {Link} from "react-router-dom"; +import RolesTable from "../../../components/Roles/RolesTable"; + +const {Paragraph} = Typography; + +class Roles extends React.Component { + routes; + + constructor(props) { + super(props); + this.routes = props.routes; + } + + render() { + return ( +
+ + + + Home + + Roles + +
+

Roles

+ Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an + illud incorrupte nam. +
+
+ +
+
+
+ ); + } +} + +export default Roles; diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Users/Users.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Users/Users.js new file mode 100644 index 00000000000..71ebc7112a6 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Users/Users.js @@ -0,0 +1,63 @@ +/* + * 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 { + PageHeader, + Typography, + Breadcrumb, + Icon +} from "antd"; +import {Link} from "react-router-dom"; +import UsersTable from "../../../components/Users/UsersTable"; + +const {Paragraph} = Typography; + +class Users extends React.Component { + routes; + + constructor(props) { + super(props); + this.routes = props.routes; + } + + render() { + return ( +
+ + + + Home + + Users + +
+

Users

+ Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an + illud incorrupte nam. +
+
+ +
+
+
+ ); + } +} + +export default Users; From 318736bcbf3233c7b83f6aa1df645e095e3662f6 Mon Sep 17 00:00:00 2001 From: shamalka Date: Sun, 20 Oct 2019 00:17:02 +0530 Subject: [PATCH 2/9] Add feature descriptions --- .../src/pages/Dashboard/DeviceTypes/DeviceTypes.js | 3 +-- .../react-app/src/pages/Dashboard/Devices/Devices.js | 5 ++--- .../react-app/src/pages/Dashboard/Groups/Groups.js | 3 +-- .../react-app/src/pages/Dashboard/Policies/Policies.js | 3 +-- .../react-app/src/pages/Dashboard/Roles/Roles.js | 6 ++++-- .../react-app/src/pages/Dashboard/Users/Users.js | 6 ++++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/DeviceTypes/DeviceTypes.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/DeviceTypes/DeviceTypes.js index 0f3b92aba3c..de9625bcc13 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/DeviceTypes/DeviceTypes.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/DeviceTypes/DeviceTypes.js @@ -48,8 +48,7 @@ class DeviceTypes extends React.Component {

Device Types

- Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an - illud incorrupte nam. + All device types for device management.
diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/Devices.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/Devices.js index 7b0eadcc0ff..3adf87207c7 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/Devices.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Devices/Devices.js @@ -48,9 +48,8 @@ class Devices extends React.Component { Devices
-

Devicessss

- Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an - illud incorrupte nam. +

Devices

+ All enrolled devices
diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Groups/Groups.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Groups/Groups.js index 8e3c6390a4c..e17cac86650 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Groups/Groups.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Groups/Groups.js @@ -48,8 +48,7 @@ class Groups extends React.Component {

Groups

- Lorem ipsum dolordd sit amet, est similique constituto at, quot inermis id mel, an - illud incorrupte nam. + All device groups.
diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Policies/Policies.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Policies/Policies.js index 228468579a3..bedaff0b571 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Policies/Policies.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Policies/Policies.js @@ -47,8 +47,7 @@ class Policies extends React.Component {

Policies

- Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an - illud incorrupte nam. + All policies for device management
diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Roles/Roles.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Roles/Roles.js index 39119bbf569..03a8f5e78f1 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Roles/Roles.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Roles/Roles.js @@ -48,13 +48,15 @@ class Roles extends React.Component {

Roles

- Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an - illud incorrupte nam. + All user roles
+
+ +
); } diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Users/Users.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Users/Users.js index 71ebc7112a6..dcd9a1d0f80 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Users/Users.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Users/Users.js @@ -48,13 +48,15 @@ class Users extends React.Component {

Users

- Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an - illud incorrupte nam. + All users for device management.
+
+ +
); } From 2103306fa1020a6368a7b445f7518e636eb749e8 Mon Sep 17 00:00:00 2001 From: lasanthaDLPDS Date: Tue, 22 Oct 2019 19:45:25 +0530 Subject: [PATCH 3/9] Improve APPM source Fix formatting issues, add java doc comments, improve transaction handling --- .../GenericApplicationReleaseDAOImpl.java | 12 +- .../mgt/core/impl/ApplicationManagerImpl.java | 233 ++++++++++++------ ...ApplicationManagementPublisherAPIImpl.java | 25 +- .../DeviceManagementProviderServiceImpl.java | 8 +- 4 files changed, 185 insertions(+), 93 deletions(-) diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java index 3eefed7caad..ffe45ba3d30 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java @@ -585,20 +585,20 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements + "AR.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + "AR.RATED_USERS AS RATED_USER_COUNT " + "FROM AP_APP_RELEASE AS AR " - + "WHERE AR.TENANT_ID = ? AND AR.PACKAGE_NAME IN ("; + + "WHERE AR.PACKAGE_NAME IN ("; - StringJoiner joiner = new StringJoiner(",", sql, ")"); + StringJoiner joiner = new StringJoiner(",", sql, ") AND AR.TENANT_ID = ? "); packages.stream().map(ignored -> "?").forEach(joiner::add); sql = joiner.toString(); try { Connection connection = this.getDBConnection(); try (PreparedStatement statement = connection.prepareStatement(sql)) { - statement.setInt(1, tenantId); - for (int y = 0; y < packages.size(); y++) { - // y +2 because tenantId parameter is 1 and the counter is starting at o for y - statement.setString(y+2, packages.get(y)); + int index = 1; + for (String packageName : packages) { + statement.setObject(index++, packageName); } + statement.setInt(index, tenantId); try (ResultSet resultSet = statement.executeQuery()) { List releaseDTOs = new ArrayList<>(); while (resultSet.next()) { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java index a4db52b032b..b7f63a1f791 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java @@ -195,16 +195,21 @@ public class ApplicationManagerImpl implements ApplicationManager { ApplicationDTO applicationDTO = APIUtil.convertToAppDTO(publicAppWrapper); ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); String appInstallerUrl = publicAppStorePath + applicationReleaseDTO.getPackageName(); - //todo check app package name exist or not, do it in validation method applicationReleaseDTO.setInstallerName(appInstallerUrl); applicationReleaseDTO.setUuid(UUID.randomUUID().toString()); applicationReleaseDTO.setAppHashValue(DigestUtils.md5Hex(appInstallerUrl)); - ConnectionManagerUtil.openDBConnection(); - List exitingRelease; try { - exitingRelease = applicationReleaseDAO.getReleaseByPackages(Arrays.asList(applicationReleaseDTO.getPackageName()) - , tenantId); + ConnectionManagerUtil.openDBConnection(); + List exitingPubAppReleases = applicationReleaseDAO + .getReleaseByPackages(Collections.singletonList(applicationReleaseDTO.getPackageName()), tenantId); + if (!exitingPubAppReleases.isEmpty()){ + String msg = "Public app release exists for package name " + applicationReleaseDTO.getPackageName() + + ". Hence you can't add new public app for package name " + + applicationReleaseDTO.getPackageName(); + log.error(msg); + throw new BadRequestException(msg); + } } catch (ApplicationManagementDAOException e) { String msg = "Error Occured when fetching release: " + publicAppWrapper.getName(); log.error(msg); @@ -213,45 +218,18 @@ public class ApplicationManagerImpl implements ApplicationManager { ConnectionManagerUtil.closeDBConnection(); } - if (exitingRelease != null && !exitingRelease.isEmpty()) { - applicationDTO.getApplicationReleaseDTOs().clear(); - applicationReleaseDTO.setUuid(exitingRelease.get(0).getUuid()); - applicationReleaseDTO.setCurrentState(exitingRelease.get(0).getCurrentState()); - - try { - applicationReleaseDTO = addImageArtifacts(applicationReleaseDTO, applicationArtifact, tenantId); - applicationDTO.getApplicationReleaseDTOs().add(applicationReleaseDTO); - ConnectionManagerUtil.beginDBTransaction(); - applicationReleaseDAO.updateRelease(applicationReleaseDTO, tenantId); - ConnectionManagerUtil.commitDBTransaction(); - return APIUtil.appDtoToAppResponse(applicationDTO); - } catch (ApplicationManagementDAOException e) { - ConnectionManagerUtil.rollbackDBTransaction(); - String msg = "Error occurred when updating public app: " + publicAppWrapper.getName(); - log.error(msg, e); - throw new ApplicationManagementException(msg, e); - } catch (ResourceManagementException e) { - String msg = "Error occurred when adding artifacts of release: " + publicAppWrapper.getName(); - log.error(msg, e); - throw new ApplicationManagementException(msg, e); - } finally { - ConnectionManagerUtil.closeDBConnection(); - } - } else { + try { //uploading application artifacts - try { - applicationReleaseDTO = addImageArtifacts(applicationReleaseDTO, applicationArtifact, tenantId); - applicationDTO.getApplicationReleaseDTOs().clear(); - applicationDTO.getApplicationReleaseDTOs().add(applicationReleaseDTO); - } catch (ResourceManagementException e) { - String msg = "Error Occured when uploading artifacts of the public app: " + publicAppWrapper.getName(); - log.error(msg, e); - throw new ApplicationManagementException(msg, e); - } - //insert application data into database - return addAppDataIntoDB(applicationDTO, tenantId); + applicationReleaseDTO = addImageArtifacts(applicationReleaseDTO, applicationArtifact, tenantId); + applicationDTO.getApplicationReleaseDTOs().clear(); + applicationDTO.getApplicationReleaseDTOs().add(applicationReleaseDTO); + } catch (ResourceManagementException e) { + String msg = "Error Occured when uploading artifacts of the public app: " + publicAppWrapper.getName(); + log.error(msg, e); + throw new ApplicationManagementException(msg, e); } - + //insert application data into database + return addAppDataIntoDB(applicationDTO, tenantId); } @Override @@ -316,6 +294,13 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + /** + * Delete Application release artifacts + * + * @param directoryPaths Directory paths + * @param tenantId Tenant Id + * @throws ApplicationManagementException if error occurred while deleting application release artifacts. + */ private void deleteApplicationArtifacts(List directoryPaths, int tenantId) throws ApplicationManagementException { ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); try { @@ -328,6 +313,17 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + /** + * To add Application release artifacts + * + * @param deviceType Device Type + * @param applicationReleaseDTO Application Release + * @param applicationArtifact Application release artifacts + * @param isNewRelease Is new release or Not + * @return {@link ApplicationReleaseDTO} + * @throws ResourceManagementException if error occurred while handling application release artifacts. + * @throws ApplicationManagementException if error occurred while handling application release data. + */ private ApplicationReleaseDTO addApplicationReleaseArtifacts(String deviceType, ApplicationReleaseDTO applicationReleaseDTO, ApplicationArtifact applicationArtifact, boolean isNewRelease) throws ResourceManagementException, ApplicationManagementException { @@ -402,6 +398,16 @@ public class ApplicationManagerImpl implements ApplicationManager { return applicationReleaseDTO; } + /** + * This method could be used to update enterprise application release artifacts. + * + * @param deviceType Device Type + * @param applicationReleaseDTO Application Release + * @param applicationArtifact Application release artifacts + * @return {@link ApplicationReleaseDTO} + * @throws ResourceManagementException if error occurred while handling application release artifacts. + * @throws ApplicationManagementException if error occurred while handling application release data. + */ private ApplicationReleaseDTO updateEntAppReleaseArtifact(String deviceType, ApplicationReleaseDTO applicationReleaseDTO, ApplicationArtifact applicationArtifact) throws ResourceManagementException, ApplicationManagementException { @@ -489,6 +495,15 @@ public class ApplicationManagerImpl implements ApplicationManager { return applicationReleaseDTO; } + /** + * Add image artifacts into file system + * + * @param applicationReleaseDTO Application Release + * @param applicationArtifact Image artifacts + * @param tenantId Tenant Id + * @return {@link ApplicationReleaseDTO} + * @throws ResourceManagementException if error occurred while uploading image artifacts into file system. + */ private ApplicationReleaseDTO addImageArtifacts(ApplicationReleaseDTO applicationReleaseDTO, ApplicationArtifact applicationArtifact, int tenantId) throws ResourceManagementException { ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); @@ -518,6 +533,14 @@ public class ApplicationManagerImpl implements ApplicationManager { return applicationReleaseDTO; } + /** + * Update Image artifacts of Application RApplication Release + * + * @param applicationArtifact Application release Artifacts + * @param tenantId Tenant Id + * @return {@link ApplicationReleaseDTO} + * @throws ResourceManagementException if error occurred while uploading application release artifacts into the file system. + */ private ApplicationReleaseDTO updateImageArtifacts(ApplicationReleaseDTO applicationReleaseDTO, ApplicationArtifact applicationArtifact, int tenantId) throws ResourceManagementException{ ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); @@ -674,9 +697,19 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + /** + * Check whether at least one filtering role is in app unrestricted roles. + * + * @param appUnrestrictedRoles Application unrestricted roles + * @param filteringUnrestrictedRoles Filtering roles + * @param userName Username + * @return True if one filtering unrestricted role is associated with application unrestricted roles. + * @throws BadRequestException if user doesn't have assigned at least one filtering role + * @throws UserStoreException if error occurred when checking whether user has assigned at least one filtering role. + */ private boolean hasAppUnrestrictedRole(List appUnrestrictedRoles, List filteringUnrestrictedRoles, String userName) throws BadRequestException, UserStoreException { - if (!haveAllUserRoles(filteringUnrestrictedRoles, userName)) { + if (!hasUserRole(filteringUnrestrictedRoles, userName)) { String msg = "At least one filtering role is not assigned for the user: " + userName + ". Hence user " + userName + " Can't filter applications by giving these unrestricted role list"; @@ -850,7 +883,7 @@ public class ApplicationManagerImpl implements ApplicationManager { throw new BadRequestException(msg); } DeviceType deviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); - if (!isValidOsVersions(entAppReleaseWrapper.getSupportedOsVersions(), deviceType.getName())) { + if (isInvalidOsVersionRange(entAppReleaseWrapper.getSupportedOsVersions(), deviceType.getName())) { String msg = "You are trying to add application release which has invalid or unsupported OS versions in " + "the supportedOsVersions section. Hence, please re-evaluate the request payload."; log.error(msg); @@ -897,6 +930,13 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + /** + * Get Application and all application releases associated to the application that has given application Id + * + * @param applicationId Application Id + * @return {@link ApplicationDTO} + * @throws ApplicationManagementException if error occurred application data from the databse. + */ private ApplicationDTO getApplication(int applicationId) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); try { @@ -909,8 +949,8 @@ public class ApplicationManagerImpl implements ApplicationManager { } return applicationDTO; } catch (DBConnectionException e) { - String msg = "Error occurred while obtaining the database connection for getting application for the " - + "application ID: " + applicationId; + String msg = "Error occurred while obtaining the database connection for getting application for the app ID" + + " " + applicationId; log.error(msg, e); throw new ApplicationManagementException(msg, e); } catch (ApplicationManagementDAOException e) { @@ -922,6 +962,17 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + /** + * Upload enterprise application release artifact into file system. + * + * @param releaseDTO Apllication Release + * @param applicationArtifact Application Release artifacts + * @param deviceTypeName Device Type name + * @param tenantId Tenant Id + * @param isNewRelease New Release or Not + * @return {@link ApplicationReleaseDTO} + * @throws ApplicationManagementException if error occurred while uploading artifacts into file system. + */ private ApplicationReleaseDTO uploadEntAppReleaseArtifacts(ApplicationReleaseDTO releaseDTO, ApplicationArtifact applicationArtifact, String deviceTypeName, int tenantId, boolean isNewRelease) throws ApplicationManagementException { @@ -936,7 +987,16 @@ public class ApplicationManagerImpl implements ApplicationManager { } } - private boolean isValidOsVersions(String osRange, String deviceTypeName) + /** + * Check whether given OS range is valid or invalid + * + * @param osRange OS range + * @param deviceTypeName Device Type + * @return true if invalid OS range, Otherwise returns false + * @throws ApplicationManagementException if error occurred while getting device type version for lower OS version + * and higher OS version + */ + private boolean isInvalidOsVersionRange(String osRange, String deviceTypeName) throws ApplicationManagementException { String lowestSupportingOsVersion; String highestSupportingOsVersion = null; @@ -949,9 +1009,9 @@ public class ApplicationManagerImpl implements ApplicationManager { try { DeviceManagementProviderService deviceManagementProviderService = DAOUtil.getDeviceManagementService(); return deviceManagementProviderService.getDeviceTypeVersion(deviceTypeName, lowestSupportingOsVersion) - != null && (highestSupportingOsVersion == null - || deviceManagementProviderService.getDeviceTypeVersion(deviceTypeName, highestSupportingOsVersion) - != null); + == null || (highestSupportingOsVersion != null + && deviceManagementProviderService.getDeviceTypeVersion(deviceTypeName, highestSupportingOsVersion) + == null); } catch (DeviceManagementException e) { String msg = "Error occurred while getting supported device type versions for device type : " + deviceTypeName; @@ -1152,9 +1212,16 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + /** + * Check whether at least one role is assigned to the given user. + * + * @param unrestrictedRoleList unrestricted role list + * @param userName Username + * @return true at least one unrestricted role has assigned to given user, otherwise returns false. + * @throws UserStoreException If it is unable to load {@link UserRealm} from {@link CarbonContext} + */ private boolean hasUserRole(Collection unrestrictedRoleList, String userName) throws UserStoreException { - String[] roleList; - roleList = getRolesOfUser(userName); + String[] roleList = getRolesOfUser(userName); for (String unrestrictedRole : unrestrictedRoleList) { for (String role : roleList) { if (unrestrictedRole.equals(role)) { @@ -1165,30 +1232,18 @@ public class ApplicationManagerImpl implements ApplicationManager { return false; } - private boolean haveAllUserRoles(Collection unrestrictedRoleList, String userName) - throws UserStoreException { - String[] roleList; - roleList = getRolesOfUser(userName); - for (String unrestrictedRole : unrestrictedRoleList) { - for (String role : roleList) { - if (!unrestrictedRole.equals(role)) { - return false; - } - } - } - return true; - } - + /** + * Check whether valid unrestricted role list or not + * + * @return true or false + * @throws UserStoreException If it is unable to load {@link UserRealm} from {@link CarbonContext} + */ private boolean isValidRestrictedRole(Collection unrestrictedRoleList) throws UserStoreException { - List roleList = new ArrayList<>(Arrays.asList(getRoleNames())); - return roleList.containsAll(unrestrictedRoleList); - } - - private String[] getRoleNames() throws UserStoreException { //todo check role by role UserRealm userRealm = CarbonContext.getThreadLocalCarbonContext().getUserRealm(); if (userRealm != null) { - return userRealm.getUserStoreManager().getRoleNames(); + List roleList = new ArrayList<>(Arrays.asList(userRealm.getUserStoreManager().getRoleNames())); + return roleList.containsAll(unrestrictedRoleList); } else { String msg = "User realm is not initiated."; log.error(msg); @@ -1196,6 +1251,13 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + /** + * Get assigned role list of the given user. + * + * @param userName Username + * @return List of roles + * @throws UserStoreException If it is unable to load {@link UserRealm} from {@link CarbonContext} + */ private String[] getRolesOfUser(String userName) throws UserStoreException { UserRealm userRealm = CarbonContext.getThreadLocalCarbonContext().getUserRealm(); String[] roleList; @@ -2119,6 +2181,7 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + @Override public List addApplicationTags(int appId, List tags) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); try { @@ -2171,6 +2234,7 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + @Override public List addCategories(List categories) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); try { @@ -2291,7 +2355,12 @@ public class ApplicationManagerImpl implements ApplicationManager { return lifecycleStateManager.getInstallableState(); } - + /** + * This method can be used to validate {@link Filter} object. + * + * @param filter {@link Filter} + * @throws BadRequestException if filter object contains incompatible data. + */ private void validateFilter(Filter filter) throws BadRequestException { if (filter == null) { String msg = "Filter validation is failed, Filter shouldn't be null, hence please verify the request payload"; @@ -2340,9 +2409,16 @@ public class ApplicationManagerImpl implements ApplicationManager { log.error(msg); throw new BadRequestException(msg); } - } + /** + * This method can be used to get difference of two lists. + * + * @param list1 List of objects + * @param list2 List of object + * @param Object type + * @return return list of values which are not in the list2 but in the list1 + */ private List getDifference(List list1, Collection list2) { List list = new ArrayList<>(); for (T t : list1) { @@ -2353,7 +2429,7 @@ public class ApplicationManagerImpl implements ApplicationManager { return list; } - /*** + /** * By invoking the method, it returns Lifecycle State Instance. * @param currentState Current state of the lifecycle * @param previousState Previouse state of the Lifecycle @@ -2726,7 +2802,7 @@ public class ApplicationManagerImpl implements ApplicationManager { .equals(appType)) { DeviceType deviceTypeObj = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); String supportedOSVersions = applicationReleaseDTO.getSupportedOsVersions(); - if (!StringUtils.isEmpty(supportedOSVersions) && !isValidOsVersions(supportedOSVersions, + if (!StringUtils.isEmpty(supportedOSVersions) && isInvalidOsVersionRange(supportedOSVersions, deviceTypeObj.getName())) { String msg = "You are trying to update application release which has invalid or unsupported OS " + "versions in the supportedOsVersions section. Hence, please re-evaluate the request payload."; @@ -2736,7 +2812,6 @@ public class ApplicationManagerImpl implements ApplicationManager { } } - @Override public void validateAppCreatingRequest(T param) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); @@ -2988,7 +3063,7 @@ public class ApplicationManagerImpl implements ApplicationManager { log.error(msg); throw new BadRequestException(msg); } - if (!isValidOsVersions(entAppReleaseWrapper.get().getSupportedOsVersions(), deviceType)) { + if (isInvalidOsVersionRange(entAppReleaseWrapper.get().getSupportedOsVersions(), deviceType)) { String msg = "You are trying to create application which has an application release contains invalid or " + "unsupported OS versions in the supportedOsVersions section. Hence, please re-evaluate the " + "request payload."; @@ -3031,7 +3106,7 @@ public class ApplicationManagerImpl implements ApplicationManager { log.error(msg); throw new BadRequestException(msg); } - if (!isValidOsVersions(publicAppReleaseWrapper.getSupportedOsVersions(), deviceType)) { + if (isInvalidOsVersionRange(publicAppReleaseWrapper.getSupportedOsVersions(), deviceType)) { String msg = "You are trying to create application which has an application release contains invalid or " + "unsupported OS versions in the supportedOsVersions section. Hence, please re-evaluate the " + "request payload."; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementPublisherAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementPublisherAPIImpl.java index 499b59815b9..5e0e7652391 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementPublisherAPIImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementPublisherAPIImpl.java @@ -198,12 +198,16 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem log.error(msg); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } + } catch (BadRequestException e) { + String msg = "Found incompatible payload with ent. app creating request."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } catch (ApplicationManagementException e) { String msg = "Error occurred while creating the ent. application"; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } catch (RequestValidatingException e) { - String msg = "Error occurred while handling the ent. application creating request"; + String msg = "Couldn't find the required artifacts to create new ent. application with the request"; log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } @@ -237,12 +241,16 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem log.error(msg); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } + } catch (BadRequestException e) { + String msg = "Found incompatible payload with web app creating request."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } catch (ApplicationManagementException e) { String msg = "Error occurred while creating the web application"; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } catch (RequestValidatingException e) { - String msg = "Error occurred while handling the web app creating request"; + String msg = "Couldn't find the required artifacts to create new web application with the request"; log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } @@ -276,12 +284,16 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem log.error(msg); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } + } catch (BadRequestException e) { + String msg = "Found incompatible payload with pub app creating request."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } catch (ApplicationManagementException e) { String msg = "Error occurred while creating the public app."; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } catch (RequestValidatingException e) { - String msg = "Error occurred while handling the public app creating request"; + String msg = "Couldn't find the required artifacts to create new public application with the request"; log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } @@ -317,12 +329,16 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem log.error(msg); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } + } catch (BadRequestException e) { + String msg = "Found incompatible payload with pub custom creating request."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } catch (ApplicationManagementException e) { String msg = "Error occurred while creating the application"; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } catch (RequestValidatingException e) { - String msg = "Error occurred while handling the application creating request"; + String msg = "Couldn't find the required artifacts to create new custom application with the request"; log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } @@ -908,6 +924,7 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem } /*** + * This method can be used to construct {@link ApplicationArtifact} * * @param binaryFile binary file of the application release * @param iconFile icon file of the application release diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index 794d679652f..613bb801673 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -3711,7 +3711,6 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv log.debug("Getting all devices details for device ids: " + devicesIds); } PaginationResult paginationResult = new PaginationResult(); - int count; List subscribedDeviceDetails; try { DeviceManagementDAOFactory.openConnection(); @@ -3721,12 +3720,11 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv paginationResult.setData(new ArrayList<>()); paginationResult.setRecordsFiltered(0); paginationResult.setRecordsTotal(0); + return paginationResult; } - count = deviceDAO.getSubscribedDeviceCount(devicesIds, tenantId, status); - paginationResult.setData(getAllDeviceInfo(subscribedDeviceDetails)); + int count = deviceDAO.getSubscribedDeviceCount(devicesIds, tenantId, status); paginationResult.setRecordsFiltered(count); paginationResult.setRecordsTotal(count); - return paginationResult; } catch (DeviceManagementDAOException e) { String msg = "Error occurred while retrieving device list for device ids " + devicesIds; log.error(msg, e); @@ -3738,6 +3736,8 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } finally { DeviceManagementDAOFactory.closeConnection(); } + paginationResult.setData(getAllDeviceInfo(subscribedDeviceDetails)); + return paginationResult; } /** From 5436d9dd37397d4099cec58a8f51071fe3a60c5a Mon Sep 17 00:00:00 2001 From: shamalka Date: Tue, 22 Oct 2019 22:56:08 +0530 Subject: [PATCH 4/9] Add roles and enrolled devices of users --- .../DeviceTypes/DeviceTypesTable.js | 1 - .../components/Devices/ReportDevicesTable.js | 2 +- .../src/components/Policies/PoliciesTable.js | 181 +++++++++++++ .../src/components/Users/UsersDevices.js | 250 ++++++++++++++++++ .../src/components/Users/UsersTable.js | 161 +++++++++-- .../src/pages/Dashboard/Groups/Groups.js | 3 + .../src/pages/Dashboard/Policies/Policies.js | 6 +- 7 files changed, 586 insertions(+), 18 deletions(-) create mode 100644 components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Policies/PoliciesTable.js create mode 100644 components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersDevices.js diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/DeviceTypes/DeviceTypesTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/DeviceTypes/DeviceTypesTable.js index ee5bed41296..5e1a5494cad 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/DeviceTypes/DeviceTypesTable.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/DeviceTypes/DeviceTypesTable.js @@ -77,7 +77,6 @@ class DeviceTypesTable extends React.Component { pagination, }); } - console.log(JSON.parse(res.data.data)) }).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/ReportDevicesTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/ReportDevicesTable.js index 5d24e85986a..80f577bcb89 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/ReportDevicesTable.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Devices/ReportDevicesTable.js @@ -151,7 +151,7 @@ class ReportDeviceTable extends React.Component { if(prevProps.paramsObject !== this.props.paramsObject){ this.fetch(); } - } + } //fetch data from api fetch = (params = {}) => { diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Policies/PoliciesTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Policies/PoliciesTable.js new file mode 100644 index 00000000000..29394b9cde5 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Policies/PoliciesTable.js @@ -0,0 +1,181 @@ +/* + * 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 {Tag, message, notification, Table, Typography, Tooltip, Icon, Divider} 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; + +const columns = [ + { + title: 'Policy Name', + dataIndex: 'policyName', + width: 100, + }, + { + title: 'Description', + dataIndex: 'description', + key: 'description', + // render: enrolmentInfo => enrolmentInfo.owner + // todo add filtering options + }, + { + title: 'Compilance', + dataIndex: 'compliance', + key: 'compliance', + // render: enrolmentInfo => enrolmentInfo.ownership + // todo add filtering options + }, + { + title: 'Policy Type', + dataIndex: 'policyType', + key: 'policyType', + // render: enrolmentInfo => enrolmentInfo.ownership + // todo add filtering options + } +]; + +const getTimeAgo = (time) => { + const timeAgo = new TimeAgo('en-US'); + return timeAgo.format(time); +}; + +class PoliciesTable extends React.Component { + constructor(props) { + super(props); + config = this.props.context; + TimeAgo.addLocale(en); + this.state = { + data: [], + pagination: {}, + loading: false, + selectedRows: [] + }; + } + + rowSelection = { + onChange: (selectedRowKeys, selectedRows) => { + this.setState({ + selectedRows: selectedRows + }) + } + }; + + componentDidMount() { + this.fetchGroups(); + } + + //fetch data from api + fetchGroups = (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 + + "/policies?" + encodedExtraParams; + + //send request to the invokerss + axios.get(apiUrl).then(res => { + if (res.status === 200) { + const pagination = {...this.state.pagination}; + this.setState({ + loading: false, + data: res.data.data.policies, + 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 policies.", + }); + } + + 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; + return ( +
+
(record.id)} + dataSource={data} + pagination={{ + ...pagination, + size: "small", + // position: "top", + showTotal: (total, range) => `showing ${range[0]}-${range[1]} of ${total} groups` + // showQuickJumper: true + }} + loading={loading} + onChange={this.handleTableChange} + rowSelection={this.rowSelection} + scroll={{x: 1000}} + /> + + ); + } +} + +export default withConfigContext(PoliciesTable); \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersDevices.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersDevices.js new file mode 100644 index 00000000000..13ce62e98e9 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersDevices.js @@ -0,0 +1,250 @@ +/* + * 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 {Tag, message, notification, Table, Typography, Tooltip, Icon, Divider} 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; + +const columns = [ + { + title: 'Device', + dataIndex: 'name', + width: 100, + }, + { + title: 'Type', + dataIndex: 'type', + key: 'type', + render: type => { + const defaultPlatformIcons = config.defaultPlatformIcons; + let icon = defaultPlatformIcons.default.icon; + let color = defaultPlatformIcons.default.color; + let theme = defaultPlatformIcons.default.theme; + + if (defaultPlatformIcons.hasOwnProperty(type)) { + icon = defaultPlatformIcons[type].icon; + color = defaultPlatformIcons[type].color; + theme = defaultPlatformIcons[type].theme; + } + + return ( + + + + ); + } + // todo add filtering options + }, + { + title: 'Owner', + dataIndex: 'enrolmentInfo', + key: 'owner', + render: enrolmentInfo => enrolmentInfo.owner + // todo add filtering options + }, + { + title: 'Ownership', + dataIndex: 'enrolmentInfo', + key: 'ownership', + width: 100, + render: enrolmentInfo => enrolmentInfo.ownership + // todo add filtering options + }, + { + title: 'Status', + dataIndex: 'enrolmentInfo', + width: 100, + key: 'status', + render: (enrolmentInfo) => { + const status = enrolmentInfo.status.toLowerCase(); + let color = "#f9ca24"; + switch (status) { + case "active": + color = "#badc58"; + break; + case "created": + color = "#6ab04c"; + break; + case "removed": + color = "#ff7979"; + break; + case "inactive": + color = "#f9ca24"; + break; + case "blocked": + color = "#636e72"; + break; + } + return {status}; + } + // todo add filtering options + }, + { + title: 'Last Updated', + dataIndex: 'enrolmentInfo', + key: 'dateOfLastUpdate', + render: (data) => { + const {dateOfLastUpdate} = data; + const timeAgoString = getTimeAgo(dateOfLastUpdate); + return {timeAgoString}; + } + // todo add filtering options + } +]; + +const getTimeAgo = (time) => { + const timeAgo = new TimeAgo('en-US'); + return timeAgo.format(time); +}; + +class UsersDevices extends React.Component { + constructor(props) { + super(props); + config = this.props.context; + TimeAgo.addLocale(en); + this.state = { + data: [], + pagination: {}, + loading: false, + selectedRows: [] + }; + } + + rowSelection = { + onChange: (selectedRowKeys, selectedRows) => { + this.setState({ + selectedRows: selectedRows + }) + } + }; + + componentDidMount() { + this.fetch(); + } + + //Rerender component when parameters change + componentDidUpdate(prevProps, prevState, snapshot) { + if(prevProps.user !== this.props.user){ + this.fetch(); + } + } + + //fetch data from api + fetch = (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, + user: this.props.user, + requireDeviceInfo: true, + }; + + const encodedExtraParams = Object.keys(extraParams) + .map(key => key + '=' + extraParams[key]).join('&'); + + //send request to the invoker + axios.get( + window.location.origin + config.serverConfig.invoker.uri + + config.serverConfig.invoker.deviceMgt + + "/devices?" + encodedExtraParams, + ).then(res => { + if (res.status === 200) { + const pagination = {...this.state.pagination}; + this.setState({ + loading: false, + data: res.data.data.devices, + 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 devices.", + }); + } + + 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; + return ( +
+
(record.deviceIdentifier + record.enrolmentInfo.owner + record.enrolmentInfo.ownership)} + dataSource={data} + showHeader={false} + size="small" + pagination={{ + ...pagination, + size: "small", + // position: "top", + showTotal: (total, range) => `showing ${range[0]}-${range[1]} of ${total} devices` + // showQuickJumper: true + }} + loading={loading} + onChange={this.handleTableChange} + rowSelection={this.rowSelection} + scroll={{x: 1000}} + /> + + ); + } +} + +export default withConfigContext(UsersDevices); \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersTable.js index beb34a94d6a..ac7fc9c66a1 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersTable.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersTable.js @@ -18,12 +18,14 @@ import React from "react"; import axios from "axios"; -import {Tag, message, notification, Table, Typography, Tooltip, Icon, Divider, Card, Col, Row, Select} from "antd"; +import {message, notification, Table, Typography, Panel, Collapse, Button, List, Modal, Icon} 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"; +import DeviceTable from "../Devices/DevicesTable"; +import UsersDevices from "./UsersDevices"; const {Text} = Typography; @@ -39,10 +41,21 @@ class UsersTable extends React.Component { data: [], pagination: {}, loading: false, - selectedRows: [] + selectedRows: [], + rolesModalVisible: false, + rolesData: [], + user:'' }; } + rowSelection = { + onChange: (selectedRowKeys, selectedRows) => { + this.setState({ + selectedRows: selectedRows + }) + } + }; + componentDidMount() { this.fetchUsers(); } @@ -65,7 +78,7 @@ class UsersTable extends React.Component { apiUrl = window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.deviceMgt + - "/users"; + "/users?" + encodedExtraParams; //send request to the invokerss axios.get(apiUrl).then(res => { @@ -95,6 +108,44 @@ class UsersTable extends React.Component { }); }; + //fetch data from api + fetchRoles = (username) => { + const config = this.props.context; + + this.setState({ + rolesModalVisible: true, + user: username + }); + + apiUrl = window.location.origin + config.serverConfig.invoker.uri + + config.serverConfig.invoker.deviceMgt + + "/users/" + username + "/roles"; + + //send request to the invokerss + axios.get(apiUrl).then(res => { + if (res.status === 200) { + this.setState({ + rolesData: res.data.data.roles, + }); + } + + }).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 roles.", + }); + } + + this.setState({loading: false}); + }); + }; + handleTableChange = (pagination, filters, sorter) => { const pager = {...this.state.pagination}; pager.current = pagination.current; @@ -110,22 +161,102 @@ class UsersTable extends React.Component { }); }; + handleOk = e => { + this.setState({ + rolesModalVisible: false, + }); + }; + + handleCancel = e => { + this.setState({ + rolesModalVisible: false, + }); + }; + render() { const {data, pagination, loading, selectedRows} = this.state; - - const itemCard = data.map((data) => - - - {data.username} - - - ); + const { Panel } = Collapse; + const columns = [ + { + title: 'User Name', + dataIndex: 'username', + width: 150, + key: "username", + }, + { + title: 'First Name', + width: 150, + dataIndex: 'firstname', + key: 'firstname', + }, + { + title: 'Last Name', + width: 150, + dataIndex: 'lastname', + key: 'lastname', + }, + { + title: 'Email', + width: 100, + dataIndex: 'emailAddress', + key: 'emailAddress', + }, + { + title: '', + dataIndex: 'username', + key: 'roles', + render: (username) => + + } + ]; return ( -
- - {itemCard} - +
+
+
(record.username)} + dataSource={data} + pagination={{ + ...pagination, + size: "small", + // position: "top", + showTotal: (total, range) => `showing ${range[0]}-${range[1]} of ${total} groups` + // showQuickJumper: true + }} + loading={loading} + onChange={this.handleTableChange} + rowSelection={this.rowSelection} + scroll={{x: 1000}} + /> + +
+ + + + {item}} + /> + + + + + + +
); } diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Groups/Groups.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Groups/Groups.js index e17cac86650..b96f869872b 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Groups/Groups.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Groups/Groups.js @@ -54,6 +54,9 @@ class Groups extends React.Component { +
+ +
); } diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Policies/Policies.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Policies/Policies.js index bedaff0b571..7c32b7a0a23 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Policies/Policies.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Policies/Policies.js @@ -24,6 +24,7 @@ import { Icon } from "antd"; import {Link} from "react-router-dom"; +import PoliciesTable from "../../../components/Policies/PoliciesTable"; const {Paragraph} = Typography; @@ -50,9 +51,12 @@ class Policies extends React.Component { All policies for device management
- +
+
+ +
); } From 08860acfbad50b5920a5b465fe137e6bd9597d47 Mon Sep 17 00:00:00 2001 From: Jayasanka Weerasinghe Date: Tue, 22 Oct 2019 17:32:56 +0000 Subject: [PATCH 5/9] Add ui improvements to APPM Publisher UI The following changes are with this commit - View subscription status of devices in release view - Display server error response in add new app form --- .../src/components/apps/list-apps/Filters.js | 14 -- .../apps/list-apps/appsTable/AppsTable.js | 8 +- .../apps/release/lifeCycle/LifeCycle.js | 12 +- .../src/components/new-app/AddNewAppForm.js | 12 +- .../apps/release/InstalledDevicesTable.js | 231 ++++++++++++++++++ .../components/apps/release/ReleaseView.js | 67 +++-- 6 files changed, 288 insertions(+), 56 deletions(-) create mode 100644 components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/InstalledDevicesTable.js diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/Filters.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/Filters.js index de8bbf83578..e042def20da 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/Filters.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/Filters.js @@ -63,9 +63,6 @@ class FiltersForm extends React.Component { delete values["deviceType"]; } - if(values.hasOwnProperty("subscriptionType") && values.subscriptionType==="ALL"){ - delete values["subscriptionType"]; - } if(values.hasOwnProperty("appType") && values.appType==="ALL"){ delete values["appType"]; } @@ -271,17 +268,6 @@ class FiltersForm extends React.Component { )} - - - {getFieldDecorator('subscriptionType', {})( - - Free - Paid - All - , - )} - - ); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/appsTable/AppsTable.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/appsTable/AppsTable.js index aae593fb2af..24e43a89c61 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/appsTable/AppsTable.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/list-apps/appsTable/AppsTable.js @@ -123,7 +123,8 @@ class AppsTable extends React.Component { filters: {}, isDrawerVisible: false, selectedApp: null, - selectedAppIndex: -1 + selectedAppIndex: -1, + loading: false }; config = this.props.context; } @@ -222,14 +223,14 @@ class AppsTable extends React.Component { onUpdateApp = (key, value) => { const apps = [...this.state.apps]; - apps[this.state.selectedAppIndex][key]= value; + apps[this.state.selectedAppIndex][key] = value; this.setState({ apps }); }; render() { - const {isDrawerVisible} = this.state; + const {isDrawerVisible, loading} = this.state; return (
{ return { onClick: event => { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/lifeCycle/LifeCycle.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/lifeCycle/LifeCycle.js index 3230939c727..34384f7f24c 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/lifeCycle/LifeCycle.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/lifeCycle/LifeCycle.js @@ -132,7 +132,7 @@ class LifeCycle extends React.Component { render() { - const {currentStatus, selectedStatus} = this.state; + const {currentStatus, selectedStatus, isConfirmButtonLoading} = this.state; const {lifecycle} = this.props; const selectedValue = selectedStatus == null ? [] : selectedStatus; let proceedingStates = []; @@ -180,21 +180,17 @@ class LifeCycle extends React.Component { type="primary" htmlType="button" onClick={this.showReasonModal} - disabled={selectedStatus == null} - > + loading={isConfirmButtonLoading} + disabled={selectedStatus == null}> Change - - - + okText="Confirm"> You are going to change the lifecycle state from,
{currentStatus}to { - handleApiError(error, "Sorry, we were unable to complete your request.") + handleApiError(error, error.response.data.data); this.setState({ loading: false, isError: true, - current: 2 + current: 2, + errorText: error.response.data.data }); }); @@ -149,7 +151,7 @@ class AddNewAppFormComponent extends React.Component { }; render() { - const {loading, current, isError, supportedOsVersions} = this.state; + const {loading, current, isError, supportedOsVersions, errorText} = this.state; const {formConfig} = this.props; return (
@@ -190,7 +192,7 @@ class AddNewAppFormComponent extends React.Component { {isError && (Back} />)} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/InstalledDevicesTable.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/InstalledDevicesTable.js new file mode 100644 index 00000000000..1b6642f3d41 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/InstalledDevicesTable.js @@ -0,0 +1,231 @@ +/* + * 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 {Tag, message, notification, Table, Typography, Tooltip, Icon, Divider, Button, Modal, Select} 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; + +const columns = [ + { + title: 'Device', + dataIndex: 'device', + width: 100, + render: device => device.name + }, + { + title: 'Owner', + dataIndex: 'device', + key: 'owner', + render: device => device.enrolmentInfo.owner + }, + { + title: 'Action Type', + dataIndex: 'actionType', + key: 'actionType', + render: actionType => actionType.toLowerCase() + }, + { + title: 'Action', + dataIndex: 'action', + key: 'action', + render: action => action.toLowerCase() + }, + { + title: 'Triggered By', + dataIndex: 'actionTriggeredBy', + key: 'actionTriggeredBy' + }, + { + title: 'Action Triggered At', + dataIndex: 'actionTriggeredTimestamp', + key: 'actionTriggeredTimestamp' + }, + { + title: 'Action Status', + dataIndex: 'status', + key: 'actionStatus', + render: (status) => { + let color = "#f9ca24"; + switch (status) { + case "COMPLETED": + color = "#badc58"; + break; + case "REPEATED": + color = "#6ab04c"; + break; + case "ERROR": + case "INVALID": + case "UNAUTHORIZED": + color = "#ff7979"; + break; + case "IN_PROGRESS": + color = "#f9ca24"; + break; + case "PENDING": + color = "#636e72"; + break; + } + return {status.toLowerCase()}; + } + }, + { + title: 'Device Status', + dataIndex: 'device', + key: 'deviceStatus', + render: (device) => { + const status = device.enrolmentInfo.status.toLowerCase(); + let color = "#f9ca24"; + switch (status) { + case "active": + color = "#badc58"; + break; + case "created": + color = "#6ab04c"; + break; + case "removed": + color = "#ff7979"; + break; + case "inactive": + color = "#f9ca24"; + break; + case "blocked": + color = "#636e72"; + break; + } + return {status}; + } + } +]; + +const getTimeAgo = (time) => { + const timeAgo = new TimeAgo('en-US'); + return timeAgo.format(time); +}; + + +class InstalledDevicesTable extends React.Component { + constructor(props) { + super(props); + config = this.props.context; + TimeAgo.addLocale(en); + this.state = { + data: [], + pagination: {}, + loading: false, + selectedRows: [], + deviceGroups: [], + groupModalVisible: false, + selectedGroupId: [] + }; + } + + componentDidMount() { + this.fetch(); + } + + //fetch data from api + fetch = (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, + requireDeviceInfo: true, + }; + + const encodedExtraParams = Object.keys(extraParams) + .map(key => key + '=' + extraParams[key]).join('&'); + + //send request to the invoker + axios.get( + window.location.origin + config.serverConfig.invoker.uri + + config.serverConfig.invoker.store + + `/admin/subscription/${this.props.uuid}?` + encodedExtraParams, + ).then(res => { + if (res.status === 200) { + const pagination = {...this.state.pagination}; + console.log(res.data.data.data); + this.setState({ + loading: false, + data: res.data.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 devices.", + }); + } + + this.setState({loading: false}); + }); + }; + + render() { + const {data, pagination, loading, selectedRows} = this.state; + return ( +
+
+ + Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque + laudantium, + totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae + dicta sunt explicabo. + +
+
(record.device.deviceIdentifier + record.device.enrolmentInfo.owner + record.device.enrolmentInfo.ownership)} + dataSource={data} + pagination={{ + ...pagination, + size: "small", + // position: "top", + showTotal: (total, range) => `showing ${range[0]}-${range[1]} of ${total} devices` + // showQuickJumper: true + }} + loading={loading} + scroll={{x: 1000}} + /> + + ); + } +} + +export default withConfigContext(InstalledDevicesTable); \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/ReleaseView.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/ReleaseView.js index 6994f16e476..51ab619df26 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/ReleaseView.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/components/apps/release/ReleaseView.js @@ -17,7 +17,7 @@ */ import React from "react"; -import {Divider, Row, Col, Typography, Button, Dropdown, notification, Menu, Icon, Spin} from "antd"; +import {Divider, Row, Col, Typography, Button, Dropdown, notification, Menu, Icon, Spin, Tabs} from "antd"; import "../../../App.css"; import ImgViewer from "../../apps/release/images/ImgViewer"; import StarRatings from "react-star-ratings"; @@ -30,8 +30,10 @@ import CurrentUsersReview from "./review/CurrentUsersReview"; import {withConfigContext} from "../../../context/ConfigContext"; import {handleApiError} from "../../../js/Utils"; import ReviewContainer from "./review/ReviewContainer"; +import InstalledDevicesTable from "./InstalledDevicesTable"; const {Title, Text, Paragraph} = Typography; +const {TabPane} = Tabs; class ReleaseView extends React.Component { constructor(props) { @@ -118,6 +120,12 @@ class ReleaseView extends React.Component { metaData = JSON.parse(release.metaData); } catch (e) { + } + if (app.hasOwnProperty("packageName")) { + metaData.push({ + key: "Package Name", + value: app.packageName + }); } const menu = ( @@ -171,31 +179,38 @@ class ReleaseView extends React.Component { - - - - - - - {release.description} - - - META DATA - - { - metaData.map((data, index) => { - return ( - - {data.key}
- {data.value} - - ) - }) - } - {(metaData.length === 0) && (No meta data available.)} - - - + + + + + + + + + {release.description} + + + META DATA + + { + metaData.map((data, index) => { + return ( + + {data.key}
+ {data.value} + + ) + }) + } + {(metaData.length === 0) && (No meta data available.)} + + + + + + + + ); From 48ffb02cb4360019987864130506721c2865952d Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Tue, 22 Oct 2019 23:40:49 +0530 Subject: [PATCH 6/9] Fix apple logo not displaying in UI DEP config --- .../app/units/cdmf.unit.ui.navbar.nav-menu/nav-menu.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.navbar.nav-menu/nav-menu.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.navbar.nav-menu/nav-menu.hbs index 8c80bd6fc77..b071abf81d8 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.navbar.nav-menu/nav-menu.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.navbar.nav-menu/nav-menu.hbs @@ -118,7 +118,7 @@ {{/if}} {{#if iosPluginFlag}}
  • - + DEP Configurations
  • From e57dd65dd8e0ce481ac8c95863a98cc5e7773a9b Mon Sep 17 00:00:00 2001 From: achala007 Date: Wed, 23 Oct 2019 09:54:00 +0530 Subject: [PATCH 7/9] Update geo featur UI and date time picker --- .../react-app/package.json | 4 +- .../Geo/geo-dashboard/GeoDashboard.js | 49 +++++++------------ .../src/pages/Dashboard/Dashboard.js | 25 +++++++--- 3 files changed, 40 insertions(+), 38 deletions(-) diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/package.json b/components/device-mgt/io.entgra.device.mgt.ui/react-app/package.json index 3f4470ef197..2471a872d95 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/package.json +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/package.json @@ -17,12 +17,11 @@ "moment": "latest", "prop-types": "latest", "rc-viewer": "0.0.9", - "react-advanced-datetimerange-picker": "^1.0.8", + "react-bootstrap": "^1.0.0-beta.12", "react-highlight-words": "^0.16.0", "react-image-viewer-zoom": "^1.0.36", "react-infinite-scroller": "^1.2.4", "react-leaflet": "^2.4.0", - "react-bootstrap": "^1.0.0-beta.12", "react-moment": "^0.9.2", "react-router": "^5.0.1", "react-router-config": "^5.0.1", @@ -31,6 +30,7 @@ "react-star-ratings": "^2.3.0", "react-twemoji": "^0.2.3", "react-virtualized": "^9.21.1", + "react-websocket": "^2.1.0", "reqwest": "^2.0.5", "storm-react-diagrams": "^5.2.1" }, diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Geo/geo-dashboard/GeoDashboard.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Geo/geo-dashboard/GeoDashboard.js index 63367f3afd3..07be907074b 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Geo/geo-dashboard/GeoDashboard.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Geo/geo-dashboard/GeoDashboard.js @@ -18,8 +18,7 @@ import React from "react"; import moment from "moment"; -import DateTimeRangeContainer from "react-advanced-datetimerange-picker"; -import {Button, Select, message, notification, Tag, Tooltip, Empty} from "antd"; +import {Button, Select, message, notification, Tag, Tooltip, Empty, DatePicker} from "antd"; import axios from "axios"; import {withConfigContext} from "../../../context/ConfigContext"; import GeoCustomMap from "../geo-custom-map/GeoCustomMap"; @@ -29,15 +28,16 @@ class GeoDashboard extends React.Component { constructor(props) { super(props); - let start = moment(new Date()); + let start = moment( + new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate(), 0, 0, 0, 0) + ); let end = moment(start) - .add(5, "days") - .subtract(1, "minute"); + .add(1, "days") + .subtract(1, "seconds"); this.state = { deviceData: [], selectedDevice: '', locationData: [], - // currentLocation: [], loading: false, start: start, end: end, @@ -55,11 +55,11 @@ class GeoDashboard extends React.Component { * @param startDate - start date * @param endDate - end date */ - applyCallback = (startDate, endDate) => { + applyCallback = (dates, dateStrings) => { console.log("Apply Callback"); this.setState({ - start: startDate, - end: endDate + start: dateStrings[0], + end: dateStrings[1] }); }; @@ -180,6 +180,7 @@ class GeoDashboard extends React.Component { */ controllerBar = () => { + const {RangePicker} = DatePicker; let now = new Date(); let start = moment( new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0) @@ -199,32 +200,20 @@ class GeoDashboard extends React.Component { "2 Weeks": [moment(start).subtract(14, "days"), moment(end)], "1 Month": [moment(start).subtract(1, "months"), moment(end)], }; - let local = { - format: "DD-MM-YYYY HH:mm", - sundayFirst: false - }; - let maxDate = moment(start).add(24, "hour"); - let value = - ` - ${this.state.start.format("DD-MM-YYYY HH:mm")} - ${this.state.end.format("DD-MM-YYYY HH:mm")} - `; + let {deviceData} = this.state; return (
    + - - {value} - - + />
    ); diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Groups/GroupsTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Groups/GroupsTable.js index f411c0782ac..1fdaedec499 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Groups/GroupsTable.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Groups/GroupsTable.js @@ -18,7 +18,7 @@ import React from "react"; import axios from "axios"; -import {Tag, message, notification, Table, Typography, Tooltip, Icon, Divider} from "antd"; +import { message, notification, Table, Typography} from "antd"; import TimeAgo from 'javascript-time-ago' // Load locale-specific relative date/time formatting rules. @@ -164,7 +164,6 @@ class GroupsTable extends React.Component { loading={loading} onChange={this.handleTableChange} rowSelection={this.rowSelection} - scroll={{x: 1000}} /> ); diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Policies/PoliciesTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Policies/PoliciesTable.js index 29394b9cde5..5a1fbb3692b 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Policies/PoliciesTable.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Policies/PoliciesTable.js @@ -18,7 +18,7 @@ import React from "react"; import axios from "axios"; -import {Tag, message, notification, Table, Typography, Tooltip, Icon, Divider} from "antd"; +import {message, notification, Table, Typography} from "antd"; import TimeAgo from 'javascript-time-ago' // Load locale-specific relative date/time formatting rules. @@ -171,7 +171,6 @@ class PoliciesTable extends React.Component { loading={loading} onChange={this.handleTableChange} rowSelection={this.rowSelection} - scroll={{x: 1000}} /> ); diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Roles/RolesTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Roles/RolesTable.js index 68083506463..1080cddddbf 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Roles/RolesTable.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Roles/RolesTable.js @@ -126,16 +126,26 @@ class RolesTable extends React.Component { render() { const {data, pagination, loading, selectedRows} = this.state; - + const { Meta } = Card; const itemCard = data.map((data) => -
    - - {data} - + + , + ,]} + > + } + title={data} + /> + ); return ( -
    +
    {itemCard} diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersDevices.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersDevices.js index 13ce62e98e9..75529becc12 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersDevices.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersDevices.js @@ -240,7 +240,6 @@ class UsersDevices extends React.Component { loading={loading} onChange={this.handleTableChange} rowSelection={this.rowSelection} - scroll={{x: 1000}} />
    ); diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersTable.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersTable.js index ac7fc9c66a1..a1651111ffa 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersTable.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Users/UsersTable.js @@ -18,7 +18,7 @@ import React from "react"; import axios from "axios"; -import {message, notification, Table, Typography, Panel, Collapse, Button, List, Modal, Icon} from "antd"; +import {message, notification, Table, Typography, Panel, Collapse, Button, List, Modal, Icon, Tabs} from "antd"; import TimeAgo from 'javascript-time-ago' // Load locale-specific relative date/time formatting rules. @@ -174,9 +174,9 @@ class UsersTable extends React.Component { }; render() { - const {data, pagination, loading, selectedRows} = this.state; const { Panel } = Collapse; + const { TabPane } = Tabs; const columns = [ { title: 'User Name', @@ -231,30 +231,44 @@ class UsersTable extends React.Component { loading={loading} onChange={this.handleTableChange} rowSelection={this.rowSelection} - scroll={{x: 1000}} />
    - - + + + + Roles + + } + key="1" + > {item}} /> - - + + + + Enrolled Devices + + } + key="2" + > - - + +