http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/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 183a276..4a13e02 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 @@ -32,16 +32,15 @@ angular.module('ambariAdminConsole') 'common.register': 'Register', 'common.clusters': 'Clusters', 'common.views': 'Views', - 'common.viewUrls': 'View URLs', 'common.roles': 'Roles', 'common.users': 'Users', 'common.groups': 'Groups', 'common.versions': 'Versions', 'common.stack': 'Stack', 'common.details': 'Details', + 'common.dashboard': 'Dashboard', 'common.goToDashboard': 'Go to Dashboard', 'common.exportBlueprint': 'Export Blueprint', - 'common.blueprint': 'Blueprint', 'common.download': 'Download', 'common.noClusters': 'No Clusters', 'common.noViews': 'No Views', @@ -70,7 +69,6 @@ angular.module('ambariAdminConsole') 'common.renameCluster': 'Rename Cluster', 'common.renameClusterTip': 'Only alpha-numeric characters, up to 80 characters', 'common.clusterCreationInProgress': 'Cluster creation in progress...', - 'common.userGroupManagement': 'User + Group Management', 'common.all': 'All', 'common.group': 'Group', 'common.user': 'User', @@ -80,6 +78,7 @@ angular.module('ambariAdminConsole') 'common.remoteClusterDelConfirmation': 'Are you sure you want to delete {{instanceType}} {{instanceName}}? This operation cannot be undone.', 'common.messageInstanceAffected': 'The following View Instances are using this Remote Cluster for configuration, and will need to be reconfigured:', 'common.local': 'Local', + 'common.remote': 'Remote', 'common.pam': 'PAM', 'common.ldap': 'LDAP', 'common.jwt': 'JWT', @@ -96,6 +95,13 @@ angular.module('ambariAdminConsole') 'common.undo': 'Undo', 'common.fromGroupMark': '(from group)', 'common.copy': '_Copy', + 'common.clusterInformation': 'Cluster Information', + 'common.clusterManagement': 'Cluster Management', + 'common.userManagement': 'User Management', + 'common.admin': 'Admin', + 'common.actions': 'Actions', + 'common.error': 'Error', + 'common.select': 'Select', 'common.clusterNameChangeConfirmation.title': 'Confirm Cluster Name Change', 'common.clusterNameChangeConfirmation.message': 'Are you sure you want to change the cluster name to {{clusterName}}?', @@ -163,23 +169,12 @@ angular.module('ambariAdminConsole') 'main.title': 'Welcome to Apache Ambari', 'main.noClusterDescription': 'Provision a cluster, manage who can access the cluster, and customize views for Ambari users.', - 'main.hasClusterDescription': 'Monitor your cluster resources, manage who can access the cluster, and customize views for Ambari users.', 'main.autoLogOut': 'Automatic Logout', - 'main.operateCluster.title': 'Operate Your Cluster', - 'main.operateCluster.description': 'Manage the configuration of your cluster and monitor the health of your services', - 'main.operateCluster.manageRoles': 'Manage Roles', - 'main.createCluster.title': 'Create a Cluster', 'main.createCluster.description': 'Use the Install Wizard to select services and configure your cluster', 'main.createCluster.launchInstallWizard': 'Launch Install Wizard', - 'main.manageUsersAndGroups.title': 'Manage Users + Groups', - 'main.manageUsersAndGroups.description': 'Manage the users and groups that can access Ambari', - - 'main.deployViews.title': 'Deploy Views', - 'main.deployViews.description': 'Create view instances and grant permissions', - 'main.controls.remainLoggedIn': 'Remain Logged In', 'main.controls.logOut': 'Log Out Now', @@ -187,7 +182,6 @@ angular.module('ambariAdminConsole') 'views.viewInstance': 'View Instance', 'views.create': 'Create Instance', 'views.clone': 'Clone Instance', - 'views.createViewInstance': 'Create View Instance', 'views.edit': 'Edit', 'views.viewName': 'View Name', 'views.instances': 'Instances', @@ -235,7 +229,6 @@ angular.module('ambariAdminConsole') 'views.alerts.cannotEditInstance': 'Cannot Edit Static Instances', 'views.alerts.cannotDeleteStaticInstance': 'Cannot Delete Static Instances', 'views.alerts.deployError': 'Error deploying. Check Ambari Server log.', - 'views.alerts.unableToCreate': 'Unable to create view instances', 'views.alerts.cannotUseOption': 'This view cannot use this option', 'views.alerts.unableToResetErrorMessage': 'Unable to reset error message for prop: {{key}}', 'views.alerts.instanceCreated': 'Created View Instance {{instanceName}}', @@ -252,7 +245,12 @@ angular.module('ambariAdminConsole') 'views.alerts.savedRemoteClusterInformation': 'Remote cluster information is saved.', 'views.alerts.credentialsUpdated': 'Credentials Updated.', - 'urls.name': 'Name', + 'views.table.viewType': 'View Type', + 'views.emptyTable': 'No Views to display', + 'views.createInstance.selectView': 'Select View', + 'views.createInstance.selectVersion': 'Select Version', + 'views.createInstance.clusterType': 'Cluster Type', + 'urls.url': 'URL', 'urls.viewUrls': 'View URLs', 'urls.createNewUrl': 'Create New URL', @@ -263,7 +261,6 @@ angular.module('ambariAdminConsole') 'urls.step1': 'Create URL', 'urls.step2': 'Select instance', 'urls.step3': 'Assign URL', - 'urls.noUrlsToDisplay': 'No URLs to display.', 'urls.noViewInstances': 'No view instances', 'urls.none': 'None', 'urls.change': 'Change', @@ -276,9 +273,12 @@ angular.module('ambariAdminConsole') 'clusters.assignRoles': 'Assign roles to these {{term}}', 'clusters.alerts.cannotLoadClusterData': 'Cannot load cluster data', + 'clusters.devBlueprint': 'Dev Blueprint', - 'groups.createLocal': 'Create Local Group', + 'groups.createLocal': 'Add Groups', 'groups.name': 'Group name', + 'groups.role': 'Add roles to this group', + 'groups.addUsers': 'Add users to this group', 'groups.members': 'Members', 'groups.membersPlural': '{{n}} member{{n == 1 ? "" : "s"}}', @@ -288,7 +288,7 @@ angular.module('ambariAdminConsole') 'groups.alerts.getGroupsListError': 'Get groups list error', 'users.username': 'Username', - 'users.userName': 'User name', + 'users.user.name': 'User name', 'users.admin': 'Admin', 'users.ambariAdmin': 'Ambari Admin', 'users.ambariClusterURL': 'Ambari Cluster URL', @@ -298,12 +298,16 @@ angular.module('ambariAdminConsole') 'users.yourPassword': 'Your Password', 'users.newPassword': 'New User Password', 'users.newPasswordConfirmation': 'New User Password Confirmation', - 'users.create': 'Create Local User', + 'users.create': 'Add Users', 'users.active': 'Active', 'users.inactive': 'Inactive', 'users.status': 'Status', 'users.password': 'Password', + 'users.role': 'Add roles for this user', + 'users.confirmPassword': 'Confirm Password', 'users.passwordConfirmation': 'Password Ñonfirmation', + 'users.isAmbariAdmin': 'Is this user an Ambari Admin?', + 'users.isActive': 'Deactivate this user?', 'users.userIsAdmin': 'This user is an Ambari Admin and has all privileges.', 'users.showAll': 'Show all users', 'users.showAdmin': 'Show only admin users', @@ -333,7 +337,7 @@ angular.module('ambariAdminConsole') 'users.alerts.wrongPassword': 'Password must match!', 'users.alerts.usernameRequired': 'Username Required', 'users.alerts.cannotChange': 'Cannot Change {{term}}', - 'users.alerts.userCreated': 'Created user <a href="#/users/{{encUserName}}">{{userName}}</a>', + 'users.alerts.userCreated': 'Created user <a href="#/users/{{encUserName}}/edit">{{userName}}</a>', 'users.alerts.userCreationError': 'User creation error', 'users.alerts.removeUserError': 'Removing from group error', 'users.alerts.cannotAddUser': 'Cannot add user to group', @@ -369,7 +373,6 @@ angular.module('ambariAdminConsole') 'versions.installOn': 'Install on...', 'versions.register.title': 'Register Version', - 'versions.register.error.header': 'Unable to Register', 'versions.register.error.body': 'You are attempting to register a version with a Base URL that is already in use with an existing registered version. You *must* review your Base URLs and confirm they are unique for the version you are trying to register.',
http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/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 a1ca59c..c8d0e96 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 @@ -19,11 +19,6 @@ angular.module('ambariAdminConsole') .constant('ROUTES', { - root: { - url: '/', - templateUrl: 'views/main.html', - controller: 'MainCtrl' - }, authentication: { main: { url: '/authentication', @@ -32,7 +27,7 @@ angular.module('ambariAdminConsole') } }, loginActivities: { - loginMessage:{ + loginMessage: { url: '/loginMessage', templateUrl: 'views/loginActivities/main.html', controller: 'LoginActivitiesMainCtrl' @@ -43,157 +38,129 @@ angular.module('ambariAdminConsole') controller: 'LoginActivitiesMainCtrl' } }, - users: { - list: { - url: '/users', - templateUrl: 'views/users/list.html', - controller: 'UsersListCtrl' + userManagement: { + main: { + url: '/userManagement', + templateUrl: 'views/userManagement/main.html', + controller: 'UserManagementCtrl', + label: 'Users' }, - edit: { + editUser: { url: '/users/:id/edit', - templateUrl: 'views/users/create.html', - controller: 'UsersCreateCtrl' - }, - create: { - url: '/users/new', - templateUrl: 'views/users/create.html', - controller: 'UsersCreateCtrl' - }, - show: { - url: '/users/:id*', - templateUrl: 'views/users/show.html', - controller: 'UsersShowCtrl' - } - }, - groups: { - list: { - url: '/groups', - templateUrl: 'views/groups/list.html', - controller: 'GroupsListCtrl' + templateUrl: 'views/userManagement/userEdit.html', + controller: 'UserEditCtrl', + label: 'Users' }, - edit: { + editGroup: { url: '/groups/:id/edit', - templateUrl: 'views/groups/edit.html', - controller: 'GroupsEditCtrl' + templateUrl: 'views/userManagement/groupEdit.html', + controller: 'GroupEditCtrl', + label: 'Groups' }, - create: { - url: '/groups/new', - templateUrl: 'views/groups/create.html', - controller: 'GroupsCreateCtrl' - } }, views: { list: { url: '/views', - templateUrl: 'views/ambariViews/listTable.html', - controller: 'ViewsListCtrl' + templateUrl: 'views/ambariViews/viewsList.html', + controller: 'ViewsListCtrl', + label: 'Views' }, - listViewUrls: { - url: '/viewUrls', - templateUrl: 'views/ambariViews/listUrls.html', - controller: 'ViewsListCtrl' + edit: { + url: '/views/:viewId/versions/:version/instances/:instanceId/edit', + templateUrl: 'views/ambariViews/edit.html', + controller: 'ViewsEditCtrl', + label: 'Views' }, - createViewUrl:{ + createViewUrl: { url: '/urls/new', templateUrl: 'views/urls/create.html', - controller: 'ViewUrlCtrl' + controller: 'ViewUrlCtrl', + label: 'Views' }, - linkViewUrl:{ + linkViewUrl: { url: '/urls/link/:viewName/:viewVersion/:viewInstanceName', templateUrl: 'views/urls/create.html', - controller: 'ViewUrlCtrl' + controller: 'ViewUrlCtrl', + label: 'Views' }, - editViewUrl:{ + editViewUrl: { url: '/urls/edit/:urlName', templateUrl: 'views/urls/edit.html', - controller: 'ViewUrlEditCtrl' - }, - clone: { - url: '/views/:viewId/versions/:version/instances/:instanceId/clone', - templateUrl: 'views/ambariViews/create.html', - controller: 'CreateViewInstanceCtrl' - }, - edit: { - url: '/views/:viewId/versions/:version/instances/:instanceId/edit', - templateUrl: 'views/ambariViews/edit.html', - controller: 'ViewsEditCtrl' - }, - create: { - url: '/views/:viewId/new', - templateUrl: 'views/ambariViews/create.html', - controller: 'CreateViewInstanceCtrl' + controller: 'ViewUrlEditCtrl', + label: 'Views' } }, stackVersions: { list: { url: '/stackVersions', templateUrl: 'views/stackVersions/list.html', - controller: 'StackVersionsListCtrl' + controller: 'StackVersionsListCtrl', + label: 'Versions' }, create: { url: '/stackVersions/create', templateUrl: 'views/stackVersions/stackVersionPage.html', - controller: 'StackVersionsCreateCtrl' + controller: 'StackVersionsCreateCtrl', + label: 'Versions' }, edit: { url: '/stackVersions/:stackName/:versionId/edit', templateUrl: 'views/stackVersions/stackVersionPage.html', - controller: 'StackVersionsEditCtrl' + controller: 'StackVersionsEditCtrl', + label: 'Versions' } }, remoteClusters: { list: { url: '/remoteClusters', templateUrl: 'views/remoteClusters/list.html', - controller: 'RemoteClustersListCtrl' + controller: 'RemoteClustersListCtrl', + label: 'Remote Clusters' }, create: { url: '/remoteClusters/create', templateUrl: 'views/remoteClusters/remoteClusterPage.html', - controller: 'RemoteClustersCreateCtrl' + controller: 'RemoteClustersCreateCtrl', + label: 'Remote Clusters' }, - edit: { - url: '/remoteClusters/:clusterName/edit', - templateUrl: 'views/remoteClusters/editRemoteClusterPage.html', - controller: 'RemoteClustersEditCtrl' - } + edit: { + url: '/remoteClusters/:clusterName/edit', + templateUrl: 'views/remoteClusters/editRemoteClusterPage.html', + controller: 'RemoteClustersEditCtrl', + label: 'Remote Clusters' + } }, clusters: { - manageAccess: { - url: '/clusters/:id/manageAccess', - templateUrl: 'views/clusters/manageAccess.html', - controller: 'ClustersManageAccessCtrl' - }, - userAccessList: { - url: '/clusters/:id/userAccessList', - templateUrl: 'views/clusters/userAccessList.html', - controller: 'UserAccessListCtrl' - }, - exportBlueprint: { - url: '/clusters/:id/exportBlueprint', - templateUrl: 'views/clusters/exportBlueprint.html', - controller: 'ExportBlueprintCtrl' + clusterInformation: { + url: '/clusterInformation', + templateUrl: 'views/clusters/clusterInformation.html', + controller: 'ClusterInformationCtrl', + label: 'Cluster Information' } }, - dashboard:{ + dashboard: { url: '/dashboard', - controller: ['$window', function($window) { + controller: ['$window', function ($window) { $window.location.replace('/#/main/dashboard'); }], template: '' } }) -.config(['$routeProvider', '$locationProvider', 'ROUTES', function($routeProvider, $locationProvider, ROUTES) { - var createRoute = function(routeObj) { - if(routeObj.url){ +.config(['$routeProvider', '$locationProvider', 'ROUTES', function ($routeProvider, $locationProvider, ROUTES) { + var createRoute = function (routeObj) { + if (routeObj.url) { $routeProvider.when(routeObj.url, routeObj); } else { angular.forEach(routeObj, createRoute); } }; + var rootUrl = ROUTES['clusters']['clusterInformation'].url; angular.forEach(ROUTES, createRoute); + $routeProvider.otherwise({ + redirectTo: rootUrl + }); }]) -.run(['$rootScope', 'ROUTES', 'Settings', function($rootScope, ROUTES, Settings) { +.run(['$rootScope', 'ROUTES', 'Settings', function ($rootScope, ROUTES, Settings) { // Make routes available in every template and controller $rootScope.ROUTES = ROUTES; $rootScope.$on('$locationChangeStart', function (e, nextUrl) { @@ -215,7 +182,7 @@ angular.module('ambariAdminConsole') * @param {string} url * @returns {string} */ - $rootScope.fromSiteRoot = function(url) { + $rootScope.fromSiteRoot = function (url) { var path = url[0] === '/' ? url.substring(1) : url; return Settings.siteRoot + path; }; http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js index 0f9b582..30ef91a 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Cluster.js @@ -18,7 +18,11 @@ 'use strict'; angular.module('ambariAdminConsole') -.factory('Cluster', ['$http', '$q', 'Settings', function($http, $q, Settings) { +.factory('Cluster', ['$http', '$q', 'Settings', '$translate', function($http, $q, Settings, $translate) { + var $t = $translate.instant; + var permissions = null; + var rolesWithAuthorizations = null; + return { repoStatusCache : {}, @@ -34,6 +38,13 @@ angular.module('ambariAdminConsole') ineditableRoles : ['VIEW.USER', 'AMBARI.ADMINISTRATOR'], + sortRoles: function(roles) { + var orderedRoles = ['AMBARI.ADMINISTRATOR'].concat(this.orderedRoles); + return roles.sort(function(a, b) { + return orderedRoles.indexOf(a.permission_name) - orderedRoles.indexOf(b.permission_name); + }); + }, + getAllClusters: function() { var deferred = $q.defer(); $http.get(Settings.baseUrl + '/clusters?fields=Clusters/cluster_id', {mock: 'cluster/clusters.json'}) @@ -120,22 +131,48 @@ angular.module('ambariAdminConsole') return deferred.promise; }, + getRoleOptions: function () { + var roleOptions = []; + var deferred = $q.defer(); + var localDeferred = $q.defer(); + var promise = permissions ? localDeferred.promise : this.getPermissions(); + + localDeferred.resolve(permissions); + promise.then(function(data) { + permissions = data; + roleOptions = data.map(function(item) { + return item.PermissionInfo; + }); + roleOptions.unshift({ + permission_name: 'NONE', + permission_label: $t('users.roles.none') + }); + }).finally(function() { + deferred.resolve(roleOptions); + }); + return deferred.promise; + }, getRolesWithAuthorizations: function() { - var self = this; var deferred = $q.defer(); - $http({ - method: 'GET', - url: Settings.baseUrl + '/permissions?PermissionInfo/resource_name.in(CLUSTER,AMBARI)', - mock: 'permission/permissions.json', - params: { - fields: 'PermissionInfo/*,authorizations/AuthorizationInfo/*' - } - }) - .success(function(data) { - deferred.resolve(data.items); + if (rolesWithAuthorizations) { + deferred.resolve(rolesWithAuthorizations); + } else { + $http({ + method: 'GET', + url: Settings.baseUrl + '/permissions?PermissionInfo/resource_name.in(CLUSTER,AMBARI)', + mock: 'permission/permissions.json', + params: { + fields: 'PermissionInfo/*,authorizations/AuthorizationInfo/*' + } }) - .catch(function(data) { - deferred.reject(data); }); + .success(function (data) { + rolesWithAuthorizations = data.items; + deferred.resolve(data.items); + }) + .catch(function (data) { + deferred.reject(data); + }); + } return deferred.promise; }, @@ -159,31 +196,6 @@ angular.module('ambariAdminConsole') return deferred.promise; }, - getPrivilegesWithFilters: function(params) { - var deferred = $q.defer(); - var isUser = params.typeFilter.value == 'USER'; - var endpoint = isUser? '/users' : '/groups'; - var nameURL = isUser? '&Users/user_name.matches(.*' : '&Groups/group_name.matches(.*'; - var nameFilter = params.nameFilter? nameURL + params.nameFilter + '.*)' : ''; - var roleFilter = params.roleFilter.value? '&privileges/PrivilegeInfo/permission_name.matches(.*' + params.roleFilter.value + '.*)' : ''; - $http({ - method: 'GET', - url: Settings.baseUrl + endpoint + '?' - + 'fields=privileges/PrivilegeInfo/*' - + nameFilter - + roleFilter - + '&from=' + (params.currentPage - 1) * params.usersPerPage - + '&page_size=' + params.usersPerPage - }) - .success(function(data) { - deferred.resolve(data); - }) - .catch(function(data) { - deferred.reject(data); - }); - - return deferred.promise; - }, getPrivilegesForResource: function(params) { var deferred = $q.defer(); var isUser = (params.typeFilter.value == 'USER'); http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Group.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Group.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Group.js index f52a7e5..0509e11 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Group.js +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Group.js @@ -18,49 +18,29 @@ 'use strict'; angular.module('ambariAdminConsole') -.factory('Group', ['$http', '$q', 'Settings', 'GroupConstants', '$translate', function($http, $q, Settings, GroupConstants, $translate) { +.factory('Group', ['$http', '$q', 'Settings', '$translate', 'Cluster', function($http, $q, Settings, $translate, Cluster) { var $t = $translate.instant; - function Group(item){ - if(typeof item === 'string'){ - this.group_name = item; - } else if(typeof item === 'object'){ - angular.extend(this, item.Groups); - this.getMembers(); + var types = { + LOCAL: { + VALUE: 'LOCAL', + LABEL_KEY: 'common.local' + }, + PAM: { + VALUE: 'PAM', + LABEL_KEY: 'common.pam' + }, + LDAP: { + VALUE: 'LDAP', + LABEL_KEY: 'common.ldap' } - } + }; - Group.prototype.isLDAP = function() { - var deferred = $q.defer(); - var self = this; - if( typeof this.ldap_group === 'boolean' ){ - deferred.resolve(this.ldap_group) - } else { - $http({ - method: 'GET', - url: Settings.baseUrl + '/groups/'+this.group_name - }). - success(function(data) { - self.ldap_group = data.Groups.ldap_group; - deferred.resolve(self.ldap_group); - }); + function Group(item) { + if (typeof item === 'string') { + this.group_name = item; + } else if (typeof item === 'object') { + angular.extend(this, item.Groups); } - - return deferred.promise; - } - - Group.prototype.getGroupType = function() { - var deferred = $q.defer(); - var self = this; - $http({ - method: 'GET', - url: Settings.baseUrl + '/groups/'+this.group_name - }). - success(function(data) { - self.group_type = data.Groups.group_type; - deferred.resolve(self.group_type); - }); - - return deferred.promise; } Group.prototype.save = function() { @@ -86,28 +66,6 @@ angular.module('ambariAdminConsole') return deferred.promise; }; - Group.prototype.getMembers = function() { - var deferred = $q.defer(); - var self = this; - - $http({ - method: 'GET', - url: Settings.baseUrl + '/groups/' + this.group_name + '/members' - }) - .success(function(data) { - self.members = []; - angular.forEach(data.items, function(member) { - self.members.push(member.MemberInfo.user_name); - }); - deferred.resolve(self.members); - }) - .error(function(data) { - deferred.reject(data); - }); - - return deferred.promise; - }; - Group.prototype.saveMembers = function() { var self = this; var deferred = $q.defer(); @@ -132,27 +90,6 @@ angular.module('ambariAdminConsole') deferred.reject(data); }); return deferred.promise; - } - - Group.prototype.addMember = function(memberName) { - var deferred = $q.defer(); - - $http({ - method: 'POST', - url: Settings.baseUrl + '/groups/' + this.group_name + '/members' + '/'+ encodeURIComponent(member.user_name) - }) - .success(function(data) { - deferred.resolve(data) - }) - .error(function(data) { - deferred.reject(data); - }); - - return deferred.promise; - }; - - Group.prototype.removeMember = function(memberId) { - return $http.delete(Settings.baseUrl + '/groups/'+this.group_name+'/members/'+memberId); }; Group.removeMemberFromGroup = function(groupName, memberName) { @@ -174,14 +111,8 @@ angular.module('ambariAdminConsole') + (params.group_type === '*' ? '' : '&Groups/group_type=' + params.group_type) ) .success(function(data) { - var groups = []; - if(Array.isArray(data.items)){ - angular.forEach(data.items, function(item) { - groups.push(new Group(item)); - }); - } - groups.itemTotal = data.itemTotal; - deferred.resolve(groups); + data.items.itemTotal = data.itemTotal; + deferred.resolve(data.items); }) .error(function(data) { deferred.reject(data); @@ -204,6 +135,23 @@ angular.module('ambariAdminConsole') }); }; + Group.get = function (group_name) { + var deferred = $q.defer(); + $http({ + method: 'GET', + url: Settings.baseUrl + '/groups/' + group_name + + '?fields=Groups,privileges/PrivilegeInfo/*,members/MemberInfo' + }).success(function (data) { + deferred.resolve(Group.makeGroup(data)); + }); + + return deferred.promise; + }; + + Group.getTypes = function () { + return types; + }; + /** * Generate group info to display by response data from API. * Generally this is a single point to manage all required and useful data @@ -212,9 +160,19 @@ angular.module('ambariAdminConsole') * @param {Object} group - object from API response * @returns {Object} */ - Group.makeGroup = function(group) { - group.groupTypeName = $t(GroupConstants.TYPES[group.group_type].LABEL_KEY); - return group; + Group.makeGroup = function(data) { + var group = new Group(data.Groups.group_name); + group.groupTypeName = $t(types[data.Groups.group_type].LABEL_KEY); + group.group_type = data.Groups.group_type; + group.ldap_group = data.Groups.ldap_group; + group.privileges = data.privileges; + group.members = data.members; + group.roles = Cluster.sortRoles(data.privileges.filter(function(item) { + return item.PrivilegeInfo.type === 'CLUSTER' || item.PrivilegeInfo.type === 'AMBARI'; + }).map(function(item) { + return item.PrivilegeInfo; + })); + return group; }; return Group; http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/GroupConstants.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/GroupConstants.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/GroupConstants.js deleted file mode 100644 index 42e8d73..0000000 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/GroupConstants.js +++ /dev/null @@ -1,38 +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').constant('GroupConstants', { - /** - * Available group_types 'values' and 'labels' map. - */ - TYPES: { - LOCAL: { - VALUE: 'LOCAL', - LABEL_KEY: 'common.local' - }, - PAM: { - VALUE: 'PAM', - LABEL_KEY: 'common.pam' - }, - LDAP: { - VALUE: 'LDAP', - LABEL_KEY: 'common.ldap' - } - } -}); http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RoleDetailsModal.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RoleDetailsModal.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RoleDetailsModal.js index 06019c2..7b01116 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RoleDetailsModal.js +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RoleDetailsModal.js @@ -22,11 +22,10 @@ angular.module('ambariAdminConsole') return { show: function(roles) { roles = roles.map(function(role) { - role.authorizations = role.authorizations.map(function(authorization) { + var r = role.PermissionInfo; + r.authorizations = role.authorizations.map(function(authorization) { return authorization.AuthorizationInfo; }); - var r = role.PermissionInfo; - r.authorizations = role.authorizations; return r; }); var modalInstance = $modal.open({ http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Stack.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Stack.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Stack.js index 8003dd1..90f4f48 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Stack.js +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Stack.js @@ -87,6 +87,20 @@ angular.module('ambariAdminConsole') return deferred.promise; }, + getGPLLicenseAccepted: function() { + var deferred = $q.defer(); + + $http.get(Settings.baseUrl + '/services/AMBARI/components/AMBARI_SERVER?fields=RootServiceComponents/properties/gpl.license.accepted&minimal_response=true', {mock: 'true'}) + .then(function(data) { + deferred.resolve(data.data.RootServiceComponents.properties['gpl.license.accepted']); + }) + .catch(function(data) { + deferred.reject(data); + }); + + return deferred.promise; + }, + allPublicStackVersions: function() { var self = this; var url = '/version_definitions?fields=VersionDefinition/stack_default,VersionDefinition/type,' + http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js index ac50653..7932d9b 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js @@ -18,7 +18,7 @@ 'use strict'; angular.module('ambariAdminConsole') - .factory('User', ['Restangular', '$http', 'Settings', 'UserConstants', '$translate', function(Restangular, $http, Settings, UserConstants, $translate) { +.factory('User', ['Restangular', '$http', 'Settings', 'UserConstants', '$translate', 'Cluster', function(Restangular, $http, Settings, UserConstants, $translate, Cluster) { Restangular.addResponseInterceptor(function(data, operation, what, url, response, deferred) { var extractedData; if(operation === 'getList'){ @@ -31,14 +31,13 @@ angular.module('ambariAdminConsole') return extractedData; }); var $t = $translate.instant; - var Users = Restangular.all('users'); return { list: function(params) { return $http.get( Settings.baseUrl + '/users/?' + 'Users/user_name.matches(.*'+params.searchString+'.*)' - + '&fields=*' + + '&fields=privileges/PrivilegeInfo/*,Users' + '&from=' + (params.currentPage-1)*params.usersPerPage + '&page_size=' + params.usersPerPage + (params.user_type === '*' ? '' : '&Users/user_type=' + params.user_type) @@ -53,6 +52,12 @@ angular.module('ambariAdminConsole') + '&from=0&page_size=20' ); }, + getWithRoles: function(userId) { + return $http.get( + Settings.baseUrl + '/users/' + userId + + '?fields=privileges/PrivilegeInfo,Users' + ); + }, get: function(userId) { return Restangular.one('users', userId).get(); }, @@ -94,9 +99,14 @@ angular.module('ambariAdminConsole') * @returns {Object} */ makeUser: function(user) { - user.Users.encoded_name = encodeURIComponent(user.Users.user_name); + user.Users.encodedName = encodeURIComponent(user.Users.user_name); user.Users.userTypeName = $t(UserConstants.TYPES[user.Users.user_type].LABEL_KEY); - user.Users.ldap_user = user.Users.user_type === UserConstants.TYPES.LDAP.VALUE; + user.Users.ldapUser = user.Users.user_type === UserConstants.TYPES.LDAP.VALUE; + user.Users.roles = Cluster.sortRoles(user.privileges.filter(function(item) { + return item.PrivilegeInfo.type === 'CLUSTER' || item.PrivilegeInfo.type === 'AMBARI'; + }).map(function(item) { + return item.PrivilegeInfo; + })); return user; } http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/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 f549b29..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 @@ -61,32 +61,6 @@ angular.module('ambariAdminConsole') angular.element(this,item); } - ViewUrl.all = function(params) { - var deferred = $q.defer(); - - $http({ - method: 'GET', - dataType: "json", - url: Settings.baseUrl + '/view/urls?' - + 'ViewUrlInfo/url_name.matches(.*'+params.searchString+'.*)' - + '&ViewUrlInfo/url_suffix.matches(.*'+params.suffixSearch+'.*)' - + '&fields=*' - + '&from=' + (params.currentPage-1)*params.urlsPerPage - + '&page_size=' + params.urlsPerPage - + (params.instanceType === '*' ? '' : '&ViewUrlInfo/view_instance_common_name=' + params.instanceType) - - }) - .success(function(data) { - deferred.resolve(new ViewUrl(data)); - }) - .error(function(data) { - deferred.reject(data); - }); - - return deferred.promise; - }; - - ViewUrl.updateShortUrl = function(payload){ var deferred = $q.defer(); @@ -176,7 +150,7 @@ angular.module('ambariAdminConsole') var versions = {}; angular.forEach(item.versions, function(version) { versions[version.ViewVersionInfo.version] = {count: version.instances.length, status: version.ViewVersionInfo.status}; - if(version.ViewVersionInfo.status === 'DEPLOYED'){ // if atelast one version is deployed + if (version.ViewVersionInfo.status === 'DEPLOYED'){ // if at least one version is deployed self.canCreateInstance = true; } @@ -203,10 +177,6 @@ angular.module('ambariAdminConsole') return ViewInstance.find(viewName, version, instanceName); }; - View.allUrls = function(req){ - return ViewUrl.all(req) - }; - View.getUrlInfo = function(urlName){ return ViewUrl.urlInfo(urlName); }; @@ -316,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 } }); @@ -327,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/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/scripts/theme/bootstrap-ambari.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/theme/bootstrap-ambari.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/theme/bootstrap-ambari.js new file mode 100644 index 0000000..434d1e9 --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/theme/bootstrap-ambari.js @@ -0,0 +1,269 @@ +/** + * 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'; + +$(document).ready(function () { + var $accordionToggler = $(this).find('[data-toggle="collapseAccordion"]'); + $accordionToggler.off('click').on('click', function (event) { + var $this = $(this); + $this.siblings('.panel-body').slideToggle(500); + $this.children().children('.panel-toggle').toggleClass('fa-angle-down fa-angle-up'); + event.stopPropagation(); + return false; + }); +}); +'use strict'; + +(function ($) { + + /** + * jQuery plugin for navigation bars + * Usage: + * <pre> + * $('.navigation-bar').navigationBar(); + * </pre> + * + * @param {object} options see <code>$.fn.navigationBar.defaults</code> + * @returns {$} + */ + + $.fn.navigationBar = function (options) { + + var settings = $.extend({}, $.fn.navigationBar.defaults, options); + + return this.each(function () { + var _this = this; + + var containerSelector = '.navigation-bar-container'; + var $navigationContainer = $(this).find(containerSelector); + var $sideNavToggler = $(this).find('[data-toggle=' + settings.navBarToggleDataAttr + ']'); + var $subMenuToggler = $(this).find('[data-toggle=' + settings.subMenuNavToggleDataAttr + ']'); + var firstLvlMenuItemsSelector = '.side-nav-menu>li'; + var secondLvlMenuItemsSelector = '.side-nav-menu>li>ul>li'; + var $moreActions = $(this).find('.more-actions'); + var $dropdownMenu = $moreActions.children('.dropdown-menu'); + + $subMenuToggler.each(function (index, toggler) { + return $(toggler).parent().addClass('has-sub-menu'); + }); + + if (settings.fitHeight) { + $(this).addClass('navigation-bar-fit-height'); + + // make scrolling effect on side nav ONLY, i.e. not effected on ambari main contents + $(this).find('.side-nav-menu').on('DOMMouseScroll mousewheel', function (ev) { + var $this = $(this), + scrollTop = this.scrollTop, + scrollHeight = this.scrollHeight, + height = $this.innerHeight(), + delta = ev.originalEvent.wheelDelta, + up = delta > 0; + var prevent = function prevent() { + ev.stopPropagation(); + ev.preventDefault(); + ev.returnValue = false; + return false; + }; + + if (!up && -delta > scrollHeight - height - scrollTop) { + // Scrolling down, but this will take us past the bottom. + $this.scrollTop(scrollHeight); + return prevent(); + } else if (up && delta > scrollTop) { + // Scrolling up, but this will take us past the top. + $this.scrollTop(0); + return prevent(); + } + }); + } + + //set main content left margin based on the width of side-nav + var containerWidth = $navigationContainer.width(); + if (settings.moveLeftContent) { + $(settings.content).css('margin-left', containerWidth); + } + if (settings.moveLeftFooter) { + $(settings.footer).css('margin-left', containerWidth); + } + + function popStateHandler() { + var path = window.location.pathname + window.location.hash; + $navigationContainer.find('li a').each(function (index, link) { + var $link = $(link); + var href = $link.attr('data-href') || $link.attr('href'); + if (path.indexOf(href) !== -1 && ['', '#'].indexOf(href) === -1) { + $link.parent().addClass('active'); + } else { + $link.parent().removeClass('active'); + } + }); + } + + if (settings.handlePopState) { + popStateHandler(); + $(window).bind('popstate', popStateHandler); + } + + function clickHandler(el) { + var $li = $(el).parent(); + var activeClass = settings.activeClass; + + var activeMenuItems = firstLvlMenuItemsSelector + '.' + activeClass; + var activeSubMenuItems = secondLvlMenuItemsSelector + '.' + activeClass; + $navigationContainer.find(activeMenuItems).removeClass(activeClass); + $navigationContainer.find(activeSubMenuItems).removeClass(activeClass); + $li.addClass(activeClass); + } + + /** + * Click on menu item + */ + $(firstLvlMenuItemsSelector + '>a').on('click', function () { + clickHandler(this); + }); + + /** + * Click on sub menu item + */ + $(secondLvlMenuItemsSelector + '>a').on('click', function () { + clickHandler(this); + $(this).parent().parent().parent().addClass(settings.activeClass); + }); + + /** + * Slider for sub menu + */ + $subMenuToggler.off('click').on('click', function (event) { + // ignore click if navigation-bar is collapsed + if ($navigationContainer.hasClass('collapsed')) { + return false; + } + var $this = $(this); + $this.siblings('.sub-menu').slideToggle(600, function () { + var $topMenuItem = $this.parent(); + var $subMenu = $topMenuItem.find('ul'); + return $subMenu.is(':visible') ? $topMenuItem.removeClass('collapsed') : $topMenuItem.addClass('collapsed'); + }); + $this.children('.toggle-icon').toggleClass(settings.menuLeftClass + ' ' + settings.menuDownClass); + event.stopPropagation(); + return false; + }); + + if (settings.fitHeight) { + $moreActions.on('click', function () { + // set actions submenu position + var $moreIcon = $(this); + var $header = $('.side-nav-header'); + $dropdownMenu.css({ + top: $moreIcon.offset().top - $header.offset().top + 20 + 'px', + left: $moreIcon.offset().left + 'px' + }); + }); + } + $dropdownMenu.on('click', function () { + // some action was triggered, should hide this icon + var moreIcon = $(this).parent(); + setTimeout(function () { + moreIcon.hide(); + }, 1000); + }); + $navigationContainer.children('.side-nav-menu').scroll(function () { + $moreActions.removeClass('open'); + }); + + /** + * Expand/collapse navigation bar + */ + $sideNavToggler.click(function () { + + $navigationContainer.toggleClass('collapsed').promise().done(function () { + var subMenuSelector = 'ul.sub-menu'; + var $subMenus = $navigationContainer.find(subMenuSelector); + var $subMenuItems = $navigationContainer.find('.side-nav-menu>li'); + if ($navigationContainer.hasClass('collapsed')) { + // set sub menu invisible when collapsed + $subMenus.hide(); + $moreActions.hide(); + // set the hover effect when collapsed, should show sub-menu on hovering + $subMenuItems.hover(function () { + $(this).find(subMenuSelector).show(); + // set sub-menu position + var $parent = $(this); + var $header = $('.side-nav-header'); + if (settings.fitHeight) { + $(this).find(subMenuSelector).css({ + position: 'fixed', + top: $parent.offset().top - $header.offset().top + 'px', + left: 50 + 'px' + }); + } + }, function () { + $(this).find(subMenuSelector).hide(); + }); + } else { + // keep showing all sub menu + $subMenus.show().each(function (index, item) { + return $(item).parent().removeClass('collapsed'); + }); + $subMenuItems.unbind('mouseenter mouseleave'); + $navigationContainer.find('.toggle-icon').removeClass(settings.menuLeftClass).addClass(settings.menuDownClass); + $moreActions.show(); + // set sub-menu position + if (settings.fitHeight) { + $(_this).find(subMenuSelector).css({ + position: 'relative', + top: 0, + left: 0 + }); + } + } + + $navigationContainer.on('transitionend', function () { + //set main content left margin based on the width of side-nav + var containerWidth = $navigationContainer.width(); + if (settings.moveLeftContent) { + $(settings.content).css('margin-left', containerWidth); + } + if (settings.moveLeftFooter) { + $(settings.footer).css('margin-left', containerWidth); + } + }); + $sideNavToggler.find('span').toggleClass(settings.collapseNavBarClass + ' ' + settings.expandNavBarClass); + }); + return false; + }); + }); + }; + + $.fn.navigationBar.defaults = { + handlePopState: true, + fitHeight: false, + content: '#main', + footer: 'footer', + moveLeftContent: true, + moveLeftFooter: true, + menuLeftClass: 'glyphicon-menu-right', + menuDownClass: 'glyphicon-menu-down', + collapseNavBarClass: 'fa-angle-double-left', + expandNavBarClass: 'fa-angle-double-right', + activeClass: 'active', + navBarToggleDataAttr: 'collapse-side-nav', + subMenuNavToggleDataAttr: 'collapse-sub-menu' + }; +})(jQuery); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/styles/cluster-information.css ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/cluster-information.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/cluster-information.css new file mode 100644 index 0000000..64e9ecb --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/cluster-information.css @@ -0,0 +1,58 @@ +/** + * 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. + */ + +#cluster-information .cluster-name label { + font-weight: normal; +} + +#cluster-information .dev-blueprint { + line-height: 35px; +} + +#cluster-information .dev-blueprint span { + vertical-align: text-top; +} + +#cluster-information .cluster-name input { + width: 75%; +} + +#cluster-information .cluster-name button { + margin-top: -34px; +} + +#cluster-information .cluster-name input.edited { + background-color: #fdfbdd; +} + +#cluster-information .welcome-header { + margin: -15px; + padding: 15px 15px 40px 15px; + background-color: #f0f0f0; + text-align: center; +} + +#cluster-information .create-cluster-section { + text-align: center; + padding: 30px; +} + +#cluster-information .fa-cloud { + font-size: 150px; + color: #f0f0f0; +} http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/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 946007d..b4aa558 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 @@ -123,14 +123,6 @@ transition: none; } -.cluster-installation-progress-label{ - display: block; - color: #888; - text-align: center; - padding: 10px 0; - cursor: default; -} - .add-item-input span{ display: block; outline: none; @@ -236,96 +228,6 @@ .paginator{ margin: 0; } -.mainpage .panel-body{ - padding: 20px; - height: 620px; -} -.mainpage h1{ - font-size: 24px; - margin-top: 10px; -} -.mainpage .panel-body #main-operations-boxes { - padding: 10px; -} -.mainpage .panel-body #main-operations-boxes .thumbnail{ - display: block; - height: 230px; - padding: 8px; - background-color: #eeeeee; - margin-bottom: 20px; - margin-left: 20px; - margin-right: 10px; - border: none; - border-radius: 0; -} -.mainpage .panel-body #main-operations-boxes .thumbnail .title, -.mainpage .panel-body #main-operations-boxes .thumbnail .description, -.mainpage .panel-body #main-operations-boxes .thumbnail .buttons { - text-align: center; - line-height: 1.5; -} -.mainpage .panel-body #main-operations-boxes .thumbnail .buttons .btn{ - width: 200px; - margin: 5px; -} -.mainpage .panel-body #main-operations-boxes .thumbnail .buttons .btn.userslist-button, -.mainpage .panel-body #main-operations-boxes .thumbnail .buttons .btn.groupslist-button { - width: 100px; -} -.mainpage .panel-body #main-operations-boxes .thumbnail .glyphicon { - font-size: 50px; - text-align: center; - display: block; - line-height: 1.5; -} -.mainpage .panel-body #main-operations-boxes .col-sm-5 { - width: 43.5%; -} - -.views-list-table .panel{ - border-radius: 0; - border: none; - margin-top: 0; -} -.views-list-table h4{ - font-size: 14px; -} -.views-list-table .panel-group .panel + .panel{ - margin-top: 0; -} -.views-list-table .panel-group .panel .panel-heading{ - border-radius: 0; - border-top: 1px solid #ddd; -} -.views-list-table .panel-group .panel .panel-heading{ - background: #f9f9f9; -} -.views-list-table .panel-group .panel:nth-child(even) .panel-heading{ - background: none; -} -.views-list-table .panel-group .panel .panel-heading .panel-title{ - font-size: 14px; - font-weight: normal; - cursor: pointer; -} -.views-list-table .panel-group .panel .panel-body{ - padding-top: 0; - padding-bottom: 0; -} -.views-list-table .panel-group .panel .panel-body table tr:first-child td{ - border-top: none; -} -.views-list-table .glyphicon.glyphicon-chevron-right{ - -webkit-transition: all 0.3s; - -o-transition: all 0.3s; - transition: all 0.3s; -} -.views-list-table .glyphicon.glyphicon-chevron-right.opened{ - -webkit-transform: rotateZ(90deg); - -ms-transform: rotateZ(90deg); - -o-transform: rotateZ(90deg); - transform: rotateZ(90deg); -} a.gotoinstance{ font-size: 12px; @@ -345,6 +247,9 @@ a.gotoinstance{ .hide-soft{ display: none; } +.nowrap { + white-space: nowrap; +} .visible{ display: block; } @@ -367,10 +272,6 @@ a.gotoinstance{ width: 14px; } -.namefilter { - font-weight: normal; -} - .settings-edit-toggle.disabled, .properties-toggle.disabled{ color: #999; cursor: not-allowed; @@ -411,84 +312,6 @@ a.gotoinstance{ font-size: 16px; } -.user-edit-panel .ats-switch span.switch-right , .create-user-form .ats-switch span.switch-right, .enable-ldap .ats-switch span.switch-right { - background-color: #da4f49; - color: white; -} -/* - Style topnav menu -*/ -.navbar-views-dropdown > a{ - color: #c3c3c3; - font-size: 1.3em; - padding: 10px 25px 18px; - display: block; - box-shadow: none!important; - background: none!important; - text-decoration: none; -} -.navbar-views-dropdown > a:hover{ - color: #fff; -} -.navbar-views-dropdown > a > i{ - display: block; - margin-top: 1px; - margin-bottom: -12px; -} -.navbar-views-dropdown .dropdown-menu, .verison-label-row .dropdown-menu { - margin-top: -2px; -} - -.navbar-views-dropdown .dropdown-menu a:hover{ - background: #666; - color: #fff; -} -.navbar-views-dropdown .dropdown-menu .disabled a:hover{ - background: none; - color: #999; -} -#top-nav .navbar.navbar-static-top{ - min-height: 40px; -} -#top-nav .navbar-inverse{ - background: none; - border: none; -} -#top-nav .navbar.navbar-static-top .navbar-inner { - background-color: #313d54; - -webkit-box-shadow: inset 0 0 0 rgba(0, 0, 0, 0.1), 0 1px 10px rgba(0, 0, 0, 0.1); - -moz-box-shadow: inset 0 0 0 rgba(0, 0, 0, 0.1), 0 1px 10px rgba(0, 0, 0, 0.1); - box-shadow: inset 0 0 0 rgba(0, 0, 0, 0.1), 0 1px 10px rgba(0, 0, 0, 0.1); - max-height: 40px; - height: 40px; -} -#top-nav .dropdown-toggle.navbar-btn{ - margin: 4px 0 0 0; -} -#top-nav .navbar.navbar-static-top .logo { - float: left; - padding-top: 2px; -} -#top-nav .navbar.navbar-static-top .logo img { - height: 32px; -} -#top-nav .navbar.navbar-static-top .brand { - color: #ffffff; - font-size: 16px; - font-weight: normal; - line-height: 32px; - margin-left: 0; - padding: 2px 5px 0 10px; - text-shadow: 0 1px 0 #555555; - display: block; - float: left; - text-decoration: none; - -} -#top-nav .navbar.navbar-static-top .brand.cluster-name{ - margin-left: 10px; -} - .create-view-form, .register-version-form, .edit-version-form { padding-bottom: 50px; } @@ -553,48 +376,13 @@ a.gotoinstance{ .search-container{ position: relative; } -.search-container .close{ +.search-container .close { position: absolute; right: 10px; - top: 32px; -} -.groups-pane .search-container .close{ - top: 32px; + top: 8px; } -.views-urls-table .search-container .close{ - top: 7px; - right: 10px; - z-index: 10; -} - -.views-list-table .search-container .close{ - right: 50px; - top: 7px; - z-index: 10; -} -.groups-pane table thead th{ - border-top: 0; -} -.groups-pane table thead tr:first-child th{ - border: 0; -} - -.container{ - padding-left: 0; - width: 940px; -} - - -@media (min-width: 1200px) { - .container, .navbar-static-top .container, .navbar-fixed-top .container, .navbar-fixed-bottom .container{ - width: 1130px; - } - .container{ - width: 1170px; - } - .mainpage .panel-body #main-operations-boxes .col-sm-5 { - width: 44%; - } +.search-container input { + font-weight: normal; } ul.nav li > a{ @@ -654,21 +442,14 @@ table.no-border tr td{ .no-border{ border: none !important; } -.top-margin-4{ - margin-top: 4px; -} + .table > thead > tr > th.vertical-top{ vertical-align: top; } -.groups-pane table ul{ - list-style-type: none; - margin: 0; - padding: 0; -} -.groups-pane table ul li { - margin: 0; - padding: 0; +.table td > .checkbox { + margin-bottom: 0; + margin-top: 0; } .property-form label{ @@ -701,318 +482,6 @@ table.no-border tr td{ /*.login-message-pane .well {height: 74px;} .login-message-pane input {margin-left: 3px;}*/ - -.btn { - display: inline-block; - *display: inline; - padding: 4px 14px; - margin-bottom: 0; - *margin-left: .3em; - font-size: 14px; - line-height: 20px; - *line-height: 20px; - color: #333333; - text-align: center; - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); - vertical-align: middle; - cursor: pointer; - background-color: #f5f5f5; - *background-color: #e6e6e6; - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); - background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); - background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); - background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); - background-repeat: repeat-x; - border: 1px solid #bbbbbb; - *border: 0; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - border-color: #e6e6e6 #e6e6e6 #bfbfbf; - border-bottom-color: #a2a2a2; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); - filter: progid:dximagetransform.microsoft.gradient(enabled=false); - *zoom: 1; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.btn:hover, -.btn:active, -.btn.active, -.btn.disabled, -.btn[disabled] { - color: #333333; - background-color: #e6e6e6; - *background-color: #d9d9d9; -} - -.btn:active, -.btn.active { - background-color: #cccccc \9; -} - -.btn:first-child { - *margin-left: 0; -} - -.btn:hover { - color: #333333; - text-decoration: none; - background-color: #e6e6e6; - *background-color: #d9d9d9; - /* Buttons in IE7 don't get borders, so darken on hover */ - - background-position: 0 -15px; - -webkit-transition: background-position 0.1s linear; - -moz-transition: background-position 0.1s linear; - -o-transition: background-position 0.1s linear; - transition: background-position 0.1s linear; -} - -.btn:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -.btn.active, -.btn:active { - background-color: #e6e6e6; - background-color: #d9d9d9 \9; - background-image: none; - outline: 0; - -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.btn.disabled, -.btn[disabled] { - cursor: default; - background-color: #e6e6e6; - background-image: none; - opacity: 0.65; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} - - - -.btn-primary.active, -.btn-warning.active, -.btn-danger.active, -.btn-success.active, -.btn-info.active, -.btn-inverse.active { - color: rgba(255, 255, 255, 0.75); -} - -.btn { - border-color: #c5c5c5; - border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); -} - -.btn-primary { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #006dcc; - *background-color: #0044cc; - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); - background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); - background-image: -o-linear-gradient(top, #0088cc, #0044cc); - background-image: linear-gradient(to bottom, #0088cc, #0044cc); - background-image: -moz-linear-gradient(top, #0088cc, #0044cc); - background-repeat: repeat-x; - border-color: #0044cc #0044cc #002a80; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); - filter: progid:dximagetransform.microsoft.gradient(enabled=false); -} - -.btn-primary:hover, -.btn-primary:active, -.btn-primary.active, -.btn-primary.disabled, -.btn-primary[disabled], -.btn-primary.disabled:hover, -.btn-primary[disabled]:hover - { - color: #ffffff; - background-color: #0044cc; - *background-color: #003bb3; -} - -.btn-primary:active, -.btn-primary.active { - background-color: #003399 \9; -} - -.btn-warning { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #faa732; - *background-color: #f89406; - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); - background-image: -webkit-linear-gradient(top, #fbb450, #f89406); - background-image: -o-linear-gradient(top, #fbb450, #f89406); - background-image: linear-gradient(to bottom, #fbb450, #f89406); - background-image: -moz-linear-gradient(top, #fbb450, #f89406); - background-repeat: repeat-x; - border-color: #f89406 #f89406 #ad6704; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:dximagetransform.microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); - filter: progid:dximagetransform.microsoft.gradient(enabled=false); -} - -.btn-warning:hover, -.btn-warning:active, -.btn-warning.active, -.btn-warning.disabled, -.btn-warning[disabled] { - color: #ffffff; - background-color: #f89406; - *background-color: #df8505; -} - -.btn-warning:active, -.btn-warning.active { - background-color: #c67605 \9; -} - -.btn-danger { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #da4f49; - *background-color: #bd362f; - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); - background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); - background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); - background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); - background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); - background-repeat: repeat-x; - border-color: #bd362f #bd362f #802420; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0); - filter: progid:dximagetransform.microsoft.gradient(enabled=false); -} - -.btn-danger:hover, -.btn-danger:active, -.btn-danger.active, -.btn-danger.disabled, -.btn-danger[disabled] { - color: #ffffff; - background-color: #bd362f; - *background-color: #a9302a; -} - -.btn-danger:active, -.btn-danger.active { - background-color: #942a25 \9; -} - -.btn-success { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #5bb75b; - *background-color: #51a351; - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); - background-image: -webkit-linear-gradient(top, #62c462, #51a351); - background-image: -o-linear-gradient(top, #62c462, #51a351); - background-image: linear-gradient(to bottom, #62c462, #51a351); - background-image: -moz-linear-gradient(top, #62c462, #51a351); - background-repeat: repeat-x; - border-color: #51a351 #51a351 #387038; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0); - filter: progid:dximagetransform.microsoft.gradient(enabled=false); -} - -.btn-success:hover, -.btn-success:active, -.btn-success.active, -.btn-success.disabled, -.btn-success[disabled] { - color: #ffffff; - background-color: #51a351; - *background-color: #499249; -} - -.btn-success:active, -.btn-success.active { - background-color: #408140 \9; -} - -.btn-info { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #49afcd; - *background-color: #2f96b4; - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); - background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); - background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); - background-image: linear-gradient(to bottom, #5bc0de, #2f96b4); - background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); - background-repeat: repeat-x; - border-color: #2f96b4 #2f96b4 #1f6377; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0); - filter: progid:dximagetransform.microsoft.gradient(enabled=false); -} - -.btn-info:hover, -.btn-info:active, -.btn-info.active, -.btn-info.disabled, -.btn-info[disabled] { - color: #ffffff; - background-color: #2f96b4; - *background-color: #2a85a0; -} - -.btn-info:active, -.btn-info.active { - background-color: #24748c \9; -} - -.btn-inverse { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #363636; - *background-color: #222222; - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222)); - background-image: -webkit-linear-gradient(top, #444444, #222222); - background-image: -o-linear-gradient(top, #444444, #222222); - background-image: linear-gradient(to bottom, #444444, #222222); - background-image: -moz-linear-gradient(top, #444444, #222222); - background-repeat: repeat-x; - border-color: #222222 #222222 #000000; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0); - filter: progid:dximagetransform.microsoft.gradient(enabled=false); -} - -.btn-inverse:hover, -.btn-inverse:active, -.btn-inverse.active, -.btn-inverse.disabled, -.btn-inverse[disabled] { - color: #ffffff; - background-color: #222222; - *background-color: #151515; -} - -.btn-inverse:active, -.btn-inverse.active { - background-color: #080808 \9; -} - button.btn, input[type="submit"].btn { *padding-top: 3px; @@ -1048,6 +517,15 @@ button.btn.btn-xs{ font-size: 12px; line-height: 1.5; border-radius: 3px; + height: 24px; +} + +a.btn-primary, a.btn-primary:focus { + color: #fff; +} + +a.btn-default, a.btn-default:focus { + color: #666; } .clusterDisplayName { @@ -1085,6 +563,12 @@ a.alert-link, a.alert-link:hover, a.alert-link:visited{ color: #666; } +.empty-table-alert { + background-color: #f0f0f0; + text-align: center; + text-transform: uppercase; +} + .alert-container { position: fixed; top: 50px; @@ -1112,13 +596,13 @@ a.alert-link, a.alert-link:hover, a.alert-link:visited{ box-sizing: border-box; } -.fix-bottom{ +.fix-bottom th { border-bottom: none !important;; border-top: none !important; border-width: 0; } -.fix-top{ +.fix-top th { border-top: none !important; border-width: 0; } @@ -1160,7 +644,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 { @@ -1201,73 +689,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) } @@ -1321,15 +745,6 @@ accordion .panel-group .panel{ padding-left: 19px; } -.repo-version-inline { - left: 11%; -} - -.repo-version-inline .repo-version-label { - text-align: left; - -} - .repo-version-inline .dot { padding-right: 15px; } @@ -1664,6 +1079,7 @@ thead.view-permission-header > tr > th { } .register-version-form .details-panel .control-label { + line-height: 20px; text-align: left; padding: 7px 2px; font-weight: normal; @@ -1872,4 +1288,46 @@ legend { .ellipsis-overflow { overflow: hidden; text-overflow: ellipsis; -} \ No newline at end of file +} + +body { + height: 100%; + background-color: #f0f0f0; +} + +#main { + transition: .5s ease; + overflow: visible; + min-width: 980px; +} + +#side-nav .ambari-header-link:hover { + text-decoration: none; +} + +.main-container { + background-color: #fff; + padding: 15px; +} + +.navigation-bar-fit-height { + z-index: 1001; +} + +.entity-actions a { + color: inherit; + font-size: 16px; + cursor: pointer; + padding: 0 5px; +} + +td.entity-actions, +th.entity-actions { + width: 10%; +} + +.entity-actions a:hover, +.entity-actions a:visited:hover, +.entity-actions a:focus:hover { + text-decoration: none; +}
