- Add an entity-search directive for adding a nice search box for users or teams
- Add support for team-based permissions to the repos
This commit is contained in:
parent
09afe0753f
commit
100ec563fa
7 changed files with 362 additions and 93 deletions
|
@ -233,6 +233,82 @@ quayApp.directive('repoCircle', function () {
|
|||
});
|
||||
|
||||
|
||||
quayApp.directive('entitySearch', function () {
|
||||
var number = 0;
|
||||
var directiveDefinitionObject = {
|
||||
priority: 0,
|
||||
templateUrl: '/static/directives/entity-search.html',
|
||||
replace: false,
|
||||
transclude: false,
|
||||
restrict: 'C',
|
||||
scope: {
|
||||
'organization': '=organization',
|
||||
'inputTitle': '=inputTitle',
|
||||
'entitySelected': '=entitySelected'
|
||||
},
|
||||
controller: function($scope, $element) {
|
||||
if (!$scope.entitySelected) { return; }
|
||||
|
||||
number++;
|
||||
|
||||
var input = $element[0].firstChild;
|
||||
$scope.organization = $scope.organization || '';
|
||||
$(input).typeahead({
|
||||
name: 'entities' + number,
|
||||
remote: {
|
||||
url: '/api/entities/%QUERY',
|
||||
replace: function (url, uriEncodedQuery) {
|
||||
url = url.replace('%QUERY', uriEncodedQuery);
|
||||
if ($scope.organization) {
|
||||
url += '?organization=' + encodeURIComponent($scope.organization);
|
||||
}
|
||||
return url;
|
||||
},
|
||||
filter: function(data) {
|
||||
var datums = [];
|
||||
for (var i = 0; i < data.results.length; ++i) {
|
||||
var entity = data.results[i];
|
||||
datums.push({
|
||||
'value': entity.name,
|
||||
'tokens': [entity.name],
|
||||
'entity': entity
|
||||
});
|
||||
}
|
||||
return datums;
|
||||
}
|
||||
},
|
||||
template: function (datum) {
|
||||
template = '<div class="entity-mini-listing">';
|
||||
if (datum.entity.kind == 'user') {
|
||||
template += '<i class="fa fa-user fa-lg"></i>';
|
||||
} else if (datum.entity.kind == 'team') {
|
||||
template += '<i class="fa fa-group fa-lg"></i>';
|
||||
}
|
||||
template += '<span class="name">' + datum.value + '</span>';
|
||||
|
||||
if (datum.entity.outside_org) {
|
||||
template += '<div class="alert-warning warning">This user is outside your organization</div>';
|
||||
}
|
||||
|
||||
template += '</div>';
|
||||
return template;
|
||||
},
|
||||
});
|
||||
|
||||
$(input).on('typeahead:selected', function(e, datum) {
|
||||
$(input).typeahead('setQuery', '');
|
||||
$scope.entitySelected(datum.entity);
|
||||
});
|
||||
|
||||
$scope.$watch('inputTitle', function(title) {
|
||||
input.setAttribute('placeholder', title);
|
||||
});
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
});
|
||||
|
||||
|
||||
quayApp.directive('namespaceSelector', function () {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 0,
|
||||
|
|
|
@ -527,39 +527,7 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
|
|||
var namespace = $routeParams.namespace;
|
||||
var name = $routeParams.name;
|
||||
|
||||
$scope.$on('$viewContentLoaded', function() {
|
||||
// THIS IS BAD, MOVE THIS TO A DIRECTIVE
|
||||
$('#userSearch').typeahead({
|
||||
name: 'users',
|
||||
remote: {
|
||||
url: '/api/users/%QUERY',
|
||||
filter: function(data) {
|
||||
var datums = [];
|
||||
for (var i = 0; i < data.users.length; ++i) {
|
||||
var user = data.users[i];
|
||||
datums.push({
|
||||
'value': user,
|
||||
'tokens': [user],
|
||||
'username': user
|
||||
});
|
||||
}
|
||||
return datums;
|
||||
}
|
||||
},
|
||||
template: function (datum) {
|
||||
template = '<div class="user-mini-listing">';
|
||||
template += '<i class="fa fa-user fa-lg"></i>'
|
||||
template += '<span class="name">' + datum.username + '</span>'
|
||||
template += '</div>'
|
||||
return template;
|
||||
},
|
||||
});
|
||||
|
||||
$('#userSearch').on('typeahead:selected', function(e, datum) {
|
||||
$('#userSearch').typeahead('setQuery', '');
|
||||
$scope.addNewPermission(datum.username);
|
||||
});
|
||||
});
|
||||
$scope.permissions = {'team': [], 'user': []};
|
||||
|
||||
$scope.isDownloadSupported = function() {
|
||||
try { return !!new Blob(); } catch(e){}
|
||||
|
@ -580,21 +548,34 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
|
|||
saveAs(blob, '.dockercfg');
|
||||
};
|
||||
|
||||
$scope.addNewPermission = function(username) {
|
||||
$scope.grantRole = function() {
|
||||
$('#confirmaddoutsideModal').modal('hide');
|
||||
var entity = $scope.currentAddEntity;
|
||||
$scope.addRole(entity.name, 'read', entity.kind, entity.outside_org)
|
||||
$scope.currentAddEntity = null;
|
||||
};
|
||||
|
||||
$scope.addNewPermission = function(entity) {
|
||||
// Don't allow duplicates.
|
||||
if ($scope.permissions[username]) { return; }
|
||||
if ($scope.permissions[entity.kind][entity.name]) { return; }
|
||||
|
||||
if (entity.outside_org) {
|
||||
$scope.currentAddEntity = entity;
|
||||
$('#confirmaddoutsideModal').modal('show');
|
||||
return;
|
||||
}
|
||||
|
||||
// Need the $scope.apply for both the permission stuff to change and for
|
||||
// the XHR call to be made.
|
||||
$scope.$apply(function() {
|
||||
$scope.addRole(username, 'read')
|
||||
$scope.addRole(entity.name, 'read', entity.kind, entity.outside_org)
|
||||
});
|
||||
};
|
||||
|
||||
$scope.deleteRole = function(username) {
|
||||
var permissionDelete = Restangular.one('repository/' + namespace + '/' + name + '/permissions/' + username);
|
||||
$scope.deleteRole = function(entityName, kind) {
|
||||
var permissionDelete = Restangular.one('repository/' + namespace + '/' + name + '/permissions/' + kind + '/' + entityName);
|
||||
permissionDelete.customDELETE().then(function() {
|
||||
delete $scope.permissions[username];
|
||||
delete $scope.permissions[kind][entityName];
|
||||
}, function(result) {
|
||||
if (result.status == 409) {
|
||||
$('#onlyadminModal').modal({});
|
||||
|
@ -604,26 +585,26 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
|
|||
});
|
||||
};
|
||||
|
||||
$scope.addRole = function(username, role) {
|
||||
$scope.addRole = function(entityName, role, kind, outside_org) {
|
||||
var permission = {
|
||||
'role': role
|
||||
'role': role,
|
||||
'outside_org': !!outside_org
|
||||
};
|
||||
|
||||
var permissionPost = Restangular.one('repository/' + namespace + '/' + name + '/permissions/' + username);
|
||||
var permissionPost = Restangular.one('repository/' + namespace + '/' + name + '/permissions/' + kind + '/' + entityName);
|
||||
permissionPost.customPOST(permission).then(function() {
|
||||
$scope.permissions[username] = permission;
|
||||
$scope.permissions = $scope.permissions;
|
||||
$scope.permissions[kind][entityName] = permission;
|
||||
}, function(result) {
|
||||
$('#cannotchangeModal').modal({});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.setRole = function(username, role) {
|
||||
var permission = $scope.permissions[username];
|
||||
$scope.setRole = function(entityName, role, kind) {
|
||||
var permission = $scope.permissions[kind][entityName];
|
||||
var currentRole = permission.role;
|
||||
permission.role = role;
|
||||
|
||||
var permissionPut = Restangular.one('repository/' + namespace + '/' + name + '/permissions/' + username);
|
||||
var permissionPut = Restangular.one('repository/' + namespace + '/' + name + '/permissions/' + kind + '/' + entityName);
|
||||
permissionPut.customPUT(permission).then(function() {}, function(result) {
|
||||
if (result.status == 409) {
|
||||
permission.role = currentRole;
|
||||
|
@ -709,6 +690,23 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
|
|||
|
||||
$scope.loading = true;
|
||||
|
||||
var checkLoading = function() {
|
||||
$scope.loading = !($scope.permissions['user'] && $scope.permissions['team'] && $scope.repo && $scope.tokens);
|
||||
};
|
||||
|
||||
var fetchPermissions = function(kind) {
|
||||
var permissionsFetch = Restangular.one('repository/' + namespace + '/' + name + '/permissions/' + kind + '/');
|
||||
permissionsFetch.get().then(function(resp) {
|
||||
$rootScope.title = 'Settings - ' + namespace + '/' + name;
|
||||
$scope.permissions[kind] = resp.permissions;
|
||||
checkLoading();
|
||||
}, function() {
|
||||
$scope.permissions[kind] = null;
|
||||
$rootScope.title = 'Unknown Repository';
|
||||
$scope.loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
// Fetch the repository information.
|
||||
var repositoryFetch = Restangular.one('repository/' + namespace + '/' + name);
|
||||
repositoryFetch.get().then(function(repo) {
|
||||
|
@ -720,23 +718,15 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
|
|||
$scope.loading = false;
|
||||
});
|
||||
|
||||
// Fetch the permissions.
|
||||
var permissionsFetch = Restangular.one('repository/' + namespace + '/' + name + '/permissions');
|
||||
permissionsFetch.get().then(function(resp) {
|
||||
$rootScope.title = 'Settings - ' + namespace + '/' + name;
|
||||
$scope.permissions = resp.permissions;
|
||||
$scope.loading = !($scope.permissions && $scope.repo && $scope.tokens);
|
||||
}, function() {
|
||||
$scope.permissions = null;
|
||||
$rootScope.title = 'Unknown Repository';
|
||||
$scope.loading = false;
|
||||
});
|
||||
// Fetch the user and team permissions.
|
||||
fetchPermissions('user');
|
||||
fetchPermissions('team');
|
||||
|
||||
// Fetch the tokens.
|
||||
var tokensFetch = Restangular.one('repository/' + namespace + '/' + name + '/tokens/');
|
||||
tokensFetch.get().then(function(resp) {
|
||||
$scope.tokens = resp.tokens;
|
||||
$scope.loading = !($scope.permissions && $scope.repo && $scope.tokens);
|
||||
checkLoading();
|
||||
}, function() {
|
||||
$scope.tokens = null;
|
||||
$scope.loading = false;
|
||||
|
|
Reference in a new issue