From 1bb5a57036d435299bc287bb4e93eab92b77f7bd Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Fri, 27 Jul 2018 13:45:16 +0200 Subject: [PATCH 1/6] frontend part with mock-team-list --- public/app/features/org/partials/profile.html | 99 +++++++++++-------- public/app/features/org/profile_ctrl.ts | 15 +++ 2 files changed, 73 insertions(+), 41 deletions(-) diff --git a/public/app/features/org/partials/profile.html b/public/app/features/org/partials/profile.html index 66e41fbb4b4..96540911290 100644 --- a/public/app/features/org/partials/profile.html +++ b/public/app/features/org/partials/profile.html @@ -3,53 +3,70 @@

User Profile

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

Organizations

+

Teams

+
+ + + + + + + + + + + + + +
NameEmail
{{team.name}}{{team.email}}
+
+ +

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..1ac950699be 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,18 @@ export class ProfileCtrl { }); } + getUserTeams() { + console.log(this.backendSrv.get('/api/teams')); + this.backendSrv.get('/api/user').then(teams => { + this.user.teams = [ + { name: 'Backend', email: 'backend@grafana.com', members: 2 }, + { name: 'Frontend', email: 'frontend@grafana.com', members: 2 }, + { name: 'Ops', email: 'ops@grafana.com', members: 2 }, + ]; + this.showTeamsList = this.user.teams.length > 1; + }); + } + getUserOrgs() { this.backendSrv.get('/api/user/orgs').then(orgs => { this.orgs = orgs; From b0ddc15e1ab7f28c6924e3f8448eea2561fcdb45 Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Wed, 8 Aug 2018 09:23:36 +0200 Subject: [PATCH 2/6] team list for profile page + mock teams --- public/app/features/org/partials/profile.html | 4 ++-- public/app/features/org/profile_ctrl.ts | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/public/app/features/org/partials/profile.html b/public/app/features/org/partials/profile.html index 96540911290..5cbb21f488a 100644 --- a/public/app/features/org/partials/profile.html +++ b/public/app/features/org/partials/profile.html @@ -32,13 +32,13 @@ Name - Email + Members {{team.name}} - {{team.email}} + {{team.members}} diff --git a/public/app/features/org/profile_ctrl.ts b/public/app/features/org/profile_ctrl.ts index 1ac950699be..361dfa9e52f 100644 --- a/public/app/features/org/profile_ctrl.ts +++ b/public/app/features/org/profile_ctrl.ts @@ -28,12 +28,11 @@ export class ProfileCtrl { } getUserTeams() { - console.log(this.backendSrv.get('/api/teams')); this.backendSrv.get('/api/user').then(teams => { this.user.teams = [ - { name: 'Backend', email: 'backend@grafana.com', members: 2 }, - { name: 'Frontend', email: 'frontend@grafana.com', members: 2 }, - { name: 'Ops', email: 'ops@grafana.com', members: 2 }, + { name: 'Backend', email: 'backend@grafana.com', members: 5 }, + { name: 'Frontend', email: 'frontend@grafana.com', members: 4 }, + { name: 'Ops', email: 'ops@grafana.com', members: 6 }, ]; this.showTeamsList = this.user.teams.length > 1; }); From beddfdd86b33a965ba30df121c76ce720e83a809 Mon Sep 17 00:00:00 2001 From: Marcus Efraimsson Date: Wed, 8 Aug 2018 10:26:05 +0200 Subject: [PATCH 3/6] add api route for retrieving teams of signed in user --- docs/sources/http_api/user.md | 33 +++++++++++++++++++++++++++++++++ pkg/api/api.go | 1 + pkg/api/user.go | 15 +++++++++++++++ 3 files changed, 49 insertions(+) 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")) From ca06893e691b07f938788af65e8d8847e05be9fc Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Wed, 8 Aug 2018 10:50:27 +0200 Subject: [PATCH 4/6] removed mock-teams, now gets teams from backend --- public/app/features/org/partials/profile.html | 4 +--- public/app/features/org/profile_ctrl.ts | 10 +++------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/public/app/features/org/partials/profile.html b/public/app/features/org/partials/profile.html index 5cbb21f488a..790872d9789 100644 --- a/public/app/features/org/partials/profile.html +++ b/public/app/features/org/partials/profile.html @@ -32,13 +32,11 @@ Name - Members - + {{team.name}} - {{team.members}} diff --git a/public/app/features/org/profile_ctrl.ts b/public/app/features/org/profile_ctrl.ts index 361dfa9e52f..6cfcdc2e64c 100644 --- a/public/app/features/org/profile_ctrl.ts +++ b/public/app/features/org/profile_ctrl.ts @@ -28,13 +28,9 @@ export class ProfileCtrl { } getUserTeams() { - this.backendSrv.get('/api/user').then(teams => { - this.user.teams = [ - { name: 'Backend', email: 'backend@grafana.com', members: 5 }, - { name: 'Frontend', email: 'frontend@grafana.com', members: 4 }, - { name: 'Ops', email: 'ops@grafana.com', members: 6 }, - ]; - this.showTeamsList = this.user.teams.length > 1; + this.backendSrv.get('/api/user/teams').then(teams => { + this.teams = teams; + this.showTeamsList = this.teams.length > 1; }); } From a94406ac53f58e4617d30f7cd18d11613ed2476c Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Wed, 8 Aug 2018 11:22:47 +0200 Subject: [PATCH 5/6] added more info about the teams --- public/app/features/org/partials/profile.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/public/app/features/org/partials/profile.html b/public/app/features/org/partials/profile.html index 790872d9789..b204c223138 100644 --- a/public/app/features/org/partials/profile.html +++ b/public/app/features/org/partials/profile.html @@ -31,12 +31,18 @@ + + + + + +
NameEmailMembers
{{team.name}}{{team.email}}{{team.memberCount}}
From 535bab1baaf45288e863fb04e89974f37b359421 Mon Sep 17 00:00:00 2001 From: Patrick O'Carroll Date: Mon, 13 Aug 2018 15:07:29 +0200 Subject: [PATCH 6/6] now hides team header when no teams + fix for list hidden when only one team --- public/app/features/org/partials/profile.html | 2 +- public/app/features/org/profile_ctrl.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/app/features/org/partials/profile.html b/public/app/features/org/partials/profile.html index b204c223138..7858e00c683 100644 --- a/public/app/features/org/partials/profile.html +++ b/public/app/features/org/partials/profile.html @@ -26,7 +26,7 @@ -

Teams

+

Teams

diff --git a/public/app/features/org/profile_ctrl.ts b/public/app/features/org/profile_ctrl.ts index 6cfcdc2e64c..40ee4d908a1 100644 --- a/public/app/features/org/profile_ctrl.ts +++ b/public/app/features/org/profile_ctrl.ts @@ -30,7 +30,7 @@ export class ProfileCtrl { getUserTeams() { this.backendSrv.get('/api/user/teams').then(teams => { this.teams = teams; - this.showTeamsList = this.teams.length > 1; + this.showTeamsList = this.teams.length > 0; }); }