diff options
-rw-r--r-- | models/issue.go | 6 | ||||
-rw-r--r-- | models/repo.go | 19 | ||||
-rw-r--r-- | modules/middleware/repo.go | 13 | ||||
-rw-r--r-- | public/js/app.js | 59 | ||||
-rw-r--r-- | templates/repo/issue/list.tmpl | 4 | ||||
-rw-r--r-- | templates/repo/nav.tmpl | 2 |
6 files changed, 93 insertions, 10 deletions
diff --git a/models/issue.go b/models/issue.go index c370af363e..6253837237 100644 --- a/models/issue.go +++ b/models/issue.go @@ -19,6 +19,7 @@ var ( ErrIssueNotExist = errors.New("Issue does not exist") ErrLabelNotExist = errors.New("Label does not exist") ErrMilestoneNotExist = errors.New("Milestone does not exist") + ErrWrongIssueCounter = errors.New("Invalid number of issues for this milestone") ) // Issue represents an issue or pull request of repository. @@ -713,6 +714,11 @@ func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) { if issue.IsClosed { m.NumClosedIssues++ } + + if m.NumIssues == 0 { + return ErrWrongIssueCounter + } + m.Completeness = m.NumClosedIssues * 100 / m.NumIssues if _, err = sess.Id(m.Id).Update(m); err != nil { sess.Rollback() diff --git a/models/repo.go b/models/repo.go index fb7bbbd036..845c1b75a9 100644 --- a/models/repo.go +++ b/models/repo.go @@ -8,9 +8,12 @@ import ( "errors" "fmt" "io/ioutil" + "html" + "html/template" "os" "path" "path/filepath" + "regexp" "runtime" "sort" "strings" @@ -46,6 +49,10 @@ var ( LanguageIgns, Licenses []string ) +var ( + DescriptionPattern = regexp.MustCompile(`https?://\S+`) +) + // getAssetList returns corresponding asset list in 'conf'. func getAssetList(prefix string) []string { assets := make([]string, 0, 15) @@ -145,6 +152,16 @@ func (repo *Repository) GetOwner() (err error) { return err } +func (repo *Repository) DescriptionHtml() template.HTML { + sanitize := func(s string) string { + // TODO(nuss-justin): Improve sanitization. Strip all tags? + ss := html.EscapeString(s) + + return fmt.Sprintf(`<a href="%s" target="_blank">%s</a>`, ss, ss) + } + return template.HTML(DescriptionPattern.ReplaceAllStringFunc(repo.Description, sanitize)) +} + // IsRepositoryExist returns true if the repository with given name under user has already existed. func IsRepositoryExist(u *User, repoName string) (bool, error) { repo := Repository{OwnerId: u.Id} @@ -1000,4 +1017,4 @@ func IsWatching(uid, rid int64) bool { func ForkRepository(repoName string, uid int64) { -} +}
\ No newline at end of file diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go index cf8ce412e5..c6febffb2e 100644 --- a/modules/middleware/repo.go +++ b/modules/middleware/repo.go @@ -248,13 +248,24 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler { ctx.Repo.IsWatching = models.IsWatching(ctx.User.Id, repo.Id) } - ctx.Data["BranchName"] = ctx.Repo.BranchName ctx.Data["TagName"] = ctx.Repo.TagName brs, err := ctx.Repo.GitRepo.GetBranches() if err != nil { log.Error("RepoAssignment(GetBranches): %v", err) } ctx.Data["Branches"] = brs + + // If not branch selected, try default one. + // If default branch doesn't exists, fall back to some other branch. + if ctx.Repo.BranchName == "" { + if ctx.Repo.Repository.DefaultBranch != "" && gitRepo.IsBranchExist(ctx.Repo.Repository.DefaultBranch) { + ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch + } else if len(brs) > 0 { + ctx.Repo.BranchName = brs[0] + } + } + + ctx.Data["BranchName"] = ctx.Repo.BranchName ctx.Data["CommitId"] = ctx.Repo.CommitId ctx.Data["IsRepositoryWatching"] = ctx.Repo.IsWatching } diff --git a/public/js/app.js b/public/js/app.js index 88ddd471dc..7d4e7839b4 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -577,15 +577,28 @@ function initIssue() { if (is_issue_bar) { var assignee = $a.data("assigned"); if (uid != assignee) { + var text = $(this).text(); + var img = $("img", this).attr("src"); + $.post($a.data("ajax"), { issue: $('#issue').data("id"), assigneeid: uid }, function (json) { if (json.ok) { - window.location.reload(); + //window.location.reload(); + $a.data("assigned", uid); + + if (uid > 0) { + $('.clear-assignee').toggleShow(); + $(".assignee > p").html('<img src="' + img + '"><strong>' + text + '</strong>'); + } else { + $('.clear-assignee').toggleHide(); + $(".assignee > p").text("No one assigned"); + } } }) } + return; } $('#assignee').val(uid); @@ -611,24 +624,31 @@ function initIssue() { $('.clear-milestone').toggleShow(); } $('.milestone', '#issue').on('click', 'li.milestone-item', function () { - var id = $(this).data("id"); + var id = $(this).data("id"); if (is_issue_bar) { var m = $m.data("milestone"); if (id != m) { + var text = $(this).text(); + $.post($m.data("ajax"), { issue: $('#issue').data("id"), milestone: id }, function (json) { if (json.ok) { - window.location.reload(); - if (id > 0) { + //window.location.reload(); + $m.data("milestone", id); + + if (id > 0) { $('.clear-milestone').toggleShow(); + $(".milestone > .name").html('<a href="' + location.pathname + '?milestone=' + id + '"><strong>' + text + '</strong></a>'); } else { $('.clear-milestone').toggleHide(); + $(".milestone > .name").text("No milestone"); } } - }) + }); } + return; } $('#milestone-id').val(id); @@ -708,13 +728,38 @@ function initIssue() { var color = $item.find('.color').data('color'); $item.css('background-color', color); }); + $('.issue-bar .labels .dropdown-menu').on('click', 'li', function (e) { - var url = $('.issue-bar .labels').data("ajax"); + var $labels = $('.issue-bar .labels'); + var url = $labels.data("ajax"); var id = $(this).data('id'); var check = $(this).hasClass("checked"); + var item = this; $.post(url, {id: id, action: check ? 'detach' : "attach", issue: $('#issue').data('id')}, function (json) { if (json.ok) { - window.location.reload(); + if (check) { + $("span.check.pull-left", item).remove(); + + $(item).removeClass("checked"); + $(item).addClass("no-checked"); + + $("#label-" + id, $labels).remove(); + } else { + $(item).prepend('<span class="check pull-left"><i class="fa fa-check"></i></span>'); + + $(item).removeClass("no-checked"); + $(item).addClass("checked"); + + var $l = $("<p></p>"); + var c = $("span.color", item).css("background-color"); + + $l.attr("id", "label-" + id); + $l.attr("class", "label-item label-white"); + $l.css("background-color", c); + + $l.append("<strong>" + $(item).text() + "</strong>"); + $labels.append($l); + } } }); e.stopPropagation(); diff --git a/templates/repo/issue/list.tmpl b/templates/repo/issue/list.tmpl index 0fae3eb663..ffbdcc8379 100644 --- a/templates/repo/issue/list.tmpl +++ b/templates/repo/issue/list.tmpl @@ -26,6 +26,7 @@ <a class="del pull-right" href="#" data-id="{{.Id}}"><i class="fa fa-times-circle-o"></i></a> </li> {{end}} + {{if or .IsRepositoryOwner .IsAdmin}} <li class="label-change-li" style="display: none"> <form id="label-change-form" action="{{$.RepoLink}}/issues/labels/edit" method="post"> {{.CsrfTokenHtml}} @@ -41,7 +42,9 @@ </div> </form> </li> + {{end}} </ul> + {{if or .IsRepositoryOwner .IsAdmin}} <button class="btn btn-default btn-block label-button" id="label-manage-btn">Manage Labels</button> <hr/> <form id="label-add-form" action="{{$.RepoLink}}/issues/labels/new" method="post"> @@ -57,6 +60,7 @@ <button class="btn btn-default btn-sm">Create</button> </div> </form> + {{end}} </div> </div> <div class="col-md-9"> diff --git a/templates/repo/nav.tmpl b/templates/repo/nav.tmpl index f6530fa1c0..69f60ba469 100644 --- a/templates/repo/nav.tmpl +++ b/templates/repo/nav.tmpl @@ -3,7 +3,7 @@ <div class="row"> <div class="col-md-7"> <h3 class="name"><i class="fa fa-book fa-lg"></i><a href="{{.Owner.HomeLink}}">{{.Owner.Name}}</a> / <a href="/{{.Owner.Name}}/{{.Repository.Name}}">{{.Repository.Name}}</a> {{if .Repository.IsPrivate}}<span class="label label-default">Private</span>{{else if .Repository.IsMirror}}<span class="label label-default">Mirror</span>{{end}}</h3> - <p class="desc">{{.Repository.Description}}{{if .Repository.Website}} <a href="{{.Repository.Website}}">{{.Repository.Website}}</a>{{end}}</p> + <p class="desc">{{.Repository.DescriptionHtml}}{{if .Repository.Website}} <a href="{{.Repository.Website}}">{{.Repository.Website}}</a>{{end}}</p> </div> <div class="col-md-5 actions text-right clone-group-btn"> {{if not .IsBareRepo}} |