You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by at...@apache.org on 2017/11/17 15:15:14 UTC
ambari git commit: AMBARI-22466 Ambari 3.0: Implement new design for
Admin View: Views page tweaks. (atkach)
Repository: ambari
Updated Branches:
refs/heads/trunk e95d34300 -> 430127b4b
AMBARI-22466 Ambari 3.0: Implement new design for Admin View: Views page tweaks. (atkach)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/430127b4
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/430127b4
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/430127b4
Branch: refs/heads/trunk
Commit: 430127b4b03513931d3d240d958516e412ed05de
Parents: e95d343
Author: Andrii Tkach <at...@apache.org>
Authored: Fri Nov 17 16:30:34 2017 +0200
Committer: Andrii Tkach <at...@apache.org>
Committed: Fri Nov 17 16:30:34 2017 +0200
----------------------------------------------------------------------
.../main/resources/ui/admin-web/app/index.html | 1 -
.../ambariViews/CloneViewInstanceCtrl.js | 274 -------------------
.../ambariViews/CreateViewInstanceCtrl.js | 103 ++++++-
.../controllers/ambariViews/ViewsListCtrl.js | 21 +-
.../ui/admin-web/app/scripts/i18n.config.js | 2 +-
.../ui/admin-web/app/scripts/routes.js | 6 -
.../ui/admin-web/app/scripts/services/View.js | 8 +-
.../resources/ui/admin-web/app/styles/main.css | 70 +----
.../resources/ui/admin-web/app/styles/views.css | 82 +++++-
.../admin-web/app/views/ambariViews/create.html | 200 --------------
.../app/views/ambariViews/modals/create.html | 261 +++++++++++-------
.../app/views/ambariViews/viewsList.html | 41 ++-
.../ui/admin-web/app/views/urls/create.html | 2 -
.../ui/admin-web/app/views/urls/edit.html | 2 -
.../unit/controllers/CloneViewInstanceCtrl.js | 135 ---------
15 files changed, 391 insertions(+), 817 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/430127b4/ambari-admin/src/main/resources/ui/admin-web/app/index.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/index.html b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
index 2b350f0..4a77e62 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/index.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
@@ -139,7 +139,6 @@
<script src="scripts/controllers/ambariViews/ViewUrlCtrl.js"></script>
<script src="scripts/controllers/ambariViews/ViewUrlEditCtrl.js"></script>
<script src="scripts/controllers/ambariViews/CreateViewInstanceCtrl.js"></script>
-<script src="scripts/controllers/ambariViews/CloneViewInstanceCtrl.js"></script>
<script src="scripts/controllers/clusters/ClustersManageAccessCtrl.js"></script>
<script src="scripts/controllers/clusters/UserAccessListCtrl.js"></script>
<script src="scripts/controllers/stackVersions/StackVersionsCreateCtrl.js"></script>
http://git-wip-us.apache.org/repos/asf/ambari/blob/430127b4/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CloneViewInstanceCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CloneViewInstanceCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CloneViewInstanceCtrl.js
deleted file mode 100644
index cb37e63..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CloneViewInstanceCtrl.js
+++ /dev/null
@@ -1,274 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-'use strict';
-
-angular.module('ambariAdminConsole')
-.controller('CloneViewInstanceCtrl',['$scope', 'View','RemoteCluster' , 'Alert', 'Cluster', '$routeParams', '$location', 'UnsavedDialog', '$translate', function($scope, View, RemoteCluster, Alert, Cluster, $routeParams, $location, UnsavedDialog, $translate) {
- var $t = $translate.instant;
- $scope.form = {};
- $scope.constants = {
- props: $t('views.properties')
- };
- $scope.isClone = $routeParams.instanceId ? true : false;
- var targetUrl = '';
-
- function loadMeta(){
- View.getMeta($routeParams.viewId, $scope.version).then(function(data) {
- var viewVersion = data.data,
- 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');
- item.clusterConfig ? $scope.numberOfClusterConfigs++ : $scope.numberOfSettingConfigs++;
- });
-
- $scope.clusterConfigurable = viewVersion.ViewVersionInfo.cluster_configurable;
- $scope.clusterConfigurableErrorMsg = $scope.clusterConfigurable ? "" : $t('views.alerts.cannotUseOption');
-
- $scope.instance = {
- view_name: viewVersion.ViewVersionInfo.view_name,
- version: viewVersion.ViewVersionInfo.version,
- instance_name: '',
- label: '',
- visible: true,
- icon_path: '',
- icon64_path: '',
- properties: parameters,
- description: '',
- clusterType: 'NONE'
- };
-
- //if cloning view instance, then get the instance data and populate settings and properties
- if($scope.isClone) {
- View.getInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId)
- .then(function(instance) {
- $scope.instanceClone = instance;
- $scope.instance.version = instance.ViewInstanceInfo.version;
- $scope.version = instance.ViewInstanceInfo.version;
- $scope.instance.instance_name = instance.ViewInstanceInfo.instance_name + $t('common.copy');
- $scope.instance.label = instance.ViewInstanceInfo.label + $t('common.copy');
- $scope.instance.visible = instance.ViewInstanceInfo.visible;
- $scope.instance.description = instance.ViewInstanceInfo.description;
- $scope.instance.clusterType=instance.ViewInstanceInfo.cluster_type;
-
- initConfigurations(parameters);
- })
- .catch(function(data) {
- Alert.error($t('views.alerts.cannotLoadInstanceInfo'), data.data.message);
- });
- }
-
- loadClusters();
- loadRemoteClusters();
-
- });
- }
-
- function initConfigurations(parameters) {
- var configuration = angular.copy($scope.instanceClone.ViewInstanceInfo.properties);
-
- //iterate through the view parameters and get the values from the instance being cloned
- for (var i = 0; i < parameters.length; i++) {
- parameters[i].value = configuration[parameters[i].name];
- parameters[i].clusterConfig = !!parameters[i].clusterConfig;
- }
- }
-
- $scope.$watch(function(scope) {
- return scope.version;
- }, function(version) {
- if( version ){
- loadMeta();
- }
- });
-
- $scope.enableLocalCluster = function () {
- if($scope.errorKeys.length > 0) {
- $scope.errorKeys.forEach( function (key) {
- try {
- $scope.form.instanceCreateForm[key].validationError = false;
- $scope.form.instanceCreateForm[key].validationMessage = '';
- } catch (e) {
- console.log($t('views.alerts.unableToResetErrorMessage', {key: key}));
- }
- });
- $scope.errorKeys = [];
- }
- };
-
- // $scope.view = viewVersion;
- $scope.isAdvancedClosed = true;
- $scope.instanceExists = false;
- $scope.errorKeys = [];
-
- $scope.clusterConfigurable = false;
- $scope.clusterConfigurableErrorMsg = "";
- $scope.clusters = [];
- $scope.remoteClusters = [];
- $scope.noLocalClusterAvailible = true;
- $scope.noRemoteClusterAvailible = true;
- $scope.cluster = null;
- $scope.data = {};
- $scope.data.remoteCluster = null;
- $scope.numberOfClusterConfigs = 0;
- $scope.numberOfSettingConfigs = 0;
-
- function loadClusters() {
- Cluster.getAllClusters().then(function (clusters) {
- if(clusters.length >0){
- clusters.forEach(function(cluster) {
- $scope.clusters.push({
- "name" : cluster.Clusters.cluster_name,
- "id" : cluster.Clusters.cluster_id
- })
- });
- $scope.noLocalClusterAvailible = false;
- //do not set to default Local Cluster configuration when cloning instance
- if($scope.clusterConfigurable && !$scope.isClone){
- $scope.instance.clusterType = "LOCAL_AMBARI";
- }
- }else{
- $scope.clusters.push($t('common.noClusters'));
- }
- $scope.cluster = $scope.clusters[0];
- });
- }
-
- function loadRemoteClusters() {
- RemoteCluster.listAll().then(function (clusters) {
- if(clusters.length >0){
- clusters.forEach(function(cluster) {
- $scope.remoteClusters.push({
- "name" : cluster.ClusterInfo.name,
- "id" : cluster.ClusterInfo.cluster_id
- })
- });
- $scope.noRemoteClusterAvailible = false;
- }else{
- $scope.remoteClusters.push($t('common.noClusters'));
- }
- $scope.data.remoteCluster = $scope.remoteClusters[0];
- });
- }
-
-
- $scope.versions = [];
- $scope.version = null;
-
- View.getVersions($routeParams.viewId).then(function(versions) {
- $scope.versions = versions;
- $scope.version = $scope.versions[$scope.versions.length-1];
- });
-
-
- $scope.nameValidationPattern = /^\s*\w*\s*$/;
-
- $scope.save = function() {
- if (!$scope.form.instanceCreateForm.isSaving) {
- $scope.form.instanceCreateForm.submitted = true;
- if($scope.form.instanceCreateForm.$valid){
- $scope.form.instanceCreateForm.isSaving = true;
-
- switch($scope.instance.clusterType) {
- case 'LOCAL_AMBARI':
- console.log($scope.cluster);
- $scope.instance.clusterId = $scope.cluster.id;
- break;
- case 'REMOTE_AMBARI':
- console.log($scope.data.remoteCluster);
- $scope.instance.clusterId = $scope.data.remoteCluster.id;
-
- break;
- default:
- $scope.instance.clusterId = null;
- }
- console.log($scope.instance.clusterId);
- View.createInstance($scope.instance)
- .then(function(data) {
- Alert.success($t('views.alerts.instanceCreated', {instanceName: $scope.instance.instance_name}));
- $scope.form.instanceCreateForm.$setPristine();
- if( targetUrl ){
- $location.path(targetUrl);
- } else {
- $location.path('/views/' + $scope.instance.view_name + '/versions/' + $scope.instance.version + '/instances/' + $scope.instance.instance_name + '/edit');
- }
- $scope.form.instanceCreateForm.isSaving = false;
- $scope.$root.$emit('instancesUpdate');
- })
- .catch(function (data) {
- var errorMessage = data.message;
- var showGeneralError = true;
-
- if (data.status >= 400 && $scope.instance.clusterType == 'NONE') {
- try {
- var errorObject = JSON.parse(errorMessage);
- errorMessage = errorObject.detail;
- angular.forEach(errorObject.propertyResults, function (item, key) {
- $scope.form.instanceCreateForm[key].validationError = !item.valid;
- if (!item.valid) {
- showGeneralError = false;
- $scope.form.instanceCreateForm[key].validationMessage = item.detail;
- $scope.errorKeys.push(key);
- }
- });
-
- if (showGeneralError) {
- $scope.form.instanceCreateForm.generalValidationError = errorMessage;
- }
- } catch (e) {
- console.error($t('views.alerts.unableToParseError', {message: data.message}));
- }
- }
- Alert.error($t('views.alerts.cannotCreateInstance'), errorMessage);
- $scope.form.instanceCreateForm.isSaving = false;
- });
- }
- }
- };
-
- $scope.cancel = function() {
- $scope.form.instanceCreateForm.$setPristine();
- $location.path('/views');
- };
-
- $scope.$on('$locationChangeStart', function(event, __targetUrl) {
- if( $scope.form.instanceCreateForm.$dirty ){
- UnsavedDialog().then(function(action) {
- targetUrl = __targetUrl.split('#').pop();
- switch(action){
- case 'save':
- $scope.save();
- break;
- case 'discard':
- $scope.form.instanceCreateForm.$setPristine();
- $location.path(targetUrl);
- break;
- case 'cancel':
- targetUrl = '';
- break;
- }
- });
- event.preventDefault();
- }
- });
-}]);
http://git-wip-us.apache.org/repos/asf/ambari/blob/430127b4/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 d5e3758..1199313 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
@@ -19,8 +19,8 @@
angular.module('ambariAdminConsole')
.controller('CreateViewInstanceCtrl',
-['$scope', 'View','RemoteCluster' , 'Alert', 'Cluster', '$routeParams', '$location', 'UnsavedDialog', '$translate', '$modalInstance', 'views', '$q',
-function($scope, View, RemoteCluster, Alert, Cluster, $routeParams, $location, UnsavedDialog, $translate, $modalInstance, views, $q) {
+['$scope', 'View','RemoteCluster' , 'Alert', 'Cluster', '$routeParams', '$location', 'UnsavedDialog', '$translate', '$modalInstance', 'views', 'instanceClone', '$q',
+function($scope, View, RemoteCluster, Alert, Cluster, $routeParams, $location, UnsavedDialog, $translate, $modalInstance, views, instanceClone, $q) {
var $t = $translate.instant;
var viewToVersionMap = {};
@@ -28,14 +28,20 @@ function($scope, View, RemoteCluster, Alert, Cluster, $routeParams, $location, U
$scope.form = {};
$scope.nameValidationPattern = /^\s*\w*\s*$/;
$scope.isLoading = false;
- $scope.isLocalTypeChosen = true;
+ $scope.clusterType = 'LOCAL_AMBARI'; // LOCAL_AMBARI, REMOTE_AMBARI, NONE
$scope.views = views;
+ $scope.instanceClone = instanceClone;
$scope.viewOptions = [];
$scope.versionOptions = [];
$scope.localClusters = [];
$scope.remoteClusters = [];
$scope.clusterOptions = [];
+ $scope.fieldsWithErrors = [];
$scope.isInstanceExists = false;
+ $scope.clusterConfigurable = false;
+ $scope.clusterSettingsCount = 0;
+ $scope.nonClusterSettingsCount = 0;
+ $scope.instanceTemplate = null;
$scope.formData = {
view: null,
version: null,
@@ -43,22 +49,52 @@ function($scope, View, RemoteCluster, Alert, Cluster, $routeParams, $location, U
displayName: '',
description: '',
clusterName: null,
- visible: true
+ visible: true,
+ settings: []
};
$scope.updateVersionOptions = function () {
if (viewToVersionMap[$scope.formData.view.value]) {
$scope.versionOptions = viewToVersionMap[$scope.formData.view.value];
$scope.formData.version = $scope.versionOptions[0];
+ $scope.updateSettingsList();
}
};
- $scope.switchClusterType = function(bool) {
- $scope.isLocalTypeChosen = bool;
- if ($scope.isLocalTypeChosen) {
+ $scope.updateSettingsList = function() {
+ $scope.formData.settings = [];
+ $scope.clusterSettingsCount = 0;
+ $scope.nonClusterSettingsCount = 0;
+ $scope.instanceTemplate = null;
+ angular.forEach($scope.views, function(view) {
+ if (view.view_name === $scope.formData.view.value) {
+ angular.forEach(view.versionsList, function(version) {
+ if (version.ViewVersionInfo.version === $scope.formData.version.value) {
+ $scope.formData.settings = version.ViewVersionInfo.parameters.map(function(param) {
+ param.value = param['defaultValue'];
+ param.clusterConfig = Boolean(param.clusterConfig);
+ param.displayName = param.name.replace(/\./g, '\.\u200B');
+ $scope.clusterSettingsCount += param.clusterConfig;
+ $scope.nonClusterSettingsCount += !param.clusterConfig;
+ return param;
+ });
+ $scope.clusterConfigurable = version.ViewVersionInfo.cluster_configurable;
+ }
+ });
+ }
+ });
+ };
+
+ $scope.switchClusterType = function(clusterType) {
+ $scope.clusterType = clusterType;
+ if (clusterType === 'LOCAL_AMBARI') {
$scope.clusterOptions = $scope.localClusters;
- } else {
+ resetErrors();
+ } else if (clusterType === 'REMOTE_AMBARI') {
$scope.clusterOptions = $scope.remoteClusters;
+ resetErrors();
+ } else {
+ $scope.clusterOptions = [];
}
$scope.formData.clusterName = $scope.clusterOptions[0];
};
@@ -76,9 +112,9 @@ function($scope, View, RemoteCluster, Alert, Cluster, $routeParams, $location, U
description: $scope.form.instanceCreateForm.description.$viewValue,
view_name: $scope.form.instanceCreateForm.view.$viewValue.value,
version: $scope.form.instanceCreateForm.version.$viewValue.value,
- properties: [],
- clusterId: $scope.form.instanceCreateForm.clusterName.$viewValue.id,
- clusterType: $scope.isLocalTypeChosen ? 'LOCAL_AMBARI': 'REMOTE_AMBARI'
+ properties: $scope.formData.settings,
+ clusterId: $scope.formData.clusterName ? $scope.formData.clusterName.id : null,
+ clusterType: $scope.clusterType
})
.then(function () {
$modalInstance.dismiss('created');
@@ -92,7 +128,16 @@ function($scope, View, RemoteCluster, Alert, Cluster, $routeParams, $location, U
if (data.status >= 400) {
try {
- errorMessage = JSON.parse(errorMessage).detail;
+ var errorObject = JSON.parse(errorMessage);
+ errorMessage = errorObject.detail;
+ angular.forEach(errorObject.propertyResults, function (item, key) {
+ $scope.form.instanceCreateForm[key].validationError = !item.valid;
+ if (!item.valid) {
+ $scope.form.instanceCreateForm[key].validationMessage = item.detail;
+ $scope.fieldsWithErrors.push(key);
+ }
+ });
+
} catch (e) {
console.warn(data.message, e);
}
@@ -110,6 +155,14 @@ function($scope, View, RemoteCluster, Alert, Cluster, $routeParams, $location, U
$scope.isInstanceExists = Boolean(instances[$scope.formData.instanceName]);
};
+ function resetErrors() {
+ $scope.fieldsWithErrors.forEach(function(field) {
+ $scope.form.instanceCreateForm[field].validationError = false;
+ $scope.form.instanceCreateForm[field].validationMessage = '';
+ });
+ $scope.fieldsWithErrors = [];
+ }
+
function initViewAndVersionSelect () {
$scope.viewOptions = [];
angular.forEach($scope.views, function(view) {
@@ -160,10 +213,34 @@ function($scope, View, RemoteCluster, Alert, Cluster, $routeParams, $location, U
initViewAndVersionSelect();
$q.all(loadClusters(), loadRemoteClusters()).then(function() {
$scope.isLoading = false;
- $scope.switchClusterType(true);
+ $scope.switchClusterType('LOCAL_AMBARI');
+ copyCloneInstanceInfo();
});
}
+ function copyCloneInstanceInfo() {
+ if ($scope.instanceClone) {
+ $scope.formData.view = $scope.viewOptions.filter(function(option) {
+ return option.value === $scope.instanceClone.view_name;
+ })[0];
+ $scope.updateVersionOptions();
+ $scope.formData.version = $scope.versionOptions.filter(function(option) {
+ return option.value === $scope.instanceClone.version;
+ })[0];
+ $scope.formData.instanceName = $scope.instanceClone.instance_name + $t('common.copy');
+ $scope.formData.displayName = $scope.instanceClone.label + $t('common.copy');
+ $scope.formData.description = $scope.instanceClone.description;
+ $scope.formData.visible = $scope.instanceClone.visible;
+ $scope.switchClusterType($scope.instanceClone.cluster_type);
+ $scope.updateSettingsList();
+ $scope.formData.settings.forEach(function (setting) {
+ if ($scope.instanceClone.properties[setting.name]) {
+ setting.value = $scope.instanceClone.properties[setting.name];
+ }
+ });
+ }
+ }
+
function unsavedChangesCheck() {
if ($scope.form.instanceCreateForm.$dirty) {
UnsavedDialog().then(function (action) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/430127b4/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
index aba5702..aa77b63 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
@@ -54,15 +54,15 @@ angular.module('ambariAdminConsole')
$scope.views = views;
$scope.instances = [];
angular.forEach(views, function (view) {
- // TODO uncomment if view need status update
- // angular.forEach(view.versions, function (versionObj, versionNumber) {
- // if (versionNeedStatusUpdate(versionObj.status)) {
- // checkViewVersionStatus(view, versionObj, versionNumber);
- // }
- // });
+ angular.forEach(view.versions, function (versionObj, versionNumber) {
+ if (versionNeedStatusUpdate(versionObj.status)) {
+ checkViewVersionStatus(view, versionObj, versionNumber);
+ }
+ });
angular.forEach(view.instances, function (instance) {
instance.ViewInstanceInfo.short_url_name = instance.ViewInstanceInfo.short_url_name || '';
instance.ViewInstanceInfo.short_url = instance.ViewInstanceInfo.short_url || '';
+ instance.ViewInstanceInfo.versionObj = view.versions[instance.ViewInstanceInfo.version] || {};
$scope.instances.push(instance.ViewInstanceInfo);
});
});
@@ -166,13 +166,20 @@ angular.module('ambariAdminConsole')
}
);
- $scope.createInstance = function () {
+ $scope.cloneInstance = function(instanceClone) {
+ $scope.createInstance(instanceClone);
+ };
+
+ $scope.createInstance = function (instanceClone) {
var modalInstance = $modal.open({
templateUrl: 'views/ambariViews/modals/create.html',
controller: 'CreateViewInstanceCtrl',
resolve: {
views: function() {
return $scope.views;
+ },
+ instanceClone: function() {
+ return instanceClone;
}
},
backdrop: 'static'
http://git-wip-us.apache.org/repos/asf/ambari/blob/430127b4/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
index 4ef3ee9..1967dfa 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
@@ -100,6 +100,7 @@ angular.module('ambariAdminConsole')
'common.userManagement': 'User Management',
'common.admin': 'Admin',
'common.actions': 'Actions',
+ 'common.error': 'Error',
'common.clusterNameChangeConfirmation.title': 'Confirm Cluster Name Change',
'common.clusterNameChangeConfirmation.message': 'Are you sure you want to change the cluster name to {{clusterName}}?',
@@ -180,7 +181,6 @@ angular.module('ambariAdminConsole')
'views.viewInstance': 'View Instance',
'views.create': 'Create Instance',
'views.clone': 'Clone Instance',
- 'views.createViewInstance': 'Create Instance',
'views.edit': 'Edit',
'views.viewName': 'View Name',
'views.instances': 'Instances',
http://git-wip-us.apache.org/repos/asf/ambari/blob/430127b4/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
index 486e598..dabc57a 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
@@ -91,12 +91,6 @@ angular.module('ambariAdminConsole')
controller: 'ViewsListCtrl',
label: 'Views'
},
- clone: {
- url: '/views/:viewId/versions/:version/instances/:instanceId/clone',
- templateUrl: 'views/ambariViews/create.html',
- controller: 'CloneViewInstanceCtrl',
- label: 'Views'
- },
edit: {
url: '/views/:viewId/versions/:version/instances/:instanceId/edit',
templateUrl: 'views/ambariViews/edit.html',
http://git-wip-us.apache.org/repos/asf/ambari/blob/430127b4/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 b38b0c2..db3dab9 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
@@ -286,10 +286,10 @@ angular.module('ambariAdminConsole')
description: instanceInfo.description
};
- angular.forEach(instanceInfo.properties, function(property) {
- if(property.clusterConfig) {
+ angular.forEach(instanceInfo.properties, function (property) {
+ if (property.clusterConfig) {
properties[property.name] = property.value
- }else {
+ } else {
settings[property.name] = property.value
}
});
@@ -297,7 +297,7 @@ angular.module('ambariAdminConsole')
data.properties = settings;
data.cluster_type = instanceInfo.clusterType;
- if(instanceInfo.clusterId != null) {
+ if (instanceInfo.clusterId != null) {
data.cluster_handle = instanceInfo.clusterId;
} else {
angular.extend(data.properties, properties);
http://git-wip-us.apache.org/repos/asf/ambari/blob/430127b4/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 9838227..94bdf11 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
@@ -665,7 +665,11 @@ a.alert-link, a.alert-link:hover, a.alert-link:visited{
border-left: 3px solid #ef2427;
}
.ambariAlert.error .icon-box, .test-ldap-icon.fa-times-circle {
- color: #ef2427;
+ color: #ef6162;
+}
+
+.error {
+ color: #ef6162;
}
.ambariAlert.success {
@@ -706,73 +710,9 @@ a.alert-link, a.alert-link:hover, a.alert-link:visited{
transition: none!important;
}
-
-.viewstatus{
- display: inline-block;
-}
-.viewstatus.pending{
- width: 12px;
- height: 12px;
- border: 2px solid black;
- border-radius: 50%;
- vertical-align: middle;
- position: relative;
-}
-
-.viewstatus.pending:before, .viewstatus.pending:after{
- content: '';
- position: absolute;
- left: 4px;
- top: 3px;
- width: 5px;
- height: 2px;
- background: black;
-}
-.viewstatus.pending:after{
- top: -3px;
- left: 3px;
- width: 2px;
- height: 2px;
- border-radius: 100%;
-}
-.viewstatus.pending:before{
- -webkit-transform-origin: 0% 50%;
- -moz-transform-origin: 0% 50%;
- -ms-transform-origin: 0% 50%;
- -o-transform-origin: 0% 50%;
- transform-origin: 0% 50%;
-
- animation: rotate 2.0s infinite linear;
- -webkit-animation: rotate 2.0s infinite linear;
-}
-
@-webkit-keyframes rotate { 100% { -webkit-transform: rotate(360deg) }}
@keyframes rotate { 100% { transform: rotate(360deg); -webkit-transform: rotate(360deg) }}
-
-.viewstatus.deploying{
- width: 17px;
- height: 12px;
- text-align: center;
- vertical-align: middle;
-}
-.viewstatus.deploying > div{
- background: black;
- height: 100%;
- width: 3px;
- display: inline-block;
- -webkit-animation: stretchdelay 1.2s infinite ease-in-out;
- animation: stretchdelay 1.2s infinite ease-in-out;
-}
-.viewstatus.deploying .rect2 {
- -webkit-animation-delay: -1.1s;
- animation-delay: -1.1s;
-}
-.viewstatus.deploying .rect3 {
- -webkit-animation-delay: -1.0s;
- animation-delay: -1.0s;
-}
-
@-webkit-keyframes stretchdelay {
0%, 40%, 100% { -webkit-transform: scaleY(0.4) }
20% { -webkit-transform: scaleY(1.0) }
http://git-wip-us.apache.org/repos/asf/ambari/blob/430127b4/ambari-admin/src/main/resources/ui/admin-web/app/styles/views.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/views.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/views.css
index 9ab66f5..58583de 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/styles/views.css
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/views.css
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-.view-instance-actions>a {
+.view-instance-actions a {
color: inherit;
font-size: 16px;
cursor: pointer;
@@ -28,9 +28,9 @@ th.view-instance-actions {
width: 10%;
}
-.view-instance-actions>a:hover,
-.view-instance-actions>a:visited:hover,
-.view-instance-actions>a:focus:hover {
+.view-instance-actions a:hover,
+.view-instance-actions a:visited:hover,
+.view-instance-actions a:focus:hover {
text-decoration: none;
}
@@ -38,6 +38,12 @@ th.view-instance-actions {
cursor: pointer;
}
+#create-instance-form .modal-body {
+ max-height: 600px;
+ overflow-y: auto;
+ overflow-x: hidden;
+}
+
#create-instance-form button.active {
color: #333;
background-color: #e6e6e6;
@@ -47,3 +53,71 @@ th.view-instance-actions {
input[type="checkbox"] + label {
line-height: 18px;
}
+
+.viewstatus {
+ display: inline-block;
+}
+
+.viewstatus.pending {
+ width: 12px;
+ height: 12px;
+ border: 2px solid black;
+ border-radius: 50%;
+ vertical-align: middle;
+ position: relative;
+}
+
+.viewstatus.pending:before, .viewstatus.pending:after {
+ content: '';
+ position: absolute;
+ left: 4px;
+ top: 3px;
+ width: 5px;
+ height: 2px;
+ background: black;
+}
+
+.viewstatus.pending:after {
+ top: -3px;
+ left: 3px;
+ width: 2px;
+ height: 2px;
+ border-radius: 100%;
+}
+
+.viewstatus.pending:before {
+ -webkit-transform-origin: 0% 50%;
+ -moz-transform-origin: 0% 50%;
+ -ms-transform-origin: 0% 50%;
+ -o-transform-origin: 0% 50%;
+ transform-origin: 0% 50%;
+
+ animation: rotate 2.0s infinite linear;
+ -webkit-animation: rotate 2.0s infinite linear;
+}
+
+.viewstatus.deploying {
+ width: 17px;
+ height: 12px;
+ text-align: center;
+ vertical-align: text-top;
+}
+
+.viewstatus.deploying > div {
+ background: black;
+ height: 100%;
+ width: 3px;
+ display: inline-block;
+ -webkit-animation: stretchdelay 1.2s infinite ease-in-out;
+ animation: stretchdelay 1.2s infinite ease-in-out;
+}
+
+.viewstatus.deploying .rect2 {
+ -webkit-animation-delay: -1.1s;
+ animation-delay: -1.1s;
+}
+
+.viewstatus.deploying .rect3 {
+ -webkit-animation-delay: -1.0s;
+ animation-delay: -1.0s;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/430127b4/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
deleted file mode 100644
index 81171c1..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html
+++ /dev/null
@@ -1,200 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
--->
-<ol class="breadcrumb">
- <li><a href="#/views">{{'common.views' | translate}}</a></li>
- <li class="active"> {{isClone ? 'views.clone' : 'views.create' | translate}}</li>
-</ol>
-<hr>
-<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">
- <label for="" class="control-label">{{'common.view' | translate}}</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">{{'common.version' | translate}}</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>
- </div>
-
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 class="panel-title">{{'common.details' | translate}}</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-3">{{'views.instanceName' | translate}}*</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'>{{'common.alerts.fieldIsRequired' | translate}}</div>
- <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm.instanceNameInput.$error.pattern && form.instanceCreateForm.submitted'>{{'views.alerts.noSpecialCharsOrSpaces' | translate}}</div>
- <div class="alert alert-danger no-margin-bottom top-margin" ng-show='instanceExists'>{{'views.alerts.instanceExists' | translate}}</div>
- </div>
- </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-3">{{'views.displayName' | translate}}*</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'>
- {{'common.alerts.fieldIsRequired' | translate}}
- </div>
- <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm.displayLabel.$error.pattern && form.instanceCreateForm.submitted'>
- {{'views.alerts.noSpecialChars' | translate}}
- </div>
- </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-3">{{'views.description' | translate}}*</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'>
- {{'common.alerts.fieldIsRequired' | translate}}
- </div>
- </div>
- </div>
-
- <div class="form-group">
- <div class="col-sm-10 col-sm-offset-3">
- <div class="checkbox">
- <input type="checkbox" ng-model='instance.visible' id="visibility-checkbox" class="visibilityCheckbox">
- <label for="visibility-checkbox">{{'views.visible' | translate}}</label>
- </div>
- </div>
- </div>
- </div>
- </div>
-
- <div class="panel panel-default" ng-hide="!numberOfSettingConfigs">
- <div class="panel-heading">
- <h3 class="panel-title">{{'views.settings' | translate}}</h3>
- </div>
- <div class="panel-body">
- <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'>
- {{'common.alerts.fieldIsRequired' | translate}}
- </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>
- </div>
-
- <div class="panel panel-default" ng-hide="!numberOfClusterConfigs && !clusterConfigurable">
- <div class="panel-heading">
- <h3 class="panel-title">{{'views.clusterConfiguration' | translate}}</h3>
- </div>
-
- <div class="panel-body property-form" popover="{{clusterConfigurableErrorMsg}}" popover-trigger="mouseenter">
- <div class="checkbox create-checkbox-cluster">
- <input type="radio" id="local-cluster" ng-disabled="!clusterConfigurable || noLocalClusterAvailible" ng-model="instance.clusterType" ng-change="enableLocalCluster()" value="LOCAL_AMBARI" class="visibilityCheckbox">
- <label for="local-cluster">{{'views.localCluster' | translate}}</label>
- </div>
-
- <div class="form-horizontal property-form">
- <div class="form-group">
-
- <label for="" class="control-label col-sm-3 ng-binding not-required" >{{'views.clusterName' | translate}}</label>
- <div>
- <div class="col-sm-9">
- <select ng-model="cluster" ng-disabled="instance.clusterType != 'LOCAL_AMBARI' || noLocalClusterAvailible" ng-change="onClusterChange()" class="clusters-name-dropdown form-control" ng-options="o as o.name for o in clusters"></select>
- </div>
- </div>
- </div>
- </div>
-
- </div>
-
- <div class="panel-body property-form" popover="{{clusterConfigurableErrorMsg}}" popover-trigger="mouseenter">
- <div class="checkbox create-checkbox-cluster">
- <input type="radio" id="remote-cluster" ng-disabled="!clusterConfigurable || noRemoteClusterAvailible" ng-model="instance.clusterType" ng-change="enableLocalCluster()" value="REMOTE_AMBARI" class="visibilityCheckbox">
- <label for="remote-cluster">{{'views.remoteCluster' | translate}}</label>
- </div>
-
- <div class="form-horizontal property-form">
- <div class="form-group">
-
- <label for="" class="control-label col-sm-3 ng-binding not-required" >{{'views.clusterName' | translate}}</label>
- <div>
- <div class="col-sm-9">
- <select ng-model="data.remoteCluster" ng-disabled="instance.clusterType != 'REMOTE_AMBARI' || noRemoteClusterAvailable" ng-change="onClusterChange()" class="clusters-name-dropdown form-control" ng-options="o as o.name for o in remoteClusters"></select>
- </div>
- </div>
- </div>
- </div>
-
- </div>
-
- <div class="panel-body property-form" ng-hide="!numberOfClusterConfigs">
- <div class="checkbox">
- <input type="radio" id="custom-view" ng-model="instance.clusterType" value="NONE" class="visibilityCheckbox">
- <label for="custom-view">{{'views.custom' | translate}}</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 | 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-disabled="instance.clusterType == 'NONE'" ng-required="parameter.required && (instance.clusterType == 'NONE')" 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-disabled="instance.clusterType != 'NONE'" ng-change="form.instanceCreateForm[parameter.name].validationError=''" ng-required="parameter.required && (instance.clusterType == 'NONE')" 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.clusterType == 'NONE')">
- {{'common.alerts.fieldIsRequired' | translate}}
- </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 ng-show="!instance.properties.length">
- <div class="alert alert-info">{{'views.alerts.notDefined' | translate: '{term: constants.props}'}}</div>
- </div>
- </div>
- </div>
-
- <div class="col-sm-12 ">
- <button class="btn btn-primary pull-right left-margin save-button"
- ng-class="{'disabled' : (form.instanceCreateForm.isSaving)}" ng-click="save()" type="submit">{{'common.controls.save' | translate}}</button>
- <a href ng-click="cancel()" class="btn btn-default pull-right cancel-button">{{'common.controls.cancel' | translate}}</a>
- </div>
-
-</form>
http://git-wip-us.apache.org/repos/asf/ambari/blob/430127b4/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/create.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/create.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/create.html
index 48757d4..82f90b3 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/create.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/create.html
@@ -17,7 +17,14 @@
-->
<form role="form" id="create-instance-form" name="form.instanceCreateForm" novalidate>
<div class="modal-header">
- <h3 class="modal-title">{{'views.createViewInstance' | translate}}</h3>
+ <h1 class="modal-title">
+ <span ng-if="!instanceClone">
+ {{'views.create' | translate}}
+ </span>
+ <span ng-if="instanceClone">
+ {{'views.clone' | translate}}
+ </span>
+ </h1>
</div>
<div class="modal-body" ng-hide="isLoading">
@@ -29,6 +36,7 @@
<i class="fa fa-question-circle" aria-hidden="true"></i>
</label>
<select
+ ng-disabled="instanceClone"
class="form-control"
id="view"
name="view"
@@ -48,10 +56,12 @@
<i class="fa fa-question-circle" aria-hidden="true"></i>
</label>
<select
+ ng-disabled="instanceClone"
class="form-control"
id="version"
name="version"
ng-model="formData.version"
+ ng-change="updateSettingsList()"
ng-options="item.label for item in versionOptions">
</select>
<span class="help-block validation-block" ng-show='form.instanceCreateForm.version.$error.required && form.instanceCreateForm.submitted'>
@@ -60,112 +70,179 @@
</div>
</div>
- <div class="h4">{{'common.details' | translate}}</div>
- <div class="form-group"
- ng-class="{ 'has-error': (form.instanceCreateForm.instanceName.$error.required || form.instanceCreateForm.instanceName.$error.pattern || isInstanceExists) && form.instanceCreateForm.submitted }">
- <label for="instanceName">
- {{'views.instanceName' | translate}}<span>*</span>
- <i class="fa fa-question-circle" aria-hidden="true"></i>
- </label>
- <input type="text" class="form-control"
- ng-model="formData.instanceName"
- name="instanceName"
- id="instanceName"
- ng-change="checkIfInstanceExist()"
- ng-pattern="nameValidationPattern" required>
- <span class="help-block validation-block"
- ng-show='form.instanceCreateForm.instanceName.$error.required && form.instanceCreateForm.submitted'>
- {{'common.alerts.fieldRequired' | translate}}
- </span>
- <span class="help-block validation-block"
- ng-show='form.instanceCreateForm.instanceName.$error.pattern && form.instanceCreateForm.submitted'>
+ <div class="details-section">
+ <h2>{{'common.details' | translate}}</h2>
+ <div class="form-group"
+ ng-class="{ 'has-error': (form.instanceCreateForm.instanceName.$error.required || form.instanceCreateForm.instanceName.$error.pattern || isInstanceExists) && form.instanceCreateForm.submitted }">
+ <label for="instanceName">
+ {{'views.instanceName' | translate}}<span>*</span>
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ <input type="text" class="form-control"
+ ng-model="formData.instanceName"
+ name="instanceName"
+ id="instanceName"
+ ng-change="checkIfInstanceExist()"
+ ng-pattern="nameValidationPattern" required>
+ <span class="help-block validation-block"
+ ng-show='form.instanceCreateForm.instanceName.$error.required && form.instanceCreateForm.submitted'>
+ {{'common.alerts.fieldRequired' | translate}}
+ </span>
+ <span class="help-block validation-block"
+ ng-show='form.instanceCreateForm.instanceName.$error.pattern && form.instanceCreateForm.submitted'>
{{'common.alerts.noSpecialChars' | translate}}
</span>
- <span class="help-block validation-block"
- ng-show='isInstanceExists && form.instanceCreateForm.submitted'>
- {{'views.alerts.instanceExists' | translate}}
- </span>
- </div>
+ <span class="help-block validation-block" ng-show='isInstanceExists && form.instanceCreateForm.submitted'>
+ {{'views.alerts.instanceExists' | translate}}
+ </span>
+ </div>
- <div class="form-group" ng-class="{ 'has-error': form.instanceCreateForm.displayName.$error.required && form.instanceCreateForm.submitted }">
- <label for="displayName">
- {{'views.displayName' | translate}}<span>*</span>
- <i class="fa fa-question-circle" aria-hidden="true"></i>
- </label>
- <input type="text" class="form-control" required
- name="displayName"
- ng-model="formData.displayName"
- id="displayName">
- <span class="help-block validation-block" ng-show='form.instanceCreateForm.displayName.$error.required && form.instanceCreateForm.submitted'>
- {{'common.alerts.fieldRequired' | translate}}
- </span>
- </div>
+ <div class="form-group" ng-class="{ 'has-error': form.instanceCreateForm.displayName.$error.required && form.instanceCreateForm.submitted }">
+ <label for="displayName">
+ {{'views.displayName' | translate}}<span>*</span>
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ <input type="text" class="form-control" required
+ name="displayName"
+ ng-model="formData.displayName"
+ id="displayName">
+ <span class="help-block validation-block" ng-show='form.instanceCreateForm.displayName.$error.required && form.instanceCreateForm.submitted'>
+ {{'common.alerts.fieldRequired' | translate}}
+ </span>
+ </div>
- <div class="form-group" ng-class="{ 'has-error': form.instanceCreateForm.description.$error.required && form.instanceCreateForm.submitted }">
- <label for="description">
- {{'views.description' | translate}}<span>*</span>
- <i class="fa fa-question-circle" aria-hidden="true"></i>
- </label>
- <input type="text" class="form-control" required
- name="description"
- ng-model="formData.description"
- id="description">
- <span class="help-block validation-block" ng-show='form.instanceCreateForm.description.$error.required && form.instanceCreateForm.submitted'>
- {{'common.alerts.fieldRequired' | translate}}
- </span>
- </div>
+ <div class="form-group" ng-class="{ 'has-error': form.instanceCreateForm.description.$error.required && form.instanceCreateForm.submitted }">
+ <label for="description">
+ {{'views.description' | translate}}<span>*</span>
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ <input type="text" class="form-control" required
+ name="description"
+ ng-model="formData.description"
+ id="description">
+ <span class="help-block validation-block" ng-show='form.instanceCreateForm.description.$error.required && form.instanceCreateForm.submitted'>
+ {{'common.alerts.fieldRequired' | translate}}
+ </span>
+ </div>
- <div class="form-group checkbox">
- <input type="checkbox" class="form-control"
- name="visible"
- ng-model="formData.visible"
- id="visible">
- <label for="visible">
- {{'views.visible' | translate}}
- <i class="fa fa-question-circle" aria-hidden="true"></i>
- </label>
+ <div class="form-group checkbox">
+ <input type="checkbox" class="form-control"
+ name="visible"
+ ng-model="formData.visible"
+ id="visible">
+ <label for="visible">
+ {{'views.visible' | translate}}
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ </div>
</div>
- <div class="h4">{{'views.clusterConfiguration' | translate}}</div>
- <div class="form-group">
- <label for="clusterType">
- {{'views.createInstance.clusterType' | translate}}?
- <i class="fa fa-question-circle" aria-hidden="true"></i>
- </label>
- <div>
- <div class="btn-group" role="group" id="clusterType">
- <button type="button" class="btn btn-default"
- ng-class="isLocalTypeChosen && 'active'"
- ng-click="switchClusterType(true)">
- {{'common.local' | translate}}
- </button>
- <button type="button" class="btn btn-default"
- ng-class="!isLocalTypeChosen && 'active'"
- ng-click="switchClusterType(false)">
- {{'common.remote' | translate}}
- </button>
- </div>
+ <div class="settings-section" ng-show="nonClusterSettingsCount">
+ <h2>{{'views.settings' | translate}}</h2>
+ <div class="form-group"
+ ng-repeat="parameter in formData.settings | filter: { clusterConfig: false }"
+ ng-class="{ 'has-error': (form.instanceCreateForm[parameter.name].$error.required && form.instanceCreateForm.submitted) || form.instanceCreateForm[parameter.name].validationError }">
+ <label ng-attr-for="{{parameter.name}}">
+ {{parameter.label || parameter.displayName}}{{parameter.required ? '*' : ''}}
+ </label>
+ <input class="form-control"
+ type="{{parameter.masked ? 'password' : 'text'}}"
+ ng-required="parameter.required"
+ ng-change="form.instanceCreateForm[parameter.name].validationError=''"
+ ng-attr-name="{{parameter.name}}"
+ popover="{{parameter.description}}"
+ popover-title="{{parameter.name}}"
+ popover-trigger="mouseenter"
+ placeholder="{{parameter.placeholder}}"
+ ng-model="parameter.value"
+ ng-attr-id="{{parameter.name}}">
+ <span class="help-block validation-block" ng-show='form.instanceCreateForm[parameter.name].$error.required && form.instanceCreateForm.submitted'>
+ {{'common.alerts.fieldRequired' | translate}}
+ </span>
+ <span class="help-block validation-block" ng-show='form.instanceCreateForm[parameter.name].validationError'>
+ {{form.instanceCreateForm[parameter.name].validationMessage}}
+ </span>
</div>
</div>
- <div class="row">
- <div class="form-group col-sm-6" ng-class="{ 'has-error': form.instanceCreateForm.clusterName.$error.required && form.instanceCreateForm.submitted }">
- <label for="clusterName">
- {{'views.clusterName' | translate}}<span>*</span>
+
+ <div class="cluster-type-section">
+ <h2>{{'views.clusterConfiguration' | translate}}</h2>
+ <div class="form-group">
+ <label for="clusterType">
+ {{'views.createInstance.clusterType' | translate}}?
<i class="fa fa-question-circle" aria-hidden="true"></i>
</label>
- <select
- required
- name="clusterName"
- ng-options="item.label for item in clusterOptions"
- class="form-control"
- ng-model="formData.clusterName"
- id="clusterName">
- </select>
- <span class="help-block validation-block" ng-show='form.instanceCreateForm.clusterName.$error.required && form.instanceCreateForm.submitted'>
+ <div>
+ <div class="btn-group" role="group" id="clusterType">
+ <button type="button" class="btn btn-default"
+ ng-class="clusterType === 'LOCAL_AMBARI' && 'active'"
+ ng-click="switchClusterType('LOCAL_AMBARI')">
+ {{'common.local' | translate}}
+ </button>
+ <button type="button" class="btn btn-default"
+ ng-class="clusterType === 'REMOTE_AMBARI' && 'active'"
+ ng-click="switchClusterType('REMOTE_AMBARI')">
+ {{'common.remote' | translate}}
+ </button>
+ <button type="button" class="btn btn-default"
+ ng-if="clusterSettingsCount && clusterConfigurable"
+ ng-class="clusterType === 'NONE' && 'active'"
+ ng-click="switchClusterType('NONE')">
+ {{'views.custom' | translate}}
+ </button>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="form-group col-sm-6" ng-class="{ 'has-error': form.instanceCreateForm.clusterName.$error.required && form.instanceCreateForm.submitted }">
+ <label for="clusterName">
+ {{'views.clusterName' | translate}}<span>*</span>
+ <i class="fa fa-question-circle" aria-hidden="true"></i>
+ </label>
+ <select
+ ng-required="clusterType !== 'NONE'"
+ ng-disabled="clusterType === 'NONE'"
+ name="clusterName"
+ ng-options="item.label for item in clusterOptions"
+ class="form-control"
+ ng-model="formData.clusterName"
+ id="clusterName">
+ </select>
+ <span class="help-block validation-block" ng-show='form.instanceCreateForm.clusterName.$error.required && form.instanceCreateForm.submitted'>
+ {{'common.alerts.fieldRequired' | translate}}
+ </span>
+ </div>
+ </div>
+ <div class="cluster-configurations-section" ng-show="clusterSettingsCount && clusterConfigurable">
+ <div class="form-group"
+ ng-repeat="parameter in formData.settings | filter: { clusterConfig: true }"
+ ng-class="{ 'has-error': (form.instanceCreateForm[parameter.name].$error.required && form.instanceCreateForm.submitted) || form.instanceCreateForm[parameter.name].validationError }">
+ <label ng-attr-for="{{parameter.name}}">
+ {{parameter.label || parameter.displayName}}{{parameter.required ? '*' : ''}}
+ </label>
+ <input class="form-control"
+ ng-disabled="clusterType !== 'NONE'"
+ type="{{parameter.masked ? 'password' : 'text'}}"
+ ng-required="clusterType === 'NONE' && parameter.required"
+ ng-change="form.instanceCreateForm[parameter.name].validationError=''"
+ ng-attr-name="{{parameter.name}}"
+ popover="{{parameter.description}}"
+ popover-title="{{parameter.name}}"
+ popover-trigger="mouseenter"
+ placeholder="{{parameter.placeholder}}"
+ ng-model="parameter.value"
+ ng-attr-id="{{parameter.name}}">
+ <span class="help-block validation-block" ng-show="form.instanceCreateForm[parameter.name].$error.required && form.instanceCreateForm.submitted && (clusterType === 'NONE')">
{{'common.alerts.fieldRequired' | translate}}
</span>
+ <span class="help-block validation-block" ng-show='form.instanceCreateForm[parameter.name].validationError'>
+ {{form.instanceCreateForm[parameter.name].validationMessage}}
+ </span>
+ </div>
</div>
</div>
+
+
</div>
<div ng-if="isLoading" class="spinner-container">
<i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
http://git-wip-us.apache.org/repos/asf/ambari/blob/430127b4/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
index 7aa25ab..2ff0fc4 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
@@ -20,7 +20,7 @@
<div class="clearfix">
<div class="pull-right">
- <button ng-disabled="views.length === 0" ng-click="createInstance(views[0]);" class="btn btn-default">
+ <button ng-disabled="views.length === 0" ng-click="createInstance();" class="btn btn-default">
{{'views.create' | translate}}
</button>
</div>
@@ -98,16 +98,35 @@
<td>
<span>{{instance.instance_name}}</span>
</td>
- <td class="view-instance-actions">
- <a href="#/views/{{instance.view_name}}/versions/{{instance.version}}/instances/{{instance.instance_name}}/edit">
- <i class="fa fa-pencil"></i>
- </a>
- <a href="#/views/{{instance.view_name}}/versions/{{instance.version}}/instances/{{instance.instance_name}}/clone">
- <i class="fa fa-copy"></i>
- </a>
- <a href ng-click="deleteInstance(instance)">
- <i class="fa fa-trash-o"></i>
- </a>
+ <td class="view-instance-actions" ng-switch="instance.versionObj.status">
+ <span ng-switch-when="PENDING">
+ <i class="viewstatus pending"></i>
+ {{'views.pending' | translate}}
+ </span>
+ <span ng-switch-when="DEPLOYING">
+ <div class="viewstatus deploying">
+ <div class="rect1"></div>
+ <div class="rect2"></div>
+ <div class="rect3"></div>
+ </div>
+ {{'views.deploying' | translate}}
+ </span>
+
+ <span ng-switch-when="DEPLOYED">
+ <a href="#/views/{{instance.view_name}}/versions/{{instance.version}}/instances/{{instance.instance_name}}/edit">
+ <i class="fa fa-pencil"></i>
+ </a>
+ <a href ng-click="cloneInstance(instance);">
+ <i class="fa fa-copy"></i>
+ </a>
+ <a href ng-click="deleteInstance(instance)">
+ <i class="fa fa-trash-o"></i>
+ </a>
+ </span>
+ <span ng-switch-when="ERROR" class="error" tooltip="{{'views.alerts.deployError' | translate}}">
+ <i class="fa fa-exclamation-triangle"></i>
+ {{'common.error' | translate}}
+ </span>
</td>
</tr>
</tbody>
http://git-wip-us.apache.org/repos/asf/ambari/blob/430127b4/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html
index c625475..dbd1021 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html
@@ -16,7 +16,6 @@
* limitations under the License.
-->
<ol class="breadcrumb">
- <li> <link-to route="views.listViewUrls">{{'urls.viewUrls' | translate}}</link-to></li>
<li class="active">{{'urls.createNewUrl' | translate}}</li>
</ol>
<hr>
@@ -68,7 +67,6 @@
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button ng-disabled="stepTwoNotCompleted" class="btn btn-primary pull-right left-margin saveuser" ng-click="saveUrl()">{{'common.controls.save' | translate}}</button>
- <link-to route="views.listViewUrls" class="btn btn-default pull-right cancel">{{'common.controls.cancel' | translate}}</link-to>
</div>
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/430127b4/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html
index dd5f65a..61366db 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html
@@ -16,7 +16,6 @@
* limitations under the License.
-->
<ol class="breadcrumb">
- <li> <link-to route="views.listViewUrls">{{'urls.viewUrls' | translate}}</link-to></li>
<li class="active">{{'urls.edit' | translate}} {{url.url_name}}</li>
<div class="pull-right top-margin-4">
<button class="btn deleteuser-btn btn-danger" ng-click="deleteUrl()">{{'views.urlDelete' | translate}}</button>
@@ -70,7 +69,6 @@
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button ng-disabled="stepTwoNotCompleted" class="btn btn-primary pull-right left-margin saveuser" ng-click="updateUrl()">{{'common.controls.save' | translate}}</button>
- <link-to route="views.listViewUrls" class="btn btn-default pull-right cancel">{{'common.controls.cancel' | translate}}</link-to>
</div>
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/430127b4/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CloneViewInstanceCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CloneViewInstanceCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CloneViewInstanceCtrl.js
deleted file mode 100644
index f78333a..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CloneViewInstanceCtrl.js
+++ /dev/null
@@ -1,135 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-describe('#CloneViewInstanceCtrl', function () {
- var scope, ctrl, $httpBackend, View;
-
- beforeEach(module('ambariAdminConsole', function($provide){
- $provide.value('$routeParams', {viewId: 'TestView'});
- }));
-
- afterEach(function() {
- $httpBackend.verifyNoOutstandingExpectation();
- $httpBackend.verifyNoOutstandingRequest();
- });
-
- beforeEach(inject(function (_$httpBackend_, $rootScope, $controller, _View_, $q) {
- View = _View_;
- spyOn(View, 'createInstance').andReturn($q.defer().promise);
- spyOn(View, 'getInstance').andReturn($q.defer().promise);
-
- $httpBackend = _$httpBackend_;
- $httpBackend.whenGET(/\/api\/v1\/views\/TestView\?.+/).respond(200, {
- "versions": [{"ViewVersionInfo": {}}]
- });
- $httpBackend.whenGET(/\/api\/v1\/views\/TestView\/versions\/1\.0\.0/).respond(200, {
- "ViewVersionInfo": {"parameters": [{"name": "n", "defaultValue": "d"}]}
- });
- $httpBackend.whenGET('template/modal/backdrop.html').respond(200, '<div></div>');
- $httpBackend.whenGET('template/modal/window.html').respond(200, '<div></div>');
- scope = $rootScope.$new();
- ctrl = $controller('CloneViewInstanceCtrl', {$scope: scope});
- }));
-
- it('it should invoke View.createInstance on save', function () {
- scope.form = {
- instanceCreateForm: {
- submitted: false,
- $valid: true
- }
- };
- $httpBackend.flush();
- scope.instance = {};
- scope.save();
- expect(View.createInstance).toHaveBeenCalled();
- });
-
- it('should set default property value before creating view instance', function () {
- scope.form = {
- instanceCreateForm: {
- $dirty: true
- }
- };
- scope.instance = {};
- scope.version = '1.0.0';
- scope.isClone=false;
- $httpBackend.expectGET('template/modal/backdrop.html');
- $httpBackend.expectGET('template/modal/window.html');
- $httpBackend.whenGET(/\/api\/v1\/clusters\?fields=Clusters\/cluster_id&_=\d+/).respond(200, {
- "items" : [
- {
- "Clusters" : {
- "cluster_name" : "c1",
- "version" : "HDP-2.2"
- }
- }
- ]
- });
- $httpBackend.whenGET(/\/api\/v1\/remoteclusters\?fields=ClusterInfo\/services,ClusterInfo\/cluster_id&_=\d+/).respond(200, {
- "items" : [
- {
- "ClusterInfo" : {
- "name" : "c1",
- "services" : ["HDFS"]
- }
- }
- ]
- });
- scope.$digest();
- $httpBackend.flush();
- chai.expect(scope.view.ViewVersionInfo.parameters[0].value).to.equal('d');
- expect(View.getInstance).not.toHaveBeenCalled();
- });
-
- it('before cloning view instance confirm that View.getInstance is called', function () {
- scope.form = {
- instanceCreateForm: {
- $dirty: true
- }
- };
- scope.instance = {};
- scope.version = '1.0.0';
- scope.isClone=true;
- $httpBackend.expectGET('template/modal/backdrop.html');
- $httpBackend.expectGET('template/modal/window.html');
- $httpBackend.whenGET(/\/api\/v1\/clusters\?fields=Clusters\/cluster_id&_=\d+/).respond(200, {
- "items" : [
- {
- "Clusters" : {
- "cluster_name" : "c1",
- "version" : "HDP-2.2"
- }
- }
- ]
- });
- $httpBackend.whenGET(/\/api\/v1\/remoteclusters\?fields=ClusterInfo\/services,ClusterInfo\/cluster_id&_=\d+/).respond(200, {
- "items" : [
- {
- "ClusterInfo" : {
- "name" : "c1",
- "services" : ["HDFS"]
- }
- }
- ]
- });
- scope.$digest();
- $httpBackend.flush();
- expect(View.getInstance).toHaveBeenCalled();
- });
-
-});