diff options
-rwxr-xr-x | ui-react-lib/libIndex.js | 1 | ||||
-rw-r--r-- | ui-react/src/components/dialogs/Policy/PolicyModal.js | 63 | ||||
-rw-r--r-- | ui-react/src/utils/OnapUtils.js | 65 |
3 files changed, 110 insertions, 19 deletions
diff --git a/ui-react-lib/libIndex.js b/ui-react-lib/libIndex.js index f090b614..583cc712 100755 --- a/ui-react-lib/libIndex.js +++ b/ui-react-lib/libIndex.js @@ -36,6 +36,7 @@ export { default as MenuBar } from './src/components/menu/MenuBar'; export { default as ModifyLoopModal } from './src/components/dialogs/Loop/ModifyLoopModal'; export { default as NotFound } from './src/NotFound'; export { default as OnapConstants } from './src/utils/OnapConstants'; +export { default as OnapUtils } from './src/utils/OnapUtils'; export { default as OpenLoopModal } from './src/components/dialogs/Loop/OpenLoopModal'; export { default as PerformActions } from './src/components/dialogs/PerformActions'; export { default as PolicyModal } from './src/components/dialogs/Policy/PolicyModal'; diff --git a/ui-react/src/components/dialogs/Policy/PolicyModal.js b/ui-react/src/components/dialogs/Policy/PolicyModal.js index d3b42739..6b1ebe17 100644 --- a/ui-react/src/components/dialogs/Policy/PolicyModal.js +++ b/ui-react/src/components/dialogs/Policy/PolicyModal.js @@ -34,11 +34,16 @@ import LoopCache from '../../../api/LoopCache'; import JSONEditor from '@json-editor/json-editor'; import Alert from 'react-bootstrap/Alert'; import OnapConstant from '../../../utils/OnapConstants'; +import OnapUtils from '../../../utils/OnapUtils'; const ModalStyled = styled(Modal)` background-color: transparent; ` +const DivWhiteSpaceStyled = styled.div` + white-space: pre; +` + export default class PolicyModal extends React.Component { state = { @@ -70,42 +75,49 @@ export default class PolicyModal extends React.Component { this.renderPdpGroupDropDown = this.renderPdpGroupDropDown.bind(this); this.renderOpenLoopMessage = this.renderOpenLoopMessage.bind(this); this.renderModalTitle = this.renderModalTitle.bind(this); + this.readOnly = props.readOnly !== undefined ? props.readOnly : false; } handleSave() { - var errors = this.state.jsonEditor.validate(); var editorData = this.state.jsonEditor.getValue(); + var errors = this.state.jsonEditor.validate(); + errors = errors.concat(this.customValidation(editorData, this.state.loopCache.getTemplateName())); if (errors.length !== 0) { console.error("Errors detected during policy data validation ", errors); this.setState({ - showFailAlert: true, - showMessage: "Errors detected during policy data validation " + errors - }); + showFailAlert: true, + showMessage: 'Errors detected during policy data validation:\n' + OnapUtils.jsonEditorErrorFormatter(errors) + }); return; } else { console.info("NO validation errors found in policy data"); if (this.state.policyInstanceType === OnapConstant.microServiceType) { - this.state.loopCache.updateMicroServiceProperties(this.state.policyName, editorData); - this.state.loopCache.updateMicroServicePdpGroup(this.state.policyName, this.state.chosenPdpGroup, this.state.chosenPdpSubgroup); - 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()); - }); + this.state.loopCache.updateMicroServiceProperties(this.state.policyName, editorData); + this.state.loopCache.updateMicroServicePdpGroup(this.state.policyName, this.state.chosenPdpGroup, this.state.chosenPdpSubgroup); + 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 (this.state.policyInstanceType === OnapConstant.operationalPolicyType) { this.state.loopCache.updateOperationalPolicyProperties(this.state.policyName, editorData); this.state.loopCache.updateOperationalPolicyPdpGroup(this.state.policyName, this.state.chosenPdpGroup, this.state.chosenPdpSubgroup); LoopService.setOperationalPolicyProperties(this.state.loopCache.getLoopName(), this.state.loopCache.getOperationalPolicies()).then(resp => { this.setState({ show: false }); - this.props.history.push('/'); + this.props.history.push('/'); this.props.loadLoopFunction(this.state.loopCache.getLoopName()); }); } } } + customValidation(editorData, templateName) { + // method for sub-classes to override with customized validation + return []; + } + handleClose() { this.setState({ show: false }); this.props.history.push('/'); @@ -115,6 +127,15 @@ export default class PolicyModal extends React.Component { this.renderJsonEditor(); } + componentDidUpdate() { + if (this.state.showSucAlert === true || this.state.showFailAlert === true) { + let modalElement = document.getElementById("policyModal") + if (modalElement) { + modalElement.scrollTo(0, 0); + } + } + } + createJsonEditor(toscaModel, editorData) { JSONEditor.defaults.themes.myBootstrap4 = JSONEditor.defaults.themes.bootstrap4.extend({ getTab: function(text,tabId) { @@ -313,12 +334,16 @@ export default class PolicyModal extends React.Component { <Modal.Header closeButton> {this.renderModalTitle()} </Modal.Header> - <Alert variant="success" show={this.state.showSucAlert} onClose={this.disableAlert} dismissible> - {this.state.showMessage} - </Alert> - <Alert variant="danger" show={this.state.showFailAlert} onClose={this.disableAlert} dismissible> - {this.state.showMessage} - </Alert> + <Alert variant="success" show={this.state.showSucAlert} onClose={this.disableAlert} dismissible> + <DivWhiteSpaceStyled> + {this.state.showMessage} + </DivWhiteSpaceStyled> + </Alert> + <Alert variant="danger" show={this.state.showFailAlert} onClose={this.disableAlert} dismissible> + <DivWhiteSpaceStyled> + {this.state.showMessage} + </DivWhiteSpaceStyled> + </Alert> <Modal.Body> {this.renderOpenLoopMessage()} <div id="editor" /> @@ -330,4 +355,4 @@ export default class PolicyModal extends React.Component { </ModalStyled> ); } -}
\ No newline at end of file +} diff --git a/ui-react/src/utils/OnapUtils.js b/ui-react/src/utils/OnapUtils.js new file mode 100644 index 00000000..316a0d65 --- /dev/null +++ b/ui-react/src/utils/OnapUtils.js @@ -0,0 +1,65 @@ +/*- + * ============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============================================ + * =================================================================== + * + */ + +export default class OnapUtils { + + constructor() { + this.clickBlocked = false; + } + + static jsonEditorErrorFormatter(errors) { + + let messages = []; + let messagesOutputString = null; + + // errors is an array of JSON Editor "error" objects, where each + // object looks like this: + + // { + // message: "Please populate the required property "Threshold"" + // path: "root.signatures.0" + // property: "required" + // } + + // In this function we concatenate all the messages, removing any duplicates, + // and adding a newline between each message. The result returned is a single + // string that can be displayed to the user in an alert message + + if (!Array.isArray(errors)) { + console.error('jsoneEditorErrorFormatter was passed a non-array argument'); + } else { + for (let ii=0; ii < errors.length; ++ii) { + if (!messages.includes(errors[ii].message)) { + messages.push(errors[ii].message); + if (messagesOutputString) { + messagesOutputString += '\n' + errors[ii].message; + } else { + messagesOutputString = errors[ii].message; + } + } + } + } + + return messagesOutputString; + } +} |