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/04/17 05:18:04 UTC
ambari git commit: AMBARI-10544. Views: FE work for adding the
ability for a view instance to be associated to a cluster for configuration
(alexantonenko)
Repository: ambari
Updated Branches:
refs/heads/trunk 23f7428a0 -> 68c68a6f0
AMBARI-10544. Views: FE work for adding the ability for a view instance to be associated to a cluster for configuration (alexantonenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/68c68a6f
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/68c68a6f
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/68c68a6f
Branch: refs/heads/trunk
Commit: 68c68a6f0eb09f0bbdd530c9c9e1baa8dbfa9828
Parents: 23f7428
Author: Alex Antonenko <hi...@gmail.com>
Authored: Fri Apr 17 06:17:28 2015 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Fri Apr 17 06:17:28 2015 +0300
----------------------------------------------------------------------
.../ambariViews/CreateViewInstanceCtrl.js | 37 ++++-
.../controllers/ambariViews/ViewsEditCtrl.js | 149 +++++++++++++------
.../ui/admin-web/app/scripts/services/View.js | 37 +++--
.../resources/ui/admin-web/app/styles/main.css | 28 +++-
.../admin-web/app/views/ambariViews/create.html | 68 ++++++---
.../admin-web/app/views/ambariViews/edit.html | 63 ++++++--
6 files changed, 284 insertions(+), 98 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/68c68a6f/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js
index 2492c91..e6c047b 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js
@@ -18,22 +18,28 @@
'use strict';
angular.module('ambariAdminConsole')
-.controller('CreateViewInstanceCtrl',['$scope', 'View', 'Alert', '$routeParams', '$location', 'UnsavedDialog', function($scope, View, Alert, $routeParams, $location, UnsavedDialog) {
+.controller('CreateViewInstanceCtrl',['$scope', 'View', 'Alert', 'Cluster', '$routeParams', '$location', 'UnsavedDialog', function($scope, View, Alert, Cluster, $routeParams, $location, UnsavedDialog) {
$scope.form = {};
var targetUrl = '';
function loadMeta(){
View.getMeta($routeParams.viewId, $scope.version).then(function(data) {
- var viewVersion = data.data;
- $scope.view = viewVersion;
+ var viewVersion = data.data,
+ parameters;
- var parameters = viewVersion.ViewVersionInfo.parameters;
+ $scope.view = viewVersion;
+ parameters = viewVersion.ViewVersionInfo.parameters;
angular.forEach(parameters, function (item) {
item.value = item['defaultValue'];
+ item.clusterConfig = !!item.clusterConfig;
item.displayName = item.name.replace(/\./g, '\.\u200B');
+ $scope.numberOfClusterConfigs = item.clusterConfig ? $scope.numberOfClusterConfigs+1 : $scope.numberOfClusterConfigs;
});
+ $scope.clusterConfigurable = viewVersion.ViewVersionInfo.cluster_configurable;
+ $scope.clusterConfigurableErrorMsg = $scope.clusterConfigurable ? "" : "This view cannot use this option";
+
$scope.instance = {
view_name: viewVersion.ViewVersionInfo.view_name,
version: viewVersion.ViewVersionInfo.version,
@@ -43,7 +49,8 @@ angular.module('ambariAdminConsole')
icon_path: '',
icon64_path: '',
properties: parameters,
- description: ''
+ description: '',
+ isLocalCluster: false
};
});
}
@@ -61,6 +68,25 @@ angular.module('ambariAdminConsole')
$scope.isAdvancedClosed = true;
$scope.instanceExists = false;
+ $scope.clusterConfigurable = false;
+ $scope.clusterConfigurableErrorMsg = "";
+ $scope.clusters = [];
+ $scope.noClusterAvailible = true;
+ $scope.cluster = null;
+ $scope.numberOfClusterConfigs = 0;
+
+ Cluster.getAllClusters().then(function (clusters) {
+ if(clusters.length >0){
+ clusters.forEach(function(cluster) {
+ $scope.clusters.push(cluster.Clusters.cluster_name)
+ });
+ $scope.noClusterAvailible = false;
+ }else{
+ $scope.clusters.push("No Clusters");
+ }
+ $scope.cluster = $scope.clusters[0];
+ });
+
$scope.versions = [];
$scope.version = null;
@@ -77,6 +103,7 @@ angular.module('ambariAdminConsole')
$scope.form.instanceCreateForm.submitted = true;
if($scope.form.instanceCreateForm.$valid){
$scope.form.instanceCreateForm.isSaving = true;
+ $scope.instance.clusterName = $scope.cluster;
View.createInstance($scope.instance)
.then(function(data) {
Alert.success('Created View Instance ' + $scope.instance.instance_name);
http://git-wip-us.apache.org/repos/asf/ambari/blob/68c68a6f/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 cbf3b0c..ab1d948 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
@@ -18,7 +18,7 @@
'use strict';
angular.module('ambariAdminConsole')
-.controller('ViewsEditCtrl', ['$scope', '$routeParams' , 'View', 'Alert', 'PermissionLoader', 'PermissionSaver', 'ConfirmationModal', '$location', 'UnsavedDialog', function($scope, $routeParams, View, Alert, PermissionLoader, PermissionSaver, ConfirmationModal, $location, UnsavedDialog) {
+.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(){
@@ -33,8 +33,15 @@ angular.module('ambariAdminConsole')
'description': $scope.instance.ViewInstanceInfo.description
};
- initConfigurations();
- $scope.isConfigurationEmpty = angular.equals({}, $scope.configuration);
+ 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";
+ }
+ $scope.isConfigurationEmpty = !$scope.numberOfClusterConfigs;
})
.catch(function(data) {
Alert.error('Cannot load instance info', data.data.message);
@@ -53,8 +60,12 @@ angular.module('ambariAdminConsole')
// Get META for properties
View.getMeta($routeParams.viewId, $routeParams.version).then(function(data) {
$scope.configurationMeta = data.data.ViewVersionInfo.parameters;
+ $scope.clusterConfigurable = data.data.ViewVersionInfo.cluster_configurable;
+ $scope.clusterConfigurableErrorMsg = $scope.clusterConfigurable ? "" : "This view cannot use this option";
angular.forEach($scope.configurationMeta, function (item) {
item.displayName = item.name.replace(/\./g, '\.\u200B');
+ item.clusterConfig = !!item.clusterConfig;
+ $scope.numberOfClusterConfigs = $scope.numberOfClusterConfigs + !!item.clusterConfig;
});
reloadViewInfo();
});
@@ -80,20 +91,57 @@ angular.module('ambariAdminConsole')
reloadViewPrivileges();
- $scope.editSettingsDisabled = true;
+ $scope.clusterConfigurable = false;
+ $scope.clusterConfigurableErrorMsg = "";
+ $scope.clusters = [];
+ $scope.cluster = null;
+ $scope.noClusterAvailible = true;
+
+
+ $scope.editSettingsDisabled = true;
+ $scope.numberOfClusterConfigs = 0;
+
$scope.toggleSettingsEdit = function() {
$scope.editSettingsDisabled = !$scope.editSettingsDisabled;
+ $scope.settingsBeforeEdit = angular.copy($scope.configuration);
+ $scope.configurationMeta.forEach(function (element) {
+ if (element.masked && !$scope.editSettingsDisabled && !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) {
+ $scope.clusters.push(cluster.Clusters.cluster_name)
+ });
+ $scope.noClusterAvailible = false;
+ }else{
+ $scope.clusters.push("No Clusters");
+ }
+ $scope.cluster = $scope.clusters[0];
+ });
+
$scope.saveSettings = function(callback) {
if( $scope.settingsForm.$valid ){
- return View.updateInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId, {
+ var data = {
'ViewInstanceInfo':{
'visible': $scope.settings.visible,
'label': $scope.settings.label,
- 'description': $scope.settings.description
+ 'description': $scope.settings.description,
+ 'properties':{}
}
- })
+ };
+ $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() {
if( callback ){
callback();
@@ -114,6 +162,7 @@ angular.module('ambariAdminConsole')
'label': $scope.instance.ViewInstanceInfo.label,
'description': $scope.instance.ViewInstanceInfo.description
};
+ angular.extend($scope.configuration, $scope.settingsBeforeEdit);
$scope.editSettingsDisabled = true;
$scope.settingsForm.$setPristine();
};
@@ -123,50 +172,62 @@ angular.module('ambariAdminConsole')
$scope.togglePropertiesEditing = function () {
$scope.editConfigurationDisabled = !$scope.editConfigurationDisabled;
$scope.configurationBeforeEdit = angular.copy($scope.configuration);
- if (!$scope.editConfigurationDisabled) {
+ $scope.configurationMeta.forEach(function (element) {
+ if (element.masked && !$scope.editConfigurationDisabled && element.clusterConfig) {
+ $scope.configuration[element.name] = '';
+ }
+ if(!element.clusterConfig) {
+ delete $scope.configurationBeforeEdit[element.name];
+ }
+ });
+ };
+ $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.masked) {
- $scope.configuration[element.name] = '';
+ if(element.clusterConfig) {
+ data.ViewInstanceInfo.properties[element.name] = $scope.configuration[element.name];
}
});
}
- };
- $scope.saveConfiguration = function() {
- return View.updateInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId, {
- 'ViewInstanceInfo':{
- 'properties': $scope.configuration
- }
- })
- .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("\{"));
-
- 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);
- }
+ 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("\{"));
+
+ 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() {
- $scope.configuration = angular.copy($scope.configurationBeforeEdit);
+ angular.extend($scope.configuration, $scope.configurationBeforeEdit);
$scope.editConfigurationDisabled = true;
$scope.propertiesForm.$setPristine();
};
http://git-wip-us.apache.org/repos/asf/ambari/blob/68c68a6f/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js
index 06a9e8f..7bf1672 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js
@@ -159,26 +159,39 @@ angular.module('ambariAdminConsole')
};
View.createInstance = function(instanceInfo) {
- var deferred = $q.defer();
- var properties = {};
+ var deferred = $q.defer(),
+ properties = {},
+ settings = {},
+ data = {
+ instance_name: instanceInfo.instance_name,
+ label: instanceInfo.label,
+ visible: instanceInfo.visible,
+ icon_path: instanceInfo.icon_path,
+ icon64_path: instanceInfo.icon64_path,
+ description: instanceInfo.description
+ };
angular.forEach(instanceInfo.properties, function(property) {
- properties[property.name] = property.value
+ if(property.clusterConfig) {
+ properties[property.name] = property.value
+ }else {
+ settings[property.name] = property.value
+ }
});
+ data.properties = settings;
+
+ if(instanceInfo.isLocalCluster) {
+ data.cluster_handle = instanceInfo.clusterName;
+ } else {
+ angular.extend(data.properties, properties);
+ }
+
$http({
method: 'POST',
url: Settings.baseUrl + '/views/' + instanceInfo.view_name +'/versions/'+instanceInfo.version + '/instances/'+instanceInfo.instance_name,
data:{
- 'ViewInstanceInfo' : {
- instance_name: instanceInfo.instance_name,
- label: instanceInfo.label,
- visible: instanceInfo.visible,
- icon_path: instanceInfo.icon_path,
- icon64_path: instanceInfo.icon64_path,
- properties: properties,
- description: instanceInfo.description
- }
+ 'ViewInstanceInfo' : data
}
})
.success(function(data) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/68c68a6f/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 5b82129..d273d07 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
@@ -127,7 +127,7 @@
display: block;
color: #888;
text-align: center;
- padding: 10px 0px;
+ padding: 10px 0;
cursor: default;
}
@@ -239,7 +239,7 @@
margin-left: 20px;
margin-right: 10px;
border: none;
- border-radius: 0px;
+ border-radius: 0;
}
.mainpage .panel-body #main-operations-boxes .thumbnail .title,
.mainpage .panel-body #main-operations-boxes .thumbnail .description,
@@ -533,7 +533,7 @@ a.gotoinstance{
padding-left: 33px;
padding-top: 8px;
padding-bottom: 8px;
- margin: 0px;
+ margin: 0;
}
.left-navbar .panel-body li.active a{
background: #666;
@@ -657,7 +657,7 @@ table.no-border tr td{
}
.property-form label{
- width: 214px;
+ width: 254px;
word-wrap: break-word;
text-overflow: ellipsis;
overflow: hidden;
@@ -1178,7 +1178,6 @@ button.btn.btn-xs{
border-radius: 50%;
vertical-align: middle;
position: relative;
- border-radius: 50%;
}
.viewstatus.pending:before, .viewstatus.pending:after{
@@ -1319,4 +1318,23 @@ accordion .panel-group .panel{
}
.verison-label-row .label {
font-size: 100%;
+}
+
+.panel-body .sub-group {
+ 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;
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/68c68a6f/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 772abae..08e4f26 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
@@ -23,14 +23,14 @@
<form class="form-horizontal create-view-form" role="form" name="form.instanceCreateForm" novalidate>
<div class="view-header">
<div class="form-group">
- <div class="col-sm-2">
+ <div class="col-sm-3">
<label for="" class="control-label">View</label>
</div>
<div class="col-sm-10"><label for="" class="control-label">{{view.ViewVersionInfo.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-2">
+ <div class="col-sm-3"><label for="" class="control-label">Version</label></div>
+ <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>
@@ -38,14 +38,14 @@
<div class="panel panel-default">
<div class="panel-heading">
- <h3 class="panel-title">Details</h3>
+ <h3 class="panel-title">Settings</h3>
</div>
<div class="panel-body">
<div class="form-group"
ng-class="{'has-error' : ( (form.instanceCreateForm.instanceNameInput.$error.required || form.instanceCreateForm.instanceNameInput.$error.pattern) && form.instanceCreateForm.submitted) || instanceExists }"
>
- <label for="" class="control-label col-sm-2">Instance Name</label>
- <div class="col-sm-10">
+ <label for="" class="control-label col-sm-3">Instance Name</label>
+ <div class="col-sm-9">
<input type="text" class="form-control instancename-input" name="instanceNameInput" ng-pattern="nameValidationPattern" required ng-model="instance.instance_name" autocomplete="off">
<div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm.instanceNameInput.$error.required && form.instanceCreateForm.submitted'>
@@ -61,8 +61,8 @@
</div>
<div class="form-group"
ng-class="{'has-error' : ( (form.instanceCreateForm.displayLabel.$error.required || form.instanceCreateForm.displayLabel.$error.pattern) && form.instanceCreateForm.submitted)}">
- <label for="" class="control-label col-sm-2">Display Name</label>
- <div class="col-sm-10">
+ <label for="" class="control-label col-sm-3">Display Name</label>
+ <div class="col-sm-9">
<input type="text" class="form-control instancelabel-input" name="displayLabel" ng-model="instance.label" required ng-pattern="/^([a-zA-Z0-9._\s]+)$/" autocomplete="off">
<div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm.displayLabel.$error.required && form.instanceCreateForm.submitted'>
@@ -74,16 +74,34 @@
</div>
</div>
<div class="form-group" ng-class="{'has-error' : form.instanceCreateForm.description.$error.required && form.instanceCreateForm.submitted }">
- <label for="" class="control-label col-sm-2">Description</label>
- <div class="col-sm-10">
+ <label for="" class="control-label col-sm-3">Description</label>
+ <div class="col-sm-9">
<input type="text" class="form-control" name="description" ng-model="instance.description" maxlength="140" required>
<div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm.description.$error.required && form.instanceCreateForm.submitted'>
This field is required.
</div>
</div>
</div>
+ <div class="form-group" ng-repeat="parameter in instance.properties | filter:{clusterConfig:false}"
+ 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">
+ <div class="col-sm-9 checkbox" ng-switch-when="boolean">
+ <input type="checkbox" class="viewproperty-input" name="{{parameter.name}}" ng-required="parameter.required" ng-model="parameter.value" popover="{{parameter.description}}" popover-title="{{parameter.name}}" popover-trigger="mouseenter">
+ </div>
+ <div class="col-sm-9" ng-switch-default>
+ <input type="{{parameter.masked ? 'password' : 'text'}}" class="form-control viewproperty-input" name="{{parameter.name}}" ng-change="form.instanceCreateForm[parameter.name].validationError=''" ng-required="parameter.required" ng-model="parameter.value" autocomplete="off" popover="{{parameter.description}}" popover-title="{{parameter.name}}" popover-trigger="mouseenter" placeholder="{{parameter.placeholder}}">
+ <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm[parameter.name].$error.required && form.instanceCreateForm.submitted'>
+ This field is required.
+ </div>
+ <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm[parameter.name].validationError'>
+ {{form.instanceCreateForm[parameter.name].validationMessage}}
+ </div>
+ </div>
+ </div>
+ </div>
<div class="form-group">
- <div class="col-sm-10 col-sm-offset-2">
+ <div class="col-sm-10 col-sm-offset-3">
<div class="checkbox">
<label>
<input type="checkbox" ng-model='instance.visible' class="visibilityCheckbox"> Visible
@@ -93,24 +111,40 @@
</div>
</div>
</div>
- <div class="panel panel-default">
+ <div class="panel panel-default" ng-hide="!numberOfClusterConfigs">
<div class="panel-heading">
- <h3 class="panel-title">Properties</h3>
+ <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">
+ <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>
</div>
<div class="panel-body property-form">
+ <div class="checkbox">
+ <label>
+ <input type="radio" ng-model="instance.isLocalCluster" ng-value="false" class="visibilityCheckbox"> Custom
+ </label>
+ </div>
<div class="alert alert-danger bottom-margin top-margin" ng-show='form.instanceCreateForm.generalValidationError'>
{{form.instanceCreateForm.generalValidationError}}
</div>
- <div class="form-group" ng-repeat="parameter in instance.properties"
+ <div class="form-group sub-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">
<div class="col-sm-9 checkbox" ng-switch-when="boolean">
- <input type="checkbox" class="viewproperty-input" name="{{parameter.name}}" ng-required="parameter.required" ng-model="parameter.value" popover="{{parameter.description}}" popover-title="{{parameter.name}}" popover-trigger="mouseenter">
+ <input type="checkbox" class="viewproperty-input" name="{{parameter.name}}" ng-disabled="instance.isLocalCluster" ng-required="parameter.required && instance.isLocalCluster" ng-model="parameter.value" popover="{{parameter.description}}" popover-title="{{parameter.name}}" popover-trigger="mouseenter">
</div>
<div class="col-sm-9" ng-switch-default>
- <input type="{{parameter.masked ? 'password' : 'text'}}" class="form-control viewproperty-input" name="{{parameter.name}}" ng-change="form.instanceCreateForm[parameter.name].validationError=''" ng-required="parameter.required" ng-model="parameter.value" autocomplete="off" popover="{{parameter.description}}" popover-title="{{parameter.name}}" popover-trigger="mouseenter" placeholder="{{parameter.placeholder}}">
- <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm[parameter.name].$error.required && form.instanceCreateForm.submitted'>
+ <input type="{{parameter.masked ? 'password' : 'text'}}" class="form-control viewproperty-input" name="{{parameter.name}}" ng-disabled="instance.isLocalCluster" ng-change="form.instanceCreateForm[parameter.name].validationError=''" ng-required="parameter.required && !instance.isLocalCluster" ng-model="parameter.value" autocomplete="off" popover="{{parameter.description}}" popover-title="{{parameter.name}}" popover-trigger="mouseenter" placeholder="{{parameter.placeholder}}">
+ <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm[parameter.name].$error.required && form.instanceCreateForm.submitted && !instance.isLocalCluster'>
This field is required.
</div>
<div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm[parameter.name].validationError'>
http://git-wip-us.apache.org/repos/asf/ambari/blob/68c68a6f/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 910b2ad..960222d 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
@@ -37,21 +37,21 @@
<div class="panel-body">
<form class="form-horizontal" name="settingsForm" novalidate>
<div class="form-group">
- <label for="" class="col-sm-2 control-label">View Name</label>
- <div class="col-sm-10"><input disabled="disabled" type="text" class="form-control instancename-input" placeholder="Display Name" value="{{instance.ViewInstanceInfo.view_name}}"></div>
+ <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-2 control-label">View Version</label>
- <div class="col-sm-10"><input disabled="disabled" type="text" class="form-control instancename-input" placeholder="Display Name" value="{{instance.ViewInstanceInfo.version}}"></div>
+ <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">
<div class="form-group">
- <label for="" class="col-sm-2 control-label">Instance Name</label>
- <div class="col-sm-10"><input disabled="disabled" type="text" class="form-control instancename-input" placeholder="Display Name" value="{{instance.ViewInstanceInfo.instance_name}}"></div>
+ <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}">
- <label for="" class="col-sm-2 control-label">Display Name</label>
- <div class="col-sm-10">
+ <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'>
This field is required.
@@ -62,16 +62,33 @@
</div>
</div>
<div class="form-group" ng-class="{'has-error' : settingsForm.description.$error.required && !editSettingsDisabled}">
- <label for="" class="control-label col-sm-2">Description</label>
- <div class="col-sm-10">
+ <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'>
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-2 col-sm-10">
+ <div class="col-sm-offset-3 col-sm-10">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="settings.visible" ng-class="instancevisibility-input"> Visible
@@ -125,18 +142,34 @@
</div>
</div>
-<div class="panel panel-default">
+<div class="panel panel-default" ng-hide="isConfigurationEmpty">
<div class="panel-heading clearfix">
- <h3 class="panel-title pull-left">Properties</h3>
+ <h3 class="panel-title pull-left">Cluster Configuration</h3>
<div class="pull-right" ng-switch="instance.ViewInstanceInfo.static">
<a href ng-switch-when="false" ng-hide="isConfigurationEmpty" ng-click="togglePropertiesEditing()" ng-show="editConfigurationDisabled" class="properties-toggle"> <span class="glyphicon glyphicon-pencil"></span> Edit</a>
<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">
+ <div class="panel-body property-form cluster-configurable-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>
+ <p> </p>
+ <div class="checkbox">
+ <label>
+ <input type="radio" ng-model="$parent.isLocalCluster" ng-disabled="editConfigurationDisabled" ng-value="false" class="visibilityCheckbox"> Custom
+ </label>
+ </div>
+ </div>
+ <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" ng-repeat="property in configurationMeta" ng-class="{'has-error' : (!editConfigurationDisabled && ((property.required && propertiesForm[property.name].$error.required && !editConfigurationDisabled) || propertiesForm[property.name].validationError))}">
+ <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))}">
<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">