From fed98063135246ded43526f4e22f17df80a8b5e2 Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Sat, 26 Nov 2016 16:14:19 -0500 Subject: [PATCH 01/13] Reorganize awx/ui/client/src/access module structure addPermissions module => add-rbac-resource module addPermissionsList module => rbac-multiselect-list module roleSelect module => rbac-multiselect-role module roleList module => rbac-role-column module Use isolate scope in rbac-multiselect-role module Move shared styles to module root --- .../src/access/add-rbac-resource/main.js | 12 +++ .../rbac-resource.controller.js} | 16 ++-- .../rbac-resource.directive.js} | 6 +- .../rbac-resource.partial.html} | 10 +-- ...issions.block.less => add-rbac.block.less} | 10 ++- .../addPermissionsList.directive.js | 47 ----------- .../client/src/access/addPermissions/main.js | 14 ---- awx/ui/client/src/access/main.js | 10 ++- .../main.js | 8 +- .../permissionsTeams.list.js | 0 .../permissionsUsers.list.js | 0 .../rbac-multiselect-list.directive.js | 80 +++++++++++++++++++ .../rbac-multiselect-role.directive.js} | 8 +- .../roleList.block.less | 2 +- .../roleList.directive.js | 2 +- .../roleList.partial.html | 0 16 files changed, 133 insertions(+), 92 deletions(-) create mode 100644 awx/ui/client/src/access/add-rbac-resource/main.js rename awx/ui/client/src/access/{addPermissions/addPermissions.controller.js => add-rbac-resource/rbac-resource.controller.js} (91%) rename awx/ui/client/src/access/{addPermissions/addPermissions.directive.js => add-rbac-resource/rbac-resource.directive.js} (82%) rename awx/ui/client/src/access/{addPermissions/addPermissions.partial.html => add-rbac-resource/rbac-resource.partial.html} (91%) rename awx/ui/client/src/access/{addPermissions/addPermissions.block.less => add-rbac.block.less} (95%) delete mode 100644 awx/ui/client/src/access/addPermissions/addPermissionsList/addPermissionsList.directive.js delete mode 100644 awx/ui/client/src/access/addPermissions/main.js rename awx/ui/client/src/access/{addPermissions/addPermissionsList => rbac-multiselect}/main.js (55%) rename awx/ui/client/src/access/{addPermissions/addPermissionsList => rbac-multiselect}/permissionsTeams.list.js (100%) rename awx/ui/client/src/access/{addPermissions/addPermissionsList => rbac-multiselect}/permissionsUsers.list.js (100%) create mode 100644 awx/ui/client/src/access/rbac-multiselect/rbac-multiselect-list.directive.js rename awx/ui/client/src/access/{addPermissions/roleSelect.directive.js => rbac-multiselect/rbac-multiselect-role.directive.js} (67%) rename awx/ui/client/src/access/{ => rbac-role-column}/roleList.block.less (96%) rename awx/ui/client/src/access/{ => rbac-role-column}/roleList.directive.js (95%) rename awx/ui/client/src/access/{ => rbac-role-column}/roleList.partial.html (100%) diff --git a/awx/ui/client/src/access/add-rbac-resource/main.js b/awx/ui/client/src/access/add-rbac-resource/main.js new file mode 100644 index 0000000000..346e6106c6 --- /dev/null +++ b/awx/ui/client/src/access/add-rbac-resource/main.js @@ -0,0 +1,12 @@ +/************************************************* + * Copyright (c) 2015 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +import addRbacResourceDirective from './rbac-resource.directive'; +import rbacMultiselect from '../rbac-multiselect/main'; + +export default + angular.module('AddRbacResourceModule', [rbacMultiselect.name]) + .directive('addRbacResource', addRbacResourceDirective); diff --git a/awx/ui/client/src/access/addPermissions/addPermissions.controller.js b/awx/ui/client/src/access/add-rbac-resource/rbac-resource.controller.js similarity index 91% rename from awx/ui/client/src/access/addPermissions/addPermissions.controller.js rename to awx/ui/client/src/access/add-rbac-resource/rbac-resource.controller.js index d5774e7c79..99cf7e9e11 100644 --- a/awx/ui/client/src/access/addPermissions/addPermissions.controller.js +++ b/awx/ui/client/src/access/add-rbac-resource/rbac-resource.controller.js @@ -18,16 +18,7 @@ export default ['$rootScope', '$scope', 'GetBasePath', 'Rest', '$q', 'Wait', 'Pr // the object permissions are being added to scope.object = scope.resourceData.data; // array for all possible roles for the object - scope.roles = Object - .keys(scope.object.summary_fields.object_roles) - .map(function(key) { - return { - value: scope.object.summary_fields - .object_roles[key].id, - label: scope.object.summary_fields - .object_roles[key].name - }; - }); + scope.roles = scope.object.summary_fields.object_roles; // TODO: get working with api // array w roles and descriptions for key @@ -44,6 +35,11 @@ export default ['$rootScope', '$scope', 'GetBasePath', 'Rest', '$q', 'Wait', 'Pr scope.showKeyPane = false; + scope.removeObject = function(obj){ + _.remove(scope.allSelected, {id: obj.id}); + obj.isSelected = false; + }; + scope.toggleKeyPane = function() { scope.showKeyPane = !scope.showKeyPane; }; diff --git a/awx/ui/client/src/access/addPermissions/addPermissions.directive.js b/awx/ui/client/src/access/add-rbac-resource/rbac-resource.directive.js similarity index 82% rename from awx/ui/client/src/access/addPermissions/addPermissions.directive.js rename to awx/ui/client/src/access/add-rbac-resource/rbac-resource.directive.js index 284110b0ce..fde8ee4054 100644 --- a/awx/ui/client/src/access/addPermissions/addPermissions.directive.js +++ b/awx/ui/client/src/access/add-rbac-resource/rbac-resource.directive.js @@ -3,7 +3,7 @@ * * All Rights Reserved *************************************************/ -import addPermissionsController from './addPermissions.controller'; +import controller from './rbac-resource.controller'; /* jshint unused: vars */ export default ['templateUrl', '$state', @@ -16,8 +16,8 @@ export default ['templateUrl', '$state', teamsDataset: '=', resourceData: '=', }, - controller: addPermissionsController, - templateUrl: templateUrl('access/addPermissions/addPermissions'), + controller: controller, + templateUrl: templateUrl('access/add-rbac-resource/rbac-resource'), link: function(scope, element, attrs) { scope.toggleFormTabs('users'); $('#add-permissions-modal').modal('show'); diff --git a/awx/ui/client/src/access/addPermissions/addPermissions.partial.html b/awx/ui/client/src/access/add-rbac-resource/rbac-resource.partial.html similarity index 91% rename from awx/ui/client/src/access/addPermissions/addPermissions.partial.html rename to awx/ui/client/src/access/add-rbac-resource/rbac-resource.partial.html index 264a4cf834..e8c3361f91 100644 --- a/awx/ui/client/src/access/addPermissions/addPermissions.partial.html +++ b/awx/ui/client/src/access/add-rbac-resource/rbac-resource.partial.html @@ -46,10 +46,10 @@
- +
- +
Please assign roles to the selected users/teams -
Key @@ -91,8 +91,8 @@ {{ obj.type }}
- - + +
\n"; } + html += ''; } } diff --git a/awx/ui/client/src/shared/stateDefinitions.factory.js b/awx/ui/client/src/shared/stateDefinitions.factory.js index b76c5b5a36..62b7f9cb68 100644 --- a/awx/ui/client/src/shared/stateDefinitions.factory.js +++ b/awx/ui/client/src/shared/stateDefinitions.factory.js @@ -230,7 +230,74 @@ export default ['$injector', '$stateExtender', '$log', function($injector, $stat */ generateFormListDefinitions: function(form, formStateDefinition) { - function buildPermissionDirective() { + function buildRbacUserTeamDirective(){ + let states = []; + + states.push($stateExtender.buildDefinition({ + name: `${formStateDefinition.name}.permissions.add`, + squashSearchUrl: true, + url: '/add-permissions', + params: { + project_search: { + value: {order_by: 'name', page_size: '5'}, + dynamic: true + }, + template_search: { + value: {order_by: 'name', page_size: '5', type: 'workflow_job_template,job_template'}, // @issue and also system_job_template? + dynamic: true + }, + inventory_search: { + value: {order_by: 'name', page_size: '5'}, + dynamic: true + }, + credential_search: { + value: {order_by: 'name', page_size: '5'}, + dynamic: true + } + }, + views: { + [`modal@${formStateDefinition.name}`]: { + template: `` + } + }, + resolve: { + templatesDataset: ['TemplateList', 'QuerySet', '$stateParams', 'GetBasePath', + function(list, qs, $stateParams, GetBasePath) { + let path = GetBasePath(list.basePath) || GetBasePath(list.name); + return qs.search(path, $stateParams[`${list.iterator}_search`]); + } + ], + projectsDataset: ['ProjectList', 'QuerySet', '$stateParams', 'GetBasePath', + function(list, qs, $stateParams, GetBasePath) { + let path = GetBasePath(list.basePath) || GetBasePath(list.name); + return qs.search(path, $stateParams[`${list.iterator}_search`]); + } + ], + inventoriesDataset: ['InventoryList', 'QuerySet', '$stateParams', 'GetBasePath', + function(list, qs, $stateParams, GetBasePath) { + let path = GetBasePath(list.basePath) || GetBasePath(list.name); + return qs.search(path, $stateParams[`${list.iterator}_search`]); + } + ], + credentialsDataset: ['CredentialList', 'QuerySet', '$stateParams', 'GetBasePath', + function(list, qs, $stateParams, GetBasePath) { + let path = GetBasePath(list.basePath) || GetBasePath(list.name); + return qs.search(path, $stateParams[`${list.iterator}_search`]); + } + ], + }, + onExit: function($state) { + if ($state.transition) { + $('#add-permissions-modal').modal('hide'); + $('.modal-backdrop').remove(); + $('body').removeClass('modal-open'); + } + }, + })); + return states; + } + + function buildRbacResourceDirective() { let states = []; states.push($stateExtender.buildDefinition({ @@ -249,7 +316,7 @@ export default ['$injector', '$stateExtender', '$log', function($injector, $stat }, views: { [`modal@${formStateDefinition.name}`]: { - template: `` + template: `` } }, resolve: { @@ -282,7 +349,13 @@ export default ['$injector', '$stateExtender', '$log', function($injector, $stat let states = []; states.push(buildListDefinition(field)); if (field.iterator === 'permission' && field.actions && field.actions.add) { - states.push(buildPermissionDirective()); + if (form.name === 'user' || form.name === 'team'){ + states.push(buildRbacUserTeamDirective()); + + } + else { + states.push(buildRbacResourceDirective()); + } states = _.flatten(states); } return states; From ce12b97d755e3f6cc874c3a5510a6b328b84cea9 Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Sat, 26 Nov 2016 16:12:57 -0500 Subject: [PATCH 04/13] New permission directive - add-rbac-user-team --- .../src/access/add-rbac-user-team/main.js | 12 ++ .../rbac-user-team.controller.js | 117 ++++++++++++ .../rbac-user-team.directive.js | 25 +++ .../rbac-user-team.partial.html | 175 ++++++++++++++++++ 4 files changed, 329 insertions(+) create mode 100644 awx/ui/client/src/access/add-rbac-user-team/main.js create mode 100644 awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js create mode 100644 awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.directive.js create mode 100644 awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html diff --git a/awx/ui/client/src/access/add-rbac-user-team/main.js b/awx/ui/client/src/access/add-rbac-user-team/main.js new file mode 100644 index 0000000000..547815a1d7 --- /dev/null +++ b/awx/ui/client/src/access/add-rbac-user-team/main.js @@ -0,0 +1,12 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +import addRbacUserTeamDirective from './rbac-user-team.directive'; +import rbacMultiselect from '../rbac-multiselect/main'; + +export default + angular.module('AddRbacUserTeamModule', [rbacMultiselect.name]) + .directive('addRbacUserTeam', addRbacUserTeamDirective); diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js new file mode 100644 index 0000000000..981478d6d0 --- /dev/null +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js @@ -0,0 +1,117 @@ +/************************************************* + * Copyright (c) 2015 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +/** + * @ngdoc function + * @name controllers.function:Access + * @description + * Controller for handling permissions adding + */ + +export default ['$rootScope', '$scope', '$state', 'GetBasePath', 'Rest', '$q', 'Wait', 'ProcessErrors', +function(rootScope, scope, $state, GetBasePath, Rest, $q, Wait, ProcessErrors) { + + init(); + + function init(){ + + let resources = ['templates', 'projects', 'inventories', 'credentials']; + + // data model: + // selected - keyed by type of resource + // selected[type] - keyed by each resource object's id + // selected[type][id] === { roles: [ ... ], ... } + scope.selected = {}; + _.each(resources, (resource) => scope.selected[resource] = {}); + + scope.keys = {}; + _.each(resources, (resource) => scope.keys[resource] = {}); + + scope.tab = { + templates: true, + projects: false, + inventories: false, + credentials: false + }; + scope.showKeyPane = false; + scope.owner = scope.resolve.resourceData.data; + } + + // aggregate name/descriptions for each available role, based on resource type + function aggregateKey(item, type){ + _.merge(scope.keys[type], item.summary_fields.object_roles); + } + + scope.closeModal = function() { + $state.go('^', null, {reload: true}); + }; + + scope.currentTab = function(){ + return _.findKey(scope.tab, (tab) => tab); + }; + + scope.toggleKeyPane = function() { + scope.showKeyPane = !scope.showKeyPane; + }; + + scope.showSection2Container = function(){ + return _.any(scope.selected, (type) => Object.keys(type).length > 0); + }; + + scope.showSection2Tab = function(tab){ + return Object.keys(scope.selected[tab]).length > 0; + }; + + scope.removeSelection = function(resource, type){ + delete scope.selected[type][resource.id]; + resource.isSelected = false; + }; + + // handle form tab changes + scope.selectTab = function(selected){ + _.each(scope.tab, (value, key, collection) => { + collection[key] = (selected === key); + }); + }; + + // pop/push into unified collection of selected users & teams + scope.$on("selectedOrDeselected", function(e, value) { + let resourceType = scope.currentTab(), + item = value.value; + + if (item.isSelected) { + scope.selected[resourceType][item.id] = item; + scope.selected[resourceType][item.id].roles = []; + aggregateKey(item, resourceType); + } else { + delete scope.selected[resourceType][item.id]; + } + }); + + // post roles to api + scope.saveForm = function() { + Wait('start'); + // scope.selected => { n: {id: n}, ... } => [ {id: n}, ... ] + let requests = _(scope.selected).map((type) => { + return _.map(type, (resource) => resource.roles); + }).flattenDeep().value(); + + Rest.setUrl(scope.owner.related.roles); + + $q.all( _.map(requests, (entity) => Rest.post({id: entity.id})) ) + .then( () =>{ + Wait('stop'); + scope.closeModal(); + }, (error) => { + scope.closeModal(); + ProcessErrors(null, error.data, error.status, null, { + hdr: 'Error!', + msg: 'Failed to post role(s): POST returned status' + + error.status + }); + }); + }; +}]; diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.directive.js b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.directive.js new file mode 100644 index 0000000000..2b89195820 --- /dev/null +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.directive.js @@ -0,0 +1,25 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ +import controller from './rbac-user-team.controller'; + +/* jshint unused: vars */ +export default ['templateUrl', + function(templateUrl) { + return { + restrict: 'E', + scope: { + resolve: "=" + }, + controller: controller, + controllerAs: 'rbac', + templateUrl: templateUrl('access/add-rbac-user-team/rbac-user-team'), + link: function(scope, element, attrs) { + $('#add-permissions-modal').modal('show'); + window.scrollTo(0, 0); + } + }; + } +]; diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html new file mode 100644 index 0000000000..e6ba2326af --- /dev/null +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html @@ -0,0 +1,175 @@ + From c753328a0b6f793a964ced36cce79d3e7423b5fb Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Tue, 13 Dec 2016 15:33:47 -0500 Subject: [PATCH 05/13] split templates into job templates / workflow job templates --- .../rbac-user-team.controller.js | 3 +- .../rbac-user-team.directive.js | 1 - .../rbac-user-team.partial.html | 20 ++++-- .../rbac-multiselect-list.directive.js | 62 +++++++++++++------ .../src/shared/stateDefinitions.factory.js | 22 +++++-- 5 files changed, 76 insertions(+), 32 deletions(-) diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js index 981478d6d0..9888370e54 100644 --- a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js @@ -31,7 +31,8 @@ function(rootScope, scope, $state, GetBasePath, Rest, $q, Wait, ProcessErrors) { _.each(resources, (resource) => scope.keys[resource] = {}); scope.tab = { - templates: true, + job_templates: true, + workflow_templates: false, projects: false, inventories: false, credentials: false diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.directive.js b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.directive.js index 2b89195820..8790410ee3 100644 --- a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.directive.js +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.directive.js @@ -14,7 +14,6 @@ export default ['templateUrl', resolve: "=" }, controller: controller, - controllerAs: 'rbac', templateUrl: templateUrl('access/add-rbac-user-team/rbac-user-team'), link: function(scope, element, attrs) { $('#add-permissions-modal').modal('show'); diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html index e6ba2326af..f148a25d70 100644 --- a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html @@ -33,14 +33,19 @@
+ ng-click="selectTab('job_templates')" + ng-class="{'is-selected': tab.job_templates }"> Templates
+ Workflow Templates +
+
Projects
-
- +
+ +
+
+
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 1cc5f29f3d..d94411ff0f 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 @@ -24,7 +24,8 @@ export default ['addPermissionsTeamsList', 'addPermissionsUsersList', 'TemplateL Teams: addPermissionsTeamsList, Users: addPermissionsUsersList, Projects: ProjectList, - Templates: TemplateList, + JobTemplates: TemplateList, + WorkflowTemplates: TemplateList, Inventories: InventoryList, Credentials: CredentialList }; @@ -34,23 +35,48 @@ export default ['addPermissionsTeamsList', 'addPermissionsUsersList', 'TemplateL list.listTitleBadge = false; delete list.actions; delete list.fieldActions; - - if (scope.view !== 'Users' && scope.view !== 'Teams' && scope.view !=='Projects' && scope.view !== 'Inventories'){ - list.fields = { - name: list.fields.name, - description: list.fields.description - }; - } else if (scope.view === 'Projects'){ - list.fields = { - name: list.fields.name, - scm_type: list.fields.scm_type - }; - } else if (scope.view === 'Inventories'){ - list.fieds = { - name: list.fields.name, - organization: list.fields.organization - }; - } + + switch(scope.view){ + + case 'Projects': + list.fields = { + name: list.fields.name, + scm_type: list.fields.scm_type + }; + break; + + case 'Inventories': + list.fields = { + name: list.fields.name, + organization: list.fields.organization + }; + break; + + case 'JobTemplates': + list.name = 'job_templates'; + list.iterator = 'job_template'; + list.fields = { + name: list.fields.name, + description: list.fields.description + }; + break; + + case 'WorkflowTemplates': + list.name = 'workflow_templates'; + list.iterator = 'workflow_template', + list.basePath = 'workflow_job_templates'; + list.fields = { + name: list.fields.name, + description: list.fields.description + }; + break; + + default: + list.fields = { + name: list.fields.name, + description: list.fields.description + }; + } list_html = generateList.build({ mode: 'edit', diff --git a/awx/ui/client/src/shared/stateDefinitions.factory.js b/awx/ui/client/src/shared/stateDefinitions.factory.js index 62b7f9cb68..21ba01aade 100644 --- a/awx/ui/client/src/shared/stateDefinitions.factory.js +++ b/awx/ui/client/src/shared/stateDefinitions.factory.js @@ -242,8 +242,12 @@ export default ['$injector', '$stateExtender', '$log', function($injector, $stat value: {order_by: 'name', page_size: '5'}, dynamic: true }, - template_search: { - value: {order_by: 'name', page_size: '5', type: 'workflow_job_template,job_template'}, // @issue and also system_job_template? + job_template_search: { + value: {order_by: 'name', page_size: '5'}, + dynamic: true + }, + workflow_template_search: { + value: {order_by: 'name', page_size: '5'}, dynamic: true }, inventory_search: { @@ -261,10 +265,16 @@ export default ['$injector', '$stateExtender', '$log', function($injector, $stat } }, resolve: { - templatesDataset: ['TemplateList', 'QuerySet', '$stateParams', 'GetBasePath', - function(list, qs, $stateParams, GetBasePath) { - let path = GetBasePath(list.basePath) || GetBasePath(list.name); - return qs.search(path, $stateParams[`${list.iterator}_search`]); + jobTemplatesDataset: ['QuerySet', '$stateParams', 'GetBasePath', + function(qs, $stateParams, GetBasePath) { + let path = GetBasePath('job_templates'); + return qs.search(path, $stateParams.job_template_search); + } + ], + workflowTemplatesDataset: ['QuerySet', '$stateParams', 'GetBasePath', + function(qs, $stateParams, GetBasePath) { + let path = GetBasePath('workflow_job_templates'); + return qs.search(path, $stateParams.workflow_template_search); } ], projectsDataset: ['ProjectList', 'QuerySet', '$stateParams', 'GetBasePath', From 1090d74ea03522330f32a97afc92837bcd949308 Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Tue, 13 Dec 2016 23:19:50 -0500 Subject: [PATCH 06/13] rough pass on rbac-selected-list directive --- .../src/access/add-rbac-user-team/main.js | 7 +- .../rbac-selected-list.directive.js | 108 ++++++++++++++++++ .../rbac-user-team.controller.js | 2 +- .../rbac-user-team.directive.js | 1 + .../rbac-user-team.partial.html | 53 ++++----- .../list-generator/list-generator.factory.js | 4 +- 6 files changed, 141 insertions(+), 34 deletions(-) create mode 100644 awx/ui/client/src/access/add-rbac-user-team/rbac-selected-list.directive.js diff --git a/awx/ui/client/src/access/add-rbac-user-team/main.js b/awx/ui/client/src/access/add-rbac-user-team/main.js index 547815a1d7..94a1fa7c60 100644 --- a/awx/ui/client/src/access/add-rbac-user-team/main.js +++ b/awx/ui/client/src/access/add-rbac-user-team/main.js @@ -5,8 +5,9 @@ *************************************************/ import addRbacUserTeamDirective from './rbac-user-team.directive'; -import rbacMultiselect from '../rbac-multiselect/main'; +import rbacSelectedList from './rbac-selected-list.directive'; export default - angular.module('AddRbacUserTeamModule', [rbacMultiselect.name]) - .directive('addRbacUserTeam', addRbacUserTeamDirective); + angular.module('AddRbacUserTeamModule', []) + .directive('addRbacUserTeam', addRbacUserTeamDirective) + .directive('rbacSelectedList', rbacSelectedList); \ No newline at end of file diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-selected-list.directive.js b/awx/ui/client/src/access/add-rbac-user-team/rbac-selected-list.directive.js new file mode 100644 index 0000000000..131a060523 --- /dev/null +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-selected-list.directive.js @@ -0,0 +1,108 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +/* jshint unused: vars */ +export default ['$compile','templateUrl', 'i18n', 'generateList', + 'ProjectList', 'TemplateList', 'InventoryList', 'CredentialList', + function($compile, templateUrl, i18n, generateList, + ProjectList, TemplateList, InventoryList, CredentialList) { + return { + restrict: 'E', + scope: { + resourceType: "=", + collection: "=", + selected: "=" + }, + link: function(scope, element, attrs) { + console.log(scope.resourceType) + let listMap, list, list_html; + + listMap = { + projects: ProjectList, + job_templates: TemplateList, + workflow_templates: TemplateList, + inventories: InventoryList, + credentials: CredentialList + }; + + list = _.cloneDeep(listMap[scope.resourceType]) + + list.fieldActions = { + remove: { + ngClick: `removeSelection(${list.iterator}, resourceType)`, + icon: 'fa-remove', + awToolTip: i18n._(`Remove ${list.iterator}`), + label: i18n._('Remove'), + class: 'btn-sm' + } + }; + delete list.actions; + + list.listTitleBadge = false; + + switch(scope.resourceType){ + + case 'projects': + list.fields = { + name: list.fields.name, + scm_type: list.fields.scm_type + }; + break; + + case 'inventories': + list.fields = { + name: list.fields.name, + organization: list.fields.organization + }; + break; + + case 'job_templates': + list.name = 'job_templates'; + list.iterator = 'job_template'; + list.fields = { + name: list.fields.name, + description: list.fields.description + }; + break; + + case 'workflow_templates': + list.name = 'workflow_templates'; + list.iterator = 'workflow_template', + list.basePath = 'workflow_job_templates'; + list.fields = { + name: list.fields.name, + description: list.fields.description + }; + break; + + default: + list.fields = { + name: list.fields.name, + description: list.fields.description + }; + } + + list.fields = _.each(list.fields, (field) => field.nosort = true); + + list_html = generateList.build({ + mode: 'edit', + list: list, + related: false, + title: false, + showSearch: false, + paginate: false + }); + + scope.list = list; + scope[`${list.iterator}_dataset`] = scope.collection; + scope[list.name] = scope.collection; + + element.append(list_html); + $compile(element.contents())(scope); + } + }; + } +]; diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js index 9888370e54..3e41460487 100644 --- a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js @@ -18,7 +18,7 @@ function(rootScope, scope, $state, GetBasePath, Rest, $q, Wait, ProcessErrors) { function init(){ - let resources = ['templates', 'projects', 'inventories', 'credentials']; + let resources = ['job_templates', 'workflow_templates', 'projects', 'inventories', 'credentials']; // data model: // selected - keyed by type of resource diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.directive.js b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.directive.js index 8790410ee3..ced1ceb744 100644 --- a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.directive.js +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.directive.js @@ -16,6 +16,7 @@ export default ['templateUrl', controller: controller, templateUrl: templateUrl('access/add-rbac-user-team/rbac-user-team'), link: function(scope, element, attrs) { + scope.selectTab('job_templates'); $('#add-permissions-modal').modal('show'); window.scrollTo(0, 0); } diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html index f148a25d70..dc330bc035 100644 --- a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html @@ -35,7 +35,7 @@
- Templates + Job Templates
- Templates + ng-click="selectTab('job_templates')" + ng-class="{'is-selected': tab.job_templates }" + ng-show="showSection2Tab('job_templates')"> + Job Templates +
+
+ Workflow Templates
-
- -
- -
-
- - {{ resource.name }} - - - {{ resource.type }} - -
- - - -
-
-
+ + + + + +
+ + +
+
diff --git a/awx/ui/client/src/shared/list-generator/list-generator.factory.js b/awx/ui/client/src/shared/list-generator/list-generator.factory.js index c41e059c81..b1a74db51a 100644 --- a/awx/ui/client/src/shared/list-generator/list-generator.factory.js +++ b/awx/ui/client/src/shared/list-generator/list-generator.factory.js @@ -443,12 +443,14 @@ export default ['$location', '$compile', '$rootScope', 'Attr', 'Icon', html += "
\n"; } - html += `
`; + } return html; }, From 81d152443957d50c392ca06a4643430afb311972 Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Wed, 14 Dec 2016 17:39:41 -0500 Subject: [PATCH 07/13] working batch requests --- .../rbac-selected-list.directive.js | 33 ++++++++-- .../rbac-user-team.controller.js | 66 ++++++++++++++----- .../rbac-user-team.partial.html | 19 ++++-- .../rbac-multiselect-list.directive.js | 8 ++- .../rbac-role-column/roleList.directive.js | 2 +- .../list-generator/list-generator.factory.js | 8 ++- 6 files changed, 103 insertions(+), 33 deletions(-) diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-selected-list.directive.js b/awx/ui/client/src/access/add-rbac-user-team/rbac-selected-list.directive.js index 131a060523..99e2cb451f 100644 --- a/awx/ui/client/src/access/add-rbac-user-team/rbac-selected-list.directive.js +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-selected-list.directive.js @@ -17,7 +17,6 @@ export default ['$compile','templateUrl', 'i18n', 'generateList', selected: "=" }, link: function(scope, element, attrs) { - console.log(scope.resourceType) let listMap, list, list_html; listMap = { @@ -28,12 +27,12 @@ export default ['$compile','templateUrl', 'i18n', 'generateList', credentials: CredentialList }; - list = _.cloneDeep(listMap[scope.resourceType]) + list = _.cloneDeep(listMap[scope.resourceType]); list.fieldActions = { remove: { ngClick: `removeSelection(${list.iterator}, resourceType)`, - icon: 'fa-remove', + iconClass: 'fa fa-times-circle', awToolTip: i18n._(`Remove ${list.iterator}`), label: i18n._('Remove'), class: 'btn-sm' @@ -43,6 +42,8 @@ export default ['$compile','templateUrl', 'i18n', 'generateList', list.listTitleBadge = false; + // @issue - fix field.columnClass values for this view + switch(scope.resourceType){ case 'projects': @@ -77,8 +78,7 @@ export default ['$compile','templateUrl', 'i18n', 'generateList', description: list.fields.description }; break; - - default: + case 'credentials': list.fields = { name: list.fields.name, description: list.fields.description @@ -93,12 +93,31 @@ export default ['$compile','templateUrl', 'i18n', 'generateList', related: false, title: false, showSearch: false, + showEmptyPanel: false, paginate: false }); scope.list = list; - scope[`${list.iterator}_dataset`] = scope.collection; - scope[list.name] = scope.collection; + + scope.$watchCollection('collection', function(selected){ + scope[`${list.iterator}_dataset`] = scope.collection; + scope[list.name] = _.values(scope.collection); + }); + + scope.removeSelection = function(resource, type){ + let multiselect_scope, deselectedIdx; + + delete scope.collection[resource.id]; + delete scope.selected[type][resource.id]; + + // a quick & dirty hack + // section 1 and section 2 elements produce sibling scopes + // This means events propogated from section 2 are not received in section 1 + // The following code directly accesses the right scope by list table id + multiselect_scope = angular.element('#AddPermissions-body').find(`#${type}_table`).scope() + deselectedIdx = _.findIndex(multiselect_scope[type], {id: resource.id}); + multiselect_scope[type][deselectedIdx].isSelected = false; + }; element.append(list_html); $compile(element.contents())(scope); diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js index 3e41460487..665f5f6c26 100644 --- a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js @@ -11,8 +11,8 @@ * Controller for handling permissions adding */ -export default ['$rootScope', '$scope', '$state', 'GetBasePath', 'Rest', '$q', 'Wait', 'ProcessErrors', -function(rootScope, scope, $state, GetBasePath, Rest, $q, Wait, ProcessErrors) { +export default ['$rootScope', '$scope', '$state', 'i18n', 'CreateSelect2', 'GetBasePath', 'Rest', '$q', 'Wait', 'ProcessErrors', +function(rootScope, scope, $state, i18n, CreateSelect2, GetBasePath, Rest, $q, Wait, ProcessErrors) { init(); @@ -24,12 +24,20 @@ function(rootScope, scope, $state, GetBasePath, Rest, $q, Wait, ProcessErrors) { // selected - keyed by type of resource // selected[type] - keyed by each resource object's id // selected[type][id] === { roles: [ ... ], ... } + + // collection of resources selected in section 1 scope.selected = {}; - _.each(resources, (resource) => scope.selected[resource] = {}); + _.each(resources, (type) => scope.selected[type] = {}); + // collection of assignable roles per type of resource scope.keys = {}; - _.each(resources, (resource) => scope.keys[resource] = {}); + _.each(resources, (type) => scope.keys[type] = {}); + // collection of currently-selected role to assign in section 2 + scope.roleSelection = {}; + _.each(resources, (type) => scope.roleSelection[type] = null); + + // tracks currently-selected tabs, initialized with the job templates tab open scope.tab = { job_templates: true, workflow_templates: false, @@ -37,13 +45,39 @@ function(rootScope, scope, $state, GetBasePath, Rest, $q, Wait, ProcessErrors) { inventories: false, credentials: false }; + + // initializes select2 per select field + // html snippet: + /* +
+ +
+ */ + _.each(resources, (type) => buildSelect2(type)); + + function buildSelect2(type){ + CreateSelect2({ + element: `#${type}-role-select`, + multiple: false, + placeholder: i18n._('Select a role') + }); + } + scope.showKeyPane = false; + + // the user or team being assigned permissions scope.owner = scope.resolve.resourceData.data; } // aggregate name/descriptions for each available role, based on resource type + // reasoning: function aggregateKey(item, type){ - _.merge(scope.keys[type], item.summary_fields.object_roles); + _.merge(scope.keys[type], _.omit(item.summary_fields.object_roles, 'read_role')); } scope.closeModal = function() { @@ -66,11 +100,6 @@ function(rootScope, scope, $state, GetBasePath, Rest, $q, Wait, ProcessErrors) { return Object.keys(scope.selected[tab]).length > 0; }; - scope.removeSelection = function(resource, type){ - delete scope.selected[type][resource.id]; - resource.isSelected = false; - }; - // handle form tab changes scope.selectTab = function(selected){ _.each(scope.tab, (value, key, collection) => { @@ -78,7 +107,7 @@ function(rootScope, scope, $state, GetBasePath, Rest, $q, Wait, ProcessErrors) { }); }; - // pop/push into unified collection of selected users & teams + // pop/push into unified collection of selected resourcesf scope.$on("selectedOrDeselected", function(e, value) { let resourceType = scope.currentTab(), item = value.value; @@ -94,15 +123,20 @@ function(rootScope, scope, $state, GetBasePath, Rest, $q, Wait, ProcessErrors) { // post roles to api scope.saveForm = function() { - Wait('start'); - // scope.selected => { n: {id: n}, ... } => [ {id: n}, ... ] - let requests = _(scope.selected).map((type) => { - return _.map(type, (resource) => resource.roles); + //Wait('start'); + + // builds an array of role entities to apply to current user or team + let roles = _(scope.selected).map( (resources, type) =>{ + return _.map(resources, (resource) => { + return resource.summary_fields.object_roles[scope.roleSelection[type]] + }); }).flattenDeep().value(); + + debugger; Rest.setUrl(scope.owner.related.roles); - $q.all( _.map(requests, (entity) => Rest.post({id: entity.id})) ) + $q.all( _.map(roles, (entity) => Rest.post({id: entity.id})) ) .then( () =>{ Wait('stop'); scope.closeModal(); diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html index dc330bc035..de79fe03f0 100644 --- a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.partial.html @@ -20,7 +20,7 @@ -
+
@@ -65,7 +65,7 @@
-
+
@@ -141,7 +141,15 @@
- + +
+ +
@@ -149,7 +157,8 @@ + selected="selected" + ng-show="tab[type]">
@@ -167,7 +176,7 @@
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 d94411ff0f..855c15e093 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 @@ -70,7 +70,13 @@ export default ['addPermissionsTeamsList', 'addPermissionsUsersList', 'TemplateL description: list.fields.description }; break; - + case 'Users': + list.fields = { + username: list.fields.username, + first_name: list.fields.first_name, + last_name: list.fields.last_name + } + break; default: list.fields = { name: list.fields.name, diff --git a/awx/ui/client/src/access/rbac-role-column/roleList.directive.js b/awx/ui/client/src/access/rbac-role-column/roleList.directive.js index 2ee33b8652..97682d0bc9 100644 --- a/awx/ui/client/src/access/rbac-role-column/roleList.directive.js +++ b/awx/ui/client/src/access/rbac-role-column/roleList.directive.js @@ -5,7 +5,7 @@ export default return { restrict: 'E', scope: true, - templateUrl: templateUrl('access/rbac-role-list/roleList'), + templateUrl: templateUrl('access/rbac-role-column/roleList'), link: function(scope, element, attrs) { // given a list of roles (things like "project // auditor") which are pulled from two different diff --git a/awx/ui/client/src/shared/list-generator/list-generator.factory.js b/awx/ui/client/src/shared/list-generator/list-generator.factory.js index b1a74db51a..cac1e129aa 100644 --- a/awx/ui/client/src/shared/list-generator/list-generator.factory.js +++ b/awx/ui/client/src/shared/list-generator/list-generator.factory.js @@ -241,9 +241,11 @@ export default ['$location', '$compile', '$rootScope', 'Attr', 'Icon', } // Show the "no items" box when loading is done and the user isn't actively searching and there are no results - html += `
`; - html += (list.emptyListText) ? list.emptyListText : i18n._("PLEASE ADD ITEMS TO THIS LIST"); - html += "
"; + if (options.showEmptyPanel === undefined || options.showEmptyPanel === true){ + html += `
`; + html += (list.emptyListText) ? list.emptyListText : i18n._("PLEASE ADD ITEMS TO THIS LIST"); + html += "
"; + } // Add a title and optionally a close button (used on Inventory->Groups) if (options.mode !== 'lookup' && list.showTitle) { From f6303d206bd2ebbed41654ca33bfe31a76c4e830 Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Wed, 14 Dec 2016 17:48:56 -0500 Subject: [PATCH 08/13] add "Add Permissions" action to Teams form --- awx/ui/client/src/forms/Teams.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/awx/ui/client/src/forms/Teams.js b/awx/ui/client/src/forms/Teams.js index 639a4b2a00..39e5099b2f 100644 --- a/awx/ui/client/src/forms/Teams.js +++ b/awx/ui/client/src/forms/Teams.js @@ -150,7 +150,16 @@ export default ngShow: 'permission.summary_fields.user_capabilities.unattach' } }, - //hideOnSuperuser: true // defunct with RBAC + actions: { + add: { + ngClick: "$state.go('.add')", + label: 'Add', + awToolTip: i18n._('Grant Permission'), + actionClass: 'btn List-buttonSubmit', + buttonContent: '+ ' + i18n._('ADD PERMISSIONS'), + ngShow: '(puser_obj.summary_fields.user_capabilities.edit || canAdd)' + } + } } }, };}]); //InventoryForm From 26de1ffc2ff09cbe3443659febe2429afeec026f Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Wed, 14 Dec 2016 17:51:38 -0500 Subject: [PATCH 09/13] Filter batch permission granting states by role level --- awx/ui/client/src/shared/stateDefinitions.factory.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/awx/ui/client/src/shared/stateDefinitions.factory.js b/awx/ui/client/src/shared/stateDefinitions.factory.js index 21ba01aade..34b3c1c67a 100644 --- a/awx/ui/client/src/shared/stateDefinitions.factory.js +++ b/awx/ui/client/src/shared/stateDefinitions.factory.js @@ -239,23 +239,23 @@ export default ['$injector', '$stateExtender', '$log', function($injector, $stat url: '/add-permissions', params: { project_search: { - value: {order_by: 'name', page_size: '5'}, + value: {order_by: 'name', page_size: '5', role_level: 'admin_role'}, dynamic: true }, job_template_search: { - value: {order_by: 'name', page_size: '5'}, + value: {order_by: 'name', page_size: '5', role_level: 'admin_role'}, dynamic: true }, workflow_template_search: { - value: {order_by: 'name', page_size: '5'}, + value: {order_by: 'name', page_size: '5', role_level: 'admin_role'}, dynamic: true }, inventory_search: { - value: {order_by: 'name', page_size: '5'}, + value: {order_by: 'name', page_size: '5', role_level: 'admin_role'}, dynamic: true }, credential_search: { - value: {order_by: 'name', page_size: '5'}, + value: {order_by: 'name', page_size: '5', role_level: 'admin_role'}, dynamic: true } }, From ad89483c1efa510e82cdbc3de2273607c9effe13 Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Thu, 15 Dec 2016 14:55:57 -0500 Subject: [PATCH 10/13] remove extra closing div --- awx/ui/client/src/shared/form-generator.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/awx/ui/client/src/shared/form-generator.js b/awx/ui/client/src/shared/form-generator.js index 0d66226088..e2aa526257 100644 --- a/awx/ui/client/src/shared/form-generator.js +++ b/awx/ui/client/src/shared/form-generator.js @@ -1760,8 +1760,6 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat if (this.form.horizontal) { html += "
\n"; } - html += ''; - } } From 11a1ca987f5f48be516d4ced830ed7f799f33332 Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Thu, 15 Dec 2016 16:06:52 -0500 Subject: [PATCH 11/13] remove debugger --- .../src/access/add-rbac-user-team/rbac-user-team.controller.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js index 665f5f6c26..3e8f637f1d 100644 --- a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js @@ -131,8 +131,6 @@ function(rootScope, scope, $state, i18n, CreateSelect2, GetBasePath, Rest, $q, W return resource.summary_fields.object_roles[scope.roleSelection[type]] }); }).flattenDeep().value(); - - debugger; Rest.setUrl(scope.owner.related.roles); From c8f1f11816594309b57a2275a823c441a8c215ad Mon Sep 17 00:00:00 2001 From: Ken Hoes Date: Fri, 16 Dec 2016 11:23:24 -0500 Subject: [PATCH 12/13] Fixed jshint errors --- .../rbac-selected-list.directive.js | 6 +++--- .../add-rbac-user-team/rbac-user-team.controller.js | 12 ++++++------ .../rbac-multiselect-list.directive.js | 12 ++++++------ awx/ui/client/src/forms/Teams.js | 3 +-- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-selected-list.directive.js b/awx/ui/client/src/access/add-rbac-user-team/rbac-selected-list.directive.js index 99e2cb451f..f65d0324ad 100644 --- a/awx/ui/client/src/access/add-rbac-user-team/rbac-selected-list.directive.js +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-selected-list.directive.js @@ -5,7 +5,7 @@ *************************************************/ /* jshint unused: vars */ -export default ['$compile','templateUrl', 'i18n', 'generateList', +export default ['$compile','templateUrl', 'i18n', 'generateList', 'ProjectList', 'TemplateList', 'InventoryList', 'CredentialList', function($compile, templateUrl, i18n, generateList, ProjectList, TemplateList, InventoryList, CredentialList) { @@ -71,7 +71,7 @@ export default ['$compile','templateUrl', 'i18n', 'generateList', case 'workflow_templates': list.name = 'workflow_templates'; - list.iterator = 'workflow_template', + list.iterator = 'workflow_template'; list.basePath = 'workflow_job_templates'; list.fields = { name: list.fields.name, @@ -114,7 +114,7 @@ export default ['$compile','templateUrl', 'i18n', 'generateList', // section 1 and section 2 elements produce sibling scopes // This means events propogated from section 2 are not received in section 1 // The following code directly accesses the right scope by list table id - multiselect_scope = angular.element('#AddPermissions-body').find(`#${type}_table`).scope() + multiselect_scope = angular.element('#AddPermissions-body').find(`#${type}_table`).scope(); deselectedIdx = _.findIndex(multiselect_scope[type], {id: resource.id}); multiselect_scope[type][deselectedIdx].isSelected = false; }; diff --git a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js index 3e8f637f1d..3530124788 100644 --- a/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js +++ b/awx/ui/client/src/access/add-rbac-user-team/rbac-user-team.controller.js @@ -11,7 +11,7 @@ * Controller for handling permissions adding */ -export default ['$rootScope', '$scope', '$state', 'i18n', 'CreateSelect2', 'GetBasePath', 'Rest', '$q', 'Wait', 'ProcessErrors', +export default ['$rootScope', '$scope', '$state', 'i18n', 'CreateSelect2', 'GetBasePath', 'Rest', '$q', 'Wait', 'ProcessErrors', function(rootScope, scope, $state, i18n, CreateSelect2, GetBasePath, Rest, $q, Wait, ProcessErrors) { init(); @@ -51,7 +51,7 @@ function(rootScope, scope, $state, i18n, CreateSelect2, GetBasePath, Rest, $q, W /*