{{.i18n.Tr "org.settings.delete_account"}}
+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 CANNOT be undo! +settings.confirm_delete_account = Confirm Deletion [action] create_repo = created repository %s 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 = 删除操作会永久清除该组织的信息,并且 不可恢复! +settings.confirm_delete_account = 确认删除组织 [action] create_repo = 创建了仓库 %s 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" .}} +
{{.i18n.Tr "org.settings.delete_account"}}
+