diff --git a/docs/sources/http_api/user.md b/docs/sources/http_api/user.md index 134c1842851..b9047187b2d 100644 --- a/docs/sources/http_api/user.md +++ b/docs/sources/http_api/user.md @@ -363,6 +363,39 @@ Content-Type: application/json ] ``` +## Teams that the actual User is member of + +`GET /api/user/teams` + +Return a list of all teams that the current user is member of. + +**Example Request**: + +```http +GET /api/user/teams HTTP/1.1 +Accept: application/json +Content-Type: application/json +Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk +``` + +**Example Response**: + +```http +HTTP/1.1 200 +Content-Type: application/json + +[ + { + "id": 1, + "orgId": 1, + "name": "MyTestTeam", + "email": "", + "avatarUrl": "\/avatar\/3f49c15916554246daa714b9bd0ee398", + "memberCount": 1 + } +] +``` + ## Star a dashboard `POST /api/user/stars/dashboard/:dashboardId` diff --git a/pkg/api/api.go b/pkg/api/api.go index 84425fdae3d..906481bbb8a 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -120,6 +120,7 @@ func (hs *HTTPServer) registerRoutes() { userRoute.Put("/", bind(m.UpdateUserCommand{}), Wrap(UpdateSignedInUser)) userRoute.Post("/using/:id", Wrap(UserSetUsingOrg)) userRoute.Get("/orgs", Wrap(GetSignedInUserOrgList)) + userRoute.Get("/teams", Wrap(GetSignedInUserTeamList)) userRoute.Post("/stars/dashboard/:id", Wrap(StarDashboard)) userRoute.Delete("/stars/dashboard/:id", Wrap(UnstarDashboard)) diff --git a/pkg/api/user.go b/pkg/api/user.go index 725c623575f..4b916202e65 100644 --- a/pkg/api/user.go +++ b/pkg/api/user.go @@ -111,6 +111,21 @@ func GetSignedInUserOrgList(c *m.ReqContext) Response { return getUserOrgList(c.UserId) } +// GET /api/user/teams +func GetSignedInUserTeamList(c *m.ReqContext) Response { + query := m.GetTeamsByUserQuery{OrgId: c.OrgId, UserId: c.UserId} + + if err := bus.Dispatch(&query); err != nil { + return Error(500, "Failed to get user teams", err) + } + + for _, team := range query.Result { + team.AvatarUrl = dtos.GetGravatarUrlWithDefault(team.Email, team.Name) + } + + return JSON(200, query.Result) +} + // GET /api/user/:id/orgs func GetUserOrgList(c *m.ReqContext) Response { return getUserOrgList(c.ParamsInt64(":id")) diff --git a/public/app/features/org/partials/profile.html b/public/app/features/org/partials/profile.html index 66e41fbb4b4..7858e00c683 100644 --- a/public/app/features/org/partials/profile.html +++ b/public/app/features/org/partials/profile.html @@ -3,53 +3,74 @@

User Profile

-
+ -
- Name - -
-
- Email - +
+ Name + +
+
+ Email +
-
- Username +
+ Username
-
- -
- +
+ +
+ - + -

Organizations

+

Teams

+
+ + + + + + + + + + + + + + + + + +
NameEmailMembers
{{team.name}}{{team.email}}{{team.memberCount}}
+
+ +

Organizations

- - - - - - - - - - - - - - - -
NameRole
{{org.name}}{{org.role}} - - Current - - - Select - -
-
- + + + + + + + + + + + + + + + +
NameRole
{{org.name}}{{org.role}} + + Current + + + Select + +
+
diff --git a/public/app/features/org/profile_ctrl.ts b/public/app/features/org/profile_ctrl.ts index 5c62a7a5fdb..40ee4d908a1 100644 --- a/public/app/features/org/profile_ctrl.ts +++ b/public/app/features/org/profile_ctrl.ts @@ -4,8 +4,10 @@ import { coreModule } from 'app/core/core'; export class ProfileCtrl { user: any; old_theme: any; + teams: any = []; orgs: any = []; userForm: any; + showTeamsList = false; showOrgsList = false; readonlyLoginFields = config.disableLoginForm; navModel: any; @@ -13,6 +15,7 @@ export class ProfileCtrl { /** @ngInject **/ constructor(private backendSrv, private contextSrv, private $location, navModelSrv) { this.getUser(); + this.getUserTeams(); this.getUserOrgs(); this.navModel = navModelSrv.getNav('profile', 'profile-settings', 0); } @@ -24,6 +27,13 @@ export class ProfileCtrl { }); } + getUserTeams() { + this.backendSrv.get('/api/user/teams').then(teams => { + this.teams = teams; + this.showTeamsList = this.teams.length > 0; + }); + } + getUserOrgs() { this.backendSrv.get('/api/user/orgs').then(orgs => { this.orgs = orgs;