mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Page: /org/:orgname/settings
				
					
				
			This commit is contained in:
		
							
								
								
									
										54
									
								
								cmd/web.go
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								cmd/web.go
									
									
									
									
									
								
							| @@ -159,18 +159,16 @@ func runWeb(*cli.Context) { | |||||||
| 		r.Get("/reset_password", user.ResetPasswd) | 		r.Get("/reset_password", user.ResetPasswd) | ||||||
| 		r.Post("/reset_password", user.ResetPasswdPost) | 		r.Post("/reset_password", user.ResetPasswdPost) | ||||||
| 	}, reqSignOut) | 	}, reqSignOut) | ||||||
| 	m.Group("/user", func(r *macaron.Router) { | 	m.Group("/user/settings", func(r *macaron.Router) { | ||||||
| 		r.Get("/settings", user.Settings) | 		r.Get("", user.Settings) | ||||||
| 		r.Post("/settings", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost) | 		r.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost) | ||||||
| 		m.Group("/settings", func(r *macaron.Router) { | 		r.Get("/password", user.SettingsPassword) | ||||||
| 			r.Get("/password", user.SettingsPassword) | 		r.Post("/password", bindIgnErr(auth.ChangePasswordForm{}), user.SettingsPasswordPost) | ||||||
| 			r.Post("/password", bindIgnErr(auth.ChangePasswordForm{}), user.SettingsPasswordPost) | 		r.Get("/ssh", user.SettingsSSHKeys) | ||||||
| 			r.Get("/ssh", user.SettingsSSHKeys) | 		r.Post("/ssh", bindIgnErr(auth.AddSSHKeyForm{}), user.SettingsSSHKeysPost) | ||||||
| 			r.Post("/ssh", bindIgnErr(auth.AddSSHKeyForm{}), user.SettingsSSHKeysPost) | 		r.Get("/social", user.SettingsSocial) | ||||||
| 			r.Get("/social", user.SettingsSocial) | 		r.Get("/orgs", user.SettingsOrgs) | ||||||
| 			r.Get("/orgs", user.SettingsOrgs) | 		r.Route("/delete", "GET,POST", user.SettingsDelete) | ||||||
| 			r.Route("/delete", "GET,POST", user.SettingsDelete) |  | ||||||
| 		}) |  | ||||||
| 	}, reqSignIn) | 	}, reqSignIn) | ||||||
| 	m.Group("/user", func(r *macaron.Router) { | 	m.Group("/user", func(r *macaron.Router) { | ||||||
| 		// r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds) | 		// r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds) | ||||||
| @@ -226,20 +224,30 @@ func runWeb(*cli.Context) { | |||||||
| 	m.Group("/org", func(r *macaron.Router) { | 	m.Group("/org", func(r *macaron.Router) { | ||||||
| 		r.Get("/create", org.Create) | 		r.Get("/create", org.Create) | ||||||
| 		r.Post("/create", bindIgnErr(auth.CreateOrgForm{}), org.CreatePost) | 		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) | 		m.Group("/:org", func(r *macaron.Router) { | ||||||
| 		r.Get("/:org/teams/new", org.NewTeam) | 			r.Get("", org.Home) | ||||||
| 		r.Post("/:org/teams/new", bindIgnErr(auth.CreateTeamForm{}), org.NewTeamPost) | 		}, middleware.OrgAssignment(true)) | ||||||
| 		r.Get("/:org/teams/:team/edit", org.EditTeam) |  | ||||||
|  |  | ||||||
| 		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.Get("/teams", org.Teams) | ||||||
| 		r.Post("/:org/settings", bindIgnErr(auth.OrgSettingForm{}), org.SettingsPost) | 			r.Get("/teams/:team", org.SingleTeam) | ||||||
| 		r.Post("/:org/settings/delete", org.DeletePost) | 		}, 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) | 	}, reqSignIn) | ||||||
|  |  | ||||||
| 	// Repository routers. | 	// Repository routers. | ||||||
|   | |||||||
| @@ -109,6 +109,7 @@ invalid_ssh_key = Sorry, we're not able to verify your SSH key: %s | |||||||
| auth_failed = Authentication failed: %v | auth_failed = Authentication failed: %v | ||||||
|  |  | ||||||
| still_own_repo = Your account still have ownership of repository, you have to delete or transfer them first. | 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] | [settings] | ||||||
| profile = Profile | profile = Profile | ||||||
| @@ -235,6 +236,19 @@ teams = Teams | |||||||
| lower_members = members | lower_members = members | ||||||
| lower_repositories = repositories | lower_repositories = repositories | ||||||
| create_new_team = Create New Team | 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] | [action] | ||||||
| create_repo = created repository <a href="/%s">%s</a> | create_repo = created repository <a href="/%s">%s</a> | ||||||
|   | |||||||
| @@ -109,6 +109,7 @@ invalid_ssh_key = 很抱歉,我们无法验证您输入的 SSH 密钥:%s | |||||||
| auth_failed = 授权验证失败:%v | auth_failed = 授权验证失败:%v | ||||||
|  |  | ||||||
| still_own_repo = 您的帐户仍然是某些仓库的拥有者,您必须先转移或删除它们才能执行删除帐户操作! | still_own_repo = 您的帐户仍然是某些仓库的拥有者,您必须先转移或删除它们才能执行删除帐户操作! | ||||||
|  | org_still_own_repo = 该组织仍然是某些仓库的拥有者,您必须先转移或删除它们才能执行删除组织操作! | ||||||
|  |  | ||||||
| [settings] | [settings] | ||||||
| profile = 个人信息 | profile = 个人信息 | ||||||
| @@ -235,6 +236,19 @@ teams = 组织团队 | |||||||
| lower_members = 名成员 | lower_members = 名成员 | ||||||
| lower_repositories = 个仓库 | lower_repositories = 个仓库 | ||||||
| create_new_team = 创建新的团队 | 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] | [action] | ||||||
| create_repo = 创建了仓库 <a href="/%s">%s</a> | create_repo = 创建了仓库 <a href="/%s">%s</a> | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							| @@ -17,7 +17,7 @@ import ( | |||||||
| 	"github.com/gogits/gogs/modules/setting" | 	"github.com/gogits/gogs/modules/setting" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const APP_VER = "0.4.7.0810 Alpha" | const APP_VER = "0.4.7.0814 Alpha" | ||||||
|  |  | ||||||
| func init() { | func init() { | ||||||
| 	runtime.GOMAXPROCS(runtime.NumCPU()) | 	runtime.GOMAXPROCS(runtime.NumCPU()) | ||||||
|   | |||||||
| @@ -27,15 +27,17 @@ func (f *CreateOrgForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i | |||||||
| 	validate(errs, ctx.Data, f, l) | 	validate(errs, ctx.Data, f, l) | ||||||
| } | } | ||||||
|  |  | ||||||
| type OrgSettingForm struct { | type UpdateOrgSettingForm struct { | ||||||
| 	DisplayName string `form:"display_name" binding:"Required;MaxSize(100)"` | 	OrgUserName string `form:"uname" binding:"Required;MaxSize(35)"` | ||||||
|  | 	OrgFullName string `form:"fullname" binding:"MaxSize(100)"` | ||||||
| 	Email       string `form:"email" binding:"Required;Email;MaxSize(50)"` | 	Email       string `form:"email" binding:"Required;Email;MaxSize(50)"` | ||||||
| 	Description string `form:"desc" binding:"MaxSize(255)"` | 	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)"` | 	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) | 	validate(errs, ctx.Data, f, l) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -76,9 +76,9 @@ func (f *SignInForm) Validate(ctx *macaron.Context, errs *binding.Errors, l i18n | |||||||
|  |  | ||||||
| type UpdateProfileForm struct { | type UpdateProfileForm struct { | ||||||
| 	UserName string `form:"uname" binding:"Required;MaxSize(35)"` | 	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)"` | 	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)"` | 	Location string `form:"location" binding:"MaxSize(50)"` | ||||||
| 	Avatar   string `form:"avatar" binding:"Required;Email;MaxSize(50)"` | 	Avatar   string `form:"avatar" binding:"Required;Email;MaxSize(50)"` | ||||||
| } | } | ||||||
|   | |||||||
| @@ -64,6 +64,12 @@ type Context struct { | |||||||
| 		CommitsCount int | 		CommitsCount int | ||||||
| 		Mirror       *models.Mirror | 		Mirror       *models.Mirror | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	Org struct { | ||||||
|  | 		IsOwner      bool | ||||||
|  | 		IsMember     bool | ||||||
|  | 		Organization *models.User | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // Query querys form parameter. | // Query querys form parameter. | ||||||
|   | |||||||
							
								
								
									
										55
									
								
								modules/middleware/org.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								modules/middleware/org.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -20,15 +20,13 @@ import ( | |||||||
|  |  | ||||||
| func RepoAssignment(redirect bool, args ...bool) macaron.Handler { | func RepoAssignment(redirect bool, args ...bool) macaron.Handler { | ||||||
| 	return func(ctx *Context) { | 	return func(ctx *Context) { | ||||||
| 		// To valid brach name. | 		var ( | ||||||
| 		var validBranch bool | 			validBranch bool // To valid brach name. | ||||||
| 		// To display bare quick start if it is a bare repo. | 			displayBare bool // To display bare page if it is a bare repo. | ||||||
| 		var displayBare bool | 		) | ||||||
|  |  | ||||||
| 		if len(args) >= 1 { | 		if len(args) >= 1 { | ||||||
| 			validBranch = args[0] | 			validBranch = args[0] | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if len(args) >= 2 { | 		if len(args) >= 2 { | ||||||
| 			displayBare = args[1] | 			displayBare = args[1] | ||||||
| 		} | 		} | ||||||
| @@ -60,12 +58,11 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler { | |||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				if err == models.ErrUserNotExist { | 				if err == models.ErrUserNotExist { | ||||||
| 					ctx.Handle(404, "GetUserByName", err) | 					ctx.Handle(404, "GetUserByName", err) | ||||||
| 					return |  | ||||||
| 				} else if redirect { | 				} else if redirect { | ||||||
| 					ctx.Redirect("/") | 					ctx.Redirect("/") | ||||||
| 					return | 				} else { | ||||||
|  | 					ctx.Handle(500, "GetUserByName", err) | ||||||
| 				} | 				} | ||||||
| 				ctx.Handle(500, "GetUserByName", err) |  | ||||||
| 				return | 				return | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
|   | |||||||
| @@ -1348,26 +1348,32 @@ The register and sign-in page style | |||||||
| .setting-content { | .setting-content { | ||||||
|   margin-left: 32px; |   margin-left: 32px; | ||||||
| } | } | ||||||
|  | #org-setting-form, | ||||||
| #repo-setting-form, | #repo-setting-form, | ||||||
| #user-profile-form { | #user-profile-form { | ||||||
|   background-color: #FFF; |   background-color: #FFF; | ||||||
|   padding: 30px 0; |   padding: 30px 0; | ||||||
| } | } | ||||||
|  | #org-setting-form textarea, | ||||||
| #repo-setting-form textarea, | #repo-setting-form textarea, | ||||||
| #user-profile-form textarea { | #user-profile-form textarea { | ||||||
|   margin-left: 4px; |   margin-left: 4px; | ||||||
|   height: 100px; |   height: 100px; | ||||||
| } | } | ||||||
|  | #org-setting-form label, | ||||||
| #repo-setting-form label, | #repo-setting-form label, | ||||||
| #user-profile-form label, | #user-profile-form label, | ||||||
|  | #org-setting-form .form-label, | ||||||
| #repo-setting-form .form-label, | #repo-setting-form .form-label, | ||||||
| #user-profile-form .form-label { | #user-profile-form .form-label { | ||||||
|   width: 240px; |   width: 240px; | ||||||
| } | } | ||||||
|  | #org-setting-form .ipt, | ||||||
| #repo-setting-form .ipt, | #repo-setting-form .ipt, | ||||||
| #user-profile-form .ipt { | #user-profile-form .ipt { | ||||||
|   width: 360px; |   width: 360px; | ||||||
| } | } | ||||||
|  | #org-setting-form .field, | ||||||
| #repo-setting-form .field, | #repo-setting-form .field, | ||||||
| #user-profile-form .field { | #user-profile-form .field { | ||||||
|   margin-bottom: 24px; |   margin-bottom: 24px; | ||||||
|   | |||||||
| @@ -225,6 +225,30 @@ function initCore() { | |||||||
|     Gogs.renderCodeView(); |     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() { | function initRepoCreate() { | ||||||
|     // Owner switch menu click. |     // Owner switch menu click. | ||||||
|     $('#repo-create-owner-list').on('click', 'li', function () { |     $('#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 () { | $(document).ready(function () { | ||||||
|     initCore(); |     initCore(); | ||||||
|  |     if ($('#user-profile-setting').length) { | ||||||
|  |         initUserSetting(); | ||||||
|  |     } | ||||||
|     if ($('#repo-create-form').length || $('#repo-migrate-form').length) { |     if ($('#repo-create-form').length || $('#repo-migrate-form').length) { | ||||||
|         initRepoCreate(); |         initRepoCreate(); | ||||||
|     } |     } | ||||||
|     if ($('#repo-setting').length) { |     if ($('#repo-setting').length) { | ||||||
|         initRepoSetting(); |         initRepoSetting(); | ||||||
|     } |     } | ||||||
|  |     if ($('#org-setting').length) { | ||||||
|  |         initOrgSetting(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     Tabs('#dashboard-sidebar-menu'); |     Tabs('#dashboard-sidebar-menu'); | ||||||
|  |  | ||||||
|     homepage(); |     homepage(); | ||||||
|     settingsProfile(); |  | ||||||
|     settingsSSHKeys(); |  | ||||||
|     settingsDelete(); |  | ||||||
|  |  | ||||||
|     // Fix language drop-down menu height. |     // Fix language drop-down menu height. | ||||||
|     var l = $('#footer-lang li').length; |     var l = $('#footer-lang li').length; | ||||||
| @@ -329,31 +375,3 @@ function homepage() { | |||||||
|         $('#promo-form').attr('action', '/user/sign_up'); |         $('#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; |  | ||||||
|         } |  | ||||||
|     }); |  | ||||||
| } |  | ||||||
| @@ -31,6 +31,7 @@ | |||||||
|   margin-left: 32px; |   margin-left: 32px; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #org-setting-form, | ||||||
| #repo-setting-form, | #repo-setting-form, | ||||||
| #user-profile-form { | #user-profile-form { | ||||||
|     background-color: #FFF; |     background-color: #FFF; | ||||||
|   | |||||||
| @@ -13,30 +13,20 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| 	HOME     base.TplName = "org/home" | 	HOME   base.TplName = "org/home" | ||||||
| 	CREATE   base.TplName = "org/create" | 	CREATE base.TplName = "org/create" | ||||||
| 	SETTINGS base.TplName = "org/settings" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func Home(ctx *middleware.Context) { | 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")) | 	repos, err := models.GetRepositories(org.Id, ctx.IsSigned && org.IsOrgMember(ctx.User.Id)) | ||||||
| 	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)) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Handle(500, "GetRepositories", err) | 		ctx.Handle(500, "GetRepositories", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  | 	ctx.Data["Repos"] = repos | ||||||
|  |  | ||||||
| 	if err = org.GetMembers(); err != nil { | 	if err = org.GetMembers(); err != nil { | ||||||
| 		ctx.Handle(500, "GetMembers", err) | 		ctx.Handle(500, "GetMembers", err) | ||||||
| @@ -94,97 +84,3 @@ func CreatePost(ctx *middleware.Context, form auth.CreateOrgForm) { | |||||||
|  |  | ||||||
| 	ctx.Redirect("/org/" + form.OrgName + "/dashboard") | 	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") |  | ||||||
| } |  | ||||||
|   | |||||||
							
								
								
									
										99
									
								
								routers/org/setting.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								routers/org/setting.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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) | ||||||
|  | } | ||||||
| @@ -252,16 +252,14 @@ func SettingsDelete(ctx *middleware.Context) { | |||||||
| 			case models.ErrUserOwnRepos: | 			case models.ErrUserOwnRepos: | ||||||
| 				ctx.Flash.Error(ctx.Tr("form.still_own_repo")) | 				ctx.Flash.Error(ctx.Tr("form.still_own_repo")) | ||||||
| 				ctx.Redirect("/user/settings/delete") | 				ctx.Redirect("/user/settings/delete") | ||||||
| 				return |  | ||||||
| 			default: | 			default: | ||||||
| 				ctx.Handle(500, "DeleteUser", err) | 				ctx.Handle(500, "DeleteUser", err) | ||||||
| 				return |  | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			log.Trace("Account deleted: %s", ctx.User.Name) | 			log.Trace("Account deleted: %s", ctx.User.Name) | ||||||
| 			ctx.Redirect("/") | 			ctx.Redirect("/") | ||||||
| 			return |  | ||||||
| 		} | 		} | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ctx.HTML(200, SETTINGS_DELETE) | 	ctx.HTML(200, SETTINGS_DELETE) | ||||||
|   | |||||||
| @@ -1 +1 @@ | |||||||
| 0.4.7.0810 Alpha | 0.4.7.0814 Alpha | ||||||
							
								
								
									
										28
									
								
								templates/org/settings/delete.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								templates/org/settings/delete.tmpl
									
									
									
									
									
										Normal file
									
								
							| @@ -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" .}} | ||||||
							
								
								
									
										11
									
								
								templates/org/settings/nav.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								templates/org/settings/nav.tmpl
									
									
									
									
									
										Normal file
									
								
							| @@ -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> | ||||||
							
								
								
									
										56
									
								
								templates/org/settings/options.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								templates/org/settings/options.tmpl
									
									
									
									
									
										Normal file
									
								
							| @@ -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" .}} | ||||||
		Reference in New Issue
	
	Block a user