Merge branch 'application-mgt-new' into 'application-mgt-new'

Add main devicemgt features to dashboard

See merge request entgra/carbon-device-mgt!333
feature/appm-store/pbac
Dharmakeerthi Lasantha 5 years ago
commit edf9486a6d

@ -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": {

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 48 KiB

@ -67,18 +67,53 @@ class App extends React.Component {
axios.get(
window.location.origin + "/entgra/public/conf/config.json",
).then(res => {
console.log(res);
const config = res.data;
this.checkUserLoggedIn(config);
}).catch((error) => {
this.setState({
loading: false,
config: res.data
error: true
})
});
}
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;

@ -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) =>
<Col span={8} key={data.id}>
<Card hoverable title="Device Type" bordered={true}>
{data.name}
</Card>
</Col>
);
return (
<div style={{ background: '#ECECEC', padding: '30px' }}>
<Row gutter={16}>
{itemCard}
</Row>
</div>
);
}
}
export default withConfigContext(DeviceTypesTable);

@ -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.",
});
}

@ -112,18 +112,7 @@ const columns = [
return <Tooltip title={new Date(dateOfLastUpdate).toString()}>{timeAgoString}</Tooltip>;
}
// todo add filtering options
},
{
title: 'Action',
key: 'action',
render: () => (
<span>
<a><Icon type="edit" /></a>
<Divider type="vertical" />
<a><Text type="danger"><Icon type="delete" /></Text></a>
</span>
),
},
}
];
const getTimeAgo = (time) => {

@ -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 (
<div>
<Table
columns={columns}
rowKey={record => (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}}
/>
</div>
);
}
}
export default withConfigContext(GroupsTable);

@ -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) =>
<Col span={8} key={data}>
<Card hoverable title="Role" bordered={true}>
{data}
</Card>
</Col>
);
return (
<div style={{ background: '#ECECEC', padding: '30px' }}>
<Row gutter={16}>
{itemCard}
</Row>
</div>
);
}
}
export default withConfigContext(RolesTable);

@ -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) =>
<Col span={8} key={data.username}>
<Card hoverable title="User Name" bordered={true}>
{data.username}
</Card>
</Col>
);
return (
<div style={{ background: '#ECECEC', padding: '30px' }}>
<Row gutter={16}>
{itemCard}
</Row>
</div>
);
}
}
export default withConfigContext(UsersTable);

@ -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
}
]
}

@ -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) {

@ -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 {
>
<div className="logo-image">
<Link to="/entgra/devices"><img alt="logo" src={this.logo}/>
<span className="brand">Entgra</span></Link>
<Link to="/entgra/devices"><img alt="logo" src={this.logo}/></Link>
</div>
<Menu theme="dark" mode="inline" defaultSelectedKeys={['devices']}>
<Menu.Item key="devices">
@ -85,6 +86,36 @@ class Dashboard extends React.Component {
<span>Reports</span>
</Link>
</Menu.Item>
<Menu.Item key="groups">
<Link to="/entgra/groups">
<Icon type="deployment-unit"/>
<span>Groups</span>
</Link>
</Menu.Item>
<Menu.Item key="users">
<Link to="/entgra/users">
<Icon type="user"/>
<span>Users</span>
</Link>
</Menu.Item>
<Menu.Item key="policies">
<Link to="/entgra/policies">
<Icon type="audit"/>
<span>Policies</span>
</Link>
</Menu.Item>
<Menu.Item key="roles">
<Link to="/entgra/roles">
<Icon type="book"/>
<span>Roles</span>
</Link>
</Menu.Item>
<Menu.Item key="devicetypes">
<Link to="/entgra/devicetypes">
<Icon type="desktop"/>
<span>Device Types</span>
</Link>
</Menu.Item>
</Menu>
</Sider>
@ -109,9 +140,8 @@ class Dashboard extends React.Component {
title={
<span className="submenu-title-wrapper">
<Icon type="user"/>
</span>
}
>
{this.config.user}
</span> }>
<Logout/>
</SubMenu>

@ -0,0 +1,65 @@
/*
* 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 (
<div>
<PageHeader style={{paddingTop: 0}}>
<Breadcrumb style={{paddingBottom: 16}}>
<Breadcrumb.Item>
<Link to="/entgra"><Icon type="home"/> Home</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>Device Types</Breadcrumb.Item>
</Breadcrumb>
<div className="wrap">
<h3>Device Types</h3>
<Paragraph>All device types for device management.</Paragraph>
</div>
<div style={{backgroundColor:"#ffffff", borderRadius: 5}}>
<DeviceTypesTable/>
</div>
</PageHeader>
<div style={{background: '#f0f2f5', padding: 24, minHeight: 720}}>
</div>
</div>
);
}
}
export default DeviceTypes;

@ -49,8 +49,7 @@ class Devices extends React.Component {
</Breadcrumb>
<div className="wrap">
<h3>Devices</h3>
<Paragraph>Lorem ipsum dolor sit amet, est similique constituto at, quot inermis id mel, an
illud incorrupte nam.</Paragraph>
<Paragraph>All enrolled devices</Paragraph>
</div>
<div style={{backgroundColor:"#ffffff", borderRadius: 5}}>
<DeviceTable/>

@ -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";
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 (
<div>
<PageHeader style={{paddingTop: 0}}>
<Breadcrumb style={{paddingBottom: 16}}>
<Breadcrumb.Item>
<Link to="/entgra"><Icon type="home"/> Home</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>Groups</Breadcrumb.Item>
</Breadcrumb>
<div className="wrap">
<h3>Groups</h3>
<Paragraph>All device groups.</Paragraph>
</div>
<div style={{backgroundColor:"#ffffff", borderRadius: 5}}>
<GroupsTable/>
</div>
</PageHeader>
</div>
);
}
}
export default Groups;

@ -0,0 +1,61 @@
/*
* 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 (
<div>
<PageHeader style={{paddingTop: 0}}>
<Breadcrumb style={{paddingBottom: 16}}>
<Breadcrumb.Item>
<Link to="/entgra"><Icon type="home"/> Home</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>Policies</Breadcrumb.Item>
</Breadcrumb>
<div className="wrap">
<h3>Policies</h3>
<Paragraph>All policies for device management</Paragraph>
</div>
<div style={{backgroundColor:"#ffffff", borderRadius: 5}}>
</div>
</PageHeader>
</div>
);
}
}
export default Policies;

@ -0,0 +1,65 @@
/*
* 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 (
<div>
<PageHeader style={{paddingTop: 0}}>
<Breadcrumb style={{paddingBottom: 16}}>
<Breadcrumb.Item>
<Link to="/entgra"><Icon type="home"/> Home</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>Roles</Breadcrumb.Item>
</Breadcrumb>
<div className="wrap">
<h3>Roles</h3>
<Paragraph>All user roles</Paragraph>
</div>
<div style={{backgroundColor:"#ffffff", borderRadius: 5}}>
<RolesTable/>
</div>
</PageHeader>
<div style={{background: '#f0f2f5', padding: 24, minHeight: 720}}>
</div>
</div>
);
}
}
export default Roles;

@ -0,0 +1,65 @@
/*
* 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 (
<div>
<PageHeader style={{paddingTop: 0}}>
<Breadcrumb style={{paddingBottom: 16}}>
<Breadcrumb.Item>
<Link to="/entgra"><Icon type="home"/> Home</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>Users</Breadcrumb.Item>
</Breadcrumb>
<div className="wrap">
<h3>Users</h3>
<Paragraph>All users for device management.</Paragraph>
</div>
<div style={{backgroundColor:"#ffffff", borderRadius: 5}}>
<UsersTable/>
</div>
</PageHeader>
<div style={{background: '#f0f2f5', padding: 24, minHeight: 720}}>
</div>
</div>
);
}
}
export default Users;
Loading…
Cancel
Save