blob: 1e71bb853445018acb5ebb26d7813eeab7f954eb [file] [log] [blame]
sebdeteb8e3f12021-01-24 18:12:36 +01001/*-
2 * ============LICENSE_START=======================================================
3 * ONAP POLICY-CLAMP
4 * ================================================================================
5 * Copyright (C) 2021 AT&T Intellectual Property. All rights
6 * reserved.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END============================================
20 * ===================================================================
21 *
22 */
23
24import React, { forwardRef } from 'react'
25import Button from 'react-bootstrap/Button';
26import Modal from 'react-bootstrap/Modal';
27import styled from 'styled-components';
sebdet37285472021-02-15 18:09:38 +010028import AddBox from '@material-ui/icons/AddBox';
29import ArrowDownward from '@material-ui/icons/ArrowDownward';
30import Check from '@material-ui/icons/Check';
sebdeteb8e3f12021-01-24 18:12:36 +010031import ChevronLeft from '@material-ui/icons/ChevronLeft';
32import ChevronRight from '@material-ui/icons/ChevronRight';
33import Clear from '@material-ui/icons/Clear';
sebdet1e2760e2021-02-26 19:14:03 +010034import DeleteRoundedIcon from '@material-ui/icons/DeleteRounded';
sebdet37285472021-02-15 18:09:38 +010035import Edit from '@material-ui/icons/Edit';
36import FilterList from '@material-ui/icons/FilterList';
sebdeteb8e3f12021-01-24 18:12:36 +010037import FirstPage from '@material-ui/icons/FirstPage';
38import LastPage from '@material-ui/icons/LastPage';
sebdet37285472021-02-15 18:09:38 +010039import Remove from '@material-ui/icons/Remove';
40import SaveAlt from '@material-ui/icons/SaveAlt';
sebdeteb8e3f12021-01-24 18:12:36 +010041import Search from '@material-ui/icons/Search';
sebdet37285472021-02-15 18:09:38 +010042import ViewColumn from '@material-ui/icons/ViewColumn';
sebdet1e2760e2021-02-26 19:14:03 +010043import DescriptionIcon from '@material-ui/icons/Description';
44import SettingsEthernetIcon from '@material-ui/icons/SettingsEthernet';
45import NoteAddIcon from '@material-ui/icons/NoteAdd';
sebdet37285472021-02-15 18:09:38 +010046import FormControlLabel from '@material-ui/core/FormControlLabel';
47import Switch from '@material-ui/core/Switch';
sebdeteb8e3f12021-01-24 18:12:36 +010048import MaterialTable from "material-table";
sebdeteb8e3f12021-01-24 18:12:36 +010049import PolicyService from '../../../api/PolicyService';
sebdet3718a162021-02-12 17:18:47 +010050import PolicyToscaService from '../../../api/PolicyToscaService';
sebdeteb8e3f12021-01-24 18:12:36 +010051import Select from 'react-select';
sebdetc427e642021-02-17 17:53:17 +010052import Alert from 'react-bootstrap/Alert';
sebdetea2969f2021-02-25 13:58:36 +010053import Tabs from 'react-bootstrap/Tabs';
54import Tab from 'react-bootstrap/Tab';
sebdet1e2760e2021-02-26 19:14:03 +010055import PolicyEditor from './PolicyEditor';
56import ToscaViewer from './ToscaViewer';
sebdetc427e642021-02-17 17:53:17 +010057
58const DivWhiteSpaceStyled = styled.div`
sebdetea2969f2021-02-25 13:58:36 +010059 white-space: pre;
sebdetc427e642021-02-17 17:53:17 +010060`
sebdeteb8e3f12021-01-24 18:12:36 +010061
62const ModalStyled = styled(Modal)`
sebdet1e2760e2021-02-26 19:14:03 +010063 @media (min-width: 1000px) {
sebdet3718a162021-02-12 17:18:47 +010064 .modal-xl {
65 max-width: 96%;
66 }
67 }
sebdeteb8e3f12021-01-24 18:12:36 +010068 background-color: transparent;
69`
sebdet1e2760e2021-02-26 19:14:03 +010070const DetailedRow = styled.div`
71 margin: 0 auto;
72 background-color: ${props => props.theme.policyEditorBackgroundColor};
73 font-size: ${props => props.theme.policyEditorFontSize};
74 width: 97%;
75 margin-left: auto;
76 margin-right: 0;
sebdet37285472021-02-15 18:09:38 +010077`
78
sebdeteb8e3f12021-01-24 18:12:36 +010079
sebdet1e2760e2021-02-26 19:14:03 +010080const standardCellStyle = { backgroundColor: '#039be5', color: '#FFF', border: '1px solid black' };
sebdeteb8e3f12021-01-24 18:12:36 +010081const cellPdpGroupStyle = { backgroundColor: '#039be5', color: '#FFF', border: '1px solid black'};
82const headerStyle = { backgroundColor: '#ddd', border: '2px solid black' };
83const rowHeaderStyle = {backgroundColor:'#ddd', fontSize: '15pt', text: 'bold', border: '1px solid black'};
sebdeteb8e3f12021-01-24 18:12:36 +010084
85export default class ViewAllPolicies extends React.Component {
86 state = {
87 show: true,
88 content: 'Please select a policy to display it',
sebdetc427e642021-02-17 17:53:17 +010089 selectedRowId: -1,
sebdeteb8e3f12021-01-24 18:12:36 +010090 policiesListData: [],
sebdet1e2760e2021-02-26 19:14:03 +010091 toscaModelsListData: [],
92 jsonEditorForPolicy: new Map(),
sebdet37285472021-02-15 18:09:38 +010093 prefixGrouping: false,
sebdetc427e642021-02-17 17:53:17 +010094 showSuccessAlert: false,
95 showFailAlert: false,
sebdeteb8e3f12021-01-24 18:12:36 +010096 policyColumnsDefinition: [
97 {
sebdeteb8e3f12021-01-24 18:12:36 +010098 title: "Policy Name", field: "name",
99 cellStyle: standardCellStyle,
100 headerStyle: headerStyle
101 },
102 {
103 title: "Policy Version", field: "version",
104 cellStyle: standardCellStyle,
105 headerStyle: headerStyle
106 },
107 {
108 title: "Policy Type", field: "type",
109 cellStyle: standardCellStyle,
110 headerStyle: headerStyle
111 },
112 {
113 title: "Policy Type Version", field: "type_version",
114 cellStyle: standardCellStyle,
115 headerStyle: headerStyle
116 },
117 {
118 title: "Deployed in PDP", field: "pdpGroupInfo.pdpGroup",
119 cellStyle: cellPdpGroupStyle,
120 headerStyle: headerStyle,
sebdet37285472021-02-15 18:09:38 +0100121 render: rowData => this.renderPdpGroupDropBox(rowData),
122 grouping: false
sebdeteb8e3f12021-01-24 18:12:36 +0100123 },
124 {
125 title: "PDP Group", field: "pdpGroupInfo.pdpGroup",
126 cellStyle: cellPdpGroupStyle,
127 headerStyle: headerStyle
128 },
129 {
130 title: "PDP SubGroup", field: "pdpGroupInfo.pdpSubGroup",
131 cellStyle: cellPdpGroupStyle,
132 headerStyle: headerStyle
133 }
134 ],
sebdet1e2760e2021-02-26 19:14:03 +0100135 toscaColumnsDefinition: [
136 {
137 title: "Policy Model Type", field: "policyModelType",
138 cellStyle: standardCellStyle,
139 headerStyle: headerStyle
140 },
141 {
142 title: "Policy Acronym", field: "policyAcronym",
143 cellStyle: standardCellStyle,
144 headerStyle: headerStyle
145 },
146 {
147 title: "Version", field: "version",
148 cellStyle: standardCellStyle,
149 headerStyle: headerStyle
150 },
151 {
152 title: "Uploaded By", field: "updatedBy",
153 cellStyle: standardCellStyle,
154 headerStyle: headerStyle
155 },
156 {
157 title: "Uploaded Date", field: "updatedDate", editable: 'never',
158 cellStyle: standardCellStyle,
159 headerStyle: headerStyle
160 }
161 ],
sebdeteb8e3f12021-01-24 18:12:36 +0100162 tableIcons: {
sebdet37285472021-02-15 18:09:38 +0100163 Add: forwardRef((props, ref) => <AddBox {...props} ref={ref} />),
164 Check: forwardRef((props, ref) => <Check {...props} ref={ref} />),
165 Clear: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
sebdet1e2760e2021-02-26 19:14:03 +0100166 Delete: forwardRef((props, ref) => <DeleteRoundedIcon {...props} ref={ref} />),
sebdet37285472021-02-15 18:09:38 +0100167 DetailPanel: forwardRef((props, ref) => <ChevronRight {...props} ref={ref} />),
168 Edit: forwardRef((props, ref) => <Edit {...props} ref={ref} />),
169 Export: forwardRef((props, ref) => <SaveAlt {...props} ref={ref} />),
170 Filter: forwardRef((props, ref) => <FilterList {...props} ref={ref} />),
sebdeteb8e3f12021-01-24 18:12:36 +0100171 FirstPage: forwardRef((props, ref) => <FirstPage {...props} ref={ref} />),
172 LastPage: forwardRef((props, ref) => <LastPage {...props} ref={ref} />),
173 NextPage: forwardRef((props, ref) => <ChevronRight {...props} ref={ref} />),
174 PreviousPage: forwardRef((props, ref) => <ChevronLeft {...props} ref={ref} />),
175 ResetSearch: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
176 Search: forwardRef((props, ref) => <Search {...props} ref={ref} />),
sebdet37285472021-02-15 18:09:38 +0100177 SortArrow: forwardRef((props, ref) => <ArrowDownward {...props} ref={ref} />),
178 ThirdStateCheck: forwardRef((props, ref) => <Remove {...props} ref={ref} />),
179 ViewColumn: forwardRef((props, ref) => <ViewColumn {...props} ref={ref} />)
sebdeteb8e3f12021-01-24 18:12:36 +0100180 }
181 };
182
183 constructor(props, context) {
184 super(props, context);
185 this.handleClose = this.handleClose.bind(this);
186 this.renderPdpGroupDropBox = this.renderPdpGroupDropBox.bind(this);
187 this.handlePdpGroupChange = this.handlePdpGroupChange.bind(this);
sebdet37285472021-02-15 18:09:38 +0100188 this.handlePrefixGrouping = this.handlePrefixGrouping.bind(this);
sebdeta0a3a032021-02-16 14:53:43 +0100189 this.handleDeletePolicy = this.handleDeletePolicy.bind(this);
sebdetc427e642021-02-17 17:53:17 +0100190 this.disableAlert = this.disableAlert.bind(this);
sebdeteb8e3f12021-01-24 18:12:36 +0100191 this.getAllPolicies();
sebdet1e2760e2021-02-26 19:14:03 +0100192 this.getAllToscaModels();
193 }
sebdeteb8e3f12021-01-24 18:12:36 +0100194
sebdet1e2760e2021-02-26 19:14:03 +0100195 getAllToscaModels() {
196 PolicyToscaService.getToscaPolicyModels().then(toscaModelsList => {
197 this.setState({ toscaModelsListData: toscaModelsList });
198 });
sebdeteb8e3f12021-01-24 18:12:36 +0100199 }
200
201 handlePdpGroupChange(e) {
202 let pdpSplit = e.value.split("/");
203 let selectedPdpGroup = pdpSplit[0];
204 let selectedSubPdpGroup = pdpSplit[1];
205 if (typeof selectedSubPdpGroup !== "undefined") {
sebdet3718a162021-02-12 17:18:47 +0100206 let temp = this.state.policiesListData;
sebdetc427e642021-02-17 17:53:17 +0100207 temp[this.state.selectedRowId]["pdpGroupInfo"] = {"pdpGroup":selectedPdpGroup,"pdpSubGroup":selectedSubPdpGroup};
sebdet3718a162021-02-12 17:18:47 +0100208 this.setState({policiesListData: temp});
sebdeteb8e3f12021-01-24 18:12:36 +0100209 } else {
sebdetc427e642021-02-17 17:53:17 +0100210 delete this.state.policiesListData[this.state.selectedRowId]["pdpGroupInfo"];
sebdeteb8e3f12021-01-24 18:12:36 +0100211 }
212 }
213
214 renderPdpGroupDropBox(dataRow) {
215 let optionItems = [{label: "NOT DEPLOYED", value: "NOT DEPLOYED"}];
216 let selectedItem = {label: "NOT DEPLOYED", value: "NOT DEPLOYED"};
217 if (typeof dataRow.supportedPdpGroups !== "undefined") {
218 for (const pdpGroup of dataRow["supportedPdpGroups"]) {
219 for (const pdpSubGroup of Object.values(pdpGroup)[0]) {
220 optionItems.push({ label: Object.keys(pdpGroup)[0]+"/"+pdpSubGroup,
221 value: Object.keys(pdpGroup)[0]+"/"+pdpSubGroup });
222 }
223 }
224 }
225 if (typeof dataRow.pdpGroupInfo !== "undefined") {
226 selectedItem = {label: dataRow["pdpGroupInfo"]["pdpGroup"]+"/"+dataRow["pdpGroupInfo"]["pdpSubGroup"],
227 value: dataRow["pdpGroupInfo"]["pdpGroup"]+"/"+dataRow["pdpGroupInfo"]["pdpSubGroup"]};
228 }
229 return (<div style={{width: '250px'}}><Select value={selectedItem} options={optionItems} onChange={this.handlePdpGroupChange}/></div>);
230 }
231
232 getAllPolicies() {
233 PolicyService.getPoliciesList().then(allPolicies => {
234 this.setState({ policiesListData: allPolicies["policies"] })
235 });
236 }
237
238 handleClose() {
239 this.setState({ show: false });
240 this.props.history.push('/')
241 }
242
sebdet37285472021-02-15 18:09:38 +0100243 handlePrefixGrouping(event) {
244 this.setState({prefixGrouping: event.target.checked});
sebdeta0a3a032021-02-16 14:53:43 +0100245 }
sebdet37285472021-02-15 18:09:38 +0100246
sebdeta0a3a032021-02-16 14:53:43 +0100247 handleDeletePolicy(event, rowData) {
sebdetea2969f2021-02-25 13:58:36 +0100248 PolicyService.deletePolicy(rowData["type"], rowData["type_version"], rowData["name"],rowData["version"]).then(
249 respPolicyDeletion => {
250 if (respPolicyDeletion === "") {
251 //it indicates a failure
252 this.setState({
253 showFailAlert: true,
254 showMessage: 'Policy Deletion Failure'
255 });
256 } else {
257 this.setState({
258 showSuccessAlert: true,
259 showMessage: 'Policy successfully Deleted'
260 });
261 }
262 }
263 )
sebdet37285472021-02-15 18:09:38 +0100264 }
265
sebdetc427e642021-02-17 17:53:17 +0100266 disableAlert() {
267 this.setState ({ showSuccessAlert: false, showFailAlert: false });
268 }
269
sebdet1e2760e2021-02-26 19:14:03 +0100270 renderPoliciesTab() {
271 return (
272 <Tab eventKey="policies" title="Policies in Policy Framework">
273 <Modal.Body>
274 <FormControlLabel
275 control={<Switch checked={this.state.prefixGrouping} onChange={this.handlePrefixGrouping} />}
276 label="Group by prefix"
277 />
278 <MaterialTable
279 title={"Policies"}
280 data={this.state.policiesListData}
281 columns={this.state.policyColumnsDefinition}
282 icons={this.state.tableIcons}
283 onRowClick={(event, rowData, togglePanel) => togglePanel()}
284 options={{
285 grouping: true,
286 exportButton: true,
287 headerStyle:rowHeaderStyle,
288 rowStyle: rowData => ({
289 backgroundColor: (this.state.selectedRowId !== -1 && this.state.selectedRowId === rowData.tableData.id) ? '#EEE' : '#FFF'
290 }),
291 actionsColumnIndex: -1
292 }}
293 detailPanel={[
294 {
295 icon: SettingsEthernetIcon,
296 tooltip: 'Show Configuration',
297 render: rowData => {
298 return (
299 <DetailedRow>
300 <PolicyEditor policyModelType={rowData["type"]} policyModelTypeVersion={rowData["type_version"]} policyName={rowData["name"]} policyVersion={rowData["version"]} policyProperties={rowData["properties"]} />
301 </DetailedRow>
302 )
303 },
304 },
305 {
306 icon: DescriptionIcon,
307 tooltip: 'Show Raw Data',
308 render: rowData => {
309 return (
310 <DetailedRow>
311 <pre>{JSON.stringify(rowData, null, 2)}</pre>
312 </DetailedRow>
313 )
314 },
315 },
316 ]}
317 actions={[
318 {
319 icon: forwardRef((props, ref) => <DeleteRoundedIcon {...props} ref={ref} />),
320 tooltip: 'Delete Policy',
321 onClick: (event, rowData) => this.handleDeletePolicy(event, rowData)
322 }
323 ]}
324 />
325 </Modal.Body>
326 </Tab>
327 );
328 }
329
330 renderToscaTab() {
331 return (
332 <Tab eventKey="tosca models" title="Tosca Models in Policy Framework">
333 <Modal.Body>
334 <FormControlLabel
335 control={<Switch checked={this.state.prefixGrouping} onChange={this.handlePrefixGrouping} />}
336 label="Group by prefix"
337 />
338 <MaterialTable
339 title={"Tosca Models"}
340 data={this.state.toscaModelsListData}
341 columns={this.state.toscaColumnsDefinition}
342 icons={this.state.tableIcons}
343 onRowClick={(event, rowData, togglePanel) => togglePanel()}
344 options={{
345 grouping: true,
346 exportButton: true,
347 headerStyle:rowHeaderStyle,
348 rowStyle: rowData => ({
349 backgroundColor: (this.state.selectedRowId !== -1 && this.state.selectedRowId === rowData.tableData.id) ? '#EEE' : '#FFF'
350 }),
351 actionsColumnIndex: -1
352 }}
353 detailPanel={[
354 {
355 icon: SettingsEthernetIcon,
356 tooltip: 'Show Tosca',
357 render: rowData => {
358 return (
359 <DetailedRow>
360 <ToscaViewer toscaData={rowData} />
361 </DetailedRow>
362 )
363 },
364 },
365 {
366 icon: DescriptionIcon,
367 tooltip: 'Show Raw Data',
368 render: rowData => {
369 return (
370 <DetailedRow>
371 <pre>{JSON.stringify(rowData, null, 2)}</pre>
372 </DetailedRow>
373 )
374 },
375 },
376 {
377 icon: NoteAddIcon,
378 tooltip: 'Create a policy from this model',
379 render: rowData => {
380 return (
381 <DetailedRow>
382 <PolicyEditor policyModelType={rowData["policyModelType"]} policyModelTypeVersion={rowData["version"]} policyProperties={{}} />
383 </DetailedRow>
384 )
385 },
386 },
387 ]}
388 actions={[
389 {
390 icon: forwardRef((props, ref) => <DeleteRoundedIcon {...props} ref={ref} />),
391 tooltip: 'Delete Tosca Model',
392 onClick: (event, rowData) => this.handleDeletePolicy(event, rowData)
393 }
394 ]}
395 />
396 </Modal.Body>
397 </Tab>
398 );
399 }
400
sebdeteb8e3f12021-01-24 18:12:36 +0100401 render() {
402 return (
sebdet37285472021-02-15 18:09:38 +0100403 <ModalStyled size="xl" show={this.state.show} onHide={this.handleClose} backdrop="static" keyboard={false}>
sebdeteb8e3f12021-01-24 18:12:36 +0100404 <Modal.Header closeButton>
405 </Modal.Header>
sebdetea2969f2021-02-25 13:58:36 +0100406 <Tabs id="controlled-tab-example" activeKey={this.state.key} onSelect={key => this.setState({ key, selectedRowData: {} })}>
sebdet1e2760e2021-02-26 19:14:03 +0100407 {this.renderPoliciesTab()}
408 {this.renderToscaTab()}
sebdetea2969f2021-02-25 13:58:36 +0100409 </Tabs>
sebdetc427e642021-02-17 17:53:17 +0100410 <Alert variant="success" show={this.state.showSuccessAlert} onClose={this.disableAlert} dismissible>
sebdetea2969f2021-02-25 13:58:36 +0100411 <DivWhiteSpaceStyled>
412 {this.state.showMessage}
413 </DivWhiteSpaceStyled>
414 </Alert>
415 <Alert variant="danger" show={this.state.showFailAlert} onClose={this.disableAlert} dismissible>
416 <DivWhiteSpaceStyled>
417 {this.state.showMessage}
418 </DivWhiteSpaceStyled>
419 </Alert>
sebdeteb8e3f12021-01-24 18:12:36 +0100420 <Modal.Footer>
421 <Button variant="secondary" onClick={this.handleClose}>Close</Button>
422 </Modal.Footer>
423 </ModalStyled>
424 );
425 }
426 }