aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsaul.gill <saul.gill@est.tech>2021-07-26 17:33:24 +0100
committersaul.gill <saul.gill@est.tech>2021-07-29 09:45:44 +0100
commit83c09e788eb75b287c946acbcba0d43cd3cd4681 (patch)
tree7a090a2227bb3a4143b14aa80ed40680801ff844
parent29871bc266df6b4418f30311ce9d0ef9ddd9965c (diff)
Added Common Parameter Form
Added save button for user edits Added commission button to push up edits Added service to retrieve common parameters Issue-ID: POLICY-3439 Change-Id: Ia355f36bf263bb1385db363a267c53af86504905 Signed-off-by: saul.gill <saul.gill@est.tech>
-rw-r--r--gui-clamp/ui-react/src/api/ControlLoopService.js16
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/CommissioningModal.js192
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/CommissioningModal.test.js4
-rw-r--r--gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/CommissioningModal.test.js.snap14
-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.snap2
6 files changed, 193 insertions, 37 deletions
diff --git a/gui-clamp/ui-react/src/api/ControlLoopService.js b/gui-clamp/ui-react/src/api/ControlLoopService.js
index 1f3cbed..5938bd2 100644
--- a/gui-clamp/ui-react/src/api/ControlLoopService.js
+++ b/gui-clamp/ui-react/src/api/ControlLoopService.js
@@ -119,6 +119,22 @@ export default class ControlLoopService {
}
+ static async getCommonProperties(name, version, windowLocationPathName) {
+ const params = {
+ name: name,
+ version: version,
+ common: "true"
+ }
+
+ const response = await fetch(windowLocationPathName +
+ '/restservices/clds/v2/toscaControlLoop/getCommonOrInstanceProperties' + '?' + (new URLSearchParams(params)));
+
+ this.checkResponseForError(response);
+
+ return response;
+
+ }
+
static async getToscaServiceTemplateSchema(section, windowLocationPathName) {
const params = {
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/CommissioningModal.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/CommissioningModal.js
index 6baa06c..ffe149a 100644
--- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/CommissioningModal.js
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/CommissioningModal.js
@@ -23,7 +23,7 @@ import React, { useEffect, useState } from "react";
import styled from "styled-components";
import { JSONEditor } from "@json-editor/json-editor";
import ControlLoopService from "../../../api/ControlLoopService";
-import OnapConstant from "../../../utils/OnapConstants";
+import { Alert } from "react-bootstrap";
const ModalStyled = styled(Modal)`
@media (min-width: 800px) {
@@ -44,10 +44,26 @@ const StyledMessagesDiv = styled.div`
const CommissioningModal = (props) => {
const [windowLocationPathName, setWindowLocationPathName] = useState('');
+ const [fullToscaTemplate, setFullToscaTemplate] = useState({});
const [toscaInitialValues, setToscaInitialValues] = useState({});
+ const [commonProperties, setCommonProperties] = useState({})
const [toscaJsonSchema, setToscaJsonSchema] = useState({});
- const [jsonEditor, setJsonEditor] = useState({});
+ const [jsonEditor, setJsonEditor] = useState(null);
const [show, setShow] = useState(true);
+ const [alertMessages, setAlertMessages] = useState();
+ const name = 'ToscaServiceTemplateSimple';
+ const version = '1.0.0';
+ let editorTemp = null
+
+ useEffect(async () => {
+ const toscaTemplateResponse = await ControlLoopService.getToscaTemplate(name, version, windowLocationPathName)
+ .catch(error => error.message);
+ const toscaCommonProperties = await ControlLoopService.getCommonProperties(name, version, windowLocationPathName)
+ .catch(error => error.message);
+
+ await renderJsonEditor(toscaTemplateResponse, toscaCommonProperties)
+
+ }, []);
const handleClose = () => {
console.log('handleClose called');
@@ -55,43 +71,150 @@ const CommissioningModal = (props) => {
props.history.push('/');
}
- const getToscaServiceTemplateHandler = async (toscaServiceTemplateResponse) => {
+ const handleSave = () => {
+ updateTemplate(jsonEditor.getValue())
+ }
- if (!toscaServiceTemplateResponse.ok) {
- const toscaData = await toscaServiceTemplateResponse;
- setToscaInitialValues(toscaData);
- } else {
- const toscaData = await toscaServiceTemplateResponse.json();
- setToscaInitialValues(toscaData);
- }
+
+
+ const handleCommission = async () => {
+ setWindowLocationPathName(window.location.pathname);
+
+ await ControlLoopService.deleteToscaTemplate('ToscaServiceTemplateSimple', "1.0.0", windowLocationPathName)
+ .catch(error => error.message)
+
+ const recommissioningResponse = await ControlLoopService.uploadToscaFile(fullToscaTemplate, windowLocationPathName)
+ .catch(error => error.message)
+
+ await receiveResponseFromCommissioning(recommissioningResponse)
}
- const getToscaSchemaHandler = async (toscaSchemaResponse) => {
+ const receiveResponseFromCommissioning = async (response) => {
- if (!toscaSchemaResponse.ok) {
- const toscaSchemaData = await toscaSchemaResponse;
- setToscaJsonSchema(toscaSchemaData);
- } else {
- const toscaSchemaData = await toscaSchemaResponse.json();
- setToscaJsonSchema(toscaSchemaData);
+ if (await response.ok) {
+ setAlertMessages(<Alert variant="success">
+ <Alert.Heading>Commissioning Success</Alert.Heading>
+ <p>Altered Template was Successfully Uploaded</p>
+ <hr/>
+ </Alert>);
+ }
+ else {
+ setAlertMessages(<Alert variant="danger">
+ <Alert.Heading>Commissioning Failure</Alert.Heading>
+ <p>Updated Template Failed to Upload</p>
+ <p>Status code: { await response.status }: { response.statusText }</p>
+ <p>Response Text: { await response.text() }</p>
+ <hr/>
+ </Alert>);
}
+ };
+
+ const renderJsonEditor = async (template, commonProps) => {
+
+ const fullTemplate = await template.json()
+
+ setFullToscaTemplate(fullTemplate)
+ const allNodeTemplates = fullTemplate.topology_template.node_templates
+ const shortenedNodeTemplatesObjectStartValues = {}
+ // Get the common properties to construct a schema
+ // Get valid start values at the same time
+ const commonNodeTemplatesJson = await commonProps.json().then(data => {
+ const nodeTemplatesArray = Object.entries(data)
+ const shortenedNodeTemplatesObject = {}
+ nodeTemplatesArray.forEach(([key, temp]) => {
+ const currentNodeTemplate = allNodeTemplates[key]
+ const propertiesObject = {
+ properties: temp.properties
+ }
+
+ shortenedNodeTemplatesObject[key] = propertiesObject
+
+ const propertiesStartValues = {}
+
+ // Get all the existing start values to populate the properties in the schema
+ Object.entries(propertiesObject.properties).forEach(([propKey, prop]) => {
+ propertiesStartValues[propKey] = currentNodeTemplate.properties[propKey]
+ })
+
+ shortenedNodeTemplatesObjectStartValues[key] = propertiesStartValues
+
+ })
+
+ setToscaInitialValues(shortenedNodeTemplatesObjectStartValues)
+ return shortenedNodeTemplatesObject;
+ })
+
+ const propertySchema = makeSchemaForCommonProperties(commonNodeTemplatesJson)
+ setToscaJsonSchema(propertySchema)
+
+ editorTemp = createJsonEditor(propertySchema, shortenedNodeTemplatesObjectStartValues);
+ setJsonEditor(editorTemp)
}
- useEffect(async () => {
- setWindowLocationPathName(window.location.pathname);
+ const updateTemplate = (userAddedCommonPropValues) => {
+ const nodeTemplates = fullToscaTemplate.topology_template.node_templates
+ const commonPropertyDataEntries = Object.entries(userAddedCommonPropValues)
- const toscaTemplateResponse = await ControlLoopService.getToscaControlLoopDefinitions(windowLocationPathName)
- .catch(error => error.message);
+ // This replaces the values for properties in the full tosca template
+ // that will be sent up to the api with the entries the user provided.
+ commonPropertyDataEntries.forEach(([templateKey, values]) => {
+ Object.entries(values).forEach(([propKey, propVal]) => {
+ nodeTemplates[templateKey].properties[propKey] = propVal
+ })
+ })
+
+ fullToscaTemplate.topology_template.node_templates = nodeTemplates
+
+ setFullToscaTemplate(fullToscaTemplate)
+ alert('Changes saved. Commission When Ready...')
+ }
- const toscaSchemaResponse = await ControlLoopService.getToscaServiceTemplateSchema('node_templates', windowLocationPathName);
+ const makeSchemaForCommonProperties = (commonProps) => {
+ const commonPropsArr = Object.entries(commonProps)
- createJsonEditor(await toscaSchemaResponse.json(), await toscaTemplateResponse.json());
+ const newSchemaObject = {}
- }, []);
+ newSchemaObject.title = "CommonProperties"
+ newSchemaObject.type = "object"
+ newSchemaObject.properties = {}
+
+ commonPropsArr.forEach(([templateKey, template]) => {
+
+ const propertiesObject = {}
+ Object.entries(template.properties).forEach(([propKey, prop]) => {
+
+ propertiesObject[propKey] = {
+ type: getType(prop.type)
+ }
+
+ })
+ newSchemaObject.properties[templateKey] = {
+ properties: propertiesObject
+ }
+ })
+
+ return newSchemaObject
+
+ }
+
+ const getType = (propertyType) => {
+ switch (propertyType)
+ {
+ case "string":
+ return "string"
+ case "integer":
+ return "integer"
+ case "list":
+ return "array"
+ case "object":
+ return "object"
+ default:
+ return "string"
+ }
+ }
- // TODO Need to Hook this up to a new camel endpoint to get it working
const createJsonEditor = (toscaModel, editorData) => {
- JSONEditor.defaults.options.collapse = true;
+ JSONEditor.defaults.options.collapse = false;
return new JSONEditor(document.getElementById("editor"),
{
@@ -101,13 +224,13 @@ const CommissioningModal = (props) => {
iconlib: 'fontawesome5',
object_layout: 'normal',
disable_properties: false,
- disable_edit_json: false,
+ disable_edit_json: true,
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,
+ collapsed: false,
show_errors: 'always',
display_required_only: false,
show_opt_in: false,
@@ -123,7 +246,7 @@ const CommissioningModal = (props) => {
backdrop="static"
keyboard={ false }>
<Modal.Header closeButton>
- <Modal.Title>Edit Control Loop Parameters</Modal.Title>
+ <Modal.Title>Edit Common Properties</Modal.Title>
</Modal.Header>
<br/>
<div style={ { padding: '5px 5px 0px 5px' } }>
@@ -131,9 +254,16 @@ const CommissioningModal = (props) => {
<div id="editor"/>
</Modal.Body>
</div>
+ <StyledMessagesDiv>
+ { alertMessages }
+ </StyledMessagesDiv>
<Modal.Footer>
- <Button variant="primary"
- >Submit</Button>
+ <Button
+ variant="primary"
+ onClick={ handleSave }
+ >Save</Button>
+ <Button variant="success"
+ onClick={ handleCommission }>Commission</Button>
<Button variant="secondary"
onClick={ handleClose }>Close</Button>
</Modal.Footer>
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/CommissioningModal.test.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/CommissioningModal.test.js
index f189c58..054450c 100644
--- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/CommissioningModal.test.js
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/CommissioningModal.test.js
@@ -37,9 +37,9 @@ describe('Verify ReadAndConvertYaml', () => {
expect(toJson(tree)).toMatchSnapshot();
});
- it('should have two Button elements', () => {
+ it('should have three Button elements', () => {
const container = shallow(<CommissioningModal/>)
- expect(container.find('Button').length).toEqual(2);
+ expect(container.find('Button').length).toEqual(3);
});
it('handleClose called when bottom button clicked', () => {
diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/CommissioningModal.test.js.snap b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/CommissioningModal.test.js.snap
index 78c8983..41c13de 100644
--- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/CommissioningModal.test.js.snap
+++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/CommissioningModal.test.js.snap
@@ -13,7 +13,7 @@ exports[`Verify ReadAndConvertYaml renders correctly 1`] = `
closeLabel="Close"
>
<ModalTitle>
- Edit Control Loop Parameters
+ Edit Common Properties
</ModalTitle>
</ModalHeader>
<br />
@@ -30,13 +30,23 @@ exports[`Verify ReadAndConvertYaml renders correctly 1`] = `
/>
</ModalBody>
</div>
+ <styled.div />
<ModalFooter>
<Button
active={false}
disabled={false}
+ onClick={[Function]}
variant="primary"
>
- Submit
+ Save
+ </Button>
+ <Button
+ active={false}
+ disabled={false}
+ onClick={[Function]}
+ variant="success"
+ >
+ Commission
</Button>
<Button
active={false}
diff --git a/gui-clamp/ui-react/src/components/menu/MenuBar.js b/gui-clamp/ui-react/src/components/menu/MenuBar.js
index 650196c..abe73c1 100644
--- a/gui-clamp/ui-react/src/components/menu/MenuBar.js
+++ b/gui-clamp/ui-react/src/components/menu/MenuBar.js
@@ -121,7 +121,7 @@ export default class MenuBar extends React.Component {
<NavDropdown.Header>Commissioning</NavDropdown.Header>
<NavDropdown.Item as={ StyledLink } to="/readToscaTemplate">Manage Commissioned Tosca Template</NavDropdown.Item>
<NavDropdown.Item as={ StyledLink } to="/uploadToscaFile">Upload Tosca to Commissioning</NavDropdown.Item>
- <NavDropdown.Item as={ StyledLink } to="/getJsonSchema">Edit Control Loop Type Definitions</NavDropdown.Item>
+ <NavDropdown.Item as={ StyledLink } to="/getJsonSchema">Edit Control Loop Common Properties</NavDropdown.Item>
</StyledNavDropdown>
<StyledNavDropdown title="Help">
<StyledNavLink href="https://wiki.onap.org/" target="_blank">Wiki</StyledNavLink>
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 a1705ee..800e1dd 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
@@ -1341,7 +1341,7 @@ exports[`Verify MenuBar Test the render method 1`] = `
disabled={false}
to="/getJsonSchema"
>
- Edit Control Loop Type Definitions
+ Edit Control Loop Common Properties
</DropdownItem>
</Styled(NavDropdown)>
<Styled(NavDropdown)