diff --git a/awx/ui/client/src/configuration/configuration.block.less b/awx/ui/client/src/configuration/configuration.block.less
index 7cba028ef9..693fd9a9d5 100644
--- a/awx/ui/client/src/configuration/configuration.block.less
+++ b/awx/ui/client/src/configuration/configuration.block.less
@@ -97,11 +97,19 @@ input#filePickerText {
.Section-messageBar {
width: 120%;
margin-left: -20px;
- padding: 10px;
+ padding: 10px 10px 10px 20px;
color: @white;
background-color: @default-link;
}
+.Section-messageBar-text {
+ margin-left: @at-space-2x;
+}
+
+.Section-messageBar-warning {
+ color: @at-color-warning;
+}
+
.Section-messageBar--close {
position: absolute;
right: 0;
diff --git a/awx/ui/client/src/shared/form-generator.js b/awx/ui/client/src/shared/form-generator.js
index 892b156d5c..eee1106922 100644
--- a/awx/ui/client/src/shared/form-generator.js
+++ b/awx/ui/client/src/shared/form-generator.js
@@ -142,10 +142,10 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
.factory('GenerateForm', ['$rootScope', '$compile', 'generateList',
'Attr', 'Icon', 'Column',
'NavigationLink', 'HelpCollapse', 'Empty', 'SelectIcon',
- 'ActionButton', '$log', 'i18n',
+ 'ActionButton', 'MessageBar', '$log', 'i18n',
function ($rootScope, $compile, GenerateList,
Attr, Icon, Column, NavigationLink, HelpCollapse,
- Empty, SelectIcon, ActionButton, $log, i18n) {
+ Empty, SelectIcon, ActionButton, MessageBar, $log, i18n) {
return {
setForm: function (form) { this.form = form; },
@@ -177,6 +177,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat
else {
return `
${html}
diff --git a/awx/ui/client/src/shared/generator-helpers.js b/awx/ui/client/src/shared/generator-helpers.js
index f01b7110af..f365aeb042 100644
--- a/awx/ui/client/src/shared/generator-helpers.js
+++ b/awx/ui/client/src/shared/generator-helpers.js
@@ -766,4 +766,18 @@ angular.module('GeneratorHelpers', [systemStatus.name])
return html;
};
+})
+
+.factory('MessageBar', function() {
+ return function(options) {
+ let html = '';
+ if (_.has(options, 'messageBar')) {
+ let { messageBar } = options;
+ html += `
+
+ ${messageBar.message}
+
`;
+ }
+ return html;
+ };
});
diff --git a/awx/ui/client/src/teams/edit/teams-edit.controller.js b/awx/ui/client/src/teams/edit/teams-edit.controller.js
index 49c90c1316..41a37b19cb 100644
--- a/awx/ui/client/src/teams/edit/teams-edit.controller.js
+++ b/awx/ui/client/src/teams/edit/teams-edit.controller.js
@@ -5,17 +5,20 @@
*************************************************/
export default ['$scope', '$rootScope', '$stateParams', 'TeamForm', 'Rest',
- 'ProcessErrors', 'GetBasePath', 'Wait', '$state', 'OrgAdminLookup',
+ 'ProcessErrors', 'GetBasePath', 'Wait', '$state', 'OrgAdminLookup', 'resolvedModels',
function($scope, $rootScope, $stateParams, TeamForm, Rest, ProcessErrors,
- GetBasePath, Wait, $state, OrgAdminLookup) {
+ GetBasePath, Wait, $state, OrgAdminLookup, models) {
+ const { me } = models;
var form = TeamForm,
- id = $stateParams.team_id,
- defaultUrl = GetBasePath('teams') + id;
+ id = $stateParams.team_id,
+ defaultUrl = GetBasePath('teams') + id;
init();
function init() {
+ $scope.canEdit = me.get('summary_fields.user_capabilities.edit');
+ $scope.isOrgAdmin = me.get('related.admin_of_organizations.count') > 0;
$scope.team_id = id;
Rest.setUrl(defaultUrl);
Wait('start');
@@ -33,9 +36,7 @@ export default ['$scope', '$rootScope', '$stateParams', 'TeamForm', 'Rest',
});
$scope.$watch('team_obj.summary_fields.user_capabilities.edit', function(val) {
- if (val === false) {
- $scope.canAdd = false;
- }
+ $scope.canAdd = (val === false) ? false : true;
});
diff --git a/awx/ui/client/src/teams/list/teams-list.controller.js b/awx/ui/client/src/teams/list/teams-list.controller.js
index 32b90528f8..254629d30b 100644
--- a/awx/ui/client/src/teams/list/teams-list.controller.js
+++ b/awx/ui/client/src/teams/list/teams-list.controller.js
@@ -6,16 +6,18 @@
export default ['$scope', 'Rest', 'TeamList', 'Prompt',
'ProcessErrors', 'GetBasePath', 'Wait', '$state', '$filter',
- 'rbacUiControlService', 'Dataset', 'i18n',
+ 'rbacUiControlService', 'Dataset', 'resolvedModels', 'i18n',
function($scope, Rest, TeamList, Prompt, ProcessErrors,
- GetBasePath, Wait, $state, $filter, rbacUiControlService, Dataset, i18n) {
+ GetBasePath, Wait, $state, $filter, rbacUiControlService, Dataset, models, i18n) {
+ const { me } = models;
var list = TeamList,
defaultUrl = GetBasePath('teams');
init();
function init() {
+ $scope.canEdit = me.get('summary_fields.user_capabilities.edit');
$scope.canAdd = false;
rbacUiControlService.canAdd('teams')
diff --git a/awx/ui/client/src/teams/main.js b/awx/ui/client/src/teams/main.js
index f0ac982c7f..7140e9aaf9 100644
--- a/awx/ui/client/src/teams/main.js
+++ b/awx/ui/client/src/teams/main.js
@@ -41,6 +41,26 @@ angular.module('Teams', [])
activityStream: true,
activityStreamTarget: 'team'
},
+ resolve: {
+ edit: {
+ resolvedModels: ['MeModel', '$q', function(Me, $q) {
+ const promises = {
+ me: new Me('get').then((me) => me.extend('get', 'admin_of_organizations'))
+ };
+
+ return $q.all(promises);
+ }]
+ },
+ list: {
+ resolvedModels: ['MeModel', '$q', function(Me, $q) {
+ const promises = {
+ me: new Me('get')
+ };
+
+ return $q.all(promises);
+ }]
+ }
+ },
ncyBreadcrumb: {
label: N_('TEAMS')
}
diff --git a/awx/ui/client/src/teams/teams.form.js b/awx/ui/client/src/teams/teams.form.js
index 1314cbd183..855d8519d1 100644
--- a/awx/ui/client/src/teams/teams.form.js
+++ b/awx/ui/client/src/teams/teams.form.js
@@ -19,7 +19,10 @@ export default ['i18n', function(i18n) {
// the top-most node of generated state tree
stateTree: 'teams',
tabs: true,
-
+ messageBar: {
+ ngShow: 'isOrgAdmin && !canEdit',
+ message: i18n._("Contact your System Administrator to grant you the appropriate permissions to add and edit Users and Teams.")
+ },
fields: {
name: {
label: i18n._('Name'),
diff --git a/awx/ui/client/src/teams/teams.list.js b/awx/ui/client/src/teams/teams.list.js
index 93aab82848..1af52a8084 100644
--- a/awx/ui/client/src/teams/teams.list.js
+++ b/awx/ui/client/src/teams/teams.list.js
@@ -43,7 +43,7 @@ export default ['i18n', function(i18n) {
awToolTip: i18n._('Create a new team'),
actionClass: 'btn List-buttonSubmit',
buttonContent: '+ ' + i18n._('ADD'),
- ngShow: 'canAdd'
+ ngShow: 'canAdd && canEdit'
}
},
diff --git a/awx/ui/client/src/users/edit/users-edit.controller.js b/awx/ui/client/src/users/edit/users-edit.controller.js
index 0accb1bdcf..82ae48af1d 100644
--- a/awx/ui/client/src/users/edit/users-edit.controller.js
+++ b/awx/ui/client/src/users/edit/users-edit.controller.js
@@ -14,14 +14,15 @@ const user_type_options = [
export default ['$scope', '$rootScope', '$stateParams', 'UserForm', 'Rest',
'ProcessErrors', 'GetBasePath', 'Wait', 'CreateSelect2',
- '$state', 'i18n',
+ '$state', 'i18n', 'resolvedModels',
function($scope, $rootScope, $stateParams, UserForm, Rest, ProcessErrors,
- GetBasePath, Wait, CreateSelect2, $state, i18n) {
+ GetBasePath, Wait, CreateSelect2, $state, i18n, models) {
for (var i = 0; i < user_type_options.length; i++) {
user_type_options[i].label = i18n._(user_type_options[i].label);
}
+ const { me } = models;
var form = UserForm,
master = {},
id = $stateParams.user_id,
@@ -30,6 +31,8 @@ export default ['$scope', '$rootScope', '$stateParams', 'UserForm', 'Rest',
init();
function init() {
+ $scope.canEdit = me.get('summary_fields.user_capabilities.edit');
+ $scope.isOrgAdmin = me.get('related.admin_of_organizations.count') > 0;
$scope.isCurrentlyLoggedInUser = (parseInt(id) === $rootScope.current_user.id);
$scope.hidePagination = false;
$scope.hideSmartSearch = false;
@@ -68,9 +71,7 @@ export default ['$scope', '$rootScope', '$stateParams', 'UserForm', 'Rest',
});
$scope.$watch('user_obj.summary_fields.user_capabilities.edit', function(val) {
- if (val === false) {
- $scope.canAdd = false;
- }
+ $scope.canAdd = (val === false) ? false : true;
});
setScopeFields(data);
diff --git a/awx/ui/client/src/users/list/users-list.controller.js b/awx/ui/client/src/users/list/users-list.controller.js
index f0c9022581..b684a5bbdb 100644
--- a/awx/ui/client/src/users/list/users-list.controller.js
+++ b/awx/ui/client/src/users/list/users-list.controller.js
@@ -14,21 +14,23 @@ const user_type_options = [
export default ['$scope', '$rootScope', 'Rest', 'UserList', 'Prompt',
'ProcessErrors', 'GetBasePath', 'Wait', '$state', '$filter',
- 'rbacUiControlService', 'Dataset', 'i18n',
+ 'rbacUiControlService', 'Dataset', 'i18n', 'resolvedModels',
function($scope, $rootScope, Rest, UserList, Prompt,
ProcessErrors, GetBasePath, Wait, $state, $filter, rbacUiControlService,
- Dataset, i18n) {
+ Dataset, i18n, models) {
for (var i = 0; i < user_type_options.length; i++) {
user_type_options[i].label = i18n._(user_type_options[i].label);
}
+ const { me } = models;
var list = UserList,
- defaultUrl = GetBasePath('users');
+ defaultUrl = GetBasePath('users');
init();
function init() {
+ $scope.canEdit = me.get('summary_fields.user_capabilities.edit');
$scope.canAdd = false;
rbacUiControlService.canAdd('users')
diff --git a/awx/ui/client/src/users/main.js b/awx/ui/client/src/users/main.js
index 5168262f3c..3701d4f626 100644
--- a/awx/ui/client/src/users/main.js
+++ b/awx/ui/client/src/users/main.js
@@ -43,6 +43,26 @@ angular.module('Users', [])
activityStream: true,
activityStreamTarget: 'user'
},
+ resolve: {
+ edit: {
+ resolvedModels: ['MeModel', '$q', function(Me, $q) {
+ const promises= {
+ me: new Me('get').then((me) => me.extend('get', 'admin_of_organizations'))
+ };
+
+ return $q.all(promises);
+ }]
+ },
+ list: {
+ resolvedModels: ['MeModel', '$q', function(Me, $q) {
+ const promises= {
+ me: new Me('get')
+ };
+
+ return $q.all(promises);
+ }]
+ }
+ },
ncyBreadcrumb: {
label: N_('USERS')
}
diff --git a/awx/ui/client/src/users/users.form.js b/awx/ui/client/src/users/users.form.js
index 78ea4f33e4..93a1264edd 100644
--- a/awx/ui/client/src/users/users.form.js
+++ b/awx/ui/client/src/users/users.form.js
@@ -20,7 +20,10 @@ export default ['i18n', function(i18n) {
stateTree: 'users',
forceListeners: true,
tabs: true,
-
+ messageBar: {
+ ngShow: 'isOrgAdmin && !canEdit',
+ message: i18n._("Contact your System Administrator to grant you the appropriate permissions to add and edit Users and Teams.")
+ },
fields: {
first_name: {
label: i18n._('First Name'),
diff --git a/awx/ui/client/src/users/users.list.js b/awx/ui/client/src/users/users.list.js
index c53eb79887..95ff26f5e6 100644
--- a/awx/ui/client/src/users/users.list.js
+++ b/awx/ui/client/src/users/users.list.js
@@ -48,7 +48,7 @@ export default ['i18n', function(i18n) {
awToolTip: i18n._('Create a new user'),
actionClass: 'btn List-buttonSubmit',
buttonContent: '+ ' + i18n._('ADD'),
- ngShow: 'canAdd'
+ ngShow: 'canAdd && canEdit'
}
},