Merge branch 'master' into 'master'

Add UI components to Assign policy Type, Assign Groups and Publish Policy view

See merge request entgra/carbon-device-mgt!460
4.x.x
Dharmakeerthi Lasantha 5 years ago
commit 23b68c0b1e

@ -0,0 +1,232 @@
/*
* 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 { withConfigContext } from '../../../../../../../../components/ConfigContext';
import { Button, Col, Form, message, notification, Radio, Select } from 'antd';
import axios from 'axios';
const { Option } = Select;
class AssignGroups extends React.Component {
constructor(props) {
super(props);
this.config = this.props.context;
this.userSelector = React.createRef();
this.roleSelector = React.createRef();
this.state = {
roles: [],
users: [],
groups: [],
};
}
componentDidMount() {
this.getRolesList();
this.getGroupsList();
}
handleSetUserRoleFormItem = event => {
if (event.target.value === 'roleSelector') {
this.roleSelector.current.style.cssText = 'display: block;';
this.userSelector.current.style.cssText = 'display: none;';
} else {
this.roleSelector.current.style.cssText = 'display: none;';
this.userSelector.current.style.cssText = 'display: block;';
}
};
getRolesList = () => {
let apiURL =
window.location.origin +
this.config.serverConfig.invoker.uri +
this.config.serverConfig.invoker.deviceMgt +
'/roles?user-store=PRIMARY&limit=100';
axios
.get(apiURL)
.then(res => {
if (res.status === 200) {
this.setState({
roles: 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.',
});
}
});
};
getUsersList = value => {
let apiURL =
window.location.origin +
this.config.serverConfig.invoker.uri +
this.config.serverConfig.invoker.deviceMgt +
'/users/search/usernames?filter=' +
value +
'&domain=Primary';
axios
.get(apiURL)
.then(res => {
if (res.status === 200) {
let users = JSON.parse(res.data.data);
this.setState({
users,
});
}
})
.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.',
});
}
});
};
// fetch data from api
getGroupsList = () => {
let apiUrl =
window.location.origin +
this.config.serverConfig.invoker.uri +
this.config.serverConfig.invoker.deviceMgt +
'/admin/groups';
// send request to the invokerss
axios
.get(apiUrl)
.then(res => {
if (res.status === 200) {
this.setState({
groups: res.data.data.deviceGroups,
});
}
})
.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.',
});
}
});
};
render() {
const { getFieldDecorator } = this.props.form;
return (
<div>
<div>
<Radio.Group
defaultValue={'roleSelector'}
onChange={this.handleSetUserRoleFormItem}
>
<Radio value="roleSelector">Set User role(s)</Radio>
<Radio value="userSelector">Set User(s)</Radio>
</Radio.Group>
<div
id={'roleSelector'}
ref={this.roleSelector}
style={{ display: 'block' }}
>
<Form.Item>
{getFieldDecorator('roles', {})(
<Select
mode="multiple"
style={{ width: '100%' }}
defaultActiveFirstOption={true}
>
<Option value={'ANY'}>Any</Option>
{this.state.roles.map(role => (
<Option key={role} value={role}>
{role}
</Option>
))}
</Select>,
)}
</Form.Item>
</div>
<div
id={'userSelector'}
ref={this.userSelector}
style={{ display: 'none' }}
>
<Form.Item>
{getFieldDecorator('users', {})(
<Select
mode="multiple"
style={{ width: '100%' }}
onSearch={this.getUsersList}
>
{this.state.users.map(user => (
<Option key={user.username} value={user.username}>
{user.username}
</Option>
))}
</Select>,
)}
</Form.Item>
</div>
</div>
<Form.Item label={'Select Groups'} style={{ display: 'block' }}>
{getFieldDecorator('deviceGroups', {})(
<Select mode="multiple" style={{ width: '100%' }}>
<Option value={'NONE'}>NONE</Option>
{this.state.groups.map(group => (
<Option key={group.name} value={group.name}>
{group.name}
</Option>
))}
</Select>,
)}
</Form.Item>
<Col span={16} offset={20}>
<div style={{ marginTop: 24 }}>
<Button style={{ marginRight: 8 }} onClick={this.props.getPrevStep}>
Back
</Button>
<Button type="primary" onClick={this.props.getNextStep}>
Continue
</Button>
</div>
</Col>
</div>
);
}
}
export default withConfigContext(Form.create()(AssignGroups));

@ -62,8 +62,6 @@ class ConfigureProfile extends React.Component {
}; };
} }
componentDidMount() {}
// convert time from 24h format to 12h format // convert time from 24h format to 12h format
timeConverter = time => { timeConverter = time => {
time = time time = time
@ -673,11 +671,6 @@ class ConfigureProfile extends React.Component {
const { policyUIConfigurationsList } = this.props; const { policyUIConfigurationsList } = this.props;
return ( return (
<div className="tab-container"> <div className="tab-container">
{/* <div>*/}
{/* <Select style={{ width: 200 }}>*/}
{/* {this.getOptionForTimeSelectors(1440, 1410, 30)}*/}
{/* </Select>*/}
{/* </div>*/}
<Tabs tabPosition={'left'} size={'large'}> <Tabs tabPosition={'left'} size={'large'}>
{policyUIConfigurationsList.map((element, i) => { {policyUIConfigurationsList.map((element, i) => {
return ( return (
@ -729,6 +722,16 @@ class ConfigureProfile extends React.Component {
); );
})} })}
</Tabs> </Tabs>
<Col span={16} offset={20}>
<div style={{ marginTop: 24 }}>
<Button style={{ marginRight: 8 }} onClick={this.props.getPrevStep}>
Back
</Button>
<Button type="primary" onClick={this.props.getNextStep}>
Continue
</Button>
</div>
</Col>
</div> </div>
); );
} }

@ -0,0 +1,65 @@
/*
* 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 { withConfigContext } from '../../../../../../../../components/ConfigContext';
import { Button, Col, Form, Input } from 'antd';
const { TextArea } = Input;
class PublishDevices extends React.Component {
constructor(props) {
super(props);
this.config = this.props.context;
}
render() {
const { getFieldDecorator } = this.props.form;
return (
<div>
<Form.Item
label={'Set a name to your policy *'}
style={{ display: 'block' }}
>
{getFieldDecorator('policyName', {
rules: [
{
pattern: new RegExp('^.{1,30}$'),
message: 'Should be 1-to-30 characters long',
},
],
})(<Input placeholder={'Should be 1 to 30 characters long'} />)}
</Form.Item>
<Form.Item label={'Add a Description'} style={{ display: 'block' }}>
{getFieldDecorator('description', {})(<TextArea rows={8} />)}
</Form.Item>
<Col span={16} offset={18}>
<div style={{ marginTop: 24 }}>
<Button style={{ marginRight: 8 }} onClick={this.props.getPrevStep}>
Back
</Button>
<Button type="primary" style={{ marginRight: 8 }}>
Save & Publish
</Button>
<Button type="primary">Save</Button>
</div>
</Col>
</div>
);
}
}
export default withConfigContext(Form.create()(PublishDevices));

@ -31,14 +31,12 @@ class SelectPlatform extends React.Component {
this.config = this.props.context; this.config = this.props.context;
this.state = { this.state = {
data: [], data: [],
pagination: {},
loading: false, loading: false,
selectedRows: [],
}; };
} }
componentDidMount() { componentDidMount() {
this.fetchUsers(); this.getDeviceTypes();
} }
onClickCard = (e, type) => { onClickCard = (e, type) => {
@ -46,7 +44,7 @@ class SelectPlatform extends React.Component {
}; };
// fetch data from api // fetch data from api
fetchUsers = (params = {}) => { getDeviceTypes() {
this.setState({ loading: true }); this.setState({ loading: true });
let apiUrl = let apiUrl =
@ -55,16 +53,14 @@ class SelectPlatform extends React.Component {
this.config.serverConfig.invoker.deviceMgt + this.config.serverConfig.invoker.deviceMgt +
'/device-types'; '/device-types';
// send request to the invokerss // send request to the invokers
axios axios
.get(apiUrl) .get(apiUrl)
.then(res => { .then(res => {
if (res.status === 200) { if (res.status === 200) {
const pagination = { ...this.state.pagination };
this.setState({ this.setState({
loading: false, loading: false,
data: JSON.parse(res.data.data), data: JSON.parse(res.data.data),
pagination,
}); });
} }
}) })
@ -83,22 +79,7 @@ class SelectPlatform extends React.Component {
this.setState({ loading: false }); 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() { render() {
const { data } = this.state; const { data } = this.state;

@ -0,0 +1,155 @@
/*
* 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,
Col,
Form,
Icon,
message,
notification,
Radio,
Select,
Tooltip,
} from 'antd';
import { withConfigContext } from '../../../../../../../../components/ConfigContext';
import axios from 'axios';
const { Option } = Select;
class SelectPolicyType extends React.Component {
constructor(props) {
super(props);
this.config = this.props.context;
this.state = {
correctivePoliciesList: [],
};
}
componentDidMount() {
this.fetchPolicies();
}
fetchPolicies = () => {
let apiUrl =
window.location.origin +
this.config.serverConfig.invoker.uri +
this.config.serverConfig.invoker.deviceMgt +
'/policies';
// send request to the invokerss
axios
.get(apiUrl)
.then(res => {
if (res.status === 200) {
let policies = res.data.data.policies;
let correctivePolicies = [];
for (let i = 0; i < policies.length; i++) {
if (policies[i].policyType === 'CORRECTIVE') {
correctivePolicies.push(
<Option key={policies[i].profileId}>
{policies[i].policyName}
</Option>,
);
}
}
this.setState({
correctivePoliciesList: correctivePolicies,
});
}
})
.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 });
});
};
handlePolicyTypes = event => {
if (event.target.value === 'GENERAL') {
document.getElementById('generalPolicySubPanel').style.display = 'block';
} else {
document.getElementById('generalPolicySubPanel').style.display = 'none';
}
};
render() {
const { getFieldDecorator } = this.props.form;
return (
<div>
<Form.Item style={{ display: 'block' }}>
{getFieldDecorator('policyType', {
initialValue: 'GENERAL',
})(
<Radio.Group onChange={this.handlePolicyTypes}>
<Radio value="GENERAL">General Policy</Radio>
<Radio value="CORRECTIVE">Corrective Policy</Radio>
</Radio.Group>,
)}
</Form.Item>
<div id="generalPolicySubPanel" style={{ display: 'block' }}>
<Form.Item
label={
<span>
Select Corrective Policy&nbsp;
<Tooltip
title={
'Select the corrective policy to be applied when this general policy is violated'
}
placement="right"
>
<Icon type="question-circle-o" />
</Tooltip>
</span>
}
>
{getFieldDecorator('correctiveActions', {
initialValue: 'NONE',
})(
<Select style={{ width: '100%' }}>
<Option value="NONE">None</Option>
{this.state.correctivePoliciesList}
</Select>,
)}
</Form.Item>
</div>
<Col span={16} offset={20}>
<div style={{ marginTop: 24 }}>
<Button style={{ marginRight: 8 }} onClick={this.props.getPrevStep}>
Back
</Button>
<Button type="primary" onClick={this.props.getNextStep}>
Continue
</Button>
</div>
</Col>
</div>
);
}
}
export default withConfigContext(Form.create()(SelectPolicyType));

@ -17,19 +17,13 @@
*/ */
import React from 'react'; import React from 'react';
import { import { Form, Row, Col, Card, Steps, message, notification } from 'antd';
Button,
Form,
Row,
Col,
Card,
Steps,
message,
notification,
} from 'antd';
import { withConfigContext } from '../../../../../../components/ConfigContext'; import { withConfigContext } from '../../../../../../components/ConfigContext';
import SelectPlatform from './components/SelectPlatform'; import SelectPlatform from './components/SelectPlatform';
import ConfigureProfile from './components/ConfigureProfile'; import ConfigureProfile from './components/ConfigureProfile';
import SelectPolicyType from './components/SelectPolicyType';
import AssignGroups from './components/AssignGroups';
import PublishDevices from './components/PublishDevices';
import axios from 'axios'; import axios from 'axios';
const { Step } = Steps; const { Step } = Steps;
@ -82,12 +76,12 @@ class AddPolicy extends React.Component {
}); });
}; };
onHandleNext = () => { getNextStep = () => {
const currentStepIndex = this.state.currentStepIndex + 1; const currentStepIndex = this.state.currentStepIndex + 1;
this.setState({ currentStepIndex }); this.setState({ currentStepIndex });
}; };
onHandlePrev = () => { getPrevStep = () => {
const currentStepIndex = this.state.currentStepIndex - 1; const currentStepIndex = this.state.currentStepIndex - 1;
this.setState({ currentStepIndex }); this.setState({ currentStepIndex });
}; };
@ -104,7 +98,6 @@ class AddPolicy extends React.Component {
<Step key="PolicyType" title="Select policy type" /> <Step key="PolicyType" title="Select policy type" />
<Step key="AssignGroups" title="Assign to groups" /> <Step key="AssignGroups" title="Assign to groups" />
<Step key="Publish" title="Publish to devices" /> <Step key="Publish" title="Publish to devices" />
<Step key="Result" title="Result" />
</Steps> </Steps>
</Col> </Col>
<Col span={16} offset={4}> <Col span={16} offset={4}>
@ -121,40 +114,33 @@ class AddPolicy extends React.Component {
> >
<ConfigureProfile <ConfigureProfile
policyUIConfigurationsList={policyUIConfigurationsList} policyUIConfigurationsList={policyUIConfigurationsList}
getPrevStep={this.getPrevStep}
getNextStep={this.getNextStep}
/> />
</div> </div>
<div <div
style={{ display: currentStepIndex === 2 ? 'unset' : 'none' }} style={{ display: currentStepIndex === 2 ? 'unset' : 'none' }}
></div> >
<SelectPolicyType
getPrevStep={this.getPrevStep}
getNextStep={this.getNextStep}
/>
</div>
<div <div
style={{ display: currentStepIndex === 3 ? 'unset' : 'none' }} style={{ display: currentStepIndex === 3 ? 'unset' : 'none' }}
></div> >
<AssignGroups
getPrevStep={this.getPrevStep}
getNextStep={this.getNextStep}
/>
</div>
<div <div
style={{ display: currentStepIndex === 4 ? 'unset' : 'none' }} style={{ display: currentStepIndex === 4 ? 'unset' : 'none' }}
></div> >
<div <PublishDevices getPrevStep={this.getPrevStep} />
style={{ display: currentStepIndex === 5 ? 'unset' : 'none' }} </div>
></div>
</Card> </Card>
</Col> </Col>
<Col span={16} offset={4}>
<div style={{ marginTop: 24 }}>
{currentStepIndex > 0 && (
<Button
style={{ marginRight: 8 }}
onClick={() => this.onHandlePrev()}
>
Previous
</Button>
)}
{currentStepIndex > 0 && currentStepIndex < 5 && (
<Button type="primary" onClick={() => this.onHandleNext()}>
Next
</Button>
)}
{currentStepIndex === 5 && <Button type="primary">Done</Button>}
</div>
</Col>
</Row> </Row>
</div> </div>
); );

Loading…
Cancel
Save