summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrunomilitzer <bruno.militzer@est.tech>2021-07-27 17:47:25 +0100
committerbrunomilitzer <bruno.militzer@est.tech>2021-07-30 17:02:30 +0100
commitbdc4cc9d4a75bfdd2f5656f102d2f6ac7817e4ef (patch)
tree4f7a851ae2d78a386626c85091761042894d55e9
parent83c09e788eb75b287c946acbcba0d43cd3cd4681 (diff)
Add Instance Properties Form
Added save button to update paramaters Added service to retrieve paramaters; Added service to upload instance paramaters Issue-ID: POLICY-3436 Change-Id: I82e7545b12160f2e7937db2fdb3857c66ea0b858 Signed-off-by: brunomilitzer <bruno.militzer@est.tech>
-rw-r--r--gui-clamp/ui-react-lib/libIndex.js2
-rw-r--r--gui-clamp/ui-react/src/LoopUI.js4
-rw-r--r--gui-clamp/ui-react/src/__snapshots__/LoopUI.test.js.snap2
-rw-r--r--gui-clamp/ui-react/src/__snapshots__/OnapClamp.test.js.snap2
-rw-r--r--gui-clamp/ui-react/src/api/ControlLoopService.js64
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.js261
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.test.js70
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/MonitorInstantiation.js2
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiation.js136
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiation.test.js102
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiationFile.js52
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiationFile.test.js61
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/InstanceModal.test.js.snap52
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/UploadToscaInstantiation.test.js.snap91
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/UploadToscaInstantiationFile.test.js.snap16
-rw-r--r--gui-clamp/ui-react/src/components/menu/MenuBar.js2
-rw-r--r--gui-clamp/ui-react/src/components/menu/__snapshots__/MenuBar.test.js.snap4
17 files changed, 419 insertions, 504 deletions
diff --git a/gui-clamp/ui-react-lib/libIndex.js b/gui-clamp/ui-react-lib/libIndex.js
index b0981b0..2af68db 100644
--- a/gui-clamp/ui-react-lib/libIndex.js
+++ b/gui-clamp/ui-react-lib/libIndex.js
@@ -59,7 +59,7 @@ 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 UploadToscaInstantiation } from '../ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiation';
+export { default as InstanceModal } from '../ui-react/src/components/dialogs/ControlLoop/InstanceModal';
export { default as ControlLoopService } from '../ui-react/src/api/ControlLoopService';
export { default as GetLocalToscaFileForUpload } from '../ui-react/src/components/dialogs/ControlLoop/GetLocalToscaFileForUpload';
export { default as ReadAndConvertYaml } from '../ui-react/src/components/dialogs/ControlLoop/ReadAndConvertYaml';
diff --git a/gui-clamp/ui-react/src/LoopUI.js b/gui-clamp/ui-react/src/LoopUI.js
index 83ba570..bfdd7dd 100644
--- a/gui-clamp/ui-react/src/LoopUI.js
+++ b/gui-clamp/ui-react/src/LoopUI.js
@@ -55,7 +55,7 @@ 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 UploadToscaInstantiation from "./components/dialogs/ControlLoop/UploadToscaInstantiation";
+import InstanceModal from "./components/dialogs/ControlLoop/InstanceModal";
const StyledMainDiv = styled.div`
background-color: ${ props => props.theme.backgroundColor };
@@ -386,7 +386,7 @@ export default class LoopUI extends React.Component {
showFailAlert={ this.showFailAlert }/>) }
/>
<Route path="/monitorInstantiation" render={ (routeProps) => (<MonitorInstantiation { ...routeProps } />) }/>
- <Route path="/uploadToscaInstantiation" render={ (routeProps) => (<UploadToscaInstantiation { ...routeProps } />) }/>
+ <Route path="/editControlLoopInstanceProperties" render={ (routeProps) => (<InstanceModal { ...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 4529589..2123f37 100644
--- a/gui-clamp/ui-react/src/__snapshots__/LoopUI.test.js.snap
+++ b/gui-clamp/ui-react/src/__snapshots__/LoopUI.test.js.snap
@@ -90,7 +90,7 @@ exports[`Verify LoopUI Test the render method 1`] = `
render={[Function]}
/>
<Route
- path="/uploadToscaInstantiation"
+ path="/editControlLoopInstanceProperties"
render={[Function]}
/>
<div />
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 a5f4c33..d9cf3d3 100644
--- a/gui-clamp/ui-react/src/__snapshots__/OnapClamp.test.js.snap
+++ b/gui-clamp/ui-react/src/__snapshots__/OnapClamp.test.js.snap
@@ -119,7 +119,7 @@ exports[`Verify OnapClamp Test the render method 1`] = `
render={[Function]}
/>
<Route
- path="/uploadToscaInstantiation"
+ path="/editControlLoopInstanceProperties"
render={[Function]}
/>
<div />
diff --git a/gui-clamp/ui-react/src/api/ControlLoopService.js b/gui-clamp/ui-react/src/api/ControlLoopService.js
index 5938bd2..513fe68 100644
--- a/gui-clamp/ui-react/src/api/ControlLoopService.js
+++ b/gui-clamp/ui-react/src/api/ControlLoopService.js
@@ -19,7 +19,7 @@
export default class ControlLoopService {
- static async fetchControlLoopInstantiation(windowLocationPathname) {
+ static async getControlLoopInstantiation(windowLocationPathname) {
return await fetch(windowLocationPathname + '/restservices/clds/v2/toscaControlLoop/getToscaInstantiation', {
method: 'GET',
@@ -45,18 +45,33 @@ export default class ControlLoopService {
});
}
- static async uploadToscaInstantiation(toscaObject, windowLocationPathname) {
+ static async getInstanceProperties(name, version, windowLocationPathname) {
+ const params = {
+ name: name,
+ version: version,
+ common: "false"
+ }
+
+ const response = await fetch(windowLocationPathname + '/restservices/clds/v2/toscaControlLoop/getCommonOrInstanceProperties' + '?' + (new URLSearchParams(params)));
+
+ this.checkResponseForError(response);
+
+ return response;
+ }
+
+ static async createInstanceProperties(instancePropertiesTemplate, windowLocationPathname) {
- const response = await fetch(windowLocationPathname + '/restservices/clds/v2/toscaControlLoop/postToscaInstantiation', {
+ const response = await fetch(windowLocationPathname +
+ '/restservices/clds/v2/toscaControlLoop/postToscaInstanceProperties', {
method: 'POST',
headers: {
- 'Content-Type': 'application/json',
+ "Content-Type": "application/json"
},
credentials: 'same-origin',
- body: JSON.stringify(toscaObject)
+ body: JSON.stringify(instancePropertiesTemplate),
});
- return response;
+ return response
}
static async getToscaTemplate(name, version, windowLocationPathname) {
@@ -68,37 +83,11 @@ export default class ControlLoopService {
const response = await fetch(windowLocationPathname +
'/restservices/clds/v2/toscaControlLoop/getToscaTemplate' + '?' + (new URLSearchParams(params)));
- const data = await response;
-
- return data;
- }
-
- static async deleteToscaTemplate(name, version, windowLocationPathname) {
- const params = {
- name: name,
- version: version
+ if (!response.ok) {
+ const message = `An error has occurred: ${ response.status }`;
+ throw new Error(message);
}
- const response = await fetch(windowLocationPathname +
- '/restservices/clds/v2/toscaControlLoop/decommissionToscaTemplate' + '?' + (new URLSearchParams(params)),
- {
- method: 'DELETE'
- });
-
- this.checkResponseForError(response);
-
- const data = await response;
-
- return data;
- }
-
- static async getToscaControlLoopDefinitions(windowLocationPathname) {
-
- const response = await fetch(windowLocationPathname +
- '/restservices/clds/v2/toscaControlLoop/getElementDefinitions');
-
- this.checkResponseForError(response);
-
const data = await response;
return data;
@@ -149,10 +138,11 @@ export default class ControlLoopService {
return response;
}
- static checkResponseForError (response) {
+ static checkResponseForError(response) {
if (!response.ok) {
- const message = `An error has occurred: ${response.status}`;
+ const message = `An error has occurred: ${ response.status }`;
throw new Error(message);
}
}
+
}
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.js
new file mode 100644
index 0000000..7a66812
--- /dev/null
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.js
@@ -0,0 +1,261 @@
+/*
+ * ============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 Modal from "react-bootstrap/Modal";
+import styled from "styled-components";
+import Button from "react-bootstrap/Button";
+import ControlLoopService from "../../../api/ControlLoopService";
+import { JSONEditor } from "@json-editor/json-editor";
+import Alert from "react-bootstrap/Alert";
+
+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 templateName = "ToscaServiceTemplateSimple";
+const templateVersion = "1.0.0";
+let tempJsonEditor = null;
+
+const InstanceModal = (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);
+
+ useEffect(async () => {
+ const toscaInstanceProperties = await ControlLoopService.getInstanceProperties(templateName, templateVersion, windowLocationPathname).catch(error => error.message);
+
+ const toscaSchemaResponse = await ControlLoopService.getToscaTemplate(templateName, templateVersion, windowLocationPathname).catch(error => error.message);
+
+ await parseJsonSchema(toscaSchemaResponse, toscaInstanceProperties);
+
+ }, []);
+
+ const parseJsonSchema = async (fullTemplate, initialProperties) => {
+
+ const fullJsonSchemaTemplate = await fullTemplate.json();
+ setToscaFullTemplate(fullJsonSchemaTemplate);
+
+ const filteredInitialStartValues = {};
+
+ const instanceProperties = await initialProperties.json().then(properties => {
+ const filteredTemplateObj = {};
+ const propertiesTemplateArray = Object.entries(properties);
+
+ propertiesTemplateArray.forEach(([key, value]) => {
+ const propertiesObj = {
+ properties: value.properties
+ }
+
+ const propValues = {};
+ filteredTemplateObj[key] = propertiesObj;
+
+ const jsonNodeSchemaKey = fullJsonSchemaTemplate.topology_template.node_templates[key]
+
+ Object.entries(propertiesObj.properties).forEach(([pKey, pValue]) => {
+ propValues[pKey] = jsonNodeSchemaKey.properties[pKey];
+ });
+
+ filteredInitialStartValues[key] = propValues;
+ });
+
+ setToscaFilteredInitialValues(filteredInitialStartValues);
+
+ return filteredTemplateObj;
+ });
+
+ const propertySchema = makeSchemaForInstanceProperties(instanceProperties);
+ setToscaJsonSchema(propertySchema);
+
+ tempJsonEditor = createJsonEditor(propertySchema, filteredInitialStartValues);
+ setJsonEditor(tempJsonEditor);
+ }
+
+ const makeSchemaForInstanceProperties = (instanceProps) => {
+ const instancePropsArray = Object.entries(instanceProps);
+
+ const newSchemaObject = {};
+
+ newSchemaObject.title = "InstanceProperties";
+ newSchemaObject.type = "object";
+ newSchemaObject.properties = {};
+
+ const newSchemaObjectArray = [];
+ instancePropsArray.forEach(([key, value]) => {
+ const templateObj = {};
+ const propertiesObject = {};
+
+ Object.entries(value.properties).forEach(([pKey, pValue]) => {
+ propertiesObject[pKey] = {
+ type: getType(pValue.type)
+ }
+ });
+
+ newSchemaObject.properties[key] = {
+ properties: propertiesObject
+ }
+ });
+
+ return newSchemaObject;
+ }
+
+ const getType = (pType) => {
+ switch (pType) {
+ case "string":
+ return "string";
+ case "integer":
+ return "integer";
+ case "list":
+ return "array";
+ case "object":
+ return "object";
+ default:
+ return "string";
+
+ }
+ }
+
+ const createJsonEditor = (fullSchema, instanceProperties) => {
+ JSONEditor.defaults.options.collapse = true;
+
+ return new JSONEditor(document.getElementById("editor"),
+ {
+ schema: fullSchema,
+ startval: instanceProperties,
+ theme: 'bootstrap4',
+ iconlib: 'fontawesome5',
+ object_layout: 'normal',
+ disable_properties: false,
+ disable_edit_json: false,
+ disable_array_reorder: true,
+ disable_array_delete_last_row: true,
+ disable_array_delete_all_rows: false,
+ array_controls_top: true,
+ keep_oneof_values: false,
+ collapsed: true,
+ show_errors: 'always',
+ display_required_only: false,
+ show_opt_in: false,
+ prompt_before_delete: true,
+ required_by_default: false,
+ });
+ }
+
+ const handleClose = () => {
+ console.log('handleClose called');
+ setShow(false);
+ props.history.push('/');
+ }
+
+ const updateTemplate = (jsonEditorValues) => {
+ const nodeTemplates = toscaFullTemplate.topology_template.node_templates;
+ const instanceDataProperties = Object.entries(jsonEditorValues);
+
+ instanceDataProperties.forEach(([key, value]) => {
+ const nodeTemplatesKey = nodeTemplates[key]
+ Object.entries(value).forEach((pKey, pValue) => {
+ nodeTemplatesKey.properties[pKey] = pValue;
+ });
+ });
+
+ toscaFullTemplate.topology_template.node_templates = nodeTemplates;
+
+ setToscaFullTemplate(toscaFullTemplate);
+
+ }
+
+ const handleSave = async () => {
+ console.log("handleSave called")
+
+ setWindowLocationPathname(window.location.pathname);
+
+ updateTemplate(jsonEditor.getValue());
+
+ const response = await ControlLoopService.createInstanceProperties(toscaFullTemplate, windowLocationPathname).catch(error => error.message);
+
+ if (response.ok) {
+ successAlert();
+ } else {
+ await errorAlert(response);
+ }
+ }
+
+ const successAlert = () => {
+ console.log("successAlert called");
+ setAlertMessage(<Alert variant="success">
+ <Alert.Heading>Instantiation Properties Success</Alert.Heading>
+ <p>Instance Properties was successfully saved</p>
+ <hr/>
+ </Alert>);
+ }
+
+ const errorAlert = async (response) => {
+ console.log("errorAlert called");
+ setAlertMessage(<Alert variant="danger">
+ <Alert.Heading>Instantiation Properties Failure</Alert.Heading>
+ <p>An error occurred while trying to save</p>
+ <p>Status code: { await response.status } : { response.statusText }</p>
+ <p>Status Text: { await response.text() }</p>
+ <hr/>
+ </Alert>);
+ }
+
+ return (
+ <ModalStyled size="xl"
+ show={ show }
+ onHide={ handleClose }
+ backdrop="static"
+ keyboard={ false }>
+ <Modal.Header closeButton>
+ <Modal.Title>Change Tosca Instance Properties</Modal.Title>
+ </Modal.Header>
+ <div style={ { padding: '5px 5px 0 5px' } }>
+ <Modal.Body>
+ <div id="editor"/>
+ </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 InstanceModal;
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.test.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.test.js
new file mode 100644
index 0000000..36a77d7
--- /dev/null
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.test.js
@@ -0,0 +1,70 @@
+/*
+ * ============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 InstanceModal from "./InstanceModal";
+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 />);
+ });
+
+ it("renders correctly", () => {
+ const tree = shallow(<InstanceModal />);
+ expect(toJson(tree)).toMatchSnapshot();
+ });
+
+ it('should have submit button element', () => {
+ const container = shallow(<InstanceModal/>)
+ expect(container.find('[variant="primary"]').length).toEqual(1);
+ });
+
+ it('should have close button element', () => {
+ const container = shallow(<InstanceModal/>)
+ expect(container.find('[variant="secondary"]').length).toEqual(1);
+ });
+
+ it('handleCreateUpdateToscaInstanceProperties called when submit button clicked', () => {
+ const history = createMemoryHistory();
+ const component = mount(<InstanceModal />)
+ const logSpy = jest.spyOn(console, 'log');
+
+ act(() => {
+ component.find('[variant="primary"]').simulate('click');
+ expect(logSpy).toHaveBeenCalledWith('handleSave called');
+ });
+ });
+
+ it('handleClose called when close button clicked', () => {
+ const history = createMemoryHistory();
+ const component = mount(<InstanceModal 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/ControlLoop/MonitorInstantiation.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/MonitorInstantiation.js
index 428defa..47de20c 100644
--- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/MonitorInstantiation.js
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/MonitorInstantiation.js
@@ -37,7 +37,7 @@ const MonitorInstantiation = (props) => {
useEffect(() => {
setWindowLocationPathname(window.location.pathname);
- ControlLoopService.fetchControlLoopInstantiation(windowLocationPathname).then(controlLoopList => {
+ ControlLoopService.getControlLoopInstantiation(windowLocationPathname).then(controlLoopList => {
setControlLoopList(controlLoopList['controlLoopList']);
});
}, [])
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiation.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiation.js
deleted file mode 100644
index d9bbe8b..0000000
--- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiation.js
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * ============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, { useState } from "react";
-import Modal from "react-bootstrap/Modal";
-import Button from "react-bootstrap/Button";
-import styled from "styled-components";
-import Row from "react-bootstrap/Row";
-import Form from "react-bootstrap/Form";
-import UploadToscaInstantiationFile from "./UploadToscaInstantiationFile";
-import jsYaml from "js-yaml";
-import Alert from "react-bootstrap/Alert";
-
-const ModalStyled = styled(Modal)`
- background-color: transparent;
-`
-const StyledMessagesDiv = styled.div`
- overflow: auto;
- min-width: 100%;
- max-height: 300px;
- padding: 5px 5px 0px 5px;
- text-align: center;
-`
-
-const UploadToscaInstantiation = (props) => {
- const [show, setShow] = useState(true);
- const [fileIsSelected, setFileIsSelected] = useState(false);
- const [selectedFile, setSelectedFile] = useState();
- const [jsonObject, setJsonObject] = useState([]);
- const [alertMessages, setAlertMessages] = useState();
-
- const fileUploadHandler = (event) => {
- event.preventDefault();
- console.log('fileUploadHandler called');
-
- const file = event.currentTarget.files[0];
-
- if (file !== undefined) {
- console.log('fileDefined called');
- setSelectedFile(file);
- setFileIsSelected(true);
-
- const fileReader = new FileReader();
- fileReader.onload = () => {
- const jsonFile = jsYaml.load(fileReader.result, 'utf8')
- setJsonObject(jsonFile)
- }
-
- fileReader.readAsText(file);
- } else {
- console.log('fileUndefined called');
- }
- }
-
- const onResponseReceivedHandler = async (response) => {
- console.log('onResponseReceivedHandler called');
-
- if (await response.ok) {
- setAlertMessages(<Alert variant="success">
- <Alert.Heading>Upload Success</Alert.Heading>
- <p>Tosca Instantiation from { selectedFile.name } was Successfully Uploaded</p>
- <hr/>
- <p>Type: { selectedFile.type }</p><p>Size: { +selectedFile.size / 1000 }Kb</p>
- </Alert>);
- } else {
- setAlertMessages(<Alert variant="danger">
- <Alert.Heading>Upload Failure</Alert.Heading>
- <p>Tosca Instantiation from { selectedFile.name } failed to upload</p>
- <p>Status code: { await response.status }: { response.statusText }</p>
- <p>Response Text: { await response.text() }</p>
- <hr/>
- <p>Type: { selectedFile.type }</p><p>Size: { +selectedFile.size / 1000 }Kb</p>
- </Alert>);
- }
- }
-
- const handleClose = () => {
- console.log('handleClose called');
- setShow(false);
- props.history.push('/');
- }
-
- return (
- <ModalStyled size="lg" show={ show } onHide={ handleClose } backdrop="static" keyboard={ false }>
- <Modal.Header closeButton>
- <Modal.Title>Tosca Control Loop - Create Instantiation</Modal.Title>
- </Modal.Header>
- <div style={ { padding: '5px 5px 0px 5px' } }>
- <Modal.Body>
- <Form style={ { paddingTop: '20px' } }>
- <Form.Group as={ Row }>
- <Form.File
- type="file"
- className="custom-file-label"
- id="inputGroupFile01"
- onChange={ fileUploadHandler }
- custom
- accept=".yaml,.yml,.json"
- label={ fileIsSelected ? selectedFile.name : 'Please select a file' }></Form.File>
- <UploadToscaInstantiationFile
- jsonObject={jsonObject}
- onResponseReceived={onResponseReceivedHandler}/>
- <Form.Text>Only .yaml, .yml and .json files are supported</Form.Text>
- </Form.Group>
- <Form.Group as={ Row }>
- <StyledMessagesDiv>
- { alertMessages }
- </StyledMessagesDiv>
- </Form.Group>
- </Form>
- </Modal.Body>
- </div>
- <Modal.Footer>
- <Button variant="secondary" type="null" onClick={ handleClose }>Close</Button>
- </Modal.Footer>
- </ModalStyled>
- )
-}
-
-export default UploadToscaInstantiation;
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiation.test.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiation.test.js
deleted file mode 100644
index 79daafb..0000000
--- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiation.test.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * ============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 UploadToscaInstantiation from "./UploadToscaInstantiation";
-import { createMemoryHistory } from "history";
-import { act } from "react-dom/test-utils";
-
-describe("Verify UploadToscaInstantiation", () => {
- const fs = require("fs");
- const jsonFile = fs.readFileSync("src/components/dialogs/Policy/toscaInstantiationData.test.json");
- const file = new Blob([jsonFile], { type: 'file' });
-
- it("renders without crashing", () => {
- shallow(<UploadToscaInstantiation/>);
- });
-
- it("renders correctly", () => {
- const tree = shallow(<UploadToscaInstantiation/>);
- expect(toJson(tree)).toMatchSnapshot();
- });
-
- it('should have a Button element', () => {
- const container = shallow(<UploadToscaInstantiation/>)
- expect(container.find('Button').length).toEqual(1);
- });
-
- it('handleClose called when bottom button clicked', () => {
- const history = createMemoryHistory();
- const component = mount(<UploadToscaInstantiation history={ history }/>)
- const logSpy = jest.spyOn(console, 'log');
-
-
- act(() => {
- component.find('[variant="secondary"]').simulate('click');
- expect(logSpy).toHaveBeenCalledWith('handleClose called');
- });
- });
-
- it('handleClose called when top-right button clicked', () => {
- const history = createMemoryHistory();
- const component = mount(<UploadToscaInstantiation history={ history }/>)
- const logSpy = jest.spyOn(console, 'log');
-
-
- act(() => {
- component.find('[size="lg"]').get(0).props.onHide();
- expect(logSpy).toHaveBeenCalledWith('handleClose called');
- });
- });
-
- it('fileUploadHandler called when uploading a defined file', () => {
- const component = mount(<UploadToscaInstantiation/>)
- const logSpy = jest.spyOn(console, 'log');
-
- const event = {
- preventDefault() {
- },
- currentTarget: { files: [file] }
- };
-
- act(() => {
- component.find('[type="file"]').get(0).props.onChange(event);
- expect(logSpy).toHaveBeenCalledWith('fileUploadHandler called');
- expect(logSpy).toHaveBeenCalledWith('fileDefined called');
- });
- });
-
- it('fileUploadHandler called when uploading a undefined file', () => {
- const component = mount(<UploadToscaInstantiation/>)
- const logSpy = jest.spyOn(console, 'log');
-
- const event = {
- preventDefault() {
- },
- currentTarget: { files: [] }
- };
-
- act(() => {
- component.find('[type="file"]').get(0).props.onChange(event);
- expect(logSpy).toHaveBeenCalledWith('fileUndefined called');
- });
- });
-});
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiationFile.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiationFile.js
deleted file mode 100644
index 5329bc0..0000000
--- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiationFile.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * ============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 Button from "react-bootstrap/Button";
-import ControlLoopService from "../../../api/ControlLoopService";
-
-const UploadToscaInstantiationFile = (props) => {
- const [windowLocationPathName, setWindowLocationPathname] = useState('');
-
- const postToscaInstantiationHandler = async (event) => {
- event.preventDefault();
- console.log('postToscaInstantiationHandler called');
-
- setWindowLocationPathname(window.location.pathname);
-
- const response = await ControlLoopService.uploadToscaInstantiation(props.jsonObject, windowLocationPathName)
- .catch(error => error.message);
-
- props.onResponseReceived(response);
- }
-
- return (
- <React.Fragment>
- <Button variant="primary"
- block={ true }
- type="submit"
- onClick={ postToscaInstantiationHandler }>
- Upload Tosca Instantiation
- </Button>
- </React.Fragment>
- );
-}
-
-export default UploadToscaInstantiationFile;
-
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiationFile.test.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiationFile.test.js
deleted file mode 100644
index 83ab8d5..0000000
--- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiationFile.test.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * ============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 UploadToscaInstantiationFile from "./UploadToscaInstantiationFile";
-import toJson from "enzyme-to-json";
-import { act } from "react-dom/test-utils";
-
-describe('Verify UploadToscaInstantiationFile', () => {
-
- it("renders without crashing", () => {
- shallow(<UploadToscaInstantiationFile />);
- });
-
- it("renders correctly", () => {
- const tree = shallow(<UploadToscaInstantiationFile />);
- expect(toJson(tree)).toMatchSnapshot();
- });
-
- it('should have a Button element', () => {
- const container = shallow(<UploadToscaInstantiationFile />)
- expect(container.find('Button').length).toEqual(1);
- });
-
- it('Button should have a specific text', () => {
- const container = shallow(<UploadToscaInstantiationFile />)
- expect(container.find('Button').text()).toBe('Upload Tosca Instantiation');
- });
-
- it('button should call postToscaInstantiationHandler when clicked', async () => {
- const mockFunction = jest.fn(() => 'default');
- const component = mount(<UploadToscaInstantiationFile onResponseReceived={mockFunction}/>)
- const logSpy = jest.spyOn(console, 'log');
- const event = {
- preventDefault() {
- }
- };
-
- await act(async () => {
- component.find('[variant="primary"]').get(0).props.onClick(event);
- expect(logSpy).toHaveBeenCalledWith('postToscaInstantiationHandler called');
- });
- });
-});
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__/InstanceModal.test.js.snap
new file mode 100644
index 0000000..07ae8f8
--- /dev/null
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/InstanceModal.test.js.snap
@@ -0,0 +1,52 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Verify MonitoringInstantiation renders correctly 1`] = `
+<Styled(Modal)
+ backdrop="static"
+ keyboard={false}
+ onHide={[Function]}
+ show={true}
+ size="xl"
+>
+ <ModalHeader
+ closeButton={true}
+ closeLabel="Close"
+ >
+ <ModalTitle>
+ Change Tosca Instance Properties
+ </ModalTitle>
+ </ModalHeader>
+ <div
+ style={
+ Object {
+ "padding": "5px 5px 0 5px",
+ }
+ }
+ >
+ <ModalBody>
+ <div
+ id="editor"
+ />
+ </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/dialogs/ControlLoop/__snapshots__/UploadToscaInstantiation.test.js.snap b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/UploadToscaInstantiation.test.js.snap
deleted file mode 100644
index 77e4b99..0000000
--- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/UploadToscaInstantiation.test.js.snap
+++ /dev/null
@@ -1,91 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Verify UploadToscaInstantiation renders correctly 1`] = `
-<Styled(Modal)
- backdrop="static"
- keyboard={false}
- onHide={[Function]}
- show={true}
- size="lg"
->
- <ModalHeader
- closeButton={true}
- closeLabel="Close"
- >
- <ModalTitle>
- Tosca Control Loop - Create Instantiation
- </ModalTitle>
- </ModalHeader>
- <div
- style={
- Object {
- "padding": "5px 5px 0px 5px",
- }
- }
- >
- <ModalBody>
- <Form
- inline={false}
- style={
- Object {
- "paddingTop": "20px",
- }
- }
- >
- <FormGroup
- as={
- Object {
- "$$typeof": Symbol(react.forward_ref),
- "defaultProps": Object {
- "noGutters": false,
- },
- "render": [Function],
- }
- }
- >
- <FormFile
- accept=".yaml,.yml,.json"
- className="custom-file-label"
- custom={true}
- id="inputGroupFile01"
- label="Please select a file"
- onChange={[Function]}
- type="file"
- />
- <UploadToscaInstantiationFile
- jsonObject={Array []}
- onResponseReceived={[Function]}
- />
- <FormText>
- Only .yaml, .yml and .json files are supported
- </FormText>
- </FormGroup>
- <FormGroup
- as={
- Object {
- "$$typeof": Symbol(react.forward_ref),
- "defaultProps": Object {
- "noGutters": false,
- },
- "render": [Function],
- }
- }
- >
- <styled.div />
- </FormGroup>
- </Form>
- </ModalBody>
- </div>
- <ModalFooter>
- <Button
- active={false}
- disabled={false}
- onClick={[Function]}
- type="null"
- variant="secondary"
- >
- Close
- </Button>
- </ModalFooter>
-</Styled(Modal)>
-`;
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/UploadToscaInstantiationFile.test.js.snap b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/UploadToscaInstantiationFile.test.js.snap
deleted file mode 100644
index 3ac5087..0000000
--- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/UploadToscaInstantiationFile.test.js.snap
+++ /dev/null
@@ -1,16 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Verify UploadToscaInstantiationFile renders correctly 1`] = `
-<Fragment>
- <Button
- active={false}
- block={true}
- disabled={false}
- onClick={[Function]}
- type="submit"
- variant="primary"
- >
- Upload Tosca Instantiation
- </Button>
-</Fragment>
-`;
diff --git a/gui-clamp/ui-react/src/components/menu/MenuBar.js b/gui-clamp/ui-react/src/components/menu/MenuBar.js
index abe73c1..7ee7ffd 100644
--- a/gui-clamp/ui-react/src/components/menu/MenuBar.js
+++ b/gui-clamp/ui-react/src/components/menu/MenuBar.js
@@ -116,7 +116,7 @@ export default class MenuBar extends React.Component {
<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="/uploadToscaInstantiation">Upload Tosca Instantiation</NavDropdown.Item>
+ <NavDropdown.Item as={ StyledLink } to="/editControlLoopInstanceProperties">Edit Control Loop Instance Properties</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 800e1dd..edc0624 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,9 +1136,9 @@ exports[`Verify MenuBar Test the render method 1`] = `
}
}
disabled={false}
- to="/uploadToscaInstantiation"
+ to="/editControlLoopInstanceProperties"
>
- Upload Tosca Instantiation
+ Edit Control Loop Instance Properties
</DropdownItem>
<DropdownDivider
role="separator"