Add repo permissions dialog for existing teams and robots

Fixes #1686
This commit is contained in:
Joseph Schorr 2016-08-22 14:42:35 -04:00
parent b5efc57655
commit 391d70d9ec
18 changed files with 496 additions and 224 deletions

View file

@ -22,7 +22,7 @@ angular.module('quay').directive('createEntityDialog', function () {
controller: function($scope, $element, ApiService, UIService, UserService) {
$scope.context = {
'addPermissionsCounter': 0
'setPermissionsCounter': 0
};
$scope.$on('$destroy', function() {
@ -71,17 +71,17 @@ angular.module('quay').directive('createEntityDialog', function () {
});
};
$scope.permissionsAdded = function(repositories) {
$scope.permissionsSet = function(repositories) {
$scope.entity['repo_count'] = repositories.length;
$scope.hide();
};
$scope.addingPermissions = function() {
$scope.view = 'addingperms';
$scope.settingPermissions = function() {
$scope.view = 'settingperms';
};
$scope.addPermissions = function() {
$scope.context.addPermissionsCounter++;
$scope.setPermissions = function() {
$scope.context.setPermissionsCounter++;
};
$scope.repositoriesLoaded = function(repositories) {
@ -90,7 +90,7 @@ angular.module('quay').directive('createEntityDialog', function () {
return;
}
$scope.view = 'addperms';
$scope.view = 'setperms';
};
$scope.$watch('entityNameRegex', function(r) {

View file

@ -33,15 +33,6 @@ angular.module('quay').directive('robotsManager', function () {
locationListener && locationListener();
});
var loadRobotPermissions = function(info) {
var shortName = $scope.getShortenedName(info.name);
info.loading_permissions = true;
ApiService.getRobotPermissions($scope.organization, null, {'robot_shortname': shortName}).then(function(resp) {
info.permissions = resp.permissions;
info.loading_permissions = false;
}, ApiService.errorDisplay('Could not load robot permissions'));
};
$scope.filterToRobot = function(robotName) {
if ($scope.robotFilter == robotName) {
return;
@ -56,14 +47,6 @@ angular.module('quay').directive('robotsManager', function () {
$scope.robotFilter = robotName;
};
$scope.showPermissions = function(robotInfo) {
robotInfo.showing_permissions = !robotInfo.showing_permissions;
if (robotInfo.showing_permissions) {
loadRobotPermissions(robotInfo);
}
};
$scope.showRobot = function(info) {
$scope.robotDisplayInfo = {
'name': info.name
@ -126,6 +109,21 @@ angular.module('quay').directive('robotsManager', function () {
});
};
$scope.setPermissions = function(info) {
var namespace = $scope.organization ? $scope.organization.name : $scope.user.username;
$scope.setRepoPermissionsInfo = {
'namespace': namespace,
'entityName': info.name,
'entityKind': 'robot',
'entityIcon': 'ci-robot'
};
};
$scope.handlePermissionsSet = function(info, repositories) {
var index = $scope.findRobotIndexByName(info.entityName);
$scope.robots[index]['repositories'] = repositories;
};
$scope.robotCreated = function() {
update();
};

View file

@ -0,0 +1,60 @@
/**
* An element which displays a dialog for setting permissions for an entity to repositories under
* a namespace.
*/
angular.module('quay').directive('setRepoPermissionsDialog', function () {
var directiveDefinitionObject = {
priority: 0,
templateUrl: '/static/directives/set-repo-permissions-dialog.html',
replace: false,
transclude: true,
restrict: 'C',
scope: {
'info': '=info',
'permissionsSet': '&permissionsSet',
},
controller: function($scope, $element) {
$scope.setPermissionsCounter = 0;
$scope.loading = false;
$scope.context = {};
$scope.setPermissions = function() {
$scope.setPermissionsCounter++;
};
$scope.settingPermissions = function() {
$scope.working = true;
};
$scope.show = function() {
$scope.setPermissionsCounter = 0;
$scope.working = false;
$element.find('.modal').modal({});
};
$scope.hide = function() {
$scope.working = false;
$scope.context.info = null;
$scope.context.hasChangedRepositories = false;
$scope.context.hasCheckedRepositories = false;
$element.find('.modal').modal('hide');
};
$scope.permissionsSetComplete = function(repositories) {
$scope.hide();
$scope.permissionsSet({'repositories': repositories, 'info': $scope.info});
};
$scope.$watch('info', function(info) {
if (info) {
$scope.context.info = info;
$scope.show();
}
});
}
};
return directiveDefinitionObject;
});

View file

@ -1,11 +1,11 @@
/**
* An element which displays a table for adding permissions for an entity to repositories under
* An element which displays a table for setting permissions for an entity to repositories under
* a namespace.
*/
angular.module('quay').directive('addRepoPermissions', function () {
angular.module('quay').directive('setRepoPermissions', function () {
var directiveDefinitionObject = {
priority: 0,
templateUrl: '/static/directives/add-repo-permissions.html',
templateUrl: '/static/directives/set-repo-permissions.html',
replace: false,
transclude: true,
restrict: 'C',
@ -14,15 +14,14 @@ angular.module('quay').directive('addRepoPermissions', function () {
'entityName': '=entityName',
'entityKind': '=entityKind',
'checkedRepository': '=checkedRepository',
'addPermissions': '=addPermissions',
'setPermissions': '=setPermissions',
'hasCheckedRepositories': '=hasCheckedRepositories',
'hasChangedRepositories': '=hasChangedRepositories',
'repositoriesLoaded': '&repositoriesLoaded',
'addingPermissions': '&addingPermissions',
'permissionsAdded': '&permissionsAdded',
'settingPermissions': '&settingPermissions',
'permissionsSet': '&permissionsSet',
},
controller: function($scope, $element, ApiService, UIService, TableService, RolesService, UserService) {
@ -36,6 +35,20 @@ angular.module('quay').directive('addRepoPermissions', function () {
$scope.repositories = null;
$scope.currentNamespace = null;
$scope.currentEntityName = null;
var checkForChanges = function() {
var hasChanges = false;
$scope.repositories.forEach(function(repo) {
if (repo['permission'] != repo['original_permission']) {
hasChanges = true;
}
});
$scope.hasCheckedRepositories = !!$scope.checkedRepos.checked.length;
$scope.hasChangedRepositories = hasChanges;
};
var handleRepoCheckChange = function() {
$scope.repositories.forEach(function(repo) {
@ -48,7 +61,7 @@ angular.module('quay').directive('addRepoPermissions', function () {
}
});
$scope.hasCheckedRepositories = !!$scope.checkedRepos.checked.length;
checkForChanges();
};
var setRepoState = function() {
@ -62,18 +75,43 @@ angular.module('quay').directive('addRepoPermissions', function () {
['last_modified_datetime']);
};
var loadRepositories = function() {
var loadRepositoriesAndPermissions = function() {
if (!$scope.namespace || !$scope.entityName || !$scope.entityKind) {
return;
}
if ($scope.namespace == $scope.currentNamespace) {
if (($scope.entityName == $scope.currentEntityName) &&
($scope.namespace == $scope.currentNamespace)) {
return;
}
$scope.currentNamespace = $scope.namespace;
$scope.currentEntityName = $scope.entityName;
// Load the repository permissions for the entity first. We then load the full repo list
// and compare.
RolesService.getRepoPermissions($scope.namespace, $scope.entityKind, $scope.entityName,
function(permissions) {
if (permissions == null) {
$scope.currentNamespace = null;
$scope.currentEntityName = null;
return;
}
var existingPermissionsMap = {};
permissions.forEach(function(existingPermission) {
existingPermissionsMap[existingPermission.repository.name] = existingPermission.role;
});
loadRepositories(existingPermissionsMap);
});
};
var loadRepositories = function(existingPermissionsMap) {
$scope.namespaceInfo = UserService.getNamespace($scope.namespace);
// Load the repositories under the entity's namespace.
// Load the repositories under the entity's namespace, along with the current repo
// permissions for the entity.
var params = {
'namespace': $scope.namespace,
'last_modified': true
@ -84,12 +122,15 @@ angular.module('quay').directive('addRepoPermissions', function () {
var repos = [];
resp['repositories'].forEach(function(repo) {
var existingPermission = existingPermissionsMap[repo.name] || 'none';
repos.push({
'namespace': repo.namespace,
'name': repo.name,
'last_modified': repo.last_modified,
'last_modified_datetime': TableService.getReversedTimestamp(repo.last_modified),
'permission': 'none'
'permission': existingPermission,
'original_permission': existingPermission
});
});
@ -100,53 +141,55 @@ angular.module('quay').directive('addRepoPermissions', function () {
$scope.repositories = repos;
$scope.checkedRepos = UIService.createCheckStateController($scope.repositories, 'name');
$scope.checkedRepos.listen(handleRepoCheckChange);
if ($scope.checkedRepository) {
repos.forEach(function(repo) {
if (repo['namespace'] == $scope.checkedRepository.namespace &&
repo['name'] == $scope.checkedRepository.name) {
$scope.checkedRepos.checkItem(repo);
$scope.options.filter = $scope.checkedRepository.name;
}
});
}
repos.forEach(function(repo) {
if (repo.permission != 'none') {
$scope.checkedRepos.checkItem(repo);
}
});
$scope.checkedRepos.listen(handleRepoCheckChange);
setRepoState();
$scope.repositoriesLoaded({'repositories': repos});
}, ApiService.errorDisplay('Could not load repositories'));
};
var addPermissions = function() {
var setPermissions = function() {
if (!$scope.checkedRepos || !$scope.namespace || !$scope.repositories) {
return;
}
$scope.addingPermissions();
$scope.settingPermissions();
var repos = $scope.checkedRepos.checked;
var repos = $scope.repositories;
var counter = 0;
var addPerm = function() {
var setPerm = function() {
if (counter >= repos.length) {
$scope.permissionsAdded({'repositories': repos});
$scope.permissionsSet({'repositories': $scope.checkedRepos.checked});
$scope.checkedRepos.setChecked([]);
return;
}
var repo = repos[counter];
if (repo['permission'] == repo['original_permission']) {
// Skip changing it.
counter++;
setPerm();
return;
}
RolesService.setRepositoryRole(repo, repo.permission, $scope.entityKind,
$scope.entityName,
function(status) {
if (status) {
counter++;
addPerm();
} else {
$scope.permissionsAdded();
}
});
$scope.entityName, function(status) {
if (status) {
counter++;
setPerm();
}
});
};
addPerm();
setPerm();
};
$scope.setRole = function(role, repo) {
@ -157,6 +200,8 @@ angular.module('quay').directive('addRepoPermissions', function () {
} else {
$scope.checkedRepos.checkItem(repo);
}
checkForChanges();
};
$scope.allRepositoriesFilter = function(item) {
@ -175,13 +220,13 @@ angular.module('quay').directive('addRepoPermissions', function () {
$scope.$watch('options.reverse', setRepoState);
$scope.$watch('options.filter', setRepoState);
$scope.$watch('namespace', loadRepositories);
$scope.$watch('entityName', loadRepositories);
$scope.$watch('entityKind', loadRepositories);
$scope.$watch('namespace', loadRepositoriesAndPermissions);
$scope.$watch('entityName', loadRepositoriesAndPermissions);
$scope.$watch('entityKind', loadRepositoriesAndPermissions);
$scope.$watch('addPermissions', function(value) {
$scope.$watch('setPermissions', function(value) {
if (value) {
addPermissions();
setPermissions();
}
});
}

View file

@ -196,6 +196,20 @@ angular.module('quay').directive('teamsManager', function () {
$scope.removeMemberInfo = $.extend({}, memberInfo);
};
$scope.setRepoPermissions = function(teamName) {
$scope.setRepoPermissionsInfo = {
'namespace': $scope.organization.name,
'entityName': teamName,
'entityKind': 'team',
'entityIcon': 'fa-group'
};
};
$scope.handlePermissionsSet = function(info, repositories) {
var team = $scope.organization.teams[info.entityName];
team['repo_count'] = repositories.length;
};
$scope.$watch('organization', setTeamsState);
$scope.$watch('isEnabled', setTeamsState);