- Add support for orgs in the entity search and the notification system
- Fix the titles/names of the different notification types - Fix the styling of the options buttons on the notifications
This commit is contained in:
parent
1ffbc77106
commit
54ee94754e
6 changed files with 55 additions and 13 deletions
|
@ -2,9 +2,11 @@ from endpoints.api import (ApiResource, parse_args, query_param, truthy_bool, ni
|
|||
require_scope)
|
||||
from data import model
|
||||
from auth.permissions import (OrganizationMemberPermission, ViewTeamPermission,
|
||||
ReadRepositoryPermission, UserAdminPermission)
|
||||
ReadRepositoryPermission, UserAdminPermission,
|
||||
AdministerOrganizationPermission)
|
||||
from auth.auth_context import get_authenticated_user
|
||||
from auth import scopes
|
||||
from util.gravatar import compute_hash
|
||||
|
||||
|
||||
@resource('/v1/entities/<prefix>')
|
||||
|
@ -14,10 +16,12 @@ class EntitySearch(ApiResource):
|
|||
@query_param('namespace', 'Namespace to use when querying for org entities.', type=str,
|
||||
default='')
|
||||
@query_param('includeTeams', 'Whether to include team names.', type=truthy_bool, default=False)
|
||||
@query_param('includeOrgs', 'Whether to include orgs names.', type=truthy_bool, default=False)
|
||||
@nickname('getMatchingEntities')
|
||||
def get(self, args, prefix):
|
||||
""" Get a list of entities that match the specified prefix. """
|
||||
teams = []
|
||||
org_data = []
|
||||
|
||||
namespace_name = args['namespace']
|
||||
robot_namespace = None
|
||||
|
@ -34,6 +38,15 @@ class EntitySearch(ApiResource):
|
|||
if args['includeTeams']:
|
||||
teams = model.get_matching_teams(prefix, organization)
|
||||
|
||||
if args['includeOrgs'] and AdministerOrganizationPermission(namespace_name) \
|
||||
and namespace_name.startswith(prefix):
|
||||
org_data = [{
|
||||
'name': namespace_name,
|
||||
'kind': 'org',
|
||||
'is_org_member': True,
|
||||
'gravatar': compute_hash(organization.email),
|
||||
}]
|
||||
|
||||
except model.InvalidOrganizationException:
|
||||
# namespace name was a user
|
||||
user = get_authenticated_user()
|
||||
|
@ -69,7 +82,7 @@ class EntitySearch(ApiResource):
|
|||
user_data = [user_view(user) for user in users]
|
||||
|
||||
return {
|
||||
'results': team_data + user_data
|
||||
'results': team_data + user_data + org_data
|
||||
}
|
||||
|
||||
|
||||
|
@ -113,4 +126,4 @@ class FindRepositories(ApiResource):
|
|||
'repositories': [repo_view(repo) for repo in matching
|
||||
if (repo.visibility.name == 'public' or
|
||||
ReadRepositoryPermission(repo.namespace, repo.name).can())]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,17 @@ class QuayNotificationMethod(NotificationMethod):
|
|||
# Just to be safe.
|
||||
return True
|
||||
|
||||
target_users.append(target)
|
||||
elif target_info['kind'] == 'org':
|
||||
target = model.get_organization(target_info['name'])
|
||||
if not target:
|
||||
# Just to be safe.
|
||||
return True
|
||||
|
||||
# Only repositories under the organization can cause notifications to that org.
|
||||
if target_info['name'] != repository.namespace:
|
||||
return False
|
||||
|
||||
target_users.append(target)
|
||||
elif target_info['kind'] == 'team':
|
||||
# Lookup the team.
|
||||
|
|
|
@ -4469,11 +4469,11 @@ i.quay-icon {
|
|||
width: 50px;
|
||||
}
|
||||
|
||||
.external-notification-view-element .side-controls {
|
||||
opacity: 0;
|
||||
transition: opacity 300ms ease-in-out;
|
||||
.external-notification-view-element .side-controls button {
|
||||
border: 1px solid transparent;
|
||||
transition: all 300ms ease-in-out;
|
||||
}
|
||||
|
||||
.external-notification-view-element:hover .side-controls {
|
||||
opacity: 1;
|
||||
.external-notification-view-element:hover .side-controls button {
|
||||
border: 1px solid #eee;
|
||||
}
|
|
@ -66,7 +66,7 @@
|
|||
placeholder="''"
|
||||
current-entity="currentConfig[field.name]"
|
||||
ng-model="currentConfig[field.name]"
|
||||
allowed-entities="['user', 'team']"
|
||||
allowed-entities="['user', 'team', 'org']"
|
||||
ng-switch-when="entity">
|
||||
</div>
|
||||
</td>
|
||||
|
@ -89,7 +89,7 @@
|
|||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary"
|
||||
ng-disabled="createForm.$invalid || !currentMethod || !currentEvent || creating">
|
||||
ng-disabled="createForm.$invalid || !currentMethod.id || !currentEvent.id || creating">
|
||||
Create Notification
|
||||
</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal" ng-disabled="creating">Cancel</button>
|
||||
|
|
|
@ -6,7 +6,14 @@
|
|||
<span ng-if="getIsAdmin(namespace)"><a href="/organization/{{ namespace }}/teams/{{ entity.name }}">{{entity.name}}</a></span>
|
||||
</span>
|
||||
</span>
|
||||
<span ng-if="entity.kind != 'team'">
|
||||
<span ng-if="entity.kind == 'org'">
|
||||
<img src="//www.gravatar.com/avatar/{{ entity.gravatar }}?s=16&d=identicon">
|
||||
<span class="entity-name">
|
||||
<span ng-if="!getIsAdmin(entity.name)">{{entity.name}}</span>
|
||||
<span ng-if="getIsAdmin(entity.name)"><a href="/organization/{{ entity.name }}">{{entity.name}}</a></span>
|
||||
</span>
|
||||
</span>
|
||||
<span ng-if="entity.kind != 'team' && entity.kind != 'org'">
|
||||
<i class="fa fa-user" ng-show="!entity.is_robot" data-title="User" bs-tooltip="tooltip.title" data-container="body"></i>
|
||||
<i class="fa fa-wrench" ng-show="entity.is_robot" data-title="Robot Account" bs-tooltip="tooltip.title" data-container="body"></i>
|
||||
<span class="entity-name" ng-if="entity.is_robot">
|
||||
|
|
|
@ -1015,7 +1015,7 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
},
|
||||
{
|
||||
'id': 'email',
|
||||
'title': 'E-mail notification',
|
||||
'title': 'E-mail',
|
||||
'icon': 'fa-envelope',
|
||||
'fields': [
|
||||
{
|
||||
|
@ -1027,7 +1027,7 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
},
|
||||
{
|
||||
'id': 'webhook',
|
||||
'title': 'Webhook invoke',
|
||||
'title': 'Webhook POST',
|
||||
'icon': 'fa-link',
|
||||
'fields': [
|
||||
{
|
||||
|
@ -3304,6 +3304,7 @@ quayApp.directive('entitySearch', function () {
|
|||
|
||||
$scope.includeTeams = true;
|
||||
$scope.includeRobots = true;
|
||||
$scope.includeOrgs = false;
|
||||
|
||||
$scope.currentEntityInternal = $scope.currentEntity;
|
||||
|
||||
|
@ -3436,6 +3437,9 @@ quayApp.directive('entitySearch', function () {
|
|||
if ($scope.isOrganization && isSupported('team')) {
|
||||
url += '&includeTeams=true'
|
||||
}
|
||||
if (isSupported('org')) {
|
||||
url += '&includeOrgs=true'
|
||||
}
|
||||
return url;
|
||||
},
|
||||
filter: function(data) {
|
||||
|
@ -3448,6 +3452,8 @@ quayApp.directive('entitySearch', function () {
|
|||
found = entity.is_robot ? 'robot' : 'user';
|
||||
} else if (entity.kind == 'team') {
|
||||
found = 'team';
|
||||
} else if (entity.kind == 'org') {
|
||||
found = 'org';
|
||||
}
|
||||
|
||||
if (!isSupported(found)) {
|
||||
|
@ -3491,6 +3497,7 @@ quayApp.directive('entitySearch', function () {
|
|||
var classes = [];
|
||||
|
||||
if (isSupported('user')) { classes.push('users'); }
|
||||
if (isSupported('org')) { classes.push('organizations'); }
|
||||
if ($scope.isAdmin && isSupported('robot')) { classes.push('robot accounts'); }
|
||||
if ($scope.isOrganization && isSupported('team')) { classes.push('teams'); }
|
||||
|
||||
|
@ -3524,7 +3531,11 @@ quayApp.directive('entitySearch', function () {
|
|||
template += '<i class="fa fa-wrench fa-lg"></i>';
|
||||
} else if (datum.entity.kind == 'team') {
|
||||
template += '<i class="fa fa-group fa-lg"></i>';
|
||||
} else if (datum.entity.kind == 'org') {
|
||||
template += '<i class="fa"><img src="//www.gravatar.com/avatar/' +
|
||||
datum.entity.gravatar + '?s=16&d=identicon"></i>';
|
||||
}
|
||||
|
||||
template += '<span class="name">' + datum.value + '</span>';
|
||||
|
||||
if (datum.entity.is_org_member === false && datum.entity.kind == 'user') {
|
||||
|
|
Reference in a new issue