Commit fad1d4cf by Torkel Ödegaard

feat(organization): added update org address to http api and to org details…

feat(organization): added update org address to http api and to org details settings view, closes #2672
parent daf64421
...@@ -93,7 +93,8 @@ func Register(r *macaron.Macaron) { ...@@ -93,7 +93,8 @@ func Register(r *macaron.Macaron) {
// current org // current org
r.Group("/org", func() { r.Group("/org", func() {
r.Get("/", wrap(GetOrgCurrent)) r.Get("/", wrap(GetOrgCurrent))
r.Put("/", bind(m.UpdateOrgCommand{}), wrap(UpdateOrgCurrent)) r.Put("/", bind(dtos.UpdateOrgForm{}), wrap(UpdateOrgCurrent))
r.Put("/address", bind(dtos.UpdateOrgAddressForm{}), wrap(UpdateOrgAddressCurrent))
r.Post("/users", bind(m.AddOrgUserCommand{}), wrap(AddOrgUserToCurrentOrg)) r.Post("/users", bind(m.AddOrgUserCommand{}), wrap(AddOrgUserToCurrentOrg))
r.Get("/users", wrap(GetOrgUsersForCurrentOrg)) r.Get("/users", wrap(GetOrgUsersForCurrentOrg))
r.Patch("/users/:userId", bind(m.UpdateOrgUserCommand{}), wrap(UpdateOrgUserForCurrentOrg)) r.Patch("/users/:userId", bind(m.UpdateOrgUserCommand{}), wrap(UpdateOrgUserForCurrentOrg))
...@@ -114,7 +115,8 @@ func Register(r *macaron.Macaron) { ...@@ -114,7 +115,8 @@ func Register(r *macaron.Macaron) {
// orgs (admin routes) // orgs (admin routes)
r.Group("/orgs/:orgId", func() { r.Group("/orgs/:orgId", func() {
r.Get("/", wrap(GetOrgById)) r.Get("/", wrap(GetOrgById))
r.Put("/", bind(m.UpdateOrgCommand{}), wrap(UpdateOrg)) r.Put("/", bind(dtos.UpdateOrgForm{}), wrap(UpdateOrg))
r.Put("/address", bind(dtos.UpdateOrgAddressForm{}), wrap(UpdateOrgAddress))
r.Delete("/", wrap(DeleteOrgById)) r.Delete("/", wrap(DeleteOrgById))
r.Get("/users", wrap(GetOrgUsers)) r.Get("/users", wrap(GetOrgUsers))
r.Post("/users", bind(m.AddOrgUserCommand{}), wrap(AddOrgUser)) r.Post("/users", bind(m.AddOrgUserCommand{}), wrap(AddOrgUser))
......
package dtos
type UpdateOrgForm struct {
Name string `json:"name" binding:"Required"`
}
type UpdateOrgAddressForm struct {
Address1 string `json:"address1"`
Address2 string `json:"address2"`
City string `json:"city"`
ZipCode string `json:"zipcode"`
State string `json:"state"`
Country string `json:"country"`
}
package api package api
import ( import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/metrics" "github.com/grafana/grafana/pkg/metrics"
"github.com/grafana/grafana/pkg/middleware" "github.com/grafana/grafana/pkg/middleware"
...@@ -30,12 +31,21 @@ func getOrgHelper(orgId int64) Response { ...@@ -30,12 +31,21 @@ func getOrgHelper(orgId int64) Response {
return ApiError(500, "Failed to get organization", err) return ApiError(500, "Failed to get organization", err)
} }
org := m.OrgDTO{ org := query.Result
Id: query.Result.Id, result := m.OrgDetailsDTO{
Name: query.Result.Name, Id: org.Id,
Name: org.Name,
Address: m.Address{
Address1: org.Address1,
Address2: org.Address2,
City: org.City,
ZipCode: org.ZipCode,
State: org.State,
Country: org.Country,
},
} }
return Json(200, &org) return Json(200, &result)
} }
// POST /api/orgs // POST /api/orgs
...@@ -61,18 +71,17 @@ func CreateOrg(c *middleware.Context, cmd m.CreateOrgCommand) Response { ...@@ -61,18 +71,17 @@ func CreateOrg(c *middleware.Context, cmd m.CreateOrgCommand) Response {
} }
// PUT /api/org // PUT /api/org
func UpdateOrgCurrent(c *middleware.Context, cmd m.UpdateOrgCommand) Response { func UpdateOrgCurrent(c *middleware.Context, form dtos.UpdateOrgForm) Response {
cmd.OrgId = c.OrgId return updateOrgHelper(form, c.OrgId)
return updateOrgHelper(cmd)
} }
// PUT /api/orgs/:orgId // PUT /api/orgs/:orgId
func UpdateOrg(c *middleware.Context, cmd m.UpdateOrgCommand) Response { func UpdateOrg(c *middleware.Context, form dtos.UpdateOrgForm) Response {
cmd.OrgId = c.ParamsInt64(":orgId") return updateOrgHelper(form, c.ParamsInt64(":orgId"))
return updateOrgHelper(cmd)
} }
func updateOrgHelper(cmd m.UpdateOrgCommand) Response { func updateOrgHelper(form dtos.UpdateOrgForm, orgId int64) Response {
cmd := m.UpdateOrgCommand{Name: form.Name, OrgId: orgId}
if err := bus.Dispatch(&cmd); err != nil { if err := bus.Dispatch(&cmd); err != nil {
if err == m.ErrOrgNameTaken { if err == m.ErrOrgNameTaken {
return ApiError(400, "Organization name taken", err) return ApiError(400, "Organization name taken", err)
...@@ -83,6 +92,36 @@ func updateOrgHelper(cmd m.UpdateOrgCommand) Response { ...@@ -83,6 +92,36 @@ func updateOrgHelper(cmd m.UpdateOrgCommand) Response {
return ApiSuccess("Organization updated") return ApiSuccess("Organization updated")
} }
// PUT /api/org/address
func UpdateOrgAddressCurrent(c *middleware.Context, form dtos.UpdateOrgAddressForm) Response {
return updateOrgAddressHelper(form, c.OrgId)
}
// PUT /api/orgs/:orgId/address
func UpdateOrgAddress(c *middleware.Context, form dtos.UpdateOrgAddressForm) Response {
return updateOrgAddressHelper(form, c.ParamsInt64(":orgId"))
}
func updateOrgAddressHelper(form dtos.UpdateOrgAddressForm, orgId int64) Response {
cmd := m.UpdateOrgAddressCommand{
OrgId: orgId,
Address: m.Address{
Address1: form.Address1,
Address2: form.Address2,
City: form.City,
State: form.State,
ZipCode: form.ZipCode,
Country: form.Country,
},
}
if err := bus.Dispatch(&cmd); err != nil {
return ApiError(500, "Failed to update org address", err)
}
return ApiSuccess("Address updated")
}
// GET /api/orgs/:orgId // GET /api/orgs/:orgId
func DeleteOrgById(c *middleware.Context) Response { func DeleteOrgById(c *middleware.Context) Response {
if err := bus.Dispatch(&m.DeleteOrgCommand{Id: c.ParamsInt64(":orgId")}); err != nil { if err := bus.Dispatch(&m.DeleteOrgCommand{Id: c.ParamsInt64(":orgId")}); err != nil {
......
package models
type Address struct {
Address1 string `json:"address1"`
Address2 string `json:"address2"`
City string `json:"city"`
ZipCode string `json:"zipCode"`
State string `json:"state"`
Country string `json:"country"`
}
...@@ -15,6 +15,14 @@ type Org struct { ...@@ -15,6 +15,14 @@ type Org struct {
Id int64 Id int64
Version int Version int
Name string Name string
Address1 string
Address2 string
City string
ZipCode string
State string
Country string
Created time.Time Created time.Time
Updated time.Time Updated time.Time
} }
...@@ -35,8 +43,13 @@ type DeleteOrgCommand struct { ...@@ -35,8 +43,13 @@ type DeleteOrgCommand struct {
} }
type UpdateOrgCommand struct { type UpdateOrgCommand struct {
Name string `json:"name" binding:"Required"` Name string
OrgId int64 `json:"-"` OrgId int64
}
type UpdateOrgAddressCommand struct {
OrgId int64
Address
} }
type GetOrgByIdQuery struct { type GetOrgByIdQuery struct {
...@@ -63,6 +76,12 @@ type OrgDTO struct { ...@@ -63,6 +76,12 @@ type OrgDTO struct {
Name string `json:"name"` Name string `json:"name"`
} }
type OrgDetailsDTO struct {
Id int64 `json:"id"`
Name string `json:"name"`
Address Address `json:"address"`
}
type UserOrgDTO struct { type UserOrgDTO struct {
OrgId int64 `json:"orgId"` OrgId int64 `json:"orgId"`
Name string `json:"name"` Name string `json:"name"`
......
...@@ -3,6 +3,7 @@ package sqlstore ...@@ -3,6 +3,7 @@ package sqlstore
import ( import (
"time" "time"
"github.com/Unknwon/log"
"github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/events" "github.com/grafana/grafana/pkg/events"
m "github.com/grafana/grafana/pkg/models" m "github.com/grafana/grafana/pkg/models"
...@@ -12,6 +13,7 @@ func init() { ...@@ -12,6 +13,7 @@ func init() {
bus.AddHandler("sql", GetOrgById) bus.AddHandler("sql", GetOrgById)
bus.AddHandler("sql", CreateOrg) bus.AddHandler("sql", CreateOrg)
bus.AddHandler("sql", UpdateOrg) bus.AddHandler("sql", UpdateOrg)
bus.AddHandler("sql", UpdateOrgAddress)
bus.AddHandler("sql", GetOrgByName) bus.AddHandler("sql", GetOrgByName)
bus.AddHandler("sql", SearchOrgs) bus.AddHandler("sql", SearchOrgs)
bus.AddHandler("sql", DeleteOrg) bus.AddHandler("sql", DeleteOrg)
...@@ -146,6 +148,35 @@ func UpdateOrg(cmd *m.UpdateOrgCommand) error { ...@@ -146,6 +148,35 @@ func UpdateOrg(cmd *m.UpdateOrgCommand) error {
}) })
} }
func UpdateOrgAddress(cmd *m.UpdateOrgAddressCommand) error {
return inTransaction2(func(sess *session) error {
log.Info("address %s", cmd.Address1)
org := m.Org{
Address1: cmd.Address1,
Address2: cmd.Address2,
City: cmd.City,
ZipCode: cmd.ZipCode,
State: cmd.State,
Country: cmd.Country,
Updated: time.Now(),
}
if _, err := sess.Id(cmd.OrgId).Update(&org); err != nil {
return err
}
sess.publishAfterCommit(&events.OrgUpdated{
Timestamp: org.Updated,
Id: org.Id,
Name: org.Name,
})
return nil
})
}
func DeleteOrg(cmd *m.DeleteOrgCommand) error { func DeleteOrg(cmd *m.DeleteOrgCommand) error {
return inTransaction2(func(sess *session) error { return inTransaction2(func(sess *session) error {
......
...@@ -15,13 +15,20 @@ function (angular) { ...@@ -15,13 +15,20 @@ function (angular) {
$scope.getOrgInfo = function() { $scope.getOrgInfo = function() {
backendSrv.get('/api/org').then(function(org) { backendSrv.get('/api/org').then(function(org) {
$scope.org = org; $scope.org = org;
$scope.address = org.address;
contextSrv.user.orgName = org.name; contextSrv.user.orgName = org.name;
}); });
}; };
$scope.update = function() { $scope.update = function() {
if (!$scope.orgForm.$valid) { return; } if (!$scope.orgForm.$valid) { return; }
backendSrv.put('/api/org', $scope.org).then($scope.getOrgInfo); var data = {name: $scope.org.name};
backendSrv.put('/api/org', data).then($scope.getOrgInfo);
};
$scope.updateAddress = function() {
if (!$scope.addressForm.$valid) { return; }
backendSrv.put('/api/org/address', $scope.address).then($scope.getOrgInfo);
}; };
$scope.init(); $scope.init();
......
...@@ -7,28 +7,46 @@ ...@@ -7,28 +7,46 @@
<div class="page-container"> <div class="page-container">
<div class="page"> <div class="page">
<h2>Organization info</h2> <h2>Organization</h2>
<form name="orgForm"> <div class="tight-form-section">
<div> <h5>Info</h5>
<div class="tight-form">
<form name="orgForm">
<div class="tight-form last">
<ul class="tight-form-list"> <ul class="tight-form-list">
<li class="tight-form-item" style="width: 100px"> <li class="tight-form-item" style="width: 100px">
<strong>Org. name</strong> Org. name
</li> </li>
<li> <li>
<input type="text" required ng-model="org.name" class="input-xxlarge tight-form-input last" > <input type="text" required ng-model="org.name" class="tight-form-input last" style="width: 475px">
</li> </li>
</ul> </ul>
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
<br>
<button type="submit" class="pull-right btn btn-success" ng-click="update()">Update</button>
</form>
</div>
<div class="tight-form-section">
<h5>Address</h5>
<form name="addressForm">
<div class="tight-form"> <div class="tight-form">
<ul class="tight-form-list"> <ul class="tight-form-list">
<li class="tight-form-item" style="width: 100px"> <li class="tight-form-item" style="width: 100px">
<strong>Address 1</strong> Address 1
</li>
<li>
<input type="text" ng-model="address.address1" class="tight-form-input" style="width:193px">
</li>
<li class="tight-form-item" style="width: 75px">
Address 2
</li> </li>
<li> <li>
<input type="text" ng-model="org.address1" class="input-xxlarge tight-form-input last" > <input type="text" ng-model="address.address2" class="tight-form-input last" style="width:193px">
</li> </li>
</ul> </ul>
<div class="clearfix"></div> <div class="clearfix"></div>
...@@ -36,30 +54,43 @@ ...@@ -36,30 +54,43 @@
<div class="tight-form"> <div class="tight-form">
<ul class="tight-form-list"> <ul class="tight-form-list">
<li class="tight-form-item" style="width: 100px"> <li class="tight-form-item" style="width: 100px">
<strong>Address 2</strong> City
</li> </li>
<li> <li>
<input type="text" ng-model="org.address2" class="input-xxlarge tight-form-input last" > <input type="text" ng-model="address.city" class="tight-form-input" style="width: 193px">
</li>
<li class="tight-form-item" style="width: 75px">
Postal code
</li>
<li>
<input type="text" ng-model="address.zipCode" class="input-medium tight-form-input last" style="width: 193px">
</li> </li>
</ul> </ul>
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
<div class="tight-form"> <div class="tight-form last">
<ul class="tight-form-list"> <ul class="tight-form-list">
<li class="tight-form-item" style="width: 100px"> <li class="tight-form-item" style="width: 100px">
<strong>City</strong> State
</li> </li>
<li> <li>
<input type="text" ng-model="org.city" class="input-xxlarge tight-form-input last" > <input type="text" ng-model="address.state" class="tight-form-input" style="width: 193px">
</li>
<li class="tight-form-item" style="width: 75px">
Country
</li>
<li>
<input type="text" ng-model="address.country" class="tight-form-input last" style="width: 193px">
</li> </li>
</ul> </ul>
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
</div> <br>
<br> <button type="submit" class="pull-right btn btn-success" ng-click="updateAddress()">Update</button>
<button type="submit" class="pull-right btn btn-success" ng-click="update()">Update</button>
</form> </form>
</div>
</div> </div>
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment