forked from community/device-mgt-core
Merge branch 'master' of https://gitlab.com/entgra/carbon-device-mgt
commit
a76405c7e5
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* 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 {Icon, message, Modal, notification, Popconfirm, Select, Table, Tag, Tooltip, Typography} from "antd";
|
||||
import TimeAgo from 'javascript-time-ago'
|
||||
// Load locale-specific relative date/time formatting rules.
|
||||
import en from 'javascript-time-ago/locale/en'
|
||||
import {withConfigContext} from "../../../context/ConfigContext";
|
||||
import Moment from "react-moment";
|
||||
|
||||
const {Paragraph, Text} = Typography;
|
||||
|
||||
let config = null;
|
||||
|
||||
class CertificateTable extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
config = this.props.context;
|
||||
TimeAgo.addLocale(en);
|
||||
this.state = {
|
||||
data: [],
|
||||
pagination: {},
|
||||
loading: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.fetch();
|
||||
}
|
||||
|
||||
//fetch data from api
|
||||
fetch = (params = {}) => {
|
||||
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 +
|
||||
'/certificate-mgt/v1.0/admin/certificates',
|
||||
).then(res => {
|
||||
if (res.status === 200) {
|
||||
const pagination = {...this.state.pagination};
|
||||
this.setState({
|
||||
loading: false,
|
||||
data: res.data.data.certificates,
|
||||
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,
|
||||
});
|
||||
};
|
||||
|
||||
deleteCertificate = (serialNumber) =>{
|
||||
axios.delete(
|
||||
window.location.origin + config.serverConfig.invoker.uri +
|
||||
'/certificate-mgt/v1.0/admin/certificates/'+ serialNumber,
|
||||
{headers: {'Content-Type': 'application/json'}}
|
||||
).then(res => {
|
||||
if (res.status === 200) {
|
||||
this.fetch();
|
||||
notification["success"]({
|
||||
message: "Done",
|
||||
duration: 4,
|
||||
description:
|
||||
"Successfully deleted the certificate.",
|
||||
});
|
||||
}
|
||||
}).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 delete the certificate.",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
columns = [
|
||||
{
|
||||
title: 'Serial Number',
|
||||
dataIndex: 'serialNumber'
|
||||
},
|
||||
{
|
||||
title: 'Username',
|
||||
dataIndex: 'username'
|
||||
},
|
||||
{
|
||||
title: 'Certificate Version',
|
||||
dataIndex: 'certificateVersion'
|
||||
},
|
||||
{
|
||||
title: 'Certificate Serial',
|
||||
dataIndex: 'certificateserial'
|
||||
},
|
||||
{
|
||||
title: 'Not Before',
|
||||
dataIndex: 'notBefore',
|
||||
render: notBefore => (
|
||||
<Moment format="YYYY/MM/DD HH:mm" date={notBefore} />
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'Not After',
|
||||
dataIndex: 'notAfter',
|
||||
render: notAfter => (
|
||||
<Moment format="YYYY/MM/DD HH:mm" date={notAfter} />
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'Subject',
|
||||
dataIndex: 'subject',
|
||||
render: subject => (
|
||||
<Paragraph style={{marginBottom: 0}} ellipsis={{rows:1, expandable: true}}>{subject}</Paragraph>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'Issuer',
|
||||
dataIndex: 'issuer',
|
||||
render: issuer => (
|
||||
<Paragraph style={{marginBottom: 0}} ellipsis={{rows:1, expandable: true}}>{issuer}</Paragraph>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'Actions',
|
||||
key: 'actions',
|
||||
dataIndex: 'serialNumber',
|
||||
render: (serialNumber) => (
|
||||
<Tooltip placement="bottom" title={"Remove User"}>
|
||||
<Popconfirm
|
||||
placement="top"
|
||||
title={"Are you sure?"}
|
||||
onConfirm={() => {this.deleteCertificate(serialNumber)}}
|
||||
okText="Ok"
|
||||
cancelText="Cancel">
|
||||
<a><Text type="danger"><Icon type="delete"/></Text></a>
|
||||
</Popconfirm>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
];
|
||||
|
||||
render() {
|
||||
const {data, pagination, loading} = this.state;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<Table
|
||||
columns={this.columns}
|
||||
rowKey={record => record.serialNumber}
|
||||
dataSource={data}
|
||||
pagination={{
|
||||
...pagination,
|
||||
size: "small",
|
||||
// position: "top",
|
||||
showTotal: (total, range) => `showing ${range[0]}-${range[1]} of ${total} devices`
|
||||
// showQuickJumper: true
|
||||
}}
|
||||
loading={loading}
|
||||
onChange={this.handleTableChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withConfigContext(CertificateTable);
|
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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,
|
||||
Tag,
|
||||
Radio, Select, Button, Card,
|
||||
Row, Col, message, notification
|
||||
} from "antd";
|
||||
|
||||
import {Link} from "react-router-dom";
|
||||
import PoliciesTable from "../../../components/Policies/PoliciesTable";
|
||||
import DevicesTable from "../../../components/Devices/DevicesTable";
|
||||
import DateRangePicker from "../../../components/Reports/DateRangePicker";
|
||||
import ReportDeviceTable from "../../../components/Devices/ReportDevicesTable";
|
||||
import PieChart from "../../../components/Reports/Widgets/PieChart";
|
||||
import axios from "axios";
|
||||
import CountWidget from "../../../components/Reports/Widgets/CountWidget";
|
||||
import {withConfigContext} from "../../../context/ConfigContext";
|
||||
const {Paragraph} = Typography;
|
||||
const { CheckableTag } = Tag;
|
||||
|
||||
const { Option } = Select;
|
||||
let config = null;
|
||||
|
||||
|
||||
class DeviceStatusReport extends React.Component {
|
||||
routes;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.routes = props.routes;
|
||||
config = this.props.context;
|
||||
const { reportData } = this.props.location;
|
||||
this.state = {
|
||||
selectedTags: ['Enrolled'],
|
||||
paramsObject:{
|
||||
from:reportData.duration[0],
|
||||
to:reportData.duration[1]
|
||||
},
|
||||
statsObject:{},
|
||||
statArray:[{item:"ACTIVE",count:0},{item:"INACTIVE",count:0},{item:"REMOVED",count:0}]
|
||||
};
|
||||
}
|
||||
|
||||
onClickPieChart = (value) => {
|
||||
console.log(value.data.point.item);
|
||||
const chartValue = value.data.point.item;
|
||||
let tempParamObj = this.state.paramsObject;
|
||||
|
||||
tempParamObj.status = chartValue;
|
||||
|
||||
|
||||
this.setState({paramsObject:tempParamObj});
|
||||
console.log(this.state.paramsObject)
|
||||
};
|
||||
|
||||
render() {
|
||||
const { statArray } = this.state;
|
||||
const { reportData } = this.props.location;
|
||||
|
||||
const params = {...this.state.paramsObject};
|
||||
return (
|
||||
<div>
|
||||
<PageHeader style={{paddingTop: 0}}>
|
||||
<Breadcrumb style={{paddingBottom: 16}}>
|
||||
<Breadcrumb.Item>
|
||||
<Link to="/entgra"><Icon type="home"/> Home</Link>
|
||||
</Breadcrumb.Item>
|
||||
<Breadcrumb.Item>Report</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
<div className="wrap" style={{marginBottom: '10px'}}>
|
||||
<h3>Summary of enrollments</h3>
|
||||
<div style={{marginBottom: '10px'}}>
|
||||
<Select defaultValue="android" style={{ width: 120 , marginRight:10}}>
|
||||
<Option value="android">Android</Option>
|
||||
<Option value="ios">IOS</Option>
|
||||
<Option value="windows">Windows</Option>
|
||||
</Select>
|
||||
<Button onClick={this.onSubmitReport} style={{marginLeft:10}} type="primary">Generate Report</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Card
|
||||
bordered={true}
|
||||
hoverable={true}
|
||||
style={{borderRadius: 5, marginBottom: 10, height:window.innerHeight*0.5}}>
|
||||
|
||||
<PieChart onClickPieChart={this.onClickPieChart} reportData={reportData}/>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div style={{backgroundColor:"#ffffff", borderRadius: 5}}>
|
||||
<ReportDeviceTable paramsObject={params}/>
|
||||
</div>
|
||||
</PageHeader>
|
||||
<div style={{background: '#f0f2f5', padding: 24, minHeight: 720}}>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withConfigContext(DeviceStatusReport);
|
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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,
|
||||
Tag,
|
||||
Radio, Select, Button, Card,
|
||||
Row, Col, message, notification
|
||||
} from "antd";
|
||||
|
||||
import {Link} from "react-router-dom";
|
||||
import PoliciesTable from "../../../components/Policies/PoliciesTable";
|
||||
import DevicesTable from "../../../components/Devices/DevicesTable";
|
||||
import DateRangePicker from "../../../components/Reports/DateRangePicker";
|
||||
import ReportDeviceTable from "../../../components/Devices/ReportDevicesTable";
|
||||
import PieChart from "../../../components/Reports/Widgets/PieChart";
|
||||
import axios from "axios";
|
||||
import CountWidget from "../../../components/Reports/Widgets/CountWidget";
|
||||
import {withConfigContext} from "../../../context/ConfigContext";
|
||||
const {Paragraph} = Typography;
|
||||
const { CheckableTag } = Tag;
|
||||
|
||||
const { Option } = Select;
|
||||
let config = null;
|
||||
|
||||
|
||||
class EnrollmentTypeReport extends React.Component {
|
||||
routes;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.routes = props.routes;
|
||||
config = this.props.context;
|
||||
const { reportData } = this.props.location;
|
||||
this.state = {
|
||||
paramsObject:{
|
||||
from:reportData.duration[0],
|
||||
to:reportData.duration[1]
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
console.log(reportData.duration);
|
||||
}
|
||||
|
||||
setParam = (tempParamObj, type, value) => {
|
||||
if(type==="status"){
|
||||
tempParamObj.status = value;
|
||||
if(tempParamObj.status) {
|
||||
delete tempParamObj.status;
|
||||
}
|
||||
} else if(type=="ownership"){
|
||||
tempParamObj.ownership = value;
|
||||
if(value=="ALL" && tempParamObj.ownership) {
|
||||
delete tempParamObj.ownership;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onClickPieChart = (value) => {
|
||||
const chartValue = value.data.point.item;
|
||||
let tempParamObj = this.state.paramsObject;
|
||||
|
||||
console.log(chartValue)
|
||||
|
||||
tempParamObj.ownership = chartValue;
|
||||
|
||||
this.setState({paramsObject:tempParamObj});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { reportData } = this.props.location;
|
||||
|
||||
const params = {...this.state.paramsObject};
|
||||
return (
|
||||
<div>
|
||||
<PageHeader style={{paddingTop: 0}}>
|
||||
<Breadcrumb style={{paddingBottom: 16}}>
|
||||
<Breadcrumb.Item>
|
||||
<Link to="/entgra"><Icon type="home"/> Home</Link>
|
||||
</Breadcrumb.Item>
|
||||
<Breadcrumb.Item>Report</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
<div className="wrap" style={{marginBottom: '10px'}}>
|
||||
<h3>Summary of enrollments</h3>
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Card
|
||||
bordered={true}
|
||||
hoverable={true}
|
||||
style={{borderRadius: 5, marginBottom: 10, height:window.innerHeight*0.5}}>
|
||||
|
||||
|
||||
<PieChart onClickPieChart={this.onClickPieChart} reportData={reportData}/>
|
||||
|
||||
</Card>
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{backgroundColor:"#ffffff", borderRadius: 5}}>
|
||||
<ReportDeviceTable paramsObject={params}/>
|
||||
</div>
|
||||
</PageHeader>
|
||||
<div style={{background: '#f0f2f5', padding: 24, minHeight: 720}}>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withConfigContext(EnrollmentTypeReport);
|
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* 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,
|
||||
Tag,
|
||||
Radio, Select, Button, Card,
|
||||
Row, Col, message, notification
|
||||
} from "antd";
|
||||
|
||||
import {Link, Redirect} from "react-router-dom";
|
||||
import PoliciesTable from "../../../components/Policies/PoliciesTable";
|
||||
import DevicesTable from "../../../components/Devices/DevicesTable";
|
||||
import DateRangePicker from "../../../components/Reports/DateRangePicker";
|
||||
import ReportDeviceTable from "../../../components/Devices/ReportDevicesTable";
|
||||
import PieChart from "../../../components/Reports/Widgets/PieChart";
|
||||
import axios from "axios";
|
||||
import CountWidget from "../../../components/Reports/Widgets/CountWidget";
|
||||
import {withConfigContext} from "../../../context/ConfigContext";
|
||||
const {Paragraph} = Typography;
|
||||
const { CheckableTag } = Tag;
|
||||
|
||||
const { Option } = Select;
|
||||
let config = null;
|
||||
|
||||
|
||||
class EnrollmentsVsUnenrollmentsReport extends React.Component {
|
||||
routes;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.routes = props.routes;
|
||||
config = this.props.context;
|
||||
const { reportData } = this.props.location;
|
||||
|
||||
this.state = {
|
||||
paramsObject:{
|
||||
from:reportData? reportData.duration[0]: "2019-01-01",
|
||||
to:reportData? reportData.duration[1]: "2019-01-01"
|
||||
},
|
||||
redirect: false
|
||||
};
|
||||
|
||||
this.redirectToHome();
|
||||
console.log(this.state.paramsObject);
|
||||
}
|
||||
|
||||
setParam = (tempParamObj, type, value) => {
|
||||
if(type==="status"){
|
||||
tempParamObj.status = value;
|
||||
if(tempParamObj.status) {
|
||||
delete tempParamObj.status;
|
||||
}
|
||||
} else if(type=="ownership"){
|
||||
tempParamObj.ownership = value;
|
||||
if(value=="ALL" && tempParamObj.ownership) {
|
||||
delete tempParamObj.ownership;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
redirectToHome = () => {
|
||||
return <Redirect to="/entgra" />
|
||||
};
|
||||
|
||||
setRedirect = (reportData) => {
|
||||
if(!reportData){
|
||||
this.setState({
|
||||
redirect: true
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
renderRedirect = () => {
|
||||
if (this.state.redirect) {
|
||||
return <Redirect to='/entgra' />
|
||||
}
|
||||
}
|
||||
|
||||
onClickPieChart = (value) => {
|
||||
const chartValue = value.data.point.item;
|
||||
let tempParamObj = this.state.paramsObject;
|
||||
|
||||
console.log(chartValue)
|
||||
|
||||
// tempParamObj.status = chartValue;
|
||||
|
||||
if(chartValue==="Enrollments"){
|
||||
tempParamObj.status = "ACTIVE&status=INACTIVE"
|
||||
}else{
|
||||
tempParamObj.status = "REMOVED"
|
||||
}
|
||||
|
||||
|
||||
this.setState({paramsObject:tempParamObj});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { reportData } = this.props.location;
|
||||
|
||||
console.log("======")
|
||||
console.log(reportData)
|
||||
console.log("======")
|
||||
|
||||
let reportDataClone = {
|
||||
params: ["ACTIVE"],
|
||||
duration: ["2020-01-01","2020-01-01"]
|
||||
};
|
||||
|
||||
const params = {...this.state.paramsObject};
|
||||
return (
|
||||
<div>
|
||||
|
||||
<div>{!reportData ? (
|
||||
<Redirect to='/entgra/reports' />
|
||||
) : (
|
||||
<PageHeader style={{paddingTop: 0}}>
|
||||
<Breadcrumb style={{paddingBottom: 16}}>
|
||||
<Breadcrumb.Item>
|
||||
<Link to="/entgra"><Icon type="home"/> Home</Link>
|
||||
</Breadcrumb.Item>
|
||||
<Breadcrumb.Item>Report</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
<div className="wrap" style={{marginBottom: '10px'}}>
|
||||
<h3>Summary of enrollments</h3>
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Card
|
||||
bordered={true}
|
||||
hoverable={true}
|
||||
style={{borderRadius: 5, marginBottom: 10, height:window.innerHeight*0.5}}>
|
||||
|
||||
|
||||
<PieChart onClickPieChart={this.onClickPieChart} reportData={reportData? reportData : reportDataClone}/>
|
||||
|
||||
</Card>
|
||||
|
||||
</div>
|
||||
|
||||
<div style={{backgroundColor:"#ffffff", borderRadius: 5}}>
|
||||
<ReportDeviceTable paramsObject={params}/>
|
||||
</div>
|
||||
</PageHeader>
|
||||
|
||||
)}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withConfigContext(EnrollmentsVsUnenrollmentsReport);
|
@ -0,0 +1,63 @@
|
||||
import React from "react";
|
||||
|
||||
import {Card, Col, Icon} from "antd";
|
||||
import {Link} from "react-router-dom";
|
||||
|
||||
class CountWidget extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.routes = props.routes;
|
||||
this.state = {
|
||||
statArray:[]
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({statArray:this.props.statArray})
|
||||
console.log("$$$$")
|
||||
console.log(this.props.statArray)
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const countObj = [
|
||||
{item:"All",count:100},
|
||||
{item:"Enrolled",count:80},
|
||||
{item:"Unenrolled",count:20}];
|
||||
|
||||
const { statArray } = this.state;
|
||||
|
||||
let card = statArray.map((data) =>
|
||||
// <Card
|
||||
// bordered={true}
|
||||
// hoverable={true}
|
||||
// key={data.item}
|
||||
// style={{borderRadius: 5, marginBottom: 5, width:"100%"}}>
|
||||
//
|
||||
// <h3>{data.item} Devices: {data.count}</h3>
|
||||
//
|
||||
// </Card>
|
||||
<Col key={data.item} span={6}>
|
||||
<Card key={data.item} bordered={true} hoverable={true} style={{borderRadius: 10, marginBottom: 16}}>
|
||||
|
||||
<div align='center'>
|
||||
<h2><b>{data.item}</b></h2>
|
||||
<h1>{data.count}</h1>
|
||||
{/*<p>{data.duration}</p>*/}
|
||||
{/*<ReportFilterModal/>*/}
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
)
|
||||
|
||||
return(
|
||||
<div>
|
||||
{card}
|
||||
</div>
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default CountWidget;
|
@ -0,0 +1,322 @@
|
||||
import React from "react";
|
||||
import {
|
||||
G2,
|
||||
Chart,
|
||||
Geom,
|
||||
Axis,
|
||||
Tooltip,
|
||||
Coord,
|
||||
Label,
|
||||
Legend,
|
||||
View,
|
||||
Guide,
|
||||
Shape,
|
||||
Facet,
|
||||
Util
|
||||
} from "bizcharts";
|
||||
import DataSet from "@antv/data-set";
|
||||
import axios from "axios";
|
||||
import {message, notification} from "antd";
|
||||
import {withConfigContext} from "../../../context/ConfigContext";
|
||||
|
||||
let config = null;
|
||||
|
||||
class PieChart extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
config = this.props.context;
|
||||
this.state = {
|
||||
loading:true,
|
||||
statArray:[]
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let { statArray } = this.state;
|
||||
const { reportData } = this.props;
|
||||
let params = {
|
||||
status: reportData.params[0],
|
||||
from: reportData.duration[0],
|
||||
to: reportData.duration[1]
|
||||
};
|
||||
|
||||
const urlSet = {
|
||||
paramsList:reportData.params,
|
||||
duration:reportData.duration
|
||||
};
|
||||
|
||||
console.log(urlSet)
|
||||
|
||||
if(reportData.params[0]==="Enrollments"){
|
||||
this.getEnrollmentsVsUnenrollmentsCount(params, urlSet)
|
||||
}else if(reportData.params[0]==="BYOD"){
|
||||
this.getEnrollmentTypeCount(params, urlSet);
|
||||
}else{
|
||||
this.getCount(params, urlSet);
|
||||
}
|
||||
}
|
||||
|
||||
clicked = () => {
|
||||
console.log("Clicked...!!")
|
||||
};
|
||||
|
||||
onChartChange = (data) => {
|
||||
this.props.onClickPieChart(data);
|
||||
};
|
||||
|
||||
statArray = [];
|
||||
|
||||
//Call count APIs and get count for given parameters, then create data object to build pie chart
|
||||
getCount = (params, urlSet) => {
|
||||
|
||||
this.setState({loading: true});
|
||||
|
||||
let { statArray } = this.state;
|
||||
|
||||
console.log(urlSet);
|
||||
|
||||
const urlArray = [];
|
||||
|
||||
urlSet.paramsList.map((data) => {
|
||||
const paramsObj = {
|
||||
status:data,
|
||||
from:urlSet.duration[0],
|
||||
to:urlSet.duration[1]
|
||||
}
|
||||
// console.log(paramsObj)
|
||||
const encodedExtraParams = Object.keys(paramsObj)
|
||||
.map(key => key + '=' + paramsObj[key]).join('&');
|
||||
const apiUrl = window.location.origin + config.serverConfig.invoker.uri +
|
||||
config.serverConfig.invoker.deviceMgt +
|
||||
"/reports/devices/count?" + encodedExtraParams;
|
||||
|
||||
urlArray.push(axios.get(apiUrl, data));
|
||||
});
|
||||
|
||||
console.log(urlArray)
|
||||
|
||||
|
||||
axios.all(urlArray).then(res => {
|
||||
|
||||
res.map((response) => {
|
||||
if(response.status === 200){
|
||||
let countData = {item:response.config[0], count:parseInt(response.data.data)}
|
||||
statArray.push(countData);
|
||||
}
|
||||
})
|
||||
this.setState({statArray})
|
||||
}).catch((error) => {
|
||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
||||
//todo display a popup with error
|
||||
message.error('You are not logged in');
|
||||
window.location.href = window.location.origin + '/entgra/login';
|
||||
} else {
|
||||
notification["error"]({
|
||||
message: "There was a problem",
|
||||
duration: 0,
|
||||
description:"Error occurred while trying to get device count.",
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//Call count APIs and get count for given parameters, then create data object to build pie chart
|
||||
getEnrollmentsVsUnenrollmentsCount = (params, urlSet) => {
|
||||
|
||||
this.setState({loading: true});
|
||||
|
||||
let { statArray } = this.state;
|
||||
|
||||
console.log(urlSet);
|
||||
|
||||
const urlArray = [];
|
||||
|
||||
urlSet.paramsList.map((data) => {
|
||||
const paramsObj = {
|
||||
from:urlSet.duration[0],
|
||||
to:urlSet.duration[1]
|
||||
}
|
||||
const encodedExtraParams = Object.keys(paramsObj)
|
||||
.map(key => key + '=' + paramsObj[key]).join('&');
|
||||
|
||||
let apiUrl;
|
||||
if(data==="Enrollments"){
|
||||
apiUrl = window.location.origin + config.serverConfig.invoker.uri +
|
||||
config.serverConfig.invoker.deviceMgt +
|
||||
"/reports/devices/count?status=ACTIVE&status=INACTIVE&" + encodedExtraParams;
|
||||
}else{
|
||||
apiUrl = window.location.origin + config.serverConfig.invoker.uri +
|
||||
config.serverConfig.invoker.deviceMgt +
|
||||
"/reports/devices/count?status=REMOVED&" + encodedExtraParams;
|
||||
}
|
||||
|
||||
urlArray.push(axios.get(apiUrl, data));
|
||||
});
|
||||
|
||||
console.log(urlArray)
|
||||
|
||||
|
||||
axios.all(urlArray).then(res => {
|
||||
res.map((response) => {
|
||||
if(response.status === 200){
|
||||
let countData = {item:response.config[0], count:parseInt(response.data.data)}
|
||||
statArray.push(countData);
|
||||
}
|
||||
})
|
||||
this.setState({statArray})
|
||||
}).catch((error) => {
|
||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
||||
//todo display a popup with error
|
||||
message.error('You are not logged in');
|
||||
window.location.href = window.location.origin + '/entgra/login';
|
||||
} else {
|
||||
notification["error"]({
|
||||
message: "There was a problem",
|
||||
duration: 0,
|
||||
description:"Error occurred while trying to get device count.",
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//Call count APIs and get count for given parameters, then create data object to build pie chart
|
||||
getEnrollmentTypeCount = (params, urlSet) => {
|
||||
|
||||
this.setState({loading: true});
|
||||
|
||||
let { statArray } = this.state;
|
||||
|
||||
console.log(urlSet);
|
||||
|
||||
const urlArray = [];
|
||||
|
||||
urlSet.paramsList.map((data) => {
|
||||
const paramsObj = {
|
||||
ownership:data,
|
||||
from:urlSet.duration[0],
|
||||
to:urlSet.duration[1]
|
||||
}
|
||||
const encodedExtraParams = Object.keys(paramsObj)
|
||||
.map(key => key + '=' + paramsObj[key]).join('&');
|
||||
const apiUrl = window.location.origin + config.serverConfig.invoker.uri +
|
||||
config.serverConfig.invoker.deviceMgt +
|
||||
"/reports/devices/count?" + encodedExtraParams;
|
||||
|
||||
urlArray.push(axios.get(apiUrl, data));
|
||||
});
|
||||
|
||||
console.log(urlArray)
|
||||
|
||||
|
||||
axios.all(urlArray).then(res => {
|
||||
res.map((response) => {
|
||||
if(response.status === 200){
|
||||
let countData = {item:response.config[0], count:parseInt(response.data.data)}
|
||||
statArray.push(countData);
|
||||
}
|
||||
})
|
||||
this.setState({statArray})
|
||||
}).catch((error) => {
|
||||
if (error.hasOwnProperty("response") && error.response.status === 401) {
|
||||
//todo display a popup with error
|
||||
message.error('You are not logged in');
|
||||
window.location.href = window.location.origin + '/entgra/login';
|
||||
} else {
|
||||
notification["error"]({
|
||||
message: "There was a problem",
|
||||
duration: 0,
|
||||
description:"Error occurred while trying to get device count.",
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { DataView } = DataSet;
|
||||
const { Html } = Guide;
|
||||
const { statArray , loading} = this.state;
|
||||
|
||||
const dv = new DataView();
|
||||
dv.source(statArray).transform({
|
||||
type: "percent",
|
||||
field: "count",
|
||||
dimension: "item",
|
||||
as: "percent"
|
||||
});
|
||||
const cols = {
|
||||
percent: {
|
||||
formatter: val => {
|
||||
val = val * 100 + "%";
|
||||
return val;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Chart
|
||||
height={window.innerHeight/2}
|
||||
data={dv}
|
||||
scale={cols}
|
||||
padding={[20, 25, 20, 20]}
|
||||
forceFit
|
||||
onPlotClick={this.onChartChange}
|
||||
animate={true}
|
||||
>
|
||||
<Coord type={"theta"} radius={0.75} innerRadius={0.6} />
|
||||
<Axis name="percent" />
|
||||
<Legend
|
||||
position="right"
|
||||
offsetY={-window.innerHeight / 2 + 120}
|
||||
offsetX={-100}
|
||||
/>
|
||||
<Tooltip
|
||||
showTitle={false}
|
||||
itemTpl="<li><span style="background-color:{color};" class="g2-tooltip-marker"></span>{name}: {value}</li>"
|
||||
/>
|
||||
<Guide>
|
||||
<Html
|
||||
position={["50%", "50%"]}
|
||||
html="<div style="color:#8c8c8c;font-size:1.16em;text-align: center;width: 10em;">Total<br><span style="color:#262626;font-size:2.5em">200</span>台</div>"
|
||||
alignX="middle"
|
||||
alignY="middle"
|
||||
/>
|
||||
</Guide>
|
||||
<div onClick={this.clicked}>
|
||||
<Geom
|
||||
type="intervalStack"
|
||||
position="percent"
|
||||
color="item"
|
||||
|
||||
tooltip={[
|
||||
"item*percent",
|
||||
(item, percent) => {
|
||||
percent = percent * 100 + "%";
|
||||
return {
|
||||
name: item,
|
||||
value: percent
|
||||
};
|
||||
}
|
||||
]}
|
||||
style={{
|
||||
lineWidth: 1,
|
||||
stroke: "#fff"
|
||||
}}
|
||||
>
|
||||
<Label
|
||||
content="percent"
|
||||
formatter={(val, item) => {
|
||||
return item.point.item + ": " + val;
|
||||
}}/>
|
||||
</Geom>
|
||||
</div>
|
||||
|
||||
</Chart>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withConfigContext(PieChart);
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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 DeviceTable from "../../../../components/Devices/DevicesTable";
|
||||
import CertificateTable from "../../../../components/Configurations/Certificates/CertificateTable";
|
||||
|
||||
const {Paragraph} = Typography;
|
||||
|
||||
class Certificates extends React.Component {
|
||||
routes;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.routes = props.routes;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<PageHeader style={{paddingTop: 0}}>
|
||||
<Breadcrumb style={{paddingBottom: 16}}>
|
||||
<Breadcrumb.Item>
|
||||
<Link to="/entgra/devices"><Icon type="home"/> Home</Link>
|
||||
</Breadcrumb.Item>
|
||||
<Breadcrumb.Item>Configurations</Breadcrumb.Item>
|
||||
<Breadcrumb.Item>Certificates</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
<div className="wrap">
|
||||
<h3>Certificates</h3>
|
||||
<Paragraph>Certificate configurations</Paragraph>
|
||||
</div>
|
||||
<div style={{backgroundColor: "#ffffff", borderRadius: 5}}>
|
||||
<CertificateTable/>
|
||||
</div>
|
||||
</PageHeader>
|
||||
<div style={{background: '#f0f2f5', padding: 24, minHeight: 720}}>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Certificates;
|
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* 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 {
|
||||
Icon,
|
||||
Col,
|
||||
Row, Select,
|
||||
Radio, Card,
|
||||
Button
|
||||
} from "antd";
|
||||
|
||||
import {Link} from "react-router-dom";
|
||||
import moment from "moment";
|
||||
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
class ReportDurationItemList extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
reportParams:["ACTIVE","INACTIVE","REMOVED"],
|
||||
enrollmentsVsUnenrollmentsParams:["Enrollments", "Unenrollments"],
|
||||
enrollmentTypeParams:["BYOD", "COPE"]
|
||||
}
|
||||
}
|
||||
|
||||
durationItemArray = [
|
||||
{name:"Daily Report", description:"Enrollments of today", duration:[moment().format('YYYY-MM-DD'), moment().add(1, 'days').format('YYYY-MM-DD')]},
|
||||
{name:"Weekly Report", description:"Enrollments of last 7 days", duration:[moment().subtract(6, 'days').format('YYYY-MM-DD'), moment().add(1, 'days').format('YYYY-MM-DD')]},
|
||||
{name:"Monthly Report", description:"Enrollments of last month", duration:[moment().subtract(29, 'days').format('YYYY-MM-DD'), moment().add(1, 'days').format('YYYY-MM-DD')]}]
|
||||
|
||||
|
||||
render(){
|
||||
|
||||
let itemStatus = this.durationItemArray.map((data) =>
|
||||
<Col key={data.name} span={6}>
|
||||
<Link
|
||||
to={{
|
||||
//Path to respective report page
|
||||
pathname: "/entgra/devicestatus",
|
||||
reportData: {
|
||||
duration: data.duration,
|
||||
reportType: data.reportType,
|
||||
params: this.state.reportParams,
|
||||
paramsType: data.paramsType
|
||||
}
|
||||
}}>
|
||||
<Card key={data.name} bordered={true} hoverable={true} style={{borderRadius: 10, marginBottom: 16}}>
|
||||
|
||||
<div align='center'>
|
||||
<Icon type="desktop" style={{ fontSize: '25px', color: '#08c' }}/>
|
||||
<h2><b>{data.name}</b></h2>
|
||||
<p>{data.description}</p>
|
||||
{/*<p>{data.duration}</p>*/}
|
||||
</div>
|
||||
</Card>
|
||||
</Link>
|
||||
</Col>
|
||||
);
|
||||
|
||||
let itemEnrollmentsVsUnenrollments = this.durationItemArray.map((data) =>
|
||||
<Col key={data.name} span={6}>
|
||||
<Link
|
||||
to={{
|
||||
//Path to respective report page
|
||||
pathname: "/entgra/enrollmentsvsunenrollments",
|
||||
reportData: {
|
||||
duration: data.duration,
|
||||
reportType: data.reportType,
|
||||
params: this.state.enrollmentsVsUnenrollmentsParams,
|
||||
paramsType: data.paramsType
|
||||
}
|
||||
}}>
|
||||
<Card key={data.name} bordered={true} hoverable={true} style={{borderRadius: 10, marginBottom: 16}}>
|
||||
|
||||
<div align='center'>
|
||||
<Icon type="desktop" style={{ fontSize: '25px', color: '#08c' }}/>
|
||||
<h2><b>{data.name}</b></h2>
|
||||
<p>{data.description}</p>
|
||||
</div>
|
||||
</Card>
|
||||
</Link>
|
||||
</Col>
|
||||
);
|
||||
|
||||
let itemEnrollmentType = this.durationItemArray.map((data) =>
|
||||
<Col key={data.name} span={6}>
|
||||
<Link
|
||||
to={{
|
||||
//Path to respective report page
|
||||
pathname: "/entgra/enrollmenttype",
|
||||
reportData: {
|
||||
duration: data.duration,
|
||||
reportType: data.reportType,
|
||||
params: this.state.enrollmentTypeParams,
|
||||
paramsType: data.paramsType
|
||||
}
|
||||
}}>
|
||||
<Card key={data.name} bordered={true} hoverable={true} style={{borderRadius: 10, marginBottom: 16}}>
|
||||
|
||||
<div align='center'>
|
||||
<Icon type="desktop" style={{ fontSize: '25px', color: '#08c' }}/>
|
||||
<h2><b>{data.name}</b></h2>
|
||||
<p>{data.description}</p>
|
||||
</div>
|
||||
</Card>
|
||||
</Link>
|
||||
</Col>
|
||||
);
|
||||
return(
|
||||
<div>
|
||||
<div style={{borderRadius: 5}}>
|
||||
<Row gutter={16} >
|
||||
{itemStatus}
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
<div style={{borderRadius: 5}}>
|
||||
<Row gutter={16} >
|
||||
{itemEnrollmentsVsUnenrollments}
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
<div style={{borderRadius: 5}}>
|
||||
<Row gutter={16} >
|
||||
{itemEnrollmentType}
|
||||
</Row>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ReportDurationItemList;
|
Loading…
Reference in new issue