diff --git a/awx/ui/client/src/access/add-rbac-resource/rbac-resource.directive.js b/awx/ui/client/src/access/add-rbac-resource/rbac-resource.directive.js
index f125c64afd..c5ee969049 100644
--- a/awx/ui/client/src/access/add-rbac-resource/rbac-resource.directive.js
+++ b/awx/ui/client/src/access/add-rbac-resource/rbac-resource.directive.js
@@ -12,6 +12,7 @@ export default ['templateUrl', '$state',
return {
restrict: 'E',
scope: {
+ defaultParams: '=?',
usersDataset: '=',
teamsDataset: '=',
resourceData: '=',
diff --git a/awx/ui/client/src/access/add-rbac-resource/rbac-resource.partial.html b/awx/ui/client/src/access/add-rbac-resource/rbac-resource.partial.html
index 2ddfac5bc0..9779fc34f8 100644
--- a/awx/ui/client/src/access/add-rbac-resource/rbac-resource.partial.html
+++ b/awx/ui/client/src/access/add-rbac-resource/rbac-resource.partial.html
@@ -45,7 +45,7 @@
diff --git a/awx/ui/client/src/access/rbac-multiselect/permissionsUsers.list.js b/awx/ui/client/src/access/rbac-multiselect/permissionsUsers.list.js
index 7b1b91ab63..1e5a8193c3 100644
--- a/awx/ui/client/src/access/rbac-multiselect/permissionsUsers.list.js
+++ b/awx/ui/client/src/access/rbac-multiselect/permissionsUsers.list.js
@@ -15,7 +15,7 @@
multiSelectExtended: true,
index: false,
hover: true,
- emptyListText : i18n._('No Users exist'),
+ emptyListText: i18n._('No Users to add'),
disableRow: "{{ objectType === 'organization' && user.summary_fields.user_capabilities.edit === false }}",
disableRowValue: "objectType === 'organization' && user.summary_fields.user_capabilities.edit === false",
disableTooltip: {
diff --git a/awx/ui/client/src/access/rbac-multiselect/rbac-multiselect-list.directive.js b/awx/ui/client/src/access/rbac-multiselect/rbac-multiselect-list.directive.js
index 632219c8fe..602bdbcdb9 100644
--- a/awx/ui/client/src/access/rbac-multiselect/rbac-multiselect-list.directive.js
+++ b/awx/ui/client/src/access/rbac-multiselect/rbac-multiselect-list.directive.js
@@ -17,6 +17,7 @@ export default ['addPermissionsTeamsList', 'addPermissionsUsersList', 'TemplateL
allSelected: '=',
view: '@',
dataset: '=',
+ defaultParams: '=?',
objectType: '='
},
template: "
",
@@ -149,6 +150,11 @@ export default ['addPermissionsTeamsList', 'addPermissionsUsersList', 'TemplateL
scope.list = list;
scope[`${list.iterator}_dataset`] = scope.dataset.data;
+
+ if (scope.defaultParams) {
+ scope[`${list.iterator}_default_params`] = scope.defaultParams;
+ }
+
scope[`${list.name}`] = scope[`${list.iterator}_dataset`].results;
scope.$watch(list.name, function(){
diff --git a/awx/ui/client/src/inventories-hosts/shared/associate-groups/associate-groups.controller.js b/awx/ui/client/src/inventories-hosts/shared/associate-groups/associate-groups.controller.js
index bfc4cda17e..5f24ea6608 100644
--- a/awx/ui/client/src/inventories-hosts/shared/associate-groups/associate-groups.controller.js
+++ b/awx/ui/client/src/inventories-hosts/shared/associate-groups/associate-groups.controller.js
@@ -5,9 +5,9 @@
*************************************************/
export default ['$scope', '$rootScope', 'ProcessErrors', 'GetBasePath', 'generateList',
- '$state', 'Rest', '$q', 'Wait', '$window', 'QuerySet', 'GroupList',
+ '$state', 'Rest', '$q', 'Wait', '$window', 'QuerySet', 'GroupList', 'i18n',
function($scope, $rootScope, ProcessErrors, GetBasePath, generateList,
- $state, Rest, $q, Wait, $window, qs, GroupList) {
+ $state, Rest, $q, Wait, $window, qs, GroupList, i18n) {
$scope.$on("linkLists", function() {
init();
@@ -26,6 +26,8 @@
if($state.params.group_id) {
$scope.associate_group_default_params.not__id = $state.params.group_id;
$scope.associate_group_queryset.not__id = $state.params.group_id;
+ $scope.associate_group_default_params.not__parents = $state.params.group_id;
+ $scope.associate_group_queryset.not__parents = $state.params.group_id;
}
let list = _.cloneDeep(GroupList);
@@ -39,6 +41,7 @@
selectedRows: 'selectedItems',
availableRows: 'associate_groups'
};
+ list.emptyListText = i18n._('No groups to add');
delete list.actions;
delete list.fieldActions;
delete list.fields.failed_hosts;
diff --git a/awx/ui/client/src/inventories-hosts/shared/associate-hosts/associate-hosts.controller.js b/awx/ui/client/src/inventories-hosts/shared/associate-hosts/associate-hosts.controller.js
index 9a3014afcf..a72f937908 100644
--- a/awx/ui/client/src/inventories-hosts/shared/associate-hosts/associate-hosts.controller.js
+++ b/awx/ui/client/src/inventories-hosts/shared/associate-hosts/associate-hosts.controller.js
@@ -5,9 +5,9 @@
*************************************************/
export default ['$scope', '$rootScope', 'ProcessErrors', 'GetBasePath', 'generateList',
- '$state', 'Rest', '$q', 'Wait', '$window', 'QuerySet', 'RelatedHostsListDefinition',
+ '$state', 'Rest', '$q', 'Wait', '$window', 'QuerySet', 'RelatedHostsListDefinition', 'i18n',
function($scope, $rootScope, ProcessErrors, GetBasePath, generateList,
- $state, Rest, $q, Wait, $window, qs, RelatedHostsListDefinition) {
+ $state, Rest, $q, Wait, $window, qs, RelatedHostsListDefinition, i18n) {
$scope.$on("linkLists", function() {
init();
@@ -23,6 +23,11 @@
page_size: 5
};
+ if ($state.params.group_id) {
+ $scope.associate_host_default_params.not__groups = $state.params.group_id;
+ $scope.associate_host_queryset.not__groups = $state.params.group_id;
+ }
+
let list = _.cloneDeep(RelatedHostsListDefinition);
list.basePath = GetBasePath('inventory') + $state.params.inventory_id + '/hosts';
list.iterator = 'associate_host';
@@ -36,6 +41,7 @@
selectedRows: 'selectedItems',
availableRows: 'associate_hosts'
};
+ list.emptyListText = i18n._('No hosts to add');
delete list.fields.toggleHost;
delete list.fields.active_failures;
delete list.fields.groups;
diff --git a/awx/ui/client/src/organizations/linkout/addUsers/addUsers.controller.js b/awx/ui/client/src/organizations/linkout/addUsers/addUsers.controller.js
index 97f7cdd050..7127efeed8 100644
--- a/awx/ui/client/src/organizations/linkout/addUsers/addUsers.controller.js
+++ b/awx/ui/client/src/organizations/linkout/addUsers/addUsers.controller.js
@@ -12,9 +12,9 @@
*/
export default ['$scope', '$rootScope', 'ProcessErrors', 'GetBasePath', 'generateList',
-'$state', 'Rest', '$q', 'Wait', '$window', 'QuerySet', 'UserList',
+'$state', 'Rest', '$q', 'Wait', '$window', 'QuerySet', 'UserList', 'i18n',
function($scope, $rootScope, ProcessErrors, GetBasePath, generateList,
- $state, Rest, $q, Wait, $window, qs, UserList) {
+ $state, Rest, $q, Wait, $window, qs, UserList, i18n) {
$scope.$on("linkLists", function() {
if ($state.current.name.split(".")[1] === "users") {
@@ -23,18 +23,32 @@ function($scope, $rootScope, ProcessErrors, GetBasePath, generateList,
$scope.addType = "Administrators";
}
- init();
+ let notAdminAlreadyParams = {};
+
+ if ($scope.addType === 'Administrators') {
+ Rest.setUrl(GetBasePath('organizations') + `${$state.params.organization_id}/object_roles`);
+ Rest.get().then(({data}) => {
+ notAdminAlreadyParams.not__roles__in = data.results
+ .filter(({name}) => name === i18n._('Admin'))
+ .map(({id}) => id)
+ .join(',');
+ notAdminAlreadyParams.is_superuser = 'false';
+ init();
+ });
+ } else {
+ init();
+ }
function init(){
- $scope.add_user_default_params = {
+ $scope.add_user_default_params = Object.assign({
order_by: 'username',
page_size: 5
- };
+ }, notAdminAlreadyParams);
- $scope.add_user_queryset = {
+ $scope.add_user_queryset = Object.assign({
order_by: 'username',
page_size: 5
- };
+ }, notAdminAlreadyParams);
let list = _.cloneDeep(UserList);
list.basePath = 'users';
@@ -46,6 +60,9 @@ function($scope, $rootScope, ProcessErrors, GetBasePath, generateList,
list.fields.first_name.columnClass = 'col-sm-4';
list.fields.last_name.columnClass = 'col-sm-4';
list.layoutClass = 'List-staticColumnLayout--statusOrCheckbox';
+ if ($scope.addType === 'Administrators') {
+ list.emptyListText = i18n._('No users available to add as adminstrators');
+ }
delete list.actions;
delete list.fieldActions;
diff --git a/awx/ui/client/src/organizations/linkout/organizations-linkout.route.js b/awx/ui/client/src/organizations/linkout/organizations-linkout.route.js
index 877676af62..0aa7b044e0 100644
--- a/awx/ui/client/src/organizations/linkout/organizations-linkout.route.js
+++ b/awx/ui/client/src/organizations/linkout/organizations-linkout.route.js
@@ -54,7 +54,7 @@ let lists = [{
OrgUsersDataset: ['OrgUserList', 'QuerySet', '$stateParams', 'GetBasePath',
function(list, qs, $stateParams, GetBasePath) {
let path = GetBasePath(list.basePath) || list.basePath;
- return qs.search(path, $stateParams.user_search);
+ return qs.search(path, $stateParams.org_user_search);
}
],
OrgUserList: ['UserList', 'GetBasePath', '$stateParams', 'i18n', function(UserList, GetBasePath, $stateParams, i18n) {
diff --git a/awx/ui/client/src/shared/stateDefinitions.factory.js b/awx/ui/client/src/shared/stateDefinitions.factory.js
index 2c54e901f7..1a445cc83d 100644
--- a/awx/ui/client/src/shared/stateDefinitions.factory.js
+++ b/awx/ui/client/src/shared/stateDefinitions.factory.js
@@ -584,27 +584,97 @@ function($injector, $stateExtender, $log, i18n) {
squashSearchUrl: true,
url: '/add-user',
params: {
- user_search: {
+ add_user_search: {
value: { order_by: 'username', page_size: '5' },
- dynamic: true,
+ dynamic: true
}
},
views: {
[`modal@${formStateDefinition.name}`]: {
- template: `
`
+ template: `
`
}
},
ncyBreadcrumb:{
skip:true
},
resolve: {
- usersDataset: ['addPermissionsUsersList', 'QuerySet', '$stateParams', 'GetBasePath',
- function(list, qs, $stateParams, GetBasePath) {
- let path = GetBasePath(list.basePath) || GetBasePath(list.name);
- return qs.search(path, $stateParams.user_search);
-
+ orgId: ['$stateParams', 'Rest', 'GetBasePath', function($stateParams, Rest, GetBasePath) {
+ let id;
+ if ($stateParams.team_id) {
+ Rest.setUrl(GetBasePath('teams') + `${$stateParams.team_id}`);
+ id = Rest.get().then(({data}) => {
+ return data.summary_fields.organization.id;
+ });
+ } else {
+ id = null;
}
- ]
+ return id;
+ }],
+ teamRoles: ['$stateParams', 'Rest', 'GetBasePath', 'i18n', function($stateParams, Rest, GetBasePath, i18n) {
+ let roles = null;
+ if ($stateParams.team_id) {
+ const basePath = GetBasePath('teams') + `${$stateParams.team_id}/object_roles`;
+ Rest.setUrl(basePath);
+ roles = Rest.get().then(({data}) => {
+ return data.results
+ .filter(({name}) => name === i18n._('Member') || name === i18n._('Admin'))
+ .map(({id}) => id)
+ .join(',');
+ });
+ }
+ return roles;
+ }],
+ orgAdminRole: ['$stateParams', 'orgId', 'Rest', 'GetBasePath', 'i18n',
+ function($stateParams, orgId, Rest, GetBasePath, i18n) {
+ let orgIdToCheck = $stateParams.organization_id || orgId;
+ let role = null;
+ if (orgIdToCheck) {
+ const basePath = GetBasePath('organizations') + `${orgIdToCheck}/object_roles`;
+ Rest.setUrl(basePath);
+ role = Rest.get().then(({data}) => {
+ return data.results
+ .filter(({name}) => name === i18n._('Admin'))
+ .map(({id}) => id)[0];
+ });
+ }
+ return role;
+ }],
+ orgMemberRole: ['$stateParams', 'Rest', 'GetBasePath', 'i18n', function($stateParams, Rest, GetBasePath, i18n) {
+ let role = null;
+ if ($stateParams.organization_id) {
+ const basePath = GetBasePath('organizations') + `${$stateParams.organization_id}/object_roles`;
+ Rest.setUrl(basePath);
+ role = Rest.get().then(({data}) => {
+ return data.results
+ .filter(({name}) => name === i18n._('Member'))
+ .map(({id}) => id)[0];
+ });
+ }
+ return role;
+ }],
+ rolesToExclude: ['teamRoles', 'orgAdminRole', 'orgMemberRole', '$stateParams',
+ function(teamRoles, orgAdminRole, orgMemberRole, $stateParams) {
+ let roles = null;
+ if ($stateParams.team_id) {
+ roles = `${teamRoles},${orgAdminRole}`;
+ } else if ($stateParams.organization_id) {
+ roles = `${orgAdminRole},${orgMemberRole}`;
+ }
+ return roles;
+ }],
+ usersDataset: ['addPermissionsUsersList', 'QuerySet', '$stateParams', 'GetBasePath', 'rolesToExclude',
+ function(list, qs, $stateParams, GetBasePath, rolesToExclude) {
+ let path = GetBasePath(list.basePath) || GetBasePath(list.name);
+ if (rolesToExclude) {
+ $stateParams.add_user_search.not__roles__in = rolesToExclude;
+ $stateParams.add_user_search.is_superuser = 'false';
+ }
+ return qs.search(path, $stateParams.add_user_search);
+ }
+ ],
+ defaultParams: ['$stateParams', 'usersDataset', function($stateParams) {
+ return $stateParams.add_user_search;
+ }]
},
onExit: function($state) {
if ($state.transition) {