| @@ -330,7 +330,7 @@ func runWeb(ctx *cli.Context) { | |||
| m.Get("/template/*", dev.TemplatePreview) | |||
| } | |||
| reqAdmin := middleware.RequireAdmin() | |||
| reqRepoAdmin := middleware.RequireRepoAdmin() | |||
| // Organization. | |||
| m.Group("/org", func() { | |||
| @@ -405,7 +405,7 @@ func runWeb(ctx *cli.Context) { | |||
| m.Post("/:name", repo.GitHooksEditPost) | |||
| }, middleware.GitHookService()) | |||
| }) | |||
| }, reqSignIn, middleware.RepoAssignment(true), reqAdmin) | |||
| }, reqSignIn, middleware.RepoAssignment(true), reqRepoAdmin) | |||
| m.Group("/:username/:reponame", func() { | |||
| m.Get("/action/:action", repo.Action) | |||
| @@ -423,14 +423,14 @@ func runWeb(ctx *cli.Context) { | |||
| m.Post("/new", bindIgnErr(auth.CreateLabelForm{}), repo.NewLabel) | |||
| m.Post("/edit", bindIgnErr(auth.CreateLabelForm{}), repo.UpdateLabel) | |||
| m.Post("/delete", repo.DeleteLabel) | |||
| }) | |||
| }, reqRepoAdmin) | |||
| m.Group("/milestones", func() { | |||
| m.Get("/new", repo.NewMilestone) | |||
| m.Post("/new", bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost) | |||
| m.Get("/:index/edit", repo.UpdateMilestone) | |||
| m.Post("/:index/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.UpdateMilestonePost) | |||
| m.Get("/:index/:action", repo.UpdateMilestone) | |||
| }) | |||
| }, reqRepoAdmin) | |||
| m.Post("/comment/:action", repo.Comment) | |||
| @@ -439,7 +439,7 @@ func runWeb(ctx *cli.Context) { | |||
| m.Post("/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost) | |||
| m.Get("/edit/:tagname", repo.EditRelease) | |||
| m.Post("/edit/:tagname", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost) | |||
| }, middleware.RepoRef()) | |||
| }, reqRepoAdmin, middleware.RepoRef()) | |||
| }, reqSignIn, middleware.RepoAssignment(true)) | |||
| m.Group("/:username/:reponame", func() { | |||
| @@ -392,6 +392,14 @@ issues.label_deletion = Label Deletion | |||
| issues.label_deletion_desc = Delete label will remove its information in all related issues. Do you want to continue? | |||
| issues.label_deletion_success = Label has been deleted successfully! | |||
| milestones.new = New Milestone | |||
| milestones.open_tab = %d Open | |||
| milestones.close_tab = %d Closed | |||
| milestones.closed = Closed %s | |||
| milestones.no_due_date = No due date | |||
| milestones.open = Open | |||
| milestones.close = Close | |||
| settings = Settings | |||
| settings.options = Options | |||
| settings.collaboration = Collaboration | |||
| @@ -17,7 +17,7 @@ import ( | |||
| "github.com/gogits/gogs/modules/setting" | |||
| ) | |||
| const APP_VER = "0.6.3.0802 Beta" | |||
| const APP_VER = "0.6.3.0803 Beta" | |||
| func init() { | |||
| runtime.GOMAXPROCS(runtime.NumCPU()) | |||
| @@ -626,7 +626,7 @@ func DeleteLabel(repoID, labelID int64) error { | |||
| // Milestone represents a milestone of repository. | |||
| type Milestone struct { | |||
| Id int64 | |||
| ID int64 `xorm:"pk autoincr"` | |||
| RepoId int64 `xorm:"INDEX"` | |||
| Index int64 | |||
| Name string | |||
| @@ -670,7 +670,7 @@ func NewMilestone(m *Milestone) (err error) { | |||
| // GetMilestoneById returns the milestone by given ID. | |||
| func GetMilestoneById(id int64) (*Milestone, error) { | |||
| m := &Milestone{Id: id} | |||
| m := &Milestone{ID: id} | |||
| has, err := x.Get(m) | |||
| if err != nil { | |||
| return nil, err | |||
| @@ -692,16 +692,15 @@ func GetMilestoneByIndex(repoId, idx int64) (*Milestone, error) { | |||
| return m, nil | |||
| } | |||
| // GetMilestones returns a list of milestones of given repository and status. | |||
| func GetMilestones(repoId int64, isClosed bool) ([]*Milestone, error) { | |||
| // Milestones returns a list of milestones of given repository and status. | |||
| func Milestones(repoID int64, isClosed bool) ([]*Milestone, error) { | |||
| miles := make([]*Milestone, 0, 10) | |||
| err := x.Where("repo_id=?", repoId).And("is_closed=?", isClosed).Find(&miles) | |||
| return miles, err | |||
| return miles, x.Where("repo_id=? AND is_closed=?", repoID, isClosed).Find(&miles) | |||
| } | |||
| // UpdateMilestone updates information of given milestone. | |||
| func UpdateMilestone(m *Milestone) error { | |||
| _, err := x.Id(m.Id).Update(m) | |||
| _, err := x.Id(m.ID).AllCols().Update(m) | |||
| return err | |||
| } | |||
| @@ -719,7 +718,7 @@ func ChangeMilestoneStatus(m *Milestone, isClosed bool) (err error) { | |||
| } | |||
| m.IsClosed = isClosed | |||
| if _, err = sess.Id(m.Id).AllCols().Update(m); err != nil { | |||
| if _, err = sess.Id(m.ID).AllCols().Update(m); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| @@ -786,7 +785,7 @@ func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) { | |||
| m.Completeness = 0 | |||
| } | |||
| if _, err = sess.Id(m.Id).Cols("num_issues,num_completeness,num_closed_issues").Update(m); err != nil { | |||
| if _, err = sess.Id(m.ID).Cols("num_issues,num_completeness,num_closed_issues").Update(m); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| @@ -814,13 +813,13 @@ func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) { | |||
| } | |||
| m.Completeness = m.NumClosedIssues * 100 / m.NumIssues | |||
| if _, err = sess.Id(m.Id).Cols("num_issues,num_completeness,num_closed_issues").Update(m); err != nil { | |||
| if _, err = sess.Id(m.ID).Cols("num_issues,num_completeness,num_closed_issues").Update(m); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| rawSql := "UPDATE `issue_user` SET milestone_id = ? WHERE issue_id = ?" | |||
| if _, err = sess.Exec(rawSql, m.Id, issue.ID); err != nil { | |||
| if _, err = sess.Exec(rawSql, m.ID, issue.ID); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| @@ -849,19 +848,26 @@ func DeleteMilestone(m *Milestone) (err error) { | |||
| } | |||
| rawSql = "UPDATE `issue` SET milestone_id = 0 WHERE milestone_id = ?" | |||
| if _, err = sess.Exec(rawSql, m.Id); err != nil { | |||
| if _, err = sess.Exec(rawSql, m.ID); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| rawSql = "UPDATE `issue_user` SET milestone_id = 0 WHERE milestone_id = ?" | |||
| if _, err = sess.Exec(rawSql, m.Id); err != nil { | |||
| if _, err = sess.Exec(rawSql, m.ID); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| return sess.Commit() | |||
| } | |||
| // MilestoneStats returns stats of open and closed milestone count of given repository. | |||
| func MilestoneStats(repoID int64) (open int64, closed int64) { | |||
| open, _ = x.Where("repo_id=? AND is_closed=?", repoID, false).Count(new(Milestone)) | |||
| closed, _ = x.Where("repo_id=? AND is_closed=?", repoID, true).Count(new(Milestone)) | |||
| return open, closed | |||
| } | |||
| // _________ __ | |||
| // \_ ___ \ ____ _____ _____ ____ _____/ |_ | |||
| // / \ \/ / _ \ / \ / \_/ __ \ / \ __\ | |||
| @@ -348,7 +348,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler { | |||
| } | |||
| } | |||
| func RequireAdmin() macaron.Handler { | |||
| func RequireRepoAdmin() macaron.Handler { | |||
| return func(ctx *Context) { | |||
| if ctx.Repo.AccessMode < models.ACCESS_MODE_ADMIN { | |||
| if !ctx.IsSigned { | |||
| @@ -93,6 +93,9 @@ $(document).ready(function () { | |||
| }); | |||
| $('.ui.accordion').accordion(); | |||
| $('.ui.checkbox').checkbox(); | |||
| $('.ui.progress').progress({ | |||
| showActivity: false | |||
| }); | |||
| $('.poping.up').popup(); | |||
| initInstall(); | |||
| @@ -97,11 +97,10 @@ | |||
| right: 0!important; | |||
| left: auto!important; | |||
| } | |||
| .issue.list { | |||
| clear: both; | |||
| list-style: none; | |||
| font-size: 13px; | |||
| padding-top: 15px; | |||
| >.item { | |||
| padding-top: 15px; | |||
| padding-bottom: 10px; | |||
| @@ -128,9 +127,10 @@ | |||
| padding-top: 15px; | |||
| } | |||
| } | |||
| .label.list { | |||
| clear: both; | |||
| padding-top: 15px; | |||
| list-style: none; | |||
| .item { | |||
| padding-top: 10px; | |||
| padding-bottom: 10px; | |||
| @@ -149,6 +149,55 @@ | |||
| } | |||
| } | |||
| } | |||
| .milestone.list { | |||
| clear: both; | |||
| list-style: none; | |||
| .item { | |||
| padding-top: 10px; | |||
| padding-bottom: 10px; | |||
| border-bottom: 1px dashed #AAA; | |||
| > a { | |||
| padding-top: 5px; | |||
| padding-right: 10px; | |||
| color: #000; | |||
| &:hover { | |||
| color: #4078c0; | |||
| } | |||
| } | |||
| .ui.progress { | |||
| width: 40%; | |||
| padding: 0; | |||
| border: 0; | |||
| margin: 0; | |||
| .bar { | |||
| height: 20px; | |||
| } | |||
| } | |||
| .meta { | |||
| color: #999; | |||
| padding-top: 5px; | |||
| .issue-stats .octicon{ | |||
| padding-left: 5px; | |||
| } | |||
| } | |||
| .operate { | |||
| margin-top: -15px; | |||
| > a { | |||
| font-size: 15px; | |||
| padding-top: 5px; | |||
| padding-right: 10px; | |||
| color: #666; | |||
| &:hover { | |||
| color: #000; | |||
| } | |||
| } | |||
| } | |||
| .content { | |||
| padding-top: 10px; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .edit-label.modal { | |||
| @@ -159,10 +159,8 @@ func Issues(ctx *middleware.Context) { | |||
| ctx.Data["IsShowClosed"] = isShowClosed | |||
| if isShowClosed { | |||
| ctx.Data["State"] = "closed" | |||
| ctx.Data["ShowCount"] = issueStats.ClosedCount | |||
| } else { | |||
| ctx.Data["State"] = "open" | |||
| ctx.Data["ShowCount"] = issueStats.OpenCount | |||
| } | |||
| ctx.HTML(200, ISSUES) | |||
| @@ -176,12 +174,12 @@ func CreateIssue(ctx *middleware.Context) { | |||
| var err error | |||
| // Get all milestones. | |||
| ctx.Data["OpenMilestones"], err = models.GetMilestones(ctx.Repo.Repository.Id, false) | |||
| ctx.Data["OpenMilestones"], err = models.Milestones(ctx.Repo.Repository.Id, false) | |||
| if err != nil { | |||
| ctx.Handle(500, "issue.ViewIssue(GetMilestones.1): %v", err) | |||
| return | |||
| } | |||
| ctx.Data["ClosedMilestones"], err = models.GetMilestones(ctx.Repo.Repository.Id, true) | |||
| ctx.Data["ClosedMilestones"], err = models.Milestones(ctx.Repo.Repository.Id, true) | |||
| if err != nil { | |||
| ctx.Handle(500, "issue.ViewIssue(GetMilestones.2): %v", err) | |||
| return | |||
| @@ -220,12 +218,12 @@ func CreateIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) { | |||
| var err error | |||
| // Get all milestones. | |||
| _, err = models.GetMilestones(ctx.Repo.Repository.Id, false) | |||
| _, err = models.Milestones(ctx.Repo.Repository.Id, false) | |||
| if err != nil { | |||
| send(500, nil, err) | |||
| return | |||
| } | |||
| _, err = models.GetMilestones(ctx.Repo.Repository.Id, true) | |||
| _, err = models.Milestones(ctx.Repo.Repository.Id, true) | |||
| if err != nil { | |||
| send(500, nil, err) | |||
| return | |||
| @@ -385,12 +383,12 @@ func ViewIssue(ctx *middleware.Context) { | |||
| } | |||
| // Get all milestones. | |||
| ctx.Data["OpenMilestones"], err = models.GetMilestones(ctx.Repo.Repository.Id, false) | |||
| ctx.Data["OpenMilestones"], err = models.Milestones(ctx.Repo.Repository.Id, false) | |||
| if err != nil { | |||
| ctx.Handle(500, "issue.ViewIssue(GetMilestones.1): %v", err) | |||
| return | |||
| } | |||
| ctx.Data["ClosedMilestones"], err = models.GetMilestones(ctx.Repo.Repository.Id, true) | |||
| ctx.Data["ClosedMilestones"], err = models.Milestones(ctx.Repo.Repository.Id, true) | |||
| if err != nil { | |||
| ctx.Handle(500, "issue.ViewIssue(GetMilestones.2): %v", err) | |||
| return | |||
| @@ -967,13 +965,12 @@ func DeleteLabel(ctx *middleware.Context) { | |||
| } | |||
| func Milestones(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = "Milestones" | |||
| ctx.Data["IsRepoToolbarIssues"] = true | |||
| ctx.Data["IsRepoToolbarIssuesList"] = true | |||
| ctx.Data["Title"] = ctx.Tr("repo.milestones") | |||
| ctx.Data["PageIsMilestones"] = true | |||
| isShowClosed := ctx.Query("state") == "closed" | |||
| miles, err := models.GetMilestones(ctx.Repo.Repository.Id, isShowClosed) | |||
| miles, err := models.Milestones(ctx.Repo.Repository.Id, isShowClosed) | |||
| if err != nil { | |||
| ctx.Handle(500, "GetMilestones", err) | |||
| return | |||
| @@ -984,11 +981,17 @@ func Milestones(ctx *middleware.Context) { | |||
| } | |||
| ctx.Data["Milestones"] = miles | |||
| openCount, closedCount := models.MilestoneStats(ctx.Repo.Repository.Id) | |||
| ctx.Data["OpenCount"] = openCount | |||
| ctx.Data["ClosedCount"] = closedCount | |||
| if isShowClosed { | |||
| ctx.Data["State"] = "closed" | |||
| } else { | |||
| ctx.Data["State"] = "open" | |||
| } | |||
| ctx.Data["IsShowClosed"] = isShowClosed | |||
| ctx.HTML(200, MILESTONE) | |||
| } | |||
| @@ -1 +1 @@ | |||
| 0.6.3.0802 Beta | |||
| 0.6.3.0803 Beta | |||
| @@ -32,17 +32,19 @@ | |||
| <div class="ui black label">{{.i18n.Tr "repo.issues.label_count" .NumLabels}}</div> | |||
| </div> | |||
| <div class="label list"> | |||
| {{range .Labels}} | |||
| <li class="item"> | |||
| <div class="ui label" style="background-color: {{.Color}}"><i class="octicon octicon-tag"></i> {{.Name}}</div> | |||
| {{if $.IsRepositoryAdmin}} | |||
| <a class="ui right delete-label-button" href="#" data-url="{{$.RepoLink}}/labels/delete" data-id="{{.ID}}"><i class="octicon octicon-x"></i> {{$.i18n.Tr "repo.issues.label_delete"}}</a> | |||
| <a class="ui right edit-label-button" href="#" data-id={{.ID}} data-title={{.Name}} data-color={{.Color}}><i class="octicon octicon-pencil"></i> {{$.i18n.Tr "repo.issues.label_edit"}}</a> | |||
| <div class="sixteen wide column"> | |||
| <div class="label list"> | |||
| {{range .Labels}} | |||
| <li class="item"> | |||
| <div class="ui label" style="background-color: {{.Color}}"><i class="octicon octicon-tag"></i> {{.Name}}</div> | |||
| {{if $.IsRepositoryAdmin}} | |||
| <a class="ui right delete-label-button" href="#" data-url="{{$.RepoLink}}/labels/delete" data-id="{{.ID}}"><i class="octicon octicon-trashcan"></i> {{$.i18n.Tr "repo.issues.label_delete"}}</a> | |||
| <a class="ui right edit-label-button" href="#" data-id={{.ID}} data-title={{.Name}} data-color={{.Color}}><i class="octicon octicon-pencil"></i> {{$.i18n.Tr "repo.issues.label_edit"}}</a> | |||
| {{end}} | |||
| <a class="ui right open-issues" href="{{$.RepoLink}}/issues?labels={{.ID}}"><i class="octicon octicon-issue-opened"></i> {{$.i18n.Tr "repo.issues.label_open_issues" .NumOpenIssues}}</a> | |||
| </li> | |||
| {{end}} | |||
| <a class="ui right open-issues" href="{{$.RepoLink}}/issues?labels={{.ID}}"><i class="octicon octicon-issue-opened"></i> {{$.i18n.Tr "repo.issues.label_open_issues" .NumOpenIssues}}</a> | |||
| </li> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -70,43 +70,45 @@ | |||
| </div> | |||
| </div> | |||
| <div class="issue list"> | |||
| {{range .Issues}} | |||
| {{ $timeStr:= TimeSince .Created $.Lang }} | |||
| <li class="item"> | |||
| <div class="ui {{if .IsRead}}black{{else}}green{{end}} label">#{{.Index}}</div> | |||
| <a class="title" href="{{$.RepoLink}}/issues/{{.Index}}">{{.Name}}</a> | |||
| <div class="sixteen wide column"> | |||
| <div class="issue list"> | |||
| {{range .Issues}} | |||
| {{ $timeStr:= TimeSince .Created $.Lang }} | |||
| <li class="item"> | |||
| <div class="ui {{if .IsRead}}black{{else}}green{{end}} label">#{{.Index}}</div> | |||
| <a class="title" href="{{$.RepoLink}}/issues/{{.Index}}">{{.Name}}</a> | |||
| {{range .Labels}} | |||
| <a class="ui label" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}" style="background-color: {{.Color}}">{{.Name}}</a> | |||
| {{end}} | |||
| {{range .Labels}} | |||
| <a class="ui label" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}" style="background-color: {{.Color}}">{{.Name}}</a> | |||
| {{end}} | |||
| {{if .NumComments}}<span class="comment ui right"><i class="octicon octicon-comment"></i> {{.NumComments}}</span>{{end}} | |||
| <p class="desc">{{$.i18n.Tr "repo.issues.opened_by" $timeStr .Poster.Name|Str2html}}</p> | |||
| </li> | |||
| {{end}} | |||
| {{with .Page}} | |||
| {{if gt .Total 1}} | |||
| <div class="center page buttons"> | |||
| <div class="ui borderless pagination menu"> | |||
| <a class="{{if not .HasPrevious}}disabled{{end}} item" {{if .HasPrevious}}href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&page={{.Previous}}"{{end}}> | |||
| <i class="left arrow icon"></i> {{$.i18n.Tr "repo.issues.previous"}} | |||
| </a> | |||
| {{range .Pages}} | |||
| {{if eq .Num -1}} | |||
| <a class="disabled item">...</a> | |||
| {{else}} | |||
| <a class="{{if .IsCurrent}}active{{end}} item" {{if not .IsCurrent}}href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&page={{.Num}}"{{end}}>{{.Num}}</a> | |||
| {{end}} | |||
| {{end}} | |||
| <a class="{{if not .HasNext}}disabled{{end}} item" {{if .HasNext}}href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&page={{.Next}}"{{end}}> | |||
| {{$.i18n.Tr "repo.issues.next"}} <i class="icon right arrow"></i> | |||
| </a> | |||
| {{if .NumComments}}<span class="comment ui right"><i class="octicon octicon-comment"></i> {{.NumComments}}</span>{{end}} | |||
| <p class="desc">{{$.i18n.Tr "repo.issues.opened_by" $timeStr .Poster.Name|Str2html}}</p> | |||
| </li> | |||
| {{end}} | |||
| {{with .Page}} | |||
| {{if gt .Total 1}} | |||
| <div class="center page buttons"> | |||
| <div class="ui borderless pagination menu"> | |||
| <a class="{{if not .HasPrevious}}disabled{{end}} item" {{if .HasPrevious}}href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&page={{.Previous}}"{{end}}> | |||
| <i class="left arrow icon"></i> {{$.i18n.Tr "repo.issues.previous"}} | |||
| </a> | |||
| {{range .Pages}} | |||
| {{if eq .Num -1}} | |||
| <a class="disabled item">...</a> | |||
| {{else}} | |||
| <a class="{{if .IsCurrent}}active{{end}} item" {{if not .IsCurrent}}href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&page={{.Num}}"{{end}}>{{.Num}}</a> | |||
| {{end}} | |||
| {{end}} | |||
| <a class="{{if not .HasNext}}disabled{{end}} item" {{if .HasNext}}href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&page={{.Next}}"{{end}}> | |||
| {{$.i18n.Tr "repo.issues.next"}} <i class="icon right arrow"></i> | |||
| </a> | |||
| </div> | |||
| </div> | |||
| {{end}} | |||
| {{end}} | |||
| </div> | |||
| {{end}} | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -1,43 +1,70 @@ | |||
| {{template "base/head_old" .}} | |||
| {{template "base/navbar" .}} | |||
| {{template "repo/nav" .}} | |||
| {{template "repo/toolbar" .}} | |||
| <div id="body" class="container"> | |||
| <div id="issue"> | |||
| <div class="col-md-3 filter-list"> | |||
| <ul class="list-unstyled"> | |||
| <li><a href="{{.RepoLink}}/milestones"{{if eq .State "open"}} class="active"{{end}}>Open Milestones <strong class="pull-right">{{.Repository.NumOpenMilestones}}</strong></a></li> | |||
| <li><a href="{{.RepoLink}}/milestones?state=closed"{{if eq .State "closed"}} class="active"{{end}}>Close Milestones <strong class="pull-right">{{.Repository.NumClosedMilestones}}</strong></a></li> | |||
| </ul> | |||
| <hr/> | |||
| <a href="{{.RepoLink}}/milestones/new" class="text-center"> | |||
| <button class="btn btn-default btn-block">Create new milestone</button> | |||
| </a> | |||
| </div> | |||
| <div class="col-md-9"> | |||
| <div class="milestones list-group"> | |||
| {{range .Milestones}} | |||
| <div class="list-group-item milestone-item"> | |||
| <h4 class="title pull-left"><a href="{{$.RepoLink}}/issues?milestone={{.Index}}{{if .IsClosed}}&state=closed{{end}}">{{.Name}}</a></h4> | |||
| <span class="issue-open label label-success">{{.NumOpenIssues}}</span> | |||
| <span class="issue-close label label-warning">{{.NumClosedIssues}}</span> | |||
| <p class="actions pull-right"> | |||
| <a href="{{$.RepoLink}}/milestones/{{.Index}}/edit">Edit</a> | |||
| {{if .IsClosed}} | |||
| <a href="{{$.RepoLink}}/milestones/{{.Index}}/open">Open</a> | |||
| {{else}} | |||
| <a href="{{$.RepoLink}}/milestones/{{.Index}}/close">Close</a> | |||
| {{end}} | |||
| <a class="text-danger" href="{{$.RepoLink}}/milestones/{{.Index}}/delete">Delete</a> | |||
| <a href="{{$.RepoLink}}/issues?milestone={{.Index}}{{if .IsClosed}}&state=closed{{end}}">Issues</a> | |||
| </p> | |||
| <hr/> | |||
| <p class="description">{{.RenderedContent | Str2html}}</p> | |||
| </div> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/head" .}} | |||
| <div class="repository"> | |||
| {{template "repo/header" .}} | |||
| <div class="ui middle page grid body"> | |||
| <div class="navbar"> | |||
| {{template "repo/issue/navbar" .}} | |||
| <div class="ui right floated secondary menu"> | |||
| <a class="ui green button" href="{{$.RepoLink}}/milestones/new">{{.i18n.Tr "repo.milestones.new"}}</a> | |||
| </div> | |||
| </div> | |||
| <div class="ui divider"></div> | |||
| <div class="ui left"> | |||
| <div class="ui tiny buttons"> | |||
| <a class="ui green basic button {{if not .IsShowClosed}}active{{end}}" href="{{.RepoLink}}/milestones?state=open"> | |||
| <i class="octicon octicon-milestone"></i> | |||
| {{.i18n.Tr "repo.milestones.open_tab" .OpenCount}} | |||
| </a> | |||
| <a class="ui red basic button {{if .IsShowClosed}}active{{end}}" href="{{.RepoLink}}/milestones?state=closed"> | |||
| <i class="octicon octicon-milestone"></i> | |||
| {{.i18n.Tr "repo.milestones.close_tab" .ClosedCount}} | |||
| </a> | |||
| </div> | |||
| </div> | |||
| <div class="sixteen wide column"> | |||
| <div class="milestone list"> | |||
| {{range .Milestones}} | |||
| <li class="item"> | |||
| <i class="octicon octicon-milestone"></i> <a href="{{$.RepoLink}}/issues?state={{$.State}}&midx={{.Index}}">{{.Name}}</a> | |||
| <div class="ui right blue progress" data-percent="{{if .Completeness}}{{.Completeness}}{{else}}100{{end}}"> | |||
| <div class="bar"> | |||
| <div class="progress"></div> | |||
| </div> | |||
| </div> | |||
| <div class="meta"> | |||
| {{ $closedDate:= TimeSince .ClosedDate $.Lang }} | |||
| {{if .IsClosed}} | |||
| <span class="octicon octicon-clock"></span> {{$.i18n.Tr "repo.milestones.closed" $closedDate|Str2html}} | |||
| {{else}} | |||
| <span class="octicon octicon-calendar"></span> {{if .DeadlineString}}{{.DeadlineString}}{{else}}{{$.i18n.Tr "repo.milestones.no_due_date"}}{{end}} | |||
| {{end}} | |||
| <span class="issue-stats"> | |||
| <i class="octicon octicon-issue-opened"></i> {{$.i18n.Tr "repo.issues.open_tab" .NumOpenIssues}} | |||
| <i class="octicon octicon-issue-closed"></i> {{$.i18n.Tr "repo.issues.close_tab" .NumClosedIssues}} | |||
| </span> | |||
| </div> | |||
| {{if $.IsRepositoryAdmin}} | |||
| <div class="ui right operate"> | |||
| <a href="{{$.RepoLink}}/milestones/{{.Index}}/edit" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-pencil"></i> {{$.i18n.Tr "repo.issues.label_edit"}}</a> | |||
| {{if .IsClosed}} | |||
| <a href="{{$.RepoLink}}/milestones/{{.Index}}/open" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-check"></i> {{$.i18n.Tr "repo.milestones.open"}}</a> | |||
| {{else}} | |||
| <a href="{{$.RepoLink}}/milestones/{{.Index}}/close" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-x"></i> {{$.i18n.Tr "repo.milestones.close"}}</a> | |||
| {{end}} | |||
| <a class="delete-milestone-button" href="#" data-url="{{$.RepoLink}}/milestone/delete" data-id="{{.ID}}"><i class="octicon octicon-trashcan"></i> {{$.i18n.Tr "repo.issues.label_delete"}}</a> | |||
| </div> | |||
| {{if .Content}} | |||
| <div class="content"> | |||
| {{.RenderedContent|Str2html}} | |||
| </div> | |||
| {{end}} | |||
| {{end}} | |||
| </li> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer_old" .}} | |||
| {{template "base/footer" .}} | |||
| @@ -0,0 +1,43 @@ | |||
| {{template "base/head_old" .}} | |||
| {{template "base/navbar" .}} | |||
| {{template "repo/nav" .}} | |||
| {{template "repo/toolbar" .}} | |||
| <div id="body" class="container"> | |||
| <div id="issue"> | |||
| <div class="col-md-3 filter-list"> | |||
| <ul class="list-unstyled"> | |||
| <li><a href="{{.RepoLink}}/milestones"{{if eq .State "open"}} class="active"{{end}}>Open Milestones <strong class="pull-right">{{.Repository.NumOpenMilestones}}</strong></a></li> | |||
| <li><a href="{{.RepoLink}}/milestones?state=closed"{{if eq .State "closed"}} class="active"{{end}}>Close Milestones <strong class="pull-right">{{.Repository.NumClosedMilestones}}</strong></a></li> | |||
| </ul> | |||
| <hr/> | |||
| <a href="{{.RepoLink}}/milestones/new" class="text-center"> | |||
| <button class="btn btn-default btn-block">Create new milestone</button> | |||
| </a> | |||
| </div> | |||
| <div class="col-md-9"> | |||
| <div class="milestones list-group"> | |||
| {{range .Milestones}} | |||
| <div class="list-group-item milestone-item"> | |||
| <h4 class="title pull-left"><a href="{{$.RepoLink}}/issues?milestone={{.Index}}{{if .IsClosed}}&state=closed{{end}}">{{.Name}}</a></h4> | |||
| <span class="issue-open label label-success">{{.NumOpenIssues}}</span> | |||
| <span class="issue-close label label-warning">{{.NumClosedIssues}}</span> | |||
| <p class="actions pull-right"> | |||
| <a href="{{$.RepoLink}}/milestones/{{.Index}}/edit">Edit</a> | |||
| {{if .IsClosed}} | |||
| <a href="{{$.RepoLink}}/milestones/{{.Index}}/open">Open</a> | |||
| {{else}} | |||
| <a href="{{$.RepoLink}}/milestones/{{.Index}}/close">Close</a> | |||
| {{end}} | |||
| <a class="text-danger" href="{{$.RepoLink}}/milestones/{{.Index}}/delete">Delete</a> | |||
| <a href="{{$.RepoLink}}/issues?milestone={{.Index}}{{if .IsClosed}}&state=closed{{end}}">Issues</a> | |||
| </p> | |||
| <hr/> | |||
| <p class="description">{{.RenderedContent | Str2html}}</p> | |||
| </div> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer_old" .}} | |||
| @@ -2,6 +2,6 @@ | |||
| <div class="ui compact menu"> | |||
| <a class="{{if .PageIsIssueList}}active{{end}} item" href="{{.RepoLink}}/issues">{{.i18n.Tr "repo.issues"}}</a> | |||
| <a class="{{if .PageIsLabels}}active{{end}} item" href="{{.RepoLink}}/labels">{{.i18n.Tr "repo.labels"}}</a> | |||
| <a class="item" href="{{.RepoLink}}/milestones">{{.i18n.Tr "repo.milestones"}}</a> | |||
| <a class="{{if .PageIsMilestones}}active{{end}} item" href="{{.RepoLink}}/milestones">{{.i18n.Tr "repo.milestones"}}</a> | |||
| </div> | |||
| </div> | |||