Add Tosca Monitoring App to Policy Gui

Implemented the prototype monitoring gui onto the policy gui

Issue-ID: POLICY-3357
Change-Id: Iabf25cd6c26d4e65a7a963cdd79c25aa91c39736
Signed-off-by: brunomilitzer <bruno.militzer@est.tech>
diff --git a/gui-clamp/ui-react-lib/libIndex.js b/gui-clamp/ui-react-lib/libIndex.js
index 8f9eebd..21decbc 100644
--- a/gui-clamp/ui-react-lib/libIndex.js
+++ b/gui-clamp/ui-react-lib/libIndex.js
@@ -17,9 +17,9 @@
  * 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.
- * ============LICENSE_END============================================
- * ===================================================================
  *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
  */
 
 export { default as CsvToJson } from '../ui-react/src/utils/CsvToJson';
@@ -55,6 +55,8 @@
 export { default as PolicyDeploymentEditor } from '../ui-react/src/components/dialogs/Policy/PolicyDeploymentEditor';
 export { default as PoliciesTreeViewer } from '../ui-react/src/components/dialogs/Policy/PoliciesTreeViewer';
 export { default as PolicyToscaFileSelector } from '../ui-react/src/components/dialogs/Policy/PolicyToscaFileSelector';
+export { default as MonitoringControlLoopModal } from '../ui-react/src/components/dialogs/ControlLoop/MonitoringControlLoopModal';
+export { default as ControlLoopService } from '../ui-react/src/api/ControlLoopService';
 export { default as GetLocalToscaFileForUpload } from '../ui-react/src/components/dialogs/GetLocalToscaFileForUpload';
 export { default as ReadAndConvertYaml } from '../ui-react/src/components/dialogs/ReadAndConvertYaml';
 export { default as UploadToscaFile } from '../ui-react/src/api/UploadToscaFile';
diff --git a/gui-clamp/ui-react/src/LoopUI.js b/gui-clamp/ui-react/src/LoopUI.js
index 6904122..4009bf1 100644
--- a/gui-clamp/ui-react/src/LoopUI.js
+++ b/gui-clamp/ui-react/src/LoopUI.js
@@ -17,6 +17,7 @@
  * SPDX-License-Identifier: Apache-2.0
  * ============LICENSE_END=========================================================
  */
+
 import React from 'react';
 import styled from 'styled-components';
 import MenuBar from './components/menu/MenuBar';
@@ -51,6 +52,7 @@
 
 import { Link } from 'react-router-dom';
 import ReadAndConvertYaml from "./components/dialogs/ReadAndConvertYaml";
+import MonitoringControlLoopModal from "./components/dialogs/ControlLoop/MonitoringControlLoopModal";
 import GetLocalToscaFileForUpload from "./components/dialogs/GetLocalToscaFileForUpload";
 
 const StyledMainDiv = styled.div`
@@ -380,6 +382,7 @@
                                                                               showSucAlert={ this.showSucAlert }
                                                                               showFailAlert={ this.showFailAlert }/>) }
         />
+        <Route path="/monitoring" render={ (routeProps) => (<MonitoringControlLoopModal { ...routeProps } />) }/>
       </React.Fragment>
     );
   }
diff --git a/gui-clamp/ui-react/src/__snapshots__/LoopUI.test.js.snap b/gui-clamp/ui-react/src/__snapshots__/LoopUI.test.js.snap
index e9ed817..6d25823 100644
--- a/gui-clamp/ui-react/src/__snapshots__/LoopUI.test.js.snap
+++ b/gui-clamp/ui-react/src/__snapshots__/LoopUI.test.js.snap
@@ -81,6 +81,10 @@
     path="/refreshStatus"
     render={[Function]}
   />
+  <Route
+    path="/monitoring"
+    render={[Function]}
+  />
   <div />
   <div>
     <Alert
diff --git a/gui-clamp/ui-react/src/__snapshots__/OnapClamp.test.js.snap b/gui-clamp/ui-react/src/__snapshots__/OnapClamp.test.js.snap
index 4488c7c..f5680b1 100644
--- a/gui-clamp/ui-react/src/__snapshots__/OnapClamp.test.js.snap
+++ b/gui-clamp/ui-react/src/__snapshots__/OnapClamp.test.js.snap
@@ -110,6 +110,10 @@
       path="/refreshStatus"
       render={[Function]}
     />
+    <Route
+      path="/monitoring"
+      render={[Function]}
+    />
     <div />
     <div>
       <Alert
diff --git a/gui-clamp/ui-react/src/api/ControlLoopService.js b/gui-clamp/ui-react/src/api/ControlLoopService.js
new file mode 100644
index 0000000..5ef7529
--- /dev/null
+++ b/gui-clamp/ui-react/src/api/ControlLoopService.js
@@ -0,0 +1,47 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ *  ================================================================================
+ *  Licensed 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.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+export default class ControlLoopService {
+
+  static async getControlLoopList(windowLocationPathname) {
+
+    return await fetch(windowLocationPathname + '/restservices/clds/v2/toscaControlLoop/getToscaInstantiation', {
+      method: 'GET',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      credentials: 'same-origin',
+    }).then(response => {
+      console.log("getControlLoopList received " + response.status);
+
+      if (response.ok) {
+        console.info("getControlLoopList query successful");
+        return response.json();
+      } else {
+        return response.text().then(responseBody => {
+          throw Error("HTTP " + response.status + "," + responseBody);
+        });
+      }
+    }).catch(error => {
+      console.error("getControlLoopList error occurred ", error);
+      alert("getControlLoopList error occurred " + error);
+      return undefined;
+    });
+  }
+}
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/ControlLoopElementItem.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/ControlLoopElementItem.js
new file mode 100644
index 0000000..632cacd
--- /dev/null
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/ControlLoopElementItem.js
@@ -0,0 +1,124 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ *  ================================================================================
+ *  Licensed 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.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+import React, { useEffect, useState } from "react";
+import styled from "styled-components";
+import { Button } from "react-bootstrap";
+
+const UninitialisedBox = styled.div`
+  margin: 0;
+  padding: 0 0 1px 0;
+  border-bottom: 1px solid #7f7f7f;
+  background: #cccccc;
+  font-weight: normal;
+  border-radius: 0;
+`
+const PassiveBox = styled.div`
+  margin: 0;
+  padding: 0 0 1px 0;
+  border-bottom: 1px solid #7f7f7f;
+  background: #ffe87c;
+  font-weight: normal;
+  border-radius: 0;
+`
+const RunningBox = styled.div`
+  margin: 0;
+  padding: 0 0 1px 0;
+  border-bottom: 1px solid #7f7f7f;
+  background: #7ec699;
+  font-weight: normal;
+  border-radius: 0;
+`
+const ButtonStyle = styled(Button)`
+  margin: 0;
+  padding: 5px 12px;
+  width: 100%;
+  text-align: left;
+  background: transparent !important;
+  color: #000000 !important;
+  text-decoration: none !important;
+  border: none;
+  border-radius: 0;
+
+  :hover, :active :focus {
+    color: #000000 !important;
+    outline: 0 !important;
+    box-shadow: none !important;
+    background: transparent !important;
+    text-decoration: none !important;
+  }
+`
+
+const ControlLoopElementItem = (props) => {
+  const [title, setTitle] = useState("");
+
+  useEffect(() => {
+    const title = props.title.split(".");
+    setTitle(title[4]);
+  }, []);
+
+  const toggleState = () => {
+    switch (props.orderedState) {
+      case 'UNINITIALISED':
+        return renderUninitialisedOrderedState();
+      case 'PASSIVE':
+        return renderPassiveOrderedState();
+      case 'RUNNING':
+        return renderRunningOrderedState();
+    }
+  }
+
+  const renderUninitialisedOrderedState = () => {
+    return (
+      <UninitialisedBox className="panel-header">
+        <Button as={ ButtonStyle } variant="link">
+          { title }
+        </Button>
+      </UninitialisedBox>
+    )
+  }
+
+  const renderPassiveOrderedState = () => {
+    return (
+      <PassiveBox className="panel-header">
+        <Button as={ ButtonStyle } variant="link">
+          { title }
+        </Button>
+      </PassiveBox>
+    )
+  }
+
+  const renderRunningOrderedState = () => {
+    return (
+      <RunningBox className="panel-header">
+        <Button as={ ButtonStyle } variant="link" active={ true }>
+          { title }
+        </Button>
+      </RunningBox>
+    )
+  }
+
+  return (
+    <React.Fragment>
+      { toggleState() }
+    </React.Fragment>
+  );
+}
+
+export default ControlLoopElementItem;
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/ControlLoopElements.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/ControlLoopElements.js
new file mode 100644
index 0000000..57bdf40
--- /dev/null
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/ControlLoopElements.js
@@ -0,0 +1,41 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ *  ================================================================================
+ *  Licensed 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.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+import React, { useEffect, useState } from "react";
+import ControlLoopElementItem from "./ControlLoopElementItem";
+
+const ControlLoopElements = (props) => {
+  const [clElements, setClElements] = useState([]);
+
+  useEffect(() => {
+    setClElements(Object.values(props.elements));
+  }, []);
+
+  return (
+    <React.Fragment>
+      {
+        clElements.map((clEl, index) => (
+          <ControlLoopElementItem title={ clEl["definition"]["name"] } orderedState={ clEl["orderedState"] } key={ index } />
+        ))
+      }
+    </React.Fragment>
+  );
+}
+
+export default ControlLoopElements;
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/ControlLoopItem.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/ControlLoopItem.js
new file mode 100644
index 0000000..f149517
--- /dev/null
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/ControlLoopItem.js
@@ -0,0 +1,128 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ *  ================================================================================
+ *  Licensed 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.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+import React from "react";
+import styled from 'styled-components';
+
+import { Accordion, Button, Card } from "react-bootstrap";
+
+const AccordionBody = styled.div`
+  margin: 0;
+  padding: 0;
+  border: 1px solid #7f7f7f;
+  border-radius: 0;
+`
+
+const CardBody = styled(Card.Body)`
+  padding: 0;
+  margin: 0;
+`
+
+const UninitialisedHeader = styled.div`
+  margin: 0;
+  padding: 0 0 1px 0;
+  border-bottom: 1px solid #7f7f7f;
+  background: #cccccc;
+  font-weight: normal;
+  border-radius: 0;
+`
+
+const PassiveHeader = styled.div`
+  margin: 0;
+  padding: 0 0 1px 0;
+  border-bottom: 1px solid #7f7f7f;
+  background: #ffe87c;
+  font-weight: normal;
+  border-radius: 0;
+`
+
+const RunningHeader = styled.div`
+  margin: 0;
+  padding: 0 0 1px 0;
+  border-bottom: 1px solid #7f7f7f;
+  background: #7ec699;
+  font-weight: normal;
+  border-radius: 0;
+`
+
+const ToggleButton = styled(Button)`
+  color: #000000;
+  text-decoration: none;
+
+  :hover, :active {
+    color: #000000;
+    text-decoration: none !important;
+  }
+`
+
+const ControlLoopItem = (props) => {
+  const toggleState = () => {
+    switch (props.orderedState) {
+      case 'UNINITIALISED':
+        return renderUninitialisedOrderedState()
+      case 'PASSIVE':
+        return renderPassiveOrderedState();
+      case 'RUNNING':
+        return renderRunningOrderedState();
+    }
+  }
+
+  const renderUninitialisedOrderedState = () => {
+    return (
+      <UninitialisedHeader className="panel-header">
+        <Accordion.Toggle as={ToggleButton} variant="link" eventKey={ props.index.toString() }>
+          { props.title }
+        </Accordion.Toggle>
+      </UninitialisedHeader>
+    )
+  }
+
+  const renderPassiveOrderedState = () => {
+    return (
+      <PassiveHeader className="panel-header">
+        <Accordion.Toggle as={ToggleButton} variant="link" eventKey={ props.index.toString() }>
+          { props.title }
+        </Accordion.Toggle>
+      </PassiveHeader>
+    )
+  }
+
+  const renderRunningOrderedState = () => {
+    return (
+      <RunningHeader className="panel-header">
+        <Accordion.Toggle as={ToggleButton} variant="link" eventKey={ props.index.toString() }>
+          { props.title }
+        </Accordion.Toggle>
+      </RunningHeader>
+    )
+  }
+
+  return (
+    <Accordion>
+      <AccordionBody>
+        { toggleState() }
+        <Accordion.Collapse eventKey={ props.index.toString() }>
+          <CardBody>{ props.children }</CardBody>
+        </Accordion.Collapse>
+      </AccordionBody>
+    </Accordion>
+  );
+}
+
+export default ControlLoopItem;
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/MonitoringControlLoopModal.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/MonitoringControlLoopModal.js
new file mode 100644
index 0000000..03fb64b
--- /dev/null
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/MonitoringControlLoopModal.js
@@ -0,0 +1,71 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ *  ================================================================================
+ *  Licensed 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.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+import React, { useEffect, useState } from "react";
+import styled from "styled-components";
+import Modal from "react-bootstrap/Modal";
+import Button from "react-bootstrap/Button";
+import ControlLoopItem from "./ControlLoopItem";
+import ControlLoopService from "../../../api/ControlLoopService";
+import ControlLoopElements from "./ControlLoopElements";
+
+const ModalStyled = styled(Modal)`
+  background-color: transparent;
+`
+
+const MonitoringControlLoopModal = (props) => {
+  const [show, setShow] = useState(true);
+  const [controlLoopList, setControlLoopList] = useState([]);
+  const [windowLocationPathname, setWindowLocationPathname] = useState('');
+
+  useEffect(() => {
+    setWindowLocationPathname(window.location.pathname);
+
+    ControlLoopService.getControlLoopList(windowLocationPathname).then(controlLoopList => {
+      setControlLoopList(controlLoopList['controlLoopList']);
+    });
+  }, [])
+
+  const handleClose = () => {
+    setShow(false);
+    props.history.push('/');
+  }
+
+  return (
+    <ModalStyled size="xl" show={ show } onHide={ handleClose } backdrop="static" keyboard={ false }>
+      <Modal.Header closeButton>
+        <Modal.Title>Tosca Control Loop - Monitoring</Modal.Title>
+      </Modal.Header>
+      <Modal.Body>
+        {
+          controlLoopList.map((clList, index) => (
+            <ControlLoopItem title={ clList["name"] } orderedState={ clList["orderedState"] } index={ index } key={ index }>
+              <ControlLoopElements elements={ clList["elements"] } />
+            </ControlLoopItem>
+          ))
+        }
+      </Modal.Body>
+      <Modal.Footer>
+        <Button variant="secondary" type="null" onClick={ handleClose }>Cancel</Button>
+      </Modal.Footer>
+    </ModalStyled>
+  )
+}
+
+export default MonitoringControlLoopModal;
diff --git a/gui-clamp/ui-react/src/components/menu/MenuBar.js b/gui-clamp/ui-react/src/components/menu/MenuBar.js
index 978a87a..d7784ef 100644
--- a/gui-clamp/ui-react/src/components/menu/MenuBar.js
+++ b/gui-clamp/ui-react/src/components/menu/MenuBar.js
@@ -117,6 +117,9 @@
           <NavDropdown.Item as={ StyledLink } to="/deploy" disabled={ this.state.disabled }>Deploy to DCAE (DEPLOY)</NavDropdown.Item>
           <NavDropdown.Item as={ StyledLink } to="/undeploy" disabled={ this.state.disabled }>UnDeploy to DCAE (UNDEPLOY)</NavDropdown.Item>
         </StyledNavDropdown>
+        <StyledNavDropdown title="TOSCA Control Loop">
+          <NavDropdown.Item as={ StyledLink } to="/monitoring">Monitoring Control Loop</NavDropdown.Item>
+        </StyledNavDropdown>
         <StyledNavDropdown title="Help">
           <StyledNavLink href="https://wiki.onap.org/" target="_blank">Wiki</StyledNavLink>
           <StyledNavLink href="mailto:onap-discuss@lists.onap.org?subject=CLAMP&body=Please send us suggestions or feature enhancements or defect. If possible, please send us the steps to replicate any defect.">Contact
diff --git a/gui-clamp/ui-react/src/components/menu/__snapshots__/MenuBar.test.js.snap b/gui-clamp/ui-react/src/components/menu/__snapshots__/MenuBar.test.js.snap
index 2fef6c7..416d62e 100644
--- a/gui-clamp/ui-react/src/components/menu/__snapshots__/MenuBar.test.js.snap
+++ b/gui-clamp/ui-react/src/components/menu/__snapshots__/MenuBar.test.js.snap
@@ -1137,6 +1137,75 @@
     </DropdownItem>
   </Styled(NavDropdown)>
   <Styled(NavDropdown)
+    title="TOSCA Control Loop"
+  >
+    <DropdownItem
+      as={
+        Object {
+          "$$typeof": Symbol(react.forward_ref),
+          "attrs": Array [],
+          "componentStyle": e {
+            "baseHash": 1014106698,
+            "baseStyle": undefined,
+            "componentId": "sc-bdfBwQ",
+            "isStatic": false,
+            "rules": Array [
+              "
+  color: ",
+              [Function],
+              ";
+  background-color: ",
+              [Function],
+              ";
+  font-weight: normal;
+  display: block;
+  width: 100%;
+  padding: .25rem 1.5rem;
+  clear: both;
+  text-align: inherit;
+  white-space: nowrap;
+  border: 0;
+
+  :hover {
+    text-decoration: none;
+    background-color: ",
+              [Function],
+              ";
+    color: ",
+              [Function],
+              ";
+  }
+",
+            ],
+            "staticRulesId": "",
+          },
+          "foldedComponentIds": Array [],
+          "render": [Function],
+          "shouldForwardProp": undefined,
+          "styledComponentId": "sc-bdfBwQ",
+          "target": Object {
+            "$$typeof": Symbol(react.forward_ref),
+            "propTypes": Object {
+              "innerRef": [Function],
+              "onClick": [Function],
+              "replace": [Function],
+              "target": [Function],
+              "to": [Function],
+            },
+            "render": [Function],
+          },
+          "toString": [Function],
+          "warnTooManyClasses": [Function],
+          "withComponent": [Function],
+        }
+      }
+      disabled={false}
+      to="/monitoring"
+    >
+      Monitoring Control Loop
+    </DropdownItem>
+  </Styled(NavDropdown)>
+  <Styled(NavDropdown)
     title="Help"
   >
     <Styled(NavLink)