mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	Finish new admin users pages
This commit is contained in:
		| @@ -5,7 +5,7 @@ Gogs(Go Git Service) is a painless self-hosted Git Service written in Go. | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ##### Current version: 0.4.7 Alpha | ##### Current version: 0.4.7 Beta | ||||||
|  |  | ||||||
| ### NOTICES | ### NOTICES | ||||||
|  |  | ||||||
| @@ -33,6 +33,7 @@ The goal of this project is to make the easiest, fastest and most painless way t | |||||||
| - SSH/HTTP(S) protocol support | - SSH/HTTP(S) protocol support | ||||||
| - SMTP/LDAP/reverse proxy authentication support | - SMTP/LDAP/reverse proxy authentication support | ||||||
| - Register/delete/rename account | - Register/delete/rename account | ||||||
|  | - Create/manage/delete organization with team management | ||||||
| - Create/migrate/mirror/delete/watch/rename/transfer public/private repository | - Create/migrate/mirror/delete/watch/rename/transfer public/private repository | ||||||
| - Repository viewer/release/issue tracker/webhooks | - Repository viewer/release/issue tracker/webhooks | ||||||
| - Add/remove repository collaborators | - Add/remove repository collaborators | ||||||
| @@ -41,7 +42,7 @@ The goal of this project is to make the easiest, fastest and most painless way t | |||||||
| - Administration panel | - Administration panel | ||||||
| - Supports MySQL, PostgreSQL and SQLite3 | - Supports MySQL, PostgreSQL and SQLite3 | ||||||
| - Social account login(GitHub, Google, QQ, Weibo) | - Social account login(GitHub, Google, QQ, Weibo) | ||||||
| - Multi-language support(English, Chinese, etc.) | - Multi-language support(English, Chinese, Germany etc.) | ||||||
|  |  | ||||||
| ## System Requirements | ## System Requirements | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ Gogs(Go Git Service) 是一个基于 Go 语言的自助 Git 服务。 | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ##### 当前版本:0.4.7 Alpha | ##### 当前版本:0.4.7 Beta | ||||||
|  |  | ||||||
| ## 开发目的 | ## 开发目的 | ||||||
|  |  | ||||||
| @@ -23,16 +23,17 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自 | |||||||
| - 活动时间线 | - 活动时间线 | ||||||
| - 支持 SSH/HTTP(S) 协议 | - 支持 SSH/HTTP(S) 协议 | ||||||
| - 支持 SMTP/LDAP/反向代理 用户认证 | - 支持 SMTP/LDAP/反向代理 用户认证 | ||||||
| - 注册/删除/重命名用户 | - 注册/删除/重命名 用户 | ||||||
|  | - 创建/管理/删除 组织以及团队管理功能 | ||||||
| - 创建/迁移/镜像/删除/关注/重命名/转移 公开/私有 仓库 | - 创建/迁移/镜像/删除/关注/重命名/转移 公开/私有 仓库 | ||||||
| - 仓库 浏览器/发布/缺陷管理/Web 钩子 | - 仓库 浏览/发布/工单管理/Web 钩子 | ||||||
| - 添加/删除 仓库协作者 | - 添加/删除 仓库协作者 | ||||||
| - Gravatar 以及缓存支持 | - Gravatar 以及缓存支持 | ||||||
| - 邮件服务(注册、Issue) | - 邮件服务(注册、Issue) | ||||||
| - 管理员面板 | - 管理员面板 | ||||||
| - 支持 MySQL、PostgreSQL 以及 SQLite3 数据库 | - 支持 MySQL、PostgreSQL 以及 SQLite3 数据库 | ||||||
| - 社交帐号登录(GitHub、Google、QQ、微博) | - 社交帐号登录(GitHub、Google、QQ、微博) | ||||||
| - 多语言支持(英文、简体中文等等) | - 多语言支持(英文、简体中文、德语等等) | ||||||
|  |  | ||||||
| ## 系统要求 | ## 系统要求 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -200,7 +200,7 @@ func runWeb(*cli.Context) { | |||||||
| 		r.Post("/new", bindIgnErr(auth.RegisterForm{}), admin.NewUserPost) | 		r.Post("/new", bindIgnErr(auth.RegisterForm{}), admin.NewUserPost) | ||||||
| 		r.Get("/:userid", admin.EditUser) | 		r.Get("/:userid", admin.EditUser) | ||||||
| 		r.Post("/:userid", bindIgnErr(auth.AdminEditUserForm{}), admin.EditUserPost) | 		r.Post("/:userid", bindIgnErr(auth.AdminEditUserForm{}), admin.EditUserPost) | ||||||
| 		r.Get("/:userid/delete", admin.DeleteUser) | 		r.Post("/:userid/delete", admin.DeleteUser) | ||||||
| 	}, adminReq) | 	}, adminReq) | ||||||
|  |  | ||||||
| 	m.Group("/admin/auths", func(r *macaron.Router) { | 	m.Group("/admin/auths", func(r *macaron.Router) { | ||||||
|   | |||||||
| @@ -340,6 +340,26 @@ dashboard.total_gc_pause = Total GC Pause | |||||||
| dashboard.last_gc_pause = Last GC Pause | dashboard.last_gc_pause = Last GC Pause | ||||||
| dashboard.gc_times = GC Times | dashboard.gc_times = GC Times | ||||||
|  |  | ||||||
|  | users.user_manage_panel = User Manage Panel | ||||||
|  | users.new_account = Create New Account | ||||||
|  | users.name = Name | ||||||
|  | users.email = E-mail | ||||||
|  | users.activated = Activated | ||||||
|  | users.admin = Admin | ||||||
|  | users.repos = Repos | ||||||
|  | users.created = Created | ||||||
|  | users.edit = Edit | ||||||
|  | users.auth_source = Auth Source | ||||||
|  | users.local = Local | ||||||
|  | users.auth_login_name = Auth Login Name | ||||||
|  | users.update_profile_success = Account profile has been successfully updated. | ||||||
|  | users.edit_account = Edit Account | ||||||
|  | users.is_activated = This account is activated | ||||||
|  | users.is_admin = This account has administrator permissions | ||||||
|  | users.update_profile = Update Account Profile | ||||||
|  | users.delete_account = Delete This Account | ||||||
|  | users.still_own_repo = This account still have ownership of repository, you have to delete or transfer them first. | ||||||
|  |  | ||||||
| [action] | [action] | ||||||
| create_repo = created repository <a href="/%s">%s</a> | create_repo = created repository <a href="/%s">%s</a> | ||||||
| commit_repo = pushed to <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a> | commit_repo = pushed to <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a> | ||||||
|   | |||||||
| @@ -340,6 +340,25 @@ dashboard.total_gc_pause = GC 暂停时间总量 | |||||||
| dashboard.last_gc_pause = 上次 GC 暂停时间 | dashboard.last_gc_pause = 上次 GC 暂停时间 | ||||||
| dashboard.gc_times = GC 执行次数 | dashboard.gc_times = GC 执行次数 | ||||||
|  |  | ||||||
|  | users.user_manage_panel = 用户管理面板 | ||||||
|  | users.new_account = 创建新的帐户 | ||||||
|  | users.name = 用户名 | ||||||
|  | users.email = 邮箱 | ||||||
|  | users.activated = 已激活 | ||||||
|  | users.admin = 管理员 | ||||||
|  | users.repos = 仓库数 | ||||||
|  | users.created = 创建时间 | ||||||
|  | users.edit = 编辑 | ||||||
|  | users.auth_source = 认证源 | ||||||
|  | users.local = 本地 | ||||||
|  | users.auth_login_name = 认证登录名 | ||||||
|  | users.update_profile_success = 该用户信息已经更新成功! | ||||||
|  | users.edit_account = 编辑用户信息 | ||||||
|  | users.is_activated = 该用户已被激活 | ||||||
|  | users.is_admin = 该用户具有管理员权限 | ||||||
|  | users.update_profile = 更新用户信息 | ||||||
|  | users.delete_account = 删除该用户 | ||||||
|  |  | ||||||
| [action] | [action] | ||||||
| create_repo = 创建了仓库 <a href="/%s">%s</a> | create_repo = 创建了仓库 <a href="/%s">%s</a> | ||||||
| commit_repo = 推送了 <a href="/%s/src/%s">%s</a> 分支的代码到 <a href="/%s">%s</a> | commit_repo = 推送了 <a href="/%s/src/%s">%s</a> 分支的代码到 <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.0827 Alpha" | const APP_VER = "0.4.7.0829 Alpha" | ||||||
|  |  | ||||||
| func init() { | func init() { | ||||||
| 	runtime.GOMAXPROCS(runtime.NumCPU()) | 	runtime.GOMAXPROCS(runtime.NumCPU()) | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ import ( | |||||||
|  |  | ||||||
| type AdminEditUserForm struct { | type AdminEditUserForm struct { | ||||||
| 	Email     string `form:"email" binding:"Required;Email;MaxSize(50)"` | 	Email     string `form:"email" binding:"Required;Email;MaxSize(50)"` | ||||||
| 	Passwd    string `form:"passwd"` | 	Passwd    string `form:"password"` | ||||||
| 	Website   string `form:"website" binding:"MaxSize(50)"` | 	Website   string `form:"website" binding:"MaxSize(50)"` | ||||||
| 	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)"` | ||||||
|   | |||||||
| @@ -249,9 +249,22 @@ img.avatar-100 { | |||||||
|   padding: 8px; |   padding: 8px; | ||||||
|   vertical-align: top; |   vertical-align: top; | ||||||
| } | } | ||||||
| th { | .table th { | ||||||
|   text-align: left; |   text-align: left; | ||||||
| } | } | ||||||
|  | .table-striped > tbody > tr:nth-child(odd) > td, | ||||||
|  | .table-striped > tbody > tr:nth-child(odd) > th { | ||||||
|  |   background-color: #f9f9f9; | ||||||
|  | } | ||||||
|  | .pagination { | ||||||
|  |   display: inline-block; | ||||||
|  |   padding-left: 0; | ||||||
|  |   margin: 20px 0; | ||||||
|  |   border-radius: 4px; | ||||||
|  | } | ||||||
|  | .pagination li { | ||||||
|  |   display: inline; | ||||||
|  | } | ||||||
| .markdown { | .markdown { | ||||||
|   background-color: white; |   background-color: white; | ||||||
|   font-size: 16px; |   font-size: 16px; | ||||||
| @@ -1925,11 +1938,14 @@ textarea#issue-add-content { | |||||||
|   height: 40px; |   height: 40px; | ||||||
|   line-height: 40px; |   line-height: 40px; | ||||||
| } | } | ||||||
|  | .admin-panel { | ||||||
|  |   padding: 10px 20px; | ||||||
|  | } | ||||||
| .admin-desc { | .admin-desc { | ||||||
|   padding: 10px 20px; |   padding: 10px 20px; | ||||||
| } | } | ||||||
| .admin-table { | .admin-table { | ||||||
|   padding: 15px 20px 5px 20px; |   padding: 15px 0 5px 0; | ||||||
| } | } | ||||||
| .dl-horizontal dt { | .dl-horizontal dt { | ||||||
|   float: left; |   float: left; | ||||||
|   | |||||||
| @@ -427,6 +427,31 @@ function initTeamRepositoriesList() { | |||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function initAdmin() { | ||||||
|  |     // Create account. | ||||||
|  |     $('#login-type').on("change",function(){ | ||||||
|  |         var v = $(this).val(); | ||||||
|  |         if(v.indexOf("0-")+1){ | ||||||
|  |             $('.auth-name').toggleHide(); | ||||||
|  |             $(".pwd").find("input").attr("required","required") | ||||||
|  |                 .end().toggleShow(); | ||||||
|  |         }else{ | ||||||
|  |             $(".pwd").find("input").removeAttr("required") | ||||||
|  |                 .end().toggleHide(); | ||||||
|  |             $('.auth-name').toggleShow(); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  |     // Delete account. | ||||||
|  |     $('#user-delete').click(function (e) { | ||||||
|  |         if (!confirm('This account is going to be deleted, do you want to continue?')) { | ||||||
|  |             e.preventDefault(); | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |         var $form = $('user-profile-form'); | ||||||
|  |         $form.attr('action', $form.data('delete-url')); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  |  | ||||||
| $(document).ready(function () { | $(document).ready(function () { | ||||||
|     initCore(); |     initCore(); | ||||||
|     if ($('#user-profile-setting').length) { |     if ($('#user-profile-setting').length) { | ||||||
| @@ -453,6 +478,9 @@ $(document).ready(function () { | |||||||
|     if ($('#team-repositories-list').length) { |     if ($('#team-repositories-list').length) { | ||||||
|         initTeamRepositoriesList(); |         initTeamRepositoriesList(); | ||||||
|     } |     } | ||||||
|  |     if ($('#admin-setting').length) { | ||||||
|  |         initAdmin(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     Tabs('#dashboard-sidebar-menu'); |     Tabs('#dashboard-sidebar-menu'); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,8 +1,11 @@ | |||||||
|  | .admin-panel { | ||||||
|  | 	padding: 10px 20px; | ||||||
|  | } | ||||||
| .admin-desc { | .admin-desc { | ||||||
| 	padding: 10px 20px; | 	padding: 10px 20px; | ||||||
| } | } | ||||||
| .admin-table { | .admin-table { | ||||||
| 	padding: 15px 20px 5px 20px; | 	padding: 15px 0 5px 0; | ||||||
| } | } | ||||||
| .dl-horizontal dt { | .dl-horizontal dt { | ||||||
| 	float: left; | 	float: left; | ||||||
|   | |||||||
| @@ -254,18 +254,33 @@ clear: both; | |||||||
| .table { | .table { | ||||||
|     width: 100%; |     width: 100%; | ||||||
|     max-width: 100%; |     max-width: 100%; | ||||||
| } |     > thead > tr > th,  | ||||||
| .table > thead > tr > th,  |     > tbody > tr > th,  | ||||||
| .table > tbody > tr > th,  |     > tfoot > tr > th,  | ||||||
| .table > tfoot > tr > th,  |     > thead > tr > td,  | ||||||
| .table > thead > tr > td,  |     > tbody > tr > td,  | ||||||
| .table > tbody > tr > td,  |     > tfoot > tr > td { | ||||||
| .table > tfoot > tr > td { |  | ||||||
|         border-top: 1px solid #e7eaec; |         border-top: 1px solid #e7eaec; | ||||||
|         line-height: 1.42857; |         line-height: 1.42857; | ||||||
|         padding: 8px; |         padding: 8px; | ||||||
|         vertical-align: top; |         vertical-align: top; | ||||||
| } |     } | ||||||
| th { |     th { | ||||||
|         text-align: left; |         text-align: left; | ||||||
|  |     } | ||||||
|  | }  | ||||||
|  | .table-striped { | ||||||
|  |     >tbody>tr:nth-child(odd)>td, | ||||||
|  |     >tbody>tr:nth-child(odd)>th { | ||||||
|  |         background-color: #f9f9f9; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | .pagination { | ||||||
|  |     display: inline-block; | ||||||
|  |     padding-left: 0; | ||||||
|  |     margin: 20px 0; | ||||||
|  |     border-radius: 4px; | ||||||
|  |     li { | ||||||
|  |         display: inline; | ||||||
|  |     } | ||||||
| } | } | ||||||
| @@ -23,7 +23,6 @@ import ( | |||||||
|  |  | ||||||
| const ( | const ( | ||||||
| 	DASHBOARD       base.TplName = "admin/dashboard" | 	DASHBOARD       base.TplName = "admin/dashboard" | ||||||
| 	USERS           base.TplName = "admin/users" |  | ||||||
| 	REPOS           base.TplName = "admin/repos" | 	REPOS           base.TplName = "admin/repos" | ||||||
| 	AUTHS           base.TplName = "admin/auths" | 	AUTHS           base.TplName = "admin/auths" | ||||||
| 	CONFIG          base.TplName = "admin/config" | 	CONFIG          base.TplName = "admin/config" | ||||||
| @@ -157,35 +156,6 @@ func Dashboard(ctx *middleware.Context) { | |||||||
| 	ctx.HTML(200, DASHBOARD) | 	ctx.HTML(200, DASHBOARD) | ||||||
| } | } | ||||||
|  |  | ||||||
| func Users(ctx *middleware.Context) { |  | ||||||
| 	ctx.Data["Title"] = "User Management" |  | ||||||
| 	ctx.Data["PageIsUsers"] = true |  | ||||||
|  |  | ||||||
| 	p := com.StrTo(ctx.Query("p")).MustInt() |  | ||||||
| 	if p < 1 { |  | ||||||
| 		p = 1 |  | ||||||
| 	} |  | ||||||
| 	pageNum := 50 |  | ||||||
| 	count := models.CountUsers() |  | ||||||
| 	curCount := int64((p-1)*pageNum + pageNum) |  | ||||||
| 	if curCount > count { |  | ||||||
| 		p = int(count) / pageNum |  | ||||||
| 	} else if count > curCount { |  | ||||||
| 		ctx.Data["NextPageNum"] = p + 1 |  | ||||||
| 	} |  | ||||||
| 	if p > 1 { |  | ||||||
| 		ctx.Data["LastPageNum"] = p - 1 |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	var err error |  | ||||||
| 	ctx.Data["Users"], err = models.GetUsers(pageNum, (p-1)*pageNum) |  | ||||||
| 	if err != nil { |  | ||||||
| 		ctx.Handle(500, "admin.Users(GetUsers)", err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	ctx.HTML(200, USERS) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func Repositories(ctx *middleware.Context) { | func Repositories(ctx *middleware.Context) { | ||||||
| 	ctx.Data["Title"] = "Repository Management" | 	ctx.Data["Title"] = "Repository Management" | ||||||
| 	ctx.Data["PageIsRepos"] = true | 	ctx.Data["PageIsRepos"] = true | ||||||
|   | |||||||
| @@ -1,193 +0,0 @@ | |||||||
| // 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 admin |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"strings" |  | ||||||
|  |  | ||||||
| 	"github.com/Unknwon/com" |  | ||||||
|  |  | ||||||
| 	"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 ( |  | ||||||
| 	USER_NEW  base.TplName = "admin/user/new" |  | ||||||
| 	USER_EDIT base.TplName = "admin/user/edit" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func NewUser(ctx *middleware.Context) { |  | ||||||
| 	ctx.Data["Title"] = "New Account" |  | ||||||
| 	ctx.Data["PageIsUsers"] = true |  | ||||||
| 	auths, err := models.GetAuths() |  | ||||||
| 	if err != nil { |  | ||||||
| 		ctx.Handle(500, "admin.user.NewUser(GetAuths)", err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	ctx.Data["LoginSources"] = auths |  | ||||||
| 	ctx.HTML(200, USER_NEW) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) { |  | ||||||
| 	ctx.Data["Title"] = "New Account" |  | ||||||
| 	ctx.Data["PageIsUsers"] = true |  | ||||||
|  |  | ||||||
| 	if ctx.HasError() { |  | ||||||
| 		ctx.HTML(200, USER_NEW) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if form.Password != form.Retype { |  | ||||||
| 		ctx.Data["Err_Password"] = true |  | ||||||
| 		ctx.Data["Err_RetypePasswd"] = true |  | ||||||
| 		ctx.RenderWithErr("Password and re-type password are not same.", "admin/users/new", &form) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	u := &models.User{ |  | ||||||
| 		Name:      form.UserName, |  | ||||||
| 		Email:     form.Email, |  | ||||||
| 		Passwd:    form.Password, |  | ||||||
| 		IsActive:  true, |  | ||||||
| 		LoginType: models.PLAIN, |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if len(form.LoginType) > 0 { |  | ||||||
| 		// NOTE: need rewrite. |  | ||||||
| 		fields := strings.Split(form.LoginType, "-") |  | ||||||
| 		tp, _ := com.StrTo(fields[0]).Int() |  | ||||||
| 		u.LoginType = models.LoginType(tp) |  | ||||||
| 		u.LoginSource, _ = com.StrTo(fields[1]).Int64() |  | ||||||
| 		u.LoginName = form.LoginName |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if err := models.CreateUser(u); err != nil { |  | ||||||
| 		switch err { |  | ||||||
| 		case models.ErrUserAlreadyExist: |  | ||||||
| 			ctx.RenderWithErr("Username has been already taken", USER_NEW, &form) |  | ||||||
| 		case models.ErrEmailAlreadyUsed: |  | ||||||
| 			ctx.RenderWithErr("E-mail address has been already used", USER_NEW, &form) |  | ||||||
| 		case models.ErrUserNameIllegal: |  | ||||||
| 			ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), USER_NEW, &form) |  | ||||||
| 		default: |  | ||||||
| 			ctx.Handle(500, "admin.user.NewUser(CreateUser)", err) |  | ||||||
| 		} |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	log.Trace("%s User created by admin(%s): %s", ctx.Req.RequestURI, |  | ||||||
| 		ctx.User.LowerName, strings.ToLower(form.UserName)) |  | ||||||
|  |  | ||||||
| 	ctx.Redirect("/admin/users") |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func EditUser(ctx *middleware.Context) { |  | ||||||
| 	ctx.Data["Title"] = "Edit Account" |  | ||||||
| 	ctx.Data["PageIsUsers"] = true |  | ||||||
|  |  | ||||||
| 	uid, err := com.StrTo(ctx.Params(":userid")).Int() |  | ||||||
| 	if err != nil { |  | ||||||
| 		ctx.Handle(404, "admin.user.EditUser", err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	u, err := models.GetUserById(int64(uid)) |  | ||||||
| 	if err != nil { |  | ||||||
| 		ctx.Handle(500, "admin.user.EditUser(GetUserById)", err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ctx.Data["User"] = u |  | ||||||
| 	auths, err := models.GetAuths() |  | ||||||
| 	if err != nil { |  | ||||||
| 		ctx.Handle(500, "admin.user.NewUser(GetAuths)", err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	ctx.Data["LoginSources"] = auths |  | ||||||
| 	ctx.HTML(200, USER_EDIT) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func EditUserPost(ctx *middleware.Context, form auth.AdminEditUserForm) { |  | ||||||
| 	ctx.Data["Title"] = "Edit Account" |  | ||||||
| 	ctx.Data["PageIsUsers"] = true |  | ||||||
|  |  | ||||||
| 	uid, err := com.StrTo(ctx.Params(":userid")).Int() |  | ||||||
| 	if err != nil { |  | ||||||
| 		ctx.Handle(404, "admin.user.EditUserPost", err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	u, err := models.GetUserById(int64(uid)) |  | ||||||
| 	if err != nil { |  | ||||||
| 		ctx.Handle(500, "admin.user.EditUserPost(GetUserById)", err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if ctx.HasError() { |  | ||||||
| 		ctx.HTML(200, USER_EDIT) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if form.Passwd != "" { |  | ||||||
| 		u.Passwd = form.Passwd |  | ||||||
| 		u.Rands = models.GetUserSalt() |  | ||||||
| 		u.Salt = models.GetUserSalt() |  | ||||||
| 		u.EncodePasswd() |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	u.Email = form.Email |  | ||||||
| 	u.Website = form.Website |  | ||||||
| 	u.Location = form.Location |  | ||||||
| 	u.Avatar = base.EncodeMd5(form.Avatar) |  | ||||||
| 	u.AvatarEmail = form.Avatar |  | ||||||
| 	u.IsActive = form.Active |  | ||||||
| 	u.IsAdmin = form.Admin |  | ||||||
| 	if err := models.UpdateUser(u); err != nil { |  | ||||||
| 		ctx.Handle(500, "admin.user.EditUserPost(UpdateUser)", err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	log.Trace("%s User profile updated by admin(%s): %s", ctx.Req.RequestURI, |  | ||||||
| 		ctx.User.LowerName, ctx.User.LowerName) |  | ||||||
|  |  | ||||||
| 	ctx.Data["User"] = u |  | ||||||
| 	ctx.Flash.Success("Account profile has been successfully updated.") |  | ||||||
| 	ctx.Redirect("/admin/users/" + ctx.Params(":userid")) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func DeleteUser(ctx *middleware.Context) { |  | ||||||
| 	ctx.Data["Title"] = "Delete Account" |  | ||||||
| 	ctx.Data["PageIsUsers"] = true |  | ||||||
|  |  | ||||||
| 	//log.Info("delete") |  | ||||||
| 	uid, err := com.StrTo(ctx.Params(":userid")).Int() |  | ||||||
| 	if err != nil { |  | ||||||
| 		ctx.Handle(404, "admin.user.DeleteUser", err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	u, err := models.GetUserById(int64(uid)) |  | ||||||
| 	if err != nil { |  | ||||||
| 		ctx.Handle(500, "admin.user.DeleteUser(GetUserById)", err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if err = models.DeleteUser(u); err != nil { |  | ||||||
| 		switch err { |  | ||||||
| 		case models.ErrUserOwnRepos: |  | ||||||
| 			ctx.Flash.Error("This account still has ownership of repository, owner has to delete or transfer them first.") |  | ||||||
| 			ctx.Redirect("/admin/users/" + ctx.Params(":userid")) |  | ||||||
| 		default: |  | ||||||
| 			ctx.Handle(500, "admin.user.DeleteUser", err) |  | ||||||
| 		} |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	log.Trace("%s User deleted by admin(%s): %s", ctx.Req.RequestURI, |  | ||||||
| 		ctx.User.LowerName, ctx.User.LowerName) |  | ||||||
|  |  | ||||||
| 	ctx.Redirect("/admin/users") |  | ||||||
| } |  | ||||||
							
								
								
									
										224
									
								
								routers/admin/users.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								routers/admin/users.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,224 @@ | |||||||
|  | // 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 admin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"strings" | ||||||
|  |  | ||||||
|  | 	"github.com/Unknwon/com" | ||||||
|  |  | ||||||
|  | 	"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 ( | ||||||
|  | 	USERS     base.TplName = "admin/user/list" | ||||||
|  | 	USER_NEW  base.TplName = "admin/user/new" | ||||||
|  | 	USER_EDIT base.TplName = "admin/user/edit" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func Users(ctx *middleware.Context) { | ||||||
|  | 	ctx.Data["Title"] = ctx.Tr("admin.users") | ||||||
|  | 	ctx.Data["PageIsAdmin"] = true | ||||||
|  | 	ctx.Data["PageIsAdminUsers"] = true | ||||||
|  |  | ||||||
|  | 	p := com.StrTo(ctx.Query("p")).MustInt() | ||||||
|  | 	if p < 1 { | ||||||
|  | 		p = 1 | ||||||
|  | 	} | ||||||
|  | 	pageNum := 50 | ||||||
|  | 	count := models.CountUsers() | ||||||
|  | 	curCount := int64((p-1)*pageNum + pageNum) | ||||||
|  | 	if curCount > count { | ||||||
|  | 		p = int(count) / pageNum | ||||||
|  | 	} else if count > curCount { | ||||||
|  | 		ctx.Data["NextPageNum"] = p + 1 | ||||||
|  | 	} | ||||||
|  | 	if p > 1 { | ||||||
|  | 		ctx.Data["LastPageNum"] = p - 1 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var err error | ||||||
|  | 	ctx.Data["Users"], err = models.GetUsers(pageNum, (p-1)*pageNum) | ||||||
|  | 	if err != nil { | ||||||
|  | 		ctx.Handle(500, "admin.Users(GetUsers)", err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	ctx.HTML(200, USERS) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func NewUser(ctx *middleware.Context) { | ||||||
|  | 	ctx.Data["Title"] = ctx.Tr("admin.users.new_account") | ||||||
|  | 	ctx.Data["PageIsAdmin"] = true | ||||||
|  | 	ctx.Data["PageIsAdminUsers"] = true | ||||||
|  |  | ||||||
|  | 	auths, err := models.GetAuths() | ||||||
|  | 	if err != nil { | ||||||
|  | 		ctx.Handle(500, "GetAuths", err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	ctx.Data["LoginSources"] = auths | ||||||
|  | 	ctx.HTML(200, USER_NEW) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) { | ||||||
|  | 	ctx.Data["Title"] = ctx.Tr("admin.users.new_account") | ||||||
|  | 	ctx.Data["PageIsAdmin"] = true | ||||||
|  | 	ctx.Data["PageIsAdminUsers"] = true | ||||||
|  |  | ||||||
|  | 	if ctx.HasError() { | ||||||
|  | 		ctx.HTML(200, USER_NEW) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if form.Password != form.Retype { | ||||||
|  | 		ctx.Data["Err_Password"] = true | ||||||
|  | 		ctx.RenderWithErr(ctx.Tr("form.password_not_match"), USER_NEW, &form) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	u := &models.User{ | ||||||
|  | 		Name:      form.UserName, | ||||||
|  | 		Email:     form.Email, | ||||||
|  | 		Passwd:    form.Password, | ||||||
|  | 		IsActive:  true, | ||||||
|  | 		LoginType: models.PLAIN, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if len(form.LoginType) > 0 { | ||||||
|  | 		// NOTE: need rewrite. | ||||||
|  | 		fields := strings.Split(form.LoginType, "-") | ||||||
|  | 		tp, _ := com.StrTo(fields[0]).Int() | ||||||
|  | 		u.LoginType = models.LoginType(tp) | ||||||
|  | 		u.LoginSource, _ = com.StrTo(fields[1]).Int64() | ||||||
|  | 		u.LoginName = form.LoginName | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err := models.CreateUser(u); err != nil { | ||||||
|  | 		switch err { | ||||||
|  | 		case models.ErrUserAlreadyExist: | ||||||
|  | 			ctx.Data["Err_UserName"] = true | ||||||
|  | 			ctx.RenderWithErr(ctx.Tr("form.username_been_taken"), USER_NEW, &form) | ||||||
|  | 		case models.ErrEmailAlreadyUsed: | ||||||
|  | 			ctx.Data["Err_Email"] = true | ||||||
|  | 			ctx.RenderWithErr(ctx.Tr("form.email_been_used"), USER_NEW, &form) | ||||||
|  | 		case models.ErrUserNameIllegal: | ||||||
|  | 			ctx.Data["Err_UserName"] = true | ||||||
|  | 			ctx.RenderWithErr(ctx.Tr("form.illegal_username"), USER_NEW, &form) | ||||||
|  | 		default: | ||||||
|  | 			ctx.Handle(500, "CreateUser", err) | ||||||
|  | 		} | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	log.Trace("Account created by admin(%s): %s", ctx.User.Name, u.Name) | ||||||
|  | 	ctx.Redirect("/admin/users") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func EditUser(ctx *middleware.Context) { | ||||||
|  | 	ctx.Data["Title"] = ctx.Tr("admin.users.edit_account") | ||||||
|  | 	ctx.Data["PageIsAdmin"] = true | ||||||
|  | 	ctx.Data["PageIsAdminUsers"] = true | ||||||
|  |  | ||||||
|  | 	uid := com.StrTo(ctx.Params(":userid")).MustInt64() | ||||||
|  | 	if uid == 0 { | ||||||
|  | 		ctx.Handle(404, "EditUser", nil) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	u, err := models.GetUserById(uid) | ||||||
|  | 	if err != nil { | ||||||
|  | 		ctx.Handle(500, "GetUserById", err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ctx.Data["User"] = u | ||||||
|  | 	auths, err := models.GetAuths() | ||||||
|  | 	if err != nil { | ||||||
|  | 		ctx.Handle(500, "GetAuths", err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	ctx.Data["LoginSources"] = auths | ||||||
|  | 	ctx.HTML(200, USER_EDIT) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func EditUserPost(ctx *middleware.Context, form auth.AdminEditUserForm) { | ||||||
|  | 	ctx.Data["Title"] = ctx.Tr("admin.users.edit_account") | ||||||
|  | 	ctx.Data["PageIsAdmin"] = true | ||||||
|  | 	ctx.Data["PageIsAdminUsers"] = true | ||||||
|  |  | ||||||
|  | 	uid := com.StrTo(ctx.Params(":userid")).MustInt64() | ||||||
|  | 	if uid == 0 { | ||||||
|  | 		ctx.Handle(404, "EditUser", nil) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	u, err := models.GetUserById(uid) | ||||||
|  | 	if err != nil { | ||||||
|  | 		ctx.Handle(500, "GetUserById", err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if ctx.HasError() { | ||||||
|  | 		ctx.HTML(200, USER_EDIT) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// NOTE: need password length check? | ||||||
|  | 	if len(form.Passwd) > 0 { | ||||||
|  | 		u.Passwd = form.Passwd | ||||||
|  | 		u.Salt = models.GetUserSalt() | ||||||
|  | 		u.EncodePasswd() | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	u.Email = form.Email | ||||||
|  | 	u.Website = form.Website | ||||||
|  | 	u.Location = form.Location | ||||||
|  | 	if len(form.Avatar) == 0 { | ||||||
|  | 		form.Avatar = form.Email | ||||||
|  | 	} | ||||||
|  | 	u.Avatar = base.EncodeMd5(form.Avatar) | ||||||
|  | 	u.AvatarEmail = form.Avatar | ||||||
|  | 	u.IsActive = form.Active | ||||||
|  | 	u.IsAdmin = form.Admin | ||||||
|  | 	if err := models.UpdateUser(u); err != nil { | ||||||
|  | 		ctx.Handle(500, "UpdateUser", err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	log.Trace("Account profile updated by admin(%s): %s", ctx.User.Name, u.Name) | ||||||
|  |  | ||||||
|  | 	ctx.Data["User"] = u | ||||||
|  | 	ctx.Flash.Success(ctx.Tr("admin.users.update_profile_success")) | ||||||
|  | 	ctx.Redirect("/admin/users/" + ctx.Params(":userid")) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func DeleteUser(ctx *middleware.Context) { | ||||||
|  | 	uid := com.StrTo(ctx.Params(":userid")).MustInt64() | ||||||
|  | 	if uid == 0 { | ||||||
|  | 		ctx.Handle(404, "DeleteUser", nil) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	u, err := models.GetUserById(uid) | ||||||
|  | 	if err != nil { | ||||||
|  | 		ctx.Handle(500, "GetUserById", err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err = models.DeleteUser(u); err != nil { | ||||||
|  | 		switch err { | ||||||
|  | 		case models.ErrUserOwnRepos: | ||||||
|  | 			ctx.Flash.Error(ctx.Tr("admin.users.still_own_repo")) | ||||||
|  | 			ctx.Redirect("/admin/users/" + ctx.Params(":userid")) | ||||||
|  | 		default: | ||||||
|  | 			ctx.Handle(500, "DeleteUser", err) | ||||||
|  | 		} | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	log.Trace("Account deleted by admin(%s): %s", ctx.User.Name, u.Name) | ||||||
|  | 	ctx.Redirect("/admin/users") | ||||||
|  | } | ||||||
| @@ -1 +1 @@ | |||||||
| 0.4.7.0827 Alpha | 0.4.7.0829 Alpha | ||||||
| @@ -22,7 +22,7 @@ | |||||||
|                             <div class="panel-header"> |                             <div class="panel-header"> | ||||||
|                                 <strong>{{.i18n.Tr "admin.dashboard.operations"}}</strong> |                                 <strong>{{.i18n.Tr "admin.dashboard.operations"}}</strong> | ||||||
|                             </div> |                             </div> | ||||||
|                             <div class="panel-body"> |                             <div class="panel-body admin-panel"> | ||||||
|                                 <div class="admin-table"> |                                 <div class="admin-table"> | ||||||
|                                     <table class="table"> |                                     <table class="table"> | ||||||
|                                         <thead> |                                         <thead> | ||||||
|   | |||||||
| @@ -1,110 +1,78 @@ | |||||||
| {{template "base/head" .}} | {{template "ng/base/head" .}} | ||||||
| {{template "base/navbar" .}} | {{template "ng/base/header" .}} | ||||||
| <div id="body" class="container" data-page="admin"> | <div id="admin-wrapper"> | ||||||
|  |     <div id="setting-wrapper" class="main-wrapper"> | ||||||
|  |         <div id="admin-setting" class="container clear"> | ||||||
|             {{template "admin/nav" .}} |             {{template "admin/nav" .}} | ||||||
|     <div id="admin-container" class="col-md-9"> |             <div class="grid-4-5 left"> | ||||||
|         <div class="panel panel-default"> |                 <div class="setting-content"> | ||||||
|             <div class="panel-heading"> |                     {{template "ng/base/alert" .}} | ||||||
|                 Edit Account |                     <div id="setting-content"> | ||||||
|  |                         <div class="panel panel-radius"> | ||||||
|  |                             <div class="panel-header"> | ||||||
|  |                                 <strong>{{.i18n.Tr "admin.users.edit_account"}}</strong> | ||||||
|                             </div> |                             </div> | ||||||
|  |                             <form class="form form-align panel-body" id="user-profile-form" action="/admin/users/{{.User.Id}}" method="post" data-delete-url="/admin/users/{{.User.Id}}/delete"> | ||||||
|             <div class="panel-body"> |  | ||||||
|             	<br/> |  | ||||||
| 				<form action="/admin/users/{{.User.Id}}" method="post" class="form-horizontal"> |  | ||||||
| 					            {{.CsrfTokenHtml}} | 					            {{.CsrfTokenHtml}} | ||||||
| 				    {{template "base/alert" .}} |                                 <div class="field"> | ||||||
| 					<div class="form-group"> |                                     <label class="req">{{.i18n.Tr "admin.users.auth_source"}}</label> | ||||||
| 					    <label class="col-md-3 control-label">Auth Source: </label> |                                     <select id="login-type" name="logintype"> | ||||||
| 					    <div class="col-md-7"> |                                         <option value="0-0">{{.i18n.Tr "admin.users.local"}}</option> | ||||||
| 						    <select name="logintype" class="form-control"> |  | ||||||
| 							    <option value="0-0">Local</option> |  | ||||||
| 									    {{$tp := .User.LoginSource}} | 									    {{$tp := .User.LoginSource}} | ||||||
| 									    {{range $key, $val := .LoginSources}} | 									    {{range $key, $val := .LoginSources}} | ||||||
| 					  					<option value="{{$val.Type}}-{{$val.Id}}"{{if eq $val.Id $tp}} selected{{end}}>{{$val.Name}}</option> | 					  					<option value="{{$val.Type}}-{{$val.Id}}"{{if eq $val.Id $tp}} selected{{end}}>{{$val.Name}}</option> | ||||||
| 					  					{{end}} | 					  					{{end}} | ||||||
|                                     </select> |                                     </select> | ||||||
|                                 </div> |                                 </div> | ||||||
|  |                                 <div class="field"> | ||||||
|  |                                     <label for="loginname">{{.i18n.Tr "admin.users.auth_login_name"}}</label> | ||||||
|  |                                     <input class="ipt ipt-large ipt-radius {{if .Err_LoginName}}ipt-error{{end}}" id="loginname" name="loginname" value="{{.User.LoginName}}" /> | ||||||
|                                 </div> |                                 </div> | ||||||
|  |                                 <div class="field"> | ||||||
| 					<div class="form-group"> |                                     <label>{{.i18n.Tr "username"}}</label> | ||||||
| 					    <label class="col-md-3 control-label">Auth Login Name: </label> |                                     <label>{{.User.Name}}</label> | ||||||
| 					    <div class="col-md-7"> |  | ||||||
| 							<input name="loginname" class="form-control" placeholder="Type auth login's username" value="{{.User.LoginName}}"> |  | ||||||
|                                 </div> |                                 </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="{{.User.Email}}" required/> | ||||||
|                                 </div> |                                 </div> | ||||||
|  |                                 <div class="field pwd"> | ||||||
| 					<div class="form-group"> |                                     <label for="password">{{.i18n.Tr "password"}}</label> | ||||||
| 						<label class="col-md-3 control-label">Username: </label> |                                     <input class="ipt ipt-large ipt-radius {{if .Err_Password}}ipt-error{{end}}" id="password" name="password" type="password" /> | ||||||
| 						<label class="control-label">{{.User.Name}}</label> |  | ||||||
|                                 </div> |                                 </div> | ||||||
|  | 	                            <div class="field"> | ||||||
| 					<div class="form-group {{if .Err_Email}}has-error has-feedback{{end}}"> | 	                                <label for="website">{{.i18n.Tr "settings.website"}}</label> | ||||||
| 						<label class="col-md-3 control-label">Email<strong class="text-danger">*</strong></label> | 	                                <input class="ipt ipt-large ipt-radius {{if .Err_Website}}ipt-error{{end}}" id="website" name="website" type="url" value="{{.User.Website}}" /> | ||||||
| 						<div class="col-md-7"> |  | ||||||
| 							<input name="email" class="form-control" placeholder="Type account's e-mail address" value="{{.User.Email}}" required="required"> |  | ||||||
| 	                            </div> | 	                            </div> | ||||||
|  | 	                            <div class="field"> | ||||||
|  | 	                                <label for="location">{{.i18n.Tr "settings.location"}}</label> | ||||||
|  | 	                                <input class="ipt ipt-large ipt-radius {{if .Err_Location}}ipt-error{{end}}" id="location" name="location" type="text" value="{{.User.Location}}" /> | ||||||
| 	                            </div> | 	                            </div> | ||||||
|  | 	                            <div class="field"> | ||||||
| 					<div class="form-group"> | 	                                <label for="gravatar-email">Gravatar {{.i18n.Tr "email"}}</label> | ||||||
| 						<label class="col-md-3 control-label">Password</label> | 	                                <input class="ipt ipt-large ipt-radius {{if .Err_Avatar}}ipt-error{{end}}" id="gravatar-email" name="avatar" type="text" value="{{.User.AvatarEmail}}" /> | ||||||
| 						<div class="col-md-7"> |  | ||||||
| 							<input name="passwd" type="password" class="form-control" placeholder="Type account's new password or leave unfilled"> |  | ||||||
| 	                            </div> | 	                            </div> | ||||||
| 					</div> | 	                            <div class="field"> | ||||||
|  | 	                                <label></label> | ||||||
| 	                <div class="form-group"> |  | ||||||
| 	                    <label class="col-md-3 control-label">Website</label> |  | ||||||
| 	                    <div class="col-md-7"> |  | ||||||
| 	                        <input name="website" class="form-control" placeholder="Type account's website URL" value="{{.User.Website}}"> |  | ||||||
| 	                    </div> |  | ||||||
| 	                </div> |  | ||||||
|  |  | ||||||
| 	                <div class="form-group"> |  | ||||||
| 	                    <label class="col-md-3 control-label">Location</label> |  | ||||||
| 	                    <div class="col-md-7"> |  | ||||||
| 	                        <input name="location" class="form-control" placeholder="Type account's current location" value="{{.User.Location}}"> |  | ||||||
| 	                    </div> |  | ||||||
| 	                </div> |  | ||||||
|  |  | ||||||
| 	                <div class="form-group {{if .Err_Avatar}}has-error has-feedback{{end}}"> |  | ||||||
| 	                    <label class="col-md-3 control-label">Gravatar Email<strong class="text-danger">*</strong></label> |  | ||||||
| 	                    <div class="col-md-7"> |  | ||||||
| 	                        <input name="avatar" class="form-control" placeholder="Type account's Gravatar e-mail address" required="required" value="{{.User.AvatarEmail}}"> |  | ||||||
| 	                    </div> |  | ||||||
| 	                </div> |  | ||||||
|  |  | ||||||
| 	                <div class="form-group"> |  | ||||||
| 			            <div class="col-md-7 col-md-offset-3"> |  | ||||||
| 			                <div class="checkbox"> |  | ||||||
| 			                    <label> |  | ||||||
| 			                        <input type="checkbox" name="active" {{if .User.IsActive}}checked{{end}}> | 			                        <input type="checkbox" name="active" {{if .User.IsActive}}checked{{end}}> | ||||||
| 			                        <strong>This account is activated</strong> | 			                        <strong>{{.i18n.Tr "admin.users.is_activated"}}</strong> | ||||||
| 			                    </label> | 			                        <br> | ||||||
| 			                </div> | 	                                <label></label> | ||||||
| 			            </div> |  | ||||||
| 	                </div> |  | ||||||
|  |  | ||||||
| 	                <div class="form-group"> |  | ||||||
| 			            <div class="col-md-7 col-md-offset-3"> |  | ||||||
| 			                <div class="checkbox"> |  | ||||||
| 			                    <label> |  | ||||||
| 			                        <input type="checkbox" name="admin" {{if .User.IsAdmin}}checked{{end}}> | 			                        <input type="checkbox" name="admin" {{if .User.IsAdmin}}checked{{end}}> | ||||||
| 			                        <strong>This account has administrator permissions</strong> | 			                        <strong>{{.i18n.Tr "admin.users.is_admin"}}</strong> | ||||||
| 			                    </label> |  | ||||||
| 			                </div> |  | ||||||
| 			            </div> |  | ||||||
| 	                </div> |  | ||||||
| 					<hr/> |  | ||||||
| 					<div class="form-group"> |  | ||||||
| 					    <div class="col-md-offset-3 col-md-6"> |  | ||||||
| 					    	<button type="submit" class="btn btn-lg btn-primary btn-block">Update account profile</button> |  | ||||||
| 					    	<a type="button" href="/admin/users/{{.User.Id}}/delete" class="btn btn-lg btn-danger btn-block">Delete this account</a> |  | ||||||
| 	                            </div> | 	                            </div> | ||||||
|  | 					            <div class="field"> | ||||||
|  | 					                <label></label> | ||||||
|  |                                 	<button class="btn btn-green btn-large btn-radius">{{.i18n.Tr "admin.users.update_profile"}}</button> | ||||||
|  | 					                      | ||||||
|  | 					                <button class="btn btn-large btn-red btn-radius" id="user-delete">{{.i18n.Tr "admin.users.delete_account"}}</button> | ||||||
| 					            </div> | 					            </div> | ||||||
| 							</form> | 							</form> | ||||||
|             			</div> |             			</div> | ||||||
|         			</div> |         			</div> | ||||||
|  | 				</div> | ||||||
|  | 			</div> | ||||||
|  | 		</div> | ||||||
| 	</div> | 	</div> | ||||||
| </div> | </div> | ||||||
| {{template "base/footer" .}} | {{template "ng/base/footer" .}} | ||||||
|   | |||||||
							
								
								
									
										62
									
								
								templates/admin/user/list.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								templates/admin/user/list.tmpl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | |||||||
|  | {{template "ng/base/head" .}} | ||||||
|  | {{template "ng/base/header" .}} | ||||||
|  | <div id="admin-wrapper"> | ||||||
|  |     <div id="setting-wrapper" class="main-wrapper"> | ||||||
|  |         <div id="admin-setting" class="container clear"> | ||||||
|  |             {{template "admin/nav" .}} | ||||||
|  |             <div class="grid-4-5 left"> | ||||||
|  |                 <div class="setting-content"> | ||||||
|  |                     {{template "ng/base/alert" .}} | ||||||
|  |                     <div id="setting-content"> | ||||||
|  |                         <div class="panel panel-radius"> | ||||||
|  |                             <div class="panel-header"> | ||||||
|  |                                 <strong>{{.i18n.Tr "admin.users.user_manage_panel"}}</strong> | ||||||
|  |                             </div> | ||||||
|  |                             <div class="panel-body admin-panel"> | ||||||
|  | 								<a class="btn-blue btn-medium btn-link btn-radius" href="/admin/users/new">{{.i18n.Tr "admin.users.new_account"}}</a> | ||||||
|  |                                 <div class="admin-table"> | ||||||
|  | 					                <table class="table table-striped"> | ||||||
|  | 					                    <thead> | ||||||
|  | 					                        <tr> | ||||||
|  | 					                            <th>Id</th> | ||||||
|  | 					                            <th>{{.i18n.Tr "admin.users.name"}}</th> | ||||||
|  | 					                            <th>{{.i18n.Tr "admin.users.email"}}</th> | ||||||
|  | 					                            <th>{{.i18n.Tr "admin.users.activated"}}</th> | ||||||
|  | 					                            <th>{{.i18n.Tr "admin.users.admin"}}</th> | ||||||
|  | 					                            <th>{{.i18n.Tr "admin.users.repos"}}</th> | ||||||
|  | 					                            <th>{{.i18n.Tr "admin.users.created"}}</th> | ||||||
|  | 					                            <th>{{.i18n.Tr "admin.users.edit"}}</th> | ||||||
|  | 					                        </tr> | ||||||
|  | 					                    </thead> | ||||||
|  | 					                    <tbody> | ||||||
|  | 					                        {{range .Users}} | ||||||
|  | 					                        <tr> | ||||||
|  | 					                            <td>{{.Id}}</td> | ||||||
|  | 					                            <td><a href="/user/{{.Name}}">{{.Name}}</a></td> | ||||||
|  | 					                            <td>{{.Email}}</td> | ||||||
|  | 					                            <td><i class="fa fa{{if .IsActive}}-check{{end}}-square-o"></i></td> | ||||||
|  | 					                            <td><i class="fa fa{{if .IsAdmin}}-check{{end}}-square-o"></i></td> | ||||||
|  | 					                            <td>{{.NumRepos}}</td> | ||||||
|  | 					                            <td>{{DateFormat .Created "M d, Y"}}</td> | ||||||
|  | 					                            <td><a href="/admin/users/{{.Id}}"><i class="fa fa-pencil-square-o"></i></a></td> | ||||||
|  | 					                        </tr> | ||||||
|  | 					                        {{end}} | ||||||
|  | 					                    </tbody> | ||||||
|  | 					                </table> | ||||||
|  | 					                {{if or .LastPageNum .NextPageNum}} | ||||||
|  | 					                <ul class="pagination"> | ||||||
|  | 					                    {{if .LastPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="/admin/users?p={{.LastPageNum}}">« Prev.</a></li>{{end}} | ||||||
|  | 					                    {{if .NextPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="/admin/users?p={{.NextPageNum}}">» Next</a></li>{{end}} | ||||||
|  | 					                </ul> | ||||||
|  | 					                {{end}} | ||||||
|  | 				                </div> | ||||||
|  |                             </div> | ||||||
|  |  | ||||||
|  |                         </div> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
|  | {{template "ng/base/footer" .}} | ||||||
| @@ -1,94 +1,58 @@ | |||||||
| {{template "base/head" .}} | {{template "ng/base/head" .}} | ||||||
| {{template "base/navbar" .}} | {{template "ng/base/header" .}} | ||||||
| <div id="body" class="container" data-page="admin"> | <div id="admin-wrapper"> | ||||||
|  |     <div id="setting-wrapper" class="main-wrapper"> | ||||||
|  |         <div id="admin-setting" class="container clear"> | ||||||
|             {{template "admin/nav" .}} |             {{template "admin/nav" .}} | ||||||
|     <div id="admin-container" class="col-md-9"> |             <div class="grid-4-5 left"> | ||||||
|         <div class="panel panel-default"> |                 <div class="setting-content"> | ||||||
|             <div class="panel-heading"> |                     {{template "ng/base/alert" .}} | ||||||
|                 New Account |                     <div id="setting-content"> | ||||||
|  |                         <div class="panel panel-radius"> | ||||||
|  |                             <div class="panel-header"> | ||||||
|  |                                 <strong>{{.i18n.Tr "admin.users.new_account"}}</strong> | ||||||
|                             </div> |                             </div> | ||||||
|  |                             <form class="form form-align panel-body" id="repo-setting-form" action="/admin/users/new" method="post"> | ||||||
|             <div class="panel-body"> |  | ||||||
|             	<br/> |  | ||||||
| 				<form action="/admin/users/new" method="post" class="form-horizontal"> |  | ||||||
| 					            {{.CsrfTokenHtml}} | 					            {{.CsrfTokenHtml}} | ||||||
| 				    {{template "base/alert" .}} |                                 <div class="field"> | ||||||
| 				    <div class="form-group"> |                                     <label class="req">{{.i18n.Tr "admin.users.auth_source"}}</label> | ||||||
| 					    <label class="col-md-3 control-label">Auth Source: </label> |                                     <select id="login-type" name="logintype"> | ||||||
| 					    <div class="col-md-7"> |                                         <option value="0-0">{{.i18n.Tr "admin.users.local"}}</option> | ||||||
| 						    <select name="logintype" class="form-control" id="login-type"> |  | ||||||
| 							    <option value="0-0">Local</option> |  | ||||||
|                                         {{range $key, $val := .LoginSources}} |                                         {{range $key, $val := .LoginSources}} | ||||||
|                                         <option value="{{$val.Type}}-{{$val.Id}}">{{$val.Name}}</option> |                                         <option value="{{$val.Type}}-{{$val.Id}}">{{$val.Name}}</option> | ||||||
|                                         {{end}} |                                         {{end}} | ||||||
|                                     </select> |                                     </select> | ||||||
|                                 </div> |                                 </div> | ||||||
|  |                                 <div class="field auth-name hidden"> | ||||||
|  |                                     <label class="req" for="loginname">{{.i18n.Tr "admin.users.auth_login_name"}}</label> | ||||||
|  |                                     <input class="ipt ipt-large ipt-radius {{if .Err_LoginName}}ipt-error{{end}}" id="loginname" name="loginname" value="{{.loginname}}" /> | ||||||
|                                 </div> |                                 </div> | ||||||
|  |                                 <div class="field"> | ||||||
| 					<div class="auth-name hidden"> |                                     <label class="req" for="username">{{.i18n.Tr "username"}}</label> | ||||||
|                         <div class="form-group"> |                                     <input class="ipt ipt-large ipt-radius {{if .Err_UserName}}ipt-error{{end}}" id="username" name="uname" type="text" value="{{.uname}}" required /> | ||||||
|                             <label class="col-md-3 control-label">Auth Login Name: </label> |  | ||||||
|                             <div class="col-md-7"> |  | ||||||
|                                 <input name="loginname" class="form-control" placeholder="Type auth login's username" value="{{.loginname}}"> |  | ||||||
|                                 </div> |                                 </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="{{.email}}" required/> | ||||||
|                                 </div> |                                 </div> | ||||||
|  |                                 <div class="field pwd"> | ||||||
|  |                                     <label class="req" for="password">{{.i18n.Tr "password"}}</label> | ||||||
|  |                                     <input class="ipt ipt-large ipt-radius {{if .Err_Password}}ipt-error{{end}}" id="password" name="password" type="password" value="{{.password}}" required/> | ||||||
|                                 </div> |                                 </div> | ||||||
| 					 |                                 <div class="field"> | ||||||
| 					<div class="form-group {{if .Err_UserName}}has-error has-feedback{{end}}"> |                                     <label class="req" for="re-type">{{.i18n.Tr "re_type"}}</label> | ||||||
| 						<label class="col-md-3 control-label">Username: </label> |                                     <input class="ipt ipt-large ipt-radius {{if .Err_Password}}ipt-error{{end}}" id="re-type" name="retype" type="password" required/> | ||||||
| 						<div class="col-md-7"> |  | ||||||
| 							<input name="username" class="form-control" placeholder="Type account's username" value="{{.username}}" required="required"> |  | ||||||
| 						</div> |  | ||||||
| 					</div> |  | ||||||
|  |  | ||||||
| 					<div class="form-group {{if .Err_Email}}has-error has-feedback{{end}}"> |  | ||||||
| 						<label class="col-md-3 control-label">Email: </label> |  | ||||||
| 						<div class="col-md-7"> |  | ||||||
| 							<input name="email" class="form-control" placeholder="Type account's e-mail address" value="{{.email}}" required="required" title="Email is not valid"> |  | ||||||
| 						</div> |  | ||||||
| 					</div> |  | ||||||
|  |  | ||||||
| 					<div class="pwd"> |  | ||||||
|                         <div class="form-group {{if .Err_Password}}has-error has-feedback{{end}}"> |  | ||||||
|                             <label class="col-md-3 control-label">Password: </label> |  | ||||||
|                             <div class="col-md-7"> |  | ||||||
|                                 <input name="passwd" type="password" class="form-control" placeholder="Type account's password" required="required" title="Password must contain at least 6 characters"> |  | ||||||
|                             </div> |  | ||||||
|                         </div> |  | ||||||
|  |  | ||||||
|                         <div class="form-group {{if .Err_RetypePasswd}}has-error has-feedback{{end}}"> |  | ||||||
|                             <label class="col-md-3 control-label">Re-type: </label> |  | ||||||
|                             <div class="col-md-7"> |  | ||||||
|                                 <input name="retypepasswd" type="password" class="form-control" placeholder="Re-type account's password" required="required" title="Re-type Password must be same to Password"> |  | ||||||
|                             </div> |  | ||||||
|                         </div> |  | ||||||
| 					</div> |  | ||||||
|                     <hr/> |  | ||||||
|                     <div class="form-group"> |  | ||||||
|                         <div class="col-md-offset-3 col-md-7"> |  | ||||||
|                             <button type="submit" class="btn btn-lg btn-primary">Create new account</button> |  | ||||||
|                                 </div> |                                 </div> | ||||||
|  |                                 <div class="field"> | ||||||
|  |                                     <span class="form-label"></span> | ||||||
|  |                                     <button class="btn btn-blue btn-large btn-radius">{{.i18n.Tr "admin.users.new_account"}}</button> | ||||||
|                                 </div> |                                 </div> | ||||||
| 				            </form> | 				            </form> | ||||||
|                         </div> |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|     </div> |     </div> | ||||||
| </div> | </div> | ||||||
| <script> | {{template "ng/base/footer" .}} | ||||||
|     $(function(){ |  | ||||||
|         $('#login-type').on("change",function(){ |  | ||||||
|             var v = $(this).val(); |  | ||||||
|             if(v.indexOf("0-")+1){ |  | ||||||
|                 $('.auth-name').toggleHide(); |  | ||||||
|                 $(".pwd").find("input").attr("required","required") |  | ||||||
|                         .end().toggleShow(); |  | ||||||
|             }else{ |  | ||||||
|                 $(".pwd").find("input").removeAttr("required") |  | ||||||
|                         .end().toggleHide(); |  | ||||||
|                 $('.auth-name').toggleShow(); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|     }); |  | ||||||
| </script> |  | ||||||
| {{template "base/footer" .}} |  | ||||||
| @@ -1,49 +0,0 @@ | |||||||
| {{template "base/head" .}} |  | ||||||
| {{template "base/navbar" .}} |  | ||||||
| <div id="body" class="container" data-page="admin"> |  | ||||||
|     {{template "admin/nav" .}} |  | ||||||
|     <div id="admin-container" class="col-md-10"> |  | ||||||
|         <div class="panel panel-default"> |  | ||||||
|             <div class="panel-heading"> |  | ||||||
|                 User Management |  | ||||||
|             </div> |  | ||||||
|  |  | ||||||
|             <div class="panel-body"> |  | ||||||
|                 <a href="/admin/users/new" class="btn btn-primary">New Account</a> |  | ||||||
|                 <table class="table table-striped"> |  | ||||||
|                     <thead> |  | ||||||
|                         <tr> |  | ||||||
|                             <th>Id</th> |  | ||||||
|                             <th>Name</th> |  | ||||||
|                             <th>E-mail</th> |  | ||||||
|                             <th>Actived</th> |  | ||||||
|                             <th>Admin</th> |  | ||||||
|                             <th>Repos</th> |  | ||||||
|                             <th>Join</th> |  | ||||||
|                             <th>Edit</th> |  | ||||||
|                         </tr> |  | ||||||
|                     </thead> |  | ||||||
|                     <tbody> |  | ||||||
|                         {{range .Users}} |  | ||||||
|                         <tr> |  | ||||||
|                             <td>{{.Id}}</td> |  | ||||||
|                             <td><a href="/user/{{.Name}}">{{.Name}}</a></td> |  | ||||||
|                             <td>{{.Email}}</td> |  | ||||||
|                             <td><i class="fa fa{{if .IsActive}}-check{{end}}-square-o"></i></td> |  | ||||||
|                             <td><i class="fa fa{{if .IsAdmin}}-check{{end}}-square-o"></i></td> |  | ||||||
|                             <td>{{.NumRepos}}</td> |  | ||||||
|                             <td>{{DateFormat .Created "M d, Y"}}</td> |  | ||||||
|                             <td><a href="/admin/users/{{.Id}}"><i class="fa fa-pencil-square-o"></i></a></td> |  | ||||||
|                         </tr> |  | ||||||
|                         {{end}} |  | ||||||
|                     </tbody> |  | ||||||
|                 </table> |  | ||||||
|                 <ul class="pagination"> |  | ||||||
|                     {{if .LastPageNum}}<li><a href="/admin/users?p={{.LastPageNum}}">« Prev.</a></li>{{end}} |  | ||||||
|                     {{if .NextPageNum}}<li><a href="/admin/users?p={{.NextPageNum}}">» Next</a></li>{{end}} |  | ||||||
|                 </ul> |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|     </div> |  | ||||||
| </div> |  | ||||||
| {{template "base/footer" .}} |  | ||||||
| @@ -7,19 +7,26 @@ | |||||||
| 		<meta name="description" content="Gogs(Go Git Service) a painless self-hosted Git Service written in Go" /> | 		<meta name="description" content="Gogs(Go Git Service) a painless self-hosted Git Service written in Go" /> | ||||||
| 		<meta name="keywords" content="go, git, self-hosted, gogs"> | 		<meta name="keywords" content="go, git, self-hosted, gogs"> | ||||||
| 		<meta name="_csrf" content="{{.CsrfToken}}" /> | 		<meta name="_csrf" content="{{.CsrfToken}}" /> | ||||||
|  | 		{{if .Repository.IsGoget}}<meta name="go-import" content="{{.GoGetImport}} git {{.CloneLink.HTTPS}}">{{end}} | ||||||
|  |  | ||||||
| 		<link rel="shortcut icon" href="/img/favicon.png" /> | 		<link rel="shortcut icon" href="/img/favicon.png" /> | ||||||
|  |  | ||||||
|  | 		{{if CdnMode}} | ||||||
|  | 		<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css"> | ||||||
|  |  | ||||||
|  | 		<script src="//code.jquery.com/jquery-1.11.1.min.js"></script> | ||||||
|  | 		{{else}} | ||||||
|  | 		<link rel="stylesheet" href="/css/font-awesome.min.css"> | ||||||
|  | 		 | ||||||
|  | 		<script src="/ng/js/lib/jquery-1.11.1.min.js"></script> | ||||||
|  | 		{{end}} | ||||||
| 		<!-- Stylesheet --> | 		<!-- Stylesheet --> | ||||||
| 		<link rel="stylesheet" href="/ng/css/ui.css"> | 		<link rel="stylesheet" href="/ng/css/ui.css"> | ||||||
| 		<link rel="stylesheet" href="/ng/css/gogs.css"> | 		<link rel="stylesheet" href="/ng/css/gogs.css"> | ||||||
| 		<link rel="stylesheet" href="/css/font-awesome.min.css"> |  | ||||||
| 		<link rel="stylesheet" href="/ng/fonts/octicons.css"> | 		<link rel="stylesheet" href="/ng/fonts/octicons.css"> | ||||||
| 		<!-- <link rel="stylesheet" href="http://cdn.bootcss.com/highlight.js/8.1/styles/github.min.css"> --> |  | ||||||
| 		<link rel="stylesheet" href="/css/github.min.css"> | 		<link rel="stylesheet" href="/css/github.min.css"> | ||||||
|  |  | ||||||
| 		<!-- JavaScript --> | 		<!-- JavaScript --> | ||||||
| 		<script src="/ng/js/lib/jquery-1.11.1.min.js"></script> |  | ||||||
| 		<script src="/ng/js/lib/tabs.js"></script> | 		<script src="/ng/js/lib/tabs.js"></script> | ||||||
|     	<script src="/ng/js/lib/lib.js"></script> |     	<script src="/ng/js/lib/lib.js"></script> | ||||||
| 		<script src="/ng/js/gogs.js"></script> | 		<script src="/ng/js/gogs.js"></script> | ||||||
|   | |||||||
| @@ -1,75 +0,0 @@ | |||||||
| {{template "base/head" .}} |  | ||||||
| {{template "base/navbar" .}} |  | ||||||
| <div id="body-nav" class="org-nav org-nav-auto"> |  | ||||||
|     <div class="container clearfix"> |  | ||||||
|         <div id="org-nav-wrapper"> |  | ||||||
|             <ul class="nav nav-pills pull-right"> |  | ||||||
|                 <li><a href="#"><i class="fa fa-users"></i>Members |  | ||||||
|                     <span class="label label-default">5</span></a> |  | ||||||
|                 </li> |  | ||||||
|                 <li class="active"><a href="#"><i class="fa fa-tags"></i>Teams |  | ||||||
|                     <span class="label label-default">2</span></a> |  | ||||||
|                 </li> |  | ||||||
|             </ul> |  | ||||||
|             <img class="pull-left org-small-logo" src="https://avatars3.githubusercontent.com/u/6656686?s=140" alt="" width="60"/> |  | ||||||
|             <div id="org-nav-info"> |  | ||||||
|                 <h2 class="org-name">Organization Name</h2> |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|     </div> |  | ||||||
| </div> |  | ||||||
| <div id="body" class="container"> |  | ||||||
|     <div id="org"> |  | ||||||
|         <form id="org-teams-edit" class="form-horizontal card"> |  | ||||||
|             <h3>Edit team</h3> |  | ||||||
|             <div class="form-group"> |  | ||||||
|                 <label class="col-md-2 control-label">Team Name<strong class="text-danger">*</strong></label> |  | ||||||
|                 <div class="col-md-8"> |  | ||||||
|                     <input name="team" type="text" class="form-control" placeholder="Type your team name" value="" required="required"> |  | ||||||
|                     <span class="help-block">You'll use this name to mention this team in conversations.</span> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-group"> |  | ||||||
|                 <label class="col-md-2 control-label">Description</label> |  | ||||||
|                 <div class="col-md-8"> |  | ||||||
|                     <input name="desc" type="text" class="form-control" placeholder="Type your team description (optional)" value=""> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-group"> |  | ||||||
|                 <label class="col-md-2 control-label">Permission</label> |  | ||||||
|                 <div class="col-md-8"> |  | ||||||
|                     <div class="radio"> |  | ||||||
|                         <label> |  | ||||||
|                             <input type="radio" name="permission" value="pull" checked=""> |  | ||||||
|                             <strong>Read & Clone</strong> |  | ||||||
|                         </label> |  | ||||||
|                         <p>This team will be able to view and clone its repositories.</p> |  | ||||||
|                     </div> |  | ||||||
|                     <div class="radio"> |  | ||||||
|                         <label> |  | ||||||
|                             <input type="radio" name="permission" value="push"> |  | ||||||
|                             <strong>Push, Read & Clone</strong> |  | ||||||
|                         </label> |  | ||||||
|                         <p>This team will be able to read its repositories, as well as push to them.</p> |  | ||||||
|                     </div> |  | ||||||
|                     <div class="radio"> |  | ||||||
|                         <label> |  | ||||||
|                             <input type="radio" name="permission" value="admin"> |  | ||||||
|                             <strong>Collaboration, Push, Read & Clone</strong> |  | ||||||
|                         </label> |  | ||||||
|                         <p>This team will be able to push/pull to its repositories, as well as add other collaborators to them.</p> |  | ||||||
|                     </div> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <hr/> |  | ||||||
|             <div class="form-group"> |  | ||||||
|                 <label class="col-md-2"> </label> |  | ||||||
|                 <div class="col-md-8"> |  | ||||||
|                     <button class="btn btn-primary">Edit this team</button> |  | ||||||
|                     <button class="btn btn-danger pull-right" value="delete" name="delete">Delete this team</button> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|         </form> |  | ||||||
|     </div> |  | ||||||
| </div> |  | ||||||
| {{template "base/footer" .}} |  | ||||||
| @@ -1,106 +0,0 @@ | |||||||
| {{template "base/head" .}} |  | ||||||
| {{template "base/navbar" .}} |  | ||||||
| <div id="body-nav" class="org-nav org-nav-auto"> |  | ||||||
|     <div class="container clearfix"> |  | ||||||
|         <div id="org-nav-wrapper"> |  | ||||||
|             <ul class="nav nav-pills pull-right"> |  | ||||||
|                 <li><a href="#"><i class="fa fa-users"></i>Members |  | ||||||
|                     <span class="label label-default">5</span></a> |  | ||||||
|                 </li> |  | ||||||
|                 <li class="active"><a href="#"><i class="fa fa-tags"></i>Teams |  | ||||||
|                     <span class="label label-default">2</span></a> |  | ||||||
|                 </li> |  | ||||||
|             </ul> |  | ||||||
|             <img class="pull-left org-small-logo" src="https://avatars3.githubusercontent.com/u/6656686?s=140" alt="" width="60"/> |  | ||||||
|             <div id="org-nav-info"> |  | ||||||
|                 <h2 class="org-name">Organization Name</h2> |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|     </div> |  | ||||||
| </div> |  | ||||||
| <div id="body" class="container"> |  | ||||||
|     <div id="org"> |  | ||||||
|         <div id="org-team"> |  | ||||||
|             <div id="org-team-card" class="col-md-3"> |  | ||||||
|                 <h3 class="title">Team name</h3> |  | ||||||
|                 <p class="desc">team description</p> |  | ||||||
|                 <hr/> |  | ||||||
|                 <div class="meta"> |  | ||||||
|                     <div class="col-md-6"> |  | ||||||
|                         <a href="#"><span class="num"><strong>1</strong></span> |  | ||||||
|                             <br/>Member</a> |  | ||||||
|                     </div> |  | ||||||
|                     <div class="col-md-6"> |  | ||||||
|                         <a href="#"><span class="num"><strong>1</strong></span> |  | ||||||
|                             <br/>Repository</a> |  | ||||||
|                     </div> |  | ||||||
|                 </div> |  | ||||||
|                 <hr style="width: 100%"/> |  | ||||||
|                 <div class="action"> |  | ||||||
|                     <a href="#"> |  | ||||||
|                         <button class="btn btn-danger">Leave</button> |  | ||||||
|                     </a> |  | ||||||
|                     <a href="#"> |  | ||||||
|                         <button class="btn btn-success">Edit</button> |  | ||||||
|                     </a> |  | ||||||
|                     <a href="#"> |  | ||||||
|                         <button class="btn btn-default">Setting</button> |  | ||||||
|                     </a> |  | ||||||
|                 </div> |  | ||||||
|                 <hr/> |  | ||||||
|                 <p>This team grants <strong>Push, Read & Clone</strong> access: members can read from and push to the team's repositories.</p> |  | ||||||
|             </div> |  | ||||||
|             <div id="org-team-content" class="col-md-9"> |  | ||||||
|                 <div class="header"> |  | ||||||
|                     <div class="header-tab col-md-4"> |  | ||||||
|                         <div class="btn-group"> |  | ||||||
|                             <a class="btn btn-primary" href="#">Members</a> |  | ||||||
|                             <a class="btn btn-default" href="#">Repositories</a> |  | ||||||
|                         </div> |  | ||||||
|                     </div> |  | ||||||
|                     <form id="org-team-add-user-form" action="url" class="col-md-4 pull-right open" method="post"> |  | ||||||
|                         <input type="text" class="form-control" name="user" placeholder="add user to teams" id="org-team-add-user"/> |  | ||||||
|                         <div class="dropdown-menu"> |  | ||||||
|                             <ul class="list-unstyled"></ul> |  | ||||||
|                         </div> |  | ||||||
|                         <input type="hidden" name="team" value="team-id"/> |  | ||||||
|                     </form> |  | ||||||
|                 </div> |  | ||||||
|                 <div class="content" id="org-team-members"> |  | ||||||
|                     <div class="member">  |  | ||||||
|                         <div class="avatar col-md-1"> |  | ||||||
|                             <img src="https://avatars3.githubusercontent.com/u/2142787?s=140" alt=""> |  | ||||||
|                         </div> |  | ||||||
|                         <div class="name col-md-4"> |  | ||||||
|                             <a href="#"><strong>fuxiaohei</strong><span class="nick">傅小黑</span></a> |  | ||||||
|                         </div> |  | ||||||
|                         <a class="remove btn btn-danger pull-right" href="#">Remove</a> |  | ||||||
|                     </div> |  | ||||||
|                 </div> |  | ||||||
|                 <!---------------------- for ?member or ?repo ----------> |  | ||||||
|                 <div class="header"> |  | ||||||
|                     <div class="header-tab col-md-4"> |  | ||||||
|                         <div class="btn-group"> |  | ||||||
|                             <a class="btn btn-default" href="#">Members</a> |  | ||||||
|                             <a class="btn btn-primary" href="#">Repositories</a> |  | ||||||
|                         </div> |  | ||||||
|                     </div> |  | ||||||
|                     <form id="org-team-add-repo-form" action="url" class="col-md-4 pull-right open" method="post"> |  | ||||||
|                         <input type="text" class="form-control" name="repo" placeholder="add repository to teams" id="org-team-add-repo"/> |  | ||||||
|                         <div class="dropdown-menu"> |  | ||||||
|                             <ul class="list-unstyled"></ul> |  | ||||||
|                         </div> |  | ||||||
|                         <input type="hidden" name="team" value="team-id"/> |  | ||||||
|                     </form> |  | ||||||
|                 </div> |  | ||||||
|                 <div class="content" id="org-team-repos"> |  | ||||||
|                     <div class="repo"> |  | ||||||
|                         <a href="#" class="repo-name"><i class="fa fa-book"></i> repo-name</a> |  | ||||||
|                         <a class="remove btn btn-danger pull-right" href="#">Remove</a> |  | ||||||
|                     </div> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|     </div> |  | ||||||
| </div> |  | ||||||
| {{template "base/footer" .}} |  | ||||||
| @@ -16,7 +16,7 @@ | |||||||
|             </div> |             </div> | ||||||
|             <div class="field"> |             <div class="field"> | ||||||
|                 <label class="req" for="email">{{.i18n.Tr "email"}}</label> |                 <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="{{.email}}"required/> |                 <input class="ipt ipt-large ipt-radius {{if .Err_Email}}ipt-error{{end}}" id="email" name="email" type="email" value="{{.email}}" required /> | ||||||
|             </div> |             </div> | ||||||
|             <div class="field"> |             <div class="field"> | ||||||
|                 <label class="req" for="password">{{.i18n.Tr "password"}}</label> |                 <label class="req" for="password">{{.i18n.Tr "password"}}</label> | ||||||
|   | |||||||
| @@ -39,7 +39,7 @@ | |||||||
|                                 <input class="ipt ipt-large ipt-radius {{if .Err_Avatar}}ipt-error{{end}}" id="gravatar-email" name="avatar" type="text" value="{{.SignedUser.AvatarEmail}}" /> |                                 <input class="ipt ipt-large ipt-radius {{if .Err_Avatar}}ipt-error{{end}}" id="gravatar-email" name="avatar" type="text" value="{{.SignedUser.AvatarEmail}}" /> | ||||||
|                             </div> |                             </div> | ||||||
|                             <div class="field"> |                             <div class="field"> | ||||||
|                                 <span class="form-label"></span> |                                 <label></label> | ||||||
|                                 <button class="btn btn-green btn-large btn-radius">{{.i18n.Tr "settings.update_profile"}}</button> |                                 <button class="btn btn-green btn-large btn-radius">{{.i18n.Tr "settings.update_profile"}}</button> | ||||||
|                             </div> |                             </div> | ||||||
|                         </form> |                         </form> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Unknwon
					Unknwon