Merge remote-tracking branch 'origin/v1.0' 52/652/1
authorKIRAN KASHALKAR <kiran.kashalkar@riftio.com>
Thu, 10 Nov 2016 05:05:51 +0000 (00:05 -0500)
committerKIRAN KASHALKAR <kiran.kashalkar@riftio.com>
Thu, 10 Nov 2016 05:06:15 +0000 (00:06 -0500)
Signed-off-by: KIRAN KASHALKAR <kiran.kashalkar@riftio.com>
14 files changed:
skyquake/framework/widgets/skyquake_container/skyquakeContainerStore.js
skyquake/plugins/accounts/src/account/account.jsx
skyquake/plugins/composer/src/src/components/EditDescriptorModelProperties.js
skyquake/plugins/composer/src/src/libraries/model/DescriptorModelFields.js
skyquake/plugins/composer/src/src/libraries/model/DescriptorModelMetaFactory.js
skyquake/plugins/composer/src/src/libraries/model/DescriptorModelSerializer.js
skyquake/plugins/composer/src/src/libraries/utils.js
skyquake/plugins/launchpad/api/launchpad.js
skyquake/plugins/launchpad/src/instantiate/instantiateStore.js
skyquake/plugins/launchpad/src/launchpad_card/launchpadHeader.jsx
skyquake/plugins/launchpad/src/launchpad_card/launchpad_card.scss
skyquake/plugins/launchpad/src/recordViewer/recordDetails.jsx
skyquake/plugins/launchpad/src/ssh_keys/sshKeyCard.scss
skyquake/plugins/launchpad/src/ssh_keys/sshKeys.jsx

index aa4e744..d1a8a9e 100644 (file)
@@ -173,8 +173,8 @@ class SkyquakeContainerStore {
 
         } else {
             state.notificationMessage = data.msg;
-            if(data.type == 'success') {
-                state.notificationType = 'success';
+            if(data.type) {
+                state.notificationType = data.type;
             }
         }
         this.setState(state);
index 45b31fc..37063ca 100644 (file)
@@ -47,7 +47,6 @@ class Account extends React.Component {
         }
     }
     componentWillUnmount() {
-        this.props.store.closeSocket();
         this.props.store.unlisten(this.storeListener);
     }
     setUp(props){
index a2373e6..20c84da 100644 (file)
@@ -245,9 +245,10 @@ export default function EditDescriptorModelProperties(props) {
 
                                event.preventDefault();
 
-                               const name = event.target.name;
+                               let name = event.target.name;
                                const value = event.target.value;
 
+
                                /*
                                        Transient State is stored for convenience in the uiState field.
                                        The choice yang type uses case elements to describe the "options".
@@ -255,22 +256,22 @@ export default function EditDescriptorModelProperties(props) {
                                        the system to determine which type is selected by the name of
                                        the element contained within the field.
                                 */
-
-                               //const stateExample = {
-                               //      uiState: {
-                               //              choice: {
-                               //                      'conf-config': {
-                               //                              selected: 'rest',
-                               //                              'case': {
-                               //                                      rest: {},
-                               //                                      netconf: {},
-                               //                                      script: {}
-                               //                              }
-                               //                      }
-                               //              }
-                               //      }
-                               //};
-
+                               /*
+                                       const stateExample = {
+                                               uiState: {
+                                                       choice: {
+                                                               'conf-config': {
+                                                                       selected: 'rest',
+                                                                       'case': {
+                                                                               rest: {},
+                                                                               netconf: {},
+                                                                               script: {}
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       };
+                               */
                                const statePath = ['uiState.choice'].concat(name);
                                const stateObject = utils.resolvePath(this.model, statePath.join('.')) || {};
                                const selected = stateObject.selected ? stateObject.selected.split('.')[1] : undefined;
@@ -278,19 +279,34 @@ export default function EditDescriptorModelProperties(props) {
                                utils.assignPathValue(this.model, statePath.join('.'), stateObject);
 
                                // write the current choice value into the state
-                               const choiceObject = utils.resolvePath(this.model, [name, selected].join('.'));
-                               if (choiceObject) {
-                                       utils.assignPathValue(stateObject, ['case', selected].join('.'), _.cloneDeep(choiceObject));
+                               let choiceObject = utils.resolvePath(this.model, [name, selected].join('.'));
+                               let isTopCase = false;
+                               if (!choiceObject) {
+                                       isTopCase = true;
+                                       choiceObject = utils.resolvePath(this.model, [selected].join('.'));
                                }
+                               utils.assignPathValue(stateObject, [selected].join('.'), _.cloneDeep(choiceObject));
+
+                               if(this.model.uiState.choice.hasOwnProperty(name)) {
+                                       delete this.model[selected];
+                                       utils.removePathValue(this.model, [name, selected].join('.'), isTopCase);
+                               } else {
+                                       // remove the current choice value from the model
+                               utils.removePathValue(this.model, [name, selected].join('.'), isTopCase);
+                               }
+
 
-                               // remove the current choice value from the model
-                               utils.removePathValue(this.model, [name, selected].join('.'));
 
                                // get any state for the new selected choice
-                               const newChoiceObject = utils.resolvePath(stateObject, ['case', value].join('.')) || {};
+                               const newChoiceObject = utils.resolvePath(stateObject, [value].join('.')) || {};
 
                                // assign new choice value to the model
-                               utils.assignPathValue(this.model, [name, value].join('.'), newChoiceObject);
+                               if (isTopCase) {
+                                       utils.assignPathValue(this.model, [name, value].join('.'), newChoiceObject);
+                               } else {
+                                       utils.assignPathValue(this.model, [value].join('.'), newChoiceObject)
+                               }
+
 
                                // update the selected name
                                utils.assignPathValue(this.model, statePath.concat('selected').join('.'), value);
@@ -342,6 +358,14 @@ export default function EditDescriptorModelProperties(props) {
                                        }
                                });
                                selectedOptionValue = utils.resolvePath(container.model, ['uiState.choice', selectName, 'selected'].join('.'));
+                       } else {
+                               property.properties.map(function(p) {
+                                       let pname = p.properties[0].name;
+                                       if(container.model.hasOwnProperty(pname)) {
+                                               utils.assignPathValue(container.model, ['uiState.choice', selectName, 'selected'].join('.'), [p.name, pname].join('.'));
+                                       }
+                               })
+                               selectedOptionValue = utils.resolvePath(container.model, ['uiState.choice', selectName, 'selected'].join('.'));
                        }
                }
                //If selectedOptionValue is present, take first item in string which represents the case name.
@@ -358,7 +382,7 @@ export default function EditDescriptorModelProperties(props) {
                                        {build(container, d, childPath, childValue, props)}
                                </div>
                        );
-               }) : (!isMissingDescriptorMeta) ? build(container, valueProperty, path.concat(valueProperty.name), utils.resolvePath(container.model, path.concat(valueProperty.name).join('.'))) : null
+               }) : (!isMissingDescriptorMeta) ? build(container, valueProperty, path.concat(valueProperty.name), utils.resolvePath(container.model, path.concat(valueProperty.name).join('.')) || container.model[valueProperty.name]) : null
                // end magic
                const onFocus = onFocusPropertyFormInputElement.bind(container, property, path, value);
 
@@ -510,6 +534,14 @@ export default function EditDescriptorModelProperties(props) {
 
                if (property.type === 'choice') {
                        value = utils.resolvePath(container.model, ['uiState.choice'].concat(path, 'selected').join('.'));
+                       if(!value) {
+                               property.properties.map(function(p) {
+                                       let pname = p.properties[0].name;
+                                       if(container.model.hasOwnProperty(pname)) {
+                                               value = container.model[pname];
+                                       }
+                               })
+                       }
                }
 
                let displayValue = typeof value === 'object' ? '' : value;
index 40228ee..bc55760 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 
+ *
  *   Copyright 2016 RIFT.IO Inc
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,7 +27,7 @@ export default {
        nsd: common.concat(['constituent-vnfd', 'vnffgd', 'vld']),
        vld: common.concat([]),
        vnfd: common.concat(['vdu', 'internal-vld']),
-       'vnfd.vdu': common.concat(['image', 'external-interface', 'vm-flavor', 'cloud-init']),
+       'vnfd.vdu': common.concat(['image', 'external-interface', 'vm-flavor', 'cloud-init', 'filename']),
        // white-list valid fields to send in the meta field
        meta: ['containerPositionMap']
 };
index 258b894..d3ef200 100644 (file)
@@ -82,7 +82,20 @@ export default {
                // resolve paths like 'nsd' or 'vnfd.vdu' or 'nsd.constituent-vnfd'
                const found = utils.resolvePath(modelMetaByPropertyNameMap, getPathForType(typeOrPath));
                if (found) {
-                       return found[':meta'].properties.map(p => p.name);
+                       let result = [];
+                       found[':meta'].properties.map((p) => {
+                               // if(false) {
+                               if(p.type == 'choice') {
+                                       result.push(p.name)
+                                       return p.properties.map(function(q){
+                                               result.push(q.properties[0].name);
+                                       })
+
+                               } else  {
+                                       return result.push(p.name);
+                               }
+                       })
+                       return result;
                }
                console.warn('no model uiState found for type', typeOrPath);
        }
index 4e6b792..014beb3 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * 
+ *
  *   Copyright 2016 RIFT.IO Inc
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
@@ -121,7 +121,9 @@ const DescriptorModelSerializer = {
                                return constituentVNFD;
 
                        });
-
+                       for (var key in confd) {
+                               checkForChoiceAndRemove(key, confd, nsdModel);
+                       }
                        // serialize the VLD instances
                        confd.vld = confd.vld.map(d => {
                                return DescriptorModelSerializer.serialize(d);
@@ -142,11 +144,15 @@ const DescriptorModelSerializer = {
                        // once that is fixed, remove this piece of code.
                        // fix-start
                        for (var key in confd) {
-                               if (confd.hasOwnProperty(key) && confd[key] === '') {
-                                       delete confd[key];
-                               }
+                               if (confd.hasOwnProperty(key) && confd[key] === '') {
+                       delete confd[key];
+                } else {
+                       //removes choice properties from top level object and copies immediate children onto it.
+                                       checkForChoiceAndRemove(key, confd, vldModel);
+                }
                        }
 
+
                        const deepProperty = 'provider-network';
                        for (var key in confd[deepProperty]) {
                                if (confd[deepProperty].hasOwnProperty(key) && confd[deepProperty][key] === '') {
@@ -154,8 +160,6 @@ const DescriptorModelSerializer = {
                                }
                        }
                        // fix-end
-
-
                        confd[property] = confd[property].map(d => DescriptorModelSerializer[property].serialize(d));
                        return confd;
                }
@@ -186,10 +190,31 @@ const DescriptorModelSerializer = {
        },
        vdu: {
                serialize(vduModel) {
-                       const confd = _.omit(vduModel, ['uiState']);
+                       const copy = _.cloneDeep(vduModel);
+                       for (let k in copy) {
+                               checkForChoiceAndRemove(k, copy, vduModel)
+                       }
+                       const confd = _.omit(copy, ['uiState']);
                        return confd;
                }
        }
 };
 
+
+function checkForChoiceAndRemove(k, confd, model) {
+       let state = model.uiState;
+       if (state.choice) {
+               let choice = state.choice[k]
+               if(choice) {
+                       for (let key in confd[k]) {
+                               if(choice && (choice.selected.indexOf(key) > -1)) {
+                                       confd[key] = confd[k][key]
+                               }
+                       };
+                       delete confd[k];
+               }
+       }
+       return confd;
+}
+
 export default DescriptorModelSerializer;
index 01e6675..ec69bc4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 
+ *
  *   Copyright 2016 RIFT.IO Inc
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
@@ -71,7 +71,7 @@ export default {
                }, obj);
                resolvedObj[name] = value;
        },
-       updatePathValue(obj, path, value) {
+       updatePathValue(obj, path, value, isCase) {
                // todo: replace implementation of assignPathValue with this impl and
                // remove updatePathValue (only need one function, not both)
                // same as assignPathValue except removes property if value is undefined
@@ -92,18 +92,27 @@ export default {
                                if (isArray) {
                                        r[p] = r[p].filter((d, i) => i !== index);
                                } else {
-                                       delete r[p][name];
+                                       if(isCase) {
+                                               delete r[name];
+                                       } else {
+                                               delete r[p][name];
+                                       }
                                }
                        }
-                       return r[p];
+                       if(isCase) {
+                               return r;
+                       } else {
+                               return r[p];
+                       }
+
                }, obj);
                if (!isRemove) {
                        resolvedObj[name] = value;
                }
        },
-       removePathValue(obj, path) {
+       removePathValue(obj, path, isCase) {
                // note updatePathValue removes value if third argument is undefined
-               return this.updatePathValue(obj, path);
+               return this.updatePathValue(obj, path, undefined, isCase);
        },
 
        suffixAsInteger: (field) => {
index 96818e0..509ff77 100644 (file)
@@ -1664,7 +1664,7 @@ VDUR.consoleUrl.get = function(req) {
 CloudAccount.get = function(req) {
     var api_server = req.query["api_server"];
     var uri = utils.confdPort(api_server);
-    uri += APIVersion + '/api/config/cloud/account?deep';
+    uri += APIVersion + '/api/operational/cloud/account?deep';
     var headers = _.extend({}, constants.HTTP_HEADERS.accept.collection, {
         'Authorization': req.get('Authorization')
     });
index 94ba391..2e6e242 100644 (file)
@@ -131,7 +131,13 @@ class LaunchNetworkServiceStore {
     }
     getLaunchCloudAccountSuccess(cloudAccounts) {
         let newState = {};
-        newState.cloudAccounts = cloudAccounts || [];
+        newState.cloudAccounts = cloudAccounts.filter(function(v) {
+            console.log(v)
+                return v['connection-status'].status == 'success';
+            }) || [];
+        if(cloudAccounts.length != newState.cloudAccounts.length) {
+            Alt.actions.global.showNotification.defer({type: 'warning', msg: 'One or more VIM accounts have failed to connect'});
+        }
         if(cloudAccounts && cloudAccounts.length > 0) {
             newState.selectedCloudAccount = cloudAccounts[0];
             if (cloudAccounts[0]['account-type'] == 'openstack') {
index a310c27..9ee7ec4 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * 
+ *
  *   Copyright 2016 RIFT.IO Inc
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
@@ -127,12 +127,12 @@ class LaunchpadHeader extends React.Component {
             <h3 className="launchpadCard_header-link">
               {
                 isLoading ?
-                            <a title="Open Viewport Dashboard" style={{cursor:'default'}}>
+                            <a title={this.props.name} className="title" style={{cursor:'default'}}>
                               {this.props.name}
                             </a>
                           : <Link to={{pathname: '/viewport', query: {id: this.props.nsr.id,
                               sdnpresent: sdnpresent}}}
-                              title="Open Viewport Dashboard">
+                              title={"Open Viewport Dashboard for " + this.props.name}>
                               {this.props.name}
                               <span className="oi" data-glyph="external-link" aria-hidden="true"></span>
                             </Link>
index 01a798a..1f2680d 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * 
+ *
  *   Copyright 2016 RIFT.IO Inc
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
 @import 'style/_colors.scss';
 @import '../../node_modules/open-iconic/font/css/open-iconic.css';
 .launchpadCard {
+  display:-ms-flexbox;
   display:flex;
   margin-top: 0.75rem;
   &-body{
     position: relative;
   }
   .deletingIndicator {
+    display: -ms-flexbox;
     display: flex;
-    flex:1;
-    align-items: center;
-    justify-content: center;
+    -ms-flex:1;
+        flex:1;
+    -ms-flex-align: center;
+        align-items: center;
+    -ms-flex-pack: center;
+        justify-content: center;
   }
   &_launch {
+    display:-ms-flexbox;
     display:flex;
-    flex-direction:column;
-    flex: 1;
-    justify-content: center;
-    align-items: center;
+    -ms-flex-direction:column;
+        flex-direction:column;
+    -ms-flex: 1;
+        flex: 1;
+    -ms-flex-pack: center;
+        justify-content: center;
+    -ms-flex-align: center;
+        align-items: center;
     img {
       width: 88px;
       padding:1rem;
     min-width: 693px;
     max-width: 693px;
     &-link, a {
+      display:-ms-flexbox;
       display:flex;
-      align-items:center;
+      -ms-flex-align:center;
+          align-items:center;
       text-decoration: none;
       color: inherit;
     }
     &-link {
       margin-left:0.5rem;
       cursor:pointer;
+      .title {
+        overflow: hidden;
+        text-overflow: ellipsis;
+        width: 460px;
+        display: block;
+      }
     }
     .oi {
       margin:0 0 -0.25rem 0.5rem;
     }
     &-title {
+      display: -ms-flexbox;
       display: flex;
       line-height: 3rem;
       background-color: $brand-green-light;
-      //background-color: $primary-header;
+      /*background-color: $primary-header;*/
       position: relative;
-      flex-direction: row;
-      align-items: center;
-      justify-content: flex-start;
+      -ms-flex-direction: row;
+          flex-direction: row;
+      -ms-flex-align: center;
+          align-items: center;
+      -ms-flex-pack: start;
+          justify-content: flex-start;
       padding-right:1rem;
       &-off {
         background-color:white;
         position:relative;
       }
     &-actions {
-      flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+      display: -ms-flexbox;
       display: flex;
-      justify-content: flex-end;
+      -ms-flex-pack: end;
+          justify-content: flex-end;
       padding-right: 1rem;
       h3{
         padding-right:0.25rem;
     &-status {
       background-color: $brand-green;
       &-current {
+        display:-ms-flexbox;
         display:flex;
-        justify-content:space-between;
+        -ms-flex-pack:justify;
+            justify-content:space-between;
         padding: 0.5rem 0;
         span,a {
           padding: 0 0.25rem;
     }
     &-operational-status {
       &_loading {
+        display:-ms-flexbox;
         display:flex;
-        flex-direction:column;
+        -ms-flex-direction:column;
+            flex-direction:column;
+        -ms-flex-pack: center;
+            justify-content: center;
         justify-content: center;
-        justify-content: center;
-        align-items: center;
+        -ms-flex-align: center;
+            align-items: center;
         color:$gray-darkest;
      }
      &_open {
         position: absolute;
         width: 100%;
         z-index: 99;
+        display: -ms-flexbox;
         display: flex;
-        flex-direction: column;
-        align-items: center;
-        justify-content: center;
-        align-content: center;
+        -ms-flex-direction: column;
+            flex-direction: column;
+        -ms-flex-align: center;
+            align-items: center;
+        -ms-flex-pack: center;
+            justify-content: center;
+        -ms-flex-line-pack: center;
+            align-content: center;
         color: black;
         h2{
               padding: 2rem;
     &-vnfr_management-links {
 
       &_loading {
+        display:-ms-flexbox;
         display:flex;
-        flex-direction:column;
-        justify-content: center;
-        align-items: center;
+        -ms-flex-direction:column;
+            flex-direction:column;
+        -ms-flex-pack: center;
+            justify-content: center;
+        -ms-flex-align: center;
+            align-items: center;
         color:$gray-darkest;
      }
       &_open {
         position:absolute;
         width:100%;
         z-index: 99;
+        display: -ms-flexbox;
         display: flex;
-        flex-direction: column;
-        align-items: center;
-        justify-content: center;
-        align-content: center;
+        -ms-flex-direction: column;
+            flex-direction: column;
+        -ms-flex-align: center;
+            align-items: center;
+        -ms-flex-pack: center;
+            justify-content: center;
+        -ms-flex-line-pack: center;
+            align-content: center;
         color:black;
 
         .notice {
           height: inherit;
         }
         li {
-          justify-content: space-between;
+          -ms-flex-pack: justify;
+              justify-content: space-between;
+          display: -ms-flexbox;
           display: flex;
         }
       }
     .empty {
       min-height:50px;
       max-width: 100%;
+      display:-ms-flexbox;
       display:flex;
-      justify-content: center;
-      align-items: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+      -ms-flex-align: center;
+          align-items: center;
     }
   }
   &_title {
       color:$black;
       background:$secondary-header;
       padding: 0.5rem;
-      // margin: 0 0 0.5rem 0;
-      // border-top:1px solid #666;
-      // border-bottom:1px solid #666;
+      /* margin: 0 0 0.5rem 0;*/
+      /* border-top:1px solid #666;*/
+      /* border-bottom:1px solid #666;*/
       border-top:1px solid #f1f1f1;
       border-bottom:1px solid #f1f1f1;
   }
 
   &_data-list {
     ul, dl{
+      display:-ms-flexbox;
       display:flex;
-      flex-direction:row;
-      flex-wrap:wrap;
-      align-items:flex-start;
+      -ms-flex-direction:row;
+          flex-direction:row;
+      -ms-flex-wrap:wrap;
+          flex-wrap:wrap;
+      -ms-flex-align:start;
+          align-items:flex-start;
        font-size: 0.825rem;
       li{
-        flex:1 1 30%;
+        -ms-flex:1 1 30%;
+            flex:1 1 30%;
       }
     }
     dl {
     }
   }
   &_data-list.EPA-PARAMS {
-      // height: 105px;
+      /* height: 105px;*/
       width: 715px;
       overflow-y: scroll;
       h1 {
       }
   }
   &_controls{
+    display:-ms-flexbox;
     display:flex;
-    flex-direction:row;
+    -ms-flex-direction:row;
+        flex-direction:row;
     .react-tabs {
-      flex: auto;
+      -ms-flex: auto;
+          flex: auto;
     [role=tab][aria-selected=true] {
       background:none;
       border:none;
       border:none;
       margin: 0 0 10px;
       padding: 0;
+      display: -ms-flexbox;
       display: flex;
-      justify-content: flex-end;
+      -ms-flex-pack: end;
+          justify-content: flex-end;
 
          [role=tab]:first-child {
-            flex: 1;
+            -ms-flex: 1;
+                flex: 1;
          }
     }
 
 
   }
   .slick-initialized.slick-slider {
-    // min-height:200px;
+    /* min-height:200px;*/
   }
 
   .close-btn {
index 0a3e35e..9b35d1b 100644 (file)
@@ -27,7 +27,17 @@ export default class RecordDetails extends React.Component{
   }
   render(){
     let html;
-    let text = JSON.stringify(this.props.data, undefined, 2);
+    // Prism can't handle escaped \n and other characters
+    let text = JSON.stringify(this.props.data, undefined, 2)
+                .replace(/\r\n/g, '\n')
+                .replace(/\\\\n/g, "\n")
+                .replace(/\\\\'/g, "\'")
+                .replace(/\\\\"/g, '\"')
+                .replace(/\\\\&/g, "\&")
+                .replace(/\\\\r/g, "\r")
+                .replace(/\\\\t/g, "\t")
+                .replace(/\\\\b/g, "\b")
+                .replace(/\\\\f/g, "\f");
     // html = this.props.isLoading ? <LoadingIndicator size={10} show={true} /> : <pre className="json">{JSON.stringify(this.props.data, undefined, 2)}</pre>;
     html = this.props.isLoading ? <LoadingIndicator size={10} show={true} /> : Prism.highlight(text, Prism.languages.javascript, 'javascript');
     return (
index f72af71..cbb6691 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 
+ *
  *   Copyright 2016 RIFT.IO Inc
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
  */
 @import "style/_colors.scss";
 
+.sshKeyCards {
+    display:-ms-flexbox;
+    display:flex;
+    -ms-flex-direction:column;
+        flex-direction:column;
+}
+
 .sshKeyCard {
     display:-ms-flexbox;
     display:flex;
     -ms-flex-align: start;
         align-items: flex-start;
-    height:250px;
+    -ms-flex: 1 0 auto;
+        flex: 1 0 auto;
     border-top: 1px solid $neutral-white;
     &:nth-child(odd) {
         background:$gray-lighter;
     }
     &-key.sqTextInput {
         font-size:1rem;
-        -ms-flex-align: stretch;
-            -ms-grid-row-align: stretch;
-            align-items: stretch;
-            -ms-flex:1;
-                flex:1;
+
         > textarea {
             padding:0.5rem;
             min-height:190px;
         }
         > .readonly {
-            -ms-flex: 1;
-                flex: 1;
             background: none !important;
             word-break: break-all;
+            height:auto;
         }
     }
     &-name {
@@ -95,8 +98,8 @@
         -ms-flex-align: center;
         -ms-grid-row-align: center;
     align-items: center;
-        height: 100%;
-        border-left: 1px solid $neutral-white;
+        -ms-flex-item-align: center;
+            align-self: center;
         >div {
             display:-ms-flexbox;
             display:flex;
index 1676cff..f832215 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 
+ *
  *   Copyright 2016 RIFT.IO Inc
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,7 +21,7 @@ import SshKeyCard from './sshKeyCard.jsx';
 import SshKeyStore from './sshKeyStore.js';
 import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
 import '../../node_modules/open-iconic/font/css/open-iconic.css';
-import 'style/base.scss';
+// import 'style/base.scss';
 
 
 class SshKeys extends Component {
@@ -45,7 +45,7 @@ class SshKeys extends Component {
         let Store = self.Store;
         // return <div>test</div>
         return (
-          <div>
+          <div className="sshKeyCards">
             {
               self.state.data && self.state.data.keys.map(function(k, i) {
                 let sshKey = self.state.data.entities[k];