Add UI feature to delete set of devices

feature/appm-store/pbac
Dharmakeerthi Lasantha 5 years ago
commit ec4511ce01

@ -0,0 +1,85 @@
/*
* 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 {Button, Icon, notification} from "antd";
class BulkActionBar extends React.Component {
constructor(props){
super(props);
this.state = {
selectedMultiple:false,
selectedSingle:false
}
}
//This method is used to trigger delete request on selected devices
deleteDevice = () => {
const deviceStatusArray = this.props.selectedRows.map(obj => obj.enrolmentInfo.status);
if(deviceStatusArray.includes("ACTIVE") || deviceStatusArray.includes("INACTIVE")){
notification["error"]({
message: "There was a problem",
duration: 0,
description:
"Cannot delete ACTIVE/INACTIVE devices.",
});
}else{
this.props.deleteDevice();
}
}
componentDidUpdate(prevProps, prevState, snapshot) {
if(prevProps.selectedRows !== this.props.selectedRows){
if(this.props.selectedRows.length > 1){
this.setState({selectedMultiple:true,selectedSingle:false})
}else if(this.props.selectedRows.length == 1){
this.setState({selectedSingle:true,selectedMultiple:true})
}else{
this.setState({selectedSingle:false,selectedMultiple:false})
}
}
}
render() {
return(
<div style={{padding:'5px'}}>
<Button
type="normal"
icon="delete"
size={'default'}
onClick={this.deleteDevice}
style={
{display:this.state.selectedMultiple ? "inline" : "none"}
}>Delete
</Button>
<Button
type="normal"
icon="delete"
size={'default'}
style={
{display:this.state.selectedSingle ? "inline" : "none"}
}>Disenroll
</Button>
</div>
)
}
}
export default BulkActionBar;

@ -24,6 +24,7 @@ import TimeAgo from 'javascript-time-ago'
// Load locale-specific relative date/time formatting rules. // Load locale-specific relative date/time formatting rules.
import en from 'javascript-time-ago/locale/en' import en from 'javascript-time-ago/locale/en'
import {withConfigContext} from "../../context/ConfigContext"; import {withConfigContext} from "../../context/ConfigContext";
import BulkActionBar from "./BulkActionBar";
const {Text} = Typography; const {Text} = Typography;
@ -158,17 +159,6 @@ class DeviceTable extends React.Component {
this.fetch(); this.fetch();
} }
componentDidUpdate(prevProps, prevState, snapshot) {
if(prevProps.deleteRequest !== this.props.deleteRequest){
this.deleteDevice();
}
if(prevProps.deselectRequest !== this.props.deselectRequest){
this.rowSelection.getCheckboxProps = record => ({
disabled: record.enrolmentInfo.status !== 'REMOVED' // Column configuration not to be checked
})
}
}
//fetch data from api //fetch data from api
fetch = (params = {}) => { fetch = (params = {}) => {
const config = this.props.context; const config = this.props.context;
@ -222,19 +212,19 @@ class DeviceTable extends React.Component {
const config = this.props.context; const config = this.props.context;
this.setState({loading: true}); this.setState({loading: true});
const deviceData = JSON.stringify(this.state.deviceIds); const deviceData = this.state.deviceIds;
//send request to the invoker //send request to the invoker
axios.delete( axios.put(
window.location.origin + config.serverConfig.invoker.uri + window.location.origin + config.serverConfig.invoker.uri +
config.serverConfig.invoker.deviceMgt + config.serverConfig.invoker.deviceMgt +
"/admin/devices/permanent-delete", "/admin/devices/permanent-delete",
{ deviceData,
headers:{'Content-Type': 'application/json; charset=utf-8'} , { headers : {'Content-Type': 'application/json'}}
data: deviceData
},
).then(res => { ).then(res => {
if (res.status === 200) { if (res.status === 200) {
this.fetch();
const pagination = {...this.state.pagination}; const pagination = {...this.state.pagination};
this.setState({ this.setState({
loading: false, loading: false,
@ -242,7 +232,6 @@ class DeviceTable extends React.Component {
pagination, pagination,
}); });
} }
}).catch((error) => { }).catch((error) => {
if (error.hasOwnProperty("response") && error.response.status === 401) { if (error.hasOwnProperty("response") && error.response.status === 401) {
//todo display a popop with error //todo display a popop with error
@ -253,7 +242,7 @@ class DeviceTable extends React.Component {
message: "There was a problem", message: "There was a problem",
duration: 0, duration: 0,
description: description:
"Error occurred while trying to load devices.", "Error occurred while trying to delete devices.",
}); });
} }
@ -280,6 +269,9 @@ class DeviceTable extends React.Component {
const {data, pagination, loading, selectedRows} = this.state; const {data, pagination, loading, selectedRows} = this.state;
return ( return (
<div> <div>
<BulkActionBar
deleteDevice={this.deleteDevice}
selectedRows={this.state.selectedRows}/>
<Table <Table
columns={columns} columns={columns}
rowKey={record => (record.deviceIdentifier + record.enrolmentInfo.owner + record.enrolmentInfo.ownership)} rowKey={record => (record.deviceIdentifier + record.enrolmentInfo.owner + record.enrolmentInfo.ownership)}

@ -35,32 +35,6 @@ class Devices extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.routes = props.routes; this.routes = props.routes;
this.state = {
deselectRequest:false,
deleteRequest:false,
deleteButtonDisabled:true,
displayDeleteButton:'none',
selected:"Actions"
}
this.deleteCall = this.deleteCall.bind(this);
this.cancelDelete = this.cancelDelete.bind(this);
}
//This method is used to trigger delete request on selected devices
deleteCall = () => {
this.setState({deleteRequest:!this.state.deleteRequest});
}
//This method is used to cancel deletion
cancelDelete = () => {
this.setState({displayDeleteButton:'none' , deleteRequest:false})
}
//When delete action is selected, this method is called and devices which aren't in REMOVED state becomes unselectable
onChange = value => {
this.setState(
{displayDeleteButton:'inline' , deselectRequest:!this.state.deselectRequest
});
} }
render() { render() {
@ -77,49 +51,9 @@ class Devices extends React.Component {
<h3>Devices</h3> <h3>Devices</h3>
<Paragraph>Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an <Paragraph>Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an
illud incorrupte nam.</Paragraph> illud incorrupte nam.</Paragraph>
<div style={{paddingBottom:'5px'}}>
<table>
<tbody>
<tr>
<td>
<Select
value={this.state.selected}
showSearch
style={{ width: 100 }}
placeholder="Actions"
optionFilterProp="children"
onChange={this.onChange}
filterOption={(input, option) =>
option.props.children
.toLowerCase()
.indexOf(input.toLowerCase()) >= 0
}>
<Select.Option value="delete">Delete</Select.Option>
</Select>
</td>
<td>
<Button type="primary" icon="delete"
onClick={this.deleteCall}
style={{display:this.state.displayDeleteButton}}>
Delete Selected Devices
</Button>.
</td>
<td>
<Button type="danger"
onClick={this.cancelDelete}
style={{display:this.state.displayDeleteButton}}>
Cancel
</Button>
</td>
</tr>
</tbody>
</table>
</div>
</div> </div>
<div style={{backgroundColor:"#ffffff", borderRadius: 5}}> <div style={{backgroundColor:"#ffffff", borderRadius: 5}}>
<DeviceTable <DeviceTable/>
deleteRequest={this.state.deleteRequest}
deselectRequest={this.state.deselectRequest}/>
</div> </div>
</PageHeader> </PageHeader>
<div style={{background: '#f0f2f5', padding: 24, minHeight: 720}}> <div style={{background: '#f0f2f5', padding: 24, minHeight: 720}}>

@ -248,12 +248,12 @@ public interface DeviceManagementAdminService {
required = true) required = true)
List<String> deviceIdentifiers); List<String> deviceIdentifiers);
@DELETE @PUT
@Path("/permanent-delete") @Path("/permanent-delete")
@ApiOperation( @ApiOperation(
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
consumes = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON,
httpMethod = "DELETE", httpMethod = "PUT",
value = "Permanently remove the Device Specified by the Device ID", value = "Permanently remove the Device Specified by the Device ID",
notes = "Returns the status of the permanently deleted device operation and the details of the deleted device.", notes = "Returns the status of the permanently deleted device operation and the details of the deleted device.",
tags = "Device Management", tags = "Device Management",

@ -136,7 +136,7 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe
} }
} }
@DELETE @PUT
@Override @Override
@Path("/permanent-delete") @Path("/permanent-delete")
public Response deleteDevicesPermanently(List<String> deviceIdentifiers) { public Response deleteDevicesPermanently(List<String> deviceIdentifiers) {

Loading…
Cancel
Save