From c11160ecfdce03091917e2728f80848f4d8feb95 Mon Sep 17 00:00:00 2001 From: sebdet Date: Tue, 25 Feb 2020 15:13:31 -0800 Subject: Add new dialog for policy Add a new dialog component for tosca based policy, config/op should use that dialog now. Issue-ID: CLAMP-653 Change-Id: I57523bc2d4bfbf5ca5a3acf5c59823df06fd4cd9 Signed-off-by: sebdet --- ui-react/src/LoopUI.js | 3 +- ui-react/src/__snapshots__/LoopUI.test.js.snap | 6 +- ui-react/src/__snapshots__/OnapClamp.test.js.snap | 6 +- ui-react/src/api/LoopCache.js | 27 ++++ .../ConfigurationPolicyModal.js | 12 +- .../ConfigurationPolicyModal.test.js | 4 +- .../src/components/dialogs/Policy/PolicyModal.js | 145 +++++++++++++++++++++ .../loop_viewer/svg/LoopComponentConverter.js | 9 +- .../src/components/loop_viewer/svg/LoopSvg.test.js | 8 +- 9 files changed, 202 insertions(+), 18 deletions(-) create mode 100644 ui-react/src/components/dialogs/Policy/PolicyModal.js (limited to 'ui-react/src') diff --git a/ui-react/src/LoopUI.js b/ui-react/src/LoopUI.js index 7f07f343..95106702 100644 --- a/ui-react/src/LoopUI.js +++ b/ui-react/src/LoopUI.js @@ -255,7 +255,8 @@ export default class LoopUI extends React.Component { ()} /> ()} /> - ()} /> + ()} /> + ()} /> ()} /> ()} /> ()} /> diff --git a/ui-react/src/__snapshots__/LoopUI.test.js.snap b/ui-react/src/__snapshots__/LoopUI.test.js.snap index 98f802df..3d0137c1 100644 --- a/ui-react/src/__snapshots__/LoopUI.test.js.snap +++ b/ui-react/src/__snapshots__/LoopUI.test.js.snap @@ -21,7 +21,11 @@ exports[`Verify LoopUI Test the render method 1`] = ` render={[Function]} /> + + { + this.state.loopCache.updateMicroServiceProperties(this.state.policyName, editorData[0]); + LoopService.setMicroServiceProperties(this.state.loopCache.getLoopName(), this.state.loopCache.getMicroServiceForName(this.state.policyName)).then(resp => { this.setState({ show: false }); this.props.history.push('/'); this.props.loadLoopFunction(this.state.loopCache.getLoopName()); @@ -78,12 +78,12 @@ export default class ConfigurationPolicyModal extends React.Component { } renderJsonEditor() { - console.debug("Rendering ConfigurationPolicyModal ", this.state.componentName); - var toscaModel = this.state.loopCache.getMicroServiceJsonRepresentationForName(this.state.componentName); + console.debug("Rendering ConfigurationPolicyModal ", this.state.policyName); + var toscaModel = this.state.loopCache.getMicroServiceJsonRepresentationForName(this.state.policyName); if (toscaModel == null) { return; } - var editorData = this.state.loopCache.getMicroServicePropertiesForName(this.state.componentName); + var editorData = this.state.loopCache.getMicroServicePropertiesForName(this.state.policyName); JSONEditor.defaults.options.theme = 'bootstrap4'; //JSONEditor.defaults.options.iconlib = 'bootstrap2'; diff --git a/ui-react/src/components/dialogs/ConfigurationPolicy/ConfigurationPolicyModal.test.js b/ui-react/src/components/dialogs/ConfigurationPolicy/ConfigurationPolicyModal.test.js index 4fa08e68..4d527b71 100644 --- a/ui-react/src/components/dialogs/ConfigurationPolicy/ConfigurationPolicyModal.test.js +++ b/ui-react/src/components/dialogs/ConfigurationPolicy/ConfigurationPolicyModal.test.js @@ -48,7 +48,7 @@ describe('Verify ConfigurationPolicyModal', () => { }] }); const historyMock = { push: jest.fn() }; - const matchMock = { params:{ componentName: "TCA_h2NMX_v1_0_ResourceInstanceName1_tca" } } + const matchMock = { params:{ policyName: "TCA_h2NMX_v1_0_ResourceInstanceName1_tca" } } const flushPromises = () => new Promise(setImmediate); it('Test handleClose', () => { @@ -73,7 +73,7 @@ describe('Verify ConfigurationPolicyModal', () => { expect(handleSave).toHaveBeenCalledTimes(1); expect(component.state('show')).toEqual(false); - expect(component.state('componentName')).toEqual("TCA_h2NMX_v1_0_ResourceInstanceName1_tca"); + expect(component.state('policyName')).toEqual("TCA_h2NMX_v1_0_ResourceInstanceName1_tca"); expect(historyMock.push.mock.calls[0]).toEqual([ '/']); }); }); \ No newline at end of file diff --git a/ui-react/src/components/dialogs/Policy/PolicyModal.js b/ui-react/src/components/dialogs/Policy/PolicyModal.js new file mode 100644 index 00000000..75ac2c49 --- /dev/null +++ b/ui-react/src/components/dialogs/Policy/PolicyModal.js @@ -0,0 +1,145 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * 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. + * ============LICENSE_END============================================ + * =================================================================== + * + */ + +import React from 'react' +import Button from 'react-bootstrap/Button'; +import Modal from 'react-bootstrap/Modal'; +import styled from 'styled-components'; +import LoopService from '../../../api/LoopService'; +import JSONEditor from '@json-editor/json-editor'; + +const ModalStyled = styled(Modal)` + background-color: transparent; +` + +export default class PolicyModal extends React.Component { + + state = { + show: true, + loopCache: this.props.loopCache, + jsonEditor: null, + policyName: this.props.match.params.policyName, + // This is to indicate whether it's an operational or config policy (in terms of loop instance) + policyInstanceType: this.props.match.params.policyInstanceType + }; + + constructor(props, context) { + super(props, context); + this.handleClose = this.handleClose.bind(this); + this.handleSave = this.handleSave.bind(this); + this.renderJsonEditor = this.renderJsonEditor.bind(this); + } + + handleSave() { + var errors = this.state.jsonEditor.validate(); + var editorData = this.state.jsonEditor.getValue(); + + if (errors.length !== 0) { + console.error("Errors detected during policy data validation ", errors); + this.setState({ show: false }); + this.props.history.push('/'); + } + else { + console.info("NO validation errors found in policy data"); + if (policyInstanceType === 'MICRO-SERVICE-POLICY') { + this.state.loopCache.updateMicroServiceProperties(this.state.policyName, editorData[0]); + LoopService.setMicroServiceProperties(this.state.loopCache.getLoopName(), this.state.loopCache.getMicroServiceForName(this.state.policyName)).then(resp => { + this.setState({ show: false }); + this.props.history.push('/'); + this.props.loadLoopFunction(this.state.loopCache.getLoopName()); + }); + } else if (policyInstanceType === 'OPERATIONAL-POLICY') { + this.state.loopCache.updateOperationalPolicyProperties(editorData); + LoopService.setOperationalPolicyProperties(this.state.loopCache.getLoopName(), this.state.loopCache.getOperationalPolicyForName(this.state.policyName)).then(resp => { + this.setState({ show: false }); + this.props.history.push('/'); + this.props.loadLoopFunction(this.state.loopCache.getLoopName()); + }); + } + } + } + + handleClose() { + this.setState({ show: false }); + this.props.history.push('/'); + } + + componentDidMount() { + this.renderJsonEditor(); + } + + renderJsonEditor() { + console.debug("Rendering PolicyModal ", this.state.policyName); + var toscaModel = {}; + var editorData = {}; + if (policyInstanceType === 'MICRO-SERVICE-POLICY') { + toscaModel = this.state.loopCache.getMicroServiceJsonRepresentationForName(this.state.policyName); + editorData = this.state.loopCache.getMicroServicePropertiesForName(this.state.policyName); + } else if (policyInstanceType === 'OPERATIONAL-POLICY') { + toscaModel = this.state.loopCache.getOperationalPolicyJsonRepresentationForName(this.state.policyName); + editorData = this.state.loopCache.getOperationalPolicyPropertiesForName(this.state.policyName); + } + + if (toscaModel == null) { + return; + } + + JSONEditor.defaults.options.theme = 'bootstrap4'; + //JSONEditor.defaults.options.iconlib = 'bootstrap2'; + JSONEditor.defaults.options.object_layout = 'grid'; + JSONEditor.defaults.options.disable_properties = true; + JSONEditor.defaults.options.disable_edit_json = false; + JSONEditor.defaults.options.disable_array_reorder = true; + JSONEditor.defaults.options.disable_array_delete_last_row = true; + JSONEditor.defaults.options.disable_array_delete_all_rows = false; + JSONEditor.defaults.options.show_errors = 'always'; + + this.setState({ + jsonEditor: new JSONEditor(document.getElementById("editor"), + { schema: toscaModel.schema, startval: editorData }) + }) + } + + render() { + return ( + + + Configuration policies + + +
+ + + + + + + + + ); + } +} \ No newline at end of file diff --git a/ui-react/src/components/loop_viewer/svg/LoopComponentConverter.js b/ui-react/src/components/loop_viewer/svg/LoopComponentConverter.js index a409d2cd..5b0dc1e0 100644 --- a/ui-react/src/components/loop_viewer/svg/LoopComponentConverter.js +++ b/ui-react/src/components/loop_viewer/svg/LoopComponentConverter.js @@ -4,15 +4,18 @@ export default class LoopComponentConverter { var componentsMap = new Map([]); if (typeof (loopCache.getMicroServicePolicies()) !== "undefined") { loopCache.getMicroServicePolicies().forEach(ms => { - componentsMap.set(ms.name, "/configurationPolicyModal/"+ms.name); + componentsMap.set(ms.name, "/policyModal/MICRO-SERVICE-POLICY/"+ms.name); }) } if (typeof (loopCache.getOperationalPolicies()) !== "undefined") { loopCache.getOperationalPolicies().forEach(op => { - componentsMap.set(op.name, "/operationalPolicyModal"); + if (op.name.includes("legacy")) { + componentsMap.set(op.name,"/operationalPolicyModal"); + } else { + componentsMap.set(op.name, "/policyModal/OPERATIONAL-POLICY/"+op.name); + } }) } - componentsMap.set("OperationalPolicy","/operationalPolicyModal"); return componentsMap; } } diff --git a/ui-react/src/components/loop_viewer/svg/LoopSvg.test.js b/ui-react/src/components/loop_viewer/svg/LoopSvg.test.js index 63518546..17f4b356 100644 --- a/ui-react/src/components/loop_viewer/svg/LoopSvg.test.js +++ b/ui-react/src/components/loop_viewer/svg/LoopSvg.test.js @@ -99,7 +99,7 @@ describe('Verify LoopSvg', () => { component.simulate('click', event); component.update(); - expect(historyMock.push.mock.calls[0]).toEqual([ '/configurationPolicyModal/TCA_h2NMX_v1_0_ResourceInstanceName1_tca']); + expect(historyMock.push.mock.calls[0]).toEqual([ '/policyModal/MICRO-SERVICE-POLICY/TCA_h2NMX_v1_0_ResourceInstanceName1_tca']); //click operational policy dummyElement.setAttribute("data-element-id","OPERATIONAL_h2NMX_v1_0_ResourceInstanceName1_tca"); @@ -108,7 +108,7 @@ describe('Verify LoopSvg', () => { component.simulate('click', event2); component.update(); - expect(historyMock.push.mock.calls[1]).toEqual([ '/operationalPolicyModal']); + expect(historyMock.push.mock.calls[1]).toEqual([ '/policyModal/OPERATIONAL-POLICY/OPERATIONAL_h2NMX_v1_0_ResourceInstanceName1_tca']); }); it('Test componentWillReceiveProps method', () => { @@ -125,9 +125,9 @@ describe('Verify LoopSvg', () => { ); - expect(component.state('componentModalMapping').size).toEqual(2); + expect(component.state('componentModalMapping').size).toEqual(1); component.setProps({loopCache: loopCache}); - expect(component.state('componentModalMapping').size).toEqual(3); + expect(component.state('componentModalMapping').size).toEqual(2); }); }); -- cgit 1.2.3-korg