Modify the PolicyDeploymentEditor to support checkboxes

Add code to the PolicyDeploymentEditor so that checkboxes are rendered.

Issue-ID: POLICY-2931
Signed-off-by: sebdet <sebastien.determe@intl.att.com>
Change-Id: I3c933272419770595b706f6950f821220a76f789
diff --git a/ui-react/src/components/dialogs/Policy/PolicyDeploymentEditor.js b/ui-react/src/components/dialogs/Policy/PolicyDeploymentEditor.js
index da695ee..d15c739 100644
--- a/ui-react/src/components/dialogs/Policy/PolicyDeploymentEditor.js
+++ b/ui-react/src/components/dialogs/Policy/PolicyDeploymentEditor.js
@@ -25,25 +25,41 @@
 import Modal from 'react-bootstrap/Modal';
 import styled from 'styled-components';
 import Button from 'react-bootstrap/Button';
+import Alert from 'react-bootstrap/Alert';
+import PolicyService from '../../../api/PolicyService';
+import FormGroup from '@material-ui/core/FormGroup';
+import Checkbox from '@material-ui/core/Checkbox';
+import FormControlLabel from '@material-ui/core/FormControlLabel';
 
-const ModalStyled = styled(Modal)`
-    @media (min-width: 500px) {
-        .modal-xl {
-            max-width: 50%;
-        }
-    }
-    background-color: transparent;
+const DivWhiteSpaceStyled = styled.div`
+    white-space: pre;
+`
+
+const PanelDiv = styled.div`
+    text-align: justify;
+    font-size: ${props => props.theme.policyEditorFontSize};
+    background-color: ${props => props.theme.loopViewerBackgroundColor};
 `
 
 export default class PolicyDeploymentEditor extends React.Component {
 
     state = {
             policyData: this.props.policyData,
+            showSuccessAlert: false,
+            showFailAlert: false,
+            checkboxesState: this.createPdpStructure(this.props.policyData),
+            checkboxesInitialState: this.createPdpStructure(this.props.policyData),
     };
 
     constructor(props, context) {
         super(props, context);
         this.handleClose = this.handleClose.bind(this);
+        this.handleUpdatePdpDeployment = this.handleUpdatePdpDeployment.bind(this);
+        this.disableAlert = this.disableAlert.bind(this);
+        this.renderPdpDeploymentCheckboxes = this.renderPdpDeploymentCheckboxes.bind(this);
+        this.createPdpStructure = this.createPdpStructure.bind(this);
+        this.handleCheckboxChange = this.handleCheckboxChange.bind(this);
+        this.createPdpGroupOperations = this.createPdpGroupOperations.bind(this);
     }
 
     handleClose() {
@@ -51,16 +67,107 @@
 
     }
 
+    disableAlert() {
+        this.setState ({ showSuccessAlert: false, showFailAlert: false });
+    }
+
+    createPdpGroupOperations(initialStates, newStates) {
+        let commandsArray = [];
+        initialStates.forEach(initElem => {
+            let newStateFound = newStates.find(newElement => newElement.name === initElem.name);
+            if (initElem.value !== newStateFound.value && initElem.value) {
+                let newPdpGroupsArray = newStateFound.name.split("/");
+                commandsArray.push("DELETE/"+newPdpGroupsArray[0] + "/"+newPdpGroupsArray[1] + "/"+this.state.policyData.name
+                + "/" + this.state.policyData.version);
+            }
+        });
+        return commandsArray.length > 0 ? {"PdpActions":commandsArray} : undefined;
+    }
+
+    handleUpdatePdpDeployment() {
+            let operationsList = this.createPdpGroupOperations(this.state.checkboxesInitialState,
+                                                 this.state.checkboxesState);
+            if (typeof(operationsList) !== "undefined") {
+                PolicyService.updatePdpDeployment(operationsList).then(respPdpDeploymentUpdate => {
+                    if (typeof(respPdpDeploymentUpdate) === "undefined") {
+                        //it indicates a failure
+                        this.setState({
+                            showFailAlert: true,
+                            showMessage: 'Pdp Deployment update Failure'
+                        });
+                    } else {
+                        this.setState({
+                            showSuccessAlert: true,
+                            showMessage: 'Pdp Deployment Update successful'
+                        });
+                        this.props.policiesTableUpdateFunction();
+                    }
+                    this.props.policiesTableUpdateFunction()
+                })
+            } else {
+                this.setState({
+                    showSuccessAlert: true,
+                    showMessage: 'Pdp Deployment: Nothing to change'
+                });
+            }
+    }
+
+    createPdpStructure(policyData) {
+            // Create map with data for all group/subgroup where the policy is deployed
+            let infoPdpMap = new Map();
+            if (typeof policyData.pdpGroupInfo !== "undefined") {
+                policyData["pdpGroupInfo"].forEach(pdpGroupElem => {
+                    let pdpGroupName = Object.keys(pdpGroupElem)[0];
+                    pdpGroupElem[pdpGroupName]["pdpSubgroups"].forEach(pdpSubGroupElem => {
+                        infoPdpMap.set(pdpGroupName + "/" + pdpSubGroupElem["pdpType"], true);
+                    });
+                });
+            }
+            // Create the possible values for pdpgroup/subgroup and tick the ones where policy is deployed
+            let pdpStates = [];
+            if (typeof policyData.supportedPdpGroups !== "undefined") {
+                for (const pdpGroup of policyData["supportedPdpGroups"]) {
+                    let pdpGroupName = Object.keys(pdpGroup)[0];
+                    for (const pdpSubGroup of Object.values(pdpGroup)[0]) {
+                            let fullName = pdpGroupName + "/" + pdpSubGroup;
+                            pdpStates.push({name: fullName,
+                                value: infoPdpMap.get(fullName) !== undefined});
+                    }
+                }
+            }
+            return pdpStates;
+    }
+
+    handleCheckboxChange(event) {
+        const checkboxesArray = this.state.checkboxesState;
+        checkboxesArray.find(element => element.name === event.target.name).value = event.target.checked;
+        this.setState({checkboxesState:checkboxesArray});
+    }
+
+    renderPdpDeploymentCheckboxes() {
+        return this.state.checkboxesState.map(item => {
+            return <FormControlLabel control={<Checkbox checked={item.value} onChange={this.handleCheckboxChange}
+                name={item.name} />} label={item.name} />;
+        });
+    }
+
     render() {
      return (
-             <ModalStyled size="xl" show={this.state.show} onHide={this.handleClose} backdrop="static" keyboard={false}>
-                 <Modal.Header closeButton>
-                 </Modal.Header>
-
-                 <Modal.Footer>
-                     <Button variant="secondary" onClick={this.handleClose}>Close</Button>
-                </Modal.Footer>
-             </ModalStyled>
+        <PanelDiv>
+          <Alert variant="success" show={this.state.showSuccessAlert} onClose={this.disableAlert} dismissible>
+              <DivWhiteSpaceStyled>
+                  {this.state.showMessage}
+              </DivWhiteSpaceStyled>
+          </Alert>
+          <Alert variant="danger" show={this.state.showFailAlert} onClose={this.disableAlert} dismissible>
+              <DivWhiteSpaceStyled>
+                  {this.state.showMessage}
+              </DivWhiteSpaceStyled>
+          </Alert>
+          <Button variant="secondary" title="Update the policy to the specified PDP Groups/Subgroups"
+            onClick={this.handleUpdatePdpDeployment}>Update PDP</Button>
+          <FormGroup>{this.renderPdpDeploymentCheckboxes()}</FormGroup>
+        </PanelDiv>
        );
     }
  }
\ No newline at end of file
diff --git a/ui-react/src/components/dialogs/Policy/PolicyEditor.js b/ui-react/src/components/dialogs/Policy/PolicyEditor.js
index f20650e..8ee4853 100644
--- a/ui-react/src/components/dialogs/Policy/PolicyEditor.js
+++ b/ui-react/src/components/dialogs/Policy/PolicyEditor.js
@@ -33,7 +33,6 @@
 import OnapUtils from '../../../utils/OnapUtils';
 import uuid from 'react-uuid';
 
-//const JSONEditor = require("@json-editor/json-editor").JSONEditor;
 const DivWhiteSpaceStyled = styled.div`
     white-space: pre;
 `
@@ -46,7 +45,6 @@
     border: 1px solid #C0C0C0;
 `
 const PanelDiv = styled.div`
-    margin-top: 20px;
     text-align: justify;
     font-size: ${props => props.theme.policyEditorFontSize};
     background-color: ${props => props.theme.loopViewerBackgroundColor};
@@ -112,17 +110,12 @@
                         showSuccessAlert: true,
                         showMessage: 'Policy '+ this.state.policyName + '/' + this.state.policyVersion + ' created successfully'
                     });
-                    this.props.policyUpdateFunction();
+                    this.props.policiesTableUpdateFunction();
                 }
             })
         }
     }
 
-    bumpVersion(versionToBump) {
-        let semVer = versionToBump.split(".");
-        return parseInt(semVer[0])+1 + "." + semVer[1] + "." + semVer[2];
-    }
-
    getToscaModelForPolicy() {
         PolicyToscaService.getToscaPolicyModel(this.state.policyModelType, this.state.policyModelTypeVersion).then(respJsonPolicyTosca => {
             if (respJsonPolicyTosca !== {}) {
@@ -139,27 +132,10 @@
    }
 
    createJsonEditor(toscaModel, editorData) {
-        /*JSONEditor.defaults.themes.myBootstrap4 = JSONEditor.defaults.themes.bootstrap4.extend({
-                getTab: function(text,tabId) {
-                    var liel = document.createElement('li');
-                    liel.classList.add('nav-item');
-                    var ael = document.createElement("a");
-                    ael.classList.add("nav-link");
-                    ael.setAttribute("style",'padding:10px;max-width:160px;');
-                    ael.setAttribute("href", "#" + tabId);
-                    ael.setAttribute('data-toggle', 'tab');
-                    text.setAttribute("style",'word-wrap:break-word;');
-                    ael.appendChild(text);
-                    liel.appendChild(ael);
-                    return liel;
-                }
-            });*/
-
         return new JSONEditor(document.getElementById(this.state.jsonEditorDivId),
         {
               schema: toscaModel,
               startval: editorData,
-              //theme: 'myBootstrap4',
               theme: 'bootstrap4',
               iconlib: 'fontawesome5',
               object_layout: 'grid',
diff --git a/ui-react/src/components/dialogs/Policy/ToscaViewer.js b/ui-react/src/components/dialogs/Policy/ToscaViewer.js
index 06e8316..d150e39 100644
--- a/ui-react/src/components/dialogs/Policy/ToscaViewer.js
+++ b/ui-react/src/components/dialogs/Policy/ToscaViewer.js
@@ -26,8 +26,7 @@
 import styled from 'styled-components';
 import Button from 'react-bootstrap/Button';
 
-const JsonEditorDiv = styled.div`
-    margin-top: 20px;
+const ToscaDiv = styled.div`
     background-color: ${props => props.theme.toscaTextareaBackgroundColor};
     text-align: justify;
     font-size: ${props => props.theme.toscaTextareaFontSize};
@@ -57,11 +56,11 @@
 
    render() {
        return (
-                    <JsonEditorDiv>
+                    <ToscaDiv>
                         <pre>{this.state.yamlPolicyTosca}</pre>
                         <Button variant="secondary" title="Create a new policy version from the defined parameters"
                             onClick={this.handleCreateNewVersion}>Create New Version</Button>
-                    </JsonEditorDiv>
+                    </ToscaDiv>
        );
    }
 }
\ No newline at end of file
diff --git a/ui-react/src/components/dialogs/Policy/ViewAllPolicies.js b/ui-react/src/components/dialogs/Policy/ViewAllPolicies.js
index 48d52a1..f986dff 100644
--- a/ui-react/src/components/dialogs/Policy/ViewAllPolicies.js
+++ b/ui-react/src/components/dialogs/Policy/ViewAllPolicies.js
@@ -75,7 +75,8 @@
     font-size: ${props => props.theme.policyEditorFontSize};
     width: 97%;
     margin-left: auto;
-    margin-right: 0;
+    margin-right: auto;
+    margin-top: 20px;
 `
 
 
@@ -291,13 +292,14 @@
                                   render: rowData => {
                                     return (
                                         <DetailedRow>
-                                            <PolicyEditor policyModelType={rowData["type"]} policyModelTypeVersion={rowData["type_version"]} policyName={rowData["name"]} policyVersion={rowData["version"]} policyProperties={rowData["properties"]} policyUpdateFunction={this.getAllPolicies} />
+                                            <PolicyEditor policyModelType={rowData["type"]} policyModelTypeVersion={rowData["type_version"]} policyName={rowData["name"]} policyVersion={rowData["version"]} policyProperties={rowData["properties"]} policiesTableUpdateFunction={this.getAllPolicies} />
                                         </DetailedRow>
                                     )
                                   },
                                 },
                                 {
                                   icon: DehazeIcon,
+                                  openIcon: DehazeIcon,
                                   tooltip: 'Show Raw Data',
                                   render: rowData => {
                                     return (
@@ -309,10 +311,13 @@
                                 },
                                 {
                                   icon: PublishIcon,
+                                  openIcon: PublishIcon,
                                   tooltip: 'PDP Group Deployment',
                                   render: rowData => {
                                     return (
-                                        <PolicyDeploymentEditor policyData={rowData}/>
+                                        <DetailedRow>
+                                            <PolicyDeploymentEditor policyData={rowData} policiesTableUpdateFunction={this.getAllPolicies} />
+                                        </DetailedRow>
                                     )
                                   },
                                 }
@@ -367,6 +372,7 @@
                                 },
                                 {
                                   icon: DehazeIcon,
+                                  openIcon: DehazeIcon,
                                   tooltip: 'Show Raw Data',
                                   render: rowData => {
                                     return (
@@ -378,11 +384,12 @@
                                 },
                                 {
                                   icon: AddIcon,
+                                  openIcon: AddIcon,
                                   tooltip: 'Create a policy from this model',
                                   render: rowData => {
                                     return (
                                         <DetailedRow>
-                                            <PolicyEditor policyModelType={rowData["policyModelType"]} policyModelTypeVersion={rowData["version"]} policyProperties={{}} policyUpdateFunction={this.getAllPolicies} />
+                                            <PolicyEditor policyModelType={rowData["policyModelType"]} policyModelTypeVersion={rowData["version"]} policyProperties={{}} policiesTableUpdateFunction={this.getAllPolicies} />
                                         </DetailedRow>
                                     )
                                   },