diff --git a/static/directives/entity-reference.html b/static/directives/entity-reference.html index 6cb91a5c0..12ee81f86 100644 --- a/static/directives/entity-reference.html +++ b/static/directives/entity-reference.html @@ -1,19 +1,27 @@ <span class="entity-reference-element"> - <span ng-show="entity.kind == 'team'"> + <span ng-if="entity.kind == 'team'"> <i class="fa fa-group" title="Team" bs-tooltip="tooltip.title" data-container="body"></i> <span class="entity-name"> - <span ng-show="!getIsAdmin(namespace)">{{entity.name}}</span> - <span ng-show="getIsAdmin(namespace)"><a href="/organization/{{ namespace }}/teams/{{ entity.name }}">{{entity.name}}</a></span> + <span ng-if="!getIsAdmin(namespace)">{{entity.name}}</span> + <span ng-if="getIsAdmin(namespace)"><a href="/organization/{{ namespace }}/teams/{{ entity.name }}">{{entity.name}}</a></span> </span> </span> - <span ng-show="entity.kind != 'team'"> + <span ng-if="entity.kind != 'team'"> <i class="fa fa-user" ng-show="!entity.is_robot" title="User" bs-tooltip="tooltip.title" data-container="body"></i> <i class="fa fa-wrench" ng-show="entity.is_robot" title="Robot Account" bs-tooltip="tooltip.title" data-container="body"></i> - <span class="entity-name"> - <span ng-show="entity.is_robot" class="prefix">{{getPrefix(entity.name)}}</span><span>{{getShortenedName(entity.name)}}</span> + <span class="entity-name" ng-if="entity.is_robot"> + <a href="{{ getRobotUrl(entity.name) }}" ng-if="getIsAdmin(getPrefix(entity.name))"> + <span class="prefix">{{ getPrefix(entity.name) }}+</span><span>{{ getShortenedName(entity.name) }}</span> + </a> + <span ng-if="!getIsAdmin(getPrefix(entity.name))"> + <span class="prefix">{{ getPrefix(entity.name) }}+</span><span>{{ getShortenedName(entity.name) }}</span> + </span> + </span> + <span class="entity-name" ng-if="!entity.is_robot"> + <span>{{getShortenedName(entity.name)}}</span> </span> </span> - <i class="fa fa-exclamation-triangle" ng-show="entity.is_org_member === false" - title="This user is not a member of the organization" bs-tooltip="tooltip.title"> + <i class="fa fa-exclamation-triangle" ng-if="entity.is_org_member === false" + title="This user is not a member of the organization" bs-tooltip="tooltip.title" data-container="body"> </i> </span> diff --git a/static/directives/entity-search.html b/static/directives/entity-search.html index e87f3e2c3..04dac6c0f 100644 --- a/static/directives/entity-search.html +++ b/static/directives/entity-search.html @@ -7,6 +7,10 @@ </button> <ul class="dropdown-menu" role="menu" aria-labelledby="entityDropdownMenu"> <li ng-show="lazyLoading" style="padding: 10px"><div class="quay-spinner"></div></li> + + <li role="presentation" class="dropdown-header" ng-show="!lazyLoading && !robots && !isAdmin && !teams"> + You do not have permission to manage teams and robots for this organization + </li> <li role="presentation" ng-repeat="team in teams" ng-show="!lazyLoading" ng-click="setEntity(team.name, 'team', false)"> diff --git a/static/js/app.js b/static/js/app.js index cdb939745..771ae6098 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -838,15 +838,34 @@ quayApp.directive('entityReference', function () { 'entity': '=entity', 'namespace': '=namespace' }, - controller: function($scope, $element, UserService) { + controller: function($scope, $element, UserService, $sanitize) { $scope.getIsAdmin = function(namespace) { return UserService.isNamespaceAdmin(namespace); }; + $scope.getRobotUrl = function(name) { + var namespace = $scope.getPrefix(name); + if (!namespace) { + return ''; + } + + if (!$scope.getIsAdmin(namespace)) { + return ''; + } + + var org = UserService.getOrganization(namespace); + if (!org) { + // This robot is owned by the user. + return '/user/?tab=robots&showRobot=' + $sanitize(name); + } + + return '/organization/' + org['name'] + '/admin?tab=robots&showRobot=' + $sanitize(name); + }; + $scope.getPrefix = function(name) { if (!name) { return ''; } var plus = name.indexOf('+'); - return name.substr(0, plus + 1); + return name.substr(0, plus); }; $scope.getShortenedName = function(name) { @@ -1500,7 +1519,7 @@ quayApp.directive('robotsManager', function () { 'organization': '=organization', 'user': '=user' }, - controller: function($scope, $element, ApiService) { + controller: function($scope, $element, ApiService, $routeParams) { $scope.ROBOT_PATTERN = ROBOT_PATTERN; $scope.robots = null; $scope.loading = false; @@ -1511,6 +1530,15 @@ quayApp.directive('robotsManager', function () { $scope.shownRobot = info; $scope.showRobotCounter++; }; + + $scope.findRobotIndexByName = function(name) { + for (var i = 0; i < $scope.robots.length; ++i) { + if ($scope.robots[i].name == name) { + return i; + } + } + return -1; + }; $scope.getShortenedName = function(name) { var plus = name.indexOf('+'); @@ -1534,11 +1562,9 @@ quayApp.directive('robotsManager', function () { $scope.deleteRobot = function(info) { var shortName = $scope.getShortenedName(info.name); ApiService.deleteRobot($scope.organization, null, {'robot_shortname': shortName}).then(function(resp) { - for (var i = 0; i < $scope.robots.length; ++i) { - if ($scope.robots[i].name == info.name) { - $scope.robots.splice(i, 1); - return; - } + var index = $scope.findRobotIndexByName(info.name); + if (index >= 0) { + $scope.robots.splice(index, 1); } }, function() { bootbox.dialog({ @@ -1562,6 +1588,13 @@ quayApp.directive('robotsManager', function () { ApiService.getRobots($scope.organization).then(function(resp) { $scope.robots = resp.robots; $scope.loading = false; + + if ($routeParams.showRobot) { + var index = $scope.findRobotIndexByName($routeParams.showRobot); + if (index >= 0) { + $scope.showRobot($scope.robots[index]); + } + } }); }; @@ -2004,8 +2037,17 @@ quayApp.directive('entitySearch', function () { $scope.lazyLoad = function() { if (!$scope.namespace || !$scope.lazyLoading) { return; } + // Determine whether we can admin this namespace. $scope.isAdmin = UserService.isNamespaceAdmin($scope.namespace); + // If the scope is an organization and we are not part of it, then nothing more we can do. + if (!$scope.isAdmin && $scope.isOrganization && !UserService.getOrganization($scope.namespace)) { + $scope.teams = null; + $scope.robots = null; + $scope.lazyLoading = false; + return; + } + if ($scope.isOrganization && $scope.includeTeams) { ApiService.getOrganization(null, {'orgname': $scope.namespace}).then(function(resp) { $scope.teams = resp.teams; @@ -3098,8 +3140,14 @@ quayApp.run(['$location', '$rootScope', 'Restangular', 'UserService', 'PlanServi var tabName = e.target.getAttribute('data-target').substr(1); $rootScope.$apply(function() { var isDefaultTab = $('a[data-toggle="tab"]')[0] == e.target; - var data = isDefaultTab ? {} : {'tab': tabName}; - $location.search(data); + var newSearch = $.extend($location.search(), {}); + if (isDefaultTab) { + delete newSearch['tab']; + } else { + newSearch['tab'] = tabName; + } + + $location.search(newSearch); }); e.preventDefault();