Added Edit Button Functionality 20/129320/1
authorbrunomilitzer <bruno.militzer@est.tech>
Thu, 5 May 2022 13:19:39 +0000 (14:19 +0100)
committerbrunomilitzer <bruno.militzer@est.tech>
Thu, 5 May 2022 13:19:43 +0000 (14:19 +0100)
Issue-ID: POLICY-4094
Change-Id: I7e83e1c194272f274f351bc1ee34761fcc7353a4
Signed-off-by: brunomilitzer <bruno.militzer@est.tech>
gui-clamp/ui-react/src/api/ACMService.js
gui-clamp/ui-react/src/components/dialogs/ACM/CommissioningModal.js
gui-clamp/ui-react/src/components/dialogs/ACM/InstancePropertiesModal.js
gui-clamp/ui-react/src/components/dialogs/ACM/InstantiationManagementModal.js
gui-clamp/ui-react/src/components/dialogs/ACM/__snapshots__/InstancePropertiesModal.test.js.snap
gui-clamp/ui-react/src/components/dialogs/ACM/utils/InstantiationUtils.js

index 393741f..722a571 100644 (file)
@@ -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)));
index db71cd9..d120def 100644 (file)
@@ -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)
 
     }
 
index 5181b64..1c152ff 100644 (file)
@@ -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>
index 4b97748..2d87119 100644 (file)
@@ -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" } }>
index a4fea2a..4791083 100644 (file)
@@ -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
index f430b32..1e33edb 100644 (file)
@@ -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];