Просмотр исходного кода

Merge pull request #12838 from grafana/12476-show-teams-on-profile

show teams on profile
Marcus Efraimsson 7 лет назад
Родитель
Сommit
d110343e53

+ 33 - 0
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
 ## Star a dashboard
 
 
 `POST /api/user/stars/dashboard/:dashboardId`
 `POST /api/user/stars/dashboard/:dashboardId`

+ 1 - 0
pkg/api/api.go

@@ -120,6 +120,7 @@ func (hs *HTTPServer) registerRoutes() {
 			userRoute.Put("/", bind(m.UpdateUserCommand{}), Wrap(UpdateSignedInUser))
 			userRoute.Put("/", bind(m.UpdateUserCommand{}), Wrap(UpdateSignedInUser))
 			userRoute.Post("/using/:id", Wrap(UserSetUsingOrg))
 			userRoute.Post("/using/:id", Wrap(UserSetUsingOrg))
 			userRoute.Get("/orgs", Wrap(GetSignedInUserOrgList))
 			userRoute.Get("/orgs", Wrap(GetSignedInUserOrgList))
+			userRoute.Get("/teams", Wrap(GetSignedInUserTeamList))
 
 
 			userRoute.Post("/stars/dashboard/:id", Wrap(StarDashboard))
 			userRoute.Post("/stars/dashboard/:id", Wrap(StarDashboard))
 			userRoute.Delete("/stars/dashboard/:id", Wrap(UnstarDashboard))
 			userRoute.Delete("/stars/dashboard/:id", Wrap(UnstarDashboard))

+ 15 - 0
pkg/api/user.go

@@ -111,6 +111,21 @@ func GetSignedInUserOrgList(c *m.ReqContext) Response {
 	return getUserOrgList(c.UserId)
 	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
 // GET /api/user/:id/orgs
 func GetUserOrgList(c *m.ReqContext) Response {
 func GetUserOrgList(c *m.ReqContext) Response {
 	return getUserOrgList(c.ParamsInt64(":id"))
 	return getUserOrgList(c.ParamsInt64(":id"))

+ 62 - 41
public/app/features/org/partials/profile.html

@@ -3,53 +3,74 @@
 <div class="page-container page-body">
 <div class="page-container page-body">
   <h3 class="page-sub-heading">User Profile</h3>
   <h3 class="page-sub-heading">User Profile</h3>
 
 
-	<form name="ctrl.userForm" class="gf-form-group">
+  <form name="ctrl.userForm" class="gf-form-group">
 
 
-		<div class="gf-form max-width-30">
-			<span class="gf-form-label width-8">Name</span>
-			<input class="gf-form-input max-width-22" type="text" required ng-model="ctrl.user.name" >
-		</div>
-		<div class="gf-form max-width-30">
-			<span class="gf-form-label width-8">Email</span>
-			<input class="gf-form-input max-width-22" type="email" ng-readonly="ctrl.readonlyLoginFields" required ng-model="ctrl.user.email">
+    <div class="gf-form max-width-30">
+      <span class="gf-form-label width-8">Name</span>
+      <input class="gf-form-input max-width-22" type="text" required ng-model="ctrl.user.name">
+    </div>
+    <div class="gf-form max-width-30">
+      <span class="gf-form-label width-8">Email</span>
+      <input class="gf-form-input max-width-22" type="email" ng-readonly="ctrl.readonlyLoginFields" required ng-model="ctrl.user.email">
       <i ng-if="ctrl.readonlyLoginFields" class="fa fa-lock gf-form-icon--right-absolute" bs-tooltip="'Login Details Locked - managed in another system.'"></i>
       <i ng-if="ctrl.readonlyLoginFields" class="fa fa-lock gf-form-icon--right-absolute" bs-tooltip="'Login Details Locked - managed in another system.'"></i>
     </div>
     </div>
-		<div class="gf-form max-width-30">
-			<span class="gf-form-label width-8">Username</span>
+    <div class="gf-form max-width-30">
+      <span class="gf-form-label width-8">Username</span>
       <input class="gf-form-input max-width-22" type="text" ng-readonly="ctrl.readonlyLoginFields" required ng-model="ctrl.user.login">
       <input class="gf-form-input max-width-22" type="text" ng-readonly="ctrl.readonlyLoginFields" required ng-model="ctrl.user.login">
       <i ng-if="ctrl.readonlyLoginFields" class="fa fa-lock gf-form-icon--right-absolute" bs-tooltip="'Login Details Locked - managed in another system.'"></i>
       <i ng-if="ctrl.readonlyLoginFields" class="fa fa-lock gf-form-icon--right-absolute" bs-tooltip="'Login Details Locked - managed in another system.'"></i>
     </div>
     </div>
-		<div class="gf-form-button-row">
-			<button type="submit" class="btn btn-success" ng-click="ctrl.update()">Save</button>
-		</div>
-	</form>
+    <div class="gf-form-button-row">
+      <button type="submit" class="btn btn-success" ng-click="ctrl.update()">Save</button>
+    </div>
+  </form>
 
 
-	<prefs-control mode="user"></prefs-control>
+  <prefs-control mode="user"></prefs-control>
 
 
-	<h3 class="page-heading" ng-show="ctrl.showOrgsList">Organizations</h3>
-  <div class="gf-form-group" ng-show="ctrl.showOrgsList">
-		<table class="filter-table form-inline">
-			<thead>
-				<tr>
-					<th>Name</th>
-					<th>Role</th>
-					<th></th>
-				</tr>
-			</thead>
-			<tbody>
-				<tr ng-repeat="org in ctrl.orgs">
-					<td>{{org.name}}</td>
-					<td>{{org.role}}</td>
-					<td class="text-right">
-						<span class="btn btn-primary btn-mini" ng-show="org.orgId === contextSrv.user.orgId">
-							Current
-						</span>
-						<a ng-click="ctrl.setUsingOrg(org)" class="btn btn-inverse btn-mini" ng-show="org.orgId !== contextSrv.user.orgId">
-							Select
-						</a>
-					</td>
-				</tr>
-			</tbody>
-		</table>
-	</div>
+  <h3 class="page-heading" ng-show="ctrl.showTeamsList">Teams</h3>
+  <div class="gf-form-group" ng-show="ctrl.showTeamsList">
+    <table class="filter-table form-inline">
+      <thead>
+        <tr>
+          <th></th>
+          <th>Name</th>
+          <th>Email</th>
+          <th>Members</th>
+        </tr>
+      </thead>
+      <tbody>
+        <tr ng-repeat="team in ctrl.teams">
+          <td class="width-4 text-center"><img class="filter-table__avatar" src={{team.avatarUrl}}></td>
+          <td>{{team.name}}</td>
+          <td>{{team.email}}</td>
+          <td>{{team.memberCount}}</td>
+        </tr>
+      </tbody>
+    </table>
+  </div>
 
 
+  <h3 class="page-heading" ng-show="ctrl.showOrgsList">Organizations</h3>
+  <div class="gf-form-group" ng-show="ctrl.showOrgsList">
+    <table class="filter-table form-inline">
+      <thead>
+        <tr>
+          <th>Name</th>
+          <th>Role</th>
+          <th></th>
+        </tr>
+      </thead>
+      <tbody>
+        <tr ng-repeat="org in ctrl.orgs">
+          <td>{{org.name}}</td>
+          <td>{{org.role}}</td>
+          <td class="text-right">
+            <span class="btn btn-primary btn-mini" ng-show="org.orgId === contextSrv.user.orgId">
+              Current
+            </span>
+            <a ng-click="ctrl.setUsingOrg(org)" class="btn btn-inverse btn-mini" ng-show="org.orgId !== contextSrv.user.orgId">
+              Select
+            </a>
+          </td>
+        </tr>
+      </tbody>
+    </table>
+  </div>

+ 10 - 0
public/app/features/org/profile_ctrl.ts

@@ -4,8 +4,10 @@ import { coreModule } from 'app/core/core';
 export class ProfileCtrl {
 export class ProfileCtrl {
   user: any;
   user: any;
   old_theme: any;
   old_theme: any;
+  teams: any = [];
   orgs: any = [];
   orgs: any = [];
   userForm: any;
   userForm: any;
+  showTeamsList = false;
   showOrgsList = false;
   showOrgsList = false;
   readonlyLoginFields = config.disableLoginForm;
   readonlyLoginFields = config.disableLoginForm;
   navModel: any;
   navModel: any;
@@ -13,6 +15,7 @@ export class ProfileCtrl {
   /** @ngInject **/
   /** @ngInject **/
   constructor(private backendSrv, private contextSrv, private $location, navModelSrv) {
   constructor(private backendSrv, private contextSrv, private $location, navModelSrv) {
     this.getUser();
     this.getUser();
+    this.getUserTeams();
     this.getUserOrgs();
     this.getUserOrgs();
     this.navModel = navModelSrv.getNav('profile', 'profile-settings', 0);
     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() {
   getUserOrgs() {
     this.backendSrv.get('/api/user/orgs').then(orgs => {
     this.backendSrv.get('/api/user/orgs').then(orgs => {
       this.orgs = orgs;
       this.orgs = orgs;