blob: d699f781c356818d4ccf625a64e61ca971529a1c [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';
sebdetb8831e52021-03-12 19:30:22 +010043import DehazeIcon from '@material-ui/icons/Dehaze';
44import ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos';
45import AddIcon from '@material-ui/icons/Add';
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);
sebdetb8831e52021-03-12 19:30:22 +0100191 this.getAllPolicies = this.getAllPolicies.bind(this);
192 this.getAllToscaModels = this.getAllToscaModels.bind(this);
sebdeteb8e3f12021-01-24 18:12:36 +0100193 this.getAllPolicies();
sebdet1e2760e2021-02-26 19:14:03 +0100194 this.getAllToscaModels();
195 }
sebdeteb8e3f12021-01-24 18:12:36 +0100196
sebdet1e2760e2021-02-26 19:14:03 +0100197 getAllToscaModels() {
198 PolicyToscaService.getToscaPolicyModels().then(toscaModelsList => {
199 this.setState({ toscaModelsListData: toscaModelsList });
200 });
sebdeteb8e3f12021-01-24 18:12:36 +0100201 }
202
203 handlePdpGroupChange(e) {
204 let pdpSplit = e.value.split("/");
205 let selectedPdpGroup = pdpSplit[0];
206 let selectedSubPdpGroup = pdpSplit[1];
207 if (typeof selectedSubPdpGroup !== "undefined") {
sebdet3718a162021-02-12 17:18:47 +0100208 let temp = this.state.policiesListData;
sebdetc427e642021-02-17 17:53:17 +0100209 temp[this.state.selectedRowId]["pdpGroupInfo"] = {"pdpGroup":selectedPdpGroup,"pdpSubGroup":selectedSubPdpGroup};
sebdet3718a162021-02-12 17:18:47 +0100210 this.setState({policiesListData: temp});
sebdeteb8e3f12021-01-24 18:12:36 +0100211 } else {
sebdetc427e642021-02-17 17:53:17 +0100212 delete this.state.policiesListData[this.state.selectedRowId]["pdpGroupInfo"];
sebdeteb8e3f12021-01-24 18:12:36 +0100213 }
214 }
215
216 renderPdpGroupDropBox(dataRow) {
217 let optionItems = [{label: "NOT DEPLOYED", value: "NOT DEPLOYED"}];
218 let selectedItem = {label: "NOT DEPLOYED", value: "NOT DEPLOYED"};
219 if (typeof dataRow.supportedPdpGroups !== "undefined") {
220 for (const pdpGroup of dataRow["supportedPdpGroups"]) {
221 for (const pdpSubGroup of Object.values(pdpGroup)[0]) {
222 optionItems.push({ label: Object.keys(pdpGroup)[0]+"/"+pdpSubGroup,
223 value: Object.keys(pdpGroup)[0]+"/"+pdpSubGroup });
224 }
225 }
226 }
227 if (typeof dataRow.pdpGroupInfo !== "undefined") {
228 selectedItem = {label: dataRow["pdpGroupInfo"]["pdpGroup"]+"/"+dataRow["pdpGroupInfo"]["pdpSubGroup"],
229 value: dataRow["pdpGroupInfo"]["pdpGroup"]+"/"+dataRow["pdpGroupInfo"]["pdpSubGroup"]};
230 }
231 return (<div style={{width: '250px'}}><Select value={selectedItem} options={optionItems} onChange={this.handlePdpGroupChange}/></div>);
232 }
233
234 getAllPolicies() {
235 PolicyService.getPoliciesList().then(allPolicies => {
236 this.setState({ policiesListData: allPolicies["policies"] })
237 });
238 }
239
240 handleClose() {
241 this.setState({ show: false });
242 this.props.history.push('/')
243 }
244
sebdet37285472021-02-15 18:09:38 +0100245 handlePrefixGrouping(event) {
246 this.setState({prefixGrouping: event.target.checked});
sebdeta0a3a032021-02-16 14:53:43 +0100247 }
sebdet37285472021-02-15 18:09:38 +0100248
sebdeta0a3a032021-02-16 14:53:43 +0100249 handleDeletePolicy(event, rowData) {
sebdetea2969f2021-02-25 13:58:36 +0100250 PolicyService.deletePolicy(rowData["type"], rowData["type_version"], rowData["name"],rowData["version"]).then(
251 respPolicyDeletion => {
sebdetb8831e52021-03-12 19:30:22 +0100252 if (typeof(respPolicyDeletion) === "undefined") {
sebdetea2969f2021-02-25 13:58:36 +0100253 //it indicates a failure
254 this.setState({
255 showFailAlert: true,
256 showMessage: 'Policy Deletion Failure'
257 });
258 } else {
259 this.setState({
260 showSuccessAlert: true,
261 showMessage: 'Policy successfully Deleted'
262 });
263 }
sebdetb8831e52021-03-12 19:30:22 +0100264 this.getAllPolicies();
sebdetea2969f2021-02-25 13:58:36 +0100265 }
266 )
sebdet37285472021-02-15 18:09:38 +0100267 }
268
sebdetc427e642021-02-17 17:53:17 +0100269 disableAlert() {
270 this.setState ({ showSuccessAlert: false, showFailAlert: false });
271 }
272
sebdet1e2760e2021-02-26 19:14:03 +0100273 renderPoliciesTab() {
274 return (
275 <Tab eventKey="policies" title="Policies in Policy Framework">
276 <Modal.Body>
277 <FormControlLabel
278 control={<Switch checked={this.state.prefixGrouping} onChange={this.handlePrefixGrouping} />}
279 label="Group by prefix"
280 />
281 <MaterialTable
282 title={"Policies"}
283 data={this.state.policiesListData}
284 columns={this.state.policyColumnsDefinition}
285 icons={this.state.tableIcons}
286 onRowClick={(event, rowData, togglePanel) => togglePanel()}
287 options={{
288 grouping: true,
289 exportButton: true,
290 headerStyle:rowHeaderStyle,
291 rowStyle: rowData => ({
292 backgroundColor: (this.state.selectedRowId !== -1 && this.state.selectedRowId === rowData.tableData.id) ? '#EEE' : '#FFF'
293 }),
294 actionsColumnIndex: -1
295 }}
296 detailPanel={[
297 {
sebdetb8831e52021-03-12 19:30:22 +0100298 icon: ArrowForwardIosIcon,
sebdet1e2760e2021-02-26 19:14:03 +0100299 tooltip: 'Show Configuration',
300 render: rowData => {
301 return (
302 <DetailedRow>
sebdetb8831e52021-03-12 19:30:22 +0100303 <PolicyEditor policyModelType={rowData["type"]} policyModelTypeVersion={rowData["type_version"]} policyName={rowData["name"]} policyVersion={rowData["version"]} policyProperties={rowData["properties"]} policyUpdateFunction={this.getAllPolicies} />
sebdet1e2760e2021-02-26 19:14:03 +0100304 </DetailedRow>
305 )
306 },
307 },
308 {
sebdetb8831e52021-03-12 19:30:22 +0100309 icon: DehazeIcon,
sebdet1e2760e2021-02-26 19:14:03 +0100310 tooltip: 'Show Raw Data',
311 render: rowData => {
312 return (
313 <DetailedRow>
314 <pre>{JSON.stringify(rowData, null, 2)}</pre>
315 </DetailedRow>
316 )
317 },
318 },
319 ]}
320 actions={[
321 {
322 icon: forwardRef((props, ref) => <DeleteRoundedIcon {...props} ref={ref} />),
323 tooltip: 'Delete Policy',
324 onClick: (event, rowData) => this.handleDeletePolicy(event, rowData)
325 }
326 ]}
327 />
328 </Modal.Body>
329 </Tab>
330 );
331 }
332
333 renderToscaTab() {
334 return (
335 <Tab eventKey="tosca models" title="Tosca Models in Policy Framework">
336 <Modal.Body>
337 <FormControlLabel
338 control={<Switch checked={this.state.prefixGrouping} onChange={this.handlePrefixGrouping} />}
339 label="Group by prefix"
340 />
341 <MaterialTable
342 title={"Tosca Models"}
343 data={this.state.toscaModelsListData}
344 columns={this.state.toscaColumnsDefinition}
345 icons={this.state.tableIcons}
346 onRowClick={(event, rowData, togglePanel) => togglePanel()}
347 options={{
348 grouping: true,
349 exportButton: true,
350 headerStyle:rowHeaderStyle,
351 rowStyle: rowData => ({
352 backgroundColor: (this.state.selectedRowId !== -1 && this.state.selectedRowId === rowData.tableData.id) ? '#EEE' : '#FFF'
353 }),
354 actionsColumnIndex: -1
355 }}
356 detailPanel={[
357 {
sebdetb8831e52021-03-12 19:30:22 +0100358 icon: ArrowForwardIosIcon,
sebdet1e2760e2021-02-26 19:14:03 +0100359 tooltip: 'Show Tosca',
360 render: rowData => {
361 return (
362 <DetailedRow>
363 <ToscaViewer toscaData={rowData} />
364 </DetailedRow>
365 )
366 },
367 },
368 {
sebdetb8831e52021-03-12 19:30:22 +0100369 icon: DehazeIcon,
sebdet1e2760e2021-02-26 19:14:03 +0100370 tooltip: 'Show Raw Data',
371 render: rowData => {
372 return (
373 <DetailedRow>
374 <pre>{JSON.stringify(rowData, null, 2)}</pre>
375 </DetailedRow>
376 )
377 },
378 },
379 {
sebdetb8831e52021-03-12 19:30:22 +0100380 icon: AddIcon,
sebdet1e2760e2021-02-26 19:14:03 +0100381 tooltip: 'Create a policy from this model',
382 render: rowData => {
383 return (
384 <DetailedRow>
sebdetb8831e52021-03-12 19:30:22 +0100385 <PolicyEditor policyModelType={rowData["policyModelType"]} policyModelTypeVersion={rowData["version"]} policyProperties={{}} policyUpdateFunction={this.getAllPolicies} />
sebdet1e2760e2021-02-26 19:14:03 +0100386 </DetailedRow>
387 )
388 },
389 },
390 ]}
sebdet1e2760e2021-02-26 19:14:03 +0100391 />
392 </Modal.Body>
393 </Tab>
394 );
395 }
396
sebdeteb8e3f12021-01-24 18:12:36 +0100397 render() {
398 return (
sebdet37285472021-02-15 18:09:38 +0100399 <ModalStyled size="xl" show={this.state.show} onHide={this.handleClose} backdrop="static" keyboard={false}>
sebdeteb8e3f12021-01-24 18:12:36 +0100400 <Modal.Header closeButton>
401 </Modal.Header>
sebdetea2969f2021-02-25 13:58:36 +0100402 <Tabs id="controlled-tab-example" activeKey={this.state.key} onSelect={key => this.setState({ key, selectedRowData: {} })}>
sebdet1e2760e2021-02-26 19:14:03 +0100403 {this.renderPoliciesTab()}
404 {this.renderToscaTab()}
sebdetea2969f2021-02-25 13:58:36 +0100405 </Tabs>
sebdetc427e642021-02-17 17:53:17 +0100406 <Alert variant="success" show={this.state.showSuccessAlert} onClose={this.disableAlert} dismissible>
sebdetea2969f2021-02-25 13:58:36 +0100407 <DivWhiteSpaceStyled>
408 {this.state.showMessage}
409 </DivWhiteSpaceStyled>
410 </Alert>
411 <Alert variant="danger" show={this.state.showFailAlert} onClose={this.disableAlert} dismissible>
412 <DivWhiteSpaceStyled>
413 {this.state.showMessage}
414 </DivWhiteSpaceStyled>
415 </Alert>
sebdeteb8e3f12021-01-24 18:12:36 +0100416 <Modal.Footer>
417 <Button variant="secondary" onClick={this.handleClose}>Close</Button>
418 </Modal.Footer>
419 </ModalStyled>
420 );
421 }
422 }