ADD State Change CL Instantiation

Will Apply Unit Tests on POLICY-3537, since focus is to
get the functionalities completed.

Issue-ID: POLICY-3425
Change-Id: I926bb1a213e71dee56c0fc5df4779a4f1b633383
Signed-off-by: brunomilitzer <bruno.militzer@est.tech>
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstantiationManagementModal.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstantiationManagementModal.js
new file mode 100644
index 0000000..c6c1eb9
--- /dev/null
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstantiationManagementModal.js
@@ -0,0 +1,170 @@
+/*
+ * ============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 styled from "styled-components";
+import Modal from "react-bootstrap/Modal";
+import Button from "react-bootstrap/Button";
+import React, { useContext, useEffect, useRef, useState } from "react";
+import InstantiationOrderStateChangeItem from "./InstantiationOrderStateChangeItem";
+import ControlLoopService from "../../../api/ControlLoopService";
+import { Alert, Container, Dropdown } from "react-bootstrap";
+
+const ModalStyled = styled(Modal)`
+  @media (min-width: 800px) {
+    .modal-xl {
+      max-width: 96%;
+    }
+  }
+  background-color: transparent;
+`
+
+const DivWhiteSpaceStyled = styled.div`
+  overflow: auto;
+  min-width: 100%;
+  max-height: 300px;
+  padding: 5px 5px 0px 5px;
+  text-align: center;
+`
+
+const AlertStyled = styled(Alert)`
+  margin-top: 10px;
+`
+
+const InstantiationManagementModal = (props) => {
+  const [show, setShow] = useState(true);
+  const [windowLocationPathnameGet, setWindowLocationPathnameGet] = useState('');
+  const [windowLocationPathNameSave, setWindowLocationPathNameSave] = useState('');
+  const [controlLoopIdentifierList, setControlLoopIdentifierList] = useState([]);
+  const [orderedState, setOrderedState] = useState('');
+  const [toscaOrderStateObject, setToscaOrderStateObject] = useState({});
+  const [instantiationOrderStateOk, setInstantiationOrderStateOk] = useState(true);
+  const [instantiationOrderStateError, setInstantiationOrderStateError] = useState({});
+  const [alertMessage, setAlertMessage] = useState(null);
+
+  useEffect(async () => {
+    setWindowLocationPathnameGet(window.location.pathname);
+
+    const instantiationOrderState = await ControlLoopService.getInstanceOrderState(windowLocationPathnameGet)
+      .catch(error => error.message);
+
+    const orderStateJson = await instantiationOrderState.json();
+
+    if (!instantiationOrderState.ok || orderStateJson['controlLoopIdentifierList'].length === 0) {
+      setInstantiationOrderStateOk(true);
+      setInstantiationOrderStateError(orderStateJson);
+    } else {
+      setControlLoopIdentifierList(orderStateJson['controlLoopIdentifierList']);
+      setOrderedState(orderStateJson['orderedState']);
+    }
+  }, []);
+
+  const handleDropSelect = (event) => {
+    console.log("handleDropDownChange called");
+
+    const stateChangeObject = {
+      orderedState: event,
+      controlLoopIdentifierList: controlLoopIdentifierList
+    }
+    setToscaOrderStateObject(stateChangeObject);
+    orderStateContext.orderState = stateChangeObject;
+  }
+
+  const handleSave = async () => {
+    console.log("handleSave called");
+    setWindowLocationPathNameSave(window.location.pathname);
+
+    const response = await ControlLoopService.changeInstanceOrderState(toscaOrderStateObject, windowLocationPathNameSave).catch(error => error.message);
+
+    if (response.ok) {
+      successAlert();
+    } else {
+      await errorAlert(response);
+    }
+  }
+
+  const handleClose = () => {
+    console.log('handleClose called');
+    setShow(false);
+    props.history.push('/');
+  }
+
+  const successAlert = () => {
+    console.log("successAlert called");
+    setAlertMessage(<Alert variant="success">
+      <Alert.Heading>Order State Changed Success</Alert.Heading>
+      <p>Order State Changed was successfully changed</p>
+      <hr/>
+    </Alert>);
+  }
+
+  const errorAlert = async (response) => {
+    console.log("errorAlert called");
+    setAlertMessage(<Alert variant="danger">
+      <Alert.Heading>Order State Changed Failure</Alert.Heading>
+      <p>An error occurred while trying to change order state</p>
+      <p>Status code: { await response.status } : { response.statusText }</p>
+      <p>Status Text: { await response.text() }</p>
+      <hr/>
+    </Alert>);
+  }
+
+  return (
+    <ModalStyled size="sm"
+                 show={ show }
+                 onHide={ handleClose }
+                 backdrop="static"
+                 keyboard={ false }>
+      <Modal.Header closeButton>
+        <Modal.Title>Manage Instantiation</Modal.Title>
+      </Modal.Header>
+      <div style={ { padding: '5px 5px 0 5px' } }>
+        <Modal.Body>
+          <Container>
+            <Dropdown onSelect={ handleDropSelect }>
+              <Dropdown.Toggle variant="dark" id="dropdown-basic">
+                Select Order State
+              </Dropdown.Toggle>
+              <Dropdown.Menu>
+                <Dropdown.Item eventKey="UNINITIALISED">UNINITIALISED</Dropdown.Item>
+                <Dropdown.Item eventKey="PASSIVE">PASSIVE</Dropdown.Item>
+                <Dropdown.Item eventKey="RUNNING">RUNNING</Dropdown.Item>
+              </Dropdown.Menu>
+            </Dropdown>
+            {
+              controlLoopIdentifierList.map((clIdList, index) => (
+                <InstantiationOrderStateChangeItem title={ clIdList.name } index={ index } key={ index } />
+              ))
+            }
+          </Container>
+          <AlertStyled show={ !instantiationOrderStateOk }
+                       variant="danger">Can't get instantiation ordered state:<br/>{ JSON.stringify(instantiationOrderStateError, null, 2) }</AlertStyled>
+        </Modal.Body>
+        <DivWhiteSpaceStyled>
+          { alertMessage }
+        </DivWhiteSpaceStyled>
+      </div>
+      <Modal.Footer>
+        <Button variant="primary" onClick={ handleSave }>Save</Button>
+        <Button variant="secondary" onClick={ handleClose }>Close</Button>
+      </Modal.Footer>
+    </ModalStyled>
+  );
+}
+
+export default InstantiationManagementModal;
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstantiationOrderStateChangeItem.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstantiationOrderStateChangeItem.js
new file mode 100644
index 0000000..8545943
--- /dev/null
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstantiationOrderStateChangeItem.js
@@ -0,0 +1,113 @@
+/*
+ * ============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";
+
+const UninitialisedBox = styled.div`
+  margin: 2px -15px;
+  padding: 8px;
+  outline: none;
+  font-size: 16px;
+  font-weight: normal;
+  background: #cccccc;
+  border-radius: 8px;
+  border: 1px solid #7f7f7f;
+
+  &:focus, &:active, &:after {
+    outline: none;
+    border-radius: 8px;
+  }
+`
+
+const PassiveBox = styled.div`
+  margin: 2px -15px;
+  padding: 8px;
+  outline: none;
+  font-size: 16px;
+  font-weight: normal;
+  background: #ffe87c;
+  border-radius: 8px;
+  border: 1px solid #7f7f7f;
+
+  &:focus, &:active, &:after {
+    outline: none;
+    border-radius: 8px;
+  }
+`
+
+const RunningBox = styled.div`
+  margin: 2px -15px;
+  padding: 8px;
+  outline: none;
+  font-size: 16px;
+  font-weight: normal;
+  background: #7ec699;
+  border-radius: 8px;
+  border: 1px solid #7f7f7f;
+
+  &:focus, &:active, &:after {
+    outline: none;
+    border-radius: 8px;
+  }
+`
+
+const InstantiationOrderStateChangeItem = (props) => {
+
+  const renderOrderStateItem = () => {
+    console.log("renderOrderStateItem called");
+    switch (props.orderState) {
+      case 'UNINITIALISED':
+        console.log("called UNINITIALISED");
+        return renderUninitialisedOrderedState();
+      case 'PASSIVE':
+        console.log("called PASSIVE");
+        return renderPassiveOrderedState();
+      case 'RUNNING':
+        console.log("called RUNNING");
+        return renderRunningOrderedState();
+    }
+  }
+
+  const renderUninitialisedOrderedState = () => {
+    return (
+      <UninitialisedBox>{ props.title }</UninitialisedBox>
+    )
+  }
+
+  const renderPassiveOrderedState = () => {
+    return (
+      <PassiveBox>{ props.title }</PassiveBox>
+    )
+  }
+
+  const renderRunningOrderedState = () => {
+    return (
+      <RunningBox>{ props.title }</RunningBox>
+    )
+  }
+
+  return (
+    <React.Fragment>
+      { renderOrderStateItem() }
+    </React.Fragment>
+  );
+}
+
+export default InstantiationOrderStateChangeItem;
diff --git a/gui-clamp/ui-react/src/components/dialogs/InstantiationManagementModal.test.js b/gui-clamp/ui-react/src/components/dialogs/InstantiationManagementModal.test.js
new file mode 100644
index 0000000..61f8c1a
--- /dev/null
+++ b/gui-clamp/ui-react/src/components/dialogs/InstantiationManagementModal.test.js
@@ -0,0 +1,69 @@
+/*
+ * ============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 { mount, shallow } from "enzyme";
+import React from "react";
+import toJson from "enzyme-to-json";
+import { createMemoryHistory } from "history";
+import { act } from "react-dom/test-utils";
+import InstantiationManagementModal from "./ControlLoop/InstantiationManagementModal";
+
+describe('Verify InstantiationManagementModal', () => {
+
+  it("renders without crashing", () => {
+    shallow(<InstantiationManagementModal />);
+  });
+
+  it("renders correctly", () => {
+    const tree = shallow(<InstantiationManagementModal />);
+    expect(toJson(tree)).toMatchSnapshot();
+  });
+
+  it('should have save button element', () => {
+    const container = shallow(<InstantiationManagementModal/>)
+    expect(container.find('[variant="primary"]').length).toEqual(1);
+  });
+
+  it('handleSave called when save button clicked', () => {
+    const history = createMemoryHistory();
+    const component = mount(<InstantiationManagementModal history={ history }/>)
+    const logSpy = jest.spyOn(console, 'log');
+
+    act(() => {
+      component.find('[variant="primary"]').simulate('click');
+      expect(logSpy).toHaveBeenCalledWith('handleSave called');
+    });
+  });
+
+  it('should have close button element', () => {
+    const container = shallow(<InstantiationManagementModal/>)
+    expect(container.find('[variant="secondary"]').length).toEqual(1);
+  });
+
+  it('handleClose called when close button clicked', () => {
+    const history = createMemoryHistory();
+    const component = mount(<InstantiationManagementModal history={ history }/>)
+    const logSpy = jest.spyOn(console, 'log');
+
+    act(() => {
+      component.find('[variant="secondary"]').simulate('click');
+      expect(logSpy).toHaveBeenCalledWith('handleClose called');
+    });
+  });
+});
diff --git a/gui-clamp/ui-react/src/components/dialogs/__snapshots__/InstantiationManagementModal.test.js.snap b/gui-clamp/ui-react/src/components/dialogs/__snapshots__/InstantiationManagementModal.test.js.snap
new file mode 100644
index 0000000..fde9ba1
--- /dev/null
+++ b/gui-clamp/ui-react/src/components/dialogs/__snapshots__/InstantiationManagementModal.test.js.snap
@@ -0,0 +1,114 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Verify InstantiationManagementModal renders correctly 1`] = `
+<Styled(Modal)
+  backdrop="static"
+  keyboard={false}
+  onHide={[Function]}
+  show={true}
+  size="sm"
+>
+  <ModalHeader
+    closeButton={true}
+    closeLabel="Close"
+  >
+    <ModalTitle>
+      Manage Instantiation
+    </ModalTitle>
+  </ModalHeader>
+  <div
+    style={
+      Object {
+        "padding": "5px 5px 0 5px",
+      }
+    }
+  >
+    <ModalBody>
+      <Container
+        fluid={false}
+      >
+        <Dropdown
+          navbar={false}
+          onSelect={[Function]}
+        >
+          <DropdownToggle
+            id="dropdown-basic"
+            variant="dark"
+          >
+            Select Order State
+          </DropdownToggle>
+          <DropdownMenu
+            align="left"
+            alignRight={false}
+            flip={true}
+          >
+            <DropdownItem
+              as={
+                Object {
+                  "$$typeof": Symbol(react.forward_ref),
+                  "render": [Function],
+                }
+              }
+              disabled={false}
+              eventKey="UNINITIALISED"
+            >
+              UNINITIALISED
+            </DropdownItem>
+            <DropdownItem
+              as={
+                Object {
+                  "$$typeof": Symbol(react.forward_ref),
+                  "render": [Function],
+                }
+              }
+              disabled={false}
+              eventKey="PASSIVE"
+            >
+              PASSIVE
+            </DropdownItem>
+            <DropdownItem
+              as={
+                Object {
+                  "$$typeof": Symbol(react.forward_ref),
+                  "render": [Function],
+                }
+              }
+              disabled={false}
+              eventKey="RUNNING"
+            >
+              RUNNING
+            </DropdownItem>
+          </DropdownMenu>
+        </Dropdown>
+      </Container>
+      <Styled(Alert)
+        show={false}
+        variant="danger"
+      >
+        Can't get instantiation ordered state:
+        <br />
+        {}
+      </Styled(Alert)>
+    </ModalBody>
+    <styled.div />
+  </div>
+  <ModalFooter>
+    <Button
+      active={false}
+      disabled={false}
+      onClick={[Function]}
+      variant="primary"
+    >
+      Save
+    </Button>
+    <Button
+      active={false}
+      disabled={false}
+      onClick={[Function]}
+      variant="secondary"
+    >
+      Close
+    </Button>
+  </ModalFooter>
+</Styled(Modal)>
+`;
diff --git a/gui-clamp/ui-react/src/components/menu/MenuBar.js b/gui-clamp/ui-react/src/components/menu/MenuBar.js
index 7ee7ffd..99480a9 100644
--- a/gui-clamp/ui-react/src/components/menu/MenuBar.js
+++ b/gui-clamp/ui-react/src/components/menu/MenuBar.js
@@ -116,8 +116,9 @@
         <StyledNavDropdown title="TOSCA Control Loop">
           <NavDropdown.Header>Instantiation</NavDropdown.Header>
           <NavDropdown.Item as={ StyledLink } to="/monitorInstantiation">Monitor Instantiation</NavDropdown.Item>
+          <NavDropdown.Item as={ StyledLink } to="/manageInstantiation">Manage Instantiation</NavDropdown.Item>
           <NavDropdown.Item as={ StyledLink } to="/editControlLoopInstanceProperties">Edit Control Loop Instance Properties</NavDropdown.Item>
-          <NavDropdown.Divider />
+          <NavDropdown.Divider/>
           <NavDropdown.Header>Commissioning</NavDropdown.Header>
           <NavDropdown.Item as={ StyledLink } to="/readToscaTemplate">Manage Commissioned Tosca Template</NavDropdown.Item>
           <NavDropdown.Item as={ StyledLink } to="/uploadToscaFile">Upload Tosca to Commissioning</NavDropdown.Item>
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 edc0624..36132ff 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
@@ -1136,6 +1136,71 @@
         }
       }
       disabled={false}
+      to="/manageInstantiation"
+    >
+      Manage Instantiation
+    </DropdownItem>
+    <DropdownItem
+      as={
+        Object {
+          "$$typeof": Symbol(react.forward_ref),
+          "attrs": Array [],
+          "componentStyle": e {
+            "baseHash": -715527839,
+            "baseStyle": undefined,
+            "componentId": "sc-bdnxRM",
+            "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-bdnxRM",
+          "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="/editControlLoopInstanceProperties"
     >
       Edit Control Loop Instance Properties