aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrunomilitzer <bruno.militzer@est.tech>2021-08-30 18:46:53 +0100
committerbrunomilitzer <bruno.militzer@est.tech>2021-09-10 09:21:50 +0100
commita090a83268cfd8b1341c266d32ccfb670b9f0e8c (patch)
tree0b4ecc386f90316008d453c9eacd99b4063bb348
parentf2047d16b47f086395856aefca6c5047b488d207 (diff)
Add Delete Instantiation Functionality.
Update UI to centralize Instantiation Management Created Delete button to delete the instantiations Fixed Change Order State Functionality Issue-ID: POLICY-3558 Change-Id: I2efb00ce041ab4fc217e06ed72385ad8ea1b10fb Signed-off-by: brunomilitzer <bruno.militzer@est.tech>
-rw-r--r--gui-clamp/ui-react-lib/libIndex.js3
-rw-r--r--gui-clamp/ui-react/src/LoopUI.js8
-rw-r--r--gui-clamp/ui-react/src/__snapshots__/LoopUI.test.js.snap6
-rw-r--r--gui-clamp/ui-react/src/__snapshots__/OnapClamp.test.js.snap6
-rw-r--r--gui-clamp/ui-react/src/api/ControlLoopService.js27
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/ChangeOrderStateModal.js176
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstancePropertiesModal.js (renamed from gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.js)35
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstancePropertiesModal.test.js (renamed from gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.test.js)15
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstantiationManagementModal.js222
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/InstancePropertiesModal.test.js.snap (renamed from gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/InstanceModal.test.js.snap)2
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/InstantiationManagementModal.test.js14
-rw-r--r--gui-clamp/ui-react/src/components/menu/MenuBar.js4
-rw-r--r--gui-clamp/ui-react/src/components/menu/__snapshots__/MenuBar.test.js.snap134
13 files changed, 407 insertions, 245 deletions
diff --git a/gui-clamp/ui-react-lib/libIndex.js b/gui-clamp/ui-react-lib/libIndex.js
index 779e363..24e3072 100644
--- a/gui-clamp/ui-react-lib/libIndex.js
+++ b/gui-clamp/ui-react-lib/libIndex.js
@@ -59,8 +59,9 @@ export { default as MonitorInstantiation } from '../ui-react/src/components/dial
export { default as InstantiationItem } from '../ui-react/src/components/dialogs/ControlLoop/InstantiationItem';
export { default as InstantiationElements } from '../ui-react/src/components/dialogs/ControlLoop/InstantiationElements';
export { default as InstantiationElementItem } from '../ui-react/src/components/dialogs/ControlLoop/InstantiationElementItem';
-export { default as InstanceModal } from '../ui-react/src/components/dialogs/ControlLoop/InstanceModal';
+export { default as InstancePropertiesModal } from '../ui-react/src/components/dialogs/ControlLoop/InstancePropertiesModal';
export { default as InstantiationManagementModal } from '../ui-react/src/components/dialogs/ControlLoop/InstantiationManagementModal';
+export { default as ChangeOrderStateModal } from '../ui-react/src/components/dialogs/ControlLoop/ChangeOrderStateModal';
export { default as InstantiationOrderStateChangeItem } from '../ui-react/src/components/dialogs/ControlLoop/InstantiationOrderStateChangeItem';
export { default as ControlLoopService } from '../ui-react/src/api/ControlLoopService';
export { default as GetLocalToscaFileForUpload } from '../ui-react/src/components/dialogs/ControlLoop/GetLocalToscaFileForUpload';
diff --git a/gui-clamp/ui-react/src/LoopUI.js b/gui-clamp/ui-react/src/LoopUI.js
index 79943bf..e593a08 100644
--- a/gui-clamp/ui-react/src/LoopUI.js
+++ b/gui-clamp/ui-react/src/LoopUI.js
@@ -55,7 +55,8 @@ import ReadAndConvertYaml from "./components/dialogs/ControlLoop/ReadAndConvertY
import MonitorInstantiation from "./components/dialogs/ControlLoop/MonitorInstantiation";
import GetLocalToscaFileForUpload from "./components/dialogs/ControlLoop/GetLocalToscaFileForUpload";
import CommissioningModal from "./components/dialogs/ControlLoop/CommissioningModal";
-import InstanceModal from "./components/dialogs/ControlLoop/InstanceModal";
+import InstancePropertiesModal from "./components/dialogs/ControlLoop/InstancePropertiesModal";
+import ChangeOrderStateModal from "./components/dialogs/ControlLoop/ChangeOrderStateModal";
import InstantiationManagementModal from "./components/dialogs/ControlLoop/InstantiationManagementModal";
const StyledMainDiv = styled.div`
@@ -387,8 +388,9 @@ export default class LoopUI extends React.Component {
showFailAlert={ this.showFailAlert }/>) }
/>
<Route path="/monitorInstantiation" render={ (routeProps) => (<MonitorInstantiation { ...routeProps } />) }/>
- <Route path="/manageInstantiation" render={ (routeProps) => (<InstantiationManagementModal { ...routeProps } />) }/>
- <Route path="/editControlLoopInstanceProperties" render={ (routeProps) => (<InstanceModal { ...routeProps } />) }/>
+ <Route path="/instantiationManagement" render={ (routeProps) => (<InstantiationManagementModal { ...routeProps } />) }/>
+ <Route path="/editControlLoopInstanceProperties" render={ (routeProps) => (<InstancePropertiesModal { ...routeProps } />) }/>
+ <Route path="/changeOrderState" render={ (routeProps) => (<ChangeOrderStateModal { ...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 abfcb8d..222b2a7 100644
--- a/gui-clamp/ui-react/src/__snapshots__/LoopUI.test.js.snap
+++ b/gui-clamp/ui-react/src/__snapshots__/LoopUI.test.js.snap
@@ -90,13 +90,17 @@ exports[`Verify LoopUI Test the render method 1`] = `
render={[Function]}
/>
<Route
- path="/manageInstantiation"
+ path="/instantiationManagement"
render={[Function]}
/>
<Route
path="/editControlLoopInstanceProperties"
render={[Function]}
/>
+ <Route
+ path="/changeOrderState"
+ 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 a87127e..cc5541b 100644
--- a/gui-clamp/ui-react/src/__snapshots__/OnapClamp.test.js.snap
+++ b/gui-clamp/ui-react/src/__snapshots__/OnapClamp.test.js.snap
@@ -119,13 +119,17 @@ exports[`Verify OnapClamp Test the render method 1`] = `
render={[Function]}
/>
<Route
- path="/manageInstantiation"
+ path="/instantiationManagement"
render={[Function]}
/>
<Route
path="/editControlLoopInstanceProperties"
render={[Function]}
/>
+ <Route
+ path="/changeOrderState"
+ 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
index 0d6e11c..96eb403 100644
--- a/gui-clamp/ui-react/src/api/ControlLoopService.js
+++ b/gui-clamp/ui-react/src/api/ControlLoopService.js
@@ -26,7 +26,7 @@ export default class ControlLoopService {
return response
}
- static async createInstanceProperties(instancePropertiesTemplate, windowLocationPathname) {
+ static async createInstanceProperties(instanceName, instancePropertiesTemplate, windowLocationPathname) {
const response = await fetch(windowLocationPathname +
'/restservices/clds/v2/toscaControlLoop/postToscaInstanceProperties', {
@@ -41,8 +41,29 @@ export default class ControlLoopService {
return response
}
- static async getInstanceOrderState(windowLocationPathName) {
- const response = await fetch(windowLocationPathName + '/restservices/clds/v2/toscaControlLoop/getInstantiationOrderState');
+ static async deleteInstantiation(name, version, windowLocationPathName) {
+ console.log(windowLocationPathName);
+ const params = {
+ name: name,
+ version: version
+ }
+
+ const response = await fetch(windowLocationPathName + '/restservices/clds/v2/toscaControlLoop/deleteToscaInstanceProperties?' + (new URLSearchParams(params)), {
+ method: 'DELETE',
+ credentials: 'same-origin',
+ });
+
+ const data = await response;
+
+ return data;
+ }
+
+ static async getInstanceOrderState(name, version, windowLocationPathName) {
+ const params = {
+ name: name,
+ version: version
+ }
+ const response = await fetch(windowLocationPathName + '/restservices/clds/v2/toscaControlLoop/getInstantiationOrderState'+ '?' + (new URLSearchParams(params)));
const data = await response;
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/ChangeOrderStateModal.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/ChangeOrderStateModal.js
new file mode 100644
index 0000000..2c6d9aa
--- /dev/null
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/ChangeOrderStateModal.js
@@ -0,0 +1,176 @@
+/*
+ * ============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 ChangeOrderStateModal = (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 [instantiationOrderStateError, setInstantiationOrderStateError] = useState(false);
+ const [instantiationOrderStateMsgError, setInstantiationOrderStateMsgError] = useState({});
+ const [alertMessage, setAlertMessage] = useState(null);
+
+ useEffect(async () => {
+ setWindowLocationPathnameGet(window.location.pathname);
+
+ const instantiationOrderState = await ControlLoopService.getInstanceOrderState(
+ props.location.instantiationName,
+ props.location.instantiationVersion, windowLocationPathnameGet)
+ .catch(error => error.message);
+
+ const orderStateJson = await instantiationOrderState.json();
+
+ console.log(orderStateJson);
+
+ if (!instantiationOrderState.ok || orderStateJson['controlLoopIdentifierList'].length === 0) {
+ setInstantiationOrderStateError(true);
+ setInstantiationOrderStateMsgError(orderStateJson);
+ } else {
+ setControlLoopIdentifierList(orderStateJson['controlLoopIdentifierList']);
+ setOrderedState(orderStateJson['orderedState']);
+ }
+ }, []);
+
+ const handleDropSelect = (event) => {
+ console.log("handleDropDownChange called");
+
+ const stateChangeObject = {
+ orderedState: event,
+ controlLoopIdentifierList: controlLoopIdentifierList
+ }
+ setToscaOrderStateObject(stateChangeObject);
+ setOrderedState(event);
+ }
+
+ 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 } orderState={ orderedState } index={ index } key={ index }/>
+ ))
+ }
+ </Container>
+ <AlertStyled show={ instantiationOrderStateError }
+ variant="danger">Can't get instantiation ordered state:<br/>{ JSON.stringify(instantiationOrderStateMsgError, 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 ChangeOrderStateModal;
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstancePropertiesModal.js
index 0380fa6..8343237 100644
--- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.js
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstancePropertiesModal.js
@@ -24,6 +24,9 @@ import Button from "react-bootstrap/Button";
import ControlLoopService from "../../../api/ControlLoopService";
import { JSONEditor } from "@json-editor/json-editor";
import Alert from "react-bootstrap/Alert";
+import * as PropTypes from "prop-types";
+import Form from "react-bootstrap/Form";
+import Spinner from "react-bootstrap/Spinner";
const ModalStyled = styled(Modal)`
@media (min-width: 800px) {
@@ -50,17 +53,22 @@ const templateName = "ToscaServiceTemplateSimple";
const templateVersion = "1.0.0";
let tempJsonEditor = null;
-const InstanceModal = (props) => {
+function Fragment(props) {
+ return null;
+}
+
+Fragment.propTypes = { children: PropTypes.node };
+const InstancePropertiesModal = (props) => {
const [show, setShow] = useState(true);
const [windowLocationPathname, setWindowLocationPathname] = useState('');
const [toscaFullTemplate, setToscaFullTemplate] = useState({});
- const [toscaFilteredInitialValues, setToscaFilteredInitialValues] = useState({});
- const [toscaJsonSchema, setToscaJsonSchema] = useState({});
const [jsonEditor, setJsonEditor] = useState(null);
const [alertMessage, setAlertMessage] = useState(null);
const [instancePropertiesGlobal, setInstancePropertiesGlobal] = useState({});
const [serviceTemplateResponseOk, setServiceTemplateResponseOk] = useState(true);
const [instancePropertiesResponseOk, setInstancePropertiesResponseOk] = useState(true);
+ const [instanceName, setInstanceName] = useState('')
+ const [isLoading, setIsLoading] = useState(true);
useEffect(async () => {
const toscaInstanceProperties = await ControlLoopService.getCommonOrInstanceProperties(templateName, templateVersion, windowLocationPathname, false).catch(error => error.message);
@@ -92,6 +100,8 @@ const InstanceModal = (props) => {
const fullJsonSchemaTemplate = await fullTemplate.json();
setToscaFullTemplate(fullJsonSchemaTemplate);
+ console.log(fullJsonSchemaTemplate);
+
const filteredInitialStartValues = {};
const instanceProperties = await initialProperties.json().then(properties => {
@@ -115,13 +125,10 @@ const InstanceModal = (props) => {
filteredInitialStartValues[key] = propValues;
});
- setToscaFilteredInitialValues(filteredInitialStartValues);
-
return filteredTemplateObj;
});
const propertySchema = makeSchemaForInstanceProperties(instanceProperties);
- setToscaJsonSchema(propertySchema);
tempJsonEditor = createJsonEditor(propertySchema, filteredInitialStartValues);
setJsonEditor(tempJsonEditor);
@@ -159,6 +166,8 @@ const InstanceModal = (props) => {
const getType = (pType) => {
switch (pType) {
+ case "map":
+ return "string";
case "string":
return "string";
case "integer":
@@ -174,6 +183,8 @@ const InstanceModal = (props) => {
}
const createJsonEditor = (fullSchema, instanceProperties) => {
+ console.log(props.location.instanceName)
+ setIsLoading(false)
JSONEditor.defaults.options.collapse = true;
return new JSONEditor(document.getElementById("editor"),
@@ -225,11 +236,13 @@ const InstanceModal = (props) => {
const handleSave = async () => {
console.log("handleSave called")
+ console.log("instanceName to be saved is: " + instanceName)
+
setWindowLocationPathname(window.location.pathname);
updateTemplate(jsonEditor.getValue());
- const response = await ControlLoopService.createInstanceProperties(toscaFullTemplate, windowLocationPathname).catch(error => error.message);
+ const response = await ControlLoopService.createInstanceProperties(instanceName, toscaFullTemplate, windowLocationPathname).catch(error => error.message);
if (response.ok) {
successAlert();
@@ -238,6 +251,10 @@ const InstanceModal = (props) => {
}
}
+ const handleNameChange = (e) => {
+ setInstanceName(e.target.value)
+ }
+
const successAlert = () => {
console.log("successAlert called");
setAlertMessage(<Alert variant="success">
@@ -265,7 +282,7 @@ const InstanceModal = (props) => {
backdrop="static"
keyboard={ false }>
<Modal.Header closeButton>
- <Modal.Title>Change Tosca Instance Properties</Modal.Title>
+ <Modal.Title>Create Tosca Instance Properties</Modal.Title>
</Modal.Header>
<div style={ { padding: '5px 5px 0 5px' } }>
<Modal.Body>
@@ -287,4 +304,4 @@ const InstanceModal = (props) => {
);
}
-export default InstanceModal;
+export default InstancePropertiesModal;
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.test.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstancePropertiesModal.test.js
index 36a77d7..141999c 100644
--- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.test.js
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstancePropertiesModal.test.js
@@ -19,36 +19,35 @@
import { mount, shallow } from "enzyme";
import React from "react";
-import InstanceModal from "./InstanceModal";
+import InstancePropertiesModal from "./InstancePropertiesModal";
import toJson from "enzyme-to-json";
import { createMemoryHistory } from "history";
-import MonitorInstantiation from "./MonitorInstantiation";
import { act } from "react-dom/test-utils";
describe('Verify MonitoringInstantiation', () => {
it("renders without crashing", () => {
- shallow(<InstanceModal />);
+ shallow(<InstancePropertiesModal />);
});
it("renders correctly", () => {
- const tree = shallow(<InstanceModal />);
+ const tree = shallow(<InstancePropertiesModal />);
expect(toJson(tree)).toMatchSnapshot();
});
it('should have submit button element', () => {
- const container = shallow(<InstanceModal/>)
+ const container = shallow(<InstancePropertiesModal/>)
expect(container.find('[variant="primary"]').length).toEqual(1);
});
it('should have close button element', () => {
- const container = shallow(<InstanceModal/>)
+ const container = shallow(<InstancePropertiesModal/>)
expect(container.find('[variant="secondary"]').length).toEqual(1);
});
it('handleCreateUpdateToscaInstanceProperties called when submit button clicked', () => {
const history = createMemoryHistory();
- const component = mount(<InstanceModal />)
+ const component = mount(<InstancePropertiesModal />)
const logSpy = jest.spyOn(console, 'log');
act(() => {
@@ -59,7 +58,7 @@ describe('Verify MonitoringInstantiation', () => {
it('handleClose called when close button clicked', () => {
const history = createMemoryHistory();
- const component = mount(<InstanceModal history={ history }/>)
+ const component = mount(<InstancePropertiesModal history={ history }/>)
const logSpy = jest.spyOn(console, 'log');
act(() => {
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstantiationManagementModal.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstantiationManagementModal.js
index c6c1eb9..a0a849c 100644
--- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstantiationManagementModal.js
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstantiationManagementModal.js
@@ -15,25 +15,28 @@
*
* SPDX-License-Identifier: Apache-2.0
* ============LICENSE_END=========================================================
+ *
+ *
*/
-import styled from "styled-components";
import Modal from "react-bootstrap/Modal";
+import { Alert, Container, Dropdown, Table } from "react-bootstrap";
import Button from "react-bootstrap/Button";
-import React, { useContext, useEffect, useRef, useState } from "react";
-import InstantiationOrderStateChangeItem from "./InstantiationOrderStateChangeItem";
+import React, { useEffect, useState } from "react";
+import styled from "styled-components";
+import { Link } from "react-router-dom";
import ControlLoopService from "../../../api/ControlLoopService";
-import { Alert, Container, Dropdown } from "react-bootstrap";
+import Row from "react-bootstrap/Row";
const ModalStyled = styled(Modal)`
- @media (min-width: 800px) {
- .modal-xl {
- max-width: 96%;
- }
- }
background-color: transparent;
`
+const HorizontalSpace = styled.div`
+ padding-right: 2px;
+ padding-left: 2px;
+`;
+
const DivWhiteSpaceStyled = styled.div`
overflow: auto;
min-width: 100%;
@@ -41,55 +44,55 @@ const DivWhiteSpaceStyled = styled.div`
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 [windowLocationPathName, setWindowLocationPathName] = useState('');
+ const [windowLocationPathNameDelete, setWindowLocationPathNameDelete] = useState('');
+
+ const [instantiationList, setInstantiationList] = useState([]);
const [alertMessage, setAlertMessage] = useState(null);
useEffect(async () => {
- setWindowLocationPathnameGet(window.location.pathname);
+ setWindowLocationPathName(window.location.pathname);
- const instantiationOrderState = await ControlLoopService.getInstanceOrderState(windowLocationPathnameGet)
- .catch(error => error.message);
+ const response = await ControlLoopService.getControlLoopInstantiation(windowLocationPathName);
- const orderStateJson = await instantiationOrderState.json();
+ const instantiationListJson = await response.json();
- if (!instantiationOrderState.ok || orderStateJson['controlLoopIdentifierList'].length === 0) {
- setInstantiationOrderStateOk(true);
- setInstantiationOrderStateError(orderStateJson);
- } else {
- setControlLoopIdentifierList(orderStateJson['controlLoopIdentifierList']);
- setOrderedState(orderStateJson['orderedState']);
- }
- }, []);
+ const parsedInstantiationList = instantiationListJson['controlLoopList'].map((instance, index) => {
+ return {
+ index: index,
+ name: instance['name'],
+ version: instance['version'],
+ orderedState: instance['orderedState'],
+ currentState: instance['state'],
+ disableDelete: instance['state'] !== 'UNINITIALISED'
+ }
+ });
- const handleDropSelect = (event) => {
- console.log("handleDropDownChange called");
+ setInstantiationList(parsedInstantiationList);
+ }, []);
- const stateChangeObject = {
- orderedState: event,
- controlLoopIdentifierList: controlLoopIdentifierList
+ const getBackgroundColor = (index) => {
+ if (index % 2 === 0) {
+ return 'Silver';
}
- setToscaOrderStateObject(stateChangeObject);
- orderStateContext.orderState = stateChangeObject;
+
+ return 'White';
}
- const handleSave = async () => {
- console.log("handleSave called");
- setWindowLocationPathNameSave(window.location.pathname);
+ const deleteInstantiationHandler = async (instantiation, index) => {
+ console.log("deleteInstantiationHandler called");
+ setWindowLocationPathNameDelete(window.location.pathname);
+
+ const name = instantiation.name;
+ const version = instantiation.version;
+
+ console.log(window.location.pathname);
+
+ const response = await ControlLoopService.deleteInstantiation(name, version, windowLocationPathNameDelete);
- const response = await ControlLoopService.changeInstanceOrderState(toscaOrderStateObject, windowLocationPathNameSave).catch(error => error.message);
+ updateList(index);
if (response.ok) {
successAlert();
@@ -98,8 +101,34 @@ const InstantiationManagementModal = (props) => {
}
}
+ const updateList = (index) => {
+ console.log("updateList called")
+ console.log(instantiationList)
+
+ const updatedList = [...instantiationList];
+ updatedList.splice(index, 1);
+
+ setInstantiationList(updatedList);
+ }
+
+ const renderDeleteButton = (instantiation, index) => {
+ if (instantiation.disableDelete) {
+ return (
+ <Button variant="outline-danger" type="null"
+ disabled={ true }
+ style={ { cursor: "not-allowed" } }>Delete</Button>
+ );
+
+ } else {
+ return (
+ <Button variant="danger" type="null"
+ onClick={ async () => deleteInstantiationHandler(instantiation, index) }>Delete</Button>
+ );
+ }
+ }
+
const handleClose = () => {
- console.log('handleClose called');
+ console.log("handleClose called");
setShow(false);
props.history.push('/');
}
@@ -107,8 +136,8 @@ const InstantiationManagementModal = (props) => {
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>
+ <Alert.Heading>Deletion of Instantiation Success</Alert.Heading>
+ <p>Deletion of Instantiation was successful!</p>
<hr/>
</Alert>);
}
@@ -116,52 +145,93 @@ const InstantiationManagementModal = (props) => {
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>
+ <Alert.Heading>Deletion of Instantiation Failure</Alert.Heading>
+ <p>An error occurred while trying to delete instantiation</p>
<p>Status code: { await response.status } : { response.statusText }</p>
<p>Status Text: { await response.text() }</p>
<hr/>
</Alert>);
}
+ const clearErrors = () => {
+ console.log("clearErrors called");
+ setAlertMessage(null);
+ }
+
return (
- <ModalStyled size="sm"
+ <ModalStyled size="xl"
show={ show }
onHide={ handleClose }
backdrop="static"
keyboard={ false }>
<Modal.Header closeButton>
- <Modal.Title>Manage Instantiation</Modal.Title>
+ <Modal.Title>Manage Instances</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>
+ <Modal.Body>
+ <Container>
+ <Row>
+ <Link to={ { pathname: "/editControlLoopInstanceProperties" } }>
+ <Button variant="primary" type="null">Create Instance</Button>
+ </Link>
+ <HorizontalSpace/>
+ <Link to={ { pathname: "/monitorInstantiation" } }>
+ <Button variant="secondary" type="null">Monitor Instantiations</Button>
+ </Link>
+ </Row>
+ </Container>
+ <Table bordered style={ { marginTop: '10px' } }>
+ <thead>
+ <tr>
+ <th>#</th>
+ <th style={ { textAlign: "center" } }>Instantiation Name</th>
+ <th style={ { textAlign: "center" } }>Edit Instantiation</th>
+ <th style={ { textAlign: "center" } }>Delete Instantiation</th>
+ <th style={ { textAlign: "center" } }>Change Order State</th>
+ <th style={ { textAlign: "center" } }>Instantiation Order State</th>
+ <th style={ { textAlign: "center" } }>Instantiation Current State</th>
+ </tr>
+ </thead>
+ <tbody>
+ { instantiationList.map((instantiation, index) => {
+ return (
+ <tr style={ { backgroundColor: getBackgroundColor(index) } } key={ index } className="instantiationList">
+ <td>{ index + 1 }</td>
+ <td>{ instantiation.name }</td>
+ <td style={ { textAlign: "center" } }>
+ <Link to={ {
+ pathname: "editControlLoopInstanceProperties",
+ } } state={ instantiation.name }>
+ <Button variant="outline-success" type="null"
+ disabled={ true }
+ style={ { cursor: "not-allowed" } }>Edit</Button>
+ </Link>
+ </td>
+ <td style={ { textAlign: "center" } }>
+ { renderDeleteButton(instantiation, index) }
+ </td>
+ <td style={ { textAlign: "center" } }>
+ <Link to={ {
+ pathname: "changeOrderState",
+ instantiationName: instantiation.name,
+ instantiationVersion: instantiation.version
+ } }>
+ <Button variant="secondary" type="null">Change</Button>
+ </Link>
+ </td>
+ <td>{ instantiation.orderedState }</td>
+ <td>{ instantiation.currentState }</td>
+ </tr>
+ )
+ }) }
+ </tbody>
+ </Table>
<DivWhiteSpaceStyled>
{ alertMessage }
</DivWhiteSpaceStyled>
- </div>
+ </Modal.Body>
<Modal.Footer>
- <Button variant="primary" onClick={ handleSave }>Save</Button>
- <Button variant="secondary" onClick={ handleClose }>Close</Button>
+ <Button variant="secondary" type="null" onClick={ clearErrors }>Clear Error Message</Button>
+ <Button variant="secondary" type="null" onClick={ handleClose }>Close</Button>
</Modal.Footer>
</ModalStyled>
);
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/InstanceModal.test.js.snap b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/InstancePropertiesModal.test.js.snap
index ba7caf9..96b500e 100644
--- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/InstanceModal.test.js.snap
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/InstancePropertiesModal.test.js.snap
@@ -13,7 +13,7 @@ exports[`Verify MonitoringInstantiation renders correctly 1`] = `
closeLabel="Close"
>
<ModalTitle>
- Change Tosca Instance Properties
+ Create Tosca Instance Properties
</ModalTitle>
</ModalHeader>
<div
diff --git a/gui-clamp/ui-react/src/components/dialogs/InstantiationManagementModal.test.js b/gui-clamp/ui-react/src/components/dialogs/InstantiationManagementModal.test.js
index 61f8c1a..25292d0 100644
--- a/gui-clamp/ui-react/src/components/dialogs/InstantiationManagementModal.test.js
+++ b/gui-clamp/ui-react/src/components/dialogs/InstantiationManagementModal.test.js
@@ -22,27 +22,27 @@ 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";
+import ChangeOrderStateModal from "./ControlLoop/ChangeOrderStateModal";
describe('Verify InstantiationManagementModal', () => {
it("renders without crashing", () => {
- shallow(<InstantiationManagementModal />);
+ shallow(<ChangeOrderStateModal />);
});
it("renders correctly", () => {
- const tree = shallow(<InstantiationManagementModal />);
+ const tree = shallow(<ChangeOrderStateModal />);
expect(toJson(tree)).toMatchSnapshot();
});
it('should have save button element', () => {
- const container = shallow(<InstantiationManagementModal/>)
+ const container = shallow(<ChangeOrderStateModal/>)
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 component = mount(<ChangeOrderStateModal history={ history }/>)
const logSpy = jest.spyOn(console, 'log');
act(() => {
@@ -52,13 +52,13 @@ describe('Verify InstantiationManagementModal', () => {
});
it('should have close button element', () => {
- const container = shallow(<InstantiationManagementModal/>)
+ const container = shallow(<ChangeOrderStateModal/>)
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 component = mount(<ChangeOrderStateModal history={ history }/>)
const logSpy = jest.spyOn(console, 'log');
act(() => {
diff --git a/gui-clamp/ui-react/src/components/menu/MenuBar.js b/gui-clamp/ui-react/src/components/menu/MenuBar.js
index 99480a9..59cff22 100644
--- a/gui-clamp/ui-react/src/components/menu/MenuBar.js
+++ b/gui-clamp/ui-react/src/components/menu/MenuBar.js
@@ -115,9 +115,7 @@ export default class MenuBar extends React.Component {
</StyledNavDropdown>
<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.Item as={ StyledLink } to="/instantiationManagement">Instantiation Management</NavDropdown.Item>
<NavDropdown.Divider/>
<NavDropdown.Header>Commissioning</NavDropdown.Header>
<NavDropdown.Item as={ StyledLink } to="/readToscaTemplate">Manage Commissioned Tosca Template</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 36132ff..dbae793 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
@@ -1071,139 +1071,9 @@ exports[`Verify MenuBar Test the render method 1`] = `
}
}
disabled={false}
- to="/monitorInstantiation"
+ to="/instantiationManagement"
>
- Monitor 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="/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
+ Instantiation Management
</DropdownItem>
<DropdownDivider
role="separator"