blob: 04965352bc46c7afd94b8d4b47c361145589eb4e [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';
sebdetee233562021-03-22 18:55:46 +010046import PublishIcon from '@material-ui/icons/Publish';
sebdet37285472021-02-15 18:09:38 +010047import 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';
sebdetee233562021-03-22 18:55:46 +010051import Select from '@material-ui/core/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';
sebdetee233562021-03-22 18:55:46 +010057import PolicyDeploymentEditor from './PolicyDeploymentEditor';
sebdetb496fda2021-03-30 00:30:49 +020058import PoliciesTreeViewer from './PoliciesTreeViewer';
sebdetd1ed0a92021-04-21 16:28:33 +020059import PolicyToscaFileSelector from './PolicyToscaFileSelector';
sebdetc427e642021-02-17 17:53:17 +010060
61const DivWhiteSpaceStyled = styled.div`
sebdetea2969f2021-02-25 13:58:36 +010062 white-space: pre;
sebdetc427e642021-02-17 17:53:17 +010063`
sebdeteb8e3f12021-01-24 18:12:36 +010064
65const ModalStyled = styled(Modal)`
sebdetee233562021-03-22 18:55:46 +010066 @media (min-width: 800px) {
sebdet3718a162021-02-12 17:18:47 +010067 .modal-xl {
68 max-width: 96%;
69 }
70 }
sebdeteb8e3f12021-01-24 18:12:36 +010071 background-color: transparent;
72`
sebdet1e2760e2021-02-26 19:14:03 +010073const DetailedRow = styled.div`
74 margin: 0 auto;
75 background-color: ${props => props.theme.policyEditorBackgroundColor};
76 font-size: ${props => props.theme.policyEditorFontSize};
77 width: 97%;
78 margin-left: auto;
sebdet42fa9f42021-03-26 18:31:08 +010079 margin-right: auto;
80 margin-top: 20px;
sebdet37285472021-02-15 18:09:38 +010081`
82
sebdetb496fda2021-03-30 00:30:49 +020083const PoliciesTreeViewerDiv = styled.div`
84 width: 20%;
85 float: left;
86 left: 0;
87 overflow: auto;
88`
89
90const MaterialTableDiv = styled.div`
91 float: right;
92 width: 80%;
93 left: 20%;
94`
sebdeteb8e3f12021-01-24 18:12:36 +010095
sebdet1e2760e2021-02-26 19:14:03 +010096const standardCellStyle = { backgroundColor: '#039be5', color: '#FFF', border: '1px solid black' };
sebdetee233562021-03-22 18:55:46 +010097const headerStyle = { backgroundColor: '#ddd', border: '2px solid black' };
98const rowHeaderStyle = {backgroundColor:'#ddd', fontSize: '15pt', text: 'bold', border: '1px solid black'};
sebdeteb8e3f12021-01-24 18:12:36 +010099
100export default class ViewAllPolicies extends React.Component {
101 state = {
102 show: true,
sebdeteb8e3f12021-01-24 18:12:36 +0100103 policiesListData: [],
sebdetb496fda2021-03-30 00:30:49 +0200104 policiesListDataFiltered: [],
sebdet1e2760e2021-02-26 19:14:03 +0100105 toscaModelsListData: [],
sebdetb496fda2021-03-30 00:30:49 +0200106 toscaModelsListDataFiltered: [],
sebdet1e2760e2021-02-26 19:14:03 +0100107 jsonEditorForPolicy: new Map(),
sebdetc427e642021-02-17 17:53:17 +0100108 showSuccessAlert: false,
109 showFailAlert: false,
sebdetd1ed0a92021-04-21 16:28:33 +0200110 showFileSelector: false,
sebdeteb8e3f12021-01-24 18:12:36 +0100111 policyColumnsDefinition: [
112 {
sebdeteb8e3f12021-01-24 18:12:36 +0100113 title: "Policy Name", field: "name",
114 cellStyle: standardCellStyle,
115 headerStyle: headerStyle
116 },
117 {
118 title: "Policy Version", field: "version",
119 cellStyle: standardCellStyle,
sebdetee233562021-03-22 18:55:46 +0100120 headerStyle: headerStyle,
sebdeteb8e3f12021-01-24 18:12:36 +0100121 },
122 {
123 title: "Policy Type", field: "type",
124 cellStyle: standardCellStyle,
125 headerStyle: headerStyle
126 },
127 {
128 title: "Policy Type Version", field: "type_version",
129 cellStyle: standardCellStyle,
130 headerStyle: headerStyle
131 },
132 {
sebdetee233562021-03-22 18:55:46 +0100133 title: "Deployable in PDP Group", field: "supportedPdpGroupsString",
134 cellStyle: standardCellStyle,
sebdeteb8e3f12021-01-24 18:12:36 +0100135 headerStyle: headerStyle
136 },
137 {
sebdetee233562021-03-22 18:55:46 +0100138 title: "Deployed in PDP Group", field: "pdpGroupInfoString",
139 cellStyle: standardCellStyle,
sebdeteb8e3f12021-01-24 18:12:36 +0100140 headerStyle: headerStyle
141 }
142 ],
sebdet1e2760e2021-02-26 19:14:03 +0100143 toscaColumnsDefinition: [
144 {
145 title: "Policy Model Type", field: "policyModelType",
146 cellStyle: standardCellStyle,
147 headerStyle: headerStyle
148 },
149 {
150 title: "Policy Acronym", field: "policyAcronym",
151 cellStyle: standardCellStyle,
152 headerStyle: headerStyle
153 },
154 {
155 title: "Version", field: "version",
156 cellStyle: standardCellStyle,
157 headerStyle: headerStyle
158 },
159 {
160 title: "Uploaded By", field: "updatedBy",
161 cellStyle: standardCellStyle,
162 headerStyle: headerStyle
163 },
164 {
165 title: "Uploaded Date", field: "updatedDate", editable: 'never',
166 cellStyle: standardCellStyle,
167 headerStyle: headerStyle
168 }
169 ],
sebdeteb8e3f12021-01-24 18:12:36 +0100170 tableIcons: {
sebdet37285472021-02-15 18:09:38 +0100171 Add: forwardRef((props, ref) => <AddBox {...props} ref={ref} />),
172 Check: forwardRef((props, ref) => <Check {...props} ref={ref} />),
173 Clear: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
sebdet1e2760e2021-02-26 19:14:03 +0100174 Delete: forwardRef((props, ref) => <DeleteRoundedIcon {...props} ref={ref} />),
sebdet37285472021-02-15 18:09:38 +0100175 DetailPanel: forwardRef((props, ref) => <ChevronRight {...props} ref={ref} />),
176 Edit: forwardRef((props, ref) => <Edit {...props} ref={ref} />),
177 Export: forwardRef((props, ref) => <SaveAlt {...props} ref={ref} />),
178 Filter: forwardRef((props, ref) => <FilterList {...props} ref={ref} />),
sebdeteb8e3f12021-01-24 18:12:36 +0100179 FirstPage: forwardRef((props, ref) => <FirstPage {...props} ref={ref} />),
180 LastPage: forwardRef((props, ref) => <LastPage {...props} ref={ref} />),
181 NextPage: forwardRef((props, ref) => <ChevronRight {...props} ref={ref} />),
182 PreviousPage: forwardRef((props, ref) => <ChevronLeft {...props} ref={ref} />),
183 ResetSearch: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
184 Search: forwardRef((props, ref) => <Search {...props} ref={ref} />),
sebdet37285472021-02-15 18:09:38 +0100185 SortArrow: forwardRef((props, ref) => <ArrowDownward {...props} ref={ref} />),
186 ThirdStateCheck: forwardRef((props, ref) => <Remove {...props} ref={ref} />),
187 ViewColumn: forwardRef((props, ref) => <ViewColumn {...props} ref={ref} />)
sebdeteb8e3f12021-01-24 18:12:36 +0100188 }
189 };
190
191 constructor(props, context) {
192 super(props, context);
193 this.handleClose = this.handleClose.bind(this);
sebdeta0a3a032021-02-16 14:53:43 +0100194 this.handleDeletePolicy = this.handleDeletePolicy.bind(this);
sebdetc427e642021-02-17 17:53:17 +0100195 this.disableAlert = this.disableAlert.bind(this);
sebdetb8831e52021-03-12 19:30:22 +0100196 this.getAllPolicies = this.getAllPolicies.bind(this);
197 this.getAllToscaModels = this.getAllToscaModels.bind(this);
sebdetee233562021-03-22 18:55:46 +0100198 this.generateAdditionalPolicyColumns = this.generateAdditionalPolicyColumns.bind(this);
sebdetb496fda2021-03-30 00:30:49 +0200199 this.filterPolicies = this.filterPolicies.bind(this);
200 this.filterTosca = this.filterTosca.bind(this);
sebdetd1ed0a92021-04-21 16:28:33 +0200201 this.showFileSelector = this.showFileSelector.bind(this);
202 this.disableFileSelector = this.disableFileSelector.bind(this);
sebdeteb8e3f12021-01-24 18:12:36 +0100203 this.getAllPolicies();
sebdet1e2760e2021-02-26 19:14:03 +0100204 this.getAllToscaModels();
205 }
sebdeteb8e3f12021-01-24 18:12:36 +0100206
sebdetee233562021-03-22 18:55:46 +0100207 generateAdditionalPolicyColumns(policiesData) {
208 policiesData.forEach(policy => {
209 let supportedPdpGroupsString = "";
210 if (typeof policy.supportedPdpGroups !== "undefined") {
211 for (const pdpGroup of policy["supportedPdpGroups"]) {
212 for (const pdpSubGroup of Object.values(pdpGroup)[0]) {
213 supportedPdpGroupsString += (Object.keys(pdpGroup)[0] + "/" + pdpSubGroup + "\r\n");
214 }
215 }
216 policy["supportedPdpGroupsString"] = supportedPdpGroupsString;
217 }
218
219 let infoPdpGroup = "";
220 if (typeof policy.pdpGroupInfo !== "undefined") {
221 policy["pdpGroupInfo"].forEach(pdpGroupElem => {
222 let groupName = Object.keys(pdpGroupElem)[0];
223 pdpGroupElem[groupName]["pdpSubgroups"].forEach(pdpSubGroupElem => {
224 infoPdpGroup += (groupName + "/" + pdpSubGroupElem["pdpType"] + " ("
225 + pdpGroupElem[groupName]["pdpGroupState"] + ")" + "\r\n");
226 });
227 policy["pdpGroupInfoString"] = infoPdpGroup;
228 });
229 }
230 });
231 }
232
sebdet1e2760e2021-02-26 19:14:03 +0100233 getAllToscaModels() {
234 PolicyToscaService.getToscaPolicyModels().then(toscaModelsList => {
sebdetb496fda2021-03-30 00:30:49 +0200235 this.setState({ toscaModelsListData: toscaModelsList,
236 toscaModelsListDataFiltered: toscaModelsList
237 });
sebdet1e2760e2021-02-26 19:14:03 +0100238 });
sebdeteb8e3f12021-01-24 18:12:36 +0100239 }
240
sebdeteb8e3f12021-01-24 18:12:36 +0100241 getAllPolicies() {
242 PolicyService.getPoliciesList().then(allPolicies => {
sebdetee233562021-03-22 18:55:46 +0100243 this.generateAdditionalPolicyColumns(allPolicies["policies"])
sebdetb496fda2021-03-30 00:30:49 +0200244 this.setState({ policiesListData: allPolicies["policies"],
245 policiesListDataFiltered: allPolicies["policies"],
246 })
sebdeteb8e3f12021-01-24 18:12:36 +0100247 });
sebdetee233562021-03-22 18:55:46 +0100248
sebdeteb8e3f12021-01-24 18:12:36 +0100249 }
250
251 handleClose() {
252 this.setState({ show: false });
253 this.props.history.push('/')
254 }
255
sebdeta0a3a032021-02-16 14:53:43 +0100256 handleDeletePolicy(event, rowData) {
sebdetea2969f2021-02-25 13:58:36 +0100257 PolicyService.deletePolicy(rowData["type"], rowData["type_version"], rowData["name"],rowData["version"]).then(
258 respPolicyDeletion => {
sebdetb8831e52021-03-12 19:30:22 +0100259 if (typeof(respPolicyDeletion) === "undefined") {
sebdetea2969f2021-02-25 13:58:36 +0100260 //it indicates a failure
261 this.setState({
262 showFailAlert: true,
263 showMessage: 'Policy Deletion Failure'
264 });
265 } else {
266 this.setState({
267 showSuccessAlert: true,
268 showMessage: 'Policy successfully Deleted'
269 });
sebdetd1ed0a92021-04-21 16:28:33 +0200270 this.getAllPolicies();
sebdetea2969f2021-02-25 13:58:36 +0100271 }
272 }
273 )
sebdet37285472021-02-15 18:09:38 +0100274 }
275
sebdetc427e642021-02-17 17:53:17 +0100276 disableAlert() {
277 this.setState ({ showSuccessAlert: false, showFailAlert: false });
278 }
279
sebdetb496fda2021-03-30 00:30:49 +0200280 filterPolicies(prefixForFiltering) {
281 this.setState({policiesListDataFiltered: this.state.policiesListData.filter(element => element.name.startsWith(prefixForFiltering))});
282 }
283
284 filterTosca(prefixForFiltering) {
285 this.setState({toscaModelsListDataFiltered: this.state.toscaModelsListData.filter(element => element.policyModelType.startsWith(prefixForFiltering))});
286 }
287
sebdetd1ed0a92021-04-21 16:28:33 +0200288 showFileSelector() {
289 this.setState({showFileSelector:true});
290 }
291
292 disableFileSelector() {
293 this.setState({showFileSelector:false});
294 }
295
sebdet1e2760e2021-02-26 19:14:03 +0100296 renderPoliciesTab() {
297 return (
298 <Tab eventKey="policies" title="Policies in Policy Framework">
299 <Modal.Body>
sebdetb496fda2021-03-30 00:30:49 +0200300 <div>
301 <PoliciesTreeViewerDiv>
302 <PoliciesTreeViewer policiesData={this.state.policiesListData} valueForTreeCreation="name" policiesFilterFunction={this.filterPolicies} />
303 </PoliciesTreeViewerDiv>
304 <MaterialTableDiv>
305 <MaterialTable
306 title={"Policies"}
307 data={this.state.policiesListDataFiltered}
308 columns={this.state.policyColumnsDefinition}
309 icons={this.state.tableIcons}
310 onRowClick={(event, rowData, togglePanel) => togglePanel()}
311 options={{
312 grouping: true,
313 exportButton: true,
314 headerStyle:rowHeaderStyle,
315 actionsColumnIndex: -1
316 }}
317 detailPanel={[
318 {
319 icon: ArrowForwardIosIcon,
320 tooltip: 'Show Configuration',
321 render: rowData => {
322 return (
323 <DetailedRow>
324 <PolicyEditor policyModelType={rowData["type"]} policyModelTypeVersion={rowData["type_version"]}
325 policyName={rowData["name"]} policyVersion={rowData["version"]} policyProperties={rowData["properties"]}
326 policiesTableUpdateFunction={this.getAllPolicies} />
327 </DetailedRow>
328 )
329 },
330 },
331 {
332 icon: DehazeIcon,
333 openIcon: DehazeIcon,
334 tooltip: 'Show Raw Data',
335 render: rowData => {
336 return (
337 <DetailedRow>
338 <pre>{JSON.stringify(rowData, null, 2)}</pre>
339 </DetailedRow>
340 )
341 },
342 },
343 {
344 icon: PublishIcon,
345 openIcon: PublishIcon,
346 tooltip: 'PDP Group Deployment',
347 render: rowData => {
348 return (
349 <DetailedRow>
350 <PolicyDeploymentEditor policyData={rowData} policiesTableUpdateFunction={this.getAllPolicies} />
351 </DetailedRow>
352 )
353 },
354 }
355 ]}
356 actions={[
357 {
sebdetd1ed0a92021-04-21 16:28:33 +0200358 icon: DeleteRoundedIcon,
sebdetb496fda2021-03-30 00:30:49 +0200359 tooltip: 'Delete Policy',
360 onClick: (event, rowData) => this.handleDeletePolicy(event, rowData)
361 }
362 ]}
sebdet1e2760e2021-02-26 19:14:03 +0100363 />
sebdetb496fda2021-03-30 00:30:49 +0200364 </MaterialTableDiv>
365 </div>
sebdet1e2760e2021-02-26 19:14:03 +0100366 </Modal.Body>
367 </Tab>
368 );
369 }
370
371 renderToscaTab() {
372 return (
373 <Tab eventKey="tosca models" title="Tosca Models in Policy Framework">
374 <Modal.Body>
sebdetb496fda2021-03-30 00:30:49 +0200375 <div>
376 <PoliciesTreeViewerDiv>
377 <PoliciesTreeViewer policiesData={this.state.toscaModelsListData} valueForTreeCreation="policyModelType" policiesFilterFunction={this.filterTosca} />
378 </PoliciesTreeViewerDiv>
379 <MaterialTableDiv>
380 <MaterialTable
381 title={"Tosca Models"}
382 data={this.state.toscaModelsListDataFiltered}
383 columns={this.state.toscaColumnsDefinition}
384 icons={this.state.tableIcons}
385 onRowClick={(event, rowData, togglePanel) => togglePanel()}
386 options={{
387 grouping: true,
388 exportButton: true,
389 headerStyle:rowHeaderStyle,
390 actionsColumnIndex: -1
391 }}
sebdetd1ed0a92021-04-21 16:28:33 +0200392 actions={[
393 {
394 icon: AddIcon,
395 tooltip: 'Add New Tosca Model',
396 isFreeAction: true,
397 onClick: () => this.showFileSelector()
398 }
399 ]}
sebdetb496fda2021-03-30 00:30:49 +0200400 detailPanel={[
401 {
402 icon: ArrowForwardIosIcon,
403 tooltip: 'Show Tosca',
404 render: rowData => {
405 return (
406 <DetailedRow>
407 <ToscaViewer toscaData={rowData} />
408 </DetailedRow>
409 )
410 },
411 },
412 {
413 icon: DehazeIcon,
414 openIcon: DehazeIcon,
415 tooltip: 'Show Raw Data',
416 render: rowData => {
417 return (
418 <DetailedRow>
419 <pre>{JSON.stringify(rowData, null, 2)}</pre>
420 </DetailedRow>
421 )
422 },
423 },
424 {
425 icon: AddIcon,
426 openIcon: AddIcon,
427 tooltip: 'Create a policy from this model',
428 render: rowData => {
429 return (
430 <DetailedRow>
431 <PolicyEditor policyModelType={rowData["policyModelType"]} policyModelTypeVersion={rowData["version"]} policyProperties={{}} policiesTableUpdateFunction={this.getAllPolicies} />
432 </DetailedRow>
433 )
434 },
435 },
436 ]}
437 />
438 </MaterialTableDiv>
439 </div>
sebdet1e2760e2021-02-26 19:14:03 +0100440 </Modal.Body>
441 </Tab>
442 );
443 }
444
sebdeteb8e3f12021-01-24 18:12:36 +0100445 render() {
sebdetd1ed0a92021-04-21 16:28:33 +0200446 return (
447 <React.Fragment>
sebdet37285472021-02-15 18:09:38 +0100448 <ModalStyled size="xl" show={this.state.show} onHide={this.handleClose} backdrop="static" keyboard={false}>
sebdeteb8e3f12021-01-24 18:12:36 +0100449 <Modal.Header closeButton>
450 </Modal.Header>
sebdetea2969f2021-02-25 13:58:36 +0100451 <Tabs id="controlled-tab-example" activeKey={this.state.key} onSelect={key => this.setState({ key, selectedRowData: {} })}>
sebdet1e2760e2021-02-26 19:14:03 +0100452 {this.renderPoliciesTab()}
453 {this.renderToscaTab()}
sebdetea2969f2021-02-25 13:58:36 +0100454 </Tabs>
sebdetc427e642021-02-17 17:53:17 +0100455 <Alert variant="success" show={this.state.showSuccessAlert} onClose={this.disableAlert} dismissible>
sebdetea2969f2021-02-25 13:58:36 +0100456 <DivWhiteSpaceStyled>
457 {this.state.showMessage}
458 </DivWhiteSpaceStyled>
459 </Alert>
460 <Alert variant="danger" show={this.state.showFailAlert} onClose={this.disableAlert} dismissible>
461 <DivWhiteSpaceStyled>
462 {this.state.showMessage}
463 </DivWhiteSpaceStyled>
464 </Alert>
sebdeteb8e3f12021-01-24 18:12:36 +0100465 <Modal.Footer>
466 <Button variant="secondary" onClick={this.handleClose}>Close</Button>
467 </Modal.Footer>
sebdetee233562021-03-22 18:55:46 +0100468 </ModalStyled>
sebdetd1ed0a92021-04-21 16:28:33 +0200469 <PolicyToscaFileSelector show={this.state.showFileSelector} disableFunction={this.disableFileSelector} toscaTableUpdateFunction={this.getAllToscaModels}/>
470 </React.Fragment>
sebdeteb8e3f12021-01-24 18:12:36 +0100471 );
472 }
473 }