diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6ba7b4a1aff..f6512314d65 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,7 @@
### WIP (in develop branch currently as its unstable or unfinished)
- Dashboard folders
-- User groups
+- Teams
- Dashboard permissions (on folder & dashboard level), permissions can be assigned to groups or individual users
- UX changes to nav & side menu
- New dashboard grid layout system
diff --git a/ROADMAP.md b/ROADMAP.md
index 4273d8df6a9..479c1933bc0 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -6,7 +6,7 @@ But it will give you an idea of our current vision and plan.
### Short term (1-4 months)
- Release Grafana v5
- - User groups
+ - Teams
- Dashboard folders
- Dashboard & folder permissions (assigned to users or groups)
- New Dashboard layout engine
diff --git a/pkg/api/api.go b/pkg/api/api.go
index b707dc17e21..a37f200f9d1 100644
--- a/pkg/api/api.go
+++ b/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.
diff --git a/pkg/api/dashboard_acl.go b/pkg/api/dashboard_acl.go
index c6847963d34..88cc74b9d1c 100644
--- a/pkg/api/dashboard_acl.go
+++ b/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(),
diff --git a/pkg/api/dashboard_acl_test.go b/pkg/api/dashboard_acl_test.go
index 162bac0aba8..e22e625dcf9 100644
--- a/pkg/api/dashboard_acl_test.go
+++ b/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)
}
diff --git a/pkg/api/dashboard_test.go b/pkg/api/dashboard_test.go
index 84ac01bce9a..1ddb32b4adc 100644
--- a/pkg/api/dashboard_test.go
+++ b/pkg/api/dashboard_test.go
@@ -56,8 +56,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
})
@@ -217,8 +217,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
})
diff --git a/pkg/api/dtos/acl.go b/pkg/api/dtos/acl.go
index 41f560e794b..6c74e68ce0d 100644
--- a/pkg/api/dtos/acl.go
+++ b/pkg/api/dtos/acl.go
@@ -9,8 +9,8 @@ type UpdateDashboardAclCommand struct {
}
type DashboardAclUpdateItem struct {
- UserId int64 `json:"userId"`
- UserGroupId int64 `json:"userGroupId"`
- Role *m.RoleType `json:"role,omitempty"`
- Permission m.PermissionType `json:"permission"`
+ UserId int64 `json:"userId"`
+ TeamId int64 `json:"teamId"`
+ Role *m.RoleType `json:"role,omitempty"`
+ Permission m.PermissionType `json:"permission"`
}
diff --git a/pkg/api/index.go b/pkg/api/index.go
index e179828d2f7..862e9af0519 100644
--- a/pkg/api/index.go
+++ b/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",
diff --git a/pkg/api/team.go b/pkg/api/team.go
new file mode 100644
index 00000000000..31e465d3232
--- /dev/null
+++ b/pkg/api/team.go
@@ -0,0 +1,92 @@
+package api
+
+import (
+ "github.com/grafana/grafana/pkg/bus"
+ "github.com/grafana/grafana/pkg/middleware"
+ m "github.com/grafana/grafana/pkg/models"
+ "github.com/grafana/grafana/pkg/util"
+)
+
+// 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.ErrTeamNameTaken {
+ return ApiError(409, "Team name taken", err)
+ }
+ return ApiError(500, "Failed to create Team", err)
+ }
+
+ return Json(200, &util.DynMap{
+ "teamId": cmd.Result.Id,
+ "message": "Team created",
+ })
+}
+
+// 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.ErrTeamNameTaken {
+ return ApiError(400, "Team name taken", err)
+ }
+ return ApiError(500, "Failed to update Team", err)
+ }
+
+ return ApiSuccess("Team updated")
+}
+
+// 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 Team", err)
+ }
+ return ApiSuccess("Team deleted")
+}
+
+// GET /api/teams/search
+func SearchTeams(c *middleware.Context) Response {
+ perPage := c.QueryInt("perpage")
+ if perPage <= 0 {
+ perPage = 1000
+ }
+ page := c.QueryInt("page")
+ if page < 1 {
+ page = 1
+ }
+
+ query := m.SearchTeamsQuery{
+ Query: c.Query("query"),
+ Name: c.Query("name"),
+ Page: page,
+ Limit: perPage,
+ OrgId: c.OrgId,
+ }
+
+ if err := bus.Dispatch(&query); err != nil {
+ return ApiError(500, "Failed to search Teams", err)
+ }
+
+ query.Result.Page = page
+ query.Result.PerPage = perPage
+
+ return Json(200, query.Result)
+}
+
+// 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.ErrTeamNotFound {
+ return ApiError(404, "Team not found", err)
+ }
+
+ return ApiError(500, "Failed to get Team", err)
+ }
+
+ return Json(200, &query.Result)
+}
diff --git a/pkg/api/team_members.go b/pkg/api/team_members.go
new file mode 100644
index 00000000000..0999c9573a5
--- /dev/null
+++ b/pkg/api/team_members.go
@@ -0,0 +1,44 @@
+package api
+
+import (
+ "github.com/grafana/grafana/pkg/bus"
+ "github.com/grafana/grafana/pkg/middleware"
+ m "github.com/grafana/grafana/pkg/models"
+ "github.com/grafana/grafana/pkg/util"
+)
+
+// 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 Team Members", err)
+ }
+
+ return Json(200, query.Result)
+}
+
+// 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.ErrTeamMemberAlreadyAdded {
+ return ApiError(400, "User is already added to this team", err)
+ }
+ return ApiError(500, "Failed to add Member to Team", err)
+ }
+
+ return Json(200, &util.DynMap{
+ "message": "Member added to Team",
+ })
+}
+
+// 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("Team Member removed")
+}
diff --git a/pkg/api/user_group_test.go b/pkg/api/team_test.go
similarity index 61%
rename from pkg/api/user_group_test.go
rename to pkg/api/team_test.go
index 730461ac8e8..535d24ff553 100644
--- a/pkg/api/user_group_test.go
+++ b/pkg/api/team_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)
diff --git a/pkg/api/user_group.go b/pkg/api/user_group.go
deleted file mode 100644
index 8371881aecb..00000000000
--- a/pkg/api/user_group.go
+++ /dev/null
@@ -1,92 +0,0 @@
-package api
-
-import (
- "github.com/grafana/grafana/pkg/bus"
- "github.com/grafana/grafana/pkg/middleware"
- m "github.com/grafana/grafana/pkg/models"
- "github.com/grafana/grafana/pkg/util"
-)
-
-// POST /api/user-groups
-func CreateUserGroup(c *middleware.Context, cmd m.CreateUserGroupCommand) Response {
- cmd.OrgId = c.OrgId
- if err := bus.Dispatch(&cmd); err != nil {
- if err == m.ErrUserGroupNameTaken {
- return ApiError(409, "User Group name taken", err)
- }
- return ApiError(500, "Failed to create User Group", err)
- }
-
- return Json(200, &util.DynMap{
- "userGroupId": cmd.Result.Id,
- "message": "User Group created",
- })
-}
-
-// PUT /api/user-groups/:userGroupId
-func UpdateUserGroup(c *middleware.Context, cmd m.UpdateUserGroupCommand) Response {
- cmd.Id = c.ParamsInt64(":userGroupId")
- if err := bus.Dispatch(&cmd); err != nil {
- if err == m.ErrUserGroupNameTaken {
- return ApiError(400, "User Group name taken", err)
- }
- return ApiError(500, "Failed to update User Group", err)
- }
-
- return ApiSuccess("User Group 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)
- }
- return ApiError(500, "Failed to update User Group", err)
- }
- return ApiSuccess("User Group deleted")
-}
-
-// GET /api/user-groups/search
-func SearchUserGroups(c *middleware.Context) Response {
- perPage := c.QueryInt("perpage")
- if perPage <= 0 {
- perPage = 1000
- }
- page := c.QueryInt("page")
- if page < 1 {
- page = 1
- }
-
- query := m.SearchUserGroupsQuery{
- Query: c.Query("query"),
- Name: c.Query("name"),
- Page: page,
- Limit: perPage,
- OrgId: c.OrgId,
- }
-
- if err := bus.Dispatch(&query); err != nil {
- return ApiError(500, "Failed to search User Groups", err)
- }
-
- query.Result.Page = page
- query.Result.PerPage = perPage
-
- return Json(200, query.Result)
-}
-
-// GET /api/user-groups/:userGroupId
-func GetUserGroupById(c *middleware.Context) Response {
- query := m.GetUserGroupByIdQuery{Id: c.ParamsInt64(":userGroupId")}
-
- if err := bus.Dispatch(&query); err != nil {
- if err == m.ErrUserGroupNotFound {
- return ApiError(404, "User Group not found", err)
- }
-
- return ApiError(500, "Failed to get User Group", err)
- }
-
- return Json(200, &query.Result)
-}
diff --git a/pkg/api/user_group_members.go b/pkg/api/user_group_members.go
deleted file mode 100644
index 09f3def59bd..00000000000
--- a/pkg/api/user_group_members.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package api
-
-import (
- "github.com/grafana/grafana/pkg/bus"
- "github.com/grafana/grafana/pkg/middleware"
- m "github.com/grafana/grafana/pkg/models"
- "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")}
-
- if err := bus.Dispatch(&query); err != nil {
- return ApiError(500, "Failed to get User Group 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")
- 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)
- }
- return ApiError(500, "Failed to add Member to User Group", err)
- }
-
- return Json(200, &util.DynMap{
- "message": "Member added to User Group",
- })
-}
-
-// 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)
- }
- return ApiSuccess("User Group Member removed")
-}
diff --git a/pkg/models/dashboard_acl.go b/pkg/models/dashboard_acl.go
index 9b65ec8eb33..fa7ad00de7f 100644
--- a/pkg/models/dashboard_acl.go
+++ b/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.")
)
@@ -34,10 +34,10 @@ type DashboardAcl struct {
OrgId int64
DashboardId int64
- UserId int64
- UserGroupId int64
- Role *RoleType // pointer to be nullable
- Permission PermissionType
+ UserId int64
+ TeamId int64
+ Role *RoleType // pointer to be nullable
+ Permission PermissionType
Created time.Time
Updated time.Time
@@ -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
diff --git a/pkg/models/team.go b/pkg/models/team.go
new file mode 100644
index 00000000000..a8f53e81a1e
--- /dev/null
+++ b/pkg/models/team.go
@@ -0,0 +1,68 @@
+package models
+
+import (
+ "errors"
+ "time"
+)
+
+// Typed errors
+var (
+ ErrTeamNotFound = errors.New("Team not found")
+ ErrTeamNameTaken = errors.New("Team name is taken")
+)
+
+// Team model
+type Team struct {
+ Id int64 `json:"id"`
+ OrgId int64 `json:"orgId"`
+ Name string `json:"name"`
+
+ Created time.Time `json:"created"`
+ Updated time.Time `json:"updated"`
+}
+
+// ---------------------
+// COMMANDS
+
+type CreateTeamCommand struct {
+ Name string `json:"name" binding:"Required"`
+ OrgId int64 `json:"-"`
+
+ Result Team `json:"-"`
+}
+
+type UpdateTeamCommand struct {
+ Id int64
+ Name string
+}
+
+type DeleteTeamCommand struct {
+ Id int64
+}
+
+type GetTeamByIdQuery struct {
+ Id int64
+ Result *Team
+}
+
+type GetTeamsByUserQuery struct {
+ UserId int64 `json:"userId"`
+ Result []*Team `json:"teams"`
+}
+
+type SearchTeamsQuery struct {
+ Query string
+ Name string
+ Limit int
+ Page int
+ OrgId int64
+
+ Result SearchTeamQueryResult
+}
+
+type SearchTeamQueryResult struct {
+ TotalCount int64 `json:"totalCount"`
+ Teams []*Team `json:"teams"`
+ Page int `json:"page"`
+ PerPage int `json:"perPage"`
+}
diff --git a/pkg/models/team_member.go b/pkg/models/team_member.go
new file mode 100644
index 00000000000..71e5cd4ba12
--- /dev/null
+++ b/pkg/models/team_member.go
@@ -0,0 +1,55 @@
+package models
+
+import (
+ "errors"
+ "time"
+)
+
+// Typed errors
+var (
+ ErrTeamMemberAlreadyAdded = errors.New("User is already added to this team")
+)
+
+// TeamMember model
+type TeamMember struct {
+ Id int64
+ OrgId int64
+ TeamId int64
+ UserId int64
+
+ Created time.Time
+ Updated time.Time
+}
+
+// ---------------------
+// COMMANDS
+
+type AddTeamMemberCommand struct {
+ UserId int64 `json:"userId" binding:"Required"`
+ OrgId int64 `json:"-"`
+ TeamId int64 `json:"-"`
+}
+
+type RemoveTeamMemberCommand struct {
+ UserId int64
+ TeamId int64
+}
+
+// ----------------------
+// QUERIES
+
+type GetTeamMembersQuery struct {
+ TeamId int64
+ Result []*TeamMemberDTO
+}
+
+// ----------------------
+// Projections and DTOs
+
+type TeamMemberDTO struct {
+ OrgId int64 `json:"orgId"`
+ TeamId int64 `json:"teamId"`
+ UserId int64 `json:"userId"`
+ Email string `json:"email"`
+ Login string `json:"login"`
+}
diff --git a/pkg/models/user_group.go b/pkg/models/user_group.go
deleted file mode 100644
index e5e361526d4..00000000000
--- a/pkg/models/user_group.go
+++ /dev/null
@@ -1,68 +0,0 @@
-package models
-
-import (
- "errors"
- "time"
-)
-
-// Typed errors
-var (
- ErrUserGroupNotFound = errors.New("User Group not found")
- ErrUserGroupNameTaken = errors.New("User Group name is taken")
-)
-
-// UserGroup model
-type UserGroup struct {
- Id int64 `json:"id"`
- OrgId int64 `json:"orgId"`
- Name string `json:"name"`
-
- Created time.Time `json:"created"`
- Updated time.Time `json:"updated"`
-}
-
-// ---------------------
-// COMMANDS
-
-type CreateUserGroupCommand struct {
- Name string `json:"name" binding:"Required"`
- OrgId int64 `json:"-"`
-
- Result UserGroup `json:"-"`
-}
-
-type UpdateUserGroupCommand struct {
- Id int64
- Name string
-}
-
-type DeleteUserGroupCommand struct {
- Id int64
-}
-
-type GetUserGroupByIdQuery struct {
- Id int64
- Result *UserGroup
-}
-
-type GetUserGroupsByUserQuery struct {
- UserId int64 `json:"userId"`
- Result []*UserGroup `json:"userGroups"`
-}
-
-type SearchUserGroupsQuery struct {
- Query string
- Name string
- Limit int
- Page int
- OrgId int64
-
- Result SearchUserGroupQueryResult
-}
-
-type SearchUserGroupQueryResult struct {
- TotalCount int64 `json:"totalCount"`
- UserGroups []*UserGroup `json:"userGroups"`
- Page int `json:"page"`
- PerPage int `json:"perPage"`
-}
diff --git a/pkg/models/user_group_member.go b/pkg/models/user_group_member.go
deleted file mode 100644
index 23ddd84601b..00000000000
--- a/pkg/models/user_group_member.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package models
-
-import (
- "errors"
- "time"
-)
-
-// Typed errors
-var (
- ErrUserGroupMemberAlreadyAdded = errors.New("User is already added to this user group")
-)
-
-// UserGroupMember model
-type UserGroupMember struct {
- Id int64
- OrgId int64
- UserGroupId int64
- UserId int64
-
- Created time.Time
- Updated time.Time
-}
-
-// ---------------------
-// COMMANDS
-
-type AddUserGroupMemberCommand struct {
- UserId int64 `json:"userId" binding:"Required"`
- OrgId int64 `json:"-"`
- UserGroupId int64 `json:"-"`
-}
-
-type RemoveUserGroupMemberCommand struct {
- UserId int64
- UserGroupId int64
-}
-
-// ----------------------
-// QUERIES
-
-type GetUserGroupMembersQuery struct {
- UserGroupId int64
- Result []*UserGroupMemberDTO
-}
-
-// ----------------------
-// Projections and DTOs
-
-type UserGroupMemberDTO struct {
- OrgId int64 `json:"orgId"`
- UserGroupId int64 `json:"userGroupId"`
- UserId int64 `json:"userId"`
- Email string `json:"email"`
- Login string `json:"login"`
-}
diff --git a/pkg/services/guardian/guardian.go b/pkg/services/guardian/guardian.go
index a05213e87c8..72fe00a4ceb 100644
--- a/pkg/services/guardian/guardian.go
+++ b/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
diff --git a/pkg/services/sqlstore/dashboard_acl.go b/pkg/services/sqlstore/dashboard_acl.go
index 8d3a2455f1f..3ab0361d175 100644
--- a/pkg/services/sqlstore/dashboard_acl.go
+++ b/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
diff --git a/pkg/services/sqlstore/dashboard_acl_test.go b/pkg/services/sqlstore/dashboard_acl_test.go
index 55f4b24808b..bb6363883d6 100644
--- a/pkg/services/sqlstore/dashboard_acl_test.go
+++ b/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)
})
})
diff --git a/pkg/services/sqlstore/migrations/dashboard_acl.go b/pkg/services/sqlstore/migrations/dashboard_acl.go
index af85e48af0d..5d92f721d38 100644
--- a/pkg/services/sqlstore/migrations/dashboard_acl.go
+++ b/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},
},
}
diff --git a/pkg/services/sqlstore/migrations/migrations.go b/pkg/services/sqlstore/migrations/migrations.go
index 3cd4f4399fb..8e9268779ef 100644
--- a/pkg/services/sqlstore/migrations/migrations.go
+++ b/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)
}
diff --git a/pkg/services/sqlstore/migrations/user_group_mig.go b/pkg/services/sqlstore/migrations/team_mig.go
similarity index 50%
rename from pkg/services/sqlstore/migrations/user_group_mig.go
rename to pkg/services/sqlstore/migrations/team_mig.go
index 589def0c504..cc479097f9b 100644
--- a/pkg/services/sqlstore/migrations/user_group_mig.go
+++ b/pkg/services/sqlstore/migrations/team_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]))
}
diff --git a/pkg/services/sqlstore/org_users.go b/pkg/services/sqlstore/org_users.go
index 2acb623bd34..2c2a51fd362 100644
--- a/pkg/services/sqlstore/org_users.go
+++ b/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 {
diff --git a/pkg/services/sqlstore/search_builder.go b/pkg/services/sqlstore/search_builder.go
index 99bde21d171..6a5e8e60b54 100644
--- a/pkg/services/sqlstore/search_builder.go
+++ b/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
diff --git a/pkg/services/sqlstore/team.go b/pkg/services/sqlstore/team.go
new file mode 100644
index 00000000000..2bc04bad0c6
--- /dev/null
+++ b/pkg/services/sqlstore/team.go
@@ -0,0 +1,233 @@
+package sqlstore
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/grafana/grafana/pkg/bus"
+ m "github.com/grafana/grafana/pkg/models"
+)
+
+func init() {
+ 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 CreateTeam(cmd *m.CreateTeamCommand) error {
+ return inTransaction(func(sess *DBSession) error {
+
+ if isNameTaken, err := isTeamNameTaken(cmd.Name, 0, sess); err != nil {
+ return err
+ } else if isNameTaken {
+ return m.ErrTeamNameTaken
+ }
+
+ team := m.Team{
+ Name: cmd.Name,
+ OrgId: cmd.OrgId,
+ Created: time.Now(),
+ Updated: time.Now(),
+ }
+
+ _, err := sess.Insert(&team)
+
+ cmd.Result = team
+
+ return err
+ })
+}
+
+func UpdateTeam(cmd *m.UpdateTeamCommand) error {
+ return inTransaction(func(sess *DBSession) error {
+
+ if isNameTaken, err := isTeamNameTaken(cmd.Name, cmd.Id, sess); err != nil {
+ return err
+ } else if isNameTaken {
+ return m.ErrTeamNameTaken
+ }
+
+ team := m.Team{
+ Name: cmd.Name,
+ Updated: time.Now(),
+ }
+
+ affectedRows, err := sess.Id(cmd.Id).Update(&team)
+
+ if err != nil {
+ return err
+ }
+
+ if affectedRows == 0 {
+ return m.ErrTeamNotFound
+ }
+
+ return nil
+ })
+}
+
+func DeleteTeam(cmd *m.DeleteTeamCommand) error {
+ return inTransaction(func(sess *DBSession) error {
+ if res, err := sess.Query("SELECT 1 from team WHERE id=?", cmd.Id); err != nil {
+ return err
+ } else if len(res) != 1 {
+ return m.ErrTeamNotFound
+ }
+
+ deletes := []string{
+ "DELETE FROM team_member WHERE team_id = ?",
+ "DELETE FROM team WHERE id = ?",
+ "DELETE FROM dashboard_acl WHERE team_id = ?",
+ }
+
+ for _, sql := range deletes {
+ _, err := sess.Exec(sql, cmd.Id)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+ })
+}
+
+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 != team.Id {
+ return true, nil
+ }
+
+ return false, nil
+}
+
+func SearchTeams(query *m.SearchTeamsQuery) error {
+ query.Result = m.SearchTeamQueryResult{
+ Teams: make([]*m.Team, 0),
+ }
+ queryWithWildcards := "%" + query.Query + "%"
+
+ sess := x.Table("team")
+ sess.Where("org_id=?", query.OrgId)
+
+ if query.Query != "" {
+ sess.Where("name LIKE ?", queryWithWildcards)
+ }
+ if query.Name != "" {
+ sess.Where("name=?", query.Name)
+ }
+ sess.Asc("name")
+
+ offset := query.Limit * (query.Page - 1)
+ sess.Limit(query.Limit, offset)
+ sess.Cols("id", "name")
+ if err := sess.Find(&query.Result.Teams); err != nil {
+ return err
+ }
+
+ team := m.Team{}
+
+ countSess := x.Table("team")
+ if query.Query != "" {
+ countSess.Where("name LIKE ?", queryWithWildcards)
+ }
+ if query.Name != "" {
+ countSess.Where("name=?", query.Name)
+ }
+ count, err := countSess.Count(&team)
+ query.Result.TotalCount = count
+
+ return err
+}
+
+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.ErrTeamNotFound
+ }
+
+ query.Result = &team
+ return nil
+}
+
+func GetTeamsByUser(query *m.GetTeamsByUserQuery) error {
+ query.Result = make([]*m.Team, 0)
+
+ 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 {
+ return err
+ }
+
+ return nil
+}
+
+func AddTeamMember(cmd *m.AddTeamMemberCommand) error {
+ return inTransaction(func(sess *DBSession) error {
+ 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.ErrTeamMemberAlreadyAdded
+ }
+
+ if res, err := sess.Query("SELECT 1 from team WHERE id=?", cmd.TeamId); err != nil {
+ return err
+ } else if len(res) != 1 {
+ return m.ErrTeamNotFound
+ }
+
+ entity := m.TeamMember{
+ OrgId: cmd.OrgId,
+ TeamId: cmd.TeamId,
+ UserId: cmd.UserId,
+ Created: time.Now(),
+ Updated: time.Now(),
+ }
+
+ _, err := sess.Insert(&entity)
+ return err
+ })
+}
+
+func RemoveTeamMember(cmd *m.RemoveTeamMemberCommand) error {
+ return inTransaction(func(sess *DBSession) error {
+ 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
+ }
+
+ return err
+ })
+}
+
+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)
+ return err
+}
diff --git a/pkg/services/sqlstore/team_test.go b/pkg/services/sqlstore/team_test.go
new file mode 100644
index 00000000000..4a099db14ff
--- /dev/null
+++ b/pkg/services/sqlstore/team_test.go
@@ -0,0 +1,114 @@
+package sqlstore
+
+import (
+ "fmt"
+ "testing"
+
+ . "github.com/smartystreets/goconvey/convey"
+
+ m "github.com/grafana/grafana/pkg/models"
+)
+
+func TestTeamCommandsAndQueries(t *testing.T) {
+
+ Convey("Testing Team commands & queries", t, func() {
+ InitTestDB(t)
+
+ Convey("Given saved users and two teams", func() {
+ var userIds []int64
+ for i := 0; i < 5; i++ {
+ userCmd := &m.CreateUserCommand{
+ Email: fmt.Sprint("user", i, "@test.com"),
+ Name: fmt.Sprint("user", i),
+ Login: fmt.Sprint("loginuser", i),
+ }
+ err := CreateUser(userCmd)
+ So(err, ShouldBeNil)
+ userIds = append(userIds, userCmd.Result.Id)
+ }
+
+ group1 := m.CreateTeamCommand{Name: "group1 name"}
+ group2 := m.CreateTeamCommand{Name: "group2 name"}
+
+ err := CreateTeam(&group1)
+ So(err, ShouldBeNil)
+ err = CreateTeam(&group2)
+ So(err, ShouldBeNil)
+
+ 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)
+
+ team1 := query.Result.Teams[0]
+ So(team1.Name, ShouldEqual, "group1 name")
+
+ err = AddTeamMember(&m.AddTeamMemberCommand{OrgId: 1, TeamId: team1.Id, UserId: userIds[0]})
+ So(err, ShouldBeNil)
+
+ q1 := &m.GetTeamMembersQuery{TeamId: team1.Id}
+ err = GetTeamMembers(q1)
+ So(err, ShouldBeNil)
+ So(q1.Result[0].TeamId, ShouldEqual, team1.Id)
+ So(q1.Result[0].Login, ShouldEqual, "loginuser0")
+ })
+
+ 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.Teams), ShouldEqual, 2)
+ So(query.Result.TotalCount, ShouldEqual, 2)
+
+ query2 := &m.SearchTeamsQuery{Query: ""}
+ err = SearchTeams(query2)
+ So(err, ShouldBeNil)
+ So(len(query2.Result.Teams), ShouldEqual, 2)
+ })
+
+ Convey("Should be able to return all teams a user is member of", func() {
+ groupId := group2.Result.Id
+ err := AddTeamMember(&m.AddTeamMemberCommand{OrgId: 1, TeamId: groupId, UserId: userIds[0]})
+
+ 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 = RemoveTeamMember(&m.RemoveTeamMemberCommand{TeamId: group1.Result.Id, UserId: userIds[0]})
+ So(err, ShouldBeNil)
+
+ 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 := AddTeamMember(&m.AddTeamMemberCommand{OrgId: 1, TeamId: groupId, UserId: userIds[1]})
+ So(err, ShouldBeNil)
+ 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, TeamId: groupId})
+
+ err = DeleteTeam(&m.DeleteTeamCommand{Id: groupId})
+ So(err, ShouldBeNil)
+
+ query := &m.GetTeamByIdQuery{Id: groupId}
+ err = GetTeamById(query)
+ So(err, ShouldEqual, m.ErrTeamNotFound)
+
+ permQuery := &m.GetDashboardAclInfoListQuery{DashboardId: 1, OrgId: 1}
+ err = GetDashboardAclInfoList(permQuery)
+ So(err, ShouldBeNil)
+
+ So(len(permQuery.Result), ShouldEqual, 0)
+ })
+ })
+ })
+}
diff --git a/pkg/services/sqlstore/user.go b/pkg/services/sqlstore/user.go
index 669f655a159..73ea07f031f 100644
--- a/pkg/services/sqlstore/user.go
+++ b/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 {
diff --git a/pkg/services/sqlstore/user_group.go b/pkg/services/sqlstore/user_group.go
deleted file mode 100644
index c90141310ab..00000000000
--- a/pkg/services/sqlstore/user_group.go
+++ /dev/null
@@ -1,233 +0,0 @@
-package sqlstore
-
-import (
- "fmt"
- "time"
-
- "github.com/grafana/grafana/pkg/bus"
- m "github.com/grafana/grafana/pkg/models"
-)
-
-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)
-}
-
-func CreateUserGroup(cmd *m.CreateUserGroupCommand) error {
- return inTransaction(func(sess *DBSession) error {
-
- if isNameTaken, err := isUserGroupNameTaken(cmd.Name, 0, sess); err != nil {
- return err
- } else if isNameTaken {
- return m.ErrUserGroupNameTaken
- }
-
- userGroup := m.UserGroup{
- Name: cmd.Name,
- OrgId: cmd.OrgId,
- Created: time.Now(),
- Updated: time.Now(),
- }
-
- _, err := sess.Insert(&userGroup)
-
- cmd.Result = userGroup
-
- return err
- })
-}
-
-func UpdateUserGroup(cmd *m.UpdateUserGroupCommand) error {
- return inTransaction(func(sess *DBSession) error {
-
- if isNameTaken, err := isUserGroupNameTaken(cmd.Name, cmd.Id, sess); err != nil {
- return err
- } else if isNameTaken {
- return m.ErrUserGroupNameTaken
- }
-
- userGroup := m.UserGroup{
- Name: cmd.Name,
- Updated: time.Now(),
- }
-
- affectedRows, err := sess.Id(cmd.Id).Update(&userGroup)
-
- if err != nil {
- return err
- }
-
- if affectedRows == 0 {
- return m.ErrUserGroupNotFound
- }
-
- return nil
- })
-}
-
-func DeleteUserGroup(cmd *m.DeleteUserGroupCommand) error {
- return inTransaction(func(sess *DBSession) error {
- if res, err := sess.Query("SELECT 1 from user_group WHERE id=?", cmd.Id); err != nil {
- return err
- } else if len(res) != 1 {
- return m.ErrUserGroupNotFound
- }
-
- 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 = ?",
- }
-
- for _, sql := range deletes {
- _, err := sess.Exec(sql, cmd.Id)
- if err != nil {
- return err
- }
- }
- return nil
- })
-}
-
-func isUserGroupNameTaken(name string, existingId int64, sess *DBSession) (bool, error) {
- var userGroup m.UserGroup
- exists, err := sess.Where("name=?", name).Get(&userGroup)
-
- if err != nil {
- return false, nil
- }
-
- if exists && existingId != userGroup.Id {
- return true, nil
- }
-
- return false, nil
-}
-
-func SearchUserGroups(query *m.SearchUserGroupsQuery) error {
- query.Result = m.SearchUserGroupQueryResult{
- UserGroups: make([]*m.UserGroup, 0),
- }
- queryWithWildcards := "%" + query.Query + "%"
-
- sess := x.Table("user_group")
- sess.Where("org_id=?", query.OrgId)
-
- if query.Query != "" {
- sess.Where("name LIKE ?", queryWithWildcards)
- }
- if query.Name != "" {
- sess.Where("name=?", query.Name)
- }
- sess.Asc("name")
-
- offset := query.Limit * (query.Page - 1)
- sess.Limit(query.Limit, offset)
- sess.Cols("id", "name")
- if err := sess.Find(&query.Result.UserGroups); err != nil {
- return err
- }
-
- userGroup := m.UserGroup{}
-
- countSess := x.Table("user_group")
- if query.Query != "" {
- countSess.Where("name LIKE ?", queryWithWildcards)
- }
- if query.Name != "" {
- countSess.Where("name=?", query.Name)
- }
- count, err := countSess.Count(&userGroup)
- query.Result.TotalCount = count
-
- return err
-}
-
-func GetUserGroupById(query *m.GetUserGroupByIdQuery) error {
- var userGroup m.UserGroup
- exists, err := x.Id(query.Id).Get(&userGroup)
- if err != nil {
- return err
- }
-
- if !exists {
- return m.ErrUserGroupNotFound
- }
-
- query.Result = &userGroup
- return nil
-}
-
-func GetUserGroupsByUser(query *m.GetUserGroupsByUserQuery) error {
- query.Result = make([]*m.UserGroup, 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)
-
- err := sess.Find(&query.Result)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func AddUserGroupMember(cmd *m.AddUserGroupMemberCommand) 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 {
- return err
- } else if len(res) == 1 {
- return m.ErrUserGroupMemberAlreadyAdded
- }
-
- if res, err := sess.Query("SELECT 1 from user_group WHERE id=?", cmd.UserGroupId); err != nil {
- return err
- } else if len(res) != 1 {
- return m.ErrUserGroupNotFound
- }
-
- entity := m.UserGroupMember{
- OrgId: cmd.OrgId,
- UserGroupId: cmd.UserGroupId,
- UserId: cmd.UserId,
- Created: time.Now(),
- Updated: time.Now(),
- }
-
- _, err := sess.Insert(&entity)
- return err
- })
-}
-
-func RemoveUserGroupMember(cmd *m.RemoveUserGroupMemberCommand) 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)
- if err != nil {
- return err
- }
-
- return err
- })
-}
-
-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")
- sess.Asc("user.login", "user.email")
-
- err := sess.Find(&query.Result)
- return err
-}
diff --git a/pkg/services/sqlstore/user_group_test.go b/pkg/services/sqlstore/user_group_test.go
deleted file mode 100644
index 76056f98837..00000000000
--- a/pkg/services/sqlstore/user_group_test.go
+++ /dev/null
@@ -1,114 +0,0 @@
-package sqlstore
-
-import (
- "fmt"
- "testing"
-
- . "github.com/smartystreets/goconvey/convey"
-
- m "github.com/grafana/grafana/pkg/models"
-)
-
-func TestUserGroupCommandsAndQueries(t *testing.T) {
-
- Convey("Testing User Group commands & queries", t, func() {
- InitTestDB(t)
-
- Convey("Given saved users and two user groups", func() {
- var userIds []int64
- for i := 0; i < 5; i++ {
- userCmd := &m.CreateUserCommand{
- Email: fmt.Sprint("user", i, "@test.com"),
- Name: fmt.Sprint("user", i),
- Login: fmt.Sprint("loginuser", i),
- }
- err := CreateUser(userCmd)
- So(err, ShouldBeNil)
- userIds = append(userIds, userCmd.Result.Id)
- }
-
- group1 := m.CreateUserGroupCommand{Name: "group1 name"}
- group2 := m.CreateUserGroupCommand{Name: "group2 name"}
-
- err := CreateUserGroup(&group1)
- So(err, ShouldBeNil)
- err = CreateUserGroup(&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)
- So(err, ShouldBeNil)
- So(query.Page, ShouldEqual, 1)
-
- userGroup1 := query.Result.UserGroups[0]
- So(userGroup1.Name, ShouldEqual, "group1 name")
-
- err = AddUserGroupMember(&m.AddUserGroupMemberCommand{OrgId: 1, UserGroupId: userGroup1.Id, UserId: userIds[0]})
- So(err, ShouldBeNil)
-
- q1 := &m.GetUserGroupMembersQuery{UserGroupId: userGroup1.Id}
- err = GetUserGroupMembers(q1)
- So(err, ShouldBeNil)
- So(q1.Result[0].UserGroupId, ShouldEqual, userGroup1.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)
- So(err, ShouldBeNil)
- So(len(query.Result.UserGroups), ShouldEqual, 2)
- So(query.Result.TotalCount, ShouldEqual, 2)
-
- query2 := &m.SearchUserGroupsQuery{Query: ""}
- err = SearchUserGroups(query2)
- So(err, ShouldBeNil)
- So(len(query2.Result.UserGroups), ShouldEqual, 2)
- })
-
- Convey("Should be able to return all user groups a user is member of", func() {
- groupId := group2.Result.Id
- err := AddUserGroupMember(&m.AddUserGroupMemberCommand{OrgId: 1, UserGroupId: groupId, UserId: userIds[0]})
-
- query := &m.GetUserGroupsByUserQuery{UserId: userIds[0]}
- err = GetUserGroupsByUser(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]})
- So(err, ShouldBeNil)
-
- q1 := &m.GetUserGroupMembersQuery{UserGroupId: group1.Result.Id}
- err = GetUserGroupMembers(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]})
- So(err, ShouldBeNil)
- err = AddUserGroupMember(&m.AddUserGroupMemberCommand{OrgId: 1, UserGroupId: groupId, UserId: userIds[2]})
- So(err, ShouldBeNil)
- err = SetDashboardAcl(&m.SetDashboardAclCommand{DashboardId: 1, OrgId: 1, Permission: m.PERMISSION_EDIT, UserGroupId: groupId})
-
- err = DeleteUserGroup(&m.DeleteUserGroupCommand{Id: groupId})
- So(err, ShouldBeNil)
-
- query := &m.GetUserGroupByIdQuery{Id: groupId}
- err = GetUserGroupById(query)
- So(err, ShouldEqual, m.ErrUserGroupNotFound)
-
- permQuery := &m.GetDashboardAclInfoListQuery{DashboardId: 1, OrgId: 1}
- err = GetDashboardAclInfoList(permQuery)
- So(err, ShouldBeNil)
-
- So(len(permQuery.Result), ShouldEqual, 0)
- })
- })
- })
-}
diff --git a/public/app/core/components/user_group_picker.ts b/public/app/core/components/team_picker.ts
similarity index 67%
rename from public/app/core/components/user_group_picker.ts
rename to public/app/core/components/team_picker.ts
index f9c91a7f0e6..2bf6b3c83b5 100644
--- a/public/app/core/components/user_group_picker.ts
+++ b/public/app/core/components/team_picker.ts
@@ -10,9 +10,9 @@ const template = `
`;
-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);
diff --git a/public/app/core/core.ts b/public/app/core/core.ts
index 5a9b4265f8c..f43f4df3110 100644
--- a/public/app/core/core.ts
+++ b/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/team_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,
diff --git a/public/app/core/routes/routes.ts b/public/app/core/routes/routes.ts
index a068cd4a789..f2527f14e16 100644
--- a/public/app/core/routes/routes.ts
+++ b/public/app/core/routes/routes.ts
@@ -109,15 +109,15 @@ function setupAngularRoutes($routeProvider, $locationProvider) {
controller : 'OrgApiKeysCtrl',
resolve: loadOrgBundle,
})
- .when('/org/user-groups', {
- templateUrl: 'public/app/features/org/partials/user_groups.html',
- controller : 'UserGroupsCtrl',
+ .when('/org/teams', {
+ templateUrl: 'public/app/features/org/partials/teams.html',
+ controller : 'TeamsCtrl',
controllerAs: 'ctrl',
resolve: loadOrgBundle,
})
- .when('/org/user-groups/edit/:id', {
- templateUrl: 'public/app/features/org/partials/user_group_details.html',
- controller : 'UserGroupDetailsCtrl',
+ .when('/org/teams/edit/:id', {
+ templateUrl: 'public/app/features/org/partials/team_details.html',
+ controller : 'TeamDetailsCtrl',
controllerAs: 'ctrl',
resolve: loadOrgBundle,
})
diff --git a/public/app/features/dashboard/acl/acl.html b/public/app/features/dashboard/acl/acl.html
index 8dfa86f958a..aa73f607684 100644
--- a/public/app/features/dashboard/acl/acl.html
+++ b/public/app/features/dashboard/acl/acl.html
@@ -52,7 +52,7 @@