diff options
author | Unknwon <joe2010xtmf@163.com> | 2014-08-29 15:32:52 +0800 |
---|---|---|
committer | Unknwon <joe2010xtmf@163.com> | 2014-08-29 15:32:52 +0800 |
commit | 88291745747ffb200b55ca62e1054d1d2c4315d3 (patch) | |
tree | 493d0cfe13d53c0720a25d30ced2b0d8d4f39d1a | |
parent | 6558990e3a1e3d5aac595e0f0b525a834d708647 (diff) | |
download | gitea-88291745747ffb200b55ca62e1054d1d2c4315d3.tar.gz gitea-88291745747ffb200b55ca62e1054d1d2c4315d3.zip |
Finish new admin users pages
-rw-r--r-- | README.md | 5 | ||||
-rw-r--r-- | README_ZH.md | 9 | ||||
-rw-r--r-- | cmd/web.go | 2 | ||||
-rw-r--r-- | conf/locale/locale_en-US.ini | 20 | ||||
-rw-r--r-- | conf/locale/locale_zh-CN.ini | 19 | ||||
-rw-r--r-- | gogs.go | 2 | ||||
-rw-r--r-- | modules/auth/admin.go | 2 | ||||
-rw-r--r-- | public/ng/css/gogs.css | 20 | ||||
-rw-r--r-- | public/ng/js/gogs.js | 28 | ||||
-rw-r--r-- | public/ng/less/gogs/admin.less | 5 | ||||
-rw-r--r-- | public/ng/less/gogs/base.less | 41 | ||||
-rw-r--r-- | routers/admin/admin.go | 30 | ||||
-rw-r--r-- | routers/admin/user.go | 193 | ||||
-rw-r--r-- | routers/admin/users.go | 224 | ||||
-rw-r--r-- | templates/.VERSION | 2 | ||||
-rw-r--r-- | templates/admin/dashboard.tmpl | 2 | ||||
-rw-r--r-- | templates/admin/user/edit.tmpl | 180 | ||||
-rw-r--r-- | templates/admin/user/list.tmpl | 62 | ||||
-rw-r--r-- | templates/admin/user/new.tmpl | 140 | ||||
-rw-r--r-- | templates/admin/users.tmpl | 49 | ||||
-rw-r--r-- | templates/ng/base/head.tmpl | 13 | ||||
-rw-r--r-- | templates/org/edit_team.tmpl | 75 | ||||
-rw-r--r-- | templates/org/team.tmpl | 106 | ||||
-rw-r--r-- | templates/user/auth/signup.tmpl | 2 | ||||
-rw-r--r-- | templates/user/settings/profile.tmpl | 2 |
25 files changed, 554 insertions, 679 deletions
@@ -5,7 +5,7 @@ Gogs(Go Git Service) is a painless self-hosted Git Service written in Go. ![Demo](http://gowalker.org/public/gogs_demo.gif) -##### Current version: 0.4.7 Alpha +##### Current version: 0.4.7 Beta ### 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 - SMTP/LDAP/reverse proxy authentication support - Register/delete/rename account +- Create/manage/delete organization with team management - Create/migrate/mirror/delete/watch/rename/transfer public/private repository - Repository viewer/release/issue tracker/webhooks - 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 - Supports MySQL, PostgreSQL and SQLite3 - Social account login(GitHub, Google, QQ, Weibo) -- Multi-language support(English, Chinese, etc.) +- Multi-language support(English, Chinese, Germany etc.) ## System Requirements diff --git a/README_ZH.md b/README_ZH.md index cdf858e77a..fd78922ab7 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -5,7 +5,7 @@ Gogs(Go Git Service) 是一个基于 Go 语言的自助 Git 服务。 ![Demo](http://gowalker.org/public/gogs_demo.gif) -##### 当前版本:0.4.7 Alpha +##### 当前版本:0.4.7 Beta ## 开发目的 @@ -23,16 +23,17 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自 - 活动时间线 - 支持 SSH/HTTP(S) 协议 - 支持 SMTP/LDAP/反向代理 用户认证 -- 注册/删除/重命名用户 +- 注册/删除/重命名 用户 +- 创建/管理/删除 组织以及团队管理功能 - 创建/迁移/镜像/删除/关注/重命名/转移 公开/私有 仓库 -- 仓库 浏览器/发布/缺陷管理/Web 钩子 +- 仓库 浏览/发布/工单管理/Web 钩子 - 添加/删除 仓库协作者 - Gravatar 以及缓存支持 - 邮件服务(注册、Issue) - 管理员面板 - 支持 MySQL、PostgreSQL 以及 SQLite3 数据库 - 社交帐号登录(GitHub、Google、QQ、微博) -- 多语言支持(英文、简体中文等等) +- 多语言支持(英文、简体中文、德语等等) ## 系统要求 diff --git a/cmd/web.go b/cmd/web.go index 1ce671be41..8e471eb61f 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -200,7 +200,7 @@ func runWeb(*cli.Context) { r.Post("/new", bindIgnErr(auth.RegisterForm{}), admin.NewUserPost) r.Get("/:userid", admin.EditUser) r.Post("/:userid", bindIgnErr(auth.AdminEditUserForm{}), admin.EditUserPost) - r.Get("/:userid/delete", admin.DeleteUser) + r.Post("/:userid/delete", admin.DeleteUser) }, adminReq) m.Group("/admin/auths", func(r *macaron.Router) { diff --git a/conf/locale/locale_en-US.ini b/conf/locale/locale_en-US.ini index 7882fedde8..106e765cb8 100644 --- a/conf/locale/locale_en-US.ini +++ b/conf/locale/locale_en-US.ini @@ -340,6 +340,26 @@ dashboard.total_gc_pause = Total GC Pause dashboard.last_gc_pause = Last GC Pause 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] 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> diff --git a/conf/locale/locale_zh-CN.ini b/conf/locale/locale_zh-CN.ini index 384c36c020..2254f370ba 100644 --- a/conf/locale/locale_zh-CN.ini +++ b/conf/locale/locale_zh-CN.ini @@ -340,6 +340,25 @@ dashboard.total_gc_pause = GC 暂停时间总量 dashboard.last_gc_pause = 上次 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] create_repo = 创建了仓库 <a href="/%s">%s</a> commit_repo = 推送了 <a href="/%s/src/%s">%s</a> 分支的代码到 <a href="/%s">%s</a> @@ -17,7 +17,7 @@ import ( "github.com/gogits/gogs/modules/setting" ) -const APP_VER = "0.4.7.0827 Alpha" +const APP_VER = "0.4.7.0829 Alpha" func init() { runtime.GOMAXPROCS(runtime.NumCPU()) diff --git a/modules/auth/admin.go b/modules/auth/admin.go index 38f3292b88..1f1260d65a 100644 --- a/modules/auth/admin.go +++ b/modules/auth/admin.go @@ -13,7 +13,7 @@ import ( type AdminEditUserForm struct { Email string `form:"email" binding:"Required;Email;MaxSize(50)"` - Passwd string `form:"passwd"` + Passwd string `form:"password"` Website string `form:"website" binding:"MaxSize(50)"` Location string `form:"location" binding:"MaxSize(50)"` Avatar string `form:"avatar" binding:"Required;Email;MaxSize(50)"` diff --git a/public/ng/css/gogs.css b/public/ng/css/gogs.css index dac5870064..34d71028e7 100644 --- a/public/ng/css/gogs.css +++ b/public/ng/css/gogs.css @@ -249,9 +249,22 @@ img.avatar-100 { padding: 8px; vertical-align: top; } -th { +.table th { 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 { background-color: white; font-size: 16px; @@ -1925,11 +1938,14 @@ textarea#issue-add-content { height: 40px; line-height: 40px; } +.admin-panel { + padding: 10px 20px; +} .admin-desc { padding: 10px 20px; } .admin-table { - padding: 15px 20px 5px 20px; + padding: 15px 0 5px 0; } .dl-horizontal dt { float: left; diff --git a/public/ng/js/gogs.js b/public/ng/js/gogs.js index d4c3224eee..69ac380fd9 100644 --- a/public/ng/js/gogs.js +++ b/public/ng/js/gogs.js @@ -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 () { initCore(); if ($('#user-profile-setting').length) { @@ -453,6 +478,9 @@ $(document).ready(function () { if ($('#team-repositories-list').length) { initTeamRepositoriesList(); } + if ($('#admin-setting').length) { + initAdmin(); + } Tabs('#dashboard-sidebar-menu'); diff --git a/public/ng/less/gogs/admin.less b/public/ng/less/gogs/admin.less index d327f681fd..010e0f06f6 100644 --- a/public/ng/less/gogs/admin.less +++ b/public/ng/less/gogs/admin.less @@ -1,8 +1,11 @@ +.admin-panel { + padding: 10px 20px; +} .admin-desc { padding: 10px 20px; } .admin-table { - padding: 15px 20px 5px 20px; + padding: 15px 0 5px 0; } .dl-horizontal dt { float: left; diff --git a/public/ng/less/gogs/base.less b/public/ng/less/gogs/base.less index 7ef7d24ccd..0ca733c519 100644 --- a/public/ng/less/gogs/base.less +++ b/public/ng/less/gogs/base.less @@ -254,18 +254,33 @@ clear: both; .table { width: 100%; max-width: 100%; + > thead > tr > th, + > tbody > tr > th, + > tfoot > tr > th, + > thead > tr > td, + > tbody > tr > td, + > tfoot > tr > td { + border-top: 1px solid #e7eaec; + line-height: 1.42857; + padding: 8px; + vertical-align: top; + } + th { + text-align: left; + } +} +.table-striped { + >tbody>tr:nth-child(odd)>td, + >tbody>tr:nth-child(odd)>th { + background-color: #f9f9f9; + } } -.table > thead > tr > th, -.table > tbody > tr > th, -.table > tfoot > tr > th, -.table > thead > tr > td, -.table > tbody > tr > td, -.table > tfoot > tr > td { - border-top: 1px solid #e7eaec; - line-height: 1.42857; - padding: 8px; - vertical-align: top; -} -th { - text-align: left; +.pagination { + display: inline-block; + padding-left: 0; + margin: 20px 0; + border-radius: 4px; + li { + display: inline; + } }
\ No newline at end of file diff --git a/routers/admin/admin.go b/routers/admin/admin.go index ebc446b820..75dbf2712b 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -23,7 +23,6 @@ import ( const ( DASHBOARD base.TplName = "admin/dashboard" - USERS base.TplName = "admin/users" REPOS base.TplName = "admin/repos" AUTHS base.TplName = "admin/auths" CONFIG base.TplName = "admin/config" @@ -157,35 +156,6 @@ func Dashboard(ctx *middleware.Context) { 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) { ctx.Data["Title"] = "Repository Management" ctx.Data["PageIsRepos"] = true diff --git a/routers/admin/user.go b/routers/admin/user.go deleted file mode 100644 index 0355632b53..0000000000 --- a/routers/admin/user.go +++ /dev/null @@ -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") -} diff --git a/routers/admin/users.go b/routers/admin/users.go new file mode 100644 index 0000000000..5f98a64be6 --- /dev/null +++ b/routers/admin/users.go @@ -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") +} diff --git a/templates/.VERSION b/templates/.VERSION index f7f2473b40..102c742960 100644 --- a/templates/.VERSION +++ b/templates/.VERSION @@ -1 +1 @@ -0.4.7.0827 Alpha
\ No newline at end of file +0.4.7.0829 Alpha
\ No newline at end of file diff --git a/templates/admin/dashboard.tmpl b/templates/admin/dashboard.tmpl index 81c262e2e0..09e105826a 100644 --- a/templates/admin/dashboard.tmpl +++ b/templates/admin/dashboard.tmpl @@ -22,7 +22,7 @@ <div class="panel-header"> <strong>{{.i18n.Tr "admin.dashboard.operations"}}</strong> </div> - <div class="panel-body"> + <div class="panel-body admin-panel"> <div class="admin-table"> <table class="table"> <thead> diff --git a/templates/admin/user/edit.tmpl b/templates/admin/user/edit.tmpl index 5975832f32..e88126706e 100644 --- a/templates/admin/user/edit.tmpl +++ b/templates/admin/user/edit.tmpl @@ -1,110 +1,78 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -<div id="body" class="container" data-page="admin"> - {{template "admin/nav" .}} - <div id="admin-container" class="col-md-9"> - <div class="panel panel-default"> - <div class="panel-heading"> - Edit Account - </div> - - <div class="panel-body"> - <br/> - <form action="/admin/users/{{.User.Id}}" method="post" class="form-horizontal"> - {{.CsrfTokenHtml}} - {{template "base/alert" .}} - <div class="form-group"> - <label class="col-md-3 control-label">Auth Source: </label> - <div class="col-md-7"> - <select name="logintype" class="form-control"> - <option value="0-0">Local</option> - {{$tp := .User.LoginSource}} - {{range $key, $val := .LoginSources}} - <option value="{{$val.Type}}-{{$val.Id}}"{{if eq $val.Id $tp}} selected{{end}}>{{$val.Name}}</option> - {{end}} - </select> - </div> - </div> - - <div class="form-group"> - <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="{{.User.LoginName}}"> - </div> - </div> - - <div class="form-group"> - <label class="col-md-3 control-label">Username: </label> - <label class="control-label">{{.User.Name}}</label> - </div> - - <div class="form-group {{if .Err_Email}}has-error has-feedback{{end}}"> - <label class="col-md-3 control-label">Email<strong class="text-danger">*</strong></label> - <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="form-group"> - <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 new password or leave unfilled"> - </div> - </div> - - <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> +{{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.edit_account"}}</strong> + </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"> + {{.CsrfTokenHtml}} + <div class="field"> + <label class="req">{{.i18n.Tr "admin.users.auth_source"}}</label> + <select id="login-type" name="logintype"> + <option value="0-0">{{.i18n.Tr "admin.users.local"}}</option> + {{$tp := .User.LoginSource}} + {{range $key, $val := .LoginSources}} + <option value="{{$val.Type}}-{{$val.Id}}"{{if eq $val.Id $tp}} selected{{end}}>{{$val.Name}}</option> + {{end}} + </select> + </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 class="field"> + <label>{{.i18n.Tr "username"}}</label> + <label>{{.User.Name}}</label> + </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 class="field pwd"> + <label 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" /> + </div> + <div class="field"> + <label for="website">{{.i18n.Tr "settings.website"}}</label> + <input class="ipt ipt-large ipt-radius {{if .Err_Website}}ipt-error{{end}}" id="website" name="website" type="url" value="{{.User.Website}}" /> + </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 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="{{.User.AvatarEmail}}" /> + </div> + <div class="field"> + <label></label> <input type="checkbox" name="active" {{if .User.IsActive}}checked{{end}}> - <strong>This account is activated</strong> - </label> - </div> - </div> - </div> - - <div class="form-group"> - <div class="col-md-7 col-md-offset-3"> - <div class="checkbox"> - <label> + <strong>{{.i18n.Tr "admin.users.is_activated"}}</strong> + <br> + <label></label> <input type="checkbox" name="admin" {{if .User.IsAdmin}}checked{{end}}> - <strong>This account has administrator permissions</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> - </form> - </div> - </div> - + <strong>{{.i18n.Tr "admin.users.is_admin"}}</strong> + </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> + </form> + </div> + </div> + </div> + </div> + </div> </div> </div> -{{template "base/footer" .}} +{{template "ng/base/footer" .}} diff --git a/templates/admin/user/list.tmpl b/templates/admin/user/list.tmpl new file mode 100644 index 0000000000..39e348fdf0 --- /dev/null +++ b/templates/admin/user/list.tmpl @@ -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" .}}
\ No newline at end of file diff --git a/templates/admin/user/new.tmpl b/templates/admin/user/new.tmpl index 4f4866c4b6..19126ee0c4 100644 --- a/templates/admin/user/new.tmpl +++ b/templates/admin/user/new.tmpl @@ -1,94 +1,58 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -<div id="body" class="container" data-page="admin"> - {{template "admin/nav" .}} - <div id="admin-container" class="col-md-9"> - <div class="panel panel-default"> - <div class="panel-heading"> - New Account - </div> - - <div class="panel-body"> - <br/> - <form action="/admin/users/new" method="post" class="form-horizontal"> - {{.CsrfTokenHtml}} - {{template "base/alert" .}} - <div class="form-group"> - <label class="col-md-3 control-label">Auth Source: </label> - <div class="col-md-7"> - <select name="logintype" class="form-control" id="login-type"> - <option value="0-0">Local</option> - {{range $key, $val := .LoginSources}} - <option value="{{$val.Type}}-{{$val.Id}}">{{$val.Name}}</option> - {{end}} - </select> - </div> - </div> - - <div class="auth-name hidden"> - <div class="form-group"> - <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> - - <div class="form-group {{if .Err_UserName}}has-error has-feedback{{end}}"> - <label class="col-md-3 control-label">Username: </label> - <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"> +{{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.new_account"}}</strong> </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> + <form class="form form-align panel-body" id="repo-setting-form" action="/admin/users/new" method="post"> + {{.CsrfTokenHtml}} + <div class="field"> + <label class="req">{{.i18n.Tr "admin.users.auth_source"}}</label> + <select id="login-type" name="logintype"> + <option value="0-0">{{.i18n.Tr "admin.users.local"}}</option> + {{range $key, $val := .LoginSources}} + <option value="{{$val.Type}}-{{$val.Id}}">{{$val.Name}}</option> + {{end}} + </select> + </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 class="field"> + <label class="req" for="username">{{.i18n.Tr "username"}}</label> + <input class="ipt ipt-large ipt-radius {{if .Err_UserName}}ipt-error{{end}}" id="username" name="uname" type="text" value="{{.uname}}" required /> + </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 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 class="field"> + <label class="req" for="re-type">{{.i18n.Tr "re_type"}}</label> + <input class="ipt ipt-large ipt-radius {{if .Err_Password}}ipt-error{{end}}" id="re-type" name="retype" type="password" required/> + </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> + </form> </div> </div> - </form> + </div> </div> </div> - - </div> + </div> </div> -<script> - $(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" .}}
\ No newline at end of file +{{template "ng/base/footer" .}}
\ No newline at end of file diff --git a/templates/admin/users.tmpl b/templates/admin/users.tmpl deleted file mode 100644 index 0efe909296..0000000000 --- a/templates/admin/users.tmpl +++ /dev/null @@ -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" .}}
\ No newline at end of file diff --git a/templates/ng/base/head.tmpl b/templates/ng/base/head.tmpl index 817c18807a..815453446a 100644 --- a/templates/ng/base/head.tmpl +++ b/templates/ng/base/head.tmpl @@ -7,19 +7,26 @@ <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="_csrf" content="{{.CsrfToken}}" /> + {{if .Repository.IsGoget}}<meta name="go-import" content="{{.GoGetImport}} git {{.CloneLink.HTTPS}}">{{end}} <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 --> <link rel="stylesheet" href="/ng/css/ui.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="http://cdn.bootcss.com/highlight.js/8.1/styles/github.min.css"> --> <link rel="stylesheet" href="/css/github.min.css"> <!-- 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/lib.js"></script> <script src="/ng/js/gogs.js"></script> diff --git a/templates/org/edit_team.tmpl b/templates/org/edit_team.tmpl deleted file mode 100644 index 4292575c87..0000000000 --- a/templates/org/edit_team.tmpl +++ /dev/null @@ -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" .}} diff --git a/templates/org/team.tmpl b/templates/org/team.tmpl deleted file mode 100644 index aab42f3e7c..0000000000 --- a/templates/org/team.tmpl +++ /dev/null @@ -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" .}} diff --git a/templates/user/auth/signup.tmpl b/templates/user/auth/signup.tmpl index b4736a07ce..d116ad6276 100644 --- a/templates/user/auth/signup.tmpl +++ b/templates/user/auth/signup.tmpl @@ -16,7 +16,7 @@ </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/> + <input class="ipt ipt-large ipt-radius {{if .Err_Email}}ipt-error{{end}}" id="email" name="email" type="email" value="{{.email}}" required /> </div> <div class="field"> <label class="req" for="password">{{.i18n.Tr "password"}}</label> diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index 33e6a944d7..3fff074842 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -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}}" /> </div> <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> </div> </form> |