diff options
author | 2022-05-05 14:19:39 +0100 | |
---|---|---|
committer | 2022-05-05 14:19:43 +0100 | |
commit | 777d1457e6f24ef187612d0150a5415002550cee (patch) | |
tree | c807c972826576726f0c24a8bdd2850977d3b319 /gui-clamp/ui-react/src | |
parent | 2fc78d7979c470c670e4caa154e3ec40fd47c73c (diff) |
Added Edit Button Functionality
Issue-ID: POLICY-4094
Change-Id: I7e83e1c194272f274f351bc1ee34761fcc7353a4
Signed-off-by: brunomilitzer <bruno.militzer@est.tech>
Diffstat (limited to 'gui-clamp/ui-react/src')
6 files changed, 145 insertions, 36 deletions
diff --git a/gui-clamp/ui-react/src/api/ACMService.js b/gui-clamp/ui-react/src/api/ACMService.js index 393741f..722a571 100644 --- a/gui-clamp/ui-react/src/api/ACMService.js +++ b/gui-clamp/ui-react/src/api/ACMService.js @@ -42,6 +42,25 @@ export default class ACMService { return response } + static async updateInstanceProperties(instanceName, version, instancePropertiesTemplate) { + const params = { + name: instanceName, + version: version + } + + const response = await fetch(window.location.pathname + + 'restservices/clds/v2/acm/putToscaInstanceProperties?' + (new URLSearchParams(params)), { + method: 'PUT', + headers: { + "Content-Type": "application/json" + }, + credentials: 'same-origin', + body: JSON.stringify(instancePropertiesTemplate), + }); + + return response + } + static async deleteInstantiation(name, version) { const params = { name: name, @@ -86,11 +105,17 @@ export default class ACMService { return response } - static async getToscaTemplate(name, version) { - const params = { - name: name, - version: version - } + static async getToscaTemplate(name, version, instanceName) { + const params = instanceName != null ? + { + name: name, + version: version, + instanceName: instanceName + } : + { + name: name, + version: version + } const response = await fetch(window.location.pathname + 'restservices/clds/v2/acm/getToscaTemplate' + '?' + (new URLSearchParams(params))); @@ -132,12 +157,19 @@ export default class ACMService { return data; } - static async getCommonOrInstanceProperties(name, version, isCommon) { - const params = { - name: name, - version: version, - common: isCommon - } + static async getCommonOrInstanceProperties(name, version, instanceName, isCommon) { + const params = instanceName != null ? + { + name: name, + version: version, + instanceName: instanceName, + common: isCommon + } : + { + name: name, + version: version, + common: isCommon + } const response = await fetch(window.location.pathname + 'restservices/clds/v2/acm/getCommonOrInstanceProperties' + '?' + (new URLSearchParams(params))); diff --git a/gui-clamp/ui-react/src/components/dialogs/ACM/CommissioningModal.js b/gui-clamp/ui-react/src/components/dialogs/ACM/CommissioningModal.js index db71cd9..d120def 100644 --- a/gui-clamp/ui-react/src/components/dialogs/ACM/CommissioningModal.js +++ b/gui-clamp/ui-react/src/components/dialogs/ACM/CommissioningModal.js @@ -48,9 +48,7 @@ const AlertStyled = styled(Alert)` const CommissioningModal = (props) => { const [fullToscaTemplate, setFullToscaTemplate] = useState({}); - const [toscaInitialValues, setToscaInitialValues] = useState({}); const [commonProperties, setCommonProperties] = useState({}) - const [toscaJsonSchema, setToscaJsonSchema] = useState({}); const [jsonEditor, setJsonEditor] = useState(null); const [show, setShow] = useState(true); const [alertMessages, setAlertMessages] = useState(); @@ -60,14 +58,13 @@ const CommissioningModal = (props) => { const version = '1.0.0'; useEffect(async () => { - const toscaTemplateResponse = await ACMService.getToscaTemplate(name, version) + const toscaTemplateResponse = await ACMService.getToscaTemplate(name, version, null) .catch(error => error.message); - const toscaCommonProperties = await ACMService.getCommonOrInstanceProperties(name, version, true) + const toscaCommonProperties = await ACMService.getCommonOrInstanceProperties(name, version, null, true) .catch(error => error.message); if (!toscaCommonProperties.ok) { const errorResponse = await toscaCommonProperties.json() - console.log(errorResponse) setCommonProperties(errorResponse) setCommonPropertiesResponseOk(false); } @@ -82,9 +79,7 @@ const CommissioningModal = (props) => { if (toscaTemplateResponse.ok && toscaCommonProperties.ok) { const renderedEditorObjects = CommissioningUtils.renderJsonEditor(toscaTemplateResponse, toscaCommonProperties) setFullToscaTemplate((await renderedEditorObjects).fullTemplate) - setToscaJsonSchema((await renderedEditorObjects).propertySchema) setJsonEditor((await renderedEditorObjects).editorTemp) - setToscaInitialValues((await renderedEditorObjects).toscaInitialValues) } diff --git a/gui-clamp/ui-react/src/components/dialogs/ACM/InstancePropertiesModal.js b/gui-clamp/ui-react/src/components/dialogs/ACM/InstancePropertiesModal.js index 5181b64..1c152ff 100644 --- a/gui-clamp/ui-react/src/components/dialogs/ACM/InstancePropertiesModal.js +++ b/gui-clamp/ui-react/src/components/dialogs/ACM/InstancePropertiesModal.js @@ -56,24 +56,49 @@ function Fragment(props) { return null; } -Fragment.propTypes = { children: PropTypes.node }; +const specialCharacter = /[ `!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?~]/; + +Fragment.propTypes = {children: PropTypes.node}; const InstancePropertiesModal = (props) => { const [show, setShow] = useState(true); const [toscaFullTemplate, setToscaFullTemplate] = useState({}); const [jsonEditor, setJsonEditor] = useState(null); const [alertMessage, setAlertMessage] = useState(null); + const [clearButton, setClearButton] = useState(null); const [instancePropertiesGlobal, setInstancePropertiesGlobal] = useState({}); const [serviceTemplateResponseOk, setServiceTemplateResponseOk] = useState(true); const [instancePropertiesResponseOk, setInstancePropertiesResponseOk] = useState(true); const [instanceName, setInstanceName] = useState(''); + const [instanceVersion, setInstanceVersion] = useState(''); + const [oldInstanceName, setOldInstanceName] = useState(''); + const [tempInstanceName, setTempInstanceName] = useState(''); + const [validated, setValidated] = useState(false); + const [editMode, setEditMode] = useState(false); useEffect(async () => { - const toscaTemplateResponse = await ACMService.getToscaTemplate(templateName, templateVersion) + let isEditMode = false; + + if (props.location.instantiationName !== undefined) { + isEditMode = true; + setEditMode(true); + setInstanceName(props.location.instantiationName); + setInstanceVersion(props.location.instantiationVersion); + } + + const instantiationName = isEditMode ? props.location.instantiationName : null; + console.log(instantiationName); + + const toscaTemplateResponse = await ACMService.getToscaTemplate(templateName, templateVersion, instantiationName) .catch(error => error.message); - const toscaInstanceProperties = await ACMService.getCommonOrInstanceProperties(templateName, templateVersion, false) + const toscaInstanceProperties = await ACMService.getCommonOrInstanceProperties(templateName, templateVersion, instantiationName, false) .catch(error => error.message); + if (toscaInstanceProperties == null || toscaTemplateResponse == null) { + await warningAlert('Tosca service template is empty') + return; + } + if (!toscaInstanceProperties.ok) { const errorResponse = await toscaInstanceProperties.json(); console.log(errorResponse); @@ -96,6 +121,30 @@ const InstancePropertiesModal = (props) => { }, []); + useEffect(async () => { + + await validateInstanceName(); + + }, [instanceName]) + + const validateInstanceName = async () => { + console.log('validateInstanceName called'); + + if (specialCharacter.test(instanceName)) { + await warningAlert('Instance name cannot contain special characters'); + } else if (alertMessage) { + clearWarning(); + } + + if (instanceName.length > 2 && !specialCharacter.test(instanceName)) { + console.log('validated'); + setOldInstanceName(tempInstanceName); + setValidated(true); + } else { + setValidated(false); + } + } + const handleClose = () => { console.log('handleClose called'); setShow(false); @@ -105,7 +154,11 @@ const InstancePropertiesModal = (props) => { const handleInstanceName = (event) => { console.log('handleInstanceName called'); + setTempInstanceName(instanceName); setInstanceName(event.target.value); + + validateInstanceName().then(() => { + }); } const handleSave = async () => { @@ -118,8 +171,15 @@ const InstancePropertiesModal = (props) => { setToscaFullTemplate(InstantiationUtils.updateTemplate(instanceName, jsonEditor.getValue(), toscaFullTemplate)); } - const response = await ACMService.createInstanceProperties(toscaFullTemplate) - .catch(error => error.message); + let response = null; + + if (editMode) { + response = await ACMService.updateInstanceProperties(oldInstanceName, instanceVersion, toscaFullTemplate) + .catch(error => error.message); + } else { + response = await ACMService.createInstanceProperties(toscaFullTemplate) + .catch(error => error.message); + } if (response.ok) { successAlert(); @@ -127,15 +187,16 @@ const InstancePropertiesModal = (props) => { await errorAlert(response); } } else { - await warningAlert(); + await warningAlert('Instance name cannot be empty'); } } - const warningAlert = async () => { + const warningAlert = async (message) => { console.log("warningAlert called"); + setAlertMessage(<Alert variant="warning"> <Alert.Heading>Instantiation Properties Warning</Alert.Heading> - <p>Instance name cannot be empty</p> + <p>{message}</p> <hr/> </Alert>); } @@ -160,6 +221,17 @@ const InstancePropertiesModal = (props) => { </Alert>); } + const clearWarning = () => { + console.log("clearWarning called"); + + if (specialCharacter.test(instanceName)) { + return; + } + + setClearButton(null); + setAlertMessage(null); + } + return ( <ModalStyled size="xl" show={ show } @@ -167,7 +239,7 @@ const InstancePropertiesModal = (props) => { backdrop="static" keyboard={ false }> <Modal.Header closeButton> - <Modal.Title>Create Tosca Instance Properties</Modal.Title> + <Modal.Title>{ editMode ? 'Edit' : 'Create' } Tosca Instance Properties</Modal.Title> </Modal.Header> <div style={ { padding: '5px 5px 0 5px' } }> <Modal.Body> @@ -189,7 +261,8 @@ const InstancePropertiesModal = (props) => { </DivWhiteSpaceStyled> </div> <Modal.Footer> - <Button variant="primary" onClick={ handleSave }>Save</Button> + { clearButton } + <Button variant="primary" disabled={ !validated } onClick={ handleSave } style={validated ? {} : { cursor: "not-allowed" }}>Save</Button> <Button variant="secondary" onClick={ handleClose }>Close</Button> </Modal.Footer> </ModalStyled> diff --git a/gui-clamp/ui-react/src/components/dialogs/ACM/InstantiationManagementModal.js b/gui-clamp/ui-react/src/components/dialogs/ACM/InstantiationManagementModal.js index 4b97748..2d87119 100644 --- a/gui-clamp/ui-react/src/components/dialogs/ACM/InstantiationManagementModal.js +++ b/gui-clamp/ui-react/src/components/dialogs/ACM/InstantiationManagementModal.js @@ -172,10 +172,12 @@ const InstantiationManagementModal = (props) => { <td style={ { textAlign: "center" } }> <Link to={ { pathname: "editACMInstanceProperties", - } } state={ instantiation.name }> - <Button variant="outline-success" type="null" - disabled={ true } - style={ { cursor: "not-allowed" } }>Edit</Button> + instantiationName: instantiation.name, + instantiationVersion: instantiation.version + } }> + <Button variant={ instantiation.disabled ? "outline-success" : "success" } type="null" + disabled={ instantiation.disableEdit } + style={ instantiation.disableEdit ? { cursor: "not-allowed" } : {} }>Edit</Button> </Link> </td> <td style={ { textAlign: "center" } }> diff --git a/gui-clamp/ui-react/src/components/dialogs/ACM/__snapshots__/InstancePropertiesModal.test.js.snap b/gui-clamp/ui-react/src/components/dialogs/ACM/__snapshots__/InstancePropertiesModal.test.js.snap index a4fea2a..4791083 100644 --- a/gui-clamp/ui-react/src/components/dialogs/ACM/__snapshots__/InstancePropertiesModal.test.js.snap +++ b/gui-clamp/ui-react/src/components/dialogs/ACM/__snapshots__/InstancePropertiesModal.test.js.snap @@ -13,7 +13,8 @@ exports[`Verify InstancePropertiesModal renders correctly 1`] = ` closeLabel="Close" > <ModalTitle> - Create Tosca Instance Properties + Create + Tosca Instance Properties </ModalTitle> </ModalHeader> <div @@ -80,8 +81,13 @@ exports[`Verify InstancePropertiesModal renders correctly 1`] = ` <ModalFooter> <Button active={false} - disabled={false} + disabled={true} onClick={[Function]} + style={ + Object { + "cursor": "not-allowed", + } + } variant="primary" > Save diff --git a/gui-clamp/ui-react/src/components/dialogs/ACM/utils/InstantiationUtils.js b/gui-clamp/ui-react/src/components/dialogs/ACM/utils/InstantiationUtils.js index f430b32..1e33edb 100644 --- a/gui-clamp/ui-react/src/components/dialogs/ACM/utils/InstantiationUtils.js +++ b/gui-clamp/ui-react/src/components/dialogs/ACM/utils/InstantiationUtils.js @@ -34,7 +34,8 @@ const InstantiationUtils = { version: instance['version'], orderedState: instance['orderedState'], currentState: instance['state'], - disableDelete: instance['state'] !== 'UNINITIALISED' + disableDelete: instance['state'] !== 'UNINITIALISED', + disableEdit: instance['state'] !== 'UNINITIALISED' } parsedAcmList.push(acmObj); @@ -90,7 +91,7 @@ const InstantiationUtils = { const propValues = {}; filteredTemplateObj[key] = propertiesObj; - const jsonNodeSchemaKey = fullTemplate.topology_template.node_templates[key] + const jsonNodeSchemaKey = fullTemplate.topology_template.node_templates[key]; Object.entries(propertiesObj.properties).forEach(([pKey, pValue]) => { propValues[pKey] = jsonNodeSchemaKey.properties[pKey]; |