Răsfoiți Sursa

- Adds validation after an endpoint is added or edited
- Adds verbose to failed API calls

George Vrancianu 8 ani în urmă
părinte
comite
7c777de1cb

+ 6 - 4
src/actions/ConnectionsActions/ConnectionsActions.js

@@ -70,7 +70,7 @@ ConnectionsActions.loadProviders.listen(() => {
     .catch(ConnectionsActions.loadProviders.failed);
 })
 
-ConnectionsActions.newEndpoint.listen((data) => {
+ConnectionsActions.newEndpoint.listen((data, callback = null) => {
   if (useSecret) {
     let barbicanPayload = {
       payload: JSON.stringify(data.connection_info),
@@ -85,7 +85,7 @@ ConnectionsActions.newEndpoint.listen((data) => {
       method: "POST",
       data: barbicanPayload
     }).then((response) => {
-      ConnectionsActions.newEndpoint.success(response, data)
+      ConnectionsActions.newEndpoint.success(response, data, callback)
     }, ConnectionsActions.newEndpoint.failed)
       .catch(ConnectionsActions.newEndpoint.failed);
   } else {
@@ -93,7 +93,7 @@ ConnectionsActions.newEndpoint.listen((data) => {
   }
 });
 
-ConnectionsActions.saveEndpoint.listen((data, secretRef) => {
+ConnectionsActions.saveEndpoint.listen((data, secretRef, callback) => {
   let projectId = Reflux.GlobalState.userStore.currentUser.project.id
   let payload = null
   if (useSecret) {
@@ -115,7 +115,9 @@ ConnectionsActions.saveEndpoint.listen((data, secretRef) => {
     url: `${servicesUrl.coriolis}/${projectId}/endpoints`,
     method: "POST",
     data: payload
-  }).then(ConnectionsActions.saveEndpoint.success, ConnectionsActions.saveEndpoint.failed)
+  }).then((response) => {
+    ConnectionsActions.saveEndpoint.success(response, callback)
+  }, ConnectionsActions.saveEndpoint.failed)
     .catch(ConnectionsActions.saveEndpoint.failed);
 })
 

+ 31 - 11
src/components/AddCloudConnection/AddCloudConnection.js

@@ -24,6 +24,7 @@ import ConnectionsActions from '../../actions/ConnectionsActions';
 import NotificationActions from '../../actions/NotificationActions';
 import Dropdown from '../NewDropdown';
 import LoadingIcon from "../LoadingIcon/LoadingIcon";
+import ValidateEndpoint from '../ValidateEndpoint';
 
 const title = 'Add Cloud Endpoint';
 
@@ -45,11 +46,13 @@ class AddCloudConnection extends Reflux.Component {
     this.store = ConnectionsStore
 
     this.state = {
+      type: props.type,
+      connection: props.connection,
       connectionName: "",
       description: null,
       currentCloud: this.props.cloud,
       currentCloudData: null,
-      connected: false,
+      validateEndpoint: false,
       isConnecting: false,
       requiredFields: [],
       cloudFormsSubmitted: false
@@ -62,17 +65,17 @@ class AddCloudConnection extends Reflux.Component {
   }
 
   componentDidMount() {
-    if (this.props.connection) {
+    if (this.state.connection) {
       this.state.allClouds.forEach(item => {
-        if (item.name === this.props.connection.type) {
-          let credentials = this.props.connection.credentials
+        if (item.name === this.state.connection.type) {
+          let credentials = this.state.connection.credentials
           for (let i in credentials) {
             credentials[i] = credentials[i] + ""
           }
           this.setState({
             currentCloudData: credentials,
-            connectionName: this.props.connection.name,
-            description: this.props.connection.description
+            connectionName: this.state.connection.name,
+            description: this.state.connection.description
           }, () => {
             this.chooseCloud(item)
           })
@@ -112,16 +115,22 @@ class AddCloudConnection extends Reflux.Component {
           credentials[key] = credentials[key].value
         }
       }
-      if (this.props.type == "new") {
+      if (this.state.type == "new") {
         ConnectionsActions.newEndpoint({
           name: this.state.connectionName,
           description: this.state.description,
           type: this.state.currentCloud.name,
           connection_info: credentials
+        }, (response) => {
+          this.setState({
+            validateEndpoint: response.data.endpoint,
+            type: "edit",
+            connection: response.data.endpoint
+          })
         })
         this.props.addHandle(this.state.connectionName);
       } else {
-        ConnectionsActions.editEndpoint(this.props.connection, {
+        ConnectionsActions.editEndpoint(this.state.connection, {
           name: this.state.connectionName,
           description: this.state.description,
           connection_info: credentials
@@ -163,6 +172,10 @@ class AddCloudConnection extends Reflux.Component {
     }, this.setDefaultValues)
   }
 
+  backToEdit() {
+    this.setState({ validateEndpoint: null })
+  }
+
   handleBack() {
     this.setState({
       currentCloudData: null,
@@ -366,7 +379,7 @@ class AddCloudConnection extends Reflux.Component {
             {fields}
           </div>
           <div className={s.buttons}>
-            {this.props.type == "new" ? (
+            {this.state.type == "new" ? (
               <button className={s.leftBtn + " gray"} onClick={(e) => this.handleBack(e)}>Back</button>
             ) : (
               <button className={s.leftBtn + " gray"} onClick={(e) => this.handleCancel(e)}>Cancel</button>
@@ -411,8 +424,15 @@ class AddCloudConnection extends Reflux.Component {
 
   render() {
     let modalBody
-
-    if (this.state.currentCloud == null) {
+    if (this.state.validateEndpoint) {
+      modalBody = (
+        <ValidateEndpoint
+          closeHandle={this.props.closeHandle}
+          endpoint={this.state.validateEndpoint}
+          backHandle={(e) => this.backToEdit(e)}
+        />
+      )
+    } else if (this.state.currentCloud == null) {
       if (this.state.allClouds) {
         modalBody = this.renderCloudList()
       } else {

+ 15 - 5
src/components/CloudConnectionsView/CloudConnectionsView.js

@@ -124,12 +124,22 @@ class CloudConnectionsView extends Component {
     this.setState({ connection: connection })
   }
 
+  addItem() {
+    this.validateConnection()
+
+    this.setState({ showModal: false })
+    let connection = this.props.connections.filter(item => item.id === this.props.connectionId)[0]
+
+    this.setState({ connection: connection })
+  }
+
   updateItem(itemAttrs) {
     let endpoint = this.state.connection
     for (let i in itemAttrs) {
       endpoint[i] = itemAttrs[i]
     }
     this.setState({ connection: endpoint })
+    this.validateConnection()
   }
 
   goBack() {
@@ -176,12 +186,12 @@ class CloudConnectionsView extends Component {
         borderRadius: "4px",
         border: "none",
         bottom: "auto",
-        width: "370px",
-        height: "250px",
+        width: "400px",
+        height: "300px",
         left: "50%",
         top: "50%",
-        marginTop: "-185px",
-        marginLeft: "-125px"
+        marginTop: "-200px",
+        marginLeft: "-150px"
       }
     }
 
@@ -229,7 +239,7 @@ class CloudConnectionsView extends Component {
           >
             <AddCloudConnection
               closeHandle={(e) => this.closeModal(e)}
-              addHandle={(e) => this.closeModal(e)}
+              addHandle={(e) => this.addItem(e)}
               updateHandle={(e) => this.updateItem(e)}
               connection={item}
               type="edit"

+ 5 - 1
src/components/EndpointList/EndpointList.js

@@ -101,6 +101,10 @@ class EndpointList extends Reflux.Component {
     this.setState({ showModal: false })
   }
 
+  addHandle() {
+
+  }
+
   renderItem(item) {
     let createdAt = Helper.getTimeObject(item.created_at)
     return (
@@ -184,7 +188,7 @@ class EndpointList extends Reflux.Component {
         >
           <AddCloudConnection
             closeHandle={(e) => this.closeModal(e)}
-            addHandle={(e) => this.closeModal(e)}
+            addHandle={(e) => this.addHandle(e)}
           />
         </Modal>
       </div>

+ 6 - 3
src/components/ValidateEndpoint/ValidateEndpoint.js

@@ -26,7 +26,8 @@ class ValidateEndpoint extends Component {
 
   static propTypes = {
     endpoint: PropTypes.object,
-    closeHandle: PropTypes.func
+    closeHandle: PropTypes.func,
+    backHandle: PropTypes.func
   }
 
   constructor(props) {
@@ -65,7 +66,9 @@ class ValidateEndpoint extends Component {
       case -1:
         buttons = (<div className={s.dualBtn}>
           <button className="gray" onClick={(e) => this.close(e)}>Cancel</button>
-          <button onClick={(e) => this.validate(e)}>Retry</button>
+          { this.props.backHandle ?
+            (<button onClick={(e) => this.props.backHandle(e)}>Edit</button>) :
+            (<button onClick={(e) => this.validate(e)}>Retry</button>)}
         </div>)
         break;
       case 1:
@@ -80,7 +83,7 @@ class ValidateEndpoint extends Component {
     }
     return (<div className={s.root}>
       <div className={s.container + (this.state.status != 0 ? s.hidden : "")}>
-        { this.state.status == 0 ? <LoadingIcon /> : <div className={s.message}>{this.state.message}</div> }
+        { this.state.status == 0 ? <LoadingIcon text="Validating endpoint.." /> : <div className={s.message}>{this.state.message}</div> }
       </div>
       {buttons}
     </div>)

+ 2 - 2
src/components/ValidateEndpoint/ValidateEndpoint.scss

@@ -25,7 +25,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
     font-size: 24px;
     color: $gray-darker;
     text-align: center;
-    height: 85px;
+    height: 128px;
     padding-top: 70px;
     line-height: 40px;
   }
@@ -51,6 +51,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
     opacity: 0;
   }
   .container {
-    height: 155px;
+    height: 196px;
   }
 }

+ 1 - 1
src/routes.js

@@ -74,7 +74,7 @@ const router = new Router(on => {
   on('/migration/schedule/:migrationId/', async (params) =>
     <MigrationView migrationId={params.params.migrationId} type="schedule"><ReplicaSchedule /></MigrationView>
   )
-  // TODO: IMPORTANT Separate views migration/replica
+
   on('/replicas', async () => <WithSidebar route="/replicas"><ReplicaList /></WithSidebar>)
 
   on('/replicas/new', async () => <MigrationWizard wizard_type="replica" />)

+ 8 - 3
src/stores/ConnectionsStore/ConnectionsStore.js

@@ -176,9 +176,9 @@ class ConnectionsStore extends Reflux.Store
     }, this)
   }
 
-  onNewEndpointSuccess(response, data)
+  onNewEndpointSuccess(response, data, callback = null)
   {
-    ConnectionsActions.saveEndpoint(data, response.data.secret_ref)
+    ConnectionsActions.saveEndpoint(data, response.data.secret_ref, callback)
   }
 
   onEditEndpointSuccess(response, connection, data, callback)
@@ -187,11 +187,16 @@ class ConnectionsStore extends Reflux.Store
     ConnectionsActions.saveEditEndpoint(connection, data, callback)
   }
 
-  onSaveEndpointSuccess(response) {
+  onSaveEndpointSuccess(response, callback = null) {
     let connections = this.state.connections
     connections.push(response.data.endpoint)
+
     this.setState({connections: connections})
     ConnectionsActions.assignConnectionProvider()
+
+    if (typeof callback === "function") {
+      callback(response)
+    }
   }
 
   onSaveEditEndpointSuccess(response) {

+ 32 - 0
src/stores/NotificationsStore/NotificationsStore.js

@@ -209,6 +209,30 @@ class NotificationsStore extends Reflux.Store
     this.setState({ notifications: notifications })
   }
 
+  onLoadProvidersFailed() {
+    let notifications = [{
+      message: "Could not load providers.",
+      type: 'error'
+    }]
+    this.setState({ notifications: notifications })
+  }
+
+  onLoadNetworksFailed() {
+    let notifications = [{
+      message: "Could not load networks for target destination.",
+      type: 'error'
+    }]
+    this.setState({ notifications: notifications })
+  }
+
+  onLoadInstanceDetailFailed() {
+    let notifications = [{
+      message: "Failed to load instance details.",
+      type: 'error'
+    }]
+    this.setState({ notifications: notifications })
+  }
+
   onNewEndpoint() {
     let notifications = [{
       message: "Saving endpoint...",
@@ -249,6 +273,14 @@ class NotificationsStore extends Reflux.Store
     this.setState({ notifications: notifications })
   }
 
+  onValidateConnection() {
+    let notifications = [{
+      message: "Validating endpoint..",
+      type: 'info'
+    }]
+    this.setState({ notifications: notifications })
+  }
+
   onNotify(message, type = "info", title = null) {
     this.setState({
       notifications: [