Browse Source

refactor: rename User Groups to Teams

Alexander Zobnin 8 years ago
parent
commit
d8612380e9
40 changed files with 385 additions and 383 deletions
  1. 10 10
      pkg/api/api.go
  2. 1 1
      pkg/api/dashboard_acl.go
  3. 8 8
      pkg/api/dashboard_acl_test.go
  4. 4 4
      pkg/api/dashboard_test.go
  5. 1 1
      pkg/api/dtos/acl.go
  6. 2 2
      pkg/api/index.go
  7. 31 31
      pkg/api/user_group.go
  8. 16 16
      pkg/api/user_group_members.go
  9. 13 13
      pkg/api/user_group_test.go
  10. 5 5
      pkg/models/dashboard_acl.go
  11. 16 16
      pkg/models/user_group.go
  12. 13 13
      pkg/models/user_group_member.go
  13. 10 10
      pkg/services/guardian/guardian.go
  14. 13 13
      pkg/services/sqlstore/dashboard_acl.go
  15. 11 11
      pkg/services/sqlstore/dashboard_acl_test.go
  16. 2 2
      pkg/services/sqlstore/migrations/dashboard_acl.go
  17. 1 1
      pkg/services/sqlstore/migrations/migrations.go
  18. 13 13
      pkg/services/sqlstore/migrations/user_group_mig.go
  19. 1 1
      pkg/services/sqlstore/org_users.go
  20. 1 1
      pkg/services/sqlstore/search_builder.go
  21. 1 1
      pkg/services/sqlstore/user.go
  22. 66 66
      pkg/services/sqlstore/user_group.go
  23. 37 37
      pkg/services/sqlstore/user_group_test.go
  24. 10 10
      public/app/core/components/user_group_picker.ts
  25. 2 2
      public/app/core/core.ts
  26. 4 4
      public/app/core/routes/routes.ts
  27. 3 3
      public/app/features/dashboard/acl/acl.html
  28. 10 10
      public/app/features/dashboard/acl/acl.ts
  29. 11 11
      public/app/features/dashboard/acl/specs/acl_specs.ts
  30. 2 0
      public/app/features/org/all.ts
  31. 9 9
      public/app/features/org/create_user_group_modal.ts
  32. 4 4
      public/app/features/org/partials/create_user_group.html
  33. 6 6
      public/app/features/org/partials/user_group_details.html
  34. 7 7
      public/app/features/org/partials/user_groups.html
  35. 6 6
      public/app/features/org/specs/user_group_details_ctrl_specs.ts
  36. 18 18
      public/app/features/org/user_group_details_ctrl.ts
  37. 12 12
      public/app/features/org/user_groups_ctrl.ts
  38. 2 2
      public/app/plugins/panel/permissionlist/module.html
  39. 2 2
      public/app/plugins/panel/permissionlist/module.ts
  40. 1 1
      public/sass/base/_icons.scss

+ 10 - 10
pkg/api/api.go

@@ -135,16 +135,16 @@ func (hs *HttpServer) registerRoutes() {
 			usersRoute.Post("/:id/using/:orgId", wrap(UpdateUserActiveOrg))
 		}, reqGrafanaAdmin)
 
-		// user group (admin permission required)
-		apiRoute.Group("/user-groups", func(userGroupsRoute RouteRegister) {
-			userGroupsRoute.Get("/:userGroupId", wrap(GetUserGroupById))
-			userGroupsRoute.Get("/search", wrap(SearchUserGroups))
-			userGroupsRoute.Post("/", quota("user-groups"), bind(m.CreateUserGroupCommand{}), wrap(CreateUserGroup))
-			userGroupsRoute.Put("/:userGroupId", bind(m.UpdateUserGroupCommand{}), wrap(UpdateUserGroup))
-			userGroupsRoute.Delete("/:userGroupId", wrap(DeleteUserGroupById))
-			userGroupsRoute.Get("/:userGroupId/members", wrap(GetUserGroupMembers))
-			userGroupsRoute.Post("/:userGroupId/members", quota("user-groups"), bind(m.AddUserGroupMemberCommand{}), wrap(AddUserGroupMember))
-			userGroupsRoute.Delete("/:userGroupId/members/:userId", wrap(RemoveUserGroupMember))
+		// team (admin permission required)
+		apiRoute.Group("/teams", func(teamsRoute RouteRegister) {
+			teamsRoute.Get("/:teamId", wrap(GetTeamById))
+			teamsRoute.Get("/search", wrap(SearchTeams))
+			teamsRoute.Post("/", quota("teams"), bind(m.CreateTeamCommand{}), wrap(CreateTeam))
+			teamsRoute.Put("/:teamId", bind(m.UpdateTeamCommand{}), wrap(UpdateTeam))
+			teamsRoute.Delete("/:teamId", wrap(DeleteTeamById))
+			teamsRoute.Get("/:teamId/members", wrap(GetTeamMembers))
+			teamsRoute.Post("/:teamId/members", quota("teams"), bind(m.AddTeamMemberCommand{}), wrap(AddTeamMember))
+			teamsRoute.Delete("/:teamId/members/:userId", wrap(RemoveTeamMember))
 		}, reqOrgAdmin)
 
 		// org information available to all users.

+ 1 - 1
pkg/api/dashboard_acl.go

@@ -43,7 +43,7 @@ func UpdateDashboardAcl(c *middleware.Context, apiCmd dtos.UpdateDashboardAclCom
 			OrgId:       c.OrgId,
 			DashboardId: dashId,
 			UserId:      item.UserId,
-			UserGroupId: item.UserGroupId,
+			TeamId: item.TeamId,
 			Role:        item.Role,
 			Permission:  item.Permission,
 			Created:     time.Now(),

+ 8 - 8
pkg/api/dashboard_acl_test.go

@@ -16,8 +16,8 @@ func TestDashboardAclApiEndpoint(t *testing.T) {
 			{Id: 1, OrgId: 1, DashboardId: 1, UserId: 2, Permission: m.PERMISSION_VIEW},
 			{Id: 2, OrgId: 1, DashboardId: 1, UserId: 3, Permission: m.PERMISSION_EDIT},
 			{Id: 3, OrgId: 1, DashboardId: 1, UserId: 4, Permission: m.PERMISSION_ADMIN},
-			{Id: 4, OrgId: 1, DashboardId: 1, UserGroupId: 1, Permission: m.PERMISSION_VIEW},
-			{Id: 5, OrgId: 1, DashboardId: 1, UserGroupId: 2, Permission: m.PERMISSION_ADMIN},
+			{Id: 4, OrgId: 1, DashboardId: 1, TeamId: 1, Permission: m.PERMISSION_VIEW},
+			{Id: 5, OrgId: 1, DashboardId: 1, TeamId: 2, Permission: m.PERMISSION_ADMIN},
 		}
 		dtoRes := transformDashboardAclsToDTOs(mockResult)
 
@@ -31,9 +31,9 @@ func TestDashboardAclApiEndpoint(t *testing.T) {
 			return nil
 		})
 
-		userGroupResp := []*m.UserGroup{}
-		bus.AddHandler("test", func(query *m.GetUserGroupsByUserQuery) error {
-			query.Result = userGroupResp
+		teamResp := []*m.Team{}
+		bus.AddHandler("test", func(query *m.GetTeamsByUserQuery) error {
+			query.Result = teamResp
 			return nil
 		})
 
@@ -81,9 +81,9 @@ func TestDashboardAclApiEndpoint(t *testing.T) {
 				})
 			})
 
-			Convey("When user is a member of a user group in the ACL with admin permission", func() {
+			Convey("When user is a member of a team in the ACL with admin permission", func() {
 				loggedInUserScenarioWithRole("When calling DELETE on", "DELETE", "/api/dashboards/id/1/acl/1", "/api/dashboards/id/:dashboardsId/acl/:aclId", m.ROLE_EDITOR, func(sc *scenarioContext) {
-					userGroupResp = append(userGroupResp, &m.UserGroup{Id: 2, OrgId: 1, Name: "UG2"})
+					teamResp = append(teamResp, &m.Team{Id: 2, OrgId: 1, Name: "UG2"})
 
 					bus.AddHandler("test3", func(cmd *m.RemoveDashboardAclCommand) error {
 						return nil
@@ -165,7 +165,7 @@ func transformDashboardAclsToDTOs(acls []*m.DashboardAclInfoDTO) []*m.DashboardA
 			DashboardId: acl.DashboardId,
 			Permission:  acl.Permission,
 			UserId:      acl.UserId,
-			UserGroupId: acl.UserGroupId,
+			TeamId: acl.TeamId,
 		}
 		dtos = append(dtos, dto)
 	}

+ 4 - 4
pkg/api/dashboard_test.go

@@ -43,8 +43,8 @@ func TestDashboardApiEndpoint(t *testing.T) {
 			return nil
 		})
 
-		bus.AddHandler("test", func(query *m.GetUserGroupsByUserQuery) error {
-			query.Result = []*m.UserGroup{}
+		bus.AddHandler("test", func(query *m.GetTeamsByUserQuery) error {
+			query.Result = []*m.Team{}
 			return nil
 		})
 
@@ -204,8 +204,8 @@ func TestDashboardApiEndpoint(t *testing.T) {
 			return nil
 		})
 
-		bus.AddHandler("test", func(query *m.GetUserGroupsByUserQuery) error {
-			query.Result = []*m.UserGroup{}
+		bus.AddHandler("test", func(query *m.GetTeamsByUserQuery) error {
+			query.Result = []*m.Team{}
 			return nil
 		})
 

+ 1 - 1
pkg/api/dtos/acl.go

@@ -10,7 +10,7 @@ type UpdateDashboardAclCommand struct {
 
 type DashboardAclUpdateItem struct {
 	UserId      int64            `json:"userId"`
-	UserGroupId int64            `json:"userGroupId"`
+	TeamId int64            `json:"teamId"`
 	Role        *m.RoleType      `json:"role,omitempty"`
 	Permission  m.PermissionType `json:"permission"`
 }

+ 2 - 2
pkg/api/index.go

@@ -231,8 +231,8 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
 					Text:        "Teams",
 					Id:          "teams",
 					Description: "Manage org groups",
-					Icon:        "gicon gicon-user-group",
-					Url:         setting.AppSubUrl + "/org/user-groups",
+					Icon:        "gicon gicon-team",
+					Url:         setting.AppSubUrl + "/org/teams",
 				},
 				{
 					Text:        "Plugins",

+ 31 - 31
pkg/api/user_group.go

@@ -7,48 +7,48 @@ import (
 	"github.com/grafana/grafana/pkg/util"
 )
 
-// POST /api/user-groups
-func CreateUserGroup(c *middleware.Context, cmd m.CreateUserGroupCommand) Response {
+// POST /api/teams
+func CreateTeam(c *middleware.Context, cmd m.CreateTeamCommand) Response {
 	cmd.OrgId = c.OrgId
 	if err := bus.Dispatch(&cmd); err != nil {
-		if err == m.ErrUserGroupNameTaken {
-			return ApiError(409, "User Group name taken", err)
+		if err == m.ErrTeamNameTaken {
+			return ApiError(409, "Team name taken", err)
 		}
-		return ApiError(500, "Failed to create User Group", err)
+		return ApiError(500, "Failed to create Team", err)
 	}
 
 	return Json(200, &util.DynMap{
-		"userGroupId": cmd.Result.Id,
-		"message":     "User Group created",
+		"teamId":  cmd.Result.Id,
+		"message": "Team created",
 	})
 }
 
-// PUT /api/user-groups/:userGroupId
-func UpdateUserGroup(c *middleware.Context, cmd m.UpdateUserGroupCommand) Response {
-	cmd.Id = c.ParamsInt64(":userGroupId")
+// PUT /api/teams/:teamId
+func UpdateTeam(c *middleware.Context, cmd m.UpdateTeamCommand) Response {
+	cmd.Id = c.ParamsInt64(":teamId")
 	if err := bus.Dispatch(&cmd); err != nil {
-		if err == m.ErrUserGroupNameTaken {
-			return ApiError(400, "User Group name taken", err)
+		if err == m.ErrTeamNameTaken {
+			return ApiError(400, "Team name taken", err)
 		}
-		return ApiError(500, "Failed to update User Group", err)
+		return ApiError(500, "Failed to update Team", err)
 	}
 
-	return ApiSuccess("User Group updated")
+	return ApiSuccess("Team updated")
 }
 
-// DELETE /api/user-groups/:userGroupId
-func DeleteUserGroupById(c *middleware.Context) Response {
-	if err := bus.Dispatch(&m.DeleteUserGroupCommand{Id: c.ParamsInt64(":userGroupId")}); err != nil {
-		if err == m.ErrUserGroupNotFound {
-			return ApiError(404, "Failed to delete User Group. ID not found", nil)
+// DELETE /api/teams/:teamId
+func DeleteTeamById(c *middleware.Context) Response {
+	if err := bus.Dispatch(&m.DeleteTeamCommand{Id: c.ParamsInt64(":teamId")}); err != nil {
+		if err == m.ErrTeamNotFound {
+			return ApiError(404, "Failed to delete Team. ID not found", nil)
 		}
-		return ApiError(500, "Failed to update User Group", err)
+		return ApiError(500, "Failed to update Team", err)
 	}
-	return ApiSuccess("User Group deleted")
+	return ApiSuccess("Team deleted")
 }
 
-// GET /api/user-groups/search
-func SearchUserGroups(c *middleware.Context) Response {
+// GET /api/teams/search
+func SearchTeams(c *middleware.Context) Response {
 	perPage := c.QueryInt("perpage")
 	if perPage <= 0 {
 		perPage = 1000
@@ -58,7 +58,7 @@ func SearchUserGroups(c *middleware.Context) Response {
 		page = 1
 	}
 
-	query := m.SearchUserGroupsQuery{
+	query := m.SearchTeamsQuery{
 		Query: c.Query("query"),
 		Name:  c.Query("name"),
 		Page:  page,
@@ -67,7 +67,7 @@ func SearchUserGroups(c *middleware.Context) Response {
 	}
 
 	if err := bus.Dispatch(&query); err != nil {
-		return ApiError(500, "Failed to search User Groups", err)
+		return ApiError(500, "Failed to search Teams", err)
 	}
 
 	query.Result.Page = page
@@ -76,16 +76,16 @@ func SearchUserGroups(c *middleware.Context) Response {
 	return Json(200, query.Result)
 }
 
-// GET /api/user-groups/:userGroupId
-func GetUserGroupById(c *middleware.Context) Response {
-	query := m.GetUserGroupByIdQuery{Id: c.ParamsInt64(":userGroupId")}
+// GET /api/teams/:teamId
+func GetTeamById(c *middleware.Context) Response {
+	query := m.GetTeamByIdQuery{Id: c.ParamsInt64(":teamId")}
 
 	if err := bus.Dispatch(&query); err != nil {
-		if err == m.ErrUserGroupNotFound {
-			return ApiError(404, "User Group not found", err)
+		if err == m.ErrTeamNotFound {
+			return ApiError(404, "Team not found", err)
 		}
 
-		return ApiError(500, "Failed to get User Group", err)
+		return ApiError(500, "Failed to get Team", err)
 	}
 
 	return Json(200, &query.Result)

+ 16 - 16
pkg/api/user_group_members.go

@@ -7,38 +7,38 @@ import (
 	"github.com/grafana/grafana/pkg/util"
 )
 
-// GET /api/user-groups/:userGroupId/members
-func GetUserGroupMembers(c *middleware.Context) Response {
-	query := m.GetUserGroupMembersQuery{UserGroupId: c.ParamsInt64(":userGroupId")}
+// GET /api/teams/:teamId/members
+func GetTeamMembers(c *middleware.Context) Response {
+	query := m.GetTeamMembersQuery{TeamId: c.ParamsInt64(":teamId")}
 
 	if err := bus.Dispatch(&query); err != nil {
-		return ApiError(500, "Failed to get User Group Members", err)
+		return ApiError(500, "Failed to get Team Members", err)
 	}
 
 	return Json(200, query.Result)
 }
 
-// POST /api/user-groups/:userGroupId/members
-func AddUserGroupMember(c *middleware.Context, cmd m.AddUserGroupMemberCommand) Response {
-	cmd.UserGroupId = c.ParamsInt64(":userGroupId")
+// POST /api/teams/:teamId/members
+func AddTeamMember(c *middleware.Context, cmd m.AddTeamMemberCommand) Response {
+	cmd.TeamId = c.ParamsInt64(":teamId")
 	cmd.OrgId = c.OrgId
 
 	if err := bus.Dispatch(&cmd); err != nil {
-		if err == m.ErrUserGroupMemberAlreadyAdded {
-			return ApiError(400, "User is already added to this user group", err)
+		if err == m.ErrTeamMemberAlreadyAdded {
+			return ApiError(400, "User is already added to this team", err)
 		}
-		return ApiError(500, "Failed to add Member to User Group", err)
+		return ApiError(500, "Failed to add Member to Team", err)
 	}
 
 	return Json(200, &util.DynMap{
-		"message": "Member added to User Group",
+		"message": "Member added to Team",
 	})
 }
 
-// DELETE /api/user-groups/:userGroupId/members/:userId
-func RemoveUserGroupMember(c *middleware.Context) Response {
-	if err := bus.Dispatch(&m.RemoveUserGroupMemberCommand{UserGroupId: c.ParamsInt64(":userGroupId"), UserId: c.ParamsInt64(":userId")}); err != nil {
-		return ApiError(500, "Failed to remove Member from User Group", err)
+// DELETE /api/teams/:teamId/members/:userId
+func RemoveTeamMember(c *middleware.Context) Response {
+	if err := bus.Dispatch(&m.RemoveTeamMemberCommand{TeamId: c.ParamsInt64(":teamId"), UserId: c.ParamsInt64(":userId")}); err != nil {
+		return ApiError(500, "Failed to remove Member from Team", err)
 	}
-	return ApiSuccess("User Group Member removed")
+	return ApiSuccess("Team Member removed")
 }

+ 13 - 13
pkg/api/user_group_test.go

@@ -10,21 +10,21 @@ import (
 	. "github.com/smartystreets/goconvey/convey"
 )
 
-func TestUserGroupApiEndpoint(t *testing.T) {
-	Convey("Given two user groups", t, func() {
-		mockResult := models.SearchUserGroupQueryResult{
-			UserGroups: []*models.UserGroup{
-				{Name: "userGroup1"},
-				{Name: "userGroup2"},
+func TestTeamApiEndpoint(t *testing.T) {
+	Convey("Given two teams", t, func() {
+		mockResult := models.SearchTeamQueryResult{
+			Teams: []*models.Team{
+				{Name: "team1"},
+				{Name: "team2"},
 			},
 			TotalCount: 2,
 		}
 
 		Convey("When searching with no parameters", func() {
-			loggedInUserScenario("When calling GET on", "/api/user-groups/search", func(sc *scenarioContext) {
+			loggedInUserScenario("When calling GET on", "/api/teams/search", func(sc *scenarioContext) {
 				var sentLimit int
 				var sendPage int
-				bus.AddHandler("test", func(query *models.SearchUserGroupsQuery) error {
+				bus.AddHandler("test", func(query *models.SearchTeamsQuery) error {
 					query.Result = mockResult
 
 					sentLimit = query.Limit
@@ -33,7 +33,7 @@ func TestUserGroupApiEndpoint(t *testing.T) {
 					return nil
 				})
 
-				sc.handlerFunc = SearchUserGroups
+				sc.handlerFunc = SearchTeams
 				sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
 
 				So(sentLimit, ShouldEqual, 1000)
@@ -43,15 +43,15 @@ func TestUserGroupApiEndpoint(t *testing.T) {
 				So(err, ShouldBeNil)
 
 				So(respJSON.Get("totalCount").MustInt(), ShouldEqual, 2)
-				So(len(respJSON.Get("userGroups").MustArray()), ShouldEqual, 2)
+				So(len(respJSON.Get("teams").MustArray()), ShouldEqual, 2)
 			})
 		})
 
 		Convey("When searching with page and perpage parameters", func() {
-			loggedInUserScenario("When calling GET on", "/api/user-groups/search", func(sc *scenarioContext) {
+			loggedInUserScenario("When calling GET on", "/api/teams/search", func(sc *scenarioContext) {
 				var sentLimit int
 				var sendPage int
-				bus.AddHandler("test", func(query *models.SearchUserGroupsQuery) error {
+				bus.AddHandler("test", func(query *models.SearchTeamsQuery) error {
 					query.Result = mockResult
 
 					sentLimit = query.Limit
@@ -60,7 +60,7 @@ func TestUserGroupApiEndpoint(t *testing.T) {
 					return nil
 				})
 
-				sc.handlerFunc = SearchUserGroups
+				sc.handlerFunc = SearchTeams
 				sc.fakeReqWithParams("GET", sc.url, map[string]string{"perpage": "10", "page": "2"}).exec()
 
 				So(sentLimit, ShouldEqual, 10)

+ 5 - 5
pkg/models/dashboard_acl.go

@@ -24,7 +24,7 @@ func (p PermissionType) String() string {
 
 // Typed errors
 var (
-	ErrDashboardAclInfoMissing           = errors.New("User id and user group id cannot both be empty for a dashboard permission.")
+	ErrDashboardAclInfoMissing           = errors.New("User id and team id cannot both be empty for a dashboard permission.")
 	ErrDashboardPermissionDashboardEmpty = errors.New("Dashboard Id must be greater than zero for a dashboard permission.")
 )
 
@@ -35,7 +35,7 @@ type DashboardAcl struct {
 	DashboardId int64
 
 	UserId      int64
-	UserGroupId int64
+	TeamId int64
 	Role        *RoleType // pointer to be nullable
 	Permission  PermissionType
 
@@ -54,8 +54,8 @@ type DashboardAclInfoDTO struct {
 	UserId         int64          `json:"userId"`
 	UserLogin      string         `json:"userLogin"`
 	UserEmail      string         `json:"userEmail"`
-	UserGroupId    int64          `json:"userGroupId"`
-	UserGroup      string         `json:"userGroup"`
+	TeamId    int64          `json:"teamId"`
+	Team      string         `json:"team"`
 	Role           *RoleType      `json:"role,omitempty"`
 	Permission     PermissionType `json:"permission"`
 	PermissionName string         `json:"permissionName"`
@@ -74,7 +74,7 @@ type SetDashboardAclCommand struct {
 	DashboardId int64
 	OrgId       int64
 	UserId      int64
-	UserGroupId int64
+	TeamId int64
 	Permission  PermissionType
 
 	Result DashboardAcl

+ 16 - 16
pkg/models/user_group.go

@@ -7,12 +7,12 @@ import (
 
 // Typed errors
 var (
-	ErrUserGroupNotFound  = errors.New("User Group not found")
-	ErrUserGroupNameTaken = errors.New("User Group name is taken")
+	ErrTeamNotFound  = errors.New("Team not found")
+	ErrTeamNameTaken = errors.New("Team name is taken")
 )
 
-// UserGroup model
-type UserGroup struct {
+// Team model
+type Team struct {
 	Id    int64  `json:"id"`
 	OrgId int64  `json:"orgId"`
 	Name  string `json:"name"`
@@ -24,45 +24,45 @@ type UserGroup struct {
 // ---------------------
 // COMMANDS
 
-type CreateUserGroupCommand struct {
+type CreateTeamCommand struct {
 	Name  string `json:"name" binding:"Required"`
 	OrgId int64  `json:"-"`
 
-	Result UserGroup `json:"-"`
+	Result Team `json:"-"`
 }
 
-type UpdateUserGroupCommand struct {
+type UpdateTeamCommand struct {
 	Id   int64
 	Name string
 }
 
-type DeleteUserGroupCommand struct {
+type DeleteTeamCommand struct {
 	Id int64
 }
 
-type GetUserGroupByIdQuery struct {
+type GetTeamByIdQuery struct {
 	Id     int64
-	Result *UserGroup
+	Result *Team
 }
 
-type GetUserGroupsByUserQuery struct {
+type GetTeamsByUserQuery struct {
 	UserId int64        `json:"userId"`
-	Result []*UserGroup `json:"userGroups"`
+	Result []*Team `json:"teams"`
 }
 
-type SearchUserGroupsQuery struct {
+type SearchTeamsQuery struct {
 	Query string
 	Name  string
 	Limit int
 	Page  int
 	OrgId int64
 
-	Result SearchUserGroupQueryResult
+	Result SearchTeamQueryResult
 }
 
-type SearchUserGroupQueryResult struct {
+type SearchTeamQueryResult struct {
 	TotalCount int64        `json:"totalCount"`
-	UserGroups []*UserGroup `json:"userGroups"`
+	Teams []*Team `json:"teams"`
 	Page       int          `json:"page"`
 	PerPage    int          `json:"perPage"`
 }

+ 13 - 13
pkg/models/user_group_member.go

@@ -7,14 +7,14 @@ import (
 
 // Typed errors
 var (
-	ErrUserGroupMemberAlreadyAdded = errors.New("User is already added to this user group")
+	ErrTeamMemberAlreadyAdded = errors.New("User is already added to this team")
 )
 
-// UserGroupMember model
-type UserGroupMember struct {
+// TeamMember model
+type TeamMember struct {
 	Id          int64
 	OrgId       int64
-	UserGroupId int64
+	TeamId int64
 	UserId      int64
 
 	Created time.Time
@@ -24,31 +24,31 @@ type UserGroupMember struct {
 // ---------------------
 // COMMANDS
 
-type AddUserGroupMemberCommand struct {
+type AddTeamMemberCommand struct {
 	UserId      int64 `json:"userId" binding:"Required"`
 	OrgId       int64 `json:"-"`
-	UserGroupId int64 `json:"-"`
+	TeamId int64 `json:"-"`
 }
 
-type RemoveUserGroupMemberCommand struct {
+type RemoveTeamMemberCommand struct {
 	UserId      int64
-	UserGroupId int64
+	TeamId int64
 }
 
 // ----------------------
 // QUERIES
 
-type GetUserGroupMembersQuery struct {
-	UserGroupId int64
-	Result      []*UserGroupMemberDTO
+type GetTeamMembersQuery struct {
+	TeamId int64
+	Result      []*TeamMemberDTO
 }
 
 // ----------------------
 // Projections and DTOs
 
-type UserGroupMemberDTO struct {
+type TeamMemberDTO struct {
 	OrgId       int64  `json:"orgId"`
-	UserGroupId int64  `json:"userGroupId"`
+	TeamId int64  `json:"teamId"`
 	UserId      int64  `json:"userId"`
 	Email       string `json:"email"`
 	Login       string `json:"login"`

+ 10 - 10
pkg/services/guardian/guardian.go

@@ -11,7 +11,7 @@ type DashboardGuardian struct {
 	dashId int64
 	orgId  int64
 	acl    []*m.DashboardAclInfoDTO
-	groups []*m.UserGroup
+	groups []*m.Team
 	log    log.Logger
 }
 
@@ -55,7 +55,7 @@ func (g *DashboardGuardian) HasPermission(permission m.PermissionType) (bool, er
 		orgRole = m.ROLE_VIEWER
 	}
 
-	userGroupAclItems := []*m.DashboardAclInfoDTO{}
+	teamAclItems := []*m.DashboardAclInfoDTO{}
 
 	for _, p := range acl {
 		// user match
@@ -71,26 +71,26 @@ func (g *DashboardGuardian) HasPermission(permission m.PermissionType) (bool, er
 		}
 
 		// remember this rule for later
-		if p.UserGroupId > 0 {
-			userGroupAclItems = append(userGroupAclItems, p)
+		if p.TeamId > 0 {
+			teamAclItems = append(teamAclItems, p)
 		}
 	}
 
 	// do we have group rules?
-	if len(userGroupAclItems) == 0 {
+	if len(teamAclItems) == 0 {
 		return false, nil
 	}
 
 	// load groups
-	userGroups, err := g.getUserGroups()
+	teams, err := g.getTeams()
 	if err != nil {
 		return false, err
 	}
 
 	// evalute group rules
 	for _, p := range acl {
-		for _, ug := range userGroups {
-			if ug.Id == p.UserGroupId && p.Permission >= permission {
+		for _, ug := range teams {
+			if ug.Id == p.TeamId && p.Permission >= permission {
 				return true, nil
 			}
 		}
@@ -114,12 +114,12 @@ func (g *DashboardGuardian) GetAcl() ([]*m.DashboardAclInfoDTO, error) {
 	return g.acl, nil
 }
 
-func (g *DashboardGuardian) getUserGroups() ([]*m.UserGroup, error) {
+func (g *DashboardGuardian) getTeams() ([]*m.Team, error) {
 	if g.groups != nil {
 		return g.groups, nil
 	}
 
-	query := m.GetUserGroupsByUserQuery{UserId: g.user.UserId}
+	query := m.GetTeamsByUserQuery{UserId: g.user.UserId}
 	err := bus.Dispatch(&query)
 
 	g.groups = query.Result

+ 13 - 13
pkg/services/sqlstore/dashboard_acl.go

@@ -24,7 +24,7 @@ func UpdateDashboardAcl(cmd *m.UpdateDashboardAclCommand) error {
 		}
 
 		for _, item := range cmd.Items {
-			if item.UserId == 0 && item.UserGroupId == 0 && !item.Role.IsValid() {
+			if item.UserId == 0 && item.TeamId == 0 && !item.Role.IsValid() {
 				return m.ErrDashboardAclInfoMissing
 			}
 
@@ -32,7 +32,7 @@ func UpdateDashboardAcl(cmd *m.UpdateDashboardAclCommand) error {
 				return m.ErrDashboardPermissionDashboardEmpty
 			}
 
-			sess.Nullable("user_id", "user_group_id")
+			sess.Nullable("user_id", "team_id")
 			if _, err := sess.Insert(item); err != nil {
 				return err
 			}
@@ -49,7 +49,7 @@ func UpdateDashboardAcl(cmd *m.UpdateDashboardAclCommand) error {
 
 func SetDashboardAcl(cmd *m.SetDashboardAclCommand) error {
 	return inTransaction(func(sess *DBSession) error {
-		if cmd.UserId == 0 && cmd.UserGroupId == 0 {
+		if cmd.UserId == 0 && cmd.TeamId == 0 {
 			return m.ErrDashboardAclInfoMissing
 		}
 
@@ -57,7 +57,7 @@ func SetDashboardAcl(cmd *m.SetDashboardAclCommand) error {
 			return m.ErrDashboardPermissionDashboardEmpty
 		}
 
-		if res, err := sess.Query("SELECT 1 from "+dialect.Quote("dashboard_acl")+" WHERE dashboard_id =? and (user_group_id=? or user_id=?)", cmd.DashboardId, cmd.UserGroupId, cmd.UserId); err != nil {
+		if res, err := sess.Query("SELECT 1 from "+dialect.Quote("dashboard_acl")+" WHERE dashboard_id =? and (team_id=? or user_id=?)", cmd.DashboardId, cmd.TeamId, cmd.UserId); err != nil {
 			return err
 		} else if len(res) == 1 {
 
@@ -66,7 +66,7 @@ func SetDashboardAcl(cmd *m.SetDashboardAclCommand) error {
 				Updated:    time.Now(),
 			}
 
-			if _, err := sess.Cols("updated", "permission").Where("dashboard_id =? and (user_group_id=? or user_id=?)", cmd.DashboardId, cmd.UserGroupId, cmd.UserId).Update(&entity); err != nil {
+			if _, err := sess.Cols("updated", "permission").Where("dashboard_id =? and (team_id=? or user_id=?)", cmd.DashboardId, cmd.TeamId, cmd.UserId).Update(&entity); err != nil {
 				return err
 			}
 
@@ -75,7 +75,7 @@ func SetDashboardAcl(cmd *m.SetDashboardAclCommand) error {
 
 		entity := m.DashboardAcl{
 			OrgId:       cmd.OrgId,
-			UserGroupId: cmd.UserGroupId,
+			TeamId: cmd.TeamId,
 			UserId:      cmd.UserId,
 			Created:     time.Now(),
 			Updated:     time.Now(),
@@ -89,8 +89,8 @@ func SetDashboardAcl(cmd *m.SetDashboardAclCommand) error {
 			cols = append(cols, "user_id")
 		}
 
-		if cmd.UserGroupId != 0 {
-			cols = append(cols, "user_group_id")
+		if cmd.TeamId != 0 {
+			cols = append(cols, "team_id")
 		}
 
 		_, err := sess.Cols(cols...).Insert(&entity)
@@ -138,17 +138,17 @@ func GetDashboardAclInfoList(query *m.GetDashboardAclInfoListQuery) error {
 		da.org_id,
 		da.dashboard_id,
 		da.user_id,
-		da.user_group_id,
+		da.team_id,
 		da.permission,
 		da.role,
 		da.created,
 		da.updated,
 		u.login AS user_login,
 		u.email AS user_email,
-		ug.name AS user_group
+		ug.name AS team
   FROM` + dialect.Quote("dashboard_acl") + ` as da
 		LEFT OUTER JOIN ` + dialect.Quote("user") + ` AS u ON u.id = da.user_id
-		LEFT OUTER JOIN user_group ug on ug.id = da.user_group_id
+		LEFT OUTER JOIN team ug on ug.id = da.team_id
 	WHERE dashboard_id ` + dashboardFilter + ` AND da.org_id = ?
 
 	-- Also include default permission if has_acl = 0
@@ -159,14 +159,14 @@ func GetDashboardAclInfoList(query *m.GetDashboardAclInfoListQuery) error {
 			da.org_id,
 			da.dashboard_id,
 			da.user_id,
-			da.user_group_id,
+			da.team_id,
 			da.permission,
 			da.role,
 			da.created,
 			da.updated,
 			'' as user_login,
 			'' as user_email,
-			'' as user_group
+			'' as team
 			FROM dashboard_acl as da,
         dashboard as dash
         LEFT JOIN dashboard folder on dash.folder_id = folder.id

+ 11 - 11
pkg/services/sqlstore/dashboard_acl_test.go

@@ -16,7 +16,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
 			savedFolder := insertTestDashboard("1 test dash folder", 1, 0, true, "prod", "webapp")
 			childDash := insertTestDashboard("2 test dash", 1, savedFolder.Id, false, "prod", "webapp")
 
-			Convey("When adding dashboard permission with userId and userGroupId set to 0", func() {
+			Convey("When adding dashboard permission with userId and teamId set to 0", func() {
 				err := SetDashboardAcl(&m.SetDashboardAclCommand{
 					OrgId:       1,
 					DashboardId: savedFolder.Id,
@@ -175,15 +175,15 @@ func TestDashboardAclDataAccess(t *testing.T) {
 				})
 			})
 
-			Convey("Given a user group", func() {
-				group1 := m.CreateUserGroupCommand{Name: "group1 name", OrgId: 1}
-				err := CreateUserGroup(&group1)
+			Convey("Given a team", func() {
+				group1 := m.CreateTeamCommand{Name: "group1 name", OrgId: 1}
+				err := CreateTeam(&group1)
 				So(err, ShouldBeNil)
 
-				Convey("Should be able to add a user permission for a user group", func() {
+				Convey("Should be able to add a user permission for a team", func() {
 					setDashAclCmd := m.SetDashboardAclCommand{
 						OrgId:       1,
-						UserGroupId: group1.Result.Id,
+						TeamId: group1.Result.Id,
 						DashboardId: savedFolder.Id,
 						Permission:  m.PERMISSION_EDIT,
 					}
@@ -196,9 +196,9 @@ func TestDashboardAclDataAccess(t *testing.T) {
 					So(err, ShouldBeNil)
 					So(q1.Result[0].DashboardId, ShouldEqual, savedFolder.Id)
 					So(q1.Result[0].Permission, ShouldEqual, m.PERMISSION_EDIT)
-					So(q1.Result[0].UserGroupId, ShouldEqual, group1.Result.Id)
+					So(q1.Result[0].TeamId, ShouldEqual, group1.Result.Id)
 
-					Convey("Should be able to delete an existing permission for a user group", func() {
+					Convey("Should be able to delete an existing permission for a team", func() {
 						err := RemoveDashboardAcl(&m.RemoveDashboardAclCommand{
 							OrgId: 1,
 							AclId: setDashAclCmd.Result.Id,
@@ -212,10 +212,10 @@ func TestDashboardAclDataAccess(t *testing.T) {
 					})
 				})
 
-				Convey("Should be able to update an existing permission for a user group", func() {
+				Convey("Should be able to update an existing permission for a team", func() {
 					err := SetDashboardAcl(&m.SetDashboardAclCommand{
 						OrgId:       1,
-						UserGroupId: group1.Result.Id,
+						TeamId: group1.Result.Id,
 						DashboardId: savedFolder.Id,
 						Permission:  m.PERMISSION_ADMIN,
 					})
@@ -227,7 +227,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
 					So(len(q3.Result), ShouldEqual, 1)
 					So(q3.Result[0].DashboardId, ShouldEqual, savedFolder.Id)
 					So(q3.Result[0].Permission, ShouldEqual, m.PERMISSION_ADMIN)
-					So(q3.Result[0].UserGroupId, ShouldEqual, group1.Result.Id)
+					So(q3.Result[0].TeamId, ShouldEqual, group1.Result.Id)
 				})
 
 			})

+ 2 - 2
pkg/services/sqlstore/migrations/dashboard_acl.go

@@ -10,7 +10,7 @@ func addDashboardAclMigrations(mg *Migrator) {
 			{Name: "org_id", Type: DB_BigInt},
 			{Name: "dashboard_id", Type: DB_BigInt},
 			{Name: "user_id", Type: DB_BigInt, Nullable: true},
-			{Name: "user_group_id", Type: DB_BigInt, Nullable: true},
+			{Name: "team_id", Type: DB_BigInt, Nullable: true},
 			{Name: "permission", Type: DB_SmallInt, Default: "4"},
 			{Name: "role", Type: DB_Varchar, Length: 20, Nullable: true},
 			{Name: "created", Type: DB_DateTime, Nullable: false},
@@ -19,7 +19,7 @@ func addDashboardAclMigrations(mg *Migrator) {
 		Indices: []*Index{
 			{Cols: []string{"dashboard_id"}},
 			{Cols: []string{"dashboard_id", "user_id"}, Type: UniqueIndex},
-			{Cols: []string{"dashboard_id", "user_group_id"}, Type: UniqueIndex},
+			{Cols: []string{"dashboard_id", "team_id"}, Type: UniqueIndex},
 		},
 	}
 

+ 1 - 1
pkg/services/sqlstore/migrations/migrations.go

@@ -26,7 +26,7 @@ func AddMigrations(mg *Migrator) {
 	addAnnotationMig(mg)
 	addTestDataMigrations(mg)
 	addDashboardVersionMigration(mg)
-	addUserGroupMigrations(mg)
+	addTeamMigrations(mg)
 	addDashboardAclMigrations(mg)
 	addTagMigration(mg)
 }

+ 13 - 13
pkg/services/sqlstore/migrations/user_group_mig.go

@@ -2,9 +2,9 @@ package migrations
 
 import . "github.com/grafana/grafana/pkg/services/sqlstore/migrator"
 
-func addUserGroupMigrations(mg *Migrator) {
-	userGroupV1 := Table{
-		Name: "user_group",
+func addTeamMigrations(mg *Migrator) {
+	teamV1 := Table{
+		Name: "team",
 		Columns: []*Column{
 			{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
 			{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
@@ -18,31 +18,31 @@ func addUserGroupMigrations(mg *Migrator) {
 		},
 	}
 
-	mg.AddMigration("create user group table", NewAddTableMigration(userGroupV1))
+	mg.AddMigration("create team table", NewAddTableMigration(teamV1))
 
 	//-------  indexes ------------------
-	mg.AddMigration("add index user_group.org_id", NewAddIndexMigration(userGroupV1, userGroupV1.Indices[0]))
-	mg.AddMigration("add unique index user_group_org_id_name", NewAddIndexMigration(userGroupV1, userGroupV1.Indices[1]))
+	mg.AddMigration("add index team.org_id", NewAddIndexMigration(teamV1, teamV1.Indices[0]))
+	mg.AddMigration("add unique index team_org_id_name", NewAddIndexMigration(teamV1, teamV1.Indices[1]))
 
-	userGroupMemberV1 := Table{
-		Name: "user_group_member",
+	teamMemberV1 := Table{
+		Name: "team_member",
 		Columns: []*Column{
 			{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
 			{Name: "org_id", Type: DB_BigInt},
-			{Name: "user_group_id", Type: DB_BigInt},
+			{Name: "team_id", Type: DB_BigInt},
 			{Name: "user_id", Type: DB_BigInt},
 			{Name: "created", Type: DB_DateTime, Nullable: false},
 			{Name: "updated", Type: DB_DateTime, Nullable: false},
 		},
 		Indices: []*Index{
 			{Cols: []string{"org_id"}},
-			{Cols: []string{"org_id", "user_group_id", "user_id"}, Type: UniqueIndex},
+			{Cols: []string{"org_id", "team_id", "user_id"}, Type: UniqueIndex},
 		},
 	}
 
-	mg.AddMigration("create user group member table", NewAddTableMigration(userGroupMemberV1))
+	mg.AddMigration("create team member table", NewAddTableMigration(teamMemberV1))
 
 	//-------  indexes ------------------
-	mg.AddMigration("add index user_group_member.org_id", NewAddIndexMigration(userGroupMemberV1, userGroupMemberV1.Indices[0]))
-	mg.AddMigration("add unique index user_group_member_org_id_user_group_id_user_id", NewAddIndexMigration(userGroupMemberV1, userGroupMemberV1.Indices[1]))
+	mg.AddMigration("add index team_member.org_id", NewAddIndexMigration(teamMemberV1, teamMemberV1.Indices[0]))
+	mg.AddMigration("add unique index team_member_org_id_team_id_user_id", NewAddIndexMigration(teamMemberV1, teamMemberV1.Indices[1]))
 }

+ 1 - 1
pkg/services/sqlstore/org_users.go

@@ -91,7 +91,7 @@ func RemoveOrgUser(cmd *m.RemoveOrgUserCommand) error {
 		deletes := []string{
 			"DELETE FROM org_user WHERE org_id=? and user_id=?",
 			"DELETE FROM dashboard_acl WHERE org_id=? and user_id = ?",
-			"DELETE FROM user_group_member WHERE org_id=? and user_id = ?",
+			"DELETE FROM team_member WHERE org_id=? and user_id = ?",
 		}
 
 		for _, sql := range deletes {

+ 1 - 1
pkg/services/sqlstore/search_builder.go

@@ -179,7 +179,7 @@ func (sb *SearchBuilder) buildSearchWhereClause() {
 			SELECT distinct d.id AS DashboardId
 			FROM dashboard AS d
 	      		LEFT JOIN dashboard_acl as da on d.folder_id = da.dashboard_id or d.id = da.dashboard_id
-	      		LEFT JOIN user_group_member as ugm on ugm.user_group_id =  da.user_group_id
+	      		LEFT JOIN team_member as ugm on ugm.team_id =  da.team_id
 	      		LEFT JOIN org_user ou on ou.role = da.role
 			WHERE
 			  d.has_acl = 1 and

+ 1 - 1
pkg/services/sqlstore/user.go

@@ -442,7 +442,7 @@ func DeleteUser(cmd *m.DeleteUserCommand) error {
 			"DELETE FROM org_user WHERE user_id = ?",
 			"DELETE FROM dashboard_acl WHERE user_id = ?",
 			"DELETE FROM preferences WHERE user_id = ?",
-			"DELETE FROM user_group_member WHERE user_id = ?",
+			"DELETE FROM team_member WHERE user_id = ?",
 		}
 
 		for _, sql := range deletes {

+ 66 - 66
pkg/services/sqlstore/user_group.go

@@ -9,82 +9,82 @@ import (
 )
 
 func init() {
-	bus.AddHandler("sql", CreateUserGroup)
-	bus.AddHandler("sql", UpdateUserGroup)
-	bus.AddHandler("sql", DeleteUserGroup)
-	bus.AddHandler("sql", SearchUserGroups)
-	bus.AddHandler("sql", GetUserGroupById)
-	bus.AddHandler("sql", GetUserGroupsByUser)
-
-	bus.AddHandler("sql", AddUserGroupMember)
-	bus.AddHandler("sql", RemoveUserGroupMember)
-	bus.AddHandler("sql", GetUserGroupMembers)
+	bus.AddHandler("sql", CreateTeam)
+	bus.AddHandler("sql", UpdateTeam)
+	bus.AddHandler("sql", DeleteTeam)
+	bus.AddHandler("sql", SearchTeams)
+	bus.AddHandler("sql", GetTeamById)
+	bus.AddHandler("sql", GetTeamsByUser)
+
+	bus.AddHandler("sql", AddTeamMember)
+	bus.AddHandler("sql", RemoveTeamMember)
+	bus.AddHandler("sql", GetTeamMembers)
 }
 
-func CreateUserGroup(cmd *m.CreateUserGroupCommand) error {
+func CreateTeam(cmd *m.CreateTeamCommand) error {
 	return inTransaction(func(sess *DBSession) error {
 
-		if isNameTaken, err := isUserGroupNameTaken(cmd.Name, 0, sess); err != nil {
+		if isNameTaken, err := isTeamNameTaken(cmd.Name, 0, sess); err != nil {
 			return err
 		} else if isNameTaken {
-			return m.ErrUserGroupNameTaken
+			return m.ErrTeamNameTaken
 		}
 
-		userGroup := m.UserGroup{
+		team := m.Team{
 			Name:    cmd.Name,
 			OrgId:   cmd.OrgId,
 			Created: time.Now(),
 			Updated: time.Now(),
 		}
 
-		_, err := sess.Insert(&userGroup)
+		_, err := sess.Insert(&team)
 
-		cmd.Result = userGroup
+		cmd.Result = team
 
 		return err
 	})
 }
 
-func UpdateUserGroup(cmd *m.UpdateUserGroupCommand) error {
+func UpdateTeam(cmd *m.UpdateTeamCommand) error {
 	return inTransaction(func(sess *DBSession) error {
 
-		if isNameTaken, err := isUserGroupNameTaken(cmd.Name, cmd.Id, sess); err != nil {
+		if isNameTaken, err := isTeamNameTaken(cmd.Name, cmd.Id, sess); err != nil {
 			return err
 		} else if isNameTaken {
-			return m.ErrUserGroupNameTaken
+			return m.ErrTeamNameTaken
 		}
 
-		userGroup := m.UserGroup{
+		team := m.Team{
 			Name:    cmd.Name,
 			Updated: time.Now(),
 		}
 
-		affectedRows, err := sess.Id(cmd.Id).Update(&userGroup)
+		affectedRows, err := sess.Id(cmd.Id).Update(&team)
 
 		if err != nil {
 			return err
 		}
 
 		if affectedRows == 0 {
-			return m.ErrUserGroupNotFound
+			return m.ErrTeamNotFound
 		}
 
 		return nil
 	})
 }
 
-func DeleteUserGroup(cmd *m.DeleteUserGroupCommand) error {
+func DeleteTeam(cmd *m.DeleteTeamCommand) error {
 	return inTransaction(func(sess *DBSession) error {
-		if res, err := sess.Query("SELECT 1 from user_group WHERE id=?", cmd.Id); err != nil {
+		if res, err := sess.Query("SELECT 1 from team WHERE id=?", cmd.Id); err != nil {
 			return err
 		} else if len(res) != 1 {
-			return m.ErrUserGroupNotFound
+			return m.ErrTeamNotFound
 		}
 
 		deletes := []string{
-			"DELETE FROM user_group_member WHERE user_group_id = ?",
-			"DELETE FROM user_group WHERE id = ?",
-			"DELETE FROM dashboard_acl WHERE user_group_id = ?",
+			"DELETE FROM team_member WHERE team_id = ?",
+			"DELETE FROM team WHERE id = ?",
+			"DELETE FROM dashboard_acl WHERE team_id = ?",
 		}
 
 		for _, sql := range deletes {
@@ -97,28 +97,28 @@ func DeleteUserGroup(cmd *m.DeleteUserGroupCommand) error {
 	})
 }
 
-func isUserGroupNameTaken(name string, existingId int64, sess *DBSession) (bool, error) {
-	var userGroup m.UserGroup
-	exists, err := sess.Where("name=?", name).Get(&userGroup)
+func isTeamNameTaken(name string, existingId int64, sess *DBSession) (bool, error) {
+	var team m.Team
+	exists, err := sess.Where("name=?", name).Get(&team)
 
 	if err != nil {
 		return false, nil
 	}
 
-	if exists && existingId != userGroup.Id {
+	if exists && existingId != team.Id {
 		return true, nil
 	}
 
 	return false, nil
 }
 
-func SearchUserGroups(query *m.SearchUserGroupsQuery) error {
-	query.Result = m.SearchUserGroupQueryResult{
-		UserGroups: make([]*m.UserGroup, 0),
+func SearchTeams(query *m.SearchTeamsQuery) error {
+	query.Result = m.SearchTeamQueryResult{
+		Teams: make([]*m.Team, 0),
 	}
 	queryWithWildcards := "%" + query.Query + "%"
 
-	sess := x.Table("user_group")
+	sess := x.Table("team")
 	sess.Where("org_id=?", query.OrgId)
 
 	if query.Query != "" {
@@ -132,46 +132,46 @@ func SearchUserGroups(query *m.SearchUserGroupsQuery) error {
 	offset := query.Limit * (query.Page - 1)
 	sess.Limit(query.Limit, offset)
 	sess.Cols("id", "name")
-	if err := sess.Find(&query.Result.UserGroups); err != nil {
+	if err := sess.Find(&query.Result.Teams); err != nil {
 		return err
 	}
 
-	userGroup := m.UserGroup{}
+	team := m.Team{}
 
-	countSess := x.Table("user_group")
+	countSess := x.Table("team")
 	if query.Query != "" {
 		countSess.Where("name LIKE ?", queryWithWildcards)
 	}
 	if query.Name != "" {
 		countSess.Where("name=?", query.Name)
 	}
-	count, err := countSess.Count(&userGroup)
+	count, err := countSess.Count(&team)
 	query.Result.TotalCount = count
 
 	return err
 }
 
-func GetUserGroupById(query *m.GetUserGroupByIdQuery) error {
-	var userGroup m.UserGroup
-	exists, err := x.Id(query.Id).Get(&userGroup)
+func GetTeamById(query *m.GetTeamByIdQuery) error {
+	var team m.Team
+	exists, err := x.Id(query.Id).Get(&team)
 	if err != nil {
 		return err
 	}
 
 	if !exists {
-		return m.ErrUserGroupNotFound
+		return m.ErrTeamNotFound
 	}
 
-	query.Result = &userGroup
+	query.Result = &team
 	return nil
 }
 
-func GetUserGroupsByUser(query *m.GetUserGroupsByUserQuery) error {
-	query.Result = make([]*m.UserGroup, 0)
+func GetTeamsByUser(query *m.GetTeamsByUserQuery) error {
+	query.Result = make([]*m.Team, 0)
 
-	sess := x.Table("user_group")
-	sess.Join("INNER", "user_group_member", "user_group.id=user_group_member.user_group_id")
-	sess.Where("user_group_member.user_id=?", query.UserId)
+	sess := x.Table("team")
+	sess.Join("INNER", "team_member", "team.id=team_member.team_id")
+	sess.Where("team_member.user_id=?", query.UserId)
 
 	err := sess.Find(&query.Result)
 	if err != nil {
@@ -181,23 +181,23 @@ func GetUserGroupsByUser(query *m.GetUserGroupsByUserQuery) error {
 	return nil
 }
 
-func AddUserGroupMember(cmd *m.AddUserGroupMemberCommand) error {
+func AddTeamMember(cmd *m.AddTeamMemberCommand) error {
 	return inTransaction(func(sess *DBSession) error {
-		if res, err := sess.Query("SELECT 1 from user_group_member WHERE user_group_id=? and user_id=?", cmd.UserGroupId, cmd.UserId); err != nil {
+		if res, err := sess.Query("SELECT 1 from team_member WHERE team_id=? and user_id=?", cmd.TeamId, cmd.UserId); err != nil {
 			return err
 		} else if len(res) == 1 {
-			return m.ErrUserGroupMemberAlreadyAdded
+			return m.ErrTeamMemberAlreadyAdded
 		}
 
-		if res, err := sess.Query("SELECT 1 from user_group WHERE id=?", cmd.UserGroupId); err != nil {
+		if res, err := sess.Query("SELECT 1 from team WHERE id=?", cmd.TeamId); err != nil {
 			return err
 		} else if len(res) != 1 {
-			return m.ErrUserGroupNotFound
+			return m.ErrTeamNotFound
 		}
 
-		entity := m.UserGroupMember{
+		entity := m.TeamMember{
 			OrgId:       cmd.OrgId,
-			UserGroupId: cmd.UserGroupId,
+			TeamId: cmd.TeamId,
 			UserId:      cmd.UserId,
 			Created:     time.Now(),
 			Updated:     time.Now(),
@@ -208,10 +208,10 @@ func AddUserGroupMember(cmd *m.AddUserGroupMemberCommand) error {
 	})
 }
 
-func RemoveUserGroupMember(cmd *m.RemoveUserGroupMemberCommand) error {
+func RemoveTeamMember(cmd *m.RemoveTeamMemberCommand) error {
 	return inTransaction(func(sess *DBSession) error {
-		var rawSql = "DELETE FROM user_group_member WHERE user_group_id=? and user_id=?"
-		_, err := sess.Exec(rawSql, cmd.UserGroupId, cmd.UserId)
+		var rawSql = "DELETE FROM team_member WHERE team_id=? and user_id=?"
+		_, err := sess.Exec(rawSql, cmd.TeamId, cmd.UserId)
 		if err != nil {
 			return err
 		}
@@ -220,12 +220,12 @@ func RemoveUserGroupMember(cmd *m.RemoveUserGroupMemberCommand) error {
 	})
 }
 
-func GetUserGroupMembers(query *m.GetUserGroupMembersQuery) error {
-	query.Result = make([]*m.UserGroupMemberDTO, 0)
-	sess := x.Table("user_group_member")
-	sess.Join("INNER", "user", fmt.Sprintf("user_group_member.user_id=%s.id", x.Dialect().Quote("user")))
-	sess.Where("user_group_member.user_group_id=?", query.UserGroupId)
-	sess.Cols("user.org_id", "user_group_member.user_group_id", "user_group_member.user_id", "user.email", "user.login")
+func GetTeamMembers(query *m.GetTeamMembersQuery) error {
+	query.Result = make([]*m.TeamMemberDTO, 0)
+	sess := x.Table("team_member")
+	sess.Join("INNER", "user", fmt.Sprintf("team_member.user_id=%s.id", x.Dialect().Quote("user")))
+	sess.Where("team_member.team_id=?", query.TeamId)
+	sess.Cols("user.org_id", "team_member.team_id", "team_member.user_id", "user.email", "user.login")
 	sess.Asc("user.login", "user.email")
 
 	err := sess.Find(&query.Result)

+ 37 - 37
pkg/services/sqlstore/user_group_test.go

@@ -9,12 +9,12 @@ import (
 	m "github.com/grafana/grafana/pkg/models"
 )
 
-func TestUserGroupCommandsAndQueries(t *testing.T) {
+func TestTeamCommandsAndQueries(t *testing.T) {
 
-	Convey("Testing User Group commands & queries", t, func() {
+	Convey("Testing Team commands & queries", t, func() {
 		InitTestDB(t)
 
-		Convey("Given saved users and two user groups", func() {
+		Convey("Given saved users and two teams", func() {
 			var userIds []int64
 			for i := 0; i < 5; i++ {
 				userCmd := &m.CreateUserCommand{
@@ -27,81 +27,81 @@ func TestUserGroupCommandsAndQueries(t *testing.T) {
 				userIds = append(userIds, userCmd.Result.Id)
 			}
 
-			group1 := m.CreateUserGroupCommand{Name: "group1 name"}
-			group2 := m.CreateUserGroupCommand{Name: "group2 name"}
+			group1 := m.CreateTeamCommand{Name: "group1 name"}
+			group2 := m.CreateTeamCommand{Name: "group2 name"}
 
-			err := CreateUserGroup(&group1)
+			err := CreateTeam(&group1)
 			So(err, ShouldBeNil)
-			err = CreateUserGroup(&group2)
+			err = CreateTeam(&group2)
 			So(err, ShouldBeNil)
 
-			Convey("Should be able to create user groups and add users", func() {
-				query := &m.SearchUserGroupsQuery{Name: "group1 name", Page: 1, Limit: 10}
-				err = SearchUserGroups(query)
+			Convey("Should be able to create teams and add users", func() {
+				query := &m.SearchTeamsQuery{Name: "group1 name", Page: 1, Limit: 10}
+				err = SearchTeams(query)
 				So(err, ShouldBeNil)
 				So(query.Page, ShouldEqual, 1)
 
-				userGroup1 := query.Result.UserGroups[0]
-				So(userGroup1.Name, ShouldEqual, "group1 name")
+				team1 := query.Result.Teams[0]
+				So(team1.Name, ShouldEqual, "group1 name")
 
-				err = AddUserGroupMember(&m.AddUserGroupMemberCommand{OrgId: 1, UserGroupId: userGroup1.Id, UserId: userIds[0]})
+				err = AddTeamMember(&m.AddTeamMemberCommand{OrgId: 1, TeamId: team1.Id, UserId: userIds[0]})
 				So(err, ShouldBeNil)
 
-				q1 := &m.GetUserGroupMembersQuery{UserGroupId: userGroup1.Id}
-				err = GetUserGroupMembers(q1)
+				q1 := &m.GetTeamMembersQuery{TeamId: team1.Id}
+				err = GetTeamMembers(q1)
 				So(err, ShouldBeNil)
-				So(q1.Result[0].UserGroupId, ShouldEqual, userGroup1.Id)
+				So(q1.Result[0].TeamId, ShouldEqual, team1.Id)
 				So(q1.Result[0].Login, ShouldEqual, "loginuser0")
 			})
 
-			Convey("Should be able to search for user groups", func() {
-				query := &m.SearchUserGroupsQuery{Query: "group", Page: 1}
-				err = SearchUserGroups(query)
+			Convey("Should be able to search for teams", func() {
+				query := &m.SearchTeamsQuery{Query: "group", Page: 1}
+				err = SearchTeams(query)
 				So(err, ShouldBeNil)
-				So(len(query.Result.UserGroups), ShouldEqual, 2)
+				So(len(query.Result.Teams), ShouldEqual, 2)
 				So(query.Result.TotalCount, ShouldEqual, 2)
 
-				query2 := &m.SearchUserGroupsQuery{Query: ""}
-				err = SearchUserGroups(query2)
+				query2 := &m.SearchTeamsQuery{Query: ""}
+				err = SearchTeams(query2)
 				So(err, ShouldBeNil)
-				So(len(query2.Result.UserGroups), ShouldEqual, 2)
+				So(len(query2.Result.Teams), ShouldEqual, 2)
 			})
 
-			Convey("Should be able to return all user groups a user is member of", func() {
+			Convey("Should be able to return all teams a user is member of", func() {
 				groupId := group2.Result.Id
-				err := AddUserGroupMember(&m.AddUserGroupMemberCommand{OrgId: 1, UserGroupId: groupId, UserId: userIds[0]})
+				err := AddTeamMember(&m.AddTeamMemberCommand{OrgId: 1, TeamId: groupId, UserId: userIds[0]})
 
-				query := &m.GetUserGroupsByUserQuery{UserId: userIds[0]}
-				err = GetUserGroupsByUser(query)
+				query := &m.GetTeamsByUserQuery{UserId: userIds[0]}
+				err = GetTeamsByUser(query)
 				So(err, ShouldBeNil)
 				So(len(query.Result), ShouldEqual, 1)
 				So(query.Result[0].Name, ShouldEqual, "group2 name")
 			})
 
 			Convey("Should be able to remove users from a group", func() {
-				err = RemoveUserGroupMember(&m.RemoveUserGroupMemberCommand{UserGroupId: group1.Result.Id, UserId: userIds[0]})
+				err = RemoveTeamMember(&m.RemoveTeamMemberCommand{TeamId: group1.Result.Id, UserId: userIds[0]})
 				So(err, ShouldBeNil)
 
-				q1 := &m.GetUserGroupMembersQuery{UserGroupId: group1.Result.Id}
-				err = GetUserGroupMembers(q1)
+				q1 := &m.GetTeamMembersQuery{TeamId: group1.Result.Id}
+				err = GetTeamMembers(q1)
 				So(err, ShouldBeNil)
 				So(len(q1.Result), ShouldEqual, 0)
 			})
 
 			Convey("Should be able to remove a group with users and permissions", func() {
 				groupId := group2.Result.Id
-				err := AddUserGroupMember(&m.AddUserGroupMemberCommand{OrgId: 1, UserGroupId: groupId, UserId: userIds[1]})
+				err := AddTeamMember(&m.AddTeamMemberCommand{OrgId: 1, TeamId: groupId, UserId: userIds[1]})
 				So(err, ShouldBeNil)
-				err = AddUserGroupMember(&m.AddUserGroupMemberCommand{OrgId: 1, UserGroupId: groupId, UserId: userIds[2]})
+				err = AddTeamMember(&m.AddTeamMemberCommand{OrgId: 1, TeamId: groupId, UserId: userIds[2]})
 				So(err, ShouldBeNil)
-				err = SetDashboardAcl(&m.SetDashboardAclCommand{DashboardId: 1, OrgId: 1, Permission: m.PERMISSION_EDIT, UserGroupId: groupId})
+				err = SetDashboardAcl(&m.SetDashboardAclCommand{DashboardId: 1, OrgId: 1, Permission: m.PERMISSION_EDIT, TeamId: groupId})
 
-				err = DeleteUserGroup(&m.DeleteUserGroupCommand{Id: groupId})
+				err = DeleteTeam(&m.DeleteTeamCommand{Id: groupId})
 				So(err, ShouldBeNil)
 
-				query := &m.GetUserGroupByIdQuery{Id: groupId}
-				err = GetUserGroupById(query)
-				So(err, ShouldEqual, m.ErrUserGroupNotFound)
+				query := &m.GetTeamByIdQuery{Id: groupId}
+				err = GetTeamById(query)
+				So(err, ShouldEqual, m.ErrTeamNotFound)
 
 				permQuery := &m.GetDashboardAclInfoListQuery{DashboardId: 1, OrgId: 1}
 				err = GetDashboardAclInfoList(permQuery)

+ 10 - 10
public/app/core/components/user_group_picker.ts

@@ -10,9 +10,9 @@ const template = `
   </gf-form-dropdown>
 </div>
 `;
-export class UserGroupPickerCtrl {
+export class TeamPickerCtrl {
   group: any;
-  userGroupPicked: any;
+  teamPicked: any;
   debouncedSearchGroups: any;
 
   /** @ngInject */
@@ -26,34 +26,34 @@ export class UserGroupPickerCtrl {
   }
 
   searchGroups(query: string) {
-    return Promise.resolve(this.backendSrv.get('/api/user-groups/search?perpage=10&page=1&query=' + query).then(result => {
-      return _.map(result.userGroups, ug => {
+    return Promise.resolve(this.backendSrv.get('/api/teams/search?perpage=10&page=1&query=' + query).then(result => {
+      return _.map(result.teams, ug => {
         return {text: ug.name, value: ug};
       });
     }));
   }
 
   onChange(option) {
-    this.userGroupPicked({$group: option.value});
+    this.teamPicked({$group: option.value});
   }
 }
 
-export function userGroupPicker() {
+export function teamPicker() {
   return {
     restrict: 'E',
     template: template,
-    controller: UserGroupPickerCtrl,
+    controller: TeamPickerCtrl,
     bindToController: true,
     controllerAs: 'ctrl',
     scope: {
-      userGroupPicked: '&',
+      teamPicked: '&',
     },
     link: function(scope, elem, attrs, ctrl) {
-      scope.$on("user-group-picker-reset", () => {
+      scope.$on("team-picker-reset", () => {
         ctrl.reset();
       });
     }
   };
 }
 
-coreModule.directive('userGroupPicker', userGroupPicker);
+coreModule.directive('teamPicker', teamPicker);

+ 2 - 2
public/app/core/core.ts

@@ -47,7 +47,7 @@ import {helpModal} from './components/help/help';
 import {JsonExplorer} from './components/json_explorer/json_explorer';
 import {NavModelSrv, NavModel} from './nav_model_srv';
 import {userPicker} from './components/user_picker';
-import {userGroupPicker} from './components/user_group_picker';
+import {teamPicker} from './components/user_group_picker';
 import {geminiScrollbar} from './components/scroll/scroll';
 import {gfPageDirective} from './components/gf_page';
 import {orgSwitcher} from './components/org_switcher';
@@ -85,7 +85,7 @@ export {
   NavModelSrv,
   NavModel,
   userPicker,
-  userGroupPicker,
+  teamPicker,
   geminiScrollbar,
   gfPageDirective,
   orgSwitcher,

+ 4 - 4
public/app/core/routes/routes.ts

@@ -109,15 +109,15 @@ function setupAngularRoutes($routeProvider, $locationProvider) {
     controller : 'OrgApiKeysCtrl',
     resolve: loadOrgBundle,
   })
-  .when('/org/user-groups', {
+  .when('/org/teams', {
     templateUrl: 'public/app/features/org/partials/user_groups.html',
-    controller : 'UserGroupsCtrl',
+    controller : 'TeamsCtrl',
     controllerAs: 'ctrl',
     resolve: loadOrgBundle,
   })
-  .when('/org/user-groups/edit/:id', {
+  .when('/org/teams/edit/:id', {
     templateUrl: 'public/app/features/org/partials/user_group_details.html',
-    controller : 'UserGroupDetailsCtrl',
+    controller : 'TeamDetailsCtrl',
     controllerAs: 'ctrl',
     resolve: loadOrgBundle,
   })

+ 3 - 3
public/app/features/dashboard/acl/acl.html

@@ -52,7 +52,7 @@
             <user-picker user-picked="ctrl.userPicked($user)"></user-picker>
           </div>
           <div class="gf-form" ng-show="ctrl.newType === 'Group'">
-            <user-group-picker user-group-picked="ctrl.groupPicked($group)"></user-group-picker>
+            <team-picker team-picked="ctrl.groupPicked($group)"></team-picker>
           </div>
         </div>
       </form>
@@ -101,9 +101,9 @@
   <!--             </a> -->
   <!--           </td> -->
   <!--         </tr> -->
-  <!--         <tr ng&#45;repeat="permission in ctrl.userGroupPermissions" class="permissionlist__item"> -->
+  <!--         <tr ng&#45;repeat="permission in ctrl.teamPermissions" class="permissionlist__item"> -->
   <!--           <td><i class="fa fa&#45;fw fa&#45;users"></i></td> -->
-  <!--           <td>{{permission.userGroup}}</td> -->
+  <!--           <td>{{permission.team}}</td> -->
   <!--           <td><select class="gf&#45;form&#45;input gf&#45;size&#45;auto" ng&#45;model="permission.permissions" ng&#45;options="p.value as p.text for p in ctrl.permissionTypeOptions" ng&#45;change="ctrl.updatePermission(permission)"></select></td> -->
   <!--           <td class="text&#45;right"> -->
   <!--             <a ng&#45;click="ctrl.removePermission(permission)" class="btn btn&#45;danger btn&#45;small"> -->

+ 10 - 10
public/app/features/dashboard/acl/acl.ts

@@ -58,10 +58,10 @@ export class AclCtrl {
       item.nameHtml = this.$sce.trustAsHtml(item.userLogin);
       item.sortName = item.userLogin;
       item.sortRank = 10;
-    } else if (item.userGroupId > 0) {
+    } else if (item.teamId > 0) {
       item.icon = "fa fa-fw fa-users";
-      item.nameHtml = this.$sce.trustAsHtml(item.userGroup);
-      item.sortName = item.userGroup;
+      item.nameHtml = this.$sce.trustAsHtml(item.team);
+      item.sortName = item.team;
       item.sortRank = 20;
     } else if (item.role) {
       item.icon = "fa fa-fw fa-street-view";
@@ -89,7 +89,7 @@ export class AclCtrl {
       updated.push({
         id: item.id,
         userId: item.userId,
-        userGroupId: item.userGroupId,
+        teamId: item.teamId,
         role: item.role,
         permission: item.permission,
       });
@@ -144,7 +144,7 @@ export class AclCtrl {
 
     return (origItem.role && newItem.role && origItem.role === newItem.role) ||
     (origItem.userId && newItem.userId && origItem.userId === newItem.userId) ||
-    (origItem.userGroupId && newItem.userGroupId && origItem.userGroupId === newItem.userGroupId);
+    (origItem.teamId && newItem.teamId && origItem.teamId === newItem.teamId);
   }
 
   userPicked(user) {
@@ -153,8 +153,8 @@ export class AclCtrl {
   }
 
   groupPicked(group) {
-    this.addNewItem({userGroupId: group.id, userGroup: group.name, permission: 1});
-    this.$scope.$broadcast('user-group-picker-reset');
+    this.addNewItem({teamId: group.id, team: group.name, permission: 1});
+    this.$scope.$broadcast('team-picker-reset');
   }
 
   removeItem(index) {
@@ -179,7 +179,7 @@ export function dashAclModal() {
 export interface FormModel {
   dashboardId: number;
   userId?: number;
-  userGroupId?: number;
+  teamId?: number;
   PermissionType: number;
 }
 
@@ -189,8 +189,8 @@ export interface DashboardAcl {
   userId?: number;
   userLogin?: string;
   userEmail?: string;
-  userGroupId?: number;
-  userGroup?: string;
+  teamId?: number;
+  team?: string;
   permission?: number;
   permissionName?: string;
   role?: string;

+ 11 - 11
public/app/features/dashboard/acl/specs/acl_specs.ts

@@ -40,12 +40,12 @@ describe('AclCtrl', () => {
 
       ctx.ctrl.userPicked(userItem);
 
-      const userGroupItem = {
+      const teamItem = {
         id: 2,
         name: 'ug1',
       };
 
-      ctx.ctrl.groupPicked(userGroupItem);
+      ctx.ctrl.groupPicked(teamItem);
 
       ctx.ctrl.newType = 'Editor';
       ctx.ctrl.typeChanged();
@@ -57,7 +57,7 @@ describe('AclCtrl', () => {
      it('should sort the result by role, user group and user', () => {
         expect(ctx.ctrl.items[0].role).to.eql('Viewer');
         expect(ctx.ctrl.items[1].role).to.eql('Editor');
-        expect(ctx.ctrl.items[2].userGroupId).to.eql(2);
+        expect(ctx.ctrl.items[2].teamId).to.eql(2);
         expect(ctx.ctrl.items[3].userId).to.eql(2);
       });
 
@@ -71,7 +71,7 @@ describe('AclCtrl', () => {
       expect(backendSrv.post.getCall(0).args[1].items[0].permission).to.eql(1);
       expect(backendSrv.post.getCall(0).args[1].items[1].role).to.eql('Editor');
       expect(backendSrv.post.getCall(0).args[1].items[1].permission).to.eql(1);
-      expect(backendSrv.post.getCall(0).args[1].items[2].userGroupId).to.eql(2);
+      expect(backendSrv.post.getCall(0).args[1].items[2].teamId).to.eql(2);
       expect(backendSrv.post.getCall(0).args[1].items[2].permission).to.eql(1);
       expect(backendSrv.post.getCall(0).args[1].items[3].userId).to.eql(2);
       expect(backendSrv.post.getCall(0).args[1].items[3].permission).to.eql(1);
@@ -130,13 +130,13 @@ describe('AclCtrl', () => {
       backendSrv.post.reset();
       ctx.ctrl.items = [];
 
-      const userGroupItem = {
+      const teamItem = {
         id: 2,
         name: 'ug1',
       };
 
-      ctx.ctrl.groupPicked(userGroupItem);
-      ctx.ctrl.groupPicked(userGroupItem);
+      ctx.ctrl.groupPicked(teamItem);
+      ctx.ctrl.groupPicked(teamItem);
     });
 
     it('should throw a validation error', () => {
@@ -154,19 +154,19 @@ describe('AclCtrl', () => {
       backendSrv.post.reset();
       ctx.ctrl.items = [];
 
-      const inheritedUserGroupItem = {
+      const inheritedTeamItem = {
         id: 2,
         name: 'ug1',
         dashboardId: -1
       };
 
-      ctx.ctrl.items.push(inheritedUserGroupItem);
+      ctx.ctrl.items.push(inheritedTeamItem);
 
-      const userGroupItem = {
+      const teamItem = {
         id: 2,
         name: 'ug1',
       };
-      ctx.ctrl.groupPicked(userGroupItem);
+      ctx.ctrl.groupPicked(teamItem);
     });
 
     it('should not throw a validation error', () => {

+ 2 - 0
public/app/features/org/all.ts

@@ -6,6 +6,8 @@ import './change_password_ctrl';
 import './new_org_ctrl';
 import './user_invite_ctrl';
 import './user_groups_ctrl';
+import './user_group_details_ctrl';
+import './create_user_group_modal';
 import './org_api_keys_ctrl';
 import './org_details_ctrl';
 import './prefs_control';

+ 9 - 9
public/app/features/org/create_user_group_modal.ts

@@ -3,17 +3,17 @@
 import coreModule from 'app/core/core_module';
 import appEvents from 'app/core/app_events';
 
-export class CreateUserGroupCtrl {
-  userGroupName = '';
+export class CreateTeamCtrl {
+  teamName = '';
 
   /** @ngInject */
   constructor(private backendSrv, private $location) {
   }
 
-  createUserGroup() {
-    this.backendSrv.post('/api/user-groups', {name: this.userGroupName}).then((result) => {
-      if (result.userGroupId) {
-        this.$location.path('/org/user-groups/edit/' + result.userGroupId);
+  createTeam() {
+    this.backendSrv.post('/api/teams', {name: this.teamName}).then((result) => {
+      if (result.teamId) {
+        this.$location.path('/org/teams/edit/' + result.teamId);
       }
       this.dismiss();
     });
@@ -24,14 +24,14 @@ export class CreateUserGroupCtrl {
   }
 }
 
-export function createUserGroupModal() {
+export function createTeamModal() {
   return {
     restrict: 'E',
     templateUrl: 'public/app/features/org/partials/create_user_group.html',
-    controller: CreateUserGroupCtrl,
+    controller: CreateTeamCtrl,
     bindToController: true,
     controllerAs: 'ctrl',
   };
 }
 
-coreModule.directive('createUserGroupModal', createUserGroupModal);
+coreModule.directive('createTeamModal', createTeamModal);

+ 4 - 4
public/app/features/org/partials/create_user_group.html

@@ -1,7 +1,7 @@
 <div class="modal-body">
   <div class="modal-header">
 		<h2 class="modal-header-title">
-			<span class="p-l-1">Create User Group</span>
+			<span class="p-l-1">Create Team</span>
 		</h2>
 
 		<a class="modal-header-close" ng-click="ctrl.dismiss();">
@@ -10,14 +10,14 @@
 	</div>
 
 	<div class="modal-content">
-		<form name="ctrl.createUserGroupForm" class="gf-form-group" novalidate>
+		<form name="ctrl.createTeamForm" class="gf-form-group" novalidate>
       <div class="p-t-2">
         <div class="gf-form-inline">
           <div class="gf-form max-width-21">
-            <input type="text" class="gf-form-input" ng-model='ctrl.userGroupName' required give-focus="true" placeholder="Enter User Group Name"></input>
+            <input type="text" class="gf-form-input" ng-model='ctrl.teamName' required give-focus="true" placeholder="Enter User Group Name"></input>
           </div>
           <div class="gf-form">
-            <button class="btn gf-form-btn btn-success" ng-click="ctrl.createUserGroup();ctrl.dismiss();">Create</button>
+            <button class="btn gf-form-btn btn-success" ng-click="ctrl.createTeam();ctrl.dismiss();">Create</button>
           </div>
         </div>
       </div>

+ 6 - 6
public/app/features/org/partials/user_group_details.html

@@ -5,10 +5,10 @@
 		<h1>Edit User Group</h1>
 	</div>
 
-	<form name="userGroupDetailsForm" class="gf-form-group gf-form-inline">
+	<form name="teamDetailsForm" class="gf-form-group gf-form-inline">
 		<div class="gf-form">
 			<span class="gf-form-label width-10">Name</span>
-			<input type="text" required ng-model="ctrl.userGroup.name" class="gf-form-input max-width-14" >
+			<input type="text" required ng-model="ctrl.team.name" class="gf-form-input max-width-14" >
 		</div>
 
 		<div class="gf-form">
@@ -26,24 +26,24 @@
       </div>
     </form>
 
-    <table class="grafana-options-table" ng-show="ctrl.userGroupMembers.length > 0">
+    <table class="grafana-options-table" ng-show="ctrl.teamMembers.length > 0">
       <tr>
         <th>Username</th>
         <th>Email</th>
         <th></th>
       </tr>
-      <tr ng-repeat="member in ctrl.userGroupMembers">
+      <tr ng-repeat="member in ctrl.teamMembers">
         <td>{{member.login}}</td>
         <td>{{member.email}}</td>
         <td style="width: 1%">
-          <a ng-click="ctrl.removeUserGroupMember(member)" class="btn btn-danger btn-mini">
+          <a ng-click="ctrl.removeTeamMember(member)" class="btn btn-danger btn-mini">
             <i class="fa fa-remove"></i>
           </a>
         </td>
       </tr>
     </table>
     <div>
-  <em class="muted" ng-hide="ctrl.userGroupMembers.length > 0">
+  <em class="muted" ng-hide="ctrl.teamMembers.length > 0">
     This user group has no members yet.
   </em>
 </div>

+ 7 - 7
public/app/features/org/partials/user_groups.html

@@ -11,14 +11,14 @@
 
     <div class="page-action-bar__spacer"></div>
 
-    <a class="btn btn-success" ng-click="ctrl.openUserGroupModal()">
+    <a class="btn btn-success" ng-click="ctrl.openTeamModal()">
       <i class="fa fa-plus"></i>
 			Add Team
     </a>
   </div>
 
   <div class="admin-list-table">
-    <table class="filter-table form-inline" ng-show="ctrl.userGroups.length > 0">
+    <table class="filter-table form-inline" ng-show="ctrl.teams.length > 0">
       <thead>
         <tr>
           <th>Name</th>
@@ -27,18 +27,18 @@
         </tr>
       </thead>
       <tbody>
-        <tr ng-repeat="userGroup in ctrl.userGroups">
+        <tr ng-repeat="team in ctrl.teams">
           <td>
-            <a href="org/user-groups/edit/{{userGroup.id}}">{{userGroup.name}}</a>
+            <a href="org/teams/edit/{{team.id}}">{{team.name}}</a>
           </td>
           <td>#Count</td>
           <td class="text-right">
-            <a href="org/user-groups/edit/{{userGroup.id}}" class="btn btn-inverse btn-small">
+            <a href="org/teams/edit/{{team.id}}" class="btn btn-inverse btn-small">
               <i class="fa fa-edit"></i>
               Edit
             </a>
             &nbsp;&nbsp;
-            <a ng-click="ctrl.deleteUserGroup(userGroup)" class="btn btn-danger btn-small">
+            <a ng-click="ctrl.deleteTeam(team)" class="btn btn-danger btn-small">
               <i class="fa fa-remove"></i>
             </a>
           </td>
@@ -58,7 +58,7 @@
     </ol>
   </div>
 
-  <em class="muted" ng-hide="ctrl.userGroups.length > 0">
+  <em class="muted" ng-hide="ctrl.teams.length > 0">
     No User Groups found.
   </em>
 </div>

+ 6 - 6
public/app/features/org/specs/user_group_details_ctrl_specs.ts

@@ -1,8 +1,8 @@
 import '../user_group_details_ctrl';
 import {describe, beforeEach, it, expect, sinon, angularMocks} from 'test/lib/common';
-import UserGroupDetailsCtrl from '../user_group_details_ctrl';
+import TeamDetailsCtrl from '../user_group_details_ctrl';
 
-describe('UserGroupDetailsCtrl', () => {
+describe('TeamDetailsCtrl', () => {
 var ctx: any = {};
 var backendSrv = {
   searchUsers: sinon.stub().returns(Promise.resolve([])),
@@ -16,7 +16,7 @@ var backendSrv = {
   beforeEach(angularMocks.inject(($rootScope, $controller, $q) => {
     ctx.$q = $q;
     ctx.scope = $rootScope.$new();
-    ctx.ctrl = $controller(UserGroupDetailsCtrl, {
+    ctx.ctrl = $controller(TeamDetailsCtrl, {
       $scope: ctx.scope,
       backendSrv: backendSrv,
       $routeParams: {id: 1},
@@ -34,13 +34,13 @@ var backendSrv = {
     });
 
     it('should parse the result and save to db', () => {
-      expect(backendSrv.post.getCall(0).args[0]).to.eql('/api/user-groups/1/members');
+      expect(backendSrv.post.getCall(0).args[0]).to.eql('/api/teams/1/members');
       expect(backendSrv.post.getCall(0).args[1].userId).to.eql(2);
     });
 
     it('should refresh the list after saving.', () => {
-      expect(backendSrv.get.getCall(0).args[0]).to.eql('/api/user-groups/1');
-      expect(backendSrv.get.getCall(1).args[0]).to.eql('/api/user-groups/1/members');
+      expect(backendSrv.get.getCall(0).args[0]).to.eql('/api/teams/1');
+      expect(backendSrv.get.getCall(1).args[0]).to.eql('/api/teams/1/members');
     });
   });
 });

+ 18 - 18
public/app/features/org/user_group_details_ctrl.ts

@@ -2,9 +2,9 @@
 
 import coreModule from 'app/core/core_module';
 
-export default class UserGroupDetailsCtrl {
-  userGroup: UserGroup;
-  userGroupMembers: User[] = [];
+export default class TeamDetailsCtrl {
+  team: Team;
+  teamMembers: User[] = [];
   navModel: any;
 
   constructor(private $scope, private backendSrv, private $routeParams, navModelSrv) {
@@ -14,49 +14,49 @@ export default class UserGroupDetailsCtrl {
 
   get() {
     if (this.$routeParams && this.$routeParams.id) {
-      this.backendSrv.get(`/api/user-groups/${this.$routeParams.id}`)
+      this.backendSrv.get(`/api/teams/${this.$routeParams.id}`)
         .then(result => {
-          this.userGroup = result;
+          this.team = result;
         });
-      this.backendSrv.get(`/api/user-groups/${this.$routeParams.id}/members`)
+      this.backendSrv.get(`/api/teams/${this.$routeParams.id}/members`)
         .then(result => {
-          this.userGroupMembers = result;
+          this.teamMembers = result;
         });
     }
   }
 
-  removeUserGroupMember(userGroupMember: UserGroupMember) {
+  removeTeamMember(teamMember: TeamMember) {
     this.$scope.appEvent('confirm-modal', {
       title: 'Remove Member',
-      text: 'Are you sure you want to remove ' + userGroupMember.name + ' from this group?',
+      text: 'Are you sure you want to remove ' + teamMember.name + ' from this group?',
       yesText: "Remove",
       icon: "fa-warning",
       onConfirm: () => {
-        this.removeMemberConfirmed(userGroupMember);
+        this.removeMemberConfirmed(teamMember);
       }
     });
   }
 
-  removeMemberConfirmed(userGroupMember: UserGroupMember) {
-    this.backendSrv.delete(`/api/user-groups/${this.$routeParams.id}/members/${userGroupMember.userId}`)
+  removeMemberConfirmed(teamMember: TeamMember) {
+    this.backendSrv.delete(`/api/teams/${this.$routeParams.id}/members/${teamMember.userId}`)
       .then(this.get.bind(this));
   }
 
   update() {
-    if (!this.$scope.userGroupDetailsForm.$valid) { return; }
+    if (!this.$scope.teamDetailsForm.$valid) { return; }
 
-    this.backendSrv.put('/api/user-groups/' + this.userGroup.id, {name: this.userGroup.name});
+    this.backendSrv.put('/api/teams/' + this.team.id, {name: this.team.name});
   }
 
   userPicked(user) {
-    this.backendSrv.post(`/api/user-groups/${this.$routeParams.id}/members`, {userId: user.id}).then(() => {
+    this.backendSrv.post(`/api/teams/${this.$routeParams.id}/members`, {userId: user.id}).then(() => {
       this.$scope.$broadcast('user-picker-reset');
       this.get();
     });
   }
 }
 
-export interface UserGroup {
+export interface Team {
   id: number;
   name: string;
 }
@@ -68,10 +68,10 @@ export interface User {
   email: string;
 }
 
-export interface UserGroupMember {
+export interface TeamMember {
   userId: number;
   name: string;
 }
 
-coreModule.controller('UserGroupDetailsCtrl', UserGroupDetailsCtrl);
+coreModule.controller('TeamDetailsCtrl', TeamDetailsCtrl);
 

+ 12 - 12
public/app/features/org/user_groups_ctrl.ts

@@ -3,8 +3,8 @@
 import coreModule from 'app/core/core_module';
 import {appEvents} from 'app/core/core';
 
-export class UserGroupsCtrl {
-  userGroups: any;
+export class TeamsCtrl {
+  teams: any;
   pages = [];
   perPage = 50;
   page = 1;
@@ -20,9 +20,9 @@ export class UserGroupsCtrl {
   }
 
   get() {
-    this.backendSrv.get(`/api/user-groups/search?perpage=${this.perPage}&page=${this.page}&query=${this.query}`)
+    this.backendSrv.get(`/api/teams/search?perpage=${this.perPage}&page=${this.page}&query=${this.query}`)
       .then((result) => {
-        this.userGroups = result.userGroups;
+        this.teams = result.teams;
         this.page = result.page;
         this.perPage = result.perPage;
         this.totalPages = Math.ceil(result.totalCount / result.perPage);
@@ -40,29 +40,29 @@ export class UserGroupsCtrl {
     this.get();
   }
 
-  deleteUserGroup(userGroup) {
+  deleteTeam(team) {
     appEvents.emit('confirm-modal', {
       title: 'Delete',
-      text: 'Are you sure you want to delete User Group ' + userGroup.name + '?',
+      text: 'Are you sure you want to delete User Group ' + team.name + '?',
       yesText: "Delete",
       icon: "fa-warning",
       onConfirm: () => {
-        this.deleteUserGroupConfirmed(userGroup);
+        this.deleteTeamConfirmed(team);
       }
     });
   }
 
-  deleteUserGroupConfirmed(userGroup) {
-    this.backendSrv.delete('/api/user-groups/' + userGroup.id)
+  deleteTeamConfirmed(team) {
+    this.backendSrv.delete('/api/teams/' + team.id)
       .then(this.get.bind(this));
   }
 
-  openUserGroupModal() {
+  openTeamModal() {
     appEvents.emit('show-modal', {
-      templateHtml: '<create-user-group-modal></create-user-group-modal>',
+      templateHtml: '<create-team-modal></create-team-modal>',
       modalClass: 'modal--narrow'
     });
   }
 }
 
-coreModule.controller('UserGroupsCtrl', UserGroupsCtrl);
+coreModule.controller('TeamsCtrl', TeamsCtrl);

+ 2 - 2
public/app/plugins/panel/permissionlist/module.html

@@ -13,14 +13,14 @@
         </div>
       </div>
     </li>
-    <li class="card-item-wrapper" ng-repeat="permission in ctrl.userGroupPermissions">
+    <li class="card-item-wrapper" ng-repeat="permission in ctrl.teamPermissions">
         <div class="card-item card-item--alert">
           <div class="card-item-header">
             <div class="card-item-sub-name">{{permission.permissionName}}</div>
           </div>
           <div class="card-item-body">
             <div class="card-item-details">
-              <div class="card-item-notice">{{permission.userGroup}}</div>
+              <div class="card-item-notice">{{permission.team}}</div>
             </div>
           </div>
         </div>

+ 2 - 2
public/app/plugins/panel/permissionlist/module.ts

@@ -7,7 +7,7 @@ class PermissionListCtrl extends PanelCtrl {
   static templateUrl = 'module.html';
 
   userPermissions: any[];
-  userGroupPermissions: any[];
+  teamPermissions: any[];
   roles: any[];
 
   panelDefaults = {
@@ -48,7 +48,7 @@ class PermissionListCtrl extends PanelCtrl {
   return this.backendSrv.get(`/api/dashboards/id/${this.panel.folderId}/acl`)
     .then(result => {
       this.userPermissions = _.filter(result, p => { return p.userId > 0;});
-      this.userGroupPermissions = _.filter(result, p => { return p.userGroupId > 0;});
+      this.teamPermissions = _.filter(result, p => { return p.teamId > 0;});
       // this.roles = this.setRoles(result);
     });
   }

+ 1 - 1
public/sass/base/_icons.scss

@@ -51,7 +51,7 @@
   background-image: url('../img/icons_#{$theme-name}_theme/icon_notification_channels.svg');
 }
 
-.gicon-user-group {
+.gicon-team {
   background-image: url('../img/icons_#{$theme-name}_theme/icon_user_group.svg');
 }