Просмотр исходного кода

- Adds Endpoint Validation component and functionality
- Adjusts connection view to design

George Vrancianu 9 лет назад
Родитель
Сommit
42c441e83a

+ 3 - 0
src/actions/ConnectionsActions/ConnectionsActions.js

@@ -139,6 +139,9 @@ ConnectionsActions.validateConnection.listen((endpoint, callback) => {
     method: "POST",
     data: { "validate-connection": null }
   }).then(response => {
+      if (callback) {
+        callback(response)
+      }
       ConnectionsActions.validateConnection.completed(response)
     }, ConnectionsActions.validateConnection.failed)
     .catch(ConnectionsActions.validateConnection.failed);

+ 44 - 7
src/components/CloudConnectionsView/CloudConnectionsView.js

@@ -21,12 +21,11 @@ import s from './CloudConnectionsView.scss';
 import Header from '../Header';
 import ConnectionsActions from '../../actions/ConnectionsActions';
 import Location from '../../core/Location';
-import Link from '../Link';
-import Dropdown from '../NewDropdown';
 import LoadingIcon from '../LoadingIcon';
 import Modal from 'react-modal';
 import AddCloudConnection from '../AddCloudConnection';
 import ConfirmationDialog from '../ConfirmationDialog'
+import ValidateEndpoint from '../ValidateEndpoint';
 
 
 class CloudConnectionsView extends Component {
@@ -59,7 +58,8 @@ class CloudConnectionsView extends Component {
         onConfirm: null,
         onCancel: null
       },
-      showModal: false
+      showModal: false,
+      showValidationModal: false
     }
   }
 
@@ -104,7 +104,14 @@ class CloudConnectionsView extends Component {
         }
       }
     })
+  }
+
+  validateConnection() {
+    this.setState({ showValidationModal: true })
+  }
 
+  closeValidationModal() {
+    this.setState({ showValidationModal: false })
   }
 
   closeModal() {
@@ -132,6 +139,20 @@ class CloudConnectionsView extends Component {
       }
     }
 
+    let validationModalStyle = {
+      content: {
+        padding: "0px",
+        borderRadius: "4px",
+        bottom: "auto",
+        width: "370px",
+        height: "250px",
+        left: "50%",
+        top: "50%",
+        marginTop: "-185px",
+        marginLeft: "-125px"
+      }
+    }
+
     if (item) {
       return (
         <div className={s.root}>
@@ -155,10 +176,16 @@ class CloudConnectionsView extends Component {
               <br />
 
               {React.cloneElement(this.props.children, { connection: item })}
-
-              <button onClick={(e) => this.showEditConnectionModal(e)} className="gray">Edit Connection</button>
-              <br /><br />
-              <button onClick={(e) => this.deleteConnection(e)} className="wire">Delete</button>
+              <div className={s.buttons}>
+                <div className={s.leftSide}>
+                  <button onClick={(e) => this.showEditConnectionModal(e)} className="gray">Edit Endpoint</button>
+                  <br />
+                  <button onClick={(e) => this.validateConnection(e)}>Validate Endpoint</button>
+                </div>
+                <div className={s.rightSide}>
+                  <button onClick={(e) => this.deleteConnection(e)} className="wire" style={{float: "right"}}>Delete</button>
+                </div>
+              </div>
             </div>
           </div>
           <Modal
@@ -172,6 +199,16 @@ class CloudConnectionsView extends Component {
               connection={item}
             />
           </Modal>
+          <Modal
+            isOpen={this.state.showValidationModal}
+            contentLabel="Validate Endpoint"
+            style={validationModalStyle}
+          >
+            <ValidateEndpoint
+              closeHandle={(e) => this.closeValidationModal(e)}
+              endpoint={item}
+            />
+          </Modal>
           <ConfirmationDialog
             visible={this.state.confirmationDialog.visible}
             message={this.state.confirmationDialog.message}

+ 15 - 0
src/components/CloudConnectionsView/CloudConnectionsView.scss

@@ -110,4 +110,19 @@ $connectionHeaderBg: #D9DCE3;
   float: left;
   width: 800px;
   padding-bottom: 32px;
+  .connectionTypeImg {
+    margin-bottom: 16px;
+  }
+}
+
+.buttons {
+  button {
+    margin-bottom: 16px;
+  }
+  .leftSide {
+    float: left;
+  }
+  .rightSide {
+    float: right;
+  }
 }

+ 1 - 1
src/components/ConnectionsList/ConnectionsList.js

@@ -248,7 +248,7 @@ class ConnectionsList extends Reflux.Component {
             <div className={s.top}>
               <h1>{title}</h1>
               <div className={s.topActions}>
-                <button onClick={(e) => this.showNewConnectionModal(e)}>New Connection</button>
+                <button onClick={(e) => this.showNewConnectionModal(e)}>New</button>
                 <UserIcon />
                 <NotificationIcon />
               </div>

+ 91 - 0
src/components/ValidateEndpoint/ValidateEndpoint.js

@@ -0,0 +1,91 @@
+/*
+Copyright (C) 2017  Cloudbase Solutions SRL
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+import React, { Component, PropTypes } from 'react';
+import s from './ValidateEndpoint.scss';
+import withStyles from 'isomorphic-style-loader/lib/withStyles';
+import LoadingIcon from '../LoadingIcon';
+import ConnectionsActions from '../../actions/ConnectionsActions';
+
+
+class ValidateEndpoint extends Component {
+
+  static propTypes = {
+    endpoint: PropTypes.object,
+    closeHandle: PropTypes.func
+  }
+
+  constructor(props) {
+    super(props)
+    this.state = {
+      status: 0,
+      message: null
+    }
+  }
+
+  close() {
+    this.props.closeHandle()
+  }
+
+  validate() {
+    this.setState({
+      status: 0,
+      message: null
+    })
+    ConnectionsActions.validateConnection(this.props.endpoint, (response) => {
+      this.setState({
+        status: response.data["validate-connection"].valid ? 1 : -1,
+        message: response.data["validate-connection"].valid ?
+          "Endpoint is valid" : response.data["validate-connection"].message
+      })
+    })
+  }
+
+  componentDidMount() {
+    this.validate()
+  }
+
+  render() {
+    let message, buttons
+    switch (this.state.status) {
+      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>
+        </div>
+        break;
+      case 1:
+        buttons = <div className={s.singleBtn}>
+          <button onClick={(e) => this.close(e)}>Dismiss</button>
+        </div>
+        break;
+      default:
+        buttons = <div className={s.singleBtn}>
+          <button className="gray" onClick={(e) => this.close(e)}>Cancel</button>
+        </div>
+    }
+    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> }
+      </div>
+      {buttons}
+    </div>
+  }
+
+}
+
+export default withStyles(ValidateEndpoint, s);

+ 56 - 0
src/components/ValidateEndpoint/ValidateEndpoint.scss

@@ -0,0 +1,56 @@
+/*
+Copyright (C) 2017  Cloudbase Solutions SRL
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+@import '../variables.scss';
+
+
+.root {
+  padding: 16px;
+  .message {
+    font-weight: $weight-light;
+    font-size: 24px;
+    color: $gray-darker;
+    text-align: center;
+    height: 85px;
+    padding-top: 70px;
+    line-height: 40px;
+  }
+  .singleBtn {
+    text-align: center;
+    margin-top: 32px;
+    button {
+      margin: 0 auto;
+    }
+  }
+  .dualBtn {
+    margin-top: 32px;
+    button {
+      &:first-child {
+        float: left;
+      }
+      &:nth-child(2) {
+        float: right;
+      }
+    }
+  }
+  .hidden {
+    opacity: 0;
+  }
+  .container {
+    height: 155px;
+  }
+}

+ 6 - 0
src/components/ValidateEndpoint/package.json

@@ -0,0 +1,6 @@
+{
+  "name": "ValidateEndpoint",
+  "version": "0.0.0",
+  "private": true,
+  "main": "./ValidateEndpoint.js"
+}