diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Groups/GroupDevicesModal.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Groups/GroupDevicesModal.js new file mode 100644 index 0000000000..4b483b9e79 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/components/Groups/GroupDevicesModal.js @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2020, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; + +import { Button, Modal } 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 ReportDevicesTable from '../Reports/Widgets/ReportDevicesTable'; + +let apiUrl; + +class GroupDevicesModal extends React.Component { + constructor(props) { + super(props); + TimeAgo.addLocale(en); + this.state = { + data: [], + pagination: {}, + loading: false, + selectedRows: [], + visible: false, + apiUrl: null, + }; + } + + openDrawer = () => { + this.setState({ visible: true }); + const groupData = { + groupId: this.props.groupData.id, + groupName: this.props.groupData.name, + }; + this.fetchGroupDevices(groupData); + }; + + handleModalCancel = () => { + this.setState({ + visible: false, + }); + }; + + // fetch data from api + fetchGroupDevices = (params = {}, filters = {}) => { + const config = this.props.context; + + // get current page + const currentPage = params.hasOwnProperty('page') ? params.page : 1; + + const extraParams = { + offset: 10 * (currentPage - 1), // calculate the offset + limit: 10, + ...params, + }; + + const encodedExtraParams = Object.keys(extraParams) + .map(key => key + '=' + extraParams[key]) + .join('&'); + + apiUrl = + window.location.origin + + config.serverConfig.invoker.uri + + config.serverConfig.invoker.deviceMgt + + '/devices?' + + encodedExtraParams; + + this.setState({ apiUrl: apiUrl }); + }; + + handleTableChange = (pagination, filters, sorter) => { + const pager = { ...this.state.pagination }; + pager.current = pagination.current; + this.setState({ + pagination: pager, + }); + this.fetchGroupDevices({ + results: pagination.pageSize, + page: pagination.current, + sortField: sorter.field, + sortOrder: sorter.order, + ...filters, + }); + }; + + render() { + const { apiUrl, visible } = this.state; + return ( +
+ + + Cancel + , + , + ]} + > +
+ +
+
+
+ ); + } +} + +export default withConfigContext(GroupDevicesModal); 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 23768c48b0..bb16ed8371 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 @@ -26,6 +26,7 @@ import { withConfigContext } from '../../context/ConfigContext'; import GroupActions from './GroupActions'; import AddGroup from './AddGroup'; import Filter from '../Utils/Filter/Filter'; +import GroupDevicesModal from './GroupDevicesModal'; const searchFields = [ { @@ -82,6 +83,12 @@ class GroupsTable extends React.Component { ), }, + { + title: 'Devices', + dataIndex: 'id', + key: 'details', + render: (id, row) => , + }, ]; rowSelection = { 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 e37a4cc94f..acbd25f60e 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js @@ -32,8 +32,6 @@ import DeviceStatusReport from './components/Reports/Templates/DeviceStatusRepor import PolicyReportHome from './pages/Dashboard/Reports/PolicyReportHome'; import ReportDurationItemList from './pages/Dashboard/Reports/ReportDurationItemList'; import AppNotInstalledDevicesReport from './components/Reports/Templates/AppNotInstalledDevicesReport'; -import Devices from './pages/Dashboard/Devices/Devices'; -import DeviceEnroll from './pages/Dashboard/Devices/DeviceEnroll'; const routes = [ { @@ -46,16 +44,16 @@ const routes = [ exact: false, component: Dashboard, routes: [ - { - path: '/entgra/devices', - component: Devices, - exact: true, - }, - { - path: '/entgra/devices/enroll', - component: DeviceEnroll, - exact: true, - }, + // { + // path: '/entgra/devices', + // component: Devices, + // exact: true, + // }, + // { + // path: '/entgra/devices/enroll', + // component: DeviceEnroll, + // exact: true, + // }, { path: '/entgra/geo', component: Geo, diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.js index 697e3aec7c..da03b3126a 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/pages/Dashboard/Dashboard.js @@ -72,26 +72,26 @@ class Dashboard extends React.Component { marginRight: 110, }} > - - - Devices - - } - > - - - View - - - - - Enroll - - - + {/* */} + {/* */} + {/* Devices*/} + {/* */} + {/* }*/} + {/* >*/} + {/* */} + {/* */} + {/* View*/} + {/* */} + {/* */} + {/* */} + {/* */} + {/* Enroll*/} + {/* */} + {/* */} + {/* */} searchDevicesInGroup(PaginationRequest request, int tenantId) throws DeviceManagementDAOException; + /** + * This method is used to get device count within a specific group. + * + * @param request PaginationRequest object holding the data for pagination + * @param tenantId tenant id + * @return Device count + * @throws DeviceManagementDAOException + */ + int getCountOfDevicesInGroup(PaginationRequest request, int tenantId) throws DeviceManagementDAOException; + /** * This method is used to retrieve all the devices of a given tenant and device type. * diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java index 81fd4c7ce3..b01925016f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java @@ -43,10 +43,10 @@ import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.EnrolmentInfo.Status; import org.wso2.carbon.device.mgt.common.PaginationRequest; -import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; -import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistory; import org.wso2.carbon.device.mgt.common.configuration.mgt.DevicePropertyInfo; import org.wso2.carbon.device.mgt.common.device.details.DeviceData; +import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; +import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistory; import org.wso2.carbon.device.mgt.core.dao.DeviceDAO; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; @@ -842,6 +842,129 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { return devices; } + @Override + public int getCountOfDevicesInGroup(PaginationRequest request, int tenantId) + throws DeviceManagementDAOException { + int deviceCount = 0; + int groupId = request.getGroupId(); + String deviceType = request.getDeviceType(); + boolean isDeviceTypeProvided = false; + String deviceName = request.getDeviceName(); + boolean isDeviceNameProvided = false; + String owner = request.getOwner(); + boolean isOwnerProvided = false; + String ownerPattern = request.getOwnerPattern(); + boolean isOwnerPatternProvided = false; + String ownership = request.getOwnership(); + boolean isOwnershipProvided = false; + List statusList = request.getStatusList(); + boolean isStatusProvided = false; + Date since = request.getSince(); + boolean isSinceProvided = false; + + try { + Connection conn = getConnection(); + String sql = "SELECT COUNT(d1.DEVICE_ID) AS DEVICE_COUNT " + + "FROM DM_ENROLMENT e, " + + "(SELECT gd.DEVICE_ID, " + + "gd.DESCRIPTION, " + + "gd.NAME, " + + "gd.DEVICE_IDENTIFICATION, " + + "t.NAME AS DEVICE_TYPE " + + "FROM " + + "(SELECT d.ID AS DEVICE_ID, " + + "d.DESCRIPTION, " + + "d.NAME, " + + "d.DEVICE_IDENTIFICATION, " + + "d.DEVICE_TYPE_ID " + + "FROM DM_DEVICE d, " + + "(SELECT dgm.DEVICE_ID " + + "FROM DM_DEVICE_GROUP_MAP dgm " + + "WHERE dgm.GROUP_ID = ?) dgm1 " + + "WHERE d.ID = dgm1.DEVICE_ID " + + "AND d.TENANT_ID = ?"; + //Add the query for device-name + if (deviceName != null && !deviceName.isEmpty()) { + sql = sql + " AND d.NAME LIKE ?"; + isDeviceNameProvided = true; + } + sql = sql + ") gd, DM_DEVICE_TYPE t"; + if (since != null) { + sql = sql + ", DM_DEVICE_DETAIL dt"; + isSinceProvided = true; + } + sql = sql + " WHERE gd.DEVICE_TYPE_ID = t.ID"; + //Add query for last updated timestamp + if (isSinceProvided) { + sql = sql + " AND dt.DEVICE_ID = gd.DEVICE_ID AND dt.UPDATE_TIMESTAMP > ?"; + } + //Add the query for device-type + if (deviceType != null && !deviceType.isEmpty()) { + sql = sql + " AND t.NAME = ?"; + isDeviceTypeProvided = true; + } + sql = sql + " ) d1 WHERE d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ? "; + //Add the query for ownership + if (ownership != null && !ownership.isEmpty()) { + sql = sql + " AND e.OWNERSHIP = ?"; + isOwnershipProvided = true; + } + //Add the query for owner + if (owner != null && !owner.isEmpty()) { + sql = sql + " AND e.OWNER = ?"; + isOwnerProvided = true; + } else if (ownerPattern != null && !ownerPattern.isEmpty()) { + sql = sql + " AND e.OWNER LIKE ?"; + isOwnerPatternProvided = true; + } + if (statusList != null && !statusList.isEmpty()) { + sql += buildStatusQuery(statusList); + isStatusProvided = true; + } + + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + int paramIdx = 1; + stmt.setInt(paramIdx++, groupId); + stmt.setInt(paramIdx++, tenantId); + if (isDeviceNameProvided) { + stmt.setString(paramIdx++, deviceName + "%"); + } + if (isSinceProvided) { + stmt.setLong(paramIdx++, since.getTime()); + } + if (isDeviceTypeProvided) { + stmt.setString(paramIdx++, deviceType); + } + stmt.setInt(paramIdx++, tenantId); + if (isOwnershipProvided) { + stmt.setString(paramIdx++, ownership); + } + if (isOwnerProvided) { + stmt.setString(paramIdx++, owner); + } else if (isOwnerPatternProvided) { + stmt.setString(paramIdx++, ownerPattern + "%"); + } + if (isStatusProvided) { + for (String status : statusList) { + stmt.setString(paramIdx++, status); + } + } + + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + deviceCount = rs.getInt("DEVICE_COUNT"); + } + return deviceCount; + } + } + } catch (SQLException e) { + String msg = "Error occurred while retrieving count of" + + " devices belonging to group : " + groupId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + private Connection getConnection() throws SQLException { return DeviceManagementDAOFactory.getConnection(); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/report/mgt/ReportManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/report/mgt/ReportManagementServiceImpl.java index 06269c2cef..2d8971c618 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/report/mgt/ReportManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/report/mgt/ReportManagementServiceImpl.java @@ -23,15 +23,12 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.mgt.common.Count; import org.wso2.carbon.device.mgt.common.Device; -import org.wso2.carbon.device.mgt.common.app.mgt.Application; -import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.PaginationResult; import org.wso2.carbon.device.mgt.common.exceptions.DeviceTypeNotFoundException; import org.wso2.carbon.device.mgt.common.exceptions.ReportManagementException; import org.wso2.carbon.device.mgt.common.report.mgt.ReportManagementService; -import org.wso2.carbon.device.mgt.core.dao.ApplicationDAO; import org.wso2.carbon.device.mgt.core.dao.DeviceDAO; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; @@ -56,11 +53,9 @@ public class ReportManagementServiceImpl implements ReportManagementService { private static final Log log = LogFactory.getLog(ReportManagementServiceImpl.class); private DeviceDAO deviceDAO; - private ApplicationDAO applicationDAO; public ReportManagementServiceImpl() { this.deviceDAO = DeviceManagementDAOFactory.getDeviceDAO(); - this.applicationDAO = DeviceManagementDAOFactory.getApplicationDAO(); } @Override 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 60ebdb7ab6..59d4bfcd0e 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 @@ -897,10 +897,11 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv DeviceManagementDAOFactory.openConnection(); if(request.getGroupId()!=0){ allDevices = deviceDAO.searchDevicesInGroup(request, tenantId); + count = deviceDAO.getCountOfDevicesInGroup(request, tenantId); } else{ allDevices = deviceDAO.getDevices(request, tenantId); + count = deviceDAO.getDeviceCount(request, tenantId); } - count = deviceDAO.getDeviceCount(request, tenantId); } catch (DeviceManagementDAOException e) { String msg = "Error occurred while retrieving device list pertaining to the current tenant"; log.error(msg, e);