]> source.dussan.org Git - gitea.git/commitdiff
Finish new admin users pages
authorUnknwon <joe2010xtmf@163.com>
Fri, 29 Aug 2014 07:32:52 +0000 (15:32 +0800)
committerUnknwon <joe2010xtmf@163.com>
Fri, 29 Aug 2014 07:32:52 +0000 (15:32 +0800)
25 files changed:
README.md
README_ZH.md
cmd/web.go
conf/locale/locale_en-US.ini
conf/locale/locale_zh-CN.ini
gogs.go
modules/auth/admin.go
public/ng/css/gogs.css
public/ng/js/gogs.js
public/ng/less/gogs/admin.less
public/ng/less/gogs/base.less
routers/admin/admin.go
routers/admin/user.go [deleted file]
routers/admin/users.go [new file with mode: 0644]
templates/.VERSION
templates/admin/dashboard.tmpl
templates/admin/user/edit.tmpl
templates/admin/user/list.tmpl [new file with mode: 0644]
templates/admin/user/new.tmpl
templates/admin/users.tmpl [deleted file]
templates/ng/base/head.tmpl
templates/org/edit_team.tmpl [deleted file]
templates/org/team.tmpl [deleted file]
templates/user/auth/signup.tmpl
templates/user/settings/profile.tmpl

index e709e76147e44c0f3759a5d1b57bcd1d1684b483..78f8c40cad5a70ed00abe2cbd45dd488c93ad451 100644 (file)
--- a/README.md
+++ b/README.md
@@ -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
 
index cdf858e77a22db9ac417cce6d3d49330bd37d4d1..fd78922ab70f45ff8a1c7b0d45232a12cc5df3c2 100644 (file)
@@ -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、微博)
-- 多语言支持(英文、简体中文等等)
+- 多语言支持(英文、简体中文、德语等等)
 
 ## 系统要求
 
index 1ce671be412a3db2045697ff82011ec63b03298f..8e471eb61f6d5efbc4fee9329bf8150ea5f2de06 100644 (file)
@@ -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) {
index 7882fedde85aa547c9aef2f20dac448a4ba4ab40..106e765cb8c767becfd075cbf9aa3a0e5a7abb76 100644 (file)
@@ -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>
index 384c36c02051076d1c289ee2036461c9b4b4f531..2254f370ba72ee164482571433e089fc655a62e2 100644 (file)
@@ -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>
diff --git a/gogs.go b/gogs.go
index 724a6835820fbf488eb2c228478c13df845c5093..bd1ea621f6ba906aaf628f8f21c5f4b59239b743 100644 (file)
--- a/gogs.go
+++ b/gogs.go
@@ -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())
index 38f3292b880f32aa6b4efdb2afd1ccbc42274244..1f1260d65a3a01cca3f167539266ffb62d580f9b 100644 (file)
@@ -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)"`
index dac587006406605aa32f01b2951af24970edf094..34d71028e7f96e9258e4bf84808dbe101245c82f 100644 (file)
@@ -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;
index d4c3224eee8942befccd166da47329787e1a0dae..69ac380fd9687d5424343967704126d69da35a74 100644 (file)
@@ -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');
 
index d327f681fdd24d6f2cfc31dc99b323c0705bbe87..010e0f06f6d34ff99a4ef5c09d2b575e053b0e7c 100644 (file)
@@ -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;
index 7ef7d24ccdf433d4fcaed5de51e2fbad360191e6..0ca733c5197deeb97f5d6414b17ea1be270e1f13 100644 (file)
@@ -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
index ebc446b820388ee04c6dfc89a29e44532e7fd133..75dbf2712b9c9e67b94420dc5038398e86e9fd91 100644 (file)
@@ -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 (file)
index 0355632..0000000
+++ /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 (file)
index 0000000..5f98a64
--- /dev/null
@@ -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")
+}
index f7f2473b40fc9f5cd0b1f767cc3b363e6553e17b..102c742960cea8dee57ce47bc6112a83ac377ea3 100644 (file)
@@ -1 +1 @@
-0.4.7.0827 Alpha
\ No newline at end of file
+0.4.7.0829 Alpha
\ No newline at end of file
index 81c262e2e05e3065f3a5c993595f17ad86cc5b82..09e105826a1604d7a50105e2b91b9da7be3e07b0 100644 (file)
@@ -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>
index 5975832f32fce10603657e455afcbbd2be9181a6..e88126706e23b44854a0838045e6a56e72f8da28 100644 (file)
-{{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>
+                                                       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+                                                       <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 (file)
index 0000000..39e348f
--- /dev/null
@@ -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}}">&laquo; Prev.</a></li>{{end}}
+                                                           {{if .NextPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="/admin/users?p={{.NextPageNum}}">&raquo; 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
index 4f4866c4b64791b2c2372087cfcfaf3f08e5f5ae..19126ee0c4a2194acb4b9acf10c7056a9b46c048 100644 (file)
@@ -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 (file)
index 0efe909..0000000
+++ /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}}">&laquo; Prev.</a></li>{{end}}
-                    {{if .NextPageNum}}<li><a href="/admin/users?p={{.NextPageNum}}">&raquo; Next</a></li>{{end}}
-                </ul>
-            </div>
-        </div>
-    </div>
-</div>
-{{template "base/footer" .}}
\ No newline at end of file
index 817c18807a1cfd015888f789c6e9c237e1256dd6..815453446a345277dc09e1b006abc89532d1464c 100644 (file)
@@ -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 (file)
index 4292575..0000000
+++ /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">&nbsp;</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 (file)
index aab42f3..0000000
+++ /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">&nbsp;
-                        <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" .}}
index b4736a07ce694225439e894cc3cfbc91b94b2299..d116ad6276e88927a040dbb84fd4d7795f7d295a 100644 (file)
@@ -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>
index 33e6a944d7155e147e33dbe381986dfc771a7bb8..3fff0748426d2cb030619c0fee66124464ace350 100644 (file)
@@ -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>