mirror of
https://github.com/ansible/awx.git
synced 2026-03-22 03:17:39 -02:30
Merge pull request #1911 from jlmitch5/addUsersOrg
modal to add users and admins to organizations
This commit is contained in:
@@ -737,6 +737,7 @@ var tower = angular.module('Tower', [
|
|||||||
CheckLicense.notify();
|
CheckLicense.notify();
|
||||||
}
|
}
|
||||||
$rootScope.$broadcast("closePermissionsModal");
|
$rootScope.$broadcast("closePermissionsModal");
|
||||||
|
$rootScope.$broadcast("closeUsersModal");
|
||||||
// this line removes the query params attached to a route
|
// this line removes the query params attached to a route
|
||||||
if(prev && prev.$$route &&
|
if(prev && prev.$$route &&
|
||||||
prev.$$route.name === 'systemTracking'){
|
prev.$$route.name === 'systemTracking'){
|
||||||
|
|||||||
@@ -0,0 +1,218 @@
|
|||||||
|
@import "../../../shared/branding/colors.default.less";
|
||||||
|
|
||||||
|
/** @define AddUsers */
|
||||||
|
|
||||||
|
.AddUsers-backDrop {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1041;
|
||||||
|
opacity: 0.2;
|
||||||
|
transition: 0.5s opacity;
|
||||||
|
background: @login-backdrop;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-dialog {
|
||||||
|
margin: 30px auto;
|
||||||
|
margin-top: 95px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-content {
|
||||||
|
max-width: 750px;
|
||||||
|
margin: 0 auto;
|
||||||
|
border: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
background-color: @login-bg;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: opacity 0.5s;
|
||||||
|
z-index: 1042;
|
||||||
|
position: relative;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-header {
|
||||||
|
padding: 20px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-body {
|
||||||
|
padding: 0px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-footer {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap-reverse;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20px;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-list .List-searchRow {
|
||||||
|
height: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-list .List-searchWidget {
|
||||||
|
height: 66px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-list .List-tableHeader:last-child {
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-list select-all {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-title {
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-buttons {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-directions {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: @default-interface-txt;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-directionNumber {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: @default-list-header-bg;
|
||||||
|
padding: 1px 8px;
|
||||||
|
margin-right: 10px;
|
||||||
|
width: 23px;
|
||||||
|
height: 23px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-separator {
|
||||||
|
margin-top: 20px 0px;
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 1px solid @d7grey;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-roleRow {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-roleName {
|
||||||
|
width: 30%;
|
||||||
|
padding-right: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-roleNameVal {
|
||||||
|
font-size: 14px;
|
||||||
|
max-width: ~"calc(100% - 46px)";
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-roleType {
|
||||||
|
padding: 0px 6px;
|
||||||
|
font-size: 10px;
|
||||||
|
color: @default-interface-txt;
|
||||||
|
text-transform: uppercase;
|
||||||
|
background-color: @default-bg;
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-roleSelect {
|
||||||
|
width: ~"calc(70% - 40px)";
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-roleSelect .Form-dropDown {
|
||||||
|
height: inherit !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-roleRemove {
|
||||||
|
border-radius: 50%;
|
||||||
|
padding: 1px 0;
|
||||||
|
line-height: 11px;
|
||||||
|
color: @default-icon;
|
||||||
|
background-color: @default-tertiary-bg;
|
||||||
|
border: 0;
|
||||||
|
height: 23px;
|
||||||
|
width: 23px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-roleRemove:hover {
|
||||||
|
background-color: @default-err;
|
||||||
|
color: @default-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-selectHide {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers .select2-search__field {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-keyToggle {
|
||||||
|
margin-left: auto;
|
||||||
|
text-transform: uppercase;
|
||||||
|
padding: 3px 9px;
|
||||||
|
font-size: 12px;
|
||||||
|
background-color: @default-bg;
|
||||||
|
border-radius: 5px;
|
||||||
|
color: @default-interface-txt;
|
||||||
|
border: 1px solid @d7grey;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-keyToggle:hover {
|
||||||
|
background-color: @default-tertiary-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-keyToggle.is-active {
|
||||||
|
background-color: @default-link;
|
||||||
|
border-color: @default-link;
|
||||||
|
color: @default-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-keyPane {
|
||||||
|
margin: 20px 0;
|
||||||
|
font-size: 12px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 15px;
|
||||||
|
padding-top: 10px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid @login-notice-border;
|
||||||
|
background-color: @login-notice-bg;
|
||||||
|
color: @login-notice-text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-keyRow {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-keyName {
|
||||||
|
flex: 1 0 auto;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: bold;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AddUsers-keyDescription {
|
||||||
|
flex: 1 0 auto;
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/*************************************************
|
||||||
|
* Copyright (c) 2015 Ansible, Inc.
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc function
|
||||||
|
* @name controllers.function:Access
|
||||||
|
* @description
|
||||||
|
* Controller for handling permissions adding
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default ['$scope', '$rootScope', 'ProcessErrors', 'UserList', 'generateList', 'GetBasePath', 'SelectionInit', 'SearchInit', 'templateUrl', 'PaginateInit', '$state', 'Rest', '$q', 'Wait', function($scope, $rootScope, ProcessErrors, UserList, generateList, GetBasePath, SelectionInit, SearchInit, templateUrl, PaginateInit, $state, Rest, $q, Wait) {
|
||||||
|
$scope.$on("linkLists", function() {
|
||||||
|
var generator = generateList,
|
||||||
|
list = _.cloneDeep(UserList),
|
||||||
|
url = GetBasePath("users"),
|
||||||
|
set = "users",
|
||||||
|
id = "addUsersList",
|
||||||
|
mode = "add";
|
||||||
|
|
||||||
|
if ($state.current.name.split(".")[1] === "users") {
|
||||||
|
$scope.addType = "Users";
|
||||||
|
} else {
|
||||||
|
$scope.addType = "Administrators";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
list.multiSelect = true;
|
||||||
|
|
||||||
|
generator.inject(list, { id: id,
|
||||||
|
title: false, mode: mode, scope: $scope });
|
||||||
|
|
||||||
|
SearchInit({ scope: $scope, set: set,
|
||||||
|
list: list, url: url });
|
||||||
|
|
||||||
|
PaginateInit({ scope: $scope,
|
||||||
|
list: list, url: url, pageSize: 5 });
|
||||||
|
|
||||||
|
$scope.search(list.iterator);
|
||||||
|
|
||||||
|
$scope.updateUsers = function() {
|
||||||
|
var url, listToClose,
|
||||||
|
payloads = $scope.selectedItems.map(function(val) {
|
||||||
|
return {id: val.id};
|
||||||
|
});
|
||||||
|
if ($scope.addType === 'Users') {
|
||||||
|
url = $scope.$parent.orgRelatedUrls.users;
|
||||||
|
listToClose = 'user';
|
||||||
|
} else {
|
||||||
|
url = $scope.$parent.orgRelatedUrls.admins;
|
||||||
|
listToClose = 'admin';
|
||||||
|
}
|
||||||
|
|
||||||
|
Wait('start');
|
||||||
|
|
||||||
|
var requests = payloads
|
||||||
|
.map(function(post) {
|
||||||
|
Rest.setUrl(url);
|
||||||
|
return Rest.post(post);
|
||||||
|
});
|
||||||
|
|
||||||
|
$q.all(requests)
|
||||||
|
.then(function () {
|
||||||
|
Wait('stop');
|
||||||
|
$scope.$emit('ReloadOrganzationCards', $scope.$parent.org_id);
|
||||||
|
$scope.$parent.search('user');
|
||||||
|
$scope.closeModal();
|
||||||
|
}, function (error) {
|
||||||
|
Wait('stop');
|
||||||
|
$rootScope.$broadcast("refreshList", listToClose);
|
||||||
|
ProcessErrors(null, error.data, error.status, null, {
|
||||||
|
hdr: 'Error!',
|
||||||
|
msg: 'Failed to post ' + $scope.addType +
|
||||||
|
': POST returned status' + error.status
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}];
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*************************************************
|
||||||
|
* Copyright (c) 2015 Ansible, Inc.
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
/* jshint unused: vars */
|
||||||
|
import addUsers from './addUsers.controller';
|
||||||
|
export default
|
||||||
|
['Wait', 'templateUrl', function(Wait, templateUrl) {
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
scope: {},
|
||||||
|
controller: addUsers,
|
||||||
|
templateUrl: templateUrl('organizations/linkout/addUsers/addUsers'),
|
||||||
|
link: function(scope, element, attrs, ctrl) {
|
||||||
|
$("body").addClass("is-modalOpen");
|
||||||
|
|
||||||
|
$("body").append(element);
|
||||||
|
|
||||||
|
Wait('start');
|
||||||
|
|
||||||
|
scope.$broadcast("linkLists");
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
$('#add-users-modal').modal("show");
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
$('.modal[aria-hidden=false]').each(function () {
|
||||||
|
if ($(this).attr('id') !== 'add-users-modal') {
|
||||||
|
$(this).modal('hide');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
scope.closeModal = function() {
|
||||||
|
$("body").removeClass("is-modalOpen");
|
||||||
|
$('#add-users-modal').on('hidden.bs.modal',
|
||||||
|
function () {
|
||||||
|
$('.AddUsers').remove();
|
||||||
|
});
|
||||||
|
$('#add-users-modal').modal('hide');
|
||||||
|
};
|
||||||
|
|
||||||
|
scope.$on('closeUsersModal', function() {
|
||||||
|
scope.closeModal();
|
||||||
|
});
|
||||||
|
|
||||||
|
Wait('stop');
|
||||||
|
|
||||||
|
window.scrollTo(0,0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<div id="add-users-modal" class="AddUsers modal fade">
|
||||||
|
<div class="AddUsers-backDrop is-loggedOut"></div>
|
||||||
|
<div class="AddUsers-dialog">
|
||||||
|
<div class="AddUsers-content is-loggedOut">
|
||||||
|
<div class="AddUsers-header">
|
||||||
|
<div class="List-header">
|
||||||
|
<div class="List-title">
|
||||||
|
<div class="List-titleText ng-binding">{{ $parent.org_name }}<div class="List-titleLockup"></div>Add {{ addType }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="Form-exitHolder">
|
||||||
|
<button class="Form-exit" ng-click="closeModal()">
|
||||||
|
<i class="fa fa-times-circle"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="AddUsers-body">
|
||||||
|
<div class="AddUsers-inner" id="addUsersList">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="AddUsers-footer">
|
||||||
|
<div class="buttons Form-buttons AddUsers-buttons">
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-sm Form-saveButton"
|
||||||
|
ng-click="updateUsers()"
|
||||||
|
ng-disabled="!selectedItems || !selectedItems.length">
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-sm Form-cancelButton"
|
||||||
|
ng-click="closeModal()">
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
11
awx/ui/client/src/organizations/linkout/addUsers/main.js
Normal file
11
awx/ui/client/src/organizations/linkout/addUsers/main.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/*************************************************
|
||||||
|
* Copyright (c) 2015 Ansible, Inc.
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
import addUsersDirective from './addUsers.directive';
|
||||||
|
|
||||||
|
export default
|
||||||
|
angular.module('AddUsers', [])
|
||||||
|
.directive('addUsers', addUsersDirective);
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import routes from './organizations-linkout.route';
|
import routes from './organizations-linkout.route';
|
||||||
|
import AddUsers from './addUsers/main';
|
||||||
|
|
||||||
export default angular.module('organizationsLinkout', [])
|
export default angular.module('organizationsLinkout', [AddUsers.name])
|
||||||
.run(['$stateExtender', function($stateExtender) {
|
.run(['$stateExtender', function($stateExtender) {
|
||||||
routes.forEach(function(route) {
|
routes.forEach(function(route) {
|
||||||
$stateExtender.addState(route);
|
$stateExtender.addState(route);
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
export default ['$scope', '$stateParams', '$state', 'Rest', 'UserList', 'InventoryList', 'JobTemplateList', 'TeamList', 'ProjectList', 'generateList', 'SearchInit', 'PaginateInit', function($scope, $stateParams, $state, Rest, UserList, InventoryList, JobTemplateList, TeamList, ProjectList, GenerateList, SearchInit, PaginateInit) {
|
export default ['$compile', '$scope', '$stateParams', '$state', 'Rest', 'UserList', 'InventoryList', 'JobTemplateList', 'TeamList', 'ProjectList', 'generateList', 'SearchInit', 'PaginateInit', function($compile, $scope, $stateParams, $state, Rest, UserList, InventoryList, JobTemplateList, TeamList, ProjectList, GenerateList, SearchInit, PaginateInit) {
|
||||||
|
|
||||||
var getList = function(mode) {
|
var getList = function(mode) {
|
||||||
var list = {};
|
var list = {};
|
||||||
if (mode === 'users') {
|
if (mode === 'users') {
|
||||||
list = _.cloneDeep(UserList);
|
list = _.cloneDeep(UserList);
|
||||||
list.emptyListText = "Please add items to this list";
|
list.emptyListText = "Please add items to this list";
|
||||||
|
list.actions.add.label = "Add a user to the organization";
|
||||||
list.actions.add.buttonContent = '+ ADD user';
|
list.actions.add.buttonContent = '+ ADD user';
|
||||||
|
list.actions.add.awToolTip = 'Add existing user to organization';
|
||||||
|
list.actions.add.ngClick = 'addUsers()';
|
||||||
} else if (mode === 'inventories') {
|
} else if (mode === 'inventories') {
|
||||||
list = _.cloneDeep(InventoryList);
|
list = _.cloneDeep(InventoryList);
|
||||||
list.emptyListText = "List is empty";
|
list.emptyListText = "List is empty";
|
||||||
@@ -26,6 +29,8 @@ export default ['$scope', '$stateParams', '$state', 'Rest', 'UserList', 'Invento
|
|||||||
list = _.cloneDeep(UserList);
|
list = _.cloneDeep(UserList);
|
||||||
list.emptyListText = "Please add items to this list";
|
list.emptyListText = "Please add items to this list";
|
||||||
list.actions.add.buttonContent = '+ ADD administrator';
|
list.actions.add.buttonContent = '+ ADD administrator';
|
||||||
|
list.actions.add.awToolTip = 'Add existing user to organization as administrator';
|
||||||
|
list.actions.add.ngClick = 'addUsers()';
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
};
|
};
|
||||||
@@ -61,18 +66,27 @@ export default ['$scope', '$stateParams', '$state', 'Rest', 'UserList', 'Invento
|
|||||||
generator = GenerateList;
|
generator = GenerateList;
|
||||||
$scope.$parent.activeCard = parseInt($stateParams.organization_id);
|
$scope.$parent.activeCard = parseInt($stateParams.organization_id);
|
||||||
$scope.$parent.activeMode = mode;
|
$scope.$parent.activeMode = mode;
|
||||||
|
$scope.org_name = data.name;
|
||||||
|
$scope.org_id = data.id;
|
||||||
|
var listMode = (mode === 'admins') ? 'users' : mode;
|
||||||
|
|
||||||
list = getList(mode);
|
list = getList(mode);
|
||||||
list.listTitle = listTitle;
|
|
||||||
|
|
||||||
url = getUrl(mode, data);
|
url = getUrl(mode, data);
|
||||||
|
list.listTitle = listTitle;
|
||||||
|
list.basePath = url;
|
||||||
|
|
||||||
|
$scope.orgRelatedUrls = data.related;
|
||||||
|
|
||||||
generator
|
generator
|
||||||
.inject(list, { mode: 'edit', scope: $scope });
|
.inject(list, { mode: 'edit', scope: $scope });
|
||||||
|
|
||||||
|
$scope.addUsers = function () {
|
||||||
|
$compile("<add-users class='AddUsers'></add-users>")($scope);
|
||||||
|
};
|
||||||
|
|
||||||
SearchInit({
|
SearchInit({
|
||||||
scope: $scope,
|
scope: $scope,
|
||||||
set: mode,
|
set: listMode,
|
||||||
list: list,
|
list: list,
|
||||||
url: url
|
url: url
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -31,7 +31,11 @@ export default ['GetBasePath', function(GetBasePath) {
|
|||||||
if (endPoint === 'inventories') {
|
if (endPoint === 'inventories') {
|
||||||
endPoint = 'inventory';
|
endPoint = 'inventory';
|
||||||
}
|
}
|
||||||
return GetBasePath(endPoint);
|
if (endPoint.indexOf("/api/v1") > -1) {
|
||||||
|
return endPoint;
|
||||||
|
} else {
|
||||||
|
return GetBasePath(endPoint);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// inject the directive with the list and endpoint
|
// inject the directive with the list and endpoint
|
||||||
|
|||||||
@@ -162,7 +162,10 @@ export default ['Rest', '$q', 'GetBasePath', 'Wait', 'ProcessErrors', '$log', fu
|
|||||||
tags = relatedTags.concat(nonRelatedTags);
|
tags = relatedTags.concat(nonRelatedTags);
|
||||||
}
|
}
|
||||||
|
|
||||||
return basePath + "?" +
|
var returnedUrl = basePath;
|
||||||
|
returnedUrl += (basePath.indexOf("?") > - 1) ? "&" : "?";
|
||||||
|
|
||||||
|
return returnedUrl +
|
||||||
(tags || []).map(function (t) {
|
(tags || []).map(function (t) {
|
||||||
return t.url;
|
return t.url;
|
||||||
}).join("&") + "&page_size=" + pageSize;
|
}).join("&") + "&page_size=" + pageSize;
|
||||||
|
|||||||
Reference in New Issue
Block a user