forked from community/device-mgt-core
Implement create, apply, edit, view policy features to device-mgt React App See merge request entgra/carbon-device-mgt!483feature/appm-store/pbac
commit
66722ed71e
@ -0,0 +1,269 @@
|
|||||||
|
/*
|
||||||
|
* 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;';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// generate payload by adding Assign Groups
|
||||||
|
onHandleContinue = (e, formName) => {
|
||||||
|
this.props.form.validateFields((err, values) => {
|
||||||
|
if (!err) {
|
||||||
|
if (typeof values.roles === 'string') {
|
||||||
|
values.roles = [values.roles];
|
||||||
|
}
|
||||||
|
if (!values.users) {
|
||||||
|
delete values.users;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values.deviceGroups === 'NONE') {
|
||||||
|
delete values.deviceGroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.props.getPolicyPayloadData(formName, values);
|
||||||
|
this.props.getNextStep();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
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 { policyData } = this.props;
|
||||||
|
const { getFieldDecorator } = this.props.form;
|
||||||
|
let deviceGroups = null;
|
||||||
|
if (policyData.deviceGroups.length > 0) {
|
||||||
|
deviceGroups = policyData.deviceGroups;
|
||||||
|
} else {
|
||||||
|
deviceGroups = 'NONE';
|
||||||
|
}
|
||||||
|
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', {
|
||||||
|
initialValue: policyData.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', {
|
||||||
|
initialValue: policyData.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', {
|
||||||
|
initialValue: 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={e => this.onHandleContinue(e, 'groupData')}
|
||||||
|
>
|
||||||
|
Continue
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(Form.create()(AssignGroups));
|
@ -0,0 +1,873 @@
|
|||||||
|
/*
|
||||||
|
* 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 {
|
||||||
|
Tabs,
|
||||||
|
Row,
|
||||||
|
Col,
|
||||||
|
Switch,
|
||||||
|
Input,
|
||||||
|
Typography,
|
||||||
|
Form,
|
||||||
|
Collapse,
|
||||||
|
Checkbox,
|
||||||
|
Select,
|
||||||
|
Tooltip,
|
||||||
|
Icon,
|
||||||
|
Table,
|
||||||
|
Alert,
|
||||||
|
Upload,
|
||||||
|
Popconfirm,
|
||||||
|
Button,
|
||||||
|
Radio,
|
||||||
|
} from 'antd';
|
||||||
|
import { withConfigContext } from '../../../../../../../../components/ConfigContext';
|
||||||
|
import '../../../../styles.css';
|
||||||
|
import moment from 'moment';
|
||||||
|
const { Text, Title, Paragraph } = Typography;
|
||||||
|
const { TabPane } = Tabs;
|
||||||
|
const { Option } = Select;
|
||||||
|
const { TextArea } = Input;
|
||||||
|
|
||||||
|
const subPanelpayloadAttributes = {};
|
||||||
|
|
||||||
|
class ConfigureProfile extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.config = this.props.context;
|
||||||
|
this.state = {
|
||||||
|
loading: false,
|
||||||
|
activePanelKeys: [],
|
||||||
|
activeSubPanelKeys: [],
|
||||||
|
subFormList: [],
|
||||||
|
subPanelpayloadAttributes: {},
|
||||||
|
customInputDataArray: [],
|
||||||
|
inputTableDataSources: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
setProfileInfo = e => {
|
||||||
|
let activePolicies = [];
|
||||||
|
let activePolicyFields = {};
|
||||||
|
const allFields = this.props.form.getFieldsValue();
|
||||||
|
this.props.policyFeatureList.map(element => {
|
||||||
|
activePolicies.push(element.featureCode);
|
||||||
|
let featureData = JSON.parse(element.content);
|
||||||
|
Object.keys(featureData).map(key => {
|
||||||
|
let regex = new RegExp(`${element.featureCode}.+${key}`, 'g');
|
||||||
|
Object.keys(allFields).map(fieldName => {
|
||||||
|
if (fieldName.match(regex) != null) {
|
||||||
|
activePolicyFields[fieldName] = featureData[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.props.form.setFieldsValue(activePolicyFields);
|
||||||
|
this.setState({
|
||||||
|
activePanelKeys: activePolicies,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// convert time from 24h format to 12h format
|
||||||
|
timeConverter = time => {
|
||||||
|
time = time
|
||||||
|
.toString()
|
||||||
|
.match(/^([01]\d|2[0-3])(:)([0-5]\d)(:[0-5]\d)?$/) || [time];
|
||||||
|
if (time.length > 1) {
|
||||||
|
time = time.slice(1);
|
||||||
|
time[5] = +time[0] < 12 ? ' AM' : ' PM';
|
||||||
|
time[0] = +time[0] % 12 || 12;
|
||||||
|
}
|
||||||
|
return time.join('');
|
||||||
|
};
|
||||||
|
|
||||||
|
// get Option value from start Time, end Time and time difference between 2 values
|
||||||
|
getOptionForTimeSelectors = (startTimeValue, endTimeValue, timeIncrement) => {
|
||||||
|
let timeOptions = [];
|
||||||
|
let time = new Date(
|
||||||
|
moment()
|
||||||
|
.startOf('day')
|
||||||
|
.format('YYYY/MM/DD'),
|
||||||
|
);
|
||||||
|
let tempValue = startTimeValue;
|
||||||
|
time.setMinutes(time.getMinutes() + tempValue);
|
||||||
|
let startOption = (
|
||||||
|
<Option value={String(tempValue)}>
|
||||||
|
{this.timeConverter(
|
||||||
|
`${String(time)
|
||||||
|
.split(' ')[4]
|
||||||
|
.substring(0, 5)}`,
|
||||||
|
)}
|
||||||
|
</Option>
|
||||||
|
);
|
||||||
|
timeOptions.push(startOption);
|
||||||
|
|
||||||
|
while (tempValue !== endTimeValue) {
|
||||||
|
time = new Date(
|
||||||
|
moment()
|
||||||
|
.startOf('day')
|
||||||
|
.format('YYYY/MM/DD'),
|
||||||
|
);
|
||||||
|
tempValue += timeIncrement;
|
||||||
|
if (tempValue > 1440) {
|
||||||
|
tempValue = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
time.setMinutes(time.getMinutes() + tempValue);
|
||||||
|
let option = (
|
||||||
|
<Option value={String(tempValue)}>
|
||||||
|
{this.timeConverter(
|
||||||
|
`${String(time)
|
||||||
|
.split(' ')[4]
|
||||||
|
.substring(0, 5)}`,
|
||||||
|
)}
|
||||||
|
</Option>
|
||||||
|
);
|
||||||
|
timeOptions.push(option);
|
||||||
|
}
|
||||||
|
return timeOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
// handle items which handle from radio buttons
|
||||||
|
handleRadioPanel = (e, subPanel) => {
|
||||||
|
{
|
||||||
|
subPanel.map((panel, i) => {
|
||||||
|
if (panel.value === e.target.value) {
|
||||||
|
document.getElementById(panel.value).style.display = 'block';
|
||||||
|
} else {
|
||||||
|
document.getElementById(panel.value).style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// handle items which handle from select options
|
||||||
|
handleSelectedPanel = (e, subPanel) => {
|
||||||
|
{
|
||||||
|
subPanel.map((panel, i) => {
|
||||||
|
if (panel.id === e) {
|
||||||
|
document.getElementById(panel.id).style.display = 'block';
|
||||||
|
} else {
|
||||||
|
document.getElementById(panel.id).style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// handle items which handle from checkbox
|
||||||
|
handleSubPanel = e => {
|
||||||
|
if (e.target.checked) {
|
||||||
|
let joined = this.state.activeSubPanelKeys.concat(e.target.id);
|
||||||
|
this.setState({ activeSubPanelKeys: joined });
|
||||||
|
} else {
|
||||||
|
let index = this.state.activeSubPanelKeys.indexOf(e.target.id);
|
||||||
|
if (index !== -1) {
|
||||||
|
this.state.activeSubPanelKeys.splice(index, 1);
|
||||||
|
let removed = this.state.activeSubPanelKeys;
|
||||||
|
this.setState({ activeSubPanelKeys: removed });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// handle Switch on off button
|
||||||
|
handleMainPanel = (e, ref) => {
|
||||||
|
if (e) {
|
||||||
|
let joined = this.state.activePanelKeys.concat(ref);
|
||||||
|
this.setState({ activePanelKeys: joined });
|
||||||
|
} else {
|
||||||
|
let index = this.state.activePanelKeys.indexOf(ref);
|
||||||
|
if (index !== -1) {
|
||||||
|
this.state.activePanelKeys.splice(index, 1);
|
||||||
|
let removed = this.state.activePanelKeys;
|
||||||
|
this.setState({ activePanelKeys: removed });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleCustomInputTable = event => {
|
||||||
|
const { count, customInputDataArray } = this.state;
|
||||||
|
|
||||||
|
const newData = [
|
||||||
|
{
|
||||||
|
key: count,
|
||||||
|
CERT_NAME: `${event.file.name}`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
this.setState({
|
||||||
|
customInputDataArray: [...customInputDataArray, newData],
|
||||||
|
count: count + 1,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleAdd = array => {
|
||||||
|
const { count, inputTableDataSources } = this.state;
|
||||||
|
const newData = [
|
||||||
|
{
|
||||||
|
key: count,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
inputTableDataSources[array].push(newData);
|
||||||
|
Object.defineProperty(inputTableDataSources, array, {
|
||||||
|
value: inputTableDataSources[array],
|
||||||
|
});
|
||||||
|
this.setState({
|
||||||
|
inputTableDataSources,
|
||||||
|
count: count + 1,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
getColumns = ({ getFieldDecorator }, arr) => {
|
||||||
|
const columnArray = [];
|
||||||
|
const actionColumn = [
|
||||||
|
{
|
||||||
|
title: '',
|
||||||
|
dataIndex: 'operation',
|
||||||
|
render: (name, row) => (
|
||||||
|
<Form.Item>
|
||||||
|
<Popconfirm title="Sure to delete?">
|
||||||
|
<a>
|
||||||
|
<Text type="danger">
|
||||||
|
<Icon type="delete" />
|
||||||
|
</Text>
|
||||||
|
</a>
|
||||||
|
</Popconfirm>
|
||||||
|
</Form.Item>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
Object.values(arr).map((columnData, c) => {
|
||||||
|
if (columnData.type === 'input') {
|
||||||
|
const column = {
|
||||||
|
title: `${columnData.name}`,
|
||||||
|
dataIndex: `${columnData.key}`,
|
||||||
|
key: `${columnData.key}`,
|
||||||
|
render: (name, row, i) => (
|
||||||
|
<Form.Item>
|
||||||
|
{getFieldDecorator(`${columnData.key}${i}`, {})(
|
||||||
|
<Input
|
||||||
|
type={columnData.others.inputType}
|
||||||
|
placeholder={columnData.others.placeholder}
|
||||||
|
/>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
columnArray.push(column);
|
||||||
|
} else if (columnData.type === 'upload') {
|
||||||
|
const column = {
|
||||||
|
title: `${columnData.name}`,
|
||||||
|
dataIndex: `${columnData.key}`,
|
||||||
|
key: `${columnData.key}`,
|
||||||
|
render: (name, row, i) => (
|
||||||
|
<Form.Item>
|
||||||
|
{getFieldDecorator(`${columnData.key}${i}`, {})(
|
||||||
|
<Upload>
|
||||||
|
<Button>
|
||||||
|
<Icon type="upload" /> Choose file
|
||||||
|
</Button>
|
||||||
|
</Upload>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
columnArray.push(column);
|
||||||
|
} else if (columnData.type === 'select') {
|
||||||
|
const column = {
|
||||||
|
title: `${columnData.name}`,
|
||||||
|
dataIndex: `${columnData.key}`,
|
||||||
|
key: `${columnData.key}`,
|
||||||
|
render: (name, row, i) => (
|
||||||
|
<Form.Item>
|
||||||
|
{getFieldDecorator(`${columnData.key}${i}`, {
|
||||||
|
initialValue: columnData.others.initialDataIndex,
|
||||||
|
})(
|
||||||
|
<Select>
|
||||||
|
{columnData.others.option.map((option, i) => {
|
||||||
|
return (
|
||||||
|
<Option key={i} value={option.key}>
|
||||||
|
{option.value}
|
||||||
|
</Option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
columnArray.push(column);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const columns = columnArray.concat(actionColumn);
|
||||||
|
return columns;
|
||||||
|
};
|
||||||
|
|
||||||
|
// generate payload by adding policy configurations
|
||||||
|
onHandleContinue = (e, formname) => {
|
||||||
|
const allFields = this.props.form.getFieldsValue();
|
||||||
|
let activeFields = [];
|
||||||
|
// get currently active field list
|
||||||
|
for (let i = 0; i < this.state.activePanelKeys.length; i++) {
|
||||||
|
Object.keys(allFields).map(key => {
|
||||||
|
if (key.includes(`${this.state.activePanelKeys[i]}-`)) {
|
||||||
|
if (
|
||||||
|
subPanelpayloadAttributes.hasOwnProperty(
|
||||||
|
`${this.state.activePanelKeys[i]}`,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Object.keys(
|
||||||
|
subPanelpayloadAttributes[this.state.activePanelKeys[i]],
|
||||||
|
).map(subPanel => {
|
||||||
|
if (`${this.state.activePanelKeys[i]}-${subPanel}` === true) {
|
||||||
|
if (key.includes(`-${subPanel}-`)) {
|
||||||
|
activeFields.push(key);
|
||||||
|
}
|
||||||
|
} else if (!key.includes(`-${subPanel}-`)) {
|
||||||
|
activeFields.push(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
activeFields.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.onFieldValidate(activeFields, formname);
|
||||||
|
};
|
||||||
|
|
||||||
|
onFieldValidate = (fields, formName) => {
|
||||||
|
// validate fields and get profile features list
|
||||||
|
this.props.form.validateFields(fields, (err, values) => {
|
||||||
|
if (!err) {
|
||||||
|
let profileFeaturesList = [];
|
||||||
|
for (let i = 0; i < this.state.activePanelKeys.length; i++) {
|
||||||
|
let content = {};
|
||||||
|
Object.entries(values).map(([key, value]) => {
|
||||||
|
if (key.includes(`${this.state.activePanelKeys[i]}-`)) {
|
||||||
|
content[
|
||||||
|
key.replace(`${this.state.activePanelKeys[i]}-`, '')
|
||||||
|
] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let feature = {
|
||||||
|
featureCode: this.state.activePanelKeys[i],
|
||||||
|
deviceType: this.props.deviceType,
|
||||||
|
content: content,
|
||||||
|
};
|
||||||
|
profileFeaturesList.push(feature);
|
||||||
|
}
|
||||||
|
this.props.getPolicyPayloadData(formName, profileFeaturesList);
|
||||||
|
this.props.getNextStep();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// generate form items
|
||||||
|
getPanelItems = (panel, panelId) => {
|
||||||
|
const { getFieldDecorator } = this.props.form;
|
||||||
|
const subPanelList = {};
|
||||||
|
return panel.map((item, k) => {
|
||||||
|
switch (item.type) {
|
||||||
|
case 'select':
|
||||||
|
if (item.optional.hasOwnProperty('subPanel')) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Form.Item
|
||||||
|
key={k}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
style={{ display: 'block' }}
|
||||||
|
>
|
||||||
|
{getFieldDecorator(`${item.id}`, {
|
||||||
|
initialValue: `${item.optional.option[0].name}`,
|
||||||
|
})(
|
||||||
|
<Select
|
||||||
|
onChange={e =>
|
||||||
|
this.handleSelectedPanel(e, item.optional.subPanel)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{item.optional.option.map((option, i) => {
|
||||||
|
return (
|
||||||
|
<Option key={i} value={option.value}>
|
||||||
|
{option.name}
|
||||||
|
</Option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
<div className={'sub-panel-container'}>
|
||||||
|
{item.optional.subPanel.map((panel, i) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
id={panel.id}
|
||||||
|
key={i}
|
||||||
|
style={
|
||||||
|
panel.id === item.optional.initialDataIndex
|
||||||
|
? { display: 'block' }
|
||||||
|
: { display: 'none' }
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{this.getPanelItems(panel.panelItem)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
key={k}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
style={{ display: 'block' }}
|
||||||
|
>
|
||||||
|
{getFieldDecorator(`${item.id}`, {
|
||||||
|
initialValue: `${item.optional.option[0].name}`,
|
||||||
|
})(
|
||||||
|
<Select>
|
||||||
|
{item.optional.option.map((option, i) => {
|
||||||
|
return (
|
||||||
|
<Option key={i} value={option.value}>
|
||||||
|
{option.name}
|
||||||
|
</Option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
case 'timeSelector':
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
key={k}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
style={{ display: 'block' }}
|
||||||
|
>
|
||||||
|
{getFieldDecorator(`${item.id}`, {
|
||||||
|
initialValue: item.optional.initialDataIndex,
|
||||||
|
})(
|
||||||
|
<Select>
|
||||||
|
{this.getOptionForTimeSelectors(
|
||||||
|
item.optional.firstOptionValue,
|
||||||
|
item.optional.lastOptionValue,
|
||||||
|
item.optional.valueDifference,
|
||||||
|
)}
|
||||||
|
</Select>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
case 'input':
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
key={k}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
style={{ display: 'block' }}
|
||||||
|
>
|
||||||
|
{getFieldDecorator(`${item.id}`, {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
pattern: new RegExp(`${item.optional.rules.regex}`),
|
||||||
|
message: `${item.optional.rules.validationMsg}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input placeholder={item.optional.placeholder} />)}
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
case 'checkbox':
|
||||||
|
if (item.optional.hasOwnProperty('subPanel')) {
|
||||||
|
return (
|
||||||
|
<div key={k}>
|
||||||
|
<Collapse
|
||||||
|
bordered={false}
|
||||||
|
activeKey={this.state.activeSubPanelKeys}
|
||||||
|
>
|
||||||
|
<Collapse.Panel
|
||||||
|
key={item.id}
|
||||||
|
showArrow={false}
|
||||||
|
style={{ border: 0 }}
|
||||||
|
header={
|
||||||
|
<Form.Item key={k}>
|
||||||
|
{getFieldDecorator(`${item.id}`, {
|
||||||
|
valuePropName: 'checked',
|
||||||
|
initialValue: item.optional.ischecked,
|
||||||
|
})(
|
||||||
|
<Checkbox onChange={this.handleSubPanel}>
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
</Checkbox>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
{item.optional.subPanel.map((panel, i) => {
|
||||||
|
subPanelList[panel.others.itemSwitch] =
|
||||||
|
panel.others.itemPayload;
|
||||||
|
if (
|
||||||
|
subPanelpayloadAttributes.hasOwnProperty(panelId)
|
||||||
|
) {
|
||||||
|
Object.assign(
|
||||||
|
subPanelpayloadAttributes[panelId],
|
||||||
|
subPanelList,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
subPanelpayloadAttributes[panelId] = subPanelList;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div key={i}>
|
||||||
|
{this.getPanelItems(panel.panelItem, panelId)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Collapse.Panel>
|
||||||
|
</Collapse>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Form.Item key={k}>
|
||||||
|
{getFieldDecorator(`${item.id}`, {
|
||||||
|
valuePropName: 'checked',
|
||||||
|
initialValue: item.optional.ischecked,
|
||||||
|
})(
|
||||||
|
<Checkbox>
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
</Checkbox>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
case 'textArea':
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
key={k}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
style={{ display: 'block' }}
|
||||||
|
>
|
||||||
|
{getFieldDecorator(`${item.id}`, {
|
||||||
|
initialValue: null,
|
||||||
|
})(
|
||||||
|
<TextArea
|
||||||
|
placeholder={item.optional.placeholder}
|
||||||
|
rows={item.optional.row}
|
||||||
|
/>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
case 'radioGroup':
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Form.Item
|
||||||
|
key={k}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
style={{ display: 'block' }}
|
||||||
|
>
|
||||||
|
{getFieldDecorator(`${item.id}`, {
|
||||||
|
initialValue: `${item.optional.initialValue}`,
|
||||||
|
})(
|
||||||
|
<Radio.Group
|
||||||
|
onChange={e =>
|
||||||
|
this.handleRadioPanel(e, item.optional.radio)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{item.optional.radio.map((option, i) => {
|
||||||
|
return (
|
||||||
|
<Radio key={i} value={option.value}>
|
||||||
|
{option.name}
|
||||||
|
</Radio>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Radio.Group>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
<div className={'sub-panel-container'}>
|
||||||
|
{item.optional.subPanel.map((panel, i) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={i}
|
||||||
|
id={panel.id}
|
||||||
|
style={
|
||||||
|
panel.id === item.optional.initialValue
|
||||||
|
? { display: 'block' }
|
||||||
|
: { display: 'none' }
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{this.getPanelItems(panel.panelItem)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
case 'title':
|
||||||
|
return (
|
||||||
|
<Title key={k} level={4}>
|
||||||
|
{item.label}{' '}
|
||||||
|
</Title>
|
||||||
|
);
|
||||||
|
case 'paragraph':
|
||||||
|
return (
|
||||||
|
<Paragraph key={k} style={{ marginTop: 20 }}>
|
||||||
|
{item.label}{' '}
|
||||||
|
</Paragraph>
|
||||||
|
);
|
||||||
|
case 'alert':
|
||||||
|
return (
|
||||||
|
<Alert key={k} description={item.label} type="warning" showIcon />
|
||||||
|
);
|
||||||
|
case 'upload':
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
key={k}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{getFieldDecorator('upload', {})(
|
||||||
|
<Upload>
|
||||||
|
<Button>
|
||||||
|
<Icon type="upload" /> Click to upload
|
||||||
|
</Button>
|
||||||
|
</Upload>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
case 'inputTable':
|
||||||
|
if (
|
||||||
|
!(`${item.optional.dataSource}` in this.state.inputTableDataSources)
|
||||||
|
) {
|
||||||
|
Object.defineProperty(
|
||||||
|
this.state.inputTableDataSources,
|
||||||
|
`${item.optional.dataSource}`,
|
||||||
|
{ value: [], writable: true },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div key={k}>
|
||||||
|
<Button
|
||||||
|
onClick={() => this.handleAdd(item.optional.dataSource)}
|
||||||
|
type="primary"
|
||||||
|
style={{ marginBottom: 16 }}
|
||||||
|
>
|
||||||
|
<Icon type="plus-circle" />
|
||||||
|
{item.optional.button.name}
|
||||||
|
</Button>
|
||||||
|
<Table
|
||||||
|
id={item.id}
|
||||||
|
dataSource={
|
||||||
|
this.state.inputTableDataSources[item.optional.dataSource]
|
||||||
|
}
|
||||||
|
columns={this.getColumns(
|
||||||
|
{ getFieldDecorator },
|
||||||
|
item.optional.columns,
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
case 'customInputTable':
|
||||||
|
return (
|
||||||
|
<div key={k}>
|
||||||
|
<Upload onChange={this.handleCustomInputTable}>
|
||||||
|
<Button type="primary" style={{ marginBottom: 16 }}>
|
||||||
|
<Icon type="plus-circle" />
|
||||||
|
{item.optional.button.name}
|
||||||
|
</Button>
|
||||||
|
</Upload>
|
||||||
|
<Table
|
||||||
|
id={item.id}
|
||||||
|
dataSource={this.state.customInputDataArray}
|
||||||
|
columns={this.getColumns(
|
||||||
|
{ getFieldDecorator },
|
||||||
|
item.optional.columns,
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { policyUIConfigurationsList } = this.props;
|
||||||
|
const { getFieldDecorator } = this.props.form;
|
||||||
|
return (
|
||||||
|
<div className="tab-container">
|
||||||
|
<Tabs
|
||||||
|
tabPosition={'left'}
|
||||||
|
size={'large'}
|
||||||
|
onTabClick={this.setProfileInfo}
|
||||||
|
>
|
||||||
|
{policyUIConfigurationsList.map((element, i) => {
|
||||||
|
return (
|
||||||
|
<TabPane tab={<span>{element.name}</span>} key={i}>
|
||||||
|
{Object.values(element.panels).map((panel, j) => {
|
||||||
|
panel = panel.panel;
|
||||||
|
return (
|
||||||
|
<div key={j}>
|
||||||
|
<Collapse
|
||||||
|
bordered={false}
|
||||||
|
activeKey={this.state.activePanelKeys}
|
||||||
|
>
|
||||||
|
<Collapse.Panel
|
||||||
|
key={panel.panelId}
|
||||||
|
showArrow={false}
|
||||||
|
style={{ border: 0 }}
|
||||||
|
header={
|
||||||
|
<div>
|
||||||
|
<Row>
|
||||||
|
<Col offset={0} span={14}>
|
||||||
|
<Title level={4}> {panel.title} </Title>
|
||||||
|
</Col>
|
||||||
|
<Col offset={8} span={1}>
|
||||||
|
<Switch
|
||||||
|
checkedChildren="ON"
|
||||||
|
unCheckedChildren="OFF"
|
||||||
|
onChange={e =>
|
||||||
|
this.handleMainPanel(
|
||||||
|
e,
|
||||||
|
`${panel.panelId}`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>{panel.description}</Row>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{panel.hasOwnProperty('panelItem') && (
|
||||||
|
<div>
|
||||||
|
<Form name={panel.panelId}>
|
||||||
|
<Form.Item style={{ display: 'none' }}>
|
||||||
|
{getFieldDecorator(`${panel.panelId}`, {
|
||||||
|
initialValue: ' ',
|
||||||
|
})(<Input />)}
|
||||||
|
</Form.Item>
|
||||||
|
{this.getPanelItems(
|
||||||
|
panel.panelItem,
|
||||||
|
panel.panelId,
|
||||||
|
)}
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{panel.hasOwnProperty('subFormLists') && (
|
||||||
|
<div>
|
||||||
|
{Object.values(panel.subFormLists).map(
|
||||||
|
(form, i) => {
|
||||||
|
return (
|
||||||
|
<Form name={form.id} key={i}>
|
||||||
|
<Form.Item style={{ display: 'none' }}>
|
||||||
|
{getFieldDecorator(`${form.id}`, {
|
||||||
|
initialValue: ' ',
|
||||||
|
})(<Input />)}
|
||||||
|
</Form.Item>
|
||||||
|
{this.getPanelItems(form.panelItem)}
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Collapse.Panel>
|
||||||
|
</Collapse>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TabPane>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Tabs>
|
||||||
|
<Col span={16} offset={20}>
|
||||||
|
<div style={{ marginTop: 24 }}>
|
||||||
|
<Button style={{ marginRight: 8 }} onClick={this.props.getPrevStep}>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={e => this.onHandleContinue(e, 'configureProfileData')}
|
||||||
|
>
|
||||||
|
Continue
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(Form.create()(ConfigureProfile));
|
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickSavePolicy = (event, formName) => {
|
||||||
|
this.props.form.validateFields((err, values) => {
|
||||||
|
if (!err) {
|
||||||
|
this.props.getPolicyPayloadData(formName, values);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { policyData } = this.props;
|
||||||
|
const { getFieldDecorator } = this.props.form;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Form.Item
|
||||||
|
label={'Set a name to your policy *'}
|
||||||
|
style={{ display: 'block' }}
|
||||||
|
>
|
||||||
|
{getFieldDecorator('policyName', {
|
||||||
|
initialValue: policyData.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', {
|
||||||
|
initialValue: policyData.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 }}
|
||||||
|
onClick={e => this.onClickSavePolicy(e, 'publishDevicesData')}
|
||||||
|
>
|
||||||
|
Save & Publish
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={e => this.onClickSavePolicy(e, 'publishDevicesData')}
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(Form.create()(PublishDevices));
|
@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate payload using Select policy type
|
||||||
|
onHandleContinue = (e, formName) => {
|
||||||
|
this.props.form.validateFields((err, values) => {
|
||||||
|
if (!err) {
|
||||||
|
if (
|
||||||
|
values.policyType === 'CORRECTIVE' ||
|
||||||
|
values.correctiveActions === 'NONE'
|
||||||
|
) {
|
||||||
|
values.correctiveActions = [];
|
||||||
|
}
|
||||||
|
this.props.getPolicyPayloadData(formName, values);
|
||||||
|
this.props.getNextStep();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
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 { policyData } = this.props;
|
||||||
|
const { getFieldDecorator } = this.props.form;
|
||||||
|
let correctiveActions = null;
|
||||||
|
if (policyData.correctiveActions.length > 0) {
|
||||||
|
correctiveActions = '';
|
||||||
|
} else {
|
||||||
|
correctiveActions = 'NONE';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Form.Item style={{ display: 'block' }}>
|
||||||
|
{getFieldDecorator('policyType', {
|
||||||
|
initialValue: policyData.policyType,
|
||||||
|
})(
|
||||||
|
<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
|
||||||
|
<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: correctiveActions,
|
||||||
|
})(
|
||||||
|
<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={e => this.onHandleContinue(e, 'policyTypeData')}
|
||||||
|
>
|
||||||
|
Continue
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(Form.create()(SelectPolicyType));
|
@ -0,0 +1,273 @@
|
|||||||
|
/*
|
||||||
|
* 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 { Form, Row, Col, Card, Steps, message, notification } from 'antd';
|
||||||
|
import { withConfigContext } from '../../../../../../components/ConfigContext';
|
||||||
|
import ConfigureProfile from './components/ConfigureProfile';
|
||||||
|
import SelectPolicyType from './components/SelectPolicyType';
|
||||||
|
import AssignGroups from './components/AssignGroups';
|
||||||
|
import PublishDevices from './components/PublishDevices';
|
||||||
|
import axios from 'axios';
|
||||||
|
const { Step } = Steps;
|
||||||
|
|
||||||
|
class EditPolicy extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.config = this.props.context;
|
||||||
|
this.state = {
|
||||||
|
currentStepIndex: 0,
|
||||||
|
policyUIConfigurationsList: null,
|
||||||
|
newPolicyPayload: { compliance: 'enforce' },
|
||||||
|
policyProfile: {},
|
||||||
|
payloadData: {},
|
||||||
|
policyFeatureList: [],
|
||||||
|
policyData: {},
|
||||||
|
deviceType: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.getSelectedPolicy(this.props.policyId);
|
||||||
|
}
|
||||||
|
|
||||||
|
getPolicyPayloadData = (dataName, dataValue) => {
|
||||||
|
Object.defineProperty(this.state.payloadData, dataName, {
|
||||||
|
value: dataValue,
|
||||||
|
writable: true,
|
||||||
|
});
|
||||||
|
if (dataName === 'publishDevicesData') {
|
||||||
|
this.createPayload();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
createPayload = () => {
|
||||||
|
const {
|
||||||
|
publishDevicesData,
|
||||||
|
configureProfileData,
|
||||||
|
policyTypeData,
|
||||||
|
groupData,
|
||||||
|
} = this.state.payloadData;
|
||||||
|
const profile = {
|
||||||
|
profileName: publishDevicesData.policyName,
|
||||||
|
deviceType: this.state.deviceType,
|
||||||
|
profileFeaturesList: configureProfileData,
|
||||||
|
};
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
...publishDevicesData,
|
||||||
|
compliance: 'enforce',
|
||||||
|
ownershipType: null,
|
||||||
|
...policyTypeData,
|
||||||
|
profile: profile,
|
||||||
|
...groupData,
|
||||||
|
};
|
||||||
|
this.onEditPolicy(JSON.stringify(payload));
|
||||||
|
};
|
||||||
|
|
||||||
|
getSelectedPolicy = policyId => {
|
||||||
|
let apiUrl =
|
||||||
|
window.location.origin +
|
||||||
|
this.config.serverConfig.invoker.uri +
|
||||||
|
this.config.serverConfig.invoker.deviceMgt +
|
||||||
|
'/policies/' +
|
||||||
|
policyId;
|
||||||
|
|
||||||
|
// send request to the invokers
|
||||||
|
axios
|
||||||
|
.get(apiUrl)
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
this.setState({
|
||||||
|
isLoading: true,
|
||||||
|
policyData: res.data.data,
|
||||||
|
deviceType: res.data.data.profile.deviceType,
|
||||||
|
policyFeatureList: res.data.data.profile.profileFeaturesList,
|
||||||
|
});
|
||||||
|
this.getPolicyConfigJson(res.data.data.profile.deviceType);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.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 selected policy.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
getPolicyConfigJson = type => {
|
||||||
|
this.setState({ isLoading: true });
|
||||||
|
|
||||||
|
let apiUrl =
|
||||||
|
window.location.origin +
|
||||||
|
this.config.serverConfig.invoker.uri +
|
||||||
|
this.config.serverConfig.invoker.deviceMgt +
|
||||||
|
'/device-types/' +
|
||||||
|
type +
|
||||||
|
'/ui-policy-configurations';
|
||||||
|
// send request to the invokers
|
||||||
|
axios
|
||||||
|
.get(apiUrl)
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
this.setState({
|
||||||
|
policyUIConfigurationsList: 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 Policy details.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onEditPolicy = value => {
|
||||||
|
axios
|
||||||
|
.put(
|
||||||
|
window.location.origin +
|
||||||
|
this.config.serverConfig.invoker.uri +
|
||||||
|
this.config.serverConfig.invoker.deviceMgt +
|
||||||
|
'/policies/' +
|
||||||
|
this.props.policyId,
|
||||||
|
value,
|
||||||
|
{ headers: { 'Content-Type': 'application-json' } },
|
||||||
|
)
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
notification.success({
|
||||||
|
message: 'Done',
|
||||||
|
duration: 4,
|
||||||
|
description: 'Successfully Updated the Policy.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.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 Updated the Policy.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
getNextStep = () => {
|
||||||
|
const currentStepIndex = this.state.currentStepIndex + 1;
|
||||||
|
this.setState({ currentStepIndex });
|
||||||
|
};
|
||||||
|
|
||||||
|
getPrevStep = () => {
|
||||||
|
const currentStepIndex = this.state.currentStepIndex - 1;
|
||||||
|
this.setState({ currentStepIndex });
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
currentStepIndex,
|
||||||
|
policyUIConfigurationsList,
|
||||||
|
policyFeatureList,
|
||||||
|
policyData,
|
||||||
|
deviceType,
|
||||||
|
} = this.state;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{policyUIConfigurationsList != null && (
|
||||||
|
<Row>
|
||||||
|
<Col span={20} offset={2}>
|
||||||
|
<Steps style={{ minHeight: 32 }} current={currentStepIndex}>
|
||||||
|
<Step key="ProfileConfigure" title="Configure profile" />
|
||||||
|
<Step key="PolicyType" title="Select policy type" />
|
||||||
|
<Step key="AssignGroups" title="Assign to groups" />
|
||||||
|
<Step key="Publish" title="Publish to devices" />
|
||||||
|
</Steps>
|
||||||
|
</Col>
|
||||||
|
<Col span={16} offset={4}>
|
||||||
|
<Card style={{ marginTop: 24 }}>
|
||||||
|
<div
|
||||||
|
style={{ display: currentStepIndex === 0 ? 'unset' : 'none' }}
|
||||||
|
>
|
||||||
|
<ConfigureProfile
|
||||||
|
policyUIConfigurationsList={policyUIConfigurationsList}
|
||||||
|
getPolicyPayloadData={this.getPolicyPayloadData}
|
||||||
|
getNextStep={this.getNextStep}
|
||||||
|
policyFeatureList={policyFeatureList}
|
||||||
|
deviceType={deviceType}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{ display: currentStepIndex === 1 ? 'unset' : 'none' }}
|
||||||
|
>
|
||||||
|
<SelectPolicyType
|
||||||
|
getPolicyPayloadData={this.getPolicyPayloadData}
|
||||||
|
policyData={policyData}
|
||||||
|
getPrevStep={this.getPrevStep}
|
||||||
|
getNextStep={this.getNextStep}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{ display: currentStepIndex === 2 ? 'unset' : 'none' }}
|
||||||
|
>
|
||||||
|
<AssignGroups
|
||||||
|
getPolicyPayloadData={this.getPolicyPayloadData}
|
||||||
|
policyData={policyData}
|
||||||
|
getPrevStep={this.getPrevStep}
|
||||||
|
getNextStep={this.getNextStep}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{ display: currentStepIndex === 3 ? 'unset' : 'none' }}
|
||||||
|
>
|
||||||
|
<PublishDevices
|
||||||
|
policyData={policyData}
|
||||||
|
getPolicyPayloadData={this.getPolicyPayloadData}
|
||||||
|
getPrevStep={this.getPrevStep}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(
|
||||||
|
Form.create({ name: 'edit-policy' })(EditPolicy),
|
||||||
|
);
|
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* 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 { Divider, Icon, Tooltip } from 'antd';
|
||||||
|
import { withConfigContext } from '../../../../../../../../components/ConfigContext';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
class PolicyAction extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.config = this.props.context;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<Tooltip placement="top" title={'Edit Policy'}>
|
||||||
|
<Link
|
||||||
|
to={`/entgra/policy/edit/${this.props.selectedPolicyData.id}`}
|
||||||
|
>
|
||||||
|
<Icon type="edit" />
|
||||||
|
</Link>
|
||||||
|
</Tooltip>
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<Tooltip placement="top" title={''}>
|
||||||
|
<Link
|
||||||
|
to={`/entgra/policy/view/${this.props.selectedPolicyData.id}`}
|
||||||
|
>
|
||||||
|
<Icon type="eye" />
|
||||||
|
</Link>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(PolicyAction);
|
@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* 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, Tooltip, Popconfirm, Divider } from 'antd';
|
||||||
|
|
||||||
|
class BulkActionBar extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
selectedMultiple: false,
|
||||||
|
selectedSingle: false,
|
||||||
|
isPolicyActive: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method checks whether active devices are selected
|
||||||
|
onCheckPolicyStatus = () => {
|
||||||
|
let tempIsPolicyActive;
|
||||||
|
for (let i = 0; i < this.props.selectedRows.length; i++) {
|
||||||
|
if (this.props.selectedRows[i].active) {
|
||||||
|
tempIsPolicyActive = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tempIsPolicyActive = false;
|
||||||
|
}
|
||||||
|
this.setState({ isPolicyActive: tempIsPolicyActive });
|
||||||
|
};
|
||||||
|
|
||||||
|
onConfirmRemove = () => {
|
||||||
|
if (!this.state.isPolicyActive) {
|
||||||
|
this.props.removePolicy();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onConfirmPublish = () => {
|
||||||
|
if (!this.state.isPolicyActive) {
|
||||||
|
this.props.publishPolicy();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onConfirmUnpublish = () => {
|
||||||
|
if (this.state.isPolicyActive) {
|
||||||
|
this.props.unpublishPolicy();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const isSelected = this.props.selectedRows.length > 0;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div style={{ padding: '8px' }}>
|
||||||
|
<Tooltip placement="bottom" title={'Apply Changes to Device'}>
|
||||||
|
<Popconfirm
|
||||||
|
placement="topLeft"
|
||||||
|
title={'Do you really want to apply changes to all policies?'}
|
||||||
|
onConfirm={this.props.applyChanges}
|
||||||
|
okText="Yes"
|
||||||
|
cancelText="No"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
shape="circle"
|
||||||
|
icon="check-circle"
|
||||||
|
size={'default'}
|
||||||
|
style={{ margin: '2px' }}
|
||||||
|
/>
|
||||||
|
</Popconfirm>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{ display: isSelected ? 'inline' : 'none', padding: '8px' }}
|
||||||
|
>
|
||||||
|
<Tooltip
|
||||||
|
placement="bottom"
|
||||||
|
title={'Remove'}
|
||||||
|
autoAdjustOverflow={true}
|
||||||
|
>
|
||||||
|
<Popconfirm
|
||||||
|
placement="topLeft"
|
||||||
|
title={
|
||||||
|
!this.state.isPolicyActive
|
||||||
|
? 'Do you really want to remove the selected policy(s)?'
|
||||||
|
: 'You cannot select already active policies. Please deselect active policies and try again.'
|
||||||
|
}
|
||||||
|
onConfirm={this.onConfirmRemove}
|
||||||
|
okText="Yes"
|
||||||
|
cancelText="No"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
shape="circle"
|
||||||
|
icon="delete"
|
||||||
|
size={'default'}
|
||||||
|
onClick={this.onCheckPolicyStatus}
|
||||||
|
style={{ margin: '2px' }}
|
||||||
|
/>
|
||||||
|
</Popconfirm>
|
||||||
|
</Tooltip>
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<Tooltip placement="bottom" title={'Publish'}>
|
||||||
|
<Popconfirm
|
||||||
|
placement="topLeft"
|
||||||
|
title={
|
||||||
|
!this.state.isPolicyActive
|
||||||
|
? 'Do you really want to publish the selected policy(s)??'
|
||||||
|
: 'You cannot select already active policies. Please deselect active policies and try again.'
|
||||||
|
}
|
||||||
|
okText="Yes"
|
||||||
|
onConfirm={this.onConfirmPublish}
|
||||||
|
cancelText="No"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
shape="circle"
|
||||||
|
icon="import"
|
||||||
|
onClick={this.onCheckPolicyStatus}
|
||||||
|
size={'default'}
|
||||||
|
style={{
|
||||||
|
margin: '2px',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Popconfirm>
|
||||||
|
</Tooltip>
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<Tooltip placement="bottom" title={'Unpublish'}>
|
||||||
|
<Popconfirm
|
||||||
|
placement="topLeft"
|
||||||
|
title={
|
||||||
|
this.state.isPolicyActive
|
||||||
|
? 'Do you really want to unpublish the selected policy(s)?'
|
||||||
|
: 'You cannot select already inactive policies to be unpublished. Please deselect inactive policies and try again.'
|
||||||
|
}
|
||||||
|
okText="Yes"
|
||||||
|
onConfirm={this.onConfirmUnpublish}
|
||||||
|
cancelText="No"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
shape="circle"
|
||||||
|
icon="export"
|
||||||
|
onClick={this.onCheckPolicyStatus}
|
||||||
|
size={'default'}
|
||||||
|
style={{ margin: '2px' }}
|
||||||
|
/>
|
||||||
|
</Popconfirm>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BulkActionBar;
|
@ -0,0 +1,756 @@
|
|||||||
|
/*
|
||||||
|
* 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 {
|
||||||
|
Alert,
|
||||||
|
Button,
|
||||||
|
Checkbox,
|
||||||
|
Col,
|
||||||
|
Collapse,
|
||||||
|
Form,
|
||||||
|
Icon,
|
||||||
|
Input,
|
||||||
|
Popconfirm,
|
||||||
|
Radio,
|
||||||
|
Row,
|
||||||
|
Select,
|
||||||
|
Table,
|
||||||
|
Tabs,
|
||||||
|
Tooltip,
|
||||||
|
Typography,
|
||||||
|
Upload,
|
||||||
|
} from 'antd';
|
||||||
|
import { withConfigContext } from '../../../../../../../../components/ConfigContext';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
const { Text, Title, Paragraph } = Typography;
|
||||||
|
const { TabPane } = Tabs;
|
||||||
|
const { Option } = Select;
|
||||||
|
const { TextArea } = Input;
|
||||||
|
|
||||||
|
const subPanelpayloadAttributes = {};
|
||||||
|
const fieldKeys = [];
|
||||||
|
|
||||||
|
class PolicyInfo extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.config = this.props.context;
|
||||||
|
this.state = {
|
||||||
|
data: {},
|
||||||
|
policyFeatureList: [],
|
||||||
|
activePanelKeys: [],
|
||||||
|
profilePreviewKey: '',
|
||||||
|
customInputDataArray: [],
|
||||||
|
inputTableDataSources: {},
|
||||||
|
isInfoPreview: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
setProfileInfo = e => {
|
||||||
|
let activePolicies = [];
|
||||||
|
let activePolicyFields = {};
|
||||||
|
const allFields = this.props.form.getFieldsValue();
|
||||||
|
this.props.policyFeatureList.map(element => {
|
||||||
|
activePolicies.push(element.featureCode);
|
||||||
|
let featureData = JSON.parse(element.content);
|
||||||
|
Object.keys(featureData).map(key => {
|
||||||
|
let regex = new RegExp(`${element.featureCode}.+${key}`, 'g');
|
||||||
|
Object.keys(allFields).map(fieldName => {
|
||||||
|
if (fieldName.match(regex) != null) {
|
||||||
|
activePolicyFields[fieldName] = featureData[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.props.form.setFieldsValue(activePolicyFields);
|
||||||
|
this.setState({
|
||||||
|
activePanelKeys: activePolicies,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// convert time from 24h format to 12h format
|
||||||
|
timeConverter = time => {
|
||||||
|
time = time
|
||||||
|
.toString()
|
||||||
|
.match(/^([01]\d|2[0-3])(:)([0-5]\d)(:[0-5]\d)?$/) || [time];
|
||||||
|
if (time.length > 1) {
|
||||||
|
time = time.slice(1);
|
||||||
|
time[5] = +time[0] < 12 ? ' AM' : ' PM';
|
||||||
|
time[0] = +time[0] % 12 || 12;
|
||||||
|
}
|
||||||
|
return time.join('');
|
||||||
|
};
|
||||||
|
|
||||||
|
// get Option value from start Time, end Time and time difference between 2 values
|
||||||
|
getOptionForTimeSelectors = (startTimeValue, endTimeValue, timeIncrement) => {
|
||||||
|
let timeOptions = [];
|
||||||
|
let time = new Date(
|
||||||
|
moment()
|
||||||
|
.startOf('day')
|
||||||
|
.format('YYYY/MM/DD'),
|
||||||
|
);
|
||||||
|
let tempValue = startTimeValue;
|
||||||
|
time.setMinutes(time.getMinutes() + tempValue);
|
||||||
|
let startOption = (
|
||||||
|
<Option value={String(tempValue)}>
|
||||||
|
{this.timeConverter(
|
||||||
|
`${String(time)
|
||||||
|
.split(' ')[4]
|
||||||
|
.substring(0, 5)}`,
|
||||||
|
)}
|
||||||
|
</Option>
|
||||||
|
);
|
||||||
|
timeOptions.push(startOption);
|
||||||
|
|
||||||
|
while (tempValue !== endTimeValue) {
|
||||||
|
time = new Date(
|
||||||
|
moment()
|
||||||
|
.startOf('day')
|
||||||
|
.format('YYYY/MM/DD'),
|
||||||
|
);
|
||||||
|
tempValue += timeIncrement;
|
||||||
|
if (tempValue > 1440) {
|
||||||
|
tempValue = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
time.setMinutes(time.getMinutes() + tempValue);
|
||||||
|
let option = (
|
||||||
|
<Option value={String(tempValue)}>
|
||||||
|
{this.timeConverter(
|
||||||
|
`${String(time)
|
||||||
|
.split(' ')[4]
|
||||||
|
.substring(0, 5)}`,
|
||||||
|
)}
|
||||||
|
</Option>
|
||||||
|
);
|
||||||
|
timeOptions.push(option);
|
||||||
|
}
|
||||||
|
return timeOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
// handle items which handle from radio buttons
|
||||||
|
handleRadioPanel = (e, subPanel) => {
|
||||||
|
{
|
||||||
|
subPanel.map((panel, i) => {
|
||||||
|
if (panel.value === e.target.value) {
|
||||||
|
document.getElementById(panel.value).style.display = 'block';
|
||||||
|
} else {
|
||||||
|
document.getElementById(panel.value).style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// handle items which handle from select options
|
||||||
|
handleSelectedPanel = (e, subPanel) => {
|
||||||
|
{
|
||||||
|
subPanel.map((panel, i) => {
|
||||||
|
if (panel.id === e) {
|
||||||
|
document.getElementById(panel.id).style.display = 'block';
|
||||||
|
} else {
|
||||||
|
document.getElementById(panel.id).style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
getColumns = ({ getFieldDecorator }, arr) => {
|
||||||
|
const columnArray = [];
|
||||||
|
const actionColumn = [
|
||||||
|
{
|
||||||
|
title: '',
|
||||||
|
dataIndex: 'operation',
|
||||||
|
render: (name, row) => (
|
||||||
|
<Form.Item>
|
||||||
|
<Popconfirm title="Sure to delete?">
|
||||||
|
<a>
|
||||||
|
<Text type="danger">
|
||||||
|
<Icon type="delete" />
|
||||||
|
</Text>
|
||||||
|
</a>
|
||||||
|
</Popconfirm>
|
||||||
|
</Form.Item>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
Object.values(arr).map((columnData, c) => {
|
||||||
|
if (columnData.type === 'input') {
|
||||||
|
const column = {
|
||||||
|
title: `${columnData.name}`,
|
||||||
|
dataIndex: `${columnData.key}`,
|
||||||
|
key: `${columnData.key}`,
|
||||||
|
render: (name, row, i) => (
|
||||||
|
<Form.Item>
|
||||||
|
{getFieldDecorator(`${columnData.key}${i}`, {})(
|
||||||
|
<Input
|
||||||
|
type={columnData.others.inputType}
|
||||||
|
placeholder={columnData.others.placeholder}
|
||||||
|
/>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
columnArray.push(column);
|
||||||
|
} else if (columnData.type === 'upload') {
|
||||||
|
const column = {
|
||||||
|
title: `${columnData.name}`,
|
||||||
|
dataIndex: `${columnData.key}`,
|
||||||
|
key: `${columnData.key}`,
|
||||||
|
render: (name, row, i) => (
|
||||||
|
<Form.Item>
|
||||||
|
{getFieldDecorator(`${columnData.key}${i}`, {})(
|
||||||
|
<Upload>
|
||||||
|
<Button>
|
||||||
|
<Icon type="upload" /> Choose file
|
||||||
|
</Button>
|
||||||
|
</Upload>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
columnArray.push(column);
|
||||||
|
} else if (columnData.type === 'select') {
|
||||||
|
const column = {
|
||||||
|
title: `${columnData.name}`,
|
||||||
|
dataIndex: `${columnData.key}`,
|
||||||
|
key: `${columnData.key}`,
|
||||||
|
render: (name, row, i) => (
|
||||||
|
<Form.Item>
|
||||||
|
{getFieldDecorator(`${columnData.key}${i}`, {
|
||||||
|
initialValue: columnData.others.initialDataIndex,
|
||||||
|
})(
|
||||||
|
<Select>
|
||||||
|
{columnData.others.option.map((option, i) => {
|
||||||
|
return (
|
||||||
|
<Option key={i} value={option.key}>
|
||||||
|
{option.value}
|
||||||
|
</Option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
columnArray.push(column);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const columns = columnArray.concat(actionColumn);
|
||||||
|
return columns;
|
||||||
|
};
|
||||||
|
|
||||||
|
// generate form items
|
||||||
|
getPanelItems = (panel, panelId) => {
|
||||||
|
const { getFieldDecorator } = this.props.form;
|
||||||
|
const subPanelList = {};
|
||||||
|
return panel.map((item, k) => {
|
||||||
|
fieldKeys.push(item.id);
|
||||||
|
switch (item.type) {
|
||||||
|
case 'select':
|
||||||
|
if (item.optional.hasOwnProperty('subPanel')) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Form.Item
|
||||||
|
key={k}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
style={{ display: 'block' }}
|
||||||
|
>
|
||||||
|
{getFieldDecorator(`${item.id}`, {
|
||||||
|
initialValue: `${item.optional.option[0].name}`,
|
||||||
|
})(
|
||||||
|
<Select
|
||||||
|
onChange={e =>
|
||||||
|
this.handleSelectedPanel(e, item.optional.subPanel)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{item.optional.option.map((option, i) => {
|
||||||
|
return (
|
||||||
|
<Option key={i} value={option.value}>
|
||||||
|
{option.name}
|
||||||
|
</Option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
<div className={'sub-panel-container'}>
|
||||||
|
{item.optional.subPanel.map((panel, i) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
id={panel.id}
|
||||||
|
key={i}
|
||||||
|
style={
|
||||||
|
panel.id === item.optional.initialDataIndex
|
||||||
|
? { display: 'block' }
|
||||||
|
: { display: 'none' }
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{this.getPanelItems(panel.panelItem)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
key={k}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
style={{ display: 'block' }}
|
||||||
|
>
|
||||||
|
{getFieldDecorator(`${item.id}`, {
|
||||||
|
initialValue: `${item.optional.option[0].name}`,
|
||||||
|
})(
|
||||||
|
<Select>
|
||||||
|
{item.optional.option.map((option, i) => {
|
||||||
|
return (
|
||||||
|
<Option key={i} value={option.value}>
|
||||||
|
{option.name}
|
||||||
|
</Option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
case 'timeSelector':
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
key={k}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
style={{ display: 'block' }}
|
||||||
|
>
|
||||||
|
{getFieldDecorator(`${item.id}`, {
|
||||||
|
initialValue: item.optional.initialDataIndex,
|
||||||
|
})(
|
||||||
|
<Select>
|
||||||
|
{this.getOptionForTimeSelectors(
|
||||||
|
item.optional.firstOptionValue,
|
||||||
|
item.optional.lastOptionValue,
|
||||||
|
item.optional.valueDifference,
|
||||||
|
)}
|
||||||
|
</Select>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
case 'input':
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
key={k}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
style={{ display: 'block' }}
|
||||||
|
>
|
||||||
|
{getFieldDecorator(`${item.id}`, {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
pattern: new RegExp(`${item.optional.rules.regex}`),
|
||||||
|
message: `${item.optional.rules.validationMsg}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})(<Input placeholder={item.optional.placeholder} disabled />)}
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
case 'checkbox':
|
||||||
|
if (item.optional.hasOwnProperty('subPanel')) {
|
||||||
|
return (
|
||||||
|
<div key={k}>
|
||||||
|
<Collapse
|
||||||
|
bordered={false}
|
||||||
|
activeKey={this.state.activeSubPanelKeys}
|
||||||
|
>
|
||||||
|
<Collapse.Panel
|
||||||
|
key={item.id}
|
||||||
|
showArrow={false}
|
||||||
|
style={{ border: 0 }}
|
||||||
|
header={
|
||||||
|
<Form.Item key={k}>
|
||||||
|
{getFieldDecorator(`${item.id}`, {
|
||||||
|
valuePropName: 'checked',
|
||||||
|
initialValue: item.optional.ischecked,
|
||||||
|
})(
|
||||||
|
<Checkbox>
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
</Checkbox>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
{item.optional.subPanel.map((panel, i) => {
|
||||||
|
subPanelList[panel.others.itemSwitch] =
|
||||||
|
panel.others.itemPayload;
|
||||||
|
if (
|
||||||
|
subPanelpayloadAttributes.hasOwnProperty(panelId)
|
||||||
|
) {
|
||||||
|
Object.assign(
|
||||||
|
subPanelpayloadAttributes[panelId],
|
||||||
|
subPanelList,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
subPanelpayloadAttributes[panelId] = subPanelList;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div key={i}>
|
||||||
|
{this.getPanelItems(panel.panelItem, panelId)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Collapse.Panel>
|
||||||
|
</Collapse>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Form.Item key={k}>
|
||||||
|
{getFieldDecorator(`${item.id}`, {
|
||||||
|
valuePropName: 'checked',
|
||||||
|
initialValue: item.optional.ischecked,
|
||||||
|
})(
|
||||||
|
<Checkbox>
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
</Checkbox>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
case 'textArea':
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
key={k}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
style={{ display: 'block' }}
|
||||||
|
>
|
||||||
|
{getFieldDecorator(`${item.id}`, {
|
||||||
|
initialValue: null,
|
||||||
|
})(
|
||||||
|
<TextArea
|
||||||
|
placeholder={item.optional.placeholder}
|
||||||
|
rows={item.optional.row}
|
||||||
|
disabled
|
||||||
|
/>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
case 'radioGroup':
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Form.Item
|
||||||
|
key={k}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
style={{ display: 'block' }}
|
||||||
|
>
|
||||||
|
{getFieldDecorator(`${item.id}`, {
|
||||||
|
initialValue: `${item.optional.initialValue}`,
|
||||||
|
})(
|
||||||
|
<Radio.Group
|
||||||
|
onChange={e =>
|
||||||
|
this.handleRadioPanel(e, item.optional.radio)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{item.optional.radio.map((option, i) => {
|
||||||
|
return (
|
||||||
|
<Radio key={i} value={option.value}>
|
||||||
|
{option.name}
|
||||||
|
</Radio>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Radio.Group>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
<div className={'sub-panel-container'}>
|
||||||
|
{item.optional.subPanel.map((panel, i) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={i}
|
||||||
|
id={panel.id}
|
||||||
|
style={
|
||||||
|
panel.id === item.optional.initialValue
|
||||||
|
? { display: 'block' }
|
||||||
|
: { display: 'none' }
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{this.getPanelItems(panel.panelItem)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
case 'title':
|
||||||
|
return (
|
||||||
|
<Title key={k} level={4}>
|
||||||
|
{item.label}{' '}
|
||||||
|
</Title>
|
||||||
|
);
|
||||||
|
case 'paragraph':
|
||||||
|
return (
|
||||||
|
<Paragraph key={k} style={{ marginTop: 20 }}>
|
||||||
|
{item.label}{' '}
|
||||||
|
</Paragraph>
|
||||||
|
);
|
||||||
|
case 'alert':
|
||||||
|
return (
|
||||||
|
<Alert key={k} description={item.label} type="warning" showIcon />
|
||||||
|
);
|
||||||
|
case 'upload':
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
key={k}
|
||||||
|
label={
|
||||||
|
<span>
|
||||||
|
{item.label}
|
||||||
|
<Tooltip title={item.tooltip} placement="right">
|
||||||
|
<Icon type="question-circle-o" />
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{getFieldDecorator('upload', {})(
|
||||||
|
<Upload>
|
||||||
|
<Button>
|
||||||
|
<Icon type="upload" /> Click to upload
|
||||||
|
</Button>
|
||||||
|
</Upload>,
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
case 'inputTable':
|
||||||
|
if (
|
||||||
|
!(`${item.optional.dataSource}` in this.state.inputTableDataSources)
|
||||||
|
) {
|
||||||
|
Object.defineProperty(
|
||||||
|
this.state.inputTableDataSources,
|
||||||
|
`${item.optional.dataSource}`,
|
||||||
|
{ value: [], writable: true },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div key={k}>
|
||||||
|
<Table
|
||||||
|
id={item.id}
|
||||||
|
dataSource={
|
||||||
|
this.state.inputTableDataSources[item.optional.dataSource]
|
||||||
|
}
|
||||||
|
columns={this.getColumns(
|
||||||
|
{ getFieldDecorator },
|
||||||
|
item.optional.columns,
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
case 'customInputTable':
|
||||||
|
return (
|
||||||
|
<div key={k}>
|
||||||
|
<Table
|
||||||
|
id={item.id}
|
||||||
|
dataSource={this.state.customInputDataArray}
|
||||||
|
columns={this.getColumns(
|
||||||
|
{ getFieldDecorator },
|
||||||
|
item.optional.columns,
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onPreview = e => {
|
||||||
|
this.setState({
|
||||||
|
profilePreviewKey: 'profileInfo',
|
||||||
|
isInfoPreview: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { policyUIConfigurationsList } = this.props;
|
||||||
|
const { getFieldDecorator } = this.props.form;
|
||||||
|
return (
|
||||||
|
<div style={{ marginTop: 20 }}>
|
||||||
|
<Row>
|
||||||
|
<Col span={4}>
|
||||||
|
<Title level={4}>Profile Information</Title>
|
||||||
|
</Col>
|
||||||
|
<Col span={16}>
|
||||||
|
<Button type="link" icon="eye" onClick={this.onPreview}>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 'small',
|
||||||
|
display: this.state.isInfoPreview ? 'none' : 'inline',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
(Click to view policy information)
|
||||||
|
</Text>
|
||||||
|
</Button>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Collapse
|
||||||
|
bordered={false}
|
||||||
|
activeKey={this.state.profilePreviewKey}
|
||||||
|
style={{ display: this.state.isInfoPreview ? 'block' : 'none' }}
|
||||||
|
>
|
||||||
|
<Collapse.Panel
|
||||||
|
key={'profileInfo'}
|
||||||
|
showArrow={false}
|
||||||
|
style={{
|
||||||
|
border: 0,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="tab-container">
|
||||||
|
<Tabs
|
||||||
|
tabPosition={'left'}
|
||||||
|
size={'large'}
|
||||||
|
onChange={this.setProfileInfo}
|
||||||
|
>
|
||||||
|
{policyUIConfigurationsList.map((element, i) => {
|
||||||
|
return (
|
||||||
|
<TabPane tab={<span>{element.name}</span>} key={i}>
|
||||||
|
{Object.values(element.panels).map((panel, j) => {
|
||||||
|
panel = panel.panel;
|
||||||
|
return (
|
||||||
|
<div key={j}>
|
||||||
|
<Collapse
|
||||||
|
bordered={false}
|
||||||
|
activeKey={this.state.activePanelKeys}
|
||||||
|
>
|
||||||
|
<Collapse.Panel
|
||||||
|
key={panel.panelId}
|
||||||
|
showArrow={false}
|
||||||
|
style={{ border: 0 }}
|
||||||
|
header={
|
||||||
|
<div>
|
||||||
|
<Row>
|
||||||
|
<Col offset={0} span={14}>
|
||||||
|
<Title level={4}> {panel.title} </Title>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>{panel.description}</Row>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{panel.hasOwnProperty('panelItem') && (
|
||||||
|
<div>
|
||||||
|
<Form name={panel.panelId}>
|
||||||
|
<Form.Item style={{ display: 'none' }}>
|
||||||
|
{getFieldDecorator(`${panel.panelId}`, {
|
||||||
|
initialValue: ' ',
|
||||||
|
})(<Input />)}
|
||||||
|
</Form.Item>
|
||||||
|
{this.getPanelItems(
|
||||||
|
panel.panelItem,
|
||||||
|
panel.panelId,
|
||||||
|
)}
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{panel.hasOwnProperty('subFormLists') && (
|
||||||
|
<div>
|
||||||
|
{Object.values(panel.subFormLists).map(
|
||||||
|
(form, i) => {
|
||||||
|
return (
|
||||||
|
<Form name={form.id} key={i}>
|
||||||
|
<Form.Item
|
||||||
|
style={{ display: 'none' }}
|
||||||
|
>
|
||||||
|
{getFieldDecorator(`${form.id}`, {
|
||||||
|
initialValue: ' ',
|
||||||
|
})(<Input />)}
|
||||||
|
</Form.Item>
|
||||||
|
{this.getPanelItems(form.panelItem)}
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Collapse.Panel>
|
||||||
|
</Collapse>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TabPane>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
</Collapse.Panel>
|
||||||
|
</Collapse>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(Form.create()(PolicyInfo));
|
@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* 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 { Card, Col, Icon, Row, Typography } from 'antd';
|
||||||
|
import { withConfigContext } from '../../../../../../../../components/ConfigContext';
|
||||||
|
const { Title, Text } = Typography;
|
||||||
|
|
||||||
|
class ProfileOverview extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.config = this.props.context;
|
||||||
|
this.state = {
|
||||||
|
data: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { policyData } = this.props;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div style={{ marginTop: 20 }}>
|
||||||
|
<div>
|
||||||
|
<Title level={4}>Policy Overview</Title>
|
||||||
|
</div>
|
||||||
|
<Card>
|
||||||
|
<div style={{ paddingLeft: 4 }}>
|
||||||
|
<Row style={{ marginTop: 8 }}>
|
||||||
|
<Col span={8}>
|
||||||
|
<Text>Platform</Text>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<Text>{policyData.profile.deviceType.toUpperCase()}</Text>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<hr style={{ backgroundColor: 'grey' }} />
|
||||||
|
<Row style={{ marginTop: 15 }}>
|
||||||
|
<Col span={8}>
|
||||||
|
<Text>Groups</Text>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<Text>{policyData.deviceGroups}</Text>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<hr />
|
||||||
|
<Row style={{ marginTop: 15 }}>
|
||||||
|
<Col span={8}>
|
||||||
|
<Text>Action upon non-compliance</Text>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<Text>{policyData.compliance.toUpperCase()}</Text>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<hr />
|
||||||
|
<Row style={{ marginTop: 15 }}>
|
||||||
|
<Col span={8}>
|
||||||
|
<Text>Status</Text>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<Text>
|
||||||
|
{policyData.active ? (
|
||||||
|
<span>
|
||||||
|
<Icon
|
||||||
|
type="exclamation-circle"
|
||||||
|
style={{ color: '#6ab04c' }}
|
||||||
|
/>
|
||||||
|
Active
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span>
|
||||||
|
<Icon
|
||||||
|
type="exclamation-circle"
|
||||||
|
style={{ color: '#f9ca24' }}
|
||||||
|
/>
|
||||||
|
Inactive
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{policyData.updated ? <span>/Updated</span> : <span></span>}
|
||||||
|
</Text>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<hr />
|
||||||
|
<Row style={{ marginTop: 15 }}>
|
||||||
|
<Col span={8}>
|
||||||
|
<Text>Assigned Roles</Text>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>{policyData.roles}</Col>
|
||||||
|
</Row>
|
||||||
|
<hr />
|
||||||
|
<Row style={{ marginTop: 15 }}>
|
||||||
|
<Col span={8}>
|
||||||
|
<Text type={8}>Policy Type</Text>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<Text>{policyData.policyType}</Text>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
<div style={{ marginTop: 20 }}>
|
||||||
|
<Title level={4}>Description</Title>
|
||||||
|
<Card>
|
||||||
|
<Row>
|
||||||
|
<Col span={4}>
|
||||||
|
<Text>{policyData.description}</Text>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(ProfileOverview);
|
@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* 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 { Col, message, notification } from 'antd';
|
||||||
|
import { withConfigContext } from '../../../../../../components/ConfigContext';
|
||||||
|
import PolicyInfo from './component/PolicyInfo';
|
||||||
|
import ProfileOverview from './component/ProfileOverview';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
class PolicyProfile extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.config = this.props.context;
|
||||||
|
this.state = {
|
||||||
|
policyId: this.props.policyId,
|
||||||
|
policyData: null,
|
||||||
|
policyUIConfigurationsList: [],
|
||||||
|
policyFeatureList: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.getSelectedPolicy(this.props.policyId);
|
||||||
|
}
|
||||||
|
|
||||||
|
getSelectedPolicy = policyId => {
|
||||||
|
let apiUrl =
|
||||||
|
window.location.origin +
|
||||||
|
this.config.serverConfig.invoker.uri +
|
||||||
|
this.config.serverConfig.invoker.deviceMgt +
|
||||||
|
'/policies/' +
|
||||||
|
policyId;
|
||||||
|
|
||||||
|
// send request to the invokers
|
||||||
|
axios
|
||||||
|
.get(apiUrl)
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
this.setState({
|
||||||
|
policyData: res.data.data,
|
||||||
|
policyFeatureList: res.data.data.profile.profileFeaturesList,
|
||||||
|
});
|
||||||
|
this.getPolicyConfigJson(res.data.data.profile.deviceType);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.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 selected policy.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
getPolicyConfigJson = type => {
|
||||||
|
this.setState({ isLoading: true });
|
||||||
|
|
||||||
|
let apiUrl =
|
||||||
|
window.location.origin +
|
||||||
|
this.config.serverConfig.invoker.uri +
|
||||||
|
this.config.serverConfig.invoker.deviceMgt +
|
||||||
|
'/device-types/' +
|
||||||
|
type +
|
||||||
|
'/ui-policy-configurations';
|
||||||
|
// send request to the invokers
|
||||||
|
axios
|
||||||
|
.get(apiUrl)
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
this.setState({
|
||||||
|
isLoading: false,
|
||||||
|
policyUIConfigurationsList: 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 Policy details.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.setState({ isLoading: false });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
policyData,
|
||||||
|
policyUIConfigurationsList,
|
||||||
|
policyFeatureList,
|
||||||
|
} = this.state;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Col span={16} offset={4}>
|
||||||
|
{/* <Card style={{ marginTop: 24 }}>*/}
|
||||||
|
<div>
|
||||||
|
{policyData != null && (
|
||||||
|
<ProfileOverview
|
||||||
|
policyId={this.props.policyId}
|
||||||
|
policyData={policyData}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{policyData != null && (
|
||||||
|
<PolicyInfo
|
||||||
|
policyId={this.state.policyId}
|
||||||
|
policyFeatureList={policyFeatureList}
|
||||||
|
policyUIConfigurationsList={policyUIConfigurationsList}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(PolicyProfile);
|
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* 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, { Component } from 'react';
|
||||||
|
import { Breadcrumb, Icon, PageHeader } from 'antd';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import EditPolicy from '../../components/EditPolicy';
|
||||||
|
import { withConfigContext } from '../../../../../../components/ConfigContext';
|
||||||
|
class EditSelectedPolicy extends Component {
|
||||||
|
routes;
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.routes = props.routes;
|
||||||
|
this.config = this.props.context;
|
||||||
|
this.state = {
|
||||||
|
data: {},
|
||||||
|
policyOverview: {},
|
||||||
|
policyId: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
match: { params },
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
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>Create new policy on IoT Server.</Paragraph>*/}
|
||||||
|
</div>
|
||||||
|
<div style={{ borderRadius: 5 }}>
|
||||||
|
<EditPolicy policyId={params.policyId} />
|
||||||
|
</div>
|
||||||
|
</PageHeader>
|
||||||
|
<div
|
||||||
|
style={{ background: '#f0f2f5', padding: 24, minHeight: 720 }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default withConfigContext(EditSelectedPolicy);
|
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* 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, { Component } from 'react';
|
||||||
|
import { Breadcrumb, Icon, PageHeader } from 'antd';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import { withConfigContext } from '../../../../../../components/ConfigContext';
|
||||||
|
import PolicyProfile from '../../components/PolicyProfile';
|
||||||
|
class ViewPolicy extends Component {
|
||||||
|
routes;
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.routes = props.routes;
|
||||||
|
this.config = this.props.context;
|
||||||
|
this.state = {
|
||||||
|
data: {},
|
||||||
|
policyOverview: {},
|
||||||
|
policyId: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
match: { params },
|
||||||
|
} = this.props;
|
||||||
|
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>Create new policy on IoT Server.</Paragraph>*/}
|
||||||
|
</div>
|
||||||
|
<div style={{ borderRadius: 5 }}>
|
||||||
|
<PolicyProfile policyId={params.policyId} />
|
||||||
|
</div>
|
||||||
|
</PageHeader>
|
||||||
|
<div
|
||||||
|
style={{ background: '#f0f2f5', padding: 24, minHeight: 720 }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default withConfigContext(ViewPolicy);
|
@ -0,0 +1,27 @@
|
|||||||
|
package org.wso2.carbon.device.mgt.extensions.device.type.template.config;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
|
||||||
|
public class SubPanelValuesList {
|
||||||
|
@XmlElement(name = "PanelSwitch")
|
||||||
|
private String itemSwitch;
|
||||||
|
|
||||||
|
@XmlElement(name = "PayloadKey")
|
||||||
|
private String itemPayload;
|
||||||
|
|
||||||
|
public String getSwitchItem() {
|
||||||
|
return itemSwitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSwitchItem(String itemSwitch) {
|
||||||
|
this.itemSwitch = itemSwitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPayloadItem() {
|
||||||
|
return itemPayload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPayloadItem(String itemPayload) {
|
||||||
|
this.itemPayload = itemPayload;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue