diff --git a/awx/ui/static/js/app.js b/awx/ui/static/js/app.js index 6871bd943a..8682155706 100644 --- a/awx/ui/static/js/app.js +++ b/awx/ui/static/js/app.js @@ -46,6 +46,7 @@ angular.module('ansible', [ 'ProjectsListDefinition', 'ProjectFormDefinition', 'PermissionFormDefinition', + 'PermissionListDefinition', 'JobsListDefinition', 'JobFormDefinition', 'JobEventsListDefinition', @@ -178,6 +179,12 @@ angular.module('ansible', [ when('/users/:user_id/permissions/add', { templateUrl: urlPrefix + 'partials/users.html', controller: PermissionsAdd }). + when('/users/:user_id/permissions', { templateUrl: urlPrefix + 'partials/users.html', + controller: PermissionsList }). + + when('/users/:user_id/permissions/:permission_id', { templateUrl: urlPrefix + 'partials/users.html', + controller: PermissionsEdit }). + when('/users/:user_id/credentials/add', { templateUrl: urlPrefix + 'partials/teams.html', controller: CredentialsAdd }). diff --git a/awx/ui/static/js/controllers/Credentials.js b/awx/ui/static/js/controllers/Credentials.js index 64c5eac5af..c9cf9d0334 100644 --- a/awx/ui/static/js/controllers/Credentials.js +++ b/awx/ui/static/js/controllers/Credentials.js @@ -21,7 +21,7 @@ function CredentialsList ($scope, $rootScope, $location, $log, $routeParams, Res var view = GenerateList; var base = $location.path().replace(/^\//,'').split('/')[0]; var mode = (base == 'credentials') ? 'edit' : 'select'; // if base path 'credentials', we're here to add/edit - var scope = view.inject(CredentialList, { mode: mode }); // Inject our view + var scope = view.inject(list, { mode: mode }); // Inject our view scope.selected = []; if (scope.PostRefreshRemove) { diff --git a/awx/ui/static/js/controllers/Permissions.js b/awx/ui/static/js/controllers/Permissions.js index 8056420ec4..35334c7da5 100644 --- a/awx/ui/static/js/controllers/Permissions.js +++ b/awx/ui/static/js/controllers/Permissions.js @@ -1,3 +1,64 @@ + +function PermissionsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, PermissionList, + GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, + ClearScope, ProcessErrors, GetBasePath) +{ + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. + var list = PermissionList; + var base = $location.path().replace(/^\//,'').split('/')[0]; + var defaultUrl = GetBasePath(base); + defaultUrl += ($routeParams['user_id'] !== undefined) ? $routeParams['user_id'] : $routeParams['team_id']; + defaultUrl += '/permissions/'; + + var view = GenerateList; + var scope = view.inject(list, { mode: 'edit' }); // Inject our view + scope.selected = []; + + SearchInit({ scope: scope, set: 'permissions', list: list, url: defaultUrl }); + PaginateInit({ scope: scope, list: list, url: defaultUrl }); + scope.search(list.iterator); + + LoadBreadCrumbs(); + + scope.addPermission = function() { + $location.path($location.path() + '/add'); + } + + scope.editPermission = function(id) { + $location.path($location.path() + '/' + id); + } + + scope.deletePermission = function(id, name) { + + var action = function() { + var url = GetBasePath('base') + 'permissions/' + id + '/'; + Rest.setUrl(url); + Rest.destroy() + .success( function(data, status, headers, config) { + $('#prompt-modal').modal('hide'); + scope.search(list.iterator); + }) + .error( function(data, status, headers, config) { + $('#prompt-modal').modal('hide'); + ProcessErrors(scope, data, status, null, + { hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); + }); + }; + + Prompt({ hdr: 'Delete', + body: 'Are you sure you want to delete ' + name + '?', + action: action + }); + } +} + +PermissionsList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'PermissionList', + 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', + 'ClearScope', 'ProcessErrors', 'GetBasePath' + ]; + + function PermissionsAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, PermissionsForm, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope, GetBasePath, ReturnToCaller, InventoryList, ProjectList, LookUpInit) @@ -8,7 +69,7 @@ function PermissionsAdd ($scope, $rootScope, $compile, $location, $log, $routePa // Inject dynamic view var form = PermissionsForm; var generator = GenerateForm; - var id = $routeParams.user_id; + var id = ($routeParams.user_id !== undefined) ? $routeParams.user_id : $routeParams.team_id; var base = $location.path().replace(/^\//,'').split('/')[0]; var defaultUrl = GetBasePath(base) + id + '/permissions'; var scope = generator.inject(form, {mode: 'add', related: false}); @@ -17,8 +78,8 @@ function PermissionsAdd ($scope, $rootScope, $compile, $location, $log, $routePa generator.reset(); LoadBreadCrumbs(); - scope.category = 'i'; - master.category = 'i'; + scope.category = 'Inventory'; + master.category = 'Inventory'; LookUpInit({ scope: scope, @@ -49,7 +110,7 @@ function PermissionsAdd ($scope, $rootScope, $compile, $location, $log, $routePa ReturnToCaller(1); }) .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, ProjectsForm, + ProcessErrors(scope, data, status, PermissionsForm, { hdr: 'Error!', msg: 'Failed to create new permission. Post returned status: ' + status }); }); }; @@ -64,9 +125,110 @@ function PermissionsAdd ($scope, $rootScope, $compile, $location, $log, $routePa }; } -ProjectsAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'PermissionForm', - 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ClearScope', 'GetBasePath', - 'ReturnToCaller', 'InventoryList', 'ProjectList', 'LookUpInit' - ]; +PermissionsAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'PermissionsForm', + 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ClearScope', 'GetBasePath', + 'ReturnToCaller', 'InventoryList', 'ProjectList', 'LookUpInit' + ]; +function PermissionsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, PermissionsForm, + GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, + ClearScope, Prompt, GetBasePath, InventoryList, ProjectList, LookUpInit) +{ + ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior + //scope. + + var generator = GenerateForm; + var form = PermissionsForm; + var scope = generator.inject(form, {mode: 'edit', related: true}); + var base_id = ($routeParams.user_id !== undefined) ? $routeParams.user_id : $routeParams.team_id; + var base = $location.path().replace(/^\//,'').split('/')[0]; + var id = $routeParams.permission_id; + var defaultUrl = GetBasePath('base') + 'permissions/' + id + '/'; + generator.reset(); + + var master = {}; + var relatedSets = {}; + + + // Retrieve detail record and prepopulate the form + Rest.setUrl(defaultUrl); + Rest.get() + .success( function(data, status, headers, config) { + + LoadBreadCrumbs({ path: '/users/' + base_id + '/permissions/' + id, title: data.name }); + + for (var fld in form.fields) { + if (data[fld]) { + if (form.fields[fld].sourceModel) { + var sourceModel = form.fields[fld].sourceModel; + var sourceField = form.fields[fld].sourceField; + scope[sourceModel + '_' + sourceField] = data.summary_fields[sourceModel][sourceField]; + master[sourceModel + '_' + sourceField] = data.summary_fields[sourceModel][sourceField]; + } + scope[fld] = data[fld]; + master[fld] = scope[fld]; + } + } + + scope.category = 'Deploy'; + if (data['permission_type'] != 'run' && data['permission_type'] != 'check' ) { + scope.category = 'Inventory'; + } + master['category'] = scope.category; + + LookUpInit({ + scope: scope, + form: form, + current_item: data.inventory, + list: InventoryList, + field: 'inventory' + }); + + LookUpInit({ + scope: scope, + form: form, + current_item: data.project, + list: ProjectList, + field: 'project' + }); + }) + .error( function(data, status, headers, config) { + ProcessErrors(scope, data, status, form, + { hdr: 'Error!', msg: 'Failed to retrieve Permission: ' + id + '. GET status: ' + status }); + }); + + + // Save changes to the parent + scope.formSave = function() { + var data = {} + for (var fld in form.fields) { + data[fld] = scope[fld]; + } + Rest.setUrl(defaultUrl); + Rest.put(data) + .success( function(data, status, headers, config) { + ReturnToCaller(1); + }) + .error( function(data, status, headers, config) { + ProcessErrors(scope, data, status, form, + { hdr: 'Error!', msg: 'Failed to update Permission: ' + $routeParams.id + '. PUT status: ' + status }); + }); + }; + + + // Cancel + scope.formReset = function() { + generator.reset(); + for (var fld in master) { + scope[fld] = master[fld]; + } + }; + +} + +PermissionsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'PermissionsForm', + 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', + 'ClearScope', 'Prompt', 'GetBasePath', 'InventoryList', 'ProjectList', 'LookUpInit' + ]; + diff --git a/awx/ui/static/js/controllers/Users.js b/awx/ui/static/js/controllers/Users.js index d91eb0b096..1e87a644cc 100644 --- a/awx/ui/static/js/controllers/Users.js +++ b/awx/ui/static/js/controllers/Users.js @@ -224,7 +224,7 @@ UsersAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$ function UsersEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, UserForm, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, - RelatedPaginateInit, ReturnToCaller, ClearScope, GetBasePath) + RelatedPaginateInit, ReturnToCaller, ClearScope, GetBasePath, Prompt) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -330,7 +330,12 @@ function UsersEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, // Related set: Edit button scope.edit = function(set, id, name) { $rootScope.flashMessage = null; - $location.path('/' + set + '/' + id); + if (set == 'permissions') { + $location.path('/users/' + $routeParams.user_id + '/permissions/' + id); + } + else { + $location.path('/' + set + '/' + id); + } }; // Related set: Delete button @@ -338,22 +343,39 @@ function UsersEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, $rootScope.flashMessage = null; var action = function() { - var url = defaultUrl + $routeParams.user_id + '/' + set + '/'; - Rest.setUrl(url); - Rest.post({ id: itm_id, disassociate: 1 }) - .success( function(data, status, headers, config) { - $('#prompt-modal').modal('hide'); - scope.search(form.related[set].iterator); - }) - .error( function(data, status, headers, config) { - $('#prompt-modal').modal('hide'); - ProcessErrors(scope, data, status, null, - { hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST returned status: ' + status }); - }); - }; + var url; + if (set == 'permissions') { + url = GetBasePath('base') + 'permissions/' + itm_id + '/'; + Rest.setUrl(url); + Rest.destroy() + .success( function(data, status, headers, config) { + $('#prompt-modal').modal('hide'); + scope.search(form.related[set].iterator); + }) + .error( function(data, status, headers, config) { + $('#prompt-modal').modal('hide'); + ProcessErrors(scope, data, status, null, + { hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status }); + }); + } + else { + url = defaultUrl + $routeParams.user_id + '/' + set + '/'; + Rest.setUrl(url); + Rest.post({ id: itm_id, disassociate: 1 }) + .success( function(data, status, headers, config) { + $('#prompt-modal').modal('hide'); + scope.search(form.related[set].iterator); + }) + .error( function(data, status, headers, config) { + $('#prompt-modal').modal('hide'); + ProcessErrors(scope, data, status, null, + { hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST returned status: ' + status }); + }); + } + } Prompt({ hdr: 'Delete', - body: 'Are you sure you want to remove ' + name + ' from ' + scope.name + ' ' + title + '?', + body: 'Are you sure you want to remove ' + name + ' from ' + scope.username + ' ' + title + '?', action: action }); } @@ -362,5 +384,5 @@ function UsersEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, UsersEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'UserForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', - 'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'GetBasePath']; + 'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'GetBasePath', 'Prompt']; diff --git a/awx/ui/static/js/forms/Permissions.js b/awx/ui/static/js/forms/Permissions.js index 87150761c6..2b31507baa 100644 --- a/awx/ui/static/js/forms/Permissions.js +++ b/awx/ui/static/js/forms/Permissions.js @@ -20,7 +20,7 @@ angular.module('PermissionFormDefinition', []) category: { label: 'Permission Type', type: 'radio', - options: [{ label: 'Inventory', value: 'i' }, { label: 'Deployment', value: 'd'}], + options: [{ label: 'Inventory', value: 'Inventory' }, { label: 'Deployment', value: 'Deploy'}], ngChange: 'selectCategory()' }, name: { @@ -49,8 +49,10 @@ angular.module('PermissionFormDefinition', []) type: 'lookup', sourceModel: 'project', sourceField: 'name', - ngShow: "category == 'd'", + ngShow: "category == 'Deploy'", ngClick: 'lookUpProject()', + addRequired: false, + editRequired: false }, inventory: { label: 'Inventory', @@ -58,26 +60,30 @@ angular.module('PermissionFormDefinition', []) sourceModel: 'inventory', sourceField: 'name', ngClick: 'lookUpInventory()', + addRequired: false, + editRequired: false }, - inventory_permission_type: { + permission_type: { label: 'Permission', type: 'radio', - ngShow: "category == 'i'", options: [ - {label: 'Admin', value: 'PERM_INVENTORY_ADMIN'}, - {label: 'Read', value: 'PERM_INVENTORY_READ'}, - {label: 'Write', value: 'PERM_INVENTORY_WRITE'} + {label: 'Admin', value: 'admin', ngShow: "category == 'Inventory'" }, + {label: 'Read', value: 'read', ngShow: "category == 'Inventory'" }, + {label: 'Write', value: 'write', ngShow: "category == 'Inventory'" }, + {label: 'Run', value: 'run', ngShow: "category == 'Deploy'" }, + {label: 'Check', value: 'check', ngShow: "category == 'Deploy'" } ] - }, + } + /* , deployment_permission_type: { label: 'Permission', type: 'radio', - ngShow: "category == 'd'", + ngShow: "category == 'Deploy'", options: [ {label: 'Deploy', value: 'PERM_INVENTORY_DEPLOY'}, {label: 'Check', value: 'PERM_INVENTORY_CHECK'} ] - } + }*/ }, buttons: { //for now always generates