diff --git a/data/model/team.py b/data/model/team.py index ce1f782b4..1fffa5dbf 100644 --- a/data/model/team.py +++ b/data/model/team.py @@ -1,7 +1,9 @@ -from data.database import Team, TeamMember, TeamRole, User, TeamMemberInvite +from data.database import Team, TeamMember, TeamRole, User, TeamMemberInvite, RepositoryPermission from data.model import (DataModelException, InvalidTeamException, UserAlreadyInTeam, InvalidTeamMemberException, user, _basequery) from util.validation import validate_username +from peewee import fn, JOIN_LEFT_OUTER +from util.morecollections import AttrDict def create_team(name, org_obj, team_role_name, description=''): @@ -186,7 +188,32 @@ def get_matching_teams(team_prefix, organization): def get_teams_within_org(organization): - return Team.select().where(Team.organization == organization) + """ Returns a AttrDict of team info (id, name, description), its role under the org, + the number of repositories on which it has permission, and the number of members. + """ + query = (Team.select(Team.id, Team.name, Team.description, TeamRole.name, + fn.Count(RepositoryPermission.id), fn.Count(TeamMember.id)) + .where(Team.organization == organization) + .join(TeamRole) + .switch(Team) + .join(RepositoryPermission, JOIN_LEFT_OUTER) + .switch(Team) + .join(TeamMember, JOIN_LEFT_OUTER) + .group_by(Team.id) + .tuples()) + + def _team_view(team_tuple): + return AttrDict({ + 'id': team_tuple[0], + 'name': team_tuple[1], + 'description': team_tuple[2], + 'role_name': team_tuple[3], + + 'repo_count': team_tuple[4], + 'member_count': team_tuple[5], + }) + + return [_team_view(team_tuple) for team_tuple in query] def get_user_teams_within_org(username, organization): diff --git a/endpoints/api/organization.py b/endpoints/api/organization.py index 5629ce879..685094d87 100644 --- a/endpoints/api/organization.py +++ b/endpoints/api/organization.py @@ -8,13 +8,12 @@ import features from app import billing as stripe, avatar from endpoints.api import (resource, nickname, ApiResource, validate_json_request, request_error, - related_user_resource, internal_only, require_user_admin, log_action, + related_user_resource, internal_only, require_user_admin, log_action, show_if, path_param, require_scope) from endpoints.exception import Unauthorized, NotFound -from endpoints.api.team import team_view from endpoints.api.user import User, PrivateRepositories from auth.permissions import (AdministerOrganizationPermission, OrganizationMemberPermission, - CreateRepositoryPermission) + CreateRepositoryPermission, ViewTeamPermission) from auth.auth_context import get_authenticated_user from auth import scopes from data import model @@ -24,6 +23,18 @@ from data.billing import get_plan logger = logging.getLogger(__name__) +def team_view(orgname, team): + return { + 'name': team.name, + 'description': team.description, + 'role': team.role_name, + 'avatar': avatar.get_data_for_team(team), + 'can_view': ViewTeamPermission(orgname, team.name).can(), + + 'repo_count': team.repo_count, + 'member_count': team.member_count, + } + def org_view(o, teams): is_admin = AdministerOrganizationPermission(o.username).can() diff --git a/static/css/directives/ui/create-entity-dialog.css b/static/css/directives/ui/create-entity-dialog.css index f7eb3fc9f..59b598b97 100644 --- a/static/css/directives/ui/create-entity-dialog.css +++ b/static/css/directives/ui/create-entity-dialog.css @@ -15,39 +15,3 @@ margin-left: 4px; margin-right: 4px; } - -.create-entity-dialog-element label { - margin-top: 4px; -} - -.create-entity-dialog-element .co-table { - margin-top: 20px; -} - -.create-entity-dialog-element .fa-hdd-o { - margin-right: 4px; - vertical-align: middle; -} - -.create-entity-dialog-element .co-filter-box { - display: block; - float: right; - margin-bottom: 20px; -} - -.create-entity-dialog-element .co-filter-box .filter-message { - left: -180px; - top: 4px; -} - -.create-entity-dialog-element .co-filter-box input { - width: 100%; - padding-top: 2px; - padding-bottom: 2px; - height: 28px; -} - -.create-entity-dialog-element label .avatar { - vertical-align: text-bottom; - margin-left: 4px; -} \ No newline at end of file diff --git a/static/css/directives/ui/teams-manager.css b/static/css/directives/ui/teams-manager.css index 5d6f74a04..a93a844ac 100644 --- a/static/css/directives/ui/teams-manager.css +++ b/static/css/directives/ui/teams-manager.css @@ -1,5 +1,19 @@ -.teams-manager .popup-input-button { +.teams-manager .co-filter-box { + display: block; float: right; + margin-bottom: 20px; +} + +.teams-manager.co-filter-box .filter-message { + left: -180px; + top: 4px; +} + +.teams-manager .co-filter-box input { + width: 100%; + padding-top: 2px; + padding-bottom: 2px; + height: 28px; } .teams-manager .manager-header { @@ -20,6 +34,10 @@ color: #ccc; } +.teams-manager .co-table .avatar { + margin-right: 6px; +} + .teams-manager .cor-confirm-dialog .entity-reference .avatar { margin-left: 4px; margin-right: 0px; @@ -36,14 +54,20 @@ } @media (max-width: 767px) { - .teams-manager .control-col { - padding-left: 55px; - padding-bottom: 10px; + .teams-manager .co-filter-box { + display: block; + float: none; } } -.teams-manager .header-col .info-icon { +.teams-manager .info-icon { + margin-left: 4px; +} + +.teams-manager .popover-content { + color: black; font-size: 16px; + text-transform: none; } .teams-manager .header-col .header-text { diff --git a/static/css/quay.css b/static/css/quay.css index fa9fb3d91..0088fda4f 100644 --- a/static/css/quay.css +++ b/static/css/quay.css @@ -634,13 +634,6 @@ i.toggle-icon:hover { padding: 6px; } -.info-icon { - display: inline-block; - float: right; - vertical-align: middle; - font-size: 20px; -} - .accordion-toggle { cursor: pointer; text-decoration: none !important; diff --git a/static/directives/add-repo-permissions.html b/static/directives/add-repo-permissions.html index 6257915ab..972763066 100644 --- a/static/directives/add-repo-permissions.html +++ b/static/directives/add-repo-permissions.html @@ -1,4 +1,4 @@ -