You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by al...@apache.org on 2015/05/03 23:20:50 UTC

ambari git commit: AMBARI-10895. Admin View: create/edit view instance UI issues (alexantonenko)

Repository: ambari
Updated Branches:
  refs/heads/trunk 727f550f8 -> 0e849f6d4


AMBARI-10895. Admin View: create/edit view instance UI issues (alexantonenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/0e849f6d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/0e849f6d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/0e849f6d

Branch: refs/heads/trunk
Commit: 0e849f6d4a58224a02fca848edea35230e3536c4
Parents: 727f550
Author: Alex Antonenko <hi...@gmail.com>
Authored: Mon May 4 00:16:04 2015 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Mon May 4 00:20:44 2015 +0300

----------------------------------------------------------------------
 .../controllers/ambariViews/ViewsEditCtrl.js    | 201 +++++++++++++------
 .../resources/ui/admin-web/app/styles/main.css  |  19 +-
 .../admin-web/app/views/ambariViews/create.html |  22 +-
 .../admin-web/app/views/ambariViews/edit.html   | 122 +++++++----
 4 files changed, 242 insertions(+), 122 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/0e849f6d/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js
index ab1d948..d75d8b2 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js
@@ -21,38 +21,69 @@ angular.module('ambariAdminConsole')
 .controller('ViewsEditCtrl', ['$scope', '$routeParams' , 'Cluster', 'View', 'Alert', 'PermissionLoader', 'PermissionSaver', 'ConfirmationModal', '$location', 'UnsavedDialog', function($scope, $routeParams, Cluster, View, Alert, PermissionLoader, PermissionSaver, ConfirmationModal, $location, UnsavedDialog) {
   $scope.identity = angular.identity;
   $scope.isConfigurationEmpty = true;
-  function reloadViewInfo(){
+  $scope.isSettingsEmpty = true;
+
+  function reloadViewInfo(section){
     // Load instance data, after View permissions meta loaded
     View.getInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId)
     .then(function(instance) {
       $scope.instance = instance;
-
       $scope.settings = {
         'visible': $scope.instance.ViewInstanceInfo.visible,
         'label': $scope.instance.ViewInstanceInfo.label,
         'description': $scope.instance.ViewInstanceInfo.description
       };
-
-      initConfigurations();
-      if(instance.ViewInstanceInfo.cluster_handle) {
-        $scope.isLocalCluster = true;
-        $scope.cluster = instance.ViewInstanceInfo.cluster_handle;
-      }else{
-        $scope.isLocalCluster = false;
-        $scope.cluster = $scope.clusters.length > 0 ? $scope.clusters[0] : "No Clusters";
+      switch (section) {
+        case "details" :
+          initConfigurations();
+          initCtrlVariables(instance);
+          break;
+        case "settings" :
+          initConfigurations(true);
+          break;
+        case "cluster" :
+          initCtrlVariables(instance);
+          break;
       }
-      $scope.isConfigurationEmpty = !$scope.numberOfClusterConfigs;
     })
     .catch(function(data) {
       Alert.error('Cannot load instance info', data.data.message);
     });
   }
 
-  function initConfigurations() {
-    $scope.configuration = angular.copy($scope.instance.ViewInstanceInfo.properties);
-    for (var confName in $scope.configuration) {
-      if ($scope.configuration.hasOwnProperty(confName)) {
-        $scope.configuration[confName] = $scope.configuration[confName] === 'null' ? '' : $scope.configuration[confName];
+  function initCtrlVariables(instance) {
+    if(instance.ViewInstanceInfo.cluster_handle) {
+      $scope.isLocalCluster = true;
+      $scope.cluster = instance.ViewInstanceInfo.cluster_handle;
+    }else{
+      $scope.isLocalCluster = false;
+      $scope.cluster = $scope.clusters.length > 0 ? $scope.clusters[0] : "No Clusters";
+    }
+    $scope.isConfigurationEmpty = !$scope.numberOfClusterConfigs;
+    $scope.isSettingsEmpty = !$scope.numberOfSettingsConfigs;
+  }
+
+  function isClusterConfig(name) {
+    var configurationMeta = $scope.configurationMeta;
+    var clusterConfigs = configurationMeta.filter(function(el) {
+      return el.clusterConfig;
+    }).map(function(el) {
+      return el.name;
+    });
+    return clusterConfigs.indexOf(name) !== -1;
+  }
+
+  function initConfigurations(initClusterConfig) {
+    var initAllConfigs = !initClusterConfig;
+    var configuration = angular.copy($scope.instance.ViewInstanceInfo.properties);
+    if (initAllConfigs) {
+      $scope.configuration = angular.copy($scope.instance.ViewInstanceInfo.properties);
+    }
+    for (var confName in configuration) {
+      if (configuration.hasOwnProperty(confName)) {
+        if (!isClusterConfig(confName) || initAllConfigs) {
+          $scope.configuration[confName] = configuration[confName] === 'null' ? '' : configuration[confName];
+        }
       }
     }
   }
@@ -65,9 +96,12 @@ angular.module('ambariAdminConsole')
     angular.forEach($scope.configurationMeta, function (item) {
       item.displayName = item.name.replace(/\./g, '\.\u200B');
       item.clusterConfig = !!item.clusterConfig;
+      if (!item.clusterConfig) {
+        $scope.numberOfSettingsConfigs++;
+      }
       $scope.numberOfClusterConfigs = $scope.numberOfClusterConfigs + !!item.clusterConfig;
     });
-    reloadViewInfo();
+    reloadViewInfo("details");
   });
 
   function reloadViewPrivileges(){
@@ -98,8 +132,10 @@ angular.module('ambariAdminConsole')
   $scope.noClusterAvailible = true;
 
 
-    $scope.editSettingsDisabled = true;
+  $scope.editSettingsDisabled = true;
+  $scope.editDetailsSettingsDisabled = true;
   $scope.numberOfClusterConfigs = 0;
+  $scope.numberOfSettingsConfigs = 0;
 
   $scope.toggleSettingsEdit = function() {
     $scope.editSettingsDisabled = !$scope.editSettingsDisabled;
@@ -114,6 +150,19 @@ angular.module('ambariAdminConsole')
     });
   };
 
+  $scope.toggleDetailsSettingsEdit = function() {
+    $scope.editDetailsSettingsDisabled = !$scope.editDetailsSettingsDisabled;
+    $scope.settingsBeforeEdit = angular.copy($scope.configuration);
+    $scope.configurationMeta.forEach(function (element) {
+      if (element.masked && !$scope.editDetailsSettingsDisabled && !element.clusterConfig) {
+        $scope.configuration[element.name] = '';
+      }
+      if(element.clusterConfig) {
+        delete $scope.settingsBeforeEdit[element.name];
+      }
+    });
+  };
+
   Cluster.getAllClusters().then(function (clusters) {
     if(clusters.length >0){
       clusters.forEach(function(cluster) {
@@ -130,9 +179,6 @@ angular.module('ambariAdminConsole')
     if( $scope.settingsForm.$valid ){
       var data = {
         'ViewInstanceInfo':{
-          'visible': $scope.settings.visible,
-          'label': $scope.settings.label,
-          'description': $scope.settings.description,
           'properties':{}
         }
       };
@@ -146,7 +192,7 @@ angular.module('ambariAdminConsole')
         if( callback ){
           callback();
         } else {
-          reloadViewInfo();
+          reloadViewInfo("settings");
           $scope.editSettingsDisabled = true;
           $scope.settingsForm.$setPristine();
         }
@@ -157,13 +203,42 @@ angular.module('ambariAdminConsole')
     }
   };
   $scope.cancelSettings = function() {
+    angular.extend($scope.configuration, $scope.settingsBeforeEdit);
+    $scope.editSettingsDisabled = true;
+    $scope.settingsForm.$setPristine();
+  };
+
+  $scope.saveDetails = function(callback) {
+    if( $scope.detailsForm.$valid ){
+      var data = {
+        'ViewInstanceInfo':{
+          'visible': $scope.settings.visible,
+          'label': $scope.settings.label,
+          'description': $scope.settings.description
+        }
+      };
+      return View.updateInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId, data)
+      .success(function() {
+        if( callback ){
+          callback();
+        } else {
+          reloadViewInfo("cluster");
+          $scope.editDetailsSettingsDisabled = true;
+          $scope.settingsForm.$setPristine();
+        }
+      })
+      .catch(function(data) {
+        Alert.error('Cannot save settings', data.data.message);
+      });
+    }
+  };
+  $scope.cancelDetails = function() {
     $scope.settings = {
       'visible': $scope.instance.ViewInstanceInfo.visible,
       'label': $scope.instance.ViewInstanceInfo.label,
       'description': $scope.instance.ViewInstanceInfo.description
     };
-    angular.extend($scope.configuration, $scope.settingsBeforeEdit);
-    $scope.editSettingsDisabled = true;
+    $scope.editDetailsSettingsDisabled = true;
     $scope.settingsForm.$setPristine();
   };
 
@@ -182,49 +257,51 @@ angular.module('ambariAdminConsole')
     });
   };
   $scope.saveConfiguration = function() {
-    var data = {
-      'ViewInstanceInfo':{
-        'properties':{}
-      }
-    };
-    if($scope.isLocalCluster) {
-      data.ViewInstanceInfo.cluster_handle = $scope.cluster;
-    } else {
-      data.ViewInstanceInfo.cluster_handle = null;
-      $scope.configurationMeta.forEach(function (element) {
-        if(element.clusterConfig) {
-          data.ViewInstanceInfo.properties[element.name] = $scope.configuration[element.name];
+    if( $scope.propertiesForm.$valid ){
+      var data = {
+        'ViewInstanceInfo':{
+          'properties':{}
         }
-      });
-    }
+      };
+      if($scope.isLocalCluster) {
+        data.ViewInstanceInfo.cluster_handle = $scope.cluster;
+      } else {
+        data.ViewInstanceInfo.cluster_handle = null;
+        $scope.configurationMeta.forEach(function (element) {
+          if(element.clusterConfig) {
+            data.ViewInstanceInfo.properties[element.name] = $scope.configuration[element.name];
+          }
+        });
+      }
 
-    return View.updateInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId, data)
-    .success(function() {
-      $scope.editConfigurationDisabled = true;
-      $scope.propertiesForm.$setPristine();
-    })
-    .catch(function(data) {
-      var errorMessage = data.data.message;
+      return View.updateInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId, data)
+      .success(function() {
+        $scope.editConfigurationDisabled = true;
+        $scope.propertiesForm.$setPristine();
+      })
+      .catch(function(data) {
+        var errorMessage = data.data.message;
 
-      //TODO: maybe the BackEnd should sanitize the string beforehand?
-      errorMessage = errorMessage.substr(errorMessage.indexOf("\{"));
+        //TODO: maybe the BackEnd should sanitize the string beforehand?
+        errorMessage = errorMessage.substr(errorMessage.indexOf("\{"));
 
-      if (data.status >= 400) {
-        try {
-          var errorObject = JSON.parse(errorMessage);
-          errorMessage = errorObject.detail;
-          angular.forEach(errorObject.propertyResults, function (item, key) {
-            $scope.propertiesForm[key].validationError = !item.valid;
-            if (!item.valid) {
-              $scope.propertiesForm[key].validationMessage = item.detail;
-            }
-          });
-        } catch (e) {
-          console.error('Unable to parse error message:', data.message);
+        if (data.status >= 400) {
+          try {
+            var errorObject = JSON.parse(errorMessage);
+            errorMessage = errorObject.detail;
+            angular.forEach(errorObject.propertyResults, function (item, key) {
+              $scope.propertiesForm[key].validationError = !item.valid;
+              if (!item.valid) {
+                $scope.propertiesForm[key].validationMessage = item.detail;
+              }
+            });
+          } catch (e) {
+            console.error('Unable to parse error message:', data.message);
+          }
         }
-      }
-      Alert.error('Cannot save properties', errorMessage);
-    });
+        Alert.error('Cannot save properties', errorMessage);
+      });
+    }
   };
   $scope.cancelConfiguration = function() {
     angular.extend($scope.configuration, $scope.configurationBeforeEdit);

http://git-wip-us.apache.org/repos/asf/ambari/blob/0e849f6d/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
index d273d07..9e791d6 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
@@ -657,7 +657,6 @@ table.no-border tr td{
 }
 
 .property-form label{
-  width: 254px;
   word-wrap: break-word;
   text-overflow: ellipsis;
   overflow: hidden;
@@ -1074,7 +1073,7 @@ button.btn.btn-xs{
   position: relative;
   border: 1px solid #c4c4c4;
   border-radius: 4px 0 0 4px;
-  box-shadow: 0 0px 4px #ebebeb;
+  box-shadow: 0 0 4px #ebebeb;
   width: 300px;
   background: white;
   margin-bottom: 20px;
@@ -1324,17 +1323,15 @@ accordion .panel-group .panel{
     margin-left: 10px;
 }
 .clusters-name-dropdown {
-  margin-top: 7px;
-  margin-left: 16px;
   width: 200px;
 }
-.cluster-configurable-form {
-  width: 350px;
-  margin-top: 15px;
-  margin-bottom: 15px;
-  padding: 0 15px;
-}
 .edit-view-custom-wrap {
   padding-top: 0;
-  margin-top: -28px;
+  margin-top: -15px;
+}
+.panel-body .checkbox {
+  min-height: 20px;
+  padding-left: 20px;
+  margin-top: 10px;
+  margin-bottom: 10px;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/0e849f6d/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html
index 4c8469b..dd274a2 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html
@@ -30,7 +30,7 @@
     </div>
     <div class="form-group">
       <div class="col-sm-2"><label for="" class="control-label">Version</label></div>
-      <div class="col-sm-2">
+      <div class="col-sm-3">
         <select ng-model="version" class="instanceversion-input form-control" ng-change="versionChanged()" ng-options="o as o for o in versions"></select>
       </div>
     </div>
@@ -125,15 +125,25 @@
       <h3 class="panel-title">Cluster Configuration</h3>
     </div>
 
-    <div class="panel-body property-form cluster-configurable-form" popover="{{clusterConfigurableErrorMsg}}" popover-trigger="mouseenter">
-      <div class="checkbox">
+    <div class="panel-body property-form" popover="{{clusterConfigurableErrorMsg}}" popover-trigger="mouseenter">
+      <div class="checkbox create-checkbox-cluster">
         <label>
           <input type="radio" ng-disabled="!clusterConfigurable || noClusterAvailible" ng-model="instance.isLocalCluster" ng-value="true" class="visibilityCheckbox"> Local Ambari Managed Cluster
         </label>
       </div>
-      <div class="form-group sub-group">
-        <select ng-model="cluster" ng-disabled="!instance.isLocalCluster" ng-change="onClusterChange()" class="clusters-name-dropdown form-control"  ng-options="o as o for o in clusters"></select>
+
+      <div class="form-horizontal property-form">
+        <div class="form-group">
+
+          <label for="" class="control-label col-sm-3 ng-binding not-required" >Cluster Name</label>
+          <div>
+            <div class="col-sm-9">
+              <select ng-model="cluster" ng-disabled="!instance.isLocalCluster" ng-change="onClusterChange()" class="clusters-name-dropdown form-control"  ng-options="o as o for o in clusters"></select>
+            </div>
+          </div>
+        </div>
       </div>
+
     </div>
     <div class="panel-body property-form">
       <div class="checkbox">
@@ -144,7 +154,7 @@
       <div class="alert alert-danger bottom-margin top-margin" ng-show='form.instanceCreateForm.generalValidationError'>
         {{form.instanceCreateForm.generalValidationError}}
       </div>
-      <div class="form-group sub-group" ng-repeat="parameter in instance.properties | filter:{clusterConfig:true}"
+      <div class="form-group" ng-repeat="parameter in instance.properties | filter:{clusterConfig:true}"
         ng-class="{'has-error' : ((form.instanceCreateForm[parameter.name].$error.required && form.instanceCreateForm.submitted) || form.instanceCreateForm[parameter.name].validationError)}" >
         <label for="" class="col-sm-3 control-label" ng-class="{'not-required': !parameter.required}">{{parameter.label || parameter.displayName}}{{parameter.required ? '*' : ''}}</label>
         <div ng-switch="parameter.type">

http://git-wip-us.apache.org/repos/asf/ambari/blob/0e849f6d/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html
index 960222d..b0a7a3b 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html
@@ -26,67 +26,57 @@
   </div>
 </div>
 <hr>
+<div class="form-horizontal create-view-form" role="form" name="form.instanceEditForm">
+  <div class="view-header">
+    <div class="form-group">
+      <div class="col-sm-2">
+        <label for="" class="control-label">View</label>
+      </div>
+      <div class="col-sm-10"><label for="" class="control-label">{{instance.ViewInstanceInfo.view_name}}</label></div>
+    </div>
+    <div class="form-group">
+      <div class="col-sm-2"><label for="" class="control-label">Version</label></div>
+      <div class="col-sm-3">
+        <input disabled="disabled" type="text" class="form-control instancename-input" placeholder="Version" value="{{instance.ViewInstanceInfo.version}}"></div>
+    </div>
+  </div>
+</div>
 <div class="panel panel-default" ng-cloak ng-show="instance">
   <div class="panel-heading clearfix">
-    <h3 class="panel-title pull-left">Settings</h3>
+    <h3 class="panel-title pull-left">Details</h3>
     <div class="pull-right" ng-switch="instance.ViewInstanceInfo.static">
-      <a href ng-switch-when="false" ng-click="toggleSettingsEdit()" ng-show="editSettingsDisabled" class="settings-edit-toggle"> <span class="glyphicon glyphicon-pencil" ></span> Edit</a>
+      <a href ng-switch-when="false" ng-click="toggleDetailsSettingsEdit()" ng-show="editDetailsSettingsDisabled" class="settings-edit-toggle"> <span class="glyphicon glyphicon-pencil" ></span> Edit</a>
       <a href ng-switch-when="true" class="settings-edit-toggle disabled" tooltip="Cannot Edit Static Instances"> <span class="glyphicon glyphicon-pencil" ></span> Edit</a>
     </div>
   </div>
   <div class="panel-body">
-    <form class="form-horizontal" name="settingsForm" novalidate>
-      <div class="form-group">
-        <label for="" class="col-sm-3 control-label">View Name</label>
-        <div class="col-sm-9"><input disabled="disabled" type="text" class="form-control instancename-input" placeholder="Display Name" value="{{instance.ViewInstanceInfo.view_name}}"></div>
-      </div>
-      <div class="form-group">
-        <label for="" class="col-sm-3 control-label">View Version</label>
-        <div class="col-sm-9"><input disabled="disabled" type="text" class="form-control instancename-input" placeholder="Display Name" value="{{instance.ViewInstanceInfo.version}}"></div>
-      </div>
-      <fieldset ng-disabled="editSettingsDisabled">
+    <form class="form-horizontal" name="detailsForm" novalidate>
+      <fieldset ng-disabled="editDetailsSettingsDisabled">
         <div class="form-group">
           <label for="" class="col-sm-3 control-label">Instance Name</label>
           <div class="col-sm-9"><input disabled="disabled" type="text" class="form-control instancename-input" placeholder="Display Name" value="{{instance.ViewInstanceInfo.instance_name}}"></div>
         </div>
-        <div class="form-group" ng-class="{'has-error' : (settingsForm.displayName.$error.required || settingsForm.displayName.$error.pattern) && !editSettingsDisabled}">
+        <div class="form-group" ng-class="{'has-error' : (detailsForm.displayName.$error.required || detailsForm.displayName.$error.pattern) && !editDetailsSettingsDisabled}">
           <label for="" class="col-sm-3 control-label">Display Name</label>
           <div class="col-sm-9">
             <input type="text" class="form-control instancename-input" placeholder="Display Name" name="displayName" required ng-model="settings.label" ng-pattern="/^([a-zA-Z0-9._\s]+)$/">
-            <div class="alert alert-danger no-margin-bottom top-margin" ng-show='settingsForm.displayName.$error.required  && !editSettingsDisabled'>
+            <div class="alert alert-danger no-margin-bottom top-margin" ng-show='detailsForm.displayName.$error.required  && !editDetailsSettingsDisabled'>
               This field is required.
             </div>
-            <div class="alert alert-danger no-margin-bottom top-margin" ng-show='settingsForm.displayName.$error.pattern && !editSettingsDisabled'>
+            <div class="alert alert-danger no-margin-bottom top-margin" ng-show='detailsForm.displayName.$error.pattern && !editDetailsSettingsDisabled'>
               Must not contain any special characters.
             </div>
           </div>
         </div>
-        <div class="form-group" ng-class="{'has-error' : settingsForm.description.$error.required  && !editSettingsDisabled}">
+        <div class="form-group" ng-class="{'has-error' : detailsForm.description.$error.required  && !editDetailsSettingsDisabled}">
           <label for="" class="control-label col-sm-3">Description</label>
           <div class="col-sm-9">
             <input type="text" class="form-control" ng-model="settings.description" name="description" placeholder="Instance Description" required>
-            <div class="alert alert-danger no-margin-bottom top-margin" ng-show='settingsForm.description.$error.required  && !editSettingsDisabled'>
+            <div class="alert alert-danger no-margin-bottom top-margin" ng-show='detailsForm.description.$error.required  && !editDetailsSettingsDisabled'>
               This field is required.
             </div>
           </div>
         </div>
-        <div class="form-group" ng-repeat="property in configurationMeta | filter:{clusterConfig:false}" ng-class="{'has-error' : (!editSettingsDisabled && ((property.required && settingsForm[property.name].$error.required && !editSettingsDisabled) || settingsForm[property.name].validationError))}">
-          <label for="" class="control-label col-sm-3" ng-class="{'not-required': !property.required}">{{property.label || property.displayName}}{{property.required ? '*' : ''}}</label>
-          <div ng-switch="property.type">
-            <div class="col-sm-9 checkbox" ng-switch-when="boolean">
-              <input type="checkbox" class="propertie-input" ng-disabled="editSettingsDisabled" name="{{property.name}}" ng-model="configuration[property.name]" ng-true-value="true" ng-false-value="false" popover="{{property.description}}" popover-title="{{property.name}}" popover-trigger="mouseenter">
-            </div>
-            <div class="col-sm-9" ng-switch-default>
-              <input type="{{property.masked ? 'password' : 'text'}}" class="form-control propertie-input" ng-required="property.required" ng-change="settingsForm[property.name].validationError=''" ng-disabled="editSettingsDisabled" name="{{property.name}}" ng-model="configuration[property.name]" popover="{{property.description}}" popover-title="{{property.name}}" popover-trigger="mouseenter" placeholder="{{property.placeholder}}">
-              <div class="alert alert-danger no-margin-bottom top-margin" ng-show='property.required && settingsForm[property.name].$error.required && !editSettingsDisabled'>
-                This field is required.
-              </div>
-              <div class="alert alert-danger no-margin-bottom top-margin" ng-show='property.required && settingsForm[property.name].validationError && !editSettingsDisabled'>
-                {{propertiesForm[property.name].validationMessage}}
-              </div>
-            </div>
-          </div>
-        </div>
         <div class="form-group">
           <div class="col-sm-offset-3 col-sm-10">
             <div class="checkbox">
@@ -96,10 +86,10 @@
             </div>
           </div>
         </div>
-        <div class="form-group" ng-hide="editSettingsDisabled">
+        <div class="form-group" ng-hide="editDetailsSettingsDisabled">
           <div class="col-sm-offset-2 col-sm-10">
-            <button class="btn btn-primary pull-right left-margin settingssave-btn" ng-click="saveSettings()">Save</button>
-            <button class="btn btn-default pull-right settingscancel-btn" ng-click="cancelSettings()">Cancel</button>
+            <button class="btn btn-primary pull-right left-margin settingssave-btn" ng-click="saveDetails()">Save</button>
+            <button class="btn btn-default pull-right settingscancel-btn" ng-click="cancelDetails()">Cancel</button>
           </div>
         </div>
       </fieldset>
@@ -142,6 +132,45 @@
   </div>
 </div>
 
+<div class="panel panel-default" ng-cloak ng-hide="isSettingsEmpty && instance">
+  <div class="panel-heading clearfix">
+    <h3 class="panel-title pull-left">Settings</h3>
+    <div class="pull-right" ng-switch="instance.ViewInstanceInfo.static">
+      <a href ng-switch-when="false" ng-click="toggleSettingsEdit()" ng-show="editSettingsDisabled" class="settings-edit-toggle"> <span class="glyphicon glyphicon-pencil" ></span> Edit</a>
+      <a href ng-switch-when="true" class="settings-edit-toggle disabled" tooltip="Cannot Edit Static Instances"> <span class="glyphicon glyphicon-pencil" ></span> Edit</a>
+    </div>
+  </div>
+  <div class="panel-body">
+    <form class="form-horizontal" name="settingsForm" novalidate>
+      <fieldset ng-disabled="editSettingsDisabled">
+        <div class="form-group" ng-repeat="property in configurationMeta | filter:{clusterConfig:false}" ng-class="{'has-error' : (!editSettingsDisabled && ((property.required && settingsForm[property.name].$error.required && !editSettingsDisabled) || settingsForm[property.name].validationError))}">
+          <label for="" class="control-label col-sm-3" ng-class="{'not-required': !property.required}">{{property.label || property.displayName}}{{property.required ? '*' : ''}}</label>
+          <div ng-switch="property.type">
+            <div class="col-sm-9 checkbox" ng-switch-when="boolean">
+              <input type="checkbox" class="propertie-input" ng-disabled="editSettingsDisabled" name="{{property.name}}" ng-model="configuration[property.name]" ng-true-value="true" ng-false-value="false" popover="{{property.description}}" popover-title="{{property.name}}" popover-trigger="mouseenter">
+            </div>
+            <div class="col-sm-9" ng-switch-default>
+              <input type="{{property.masked ? 'password' : 'text'}}" class="form-control propertie-input" ng-required="property.required" ng-change="settingsForm[property.name].validationError=''" ng-disabled="editSettingsDisabled" name="{{property.name}}" ng-model="configuration[property.name]" popover="{{property.description}}" popover-title="{{property.name}}" popover-trigger="mouseenter" placeholder="{{property.placeholder}}">
+              <div class="alert alert-danger no-margin-bottom top-margin" ng-show='property.required && settingsForm[property.name].$error.required && !editSettingsDisabled'>
+                This field is required.
+              </div>
+              <div class="alert alert-danger no-margin-bottom top-margin" ng-show='property.required && settingsForm[property.name].validationError && !editSettingsDisabled'>
+                {{propertiesForm[property.name].validationMessage}}
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="form-group" ng-hide="editSettingsDisabled">
+          <div class="col-sm-offset-2 col-sm-10">
+            <button class="btn btn-primary pull-right left-margin settingssave-btn" ng-click="saveSettings()">Save</button>
+            <button class="btn btn-default pull-right settingscancel-btn" ng-click="cancelSettings()">Cancel</button>
+          </div>
+        </div>
+      </fieldset>
+    </form>
+  </div>
+</div>
+
 <div class="panel panel-default" ng-hide="isConfigurationEmpty">
   <div class="panel-heading clearfix">
     <h3 class="panel-title pull-left">Cluster Configuration</h3>
@@ -150,14 +179,21 @@
       <a href ng-switch-when="true" ng-hide="isConfigurationEmpty"  class="properties-toggle disabled"> <span class="glyphicon glyphicon-pencil"></span> Edit</a>
     </div>
   </div>
-  <div class="panel-body property-form cluster-configurable-form" popover="{{clusterConfigurableErrorMsg}}" popover-trigger="mouseenter">
+  <div class="panel-body property-form" popover="{{clusterConfigurableErrorMsg}}" popover-trigger="mouseenter">
     <div class="checkbox">
       <label>
         <input type="radio" ng-model="$parent.isLocalCluster" ng-disabled="!clusterConfigurable || editConfigurationDisabled || noClusterAvailible" ng-value="true" class="visibilityCheckbox"> Local Ambari Managed Cluster
       </label>
     </div>
-    <div class="form-group sub-group">
-      <select ng-model="cluster" ng-disabled="!$parent.isLocalCluster || editConfigurationDisabled" ng-change="onClusterChange()" class="clusters-name-dropdown form-control"  ng-options="o as o for o in clusters"></select>
+    <div class="form-horizontal property-form">
+      <div class="form-group">
+        <label for="" class="control-label col-sm-3 ng-binding not-required" >Cluster Name</label>
+        <div>
+          <div class="col-sm-9">
+            <select ng-model="cluster" ng-disabled="!$parent.isLocalCluster || editConfigurationDisabled" ng-change="onClusterChange()" class="clusters-name-dropdown form-control"  ng-options="o as o for o in clusters"></select>
+          </div>
+        </div>
+      </div>
     </div>
     <p>&nbsp</p>
     <div class="checkbox">
@@ -169,14 +205,14 @@
   <div class="panel-body edit-view-custom-wrap">
     <form name="propertiesForm" class="form-horizontal property-form" ng-hide="isConfigurationEmpty" novalidate>
       <fieldset>
-        <div class="form-group sub-group" ng-repeat="property in configurationMeta | filter:{clusterConfig:true}" ng-class="{'has-error' : (!editConfigurationDisabled && ((property.required && propertiesForm[property.name].$error.required && !editConfigurationDisabled) || propertiesForm[property.name].validationError))}">
+        <div class="form-group" ng-repeat="property in configurationMeta | filter:{clusterConfig:true}" ng-class="{'has-error' : (!editConfigurationDisabled && ((property.required && propertiesForm[property.name].$error.required && !editConfigurationDisabled) || propertiesForm[property.name].validationError))}">
           <label for="" class="control-label col-sm-3" ng-class="{'not-required': !property.required}">{{property.label || property.displayName}}{{property.required ? '*' : ''}}</label>
           <div ng-switch="property.type">
             <div class="col-sm-9 checkbox" ng-switch-when="boolean">
-              <input type="checkbox" class="propertie-input" ng-disabled="editConfigurationDisabled" name="{{property.name}}" ng-model="configuration[property.name]" ng-true-value="true" ng-false-value="false" popover="{{property.description}}" popover-title="{{property.name}}" popover-trigger="mouseenter">
+              <input type="checkbox" class="propertie-input" ng-disabled="isLocalCluster || editConfigurationDisabled" name="{{property.name}}" ng-model="configuration[property.name]" ng-true-value="true" ng-false-value="false" popover="{{property.description}}" popover-title="{{property.name}}" popover-trigger="mouseenter">
             </div>
             <div class="col-sm-9" ng-switch-default>
-              <input type="{{property.masked ? 'password' : 'text'}}" class="form-control propertie-input" ng-required="property.required" ng-change="propertiesForm[property.name].validationError=''" ng-disabled="editConfigurationDisabled" name="{{property.name}}" ng-model="configuration[property.name]" popover="{{property.description}}" popover-title="{{property.name}}" popover-trigger="mouseenter" placeholder="{{property.placeholder}}">
+              <input type="{{property.masked ? 'password' : 'text'}}" class="form-control propertie-input" ng-required="property.required" ng-change="propertiesForm[property.name].validationError=''" ng-disabled="isLocalCluster || editConfigurationDisabled" name="{{property.name}}" ng-model="configuration[property.name]" popover="{{property.description}}" popover-title="{{property.name}}" popover-trigger="mouseenter" placeholder="{{property.placeholder}}">
               <div class="alert alert-danger no-margin-bottom top-margin" ng-show='property.required && propertiesForm[property.name].$error.required && !editConfigurationDisabled'>
                 This field is required.
               </div>