Browse Source

Reser repo owner to organization when error occurs in repo create page, dashboard news feed page, create organization page

Unknwon 10 năm trước cách đây
mục cha
commit
9813161411

+ 12 - 12
cmd/web.go

@@ -104,9 +104,8 @@ func runWeb(*cli.Context) {
 	m.Get("/install", bindIgnErr(auth.InstallForm{}), routers.Install)
 	m.Post("/install", bindIgnErr(auth.InstallForm{}), routers.InstallPost)
 	m.Group("", func(r *macaron.Router) {
-		r.Get("/issues", user.Issues)
 		r.Get("/pulls", user.Pulls)
-		r.Get("/stars", user.Stars)
+		r.Get("/issues", user.Issues)
 	}, reqSignIn)
 
 	// API routers.
@@ -171,13 +170,6 @@ func runWeb(*cli.Context) {
 	m.Map(cpt)
 	m.Get("/captcha/*", cpt.Handler)
 
-	m.Group("/repo", func(r *macaron.Router) {
-		r.Get("/create", repo.Create)
-		r.Post("/create", bindIgnErr(auth.CreateRepoForm{}), repo.CreatePost)
-		r.Get("/migrate", repo.Migrate)
-		r.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), repo.MigratePost)
-	}, reqSignIn)
-
 	adminReq := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: true, AdminRequire: true})
 
 	m.Get("/admin", adminReq, admin.Dashboard)
@@ -215,10 +207,10 @@ func runWeb(*cli.Context) {
 
 	// Organization routers.
 	m.Group("/org", func(r *macaron.Router) {
-		r.Get("/create", org.New)
-		r.Post("/create", bindIgnErr(auth.CreateOrgForm{}), org.NewPost)
+		r.Get("/create", org.Create)
+		r.Post("/create", bindIgnErr(auth.CreateOrgForm{}), org.CreatePost)
 		r.Get("/:org", org.Home)
-		r.Get("/:org/dashboard", org.Dashboard)
+		r.Get("/:org/dashboard", user.Dashboard)
 		r.Get("/:org/members", org.Members)
 
 		r.Get("/:org/teams", org.Teams)
@@ -233,6 +225,14 @@ func runWeb(*cli.Context) {
 		r.Post("/:org/settings/delete", org.DeletePost)
 	}, reqSignIn)
 
+	// Repository routers.
+	m.Group("/repo", func(r *macaron.Router) {
+		r.Get("/create", repo.Create)
+		r.Post("/create", bindIgnErr(auth.CreateRepoForm{}), repo.CreatePost)
+		r.Get("/migrate", repo.Migrate)
+		r.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), repo.MigratePost)
+	}, reqSignIn)
+
 	m.Group("/:username/:reponame", func(r *macaron.Router) {
 		r.Get("/settings", repo.Setting)
 		r.Post("/settings", bindIgnErr(auth.RepoSettingForm{}), repo.SettingPost)

+ 8 - 0
conf/locale/locale_en-US.ini

@@ -74,10 +74,12 @@ password_not_match = Password and re-type password are not same.
 
 username_been_taken = Username has been already taken.
 repo_name_been_taken = Repository name has been already taken.
+org_name_been_taken = Organization name has been already taken.
 email_been_used = E-mail address has been already used.
 ssh_key_been_used = Public key name has been used.
 illegal_username = Your username contains illegal characters.
 illegal_repo_name = Repository name contains illegal characters.
+illegal_org_name = Organization name contains illegal characters.
 username_password_incorrect = Username or password is not correct.
 
 invalid_ssh_key = Sorry, we're not able to verify your SSH key: %s
@@ -140,6 +142,12 @@ license_helper = Select a license file
 init_readme = Initialize this repository with a README.md
 create_repo = Create Repository
 
+[org]
+org_name_holder = Organization Name
+org_name_helper = Great organization names are short and memorable.
+org_email_helper = Organization's Email receives all notifications and confirmations.
+create_org = Create Organization
+
 [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>

+ 8 - 0
conf/locale/locale_zh-CN.ini

@@ -74,10 +74,12 @@ password_not_match = 密码与确认密码未匹配。
 
 username_been_taken = 用户名已经被占用。
 repo_name_been_taken = 仓库名称已经被占用。
+org_name_been_taken = 组织名称已经被占用。
 email_been_used = 邮箱地址已经被使用。
 ssh_key_been_used = SSH 密钥已经被使用。
 illegal_username = 您的用户名包含非法字符。
 illegal_repo_name = 仓库名称包含非法字符。
+illegal_org_name = 组织名称包含非法字符。
 username_password_incorrect = 用户名或密码不正确。
 
 invalid_ssh_key = 很抱歉,我们无法验证您输入的 SSH 密钥:%s
@@ -140,6 +142,12 @@ license_helper = 请选择授权许可文件
 init_readme = 使用 README.md 文件初始化仓库
 create_repo = 创建仓库
 
+[org]
+org_name_holder = 组织名称
+org_name_helper = 伟大的组织都有一个简短而寓意深刻的名字。
+org_email_helper = 组织的邮箱用于接收所有通知和确认邮件。
+create_org = 创建组织
+
 [action]
 create_repo = 创建了仓库 <a href="/%s">%s</a>
 commit_repo = 推送了 <a href="/%s/src/%s">%s</a> 分支的代码到 <a href="/%s">%s</a>

+ 3 - 5
models/action.go

@@ -305,13 +305,11 @@ func TransferRepoAction(u, newUser *User, repo *Repository) (err error) {
 }
 
 // GetFeeds returns action list of given user in given context.
-func GetFeeds(userid, offset int64, isProfile bool) ([]*Action, error) {
+func GetFeeds(uid, offset int64, isProfile bool) ([]*Action, error) {
 	actions := make([]*Action, 0, 20)
-	sess := x.Limit(20, int(offset)).Desc("id").Where("user_id=?", userid)
+	sess := x.Limit(20, int(offset)).Desc("id").Where("user_id=?", uid)
 	if isProfile {
-		sess.Where("is_private=?", false).And("act_user_id=?", userid)
-	} else {
-		sess.And("act_user_id!=?", userid)
+		sess.Where("is_private=?", false).And("act_user_id=?", uid)
 	}
 	err := sess.Find(&actions)
 	return actions, err

+ 16 - 16
models/repo.go

@@ -204,6 +204,22 @@ type Mirror struct {
 	NextUpdate time.Time
 }
 
+func GetMirror(repoId int64) (*Mirror, error) {
+	m := &Mirror{RepoId: repoId}
+	has, err := x.Get(m)
+	if err != nil {
+		return nil, err
+	} else if !has {
+		return nil, ErrMirrorNotExist
+	}
+	return m, nil
+}
+
+func UpdateMirror(m *Mirror) error {
+	_, err := x.Id(m.Id).Update(m)
+	return err
+}
+
 // MirrorRepository creates a mirror repository from source.
 func MirrorRepository(repoId int64, userName, repoName, repoPath, url string) error {
 	_, stderr, err := process.ExecTimeout(10*time.Minute,
@@ -226,22 +242,6 @@ func MirrorRepository(repoId int64, userName, repoName, repoPath, url string) er
 	return nil
 }
 
-func GetMirror(repoId int64) (*Mirror, error) {
-	m := &Mirror{RepoId: repoId}
-	has, err := x.Get(m)
-	if err != nil {
-		return nil, err
-	} else if !has {
-		return nil, ErrMirrorNotExist
-	}
-	return m, nil
-}
-
-func UpdateMirror(m *Mirror) error {
-	_, err := x.Id(m.Id).Update(m)
-	return err
-}
-
 // MirrorUpdate checks and updates mirror repositories.
 func MirrorUpdate() {
 	if err := x.Iterate(new(Mirror), func(idx int, bean interface{}) error {

+ 1 - 1
modules/auth/org.go

@@ -19,7 +19,7 @@ import (
 //         \/     /_____/     \/     \/         \/     \/                    \/
 
 type CreateOrgForm struct {
-	OrgName string `form:"orgname" binding:"Required;AlphaDashDot;MaxSize(30)"`
+	OrgName string `form:"org_name" binding:"Required;AlphaDashDot;MaxSize(30)"`
 	Email   string `form:"email" binding:"Required;Email;MaxSize(50)"`
 }
 

+ 0 - 2
modules/middleware/context.go

@@ -220,8 +220,6 @@ func Contexter() macaron.Handler {
 			ctx.IsSigned = true
 			ctx.Data["IsSigned"] = ctx.IsSigned
 			ctx.Data["SignedUser"] = ctx.User
-			ctx.Data["SignedUserId"] = ctx.User.Id
-			ctx.Data["SignedUserName"] = ctx.User.Name
 			ctx.Data["IsAdmin"] = ctx.User.IsAdmin
 		}
 

+ 12 - 4
public/ng/css/gogs.css

@@ -265,6 +265,9 @@ img.avatar-30 {
 .markdown ul li {
   list-style: inside;
 }
+.markdown ol li {
+  list-style: decimal inside;
+}
 .markdown li {
   line-height: 1.6;
   margin-top: 6px;
@@ -346,10 +349,6 @@ img.avatar-30 {
 .markdown .btn {
   color: #fff;
 }
-.markdown .anchor-wrap {
-  /*margin-top: -50px;*/
-  /*padding-top: 50px;*/
-}
 .markdown h1 a,
 .markdown h2 a,
 .markdown h3 a {
@@ -660,40 +659,49 @@ The dashboard page style
 #dashboard-sidebar-menu > li.last > a {
   border-top-right-radius: .3em;
 }
+#dashboard-my-mirror li,
 #dashboard-my-org li,
 #dashboard-my-repo li {
   border-bottom: 1px solid #EAEAEA;
 }
+#dashboard-my-mirror li.private,
 #dashboard-my-org li.private,
 #dashboard-my-repo li.private {
   background-color: #fcf8e9;
 }
+#dashboard-my-mirror li:last-child,
 #dashboard-my-org li:last-child,
 #dashboard-my-repo li:last-child {
   border-bottom: none;
 }
+#dashboard-my-mirror li a,
 #dashboard-my-org li a,
 #dashboard-my-repo li a {
   padding: 6px 1.2em;
   display: block;
 }
+#dashboard-my-mirror li a .octicon,
 #dashboard-my-org li a .octicon,
 #dashboard-my-repo li a .octicon {
   margin-right: 6px;
   color: #888;
 }
+#dashboard-my-mirror li a:hover .repo-name,
 #dashboard-my-org li a:hover .repo-name,
 #dashboard-my-repo li a:hover .repo-name {
   text-decoration: underline;
 }
+#dashboard-my-mirror .repo-name,
 #dashboard-my-org .repo-name,
 #dashboard-my-repo .repo-name {
   font-size: 1.1em;
 }
+#dashboard-my-mirror .repo-star,
 #dashboard-my-org .repo-star,
 #dashboard-my-repo .repo-star {
   color: #888;
 }
+#dashboard-my-mirror .repo-contrib-header,
 #dashboard-my-org .repo-contrib-header,
 #dashboard-my-repo .repo-contrib-header {
   border-top: 1px solid #d6d6d6;

+ 122 - 91
public/ng/js/gogs.js

@@ -1,8 +1,11 @@
 // @codekit-prepend "lib/jquery-1.11.1.min.js"
+// @codekit-prepend "lib/lib.js"
 // @codekit-prepend "lib/tabs.js"
 
+var Gogs = {};
+
 (function ($) {
-    // extend jQuery ajax, set csrf token value
+    // Extend jQuery ajax, set CSRF token value.
     var ajax = $.ajax;
     $.extend({
         ajax: function (url, options) {
@@ -51,15 +54,131 @@
     });
 }(jQuery));
 
+(function ($) {
+    // Render markdown.
+    Gogs.renderMarkdown = function () {
+        var $md = $('.markdown');
+        var $pre = $md.find('pre > code').parent();
+        $pre.addClass('prettyprint linenums');
+        prettyPrint();
+
+        // Set anchor.
+        var headers = {};
+        $md.find('h1, h2, h3, h4, h5, h6').each(function () {
+            var node = $(this);
+            var val = encodeURIComponent(node.text().toLowerCase().replace(/[^\w\- ]/g, '').replace(/[ ]/g, '-'));
+            var name = val;
+            if (headers[val] > 0) {
+                name = val + '-' + headers[val];
+            }
+            if (headers[val] == undefined) {
+                headers[val] = 1;
+            } else {
+                headers[val] += 1;
+            }
+            node = node.wrap('<div id="' + name + '" class="anchor-wrap" ></div>');
+            node.append('<a class="anchor" href="#' + name + '"><span class="octicon octicon-link"></span></a>');
+        });
+    };
+
+    // Render code view.
+    Gogs.renderCodeView = function () {
+        function selectRange($list, $select, $from) {
+            $list.removeClass('active');
+            if ($from) {
+                var a = parseInt($select.attr('rel').substr(1));
+                var b = parseInt($from.attr('rel').substr(1));
+                var c;
+                if (a != b) {
+                    if (a > b) {
+                        c = a;
+                        a = b;
+                        b = c;
+                    }
+                    var classes = [];
+                    for (i = a; i <= b; i++) {
+                        classes.push('.L' + i);
+                    }
+                    $list.filter(classes.join(',')).addClass('active');
+                    $.changeHash('#L' + a + '-' + 'L' + b);
+                    return
+                }
+            }
+            $select.addClass('active');
+            $.changeHash('#' + $select.attr('rel'));
+        }
+
+        $(document).on('click', '.lines-num span', function (e) {
+            var $select = $(this);
+            var $list = $select.parent().siblings('.lines-code').find('ol.linenums > li');
+            selectRange($list, $list.filter('[rel=' + $select.attr('rel') + ']'), (e.shiftKey ? $list.filter('.active').eq(0) : null));
+            $.deSelect();
+        });
+
+        $('.code-view .lines-code > pre').each(function () {
+            var $pre = $(this);
+            var $lineCode = $pre.parent();
+            var $lineNums = $lineCode.siblings('.lines-num');
+            if ($lineNums.length > 0) {
+                var nums = $pre.find('ol.linenums > li').length;
+                for (var i = 1; i <= nums; i++) {
+                    $lineNums.append('<span id="L' + i + '" rel="L' + i + '">' + i + '</span>');
+                }
+            }
+        });
+
+        $(window).on('hashchange', function (e) {
+            var m = window.location.hash.match(/^#(L\d+)\-(L\d+)$/);
+            var $list = $('.code-view ol.linenums > li');
+            if (m) {
+                var $first = $list.filter('.' + m[1]);
+                selectRange($list, $first, $list.filter('.' + m[2]));
+                $("html, body").scrollTop($first.offset().top - 200);
+                return;
+            }
+            m = window.location.hash.match(/^#(L\d+)$/);
+            if (m) {
+                var $first = $list.filter('.' + m[1]);
+                selectRange($list, $first);
+                $("html, body").scrollTop($first.offset().top - 200);
+            }
+        }).trigger('hashchange');
+    };
+})(jQuery);
+
+function initCore() {
+    Gogs.renderMarkdown();
+    Gogs.renderCodeView();
+}
+
+function initRepoCreate() {
+    // Owner switch menu click.
+    $('#repo-create-owner-list').on('click', 'li', function () {
+        if (!$(this).hasClass('checked')) {
+            var uid = $(this).data('uid');
+            $('#repo-owner-id').val(uid);
+            $('#repo-owner-avatar').attr("src", $(this).find('img').attr("src"));
+            $('#repo-owner-name').text($(this).text().trim());
+
+            $(this).parent().find('.checked').removeClass('checked');
+            $(this).addClass('checked');
+            console.log("set repo owner to uid :", uid, $(this).text().trim());
+        }
+    });
+}
+
 $(document).ready(function () {
+    initCore();
+    if ($('#repo-create-form').length) {
+        initRepoCreate();
+    }
+
     Tabs('#dashboard-sidebar-menu');
 
     homepage();
     settingsProfile();
     settingsSSHKeys();
     settingsDelete();
-    renderMarkdown();
-    renderCodeView();
 
     // Fix language drop-down menu height.
     var l = $('#footer-lang li').length;
@@ -114,92 +233,4 @@ function settingsDelete() {
             return true;
         }
     });
-}
-
-function renderMarkdown() {
-    var $md = $('.markdown');
-    var $pre = $md.find('pre > code').parent();
-    $pre.addClass('prettyprint linenums');
-    prettyPrint();
-
-    // Set anchor.
-    var headers = {};
-    $md.find('h1, h2, h3, h4, h5, h6').each(function () {
-        var node = $(this);
-        var val = encodeURIComponent(node.text().toLowerCase().replace(/[^\w\- ]/g, '').replace(/[ ]/g, '-'));
-        var name = val;
-        if (headers[val] > 0) {
-            name = val + '-' + headers[val];
-        }
-        if (headers[val] == undefined) {
-            headers[val] = 1;
-        } else {
-            headers[val] += 1;
-        }
-        node = node.wrap('<div id="' + name + '" class="anchor-wrap" ></div>');
-        node.append('<a class="anchor" href="#' + name + '"><span class="octicon octicon-link"></span></a>');
-    });
-}
-
-function renderCodeView() {
-    function selectRange($list, $select, $from) {
-        $list.removeClass('active');
-        if ($from) {
-            var a = parseInt($select.attr('rel').substr(1));
-            var b = parseInt($from.attr('rel').substr(1));
-            var c;
-            if (a != b) {
-                if (a > b) {
-                    c = a;
-                    a = b;
-                    b = c;
-                }
-                var classes = [];
-                for (i = a; i <= b; i++) {
-                    classes.push('.L' + i);
-                }
-                $list.filter(classes.join(',')).addClass('active');
-                $.changeHash('#L' + a + '-' + 'L' + b);
-                return
-            }
-        }
-        $select.addClass('active');
-        $.changeHash('#' + $select.attr('rel'));
-    }
-
-    $(document).on('click', '.lines-num span', function (e) {
-        var $select = $(this);
-        var $list = $select.parent().siblings('.lines-code').find('ol.linenums > li');
-        selectRange($list, $list.filter('[rel=' + $select.attr('rel') + ']'), (e.shiftKey ? $list.filter('.active').eq(0) : null));
-        $.deSelect();
-    });
-
-    $('.code-view .lines-code > pre').each(function () {
-        var $pre = $(this);
-        var $lineCode = $pre.parent();
-        var $lineNums = $lineCode.siblings('.lines-num');
-        if ($lineNums.length > 0) {
-            var nums = $pre.find('ol.linenums > li').length;
-            for (var i = 1; i <= nums; i++) {
-                $lineNums.append('<span id="L' + i + '" rel="L' + i + '">' + i + '</span>');
-            }
-        }
-    });
-
-    $(window).on('hashchange', function (e) {
-        var m = window.location.hash.match(/^#(L\d+)\-(L\d+)$/);
-        var $list = $('.code-view ol.linenums > li');
-        if (m) {
-            var $first = $list.filter('.' + m[1]);
-            selectRange($list, $first, $list.filter('.' + m[2]));
-            $("html, body").scrollTop($first.offset().top - 200);
-            return;
-        }
-        m = window.location.hash.match(/^#(L\d+)$/);
-        if (m) {
-            var $first = $list.filter('.' + m[1]);
-            selectRange($list, $first);
-            $("html, body").scrollTop($first.offset().top - 200);
-        }
-    }).trigger('hashchange');
 }

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
public/ng/js/min/gogs-min.js


+ 13 - 52
routers/org/org.go

@@ -10,12 +10,11 @@ import (
 	"github.com/gogits/gogs/modules/base"
 	"github.com/gogits/gogs/modules/log"
 	"github.com/gogits/gogs/modules/middleware"
-	"github.com/gogits/gogs/routers/user"
 )
 
 const (
 	HOME     base.TplName = "org/home"
-	NEW      base.TplName = "org/new"
+	CREATE   base.TplName = "org/create"
 	SETTINGS base.TplName = "org/settings"
 )
 
@@ -55,23 +54,23 @@ func Home(ctx *middleware.Context) {
 	ctx.HTML(200, HOME)
 }
 
-func New(ctx *middleware.Context) {
-	ctx.Data["Title"] = "Create An Organization"
-	ctx.HTML(200, NEW)
+func Create(ctx *middleware.Context) {
+	ctx.Data["Title"] = ctx.Tr("new_org")
+	ctx.HTML(200, CREATE)
 }
 
-func NewPost(ctx *middleware.Context, form auth.CreateOrgForm) {
-	ctx.Data["Title"] = "Create An Organization"
+func CreatePost(ctx *middleware.Context, form auth.CreateOrgForm) {
+	ctx.Data["Title"] = ctx.Tr("new_org")
 
 	if ctx.HasError() {
-		ctx.HTML(200, NEW)
+		ctx.HTML(200, CREATE)
 		return
 	}
 
 	org := &models.User{
 		Name:     form.OrgName,
 		Email:    form.Email,
-		IsActive: true, // NOTE: may need to set false when require e-mail confirmation.
+		IsActive: true,
 		Type:     models.ORGANIZATION,
 	}
 
@@ -80,61 +79,23 @@ func NewPost(ctx *middleware.Context, form auth.CreateOrgForm) {
 		switch err {
 		case models.ErrUserAlreadyExist:
 			ctx.Data["Err_OrgName"] = true
-			ctx.RenderWithErr("Organization name has been already taken", NEW, &form)
+			ctx.RenderWithErr(ctx.Tr("form.org_name_been_taken"), CREATE, &form)
 		case models.ErrEmailAlreadyUsed:
 			ctx.Data["Err_Email"] = true
-			ctx.RenderWithErr("E-mail address has been already used", NEW, &form)
+			ctx.RenderWithErr(ctx.Tr("form.email_been_used"), CREATE, &form)
 		case models.ErrUserNameIllegal:
 			ctx.Data["Err_OrgName"] = true
-			ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), NEW, &form)
+			ctx.RenderWithErr(ctx.Tr("form.illegal_org_name"), CREATE, &form)
 		default:
-			ctx.Handle(500, "org.NewPost(CreateUser)", err)
+			ctx.Handle(500, "CreateUser", err)
 		}
 		return
 	}
-	log.Trace("%s Organization created: %s", ctx.Req.RequestURI, org.Name)
+	log.Trace("Organization created: %s", org.Name)
 
 	ctx.Redirect("/org/" + form.OrgName + "/dashboard")
 }
 
-func Dashboard(ctx *middleware.Context) {
-	ctx.Data["Title"] = "Dashboard"
-	ctx.Data["PageIsUserDashboard"] = true
-	ctx.Data["PageIsOrgDashboard"] = true
-
-	org, err := models.GetUserByName(ctx.Params(":org"))
-	if err != nil {
-		if err == models.ErrUserNotExist {
-			ctx.Handle(404, "org.Dashboard(GetUserByName)", err)
-		} else {
-			ctx.Handle(500, "org.Dashboard(GetUserByName)", err)
-		}
-		return
-	}
-
-	if err := ctx.User.GetOrganizations(); err != nil {
-		ctx.Handle(500, "home.Dashboard(GetOrganizations)", err)
-		return
-	}
-	ctx.Data["Orgs"] = ctx.User.Orgs
-	ctx.Data["ContextUser"] = org
-
-	ctx.Data["MyRepos"], err = models.GetRepositories(org.Id, true)
-	if err != nil {
-		ctx.Handle(500, "org.Dashboard(GetRepositories)", err)
-		return
-	}
-
-	actions, err := models.GetFeeds(org.Id, 0, false)
-	if err != nil {
-		ctx.Handle(500, "org.Dashboard(GetFeeds)", err)
-		return
-	}
-	ctx.Data["Feeds"] = actions
-
-	ctx.HTML(200, user.DASHBOARD)
-}
-
 func Settings(ctx *middleware.Context) {
 	ctx.Data["Title"] = "Settings"
 

+ 19 - 33
routers/repo/repo.go

@@ -36,11 +36,10 @@ func Create(ctx *middleware.Context) {
 	ctx.Data["Licenses"] = models.Licenses
 
 	ctxUser := ctx.User
-	orgId := com.StrTo(ctx.Query("org")).MustInt64()
-	if orgId > 0 {
+	if orgId := com.StrTo(ctx.Query("org")).MustInt64(); orgId > 0 {
 		org, err := models.GetUserById(orgId)
 		if err != nil && err != models.ErrUserNotExist {
-			ctx.Handle(500, "home.Dashboard(GetUserById)", err)
+			ctx.Handle(500, "GetUserById", err)
 			return
 		}
 		ctxUser = org
@@ -48,10 +47,10 @@ func Create(ctx *middleware.Context) {
 	ctx.Data["ContextUser"] = ctxUser
 
 	if err := ctx.User.GetOrganizations(); err != nil {
-		ctx.Handle(500, "home.Dashboard(GetOrganizations)", err)
+		ctx.Handle(500, "GetOrganizations", err)
 		return
 	}
-	ctx.Data["AllUsers"] = append([]*models.User{ctx.User}, ctx.User.Orgs...)
+	ctx.Data["Orgs"] = ctx.User.Orgs
 
 	ctx.HTML(200, CREATE)
 }
@@ -64,11 +63,11 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) {
 	ctx.Data["Licenses"] = models.Licenses
 
 	ctxUser := ctx.User
-	orgId := com.StrTo(ctx.Query("org")).MustInt64()
-	if orgId > 0 {
-		org, err := models.GetUserById(orgId)
+	// Not equal means current user is an organization.
+	if form.Uid != ctx.User.Id {
+		org, err := models.GetUserById(form.Uid)
 		if err != nil && err != models.ErrUserNotExist {
-			ctx.Handle(500, "home.Dashboard(GetUserById)", err)
+			ctx.Handle(500, "GetUserById", err)
 			return
 		}
 		ctxUser = org
@@ -76,7 +75,7 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) {
 	ctx.Data["ContextUser"] = ctxUser
 
 	if err := ctx.User.GetOrganizations(); err != nil {
-		ctx.Handle(500, "home.CreatePost(GetOrganizations)", err)
+		ctx.Handle(500, "GetOrganizations", err)
 		return
 	}
 	ctx.Data["Orgs"] = ctx.User.Orgs
@@ -86,32 +85,19 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) {
 		return
 	}
 
-	u := ctx.User
-	// Not equal means current user is an organization.
-	if u.Id != form.Uid {
-		var err error
-		u, err = models.GetUserById(form.Uid)
-		if err != nil {
-			if err == models.ErrUserNotExist {
-				ctx.Handle(404, "home.CreatePost(GetUserById)", err)
-			} else {
-				ctx.Handle(500, "home.CreatePost(GetUserById)", err)
-			}
-			return
-		}
-
+	if ctxUser.IsOrganization() {
 		// Check ownership of organization.
-		if !u.IsOrgOwner(ctx.User.Id) {
+		if !ctxUser.IsOrgOwner(ctx.User.Id) {
 			ctx.Error(403)
 			return
 		}
 	}
 
-	repo, err := models.CreateRepository(u, form.RepoName, form.Description,
+	repo, err := models.CreateRepository(ctxUser, form.RepoName, form.Description,
 		form.Gitignore, form.License, form.Private, false, form.InitReadme)
 	if err == nil {
-		log.Trace("Repository created: %s/%s", u.Name, form.RepoName)
-		ctx.Redirect("/" + u.Name + "/" + form.RepoName)
+		log.Trace("Repository created: %s/%s", ctxUser.Name, form.RepoName)
+		ctx.Redirect("/" + ctxUser.Name + "/" + form.RepoName)
 		return
 	} else if err == models.ErrRepoAlreadyExist {
 		ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), CREATE, &form)
@@ -122,7 +108,7 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) {
 	}
 
 	if repo != nil {
-		if errDelete := models.DeleteRepository(u.Id, repo.Id, u.Name); errDelete != nil {
+		if errDelete := models.DeleteRepository(ctxUser.Id, repo.Id, ctxUser.Name); errDelete != nil {
 			log.Error(4, "DeleteRepository: %v", errDelete)
 		}
 	}
@@ -134,7 +120,7 @@ func Migrate(ctx *middleware.Context) {
 	ctx.Data["PageIsNewRepo"] = true
 
 	if err := ctx.User.GetOrganizations(); err != nil {
-		ctx.Handle(500, "home.Migrate(GetOrganizations)", err)
+		ctx.Handle(500, "GetOrganizations", err)
 		return
 	}
 	ctx.Data["Orgs"] = ctx.User.Orgs
@@ -147,7 +133,7 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
 	ctx.Data["PageIsNewRepo"] = true
 
 	if err := ctx.User.GetOrganizations(); err != nil {
-		ctx.Handle(500, "home.MigratePost(GetOrganizations)", err)
+		ctx.Handle(500, "GetOrganizations", err)
 		return
 	}
 	ctx.Data["Orgs"] = ctx.User.Orgs
@@ -164,9 +150,9 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
 		u, err = models.GetUserById(form.Uid)
 		if err != nil {
 			if err == models.ErrUserNotExist {
-				ctx.Handle(404, "home.MigratePost(GetUserById)", err)
+				ctx.Handle(404, "GetUserById", err)
 			} else {
-				ctx.Handle(500, "home.MigratePost(GetUserById)", err)
+				ctx.Handle(500, "GetUserById", err)
 			}
 			return
 		}

+ 57 - 18
routers/user/home.go

@@ -17,8 +17,8 @@ import (
 
 const (
 	DASHBOARD base.TplName = "user/dashboard/dashboard"
+	PULLS     base.TplName = "user/dashboard/pulls"
 	ISSUES    base.TplName = "user/issues"
-	PULLS     base.TplName = "user/pulls"
 	STARS     base.TplName = "user/stars"
 	PROFILE   base.TplName = "user/profile"
 )
@@ -28,26 +28,59 @@ func Dashboard(ctx *middleware.Context) {
 	ctx.Data["PageIsDashboard"] = true
 	ctx.Data["PageIsNews"] = true
 
+	var ctxUser *models.User
+	// Check context type.
+	orgName := ctx.Params(":org")
+	if len(orgName) > 0 {
+		// Organization.
+		org, err := models.GetUserByName(orgName)
+		if err != nil {
+			if err == models.ErrUserNotExist {
+				ctx.Handle(404, "GetUserByName", err)
+			} else {
+				ctx.Handle(500, "GetUserByName", err)
+			}
+			return
+		}
+		ctxUser = org
+	} else {
+		// Normal user.
+		ctxUser = ctx.User
+		collaborates, err := models.GetCollaborativeRepos(ctxUser.Name)
+		if err != nil {
+			ctx.Handle(500, "GetCollaborativeRepos", err)
+			return
+		}
+		ctx.Data["CollaborateCount"] = len(collaborates)
+		ctx.Data["CollaborativeRepos"] = collaborates
+	}
+	ctx.Data["ContextUser"] = ctxUser
+
 	if err := ctx.User.GetOrganizations(); err != nil {
-		ctx.Handle(500, "home.Dashboard(GetOrganizations)", err)
+		ctx.Handle(500, "GetOrganizations", err)
 		return
 	}
-	ctx.Data["ContextUser"] = ctx.User
+	ctx.Data["Orgs"] = ctx.User.Orgs
 
-	repos, err := models.GetRepositories(ctx.User.Id, true)
+	repos, err := models.GetRepositories(ctxUser.Id, true)
 	if err != nil {
 		ctx.Handle(500, "GetRepositories", err)
 		return
 	}
 	ctx.Data["Repos"] = repos
 
-	ctx.Data["CollaborativeRepos"], err = models.GetCollaborativeRepos(ctx.User.Name)
-	if err != nil {
-		ctx.Handle(500, "GetCollaborativeRepos", err)
-		return
+	// Get mirror repositories.
+	mirrors := make([]*models.Repository, 0, len(repos)/2)
+	for _, repo := range repos {
+		if repo.IsMirror {
+			mirrors = append(mirrors, repo)
+		}
 	}
+	ctx.Data["MirrorCount"] = len(mirrors)
+	ctx.Data["Mirrors"] = mirrors
 
-	actions, err := models.GetFeeds(ctx.User.Id, 0, true)
+	// Get feeds.
+	actions, err := models.GetFeeds(ctxUser.Id, 0, false)
 	if err != nil {
 		ctx.Handle(500, "GetFeeds", err)
 		return
@@ -57,7 +90,7 @@ func Dashboard(ctx *middleware.Context) {
 	feeds := make([]*models.Action, 0, len(actions))
 	for _, act := range actions {
 		if act.IsPrivate {
-			if has, _ := models.HasAccess(ctx.User.Name, act.RepoUserName+"/"+act.RepoName,
+			if has, _ := models.HasAccess(ctxUser.Name, act.RepoUserName+"/"+act.RepoName,
 				models.READABLE); !has {
 				continue
 			}
@@ -68,6 +101,20 @@ func Dashboard(ctx *middleware.Context) {
 	ctx.HTML(200, DASHBOARD)
 }
 
+func Pulls(ctx *middleware.Context) {
+	ctx.Data["Title"] = ctx.Tr("pull_requests")
+	ctx.Data["PageIsDashboard"] = true
+	ctx.Data["PageIsPulls"] = true
+
+	if err := ctx.User.GetOrganizations(); err != nil {
+		ctx.Handle(500, "GetOrganizations", err)
+		return
+	}
+	ctx.Data["ContextUser"] = ctx.User
+
+	ctx.HTML(200, PULLS)
+}
+
 func Profile(ctx *middleware.Context) {
 	ctx.Data["Title"] = "Profile"
 	ctx.Data["PageIsUserProfile"] = true
@@ -279,11 +326,3 @@ func Issues(ctx *middleware.Context) {
 	}
 	ctx.HTML(200, ISSUES)
 }
-
-func Pulls(ctx *middleware.Context) {
-	ctx.HTML(200, PULLS)
-}
-
-func Stars(ctx *middleware.Context) {
-	ctx.HTML(200, STARS)
-}

+ 1 - 0
templates/ng/base/head.tmpl

@@ -6,6 +6,7 @@
         <meta name="author" content="Gogs - Go Git Service" />
 		<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}}" />
 
 		<link rel="shortcut icon" href="/img/favicon.png" />
 

+ 31 - 0
templates/org/create.tmpl

@@ -0,0 +1,31 @@
+{{template "ng/base/head" .}}
+{{template "ng/base/header" .}}
+<div id="sign-wrapper">
+    <form class="form-align form panel sign-panel sign-form container panel-radius" id="sign-up-form" action="/org/create" method="post">
+        {{.CsrfTokenHtml}}
+        <div class="panel-header">
+            <h2>{{.i18n.Tr "new_org"}}</h2>
+        </div>
+        <div class="panel-content">
+            {{template "ng/base/alert" .}}
+            <p class="field">
+                <label class="req" for="org_name">{{.i18n.Tr "org.org_name_holder"}}</label>
+                <input class="ipt ipt-large ipt-radius {{if .Err_OrgName}}ipt-error{{end}}" id="org_name" name="org_name" type="text" value="{{.org_name}}" required/>
+                <label></label>
+                <span class="help">{{.i18n.Tr "org.org_name_helper"}}</span>
+            </p>
+            <p 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/>
+                <label></label>
+                <span class="help">{{.i18n.Tr "org.org_email_helper"}}</span>
+            </p>
+            <p class="field">
+                <span class="form-label"></span>
+                <button class="btn btn-large btn-blue btn-radius">{{.i18n.Tr "org.create_org"}}</button>
+                <a class="btn btn-small btn-gray btn-radius" id="repo-create-cancel" href="/"><strong>{{.i18n.Tr "cancel"}}</strong></a>
+            </p>
+        </div>
+    </form>
+</div>
+{{template "ng/base/footer" .}}

+ 7 - 7
templates/repo/create.tmpl

@@ -8,23 +8,23 @@
             {{template "ng/base/alert" .}}
             <div class="field">
                 <label for="owner" class="req">{{.i18n.Tr "repo.owner"}}</label>
-                <input id="owner" type="hidden" name="uid" value="{{.ContextUser.Id}}" />
+                <input id="repo-owner-id" type="hidden" name="uid" value="{{.ContextUser.Id}}" />
                 <div class="inline-block drop">
                     <a href="#" class="drop-bottom">
-                        <img class="avatar" src="{{.ContextUser.AvatarLink}}" alt="user-avatar">
-                        <strong>{{.ContextUser.Name}}</strong>
+                        <img class="avatar" src="{{.ContextUser.AvatarLink}}" id="repo-owner-avatar" alt="user-avatar">
+                        <strong id="repo-owner-name">{{.ContextUser.Name}}</strong>
                     </a>
                     <ul class="drop-down menu menu-vertical menu-radius switching-list" id="repo-create-owner-list">
-                        <li {{if eq $.ContextUser.Id .SignedUser.Id}}class="checked"{{end}}>
-                            <a href="#">
+                        <li {{if eq $.ContextUser.Id .SignedUser.Id}}class="checked"{{end}} data-uid="{{.SignedUser.Id}}">
+                            <a>
                                 <i class="octicon octicon-check"></i>
                                 <img class="avatar" src="{{.SignedUser.AvatarLink}}" alt="user-avatar">
                                 <strong>{{.SignedUser.Name}}</strong>
                             </a>
                         </li>
                         {{range .Orgs}}
-                        <li {{if eq $.ContextUser.Id .Id}}class="checked"{{end}}>
-                            <a href="#">
+                        <li {{if eq $.ContextUser.Id .Id}}class="checked"{{end}} data-uid="{{.Id}}">
+                            <a>
                                 <i class="octicon octicon-check"></i>
                                 <img class="avatar" src="{{.AvatarLink}}" alt="user-avatar">
                                 <strong>{{.Name}}</strong>

+ 27 - 4
templates/user/dashboard/dashboard.tmpl

@@ -73,7 +73,7 @@
                     <ul class="list-no-style">
                         {{range .Repos}}
                         <li {{if .IsPrivate}}class="private"{{end}}>
-                            <a href="{{$.ContextUser.Name}}/{{.Name}}">
+                            <a href="/{{$.ContextUser.Name}}/{{.Name}}">
                                 <i class="octicon octicon-{{if .IsPrivate}}lock{{else if .IsFork}}repo-forked{{else if .IsMirror}}repo-clone{{else}}repo{{end}}"></i>
                                 <span class="repo-name">
                                     <strong class="repo">{{.Name}}</strong>
@@ -88,7 +88,9 @@
                 </div>
                 {{if not .ContextUser.IsOrganization}}
                 <div class="panel-header repo-contrib-header">
-                    <h4 class="text-bold">{{.i18n.Tr "home.collaborative_repos"}}</h4>
+                    <h4 class="text-bold">{{.i18n.Tr "home.collaborative_repos"}}
+                        <span class="repo-count label label-gray label-radius">{{.CollaborateCount}}</span>
+                    </h4>
                 </div>
                 <div class="panel-body">
                     <ul class="list-no-style">
@@ -113,7 +115,9 @@
             {{if not .ContextUser.IsOrganization}}
             <div class="panel" id="dashboard-my-org">
                 <div class="panel-header">
-                    <h4 class="text-bold">{{.i18n.Tr "home.my_orgs"}}</h4>
+                    <h4 class="text-bold">{{.i18n.Tr "home.my_orgs"}}
+                        <span class="repo-count label label-gray label-radius">{{.ContextUser.GetOrganizationCount}}</span>
+                    </h4>
                 </div>
                 <div class="panel-body">
                     <ul class="list-no-style">
@@ -136,7 +140,26 @@
             {{end}}
             <div class="panel" id="dashboard-my-mirror">
                 <div class="panel-header">
-                    <h4 class="text-bold">{{.i18n.Tr "home.my_mirrors"}}</h4>
+                    <h4 class="text-bold">{{.i18n.Tr "home.my_mirrors"}}
+                        <span class="repo-count label label-gray label-radius">{{.MirrorCount}}</span>
+                    </h4>
+                </div>
+                <div class="panel-body">
+                    <ul class="list-no-style">
+                        {{range .Mirrors}}
+                        <li {{if .IsPrivate}}class="private"{{end}}>
+                            <a href="/{{$.ContextUser.Name}}/{{.Name}}">
+                                <i class="octicon octicon-repo-clone"></i>
+                                <span class="repo-name">
+                                    <strong class="repo">{{.Name}}</strong>
+                                </span>
+                                <span class="right repo-star">
+                                    <i class="octicon octicon-star"></i>{{.NumStars}}
+                                </span>
+                            </a>
+                        </li>
+                        {{end}}
+                    </ul>
                 </div>
             </div>
         </div>

+ 1 - 1
templates/user/dashboard/nav.tmpl

@@ -15,7 +15,7 @@
                             {{.SignedUser.Name}}
                         </a>
                     </li>
-                    {{range .ContextUser.Orgs}}
+                    {{range .Orgs}}
                     <li class="org {{if eq $.ContextUser.Id .Id}}checked{{end}}">
                         <a href="{{.DashboardLink}}">
                             <i class="octicon octicon-check"></i>

+ 5 - 0
templates/user/dashboard/pulls.tmpl

@@ -0,0 +1,5 @@
+{{template "ng/base/head" .}}
+{{template "ng/base/header" .}}
+{{template "user/dashboard/nav" .}}
+
+{{template "ng/base/footer" .}}

+ 0 - 17
templates/user/pulls.tmpl

@@ -1,17 +0,0 @@
-{{template "base/head" .}}
-{{template "base/navbar" .}}
-<div id="body-nav">
-    <div class="container">
-        <ul class="nav nav-pills pull-right">
-            <li><a href="/">Feed</a></li>
-            <li><a href="/issues">Issues</a></li>
-            <li class="active"><a href="/pulls">Pull Requests</a></li>
-            <li><a href="/stars">Stars</a></li>
-        </ul>
-        <h3>Pull Requests</h3>
-    </div>
-</div>
-<div id="body" class="container" data-page="user">
-    {{if .HasInfo}}<div class="alert alert-info">{{.InfoMsg}}</div>{{end}}
-</div>
-{{template "base/footer" .}}

+ 1 - 1
templates/user/signin.tmpl

@@ -7,7 +7,7 @@
             <h2>{{.i18n.Tr "sign_in"}}</h2>
         </div>
         <div class="panel-content">
-            {{template "base/alert" .}}
+            {{template "ng/base/alert" .}}
             <p class="field">
                 <label class="req" for="username">{{.i18n.Tr "home.uname_holder"}}</label>
                 <input class="ipt ipt-large ipt-radius {{if .Err_UserName}}ipt-error{{end}}" id="username" name="uname" type="text" value="{{.uname}}" required/>

+ 1 - 1
templates/user/signup.tmpl

@@ -7,7 +7,7 @@
             <h2>{{.i18n.Tr "sign_up"}}</h2>
         </div>
         <div class="panel-content">
-            {{template "base/alert" .}}
+            {{template "ng/base/alert" .}}
 	        {{if .DisableRegistration}}
 	        <p>{{.i18n.Tr "auth.disable_register_prompt"}}</p>
 	        {{else}}

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác