From: brunomilitzer Date: Mon, 30 Aug 2021 17:46:53 +0000 (+0100) Subject: Add Delete Instantiation Functionality. X-Git-Tag: 2.1.0~4^2 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F01%2F123901%2F5;p=policy%2Fgui.git 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 --- 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 }/>) } /> () }/> - () }/> - () }/> + () }/> + () }/> + () }/> ); } 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]} /> +
+
{ + 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( + Order State Changed Success +

Order State Changed was successfully changed

+
+
); + } + + const errorAlert = async (response) => { + console.log("errorAlert called"); + setAlertMessage( + Order State Changed Failure +

An error occurred while trying to change order state

+

Status code: { await response.status } : { response.statusText }

+

Status Text: { await response.text() }

+
+
); + } + + return ( + + + Manage Instantiation + +
+ + + + + Select Order State + + + UNINITIALISED + PASSIVE + RUNNING + + + { + controlLoopIdentifierList.map((clIdList, index) => ( + + )) + } + + Can't get instantiation ordered state:
{ JSON.stringify(instantiationOrderStateMsgError, null, 2) }
+
+ + { alertMessage } + +
+ + + + +
+ ); +} + +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 similarity index 91% rename from gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.js rename to 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( @@ -265,7 +282,7 @@ const InstanceModal = (props) => { backdrop="static" keyboard={ false }> - Change Tosca Instance Properties + Create Tosca Instance Properties
@@ -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 similarity index 84% rename from gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.test.js rename to 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(); + shallow(); }); it("renders correctly", () => { - const tree = shallow(); + const tree = shallow(); expect(toJson(tree)).toMatchSnapshot(); }); it('should have submit button element', () => { - const container = shallow() + const container = shallow() expect(container.find('[variant="primary"]').length).toEqual(1); }); it('should have close button element', () => { - const container = shallow() + const container = shallow() expect(container.find('[variant="secondary"]').length).toEqual(1); }); it('handleCreateUpdateToscaInstanceProperties called when submit button clicked', () => { const history = createMemoryHistory(); - const component = mount() + const component = mount() 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() + const component = mount() 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 ( + + ); + + } else { + return ( + + ); + } + } + 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( - Order State Changed Success -

Order State Changed was successfully changed

+ Deletion of Instantiation Success +

Deletion of Instantiation was successful!


); } @@ -116,52 +145,93 @@ const InstantiationManagementModal = (props) => { const errorAlert = async (response) => { console.log("errorAlert called"); setAlertMessage( - Order State Changed Failure -

An error occurred while trying to change order state

+ Deletion of Instantiation Failure +

An error occurred while trying to delete instantiation

Status code: { await response.status } : { response.statusText }

Status Text: { await response.text() }


); } + const clearErrors = () => { + console.log("clearErrors called"); + setAlertMessage(null); + } + return ( - - Manage Instantiation + Manage Instances -
- - - - - Select Order State - - - UNINITIALISED - PASSIVE - RUNNING - - - { - controlLoopIdentifierList.map((clIdList, index) => ( - - )) - } - - Can't get instantiation ordered state:
{ JSON.stringify(instantiationOrderStateError, null, 2) }
-
+ + + + + + + + + + + + + + + + + + + + + + + + + + { instantiationList.map((instantiation, index) => { + return ( + + + + + + + + + + ) + }) } + +
#Instantiation NameEdit InstantiationDelete InstantiationChange Order StateInstantiation Order StateInstantiation Current State
{ index + 1 }{ instantiation.name } + + + + + { renderDeleteButton(instantiation, index) } + + + + + { instantiation.orderedState }{ instantiation.currentState }
{ alertMessage } -
+
- - + + ); 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 similarity index 96% rename from gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/InstanceModal.test.js.snap rename to 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" > - Change Tosca Instance Properties + Create Tosca Instance Properties
{ it("renders without crashing", () => { - shallow(); + shallow(); }); it("renders correctly", () => { - const tree = shallow(); + const tree = shallow(); expect(toJson(tree)).toMatchSnapshot(); }); it('should have save button element', () => { - const container = shallow() + const container = shallow() expect(container.find('[variant="primary"]').length).toEqual(1); }); it('handleSave called when save button clicked', () => { const history = createMemoryHistory(); - const component = mount() + const component = mount() const logSpy = jest.spyOn(console, 'log'); act(() => { @@ -52,13 +52,13 @@ describe('Verify InstantiationManagementModal', () => { }); it('should have close button element', () => { - const container = shallow() + const container = shallow() expect(container.find('[variant="secondary"]').length).toEqual(1); }); it('handleClose called when close button clicked', () => { const history = createMemoryHistory(); - const component = mount() + const component = mount() 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 { Instantiation - Monitor Instantiation - Manage Instantiation - Edit Control Loop Instance Properties + Instantiation Management Commissioning Manage Commissioned Tosca Template 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 - - - Manage Instantiation - - - Edit Control Loop Instance Properties + Instantiation Management