summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUnknwon <joe2010xtmf@163.com>2014-08-14 14:12:21 +0800
committerUnknwon <joe2010xtmf@163.com>2014-08-14 14:12:21 +0800
commit5acc948562547b393ba1e89b012e7421143c6dd8 (patch)
tree657653112b206fb01ff184bd30cb680b5b5a21fa
parent2935ee440c82a7f998a74159255cc38924f6e0bc (diff)
downloadgitea-5acc948562547b393ba1e89b012e7421143c6dd8.tar.gz
gitea-5acc948562547b393ba1e89b012e7421143c6dd8.zip
Page: `/org/:orgname/settings`
-rw-r--r--cmd/web.go54
-rw-r--r--conf/locale/locale_en-US.ini14
-rw-r--r--conf/locale/locale_zh-CN.ini14
-rw-r--r--gogs.go2
-rw-r--r--modules/auth/org.go10
-rw-r--r--modules/auth/user_form.go4
-rw-r--r--modules/middleware/context.go6
-rw-r--r--modules/middleware/org.go55
-rw-r--r--modules/middleware/repo.go15
-rw-r--r--public/ng/css/gogs.css6
-rw-r--r--public/ng/js/gogs.js80
-rw-r--r--public/ng/less/gogs/settings.less1
-rw-r--r--routers/org/org.go116
-rw-r--r--routers/org/setting.go99
-rw-r--r--routers/user/setting.go4
-rw-r--r--templates/.VERSION2
-rw-r--r--templates/org/settings/delete.tmpl28
-rw-r--r--templates/org/settings/nav.tmpl11
-rw-r--r--templates/org/settings/options.tmpl56
19 files changed, 393 insertions, 184 deletions
diff --git a/cmd/web.go b/cmd/web.go
index c49ba10540..03704c64de 100644
--- a/cmd/web.go
+++ b/cmd/web.go
@@ -159,18 +159,16 @@ func runWeb(*cli.Context) {
r.Get("/reset_password", user.ResetPasswd)
r.Post("/reset_password", user.ResetPasswdPost)
}, reqSignOut)
- m.Group("/user", func(r *macaron.Router) {
- r.Get("/settings", user.Settings)
- r.Post("/settings", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost)
- m.Group("/settings", func(r *macaron.Router) {
- r.Get("/password", user.SettingsPassword)
- r.Post("/password", bindIgnErr(auth.ChangePasswordForm{}), user.SettingsPasswordPost)
- r.Get("/ssh", user.SettingsSSHKeys)
- r.Post("/ssh", bindIgnErr(auth.AddSSHKeyForm{}), user.SettingsSSHKeysPost)
- r.Get("/social", user.SettingsSocial)
- r.Get("/orgs", user.SettingsOrgs)
- r.Route("/delete", "GET,POST", user.SettingsDelete)
- })
+ m.Group("/user/settings", func(r *macaron.Router) {
+ r.Get("", user.Settings)
+ r.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost)
+ r.Get("/password", user.SettingsPassword)
+ r.Post("/password", bindIgnErr(auth.ChangePasswordForm{}), user.SettingsPasswordPost)
+ r.Get("/ssh", user.SettingsSSHKeys)
+ r.Post("/ssh", bindIgnErr(auth.AddSSHKeyForm{}), user.SettingsSSHKeysPost)
+ r.Get("/social", user.SettingsSocial)
+ r.Get("/orgs", user.SettingsOrgs)
+ r.Route("/delete", "GET,POST", user.SettingsDelete)
}, reqSignIn)
m.Group("/user", func(r *macaron.Router) {
// r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds)
@@ -226,20 +224,30 @@ func runWeb(*cli.Context) {
m.Group("/org", func(r *macaron.Router) {
r.Get("/create", org.Create)
r.Post("/create", bindIgnErr(auth.CreateOrgForm{}), org.CreatePost)
- r.Get("/:org", org.Home)
- r.Get("/:org/dashboard", user.Dashboard)
- r.Get("/:org/members", org.Members)
- r.Get("/:org/teams", org.Teams)
- r.Get("/:org/teams/new", org.NewTeam)
- r.Post("/:org/teams/new", bindIgnErr(auth.CreateTeamForm{}), org.NewTeamPost)
- r.Get("/:org/teams/:team/edit", org.EditTeam)
+ m.Group("/:org", func(r *macaron.Router) {
+ r.Get("", org.Home)
+ }, middleware.OrgAssignment(true))
- r.Get("/:org/teams/:team", org.SingleTeam)
+ m.Group("/:org", func(r *macaron.Router) {
+ r.Get("/dashboard", user.Dashboard)
+ r.Get("/members", org.Members)
- r.Get("/:org/settings", org.Settings)
- r.Post("/:org/settings", bindIgnErr(auth.OrgSettingForm{}), org.SettingsPost)
- r.Post("/:org/settings/delete", org.DeletePost)
+ r.Get("/teams", org.Teams)
+ r.Get("/teams/:team", org.SingleTeam)
+ }, middleware.OrgAssignment(true, true))
+
+ m.Group("/:org", func(r *macaron.Router) {
+ r.Get("/teams/new", org.NewTeam)
+ r.Post("/teams/new", bindIgnErr(auth.CreateTeamForm{}), org.NewTeamPost)
+ r.Get("/teams/:team/edit", org.EditTeam)
+
+ m.Group("/settings", func(r *macaron.Router) {
+ r.Get("", org.Settings)
+ r.Post("", bindIgnErr(auth.UpdateOrgSettingForm{}), org.SettingsPost)
+ r.Route("/delete", "GET,POST", org.SettingsDelete)
+ })
+ }, middleware.OrgAssignment(true, true, true))
}, reqSignIn)
// Repository routers.
diff --git a/conf/locale/locale_en-US.ini b/conf/locale/locale_en-US.ini
index 5156eaa7c6..e34dfa013b 100644
--- a/conf/locale/locale_en-US.ini
+++ b/conf/locale/locale_en-US.ini
@@ -109,6 +109,7 @@ invalid_ssh_key = Sorry, we're not able to verify your SSH key: %s
auth_failed = Authentication failed: %v
still_own_repo = Your account still have ownership of repository, you have to delete or transfer them first.
+org_still_own_repo = This organization still have ownership of repository, you have to delete or transfer them first.
[settings]
profile = Profile
@@ -235,6 +236,19 @@ teams = Teams
lower_members = members
lower_repositories = repositories
create_new_team = Create New Team
+org_desc = Description
+
+settings = Settings
+settings.options = Options
+settings.full_name = Full Name
+settings.website = Website
+settings.location = Location
+settings.update_settings = Update Settings
+settings.update_setting_success = Organization setting has been successfully updated.
+settings.delete = Delete Organization
+settings.delete_account = Delete This Organization
+settings.delete_prompt = The operation will delete this organization permanently, and <strong>CANNOT</strong> be undo!
+settings.confirm_delete_account = Confirm Deletion
[action]
create_repo = created repository <a href="/%s">%s</a>
diff --git a/conf/locale/locale_zh-CN.ini b/conf/locale/locale_zh-CN.ini
index 2c7bb715fe..2499e12154 100644
--- a/conf/locale/locale_zh-CN.ini
+++ b/conf/locale/locale_zh-CN.ini
@@ -109,6 +109,7 @@ invalid_ssh_key = 很抱歉,我们无法验证您输入的 SSH 密钥:%s
auth_failed = 授权验证失败:%v
still_own_repo = 您的帐户仍然是某些仓库的拥有者,您必须先转移或删除它们才能执行删除帐户操作!
+org_still_own_repo = 该组织仍然是某些仓库的拥有者,您必须先转移或删除它们才能执行删除组织操作!
[settings]
profile = 个人信息
@@ -235,6 +236,19 @@ teams = 组织团队
lower_members = 名成员
lower_repositories = 个仓库
create_new_team = 创建新的团队
+org_desc = 组织描述
+
+settings = 组织设置
+settings.options = 基本设置
+settings.full_name = 组织全名
+settings.website = 官方网站
+settings.location = 所在地区
+settings.update_settings = 更新组织设置
+settings.update_setting_success = 组织设置更新成功!
+settings.delete = 删除组织
+settings.delete_account = 删除当前组织
+settings.delete_prompt = 删除操作会永久清除该组织的信息,并且 <strong>不可恢复</strong>!
+settings.confirm_delete_account = 确认删除组织
[action]
create_repo = 创建了仓库 <a href="/%s">%s</a>
diff --git a/gogs.go b/gogs.go
index 17179d0320..4a3e353cdf 100644
--- a/gogs.go
+++ b/gogs.go
@@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting"
)
-const APP_VER = "0.4.7.0810 Alpha"
+const APP_VER = "0.4.7.0814 Alpha"
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
diff --git a/modules/auth/org.go b/modules/auth/org.go
index 0895780e3f..9598e6f834 100644
--- a/modules/auth/org.go
+++ b/modules/auth/org.go
@@ -27,15 +27,17 @@ func (f *CreateOrgForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i
validate(errs, ctx.Data, f, l)
}
-type OrgSettingForm struct {
- DisplayName string `form:"display_name" binding:"Required;MaxSize(100)"`
+type UpdateOrgSettingForm struct {
+ OrgUserName string `form:"uname" binding:"Required;MaxSize(35)"`
+ OrgFullName string `form:"fullname" binding:"MaxSize(100)"`
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
Description string `form:"desc" binding:"MaxSize(255)"`
- Website string `form:"site" binding:"Url;MaxSize(100)"`
+ Website string `form:"website" binding:"Url;MaxSize(100)"`
Location string `form:"location" binding:"MaxSize(50)"`
+ Avatar string `form:"avatar" binding:"Required;Email;MaxSize(50)"`
}
-func (f *OrgSettingForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
+func (f *UpdateOrgSettingForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n.Locale) {
validate(errs, ctx.Data, f, l)
}
diff --git a/modules/auth/user_form.go b/modules/auth/user_form.go
index df713b570f..51a07b9128 100644
--- a/modules/auth/user_form.go
+++ b/modules/auth/user_form.go
@@ -76,9 +76,9 @@ func (f *SignInForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n
type UpdateProfileForm struct {
UserName string `form:"uname" binding:"Required;MaxSize(35)"`
- FullName string `form:"fullname" binding:"MaxSize(40)"`
+ FullName string `form:"fullname" binding:"MaxSize(100)"`
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
- Website string `form:"website" binding:"Url;MaxSize(50)"`
+ Website string `form:"website" binding:"Url;MaxSize(100)"`
Location string `form:"location" binding:"MaxSize(50)"`
Avatar string `form:"avatar" binding:"Required;Email;MaxSize(50)"`
}
diff --git a/modules/middleware/context.go b/modules/middleware/context.go
index 1e6f8e9525..aa1266d649 100644
--- a/modules/middleware/context.go
+++ b/modules/middleware/context.go
@@ -64,6 +64,12 @@ type Context struct {
CommitsCount int
Mirror *models.Mirror
}
+
+ Org struct {
+ IsOwner bool
+ IsMember bool
+ Organization *models.User
+ }
}
// Query querys form parameter.
diff --git a/modules/middleware/org.go b/modules/middleware/org.go
new file mode 100644
index 0000000000..05316a518f
--- /dev/null
+++ b/modules/middleware/org.go
@@ -0,0 +1,55 @@
+// Copyright 2014 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package middleware
+
+import (
+ "github.com/Unknwon/macaron"
+
+ "github.com/gogits/gogs/models"
+)
+
+func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
+ return func(ctx *Context) {
+ var (
+ requireMember bool
+ requireOwner bool
+ )
+ if len(args) >= 1 {
+ requireMember = args[0]
+ }
+ if len(args) >= 2 {
+ requireOwner = args[1]
+ }
+
+ orgName := ctx.Params(":org")
+
+ var err error
+ ctx.Org.Organization, err = models.GetUserByName(orgName)
+ if err != nil {
+ if err == models.ErrUserNotExist {
+ ctx.Handle(404, "GetUserByName", err)
+ } else if redirect {
+ ctx.Redirect("/")
+ } else {
+ ctx.Handle(500, "GetUserByName", err)
+ }
+ return
+ }
+ ctx.Data["Org"] = ctx.Org.Organization
+
+ if ctx.IsSigned {
+ ctx.Org.IsOwner = ctx.Org.Organization.IsOrgOwner(ctx.User.Id)
+ if ctx.Org.IsOwner {
+ ctx.Org.IsMember = true
+ } else {
+ ctx.Org.IsMember = ctx.Org.Organization.IsOrgMember(ctx.User.Id)
+ }
+ }
+ if (requireMember && !ctx.Org.IsMember) || (requireOwner && !ctx.Org.IsOwner) {
+ ctx.Handle(404, "OrgAssignment", err)
+ return
+ }
+ }
+}
diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go
index 929850d202..a028aab802 100644
--- a/modules/middleware/repo.go
+++ b/modules/middleware/repo.go
@@ -20,15 +20,13 @@ import (
func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
return func(ctx *Context) {
- // To valid brach name.
- var validBranch bool
- // To display bare quick start if it is a bare repo.
- var displayBare bool
-
+ var (
+ validBranch bool // To valid brach name.
+ displayBare bool // To display bare page if it is a bare repo.
+ )
if len(args) >= 1 {
validBranch = args[0]
}
-
if len(args) >= 2 {
displayBare = args[1]
}
@@ -60,12 +58,11 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
if err != nil {
if err == models.ErrUserNotExist {
ctx.Handle(404, "GetUserByName", err)
- return
} else if redirect {
ctx.Redirect("/")
- return
+ } else {
+ ctx.Handle(500, "GetUserByName", err)
}
- ctx.Handle(500, "GetUserByName", err)
return
}
} else {
diff --git a/public/ng/css/gogs.css b/public/ng/css/gogs.css
index e69e4b663e..93a5d2f8c9 100644
--- a/public/ng/css/gogs.css
+++ b/public/ng/css/gogs.css
@@ -1348,26 +1348,32 @@ The register and sign-in page style
.setting-content {
margin-left: 32px;
}
+#org-setting-form,
#repo-setting-form,
#user-profile-form {
background-color: #FFF;
padding: 30px 0;
}
+#org-setting-form textarea,
#repo-setting-form textarea,
#user-profile-form textarea {
margin-left: 4px;
height: 100px;
}
+#org-setting-form label,
#repo-setting-form label,
#user-profile-form label,
+#org-setting-form .form-label,
#repo-setting-form .form-label,
#user-profile-form .form-label {
width: 240px;
}
+#org-setting-form .ipt,
#repo-setting-form .ipt,
#user-profile-form .ipt {
width: 360px;
}
+#org-setting-form .field,
#repo-setting-form .field,
#user-profile-form .field {
margin-bottom: 24px;
diff --git a/public/ng/js/gogs.js b/public/ng/js/gogs.js
index 473997e9ee..ad8df99716 100644
--- a/public/ng/js/gogs.js
+++ b/public/ng/js/gogs.js
@@ -225,6 +225,30 @@ function initCore() {
Gogs.renderCodeView();
}
+function initUserSetting() {
+ // Confirmation of change username in user profile page.
+ $('#user-profile-form').submit(function (e) {
+ var $username = $('#username');
+ if (($username.data('uname') != $username.val()) && !confirm('Username has been changed, do you want to continue?')) {
+ e.preventDefault();
+ return true;
+ }
+ });
+
+ // Show add SSH key panel.
+ $('#ssh-add').click(function () {
+ $('#user-ssh-add-form').removeClass("hide");
+ });
+
+ // Confirmation of delete account.
+ $('#delete-account-button').click(function (e) {
+ if (!confirm('This account is going to be deleted, do you want to continue?')) {
+ e.preventDefault();
+ return true;
+ }
+ });
+}
+
function initRepoCreate() {
// Owner switch menu click.
$('#repo-create-owner-list').on('click', 'li', function () {
@@ -286,21 +310,43 @@ function initRepoSetting() {
});
}
+function initOrgSetting() {
+ // Options.
+ // Confirmation of changing organization name.
+ $('#org-setting-form').submit(function (e) {
+ var $orgname = $('#orgname');
+ if (($orgname.data('orgname') != $orgname.val()) && !confirm('Organization name has been changed, do you want to continue?')) {
+ e.preventDefault();
+ return true;
+ }
+ });
+ // Confirmation of delete organization.
+ $('#delete-org-button').click(function (e) {
+ if (!confirm('This organization is going to be deleted, do you want to continue?')) {
+ e.preventDefault();
+ return true;
+ }
+ });
+}
+
$(document).ready(function () {
initCore();
+ if ($('#user-profile-setting').length) {
+ initUserSetting();
+ }
if ($('#repo-create-form').length || $('#repo-migrate-form').length) {
initRepoCreate();
}
if ($('#repo-setting').length) {
initRepoSetting();
}
+ if ($('#org-setting').length) {
+ initOrgSetting();
+ }
Tabs('#dashboard-sidebar-menu');
homepage();
- settingsProfile();
- settingsSSHKeys();
- settingsDelete();
// Fix language drop-down menu height.
var l = $('#footer-lang li').length;
@@ -328,32 +374,4 @@ function homepage() {
}
$('#promo-form').attr('action', '/user/sign_up');
});
-}
-
-function settingsProfile() {
- // Confirmation of change username in user profile page.
- $('#user-profile-form').submit(function (e) {
- var $username = $('#username');
- if (($username.data('uname') != $username.val()) && !confirm('Username has been changed, do you want to continue?')) {
- e.preventDefault();
- return true;
- }
- });
-}
-
-function settingsSSHKeys() {
- // Show add SSH key panel.
- $('#ssh-add').click(function () {
- $('#user-ssh-add-form').removeClass("hide");
- });
-}
-
-function settingsDelete() {
- // Confirmation of delete account.
- $('#delete-account-button').click(function (e) {
- if (!confirm('This account is going to deleted, do you want to continue?')) {
- e.preventDefault();
- return true;
- }
- });
} \ No newline at end of file
diff --git a/public/ng/less/gogs/settings.less b/public/ng/less/gogs/settings.less
index 1a492b03c2..ad50e4ffa8 100644
--- a/public/ng/less/gogs/settings.less
+++ b/public/ng/less/gogs/settings.less
@@ -31,6 +31,7 @@
margin-left: 32px;
}
+#org-setting-form,
#repo-setting-form,
#user-profile-form {
background-color: #FFF;
diff --git a/routers/org/org.go b/routers/org/org.go
index fed1fd5fbc..254ba8148f 100644
--- a/routers/org/org.go
+++ b/routers/org/org.go
@@ -13,30 +13,20 @@ import (
)
const (
- HOME base.TplName = "org/home"
- CREATE base.TplName = "org/create"
- SETTINGS base.TplName = "org/settings"
+ HOME base.TplName = "org/home"
+ CREATE base.TplName = "org/create"
)
func Home(ctx *middleware.Context) {
- ctx.Data["Title"] = ctx.Params(":org")
+ org := ctx.Org.Organization
+ ctx.Data["Title"] = org.Name
- org, err := models.GetUserByName(ctx.Params(":org"))
- if err != nil {
- if err == models.ErrUserNotExist {
- ctx.Handle(404, "GetUserByName", err)
- } else {
- ctx.Handle(500, "GetUserByName", err)
- }
- return
- }
- ctx.Data["Org"] = org
-
- ctx.Data["Repos"], err = models.GetRepositories(org.Id, ctx.IsSigned && org.IsOrgMember(ctx.User.Id))
+ repos, err := models.GetRepositories(org.Id, ctx.IsSigned && org.IsOrgMember(ctx.User.Id))
if err != nil {
ctx.Handle(500, "GetRepositories", err)
return
}
+ ctx.Data["Repos"] = repos
if err = org.GetMembers(); err != nil {
ctx.Handle(500, "GetMembers", err)
@@ -94,97 +84,3 @@ func CreatePost(ctx *middleware.Context, form auth.CreateOrgForm) {
ctx.Redirect("/org/" + form.OrgName + "/dashboard")
}
-
-func Settings(ctx *middleware.Context) {
- ctx.Data["Title"] = "Settings"
-
- org, err := models.GetUserByName(ctx.Params(":org"))
- if err != nil {
- if err == models.ErrUserNotExist {
- ctx.Handle(404, "org.Settings(GetUserByName)", err)
- } else {
- ctx.Handle(500, "org.Settings(GetUserByName)", err)
- }
- return
- }
- ctx.Data["Org"] = org
-
- ctx.HTML(200, SETTINGS)
-}
-
-func SettingsPost(ctx *middleware.Context, form auth.OrgSettingForm) {
- ctx.Data["Title"] = "Settings"
-
- org, err := models.GetUserByName(ctx.Params(":org"))
- if err != nil {
- if err == models.ErrUserNotExist {
- ctx.Handle(404, "org.SettingsPost(GetUserByName)", err)
- } else {
- ctx.Handle(500, "org.SettingsPost(GetUserByName)", err)
- }
- return
- }
- ctx.Data["Org"] = org
-
- if ctx.HasError() {
- ctx.HTML(200, SETTINGS)
- return
- }
-
- org.FullName = form.DisplayName
- org.Email = form.Email
- org.Description = form.Description
- org.Website = form.Website
- org.Location = form.Location
- if err = models.UpdateUser(org); err != nil {
- ctx.Handle(500, "org.SettingsPost(UpdateUser)", err)
- return
- }
- log.Trace("%s Organization setting updated: %s", ctx.Req.RequestURI, org.LowerName)
- ctx.Flash.Success("Organization profile has been successfully updated.")
- ctx.Redirect("/org/" + org.Name + "/settings")
-}
-
-func DeletePost(ctx *middleware.Context) {
- ctx.Data["Title"] = "Settings"
-
- org, err := models.GetUserByName(ctx.Params(":org"))
- if err != nil {
- if err == models.ErrUserNotExist {
- ctx.Handle(404, "org.DeletePost(GetUserByName)", err)
- } else {
- ctx.Handle(500, "org.DeletePost(GetUserByName)", err)
- }
- return
- }
- ctx.Data["Org"] = org
-
- if !org.IsOrgOwner(ctx.User.Id) {
- ctx.Error(403)
- return
- }
-
- tmpUser := models.User{
- Passwd: ctx.Query("password"),
- Salt: ctx.User.Salt,
- }
- tmpUser.EncodePasswd()
- if tmpUser.Passwd != ctx.User.Passwd {
- ctx.Flash.Error("Password is not correct. Make sure you are owner of this account.")
- } else {
- if err := models.DeleteOrganization(org); err != nil {
- switch err {
- case models.ErrUserOwnRepos:
- ctx.Flash.Error("This organization still have ownership of repository, you have to delete or transfer them first.")
- default:
- ctx.Handle(500, "org.DeletePost(DeleteOrganization)", err)
- return
- }
- } else {
- ctx.Redirect("/")
- return
- }
- }
-
- ctx.Redirect("/org/" + org.Name + "/settings")
-}
diff --git a/routers/org/setting.go b/routers/org/setting.go
new file mode 100644
index 0000000000..0ddf0065cc
--- /dev/null
+++ b/routers/org/setting.go
@@ -0,0 +1,99 @@
+// Copyright 2014 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package org
+
+import (
+ "github.com/gogits/gogs/models"
+ "github.com/gogits/gogs/modules/auth"
+ "github.com/gogits/gogs/modules/base"
+ "github.com/gogits/gogs/modules/log"
+ "github.com/gogits/gogs/modules/middleware"
+)
+
+const (
+ SETTINGS_OPTIONS base.TplName = "org/settings/options"
+ SETTINGS_DELETE base.TplName = "org/settings/delete"
+)
+
+func Settings(ctx *middleware.Context) {
+ ctx.Data["Title"] = ctx.Tr("org.settings")
+ ctx.Data["PageIsSettingsOptions"] = true
+ ctx.HTML(200, SETTINGS_OPTIONS)
+}
+
+func SettingsPost(ctx *middleware.Context, form auth.UpdateOrgSettingForm) {
+ ctx.Data["Title"] = ctx.Tr("org.settings")
+ ctx.Data["PageIsSettingsOptions"] = true
+
+ if ctx.HasError() {
+ ctx.HTML(200, SETTINGS_OPTIONS)
+ return
+ }
+
+ org := ctx.Org.Organization
+
+ // Check if organization name has been changed.
+ if org.Name != form.OrgUserName {
+ isExist, err := models.IsUserExist(form.OrgUserName)
+ if err != nil {
+ ctx.Handle(500, "IsUserExist", err)
+ return
+ } else if isExist {
+ ctx.RenderWithErr(ctx.Tr("form.username_been_taken"), SETTINGS_OPTIONS, &form)
+ return
+ } else if err = models.ChangeUserName(org, form.OrgUserName); err != nil {
+ if err == models.ErrUserNameIllegal {
+ ctx.Flash.Error(ctx.Tr("form.illegal_username"))
+ ctx.Redirect("/org/" + org.LowerName + "/settings")
+ return
+ } else {
+ ctx.Handle(500, "ChangeUserName", err)
+ }
+ return
+ }
+ log.Trace("Organization name changed: %s -> %s", org.Name, form.OrgUserName)
+ org.Name = form.OrgUserName
+ }
+
+ org.FullName = form.OrgFullName
+ org.Email = form.Email
+ org.Description = form.Description
+ org.Website = form.Website
+ org.Location = form.Location
+ org.Avatar = base.EncodeMd5(form.Avatar)
+ org.AvatarEmail = form.Avatar
+ if err := models.UpdateUser(org); err != nil {
+ ctx.Handle(500, "UpdateUser", err)
+ return
+ }
+ log.Trace("Organization setting updated: %s", org.Name)
+ ctx.Flash.Success(ctx.Tr("org.settings.update_setting_success"))
+ ctx.Redirect("/org/" + org.Name + "/settings")
+}
+
+func SettingsDelete(ctx *middleware.Context) {
+ ctx.Data["Title"] = ctx.Tr("org.settings")
+ ctx.Data["PageIsSettingsDelete"] = true
+
+ org := ctx.Org.Organization
+ if ctx.Req.Method == "POST" {
+ // TODO: validate password.
+ if err := models.DeleteOrganization(org); err != nil {
+ switch err {
+ case models.ErrUserOwnRepos:
+ ctx.Flash.Error(ctx.Tr("form.org_still_own_repo"))
+ ctx.Redirect("/org/" + org.LowerName + "/settings/delete")
+ default:
+ ctx.Handle(500, "DeleteOrganization", err)
+ }
+ } else {
+ log.Trace("Organization deleted: %s", ctx.User.Name)
+ ctx.Redirect("/")
+ }
+ return
+ }
+
+ ctx.HTML(200, SETTINGS_DELETE)
+}
diff --git a/routers/user/setting.go b/routers/user/setting.go
index 739a30d032..e091bc4381 100644
--- a/routers/user/setting.go
+++ b/routers/user/setting.go
@@ -252,16 +252,14 @@ func SettingsDelete(ctx *middleware.Context) {
case models.ErrUserOwnRepos:
ctx.Flash.Error(ctx.Tr("form.still_own_repo"))
ctx.Redirect("/user/settings/delete")
- return
default:
ctx.Handle(500, "DeleteUser", err)
- return
}
} else {
log.Trace("Account deleted: %s", ctx.User.Name)
ctx.Redirect("/")
- return
}
+ return
}
ctx.HTML(200, SETTINGS_DELETE)
diff --git a/templates/.VERSION b/templates/.VERSION
index 2575ec6bc3..f398e90110 100644
--- a/templates/.VERSION
+++ b/templates/.VERSION
@@ -1 +1 @@
-0.4.7.0810 Alpha \ No newline at end of file
+0.4.7.0814 Alpha \ No newline at end of file
diff --git a/templates/org/settings/delete.tmpl b/templates/org/settings/delete.tmpl
new file mode 100644
index 0000000000..7e24f85144
--- /dev/null
+++ b/templates/org/settings/delete.tmpl
@@ -0,0 +1,28 @@
+{{template "ng/base/head" .}}
+{{template "ng/base/header" .}}
+<div id="setting-wrapper" class="main-wrapper">
+ <div id="org-setting" class="container clear">
+ {{template "org/settings/nav" .}}
+ <div class="grid-4-5 left">
+ <div class="setting-content">
+ {{template "ng/base/alert" .}}
+ <div id="setting-content">
+ <div id="user-profile-setting-content" class="panel panel-warning panel-radius">
+ <p class="panel-header"><strong>{{.i18n.Tr "org.settings.delete_account"}}</strong></p>
+ <div class="panel-body panel-content">
+ <span class="alert alert-red alert-radius block"><i class="octicon octicon-alert"></i>{{.i18n.Tr "org.settings.delete_prompt" | Str2html}}</span>
+ <form action="/org/{{.Org.LowerName}}/settings/delete" method="post">
+ {{.CsrfTokenHtml}}
+ <p class="field">
+ <span class="form-label"></span>
+ <button class="btn btn-red btn-large btn-radius" id="delete-org-button">{{.i18n.Tr "org.settings.confirm_delete_account"}}</button>
+ </p>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+{{template "ng/base/footer" .}} \ No newline at end of file
diff --git a/templates/org/settings/nav.tmpl b/templates/org/settings/nav.tmpl
new file mode 100644
index 0000000000..950569d686
--- /dev/null
+++ b/templates/org/settings/nav.tmpl
@@ -0,0 +1,11 @@
+<div id="setting-menu" class="grid-1-5 panel panel-radius left">
+ <div class="panel-header">
+ <strong>{{.i18n.Tr "org.settings"}}</strong>
+ </div>
+ <div class="panel-body">
+ <ul class="menu menu-vertical switching-list grid-1-5 left">
+ <li {{if .PageIsSettingsOptions}}class="current"{{end}}><a href="/org/{{.Org.LowerName}}/settings">{{.i18n.Tr "org.settings.options"}}</a></li>
+ <li {{if .PageIsSettingsDelete}}class="current"{{end}}><a href="/org/{{.Org.LowerName}}/settings/delete">{{.i18n.Tr "org.settings.delete"}}</a></li>
+ </ul>
+ </div>
+</div> \ No newline at end of file
diff --git a/templates/org/settings/options.tmpl b/templates/org/settings/options.tmpl
new file mode 100644
index 0000000000..7548ad5aef
--- /dev/null
+++ b/templates/org/settings/options.tmpl
@@ -0,0 +1,56 @@
+{{template "ng/base/head" .}}
+{{template "ng/base/header" .}}
+<div id="setting-wrapper" class="main-wrapper">
+ <div id="org-setting" class="container clear">
+ {{template "org/settings/nav" .}}
+ <div class="grid-4-5 left">
+ <div class="setting-content">
+ {{template "ng/base/alert" .}}
+ <div id="setting-content">
+ <div id="user-profile-setting-content" class="panel panel-radius">
+ <div class="panel-header">
+ <strong>{{.i18n.Tr "org.settings.options"}}</strong>
+ </div>
+ <form class="form form-align panel-body" id="org-setting-form" action="/org/{{.Org.LowerName}}/settings" method="post">
+ {{.CsrfTokenHtml}}
+ <input type="hidden" name="action" value="update">
+ <div class="field">
+ <label class="req" for="orgname">{{.i18n.Tr "username"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_UserName}}ipt-error{{end}}" id="orgname" name="uname" value="{{.Org.Name}}" data-orgname="{{.Org.Name}}" required />
+ </div>
+ <div class="field">
+ <label for="full-name">{{.i18n.Tr "org.settings.full_name"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_FullName}}ipt-error{{end}}" id="full-name" name="fullname" value="{{.Org.FullName}}" />
+ </div>
+ <div class="field">
+ <label class="req" for="email">{{.i18n.Tr "email"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_Email}}ipt-error{{end}}" id="email" name="email" type="email" value="{{.Org.Email}}" required />
+ </div>
+ <div class="field clear">
+ <label class="left" for="desc">{{.i18n.Tr "org.org_desc"}}</label>
+ <textarea class="ipt ipt-large ipt-radius {{if .Err_Description}}ipt-error{{end}}" id="desc" name="desc">{{.Org.Description}}</textarea>
+ </div>
+ <div class="field">
+ <label for="website">{{.i18n.Tr "org.settings.website"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_Website}}ipt-error{{end}}" id="website" name="website" type="url" value="{{.Org.Website}}" />
+ </div>
+ <div class="field">
+ <label for="location">{{.i18n.Tr "org.settings.location"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_Location}}ipt-error{{end}}" id="location" name="location" type="text" value="{{.Org.Location}}" />
+ </div>
+ <div class="field">
+ <label for="gravatar-email">Gravatar {{.i18n.Tr "email"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_Avatar}}ipt-error{{end}}" id="gravatar-email" name="avatar" type="text" value="{{.Org.AvatarEmail}}" />
+ </div>
+ <div class="field">
+ <span class="form-label"></span>
+ <button class="btn btn-green btn-large btn-radius">{{.i18n.Tr "org.settings.update_settings"}}</button>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+{{template "ng/base/footer" .}} \ No newline at end of file