mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	finish new milestone page
This commit is contained in:
		@@ -7,7 +7,7 @@ Gogs (Go Git Service) is a painless self-hosted Git service.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||

 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##### Current version: 0.6.3 Beta
 | 
					##### Current version: 0.6.4 Beta
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### NOTICES
 | 
					### NOTICES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -429,7 +429,8 @@ func runWeb(ctx *cli.Context) {
 | 
				
			|||||||
			m.Post("/new", bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost)
 | 
								m.Post("/new", bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost)
 | 
				
			||||||
			m.Get("/:index/edit", repo.EditMilestone)
 | 
								m.Get("/:index/edit", repo.EditMilestone)
 | 
				
			||||||
			m.Post("/:index/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.EditMilestonePost)
 | 
								m.Post("/:index/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.EditMilestonePost)
 | 
				
			||||||
			m.Get("/:index/:action", repo.MilestoneActions)
 | 
								m.Get("/:index/:action", repo.ChangeMilestonStatus)
 | 
				
			||||||
 | 
								m.Post("/delete", repo.DeleteMilestone)
 | 
				
			||||||
		}, reqRepoAdmin)
 | 
							}, reqRepoAdmin)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		m.Post("/comment/:action", repo.Comment)
 | 
							m.Post("/comment/:action", repo.Comment)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -372,6 +372,7 @@ issues.close_tab = %d Closed
 | 
				
			|||||||
issues.filter_label = Label
 | 
					issues.filter_label = Label
 | 
				
			||||||
issues.filter_label_no_select = No selected label
 | 
					issues.filter_label_no_select = No selected label
 | 
				
			||||||
issues.filter_milestone = Milestone
 | 
					issues.filter_milestone = Milestone
 | 
				
			||||||
 | 
					issues.filter_milestone_no_select = No selected milestone
 | 
				
			||||||
issues.filter_assignee = Assignee
 | 
					issues.filter_assignee = Assignee
 | 
				
			||||||
issues.filter_type = Type
 | 
					issues.filter_type = Type
 | 
				
			||||||
issues.filter_type.all_issues = All issues
 | 
					issues.filter_type.all_issues = All issues
 | 
				
			||||||
@@ -412,6 +413,9 @@ milestones.edit_subheader = Use better description for milestones so people won'
 | 
				
			|||||||
milestones.cancel = Cancel
 | 
					milestones.cancel = Cancel
 | 
				
			||||||
milestones.modify = Modify Milestone
 | 
					milestones.modify = Modify Milestone
 | 
				
			||||||
milestones.edit_success = Changes of milestone '%s' has been saved successfully!
 | 
					milestones.edit_success = Changes of milestone '%s' has been saved successfully!
 | 
				
			||||||
 | 
					milestones.deletion = Milestone Deletion
 | 
				
			||||||
 | 
					milestones.deletion_desc = Delete milestone will remove its information in all related issues. Do you want to continue?
 | 
				
			||||||
 | 
					milestones.deletion_success = Milestone has been deleted successfully!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
settings = Settings
 | 
					settings = Settings
 | 
				
			||||||
settings.options = Options
 | 
					settings.options = Options
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							@@ -17,7 +17,7 @@ import (
 | 
				
			|||||||
	"github.com/gogits/gogs/modules/setting"
 | 
						"github.com/gogits/gogs/modules/setting"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const APP_VER = "0.6.3.0805 Beta"
 | 
					const APP_VER = "0.6.4.0805 Beta"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	runtime.GOMAXPROCS(runtime.NumCPU())
 | 
						runtime.GOMAXPROCS(runtime.NumCPU())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -153,7 +153,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			url := fmt.Sprintf("%s/%s/%s/commit/%s", setting.AppSubUrl, repoUserName, repoName, c.Sha1)
 | 
								url := fmt.Sprintf("%s/%s/%s/commit/%s", setting.AppSubUrl, repoUserName, repoName, c.Sha1)
 | 
				
			||||||
			message := fmt.Sprintf(`<a href="%s">%s</a>`, url, c.Message)
 | 
								message := fmt.Sprintf(`<a href="%s">%s</a>`, url, c.Message)
 | 
				
			||||||
			if _, err = CreateComment(userId, issue.RepoId, issue.ID, 0, 0, COMMENT_TYPE_COMMIT, message, nil); err != nil {
 | 
								if _, err = CreateComment(userId, issue.RepoID, issue.ID, 0, 0, COMMENT_TYPE_COMMIT, message, nil); err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -183,7 +183,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
 | 
				
			|||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if issue.RepoId == repoId {
 | 
								if issue.RepoID == repoId {
 | 
				
			||||||
				if issue.IsClosed {
 | 
									if issue.IsClosed {
 | 
				
			||||||
					continue
 | 
										continue
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -242,7 +242,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
 | 
				
			|||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if issue.RepoId == repoId {
 | 
								if issue.RepoID == repoId {
 | 
				
			||||||
				if !issue.IsClosed {
 | 
									if !issue.IsClosed {
 | 
				
			||||||
					continue
 | 
										continue
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										132
									
								
								models/issue.go
									
									
									
									
									
								
							
							
						
						
									
										132
									
								
								models/issue.go
									
									
									
									
									
								
							@@ -32,16 +32,17 @@ var (
 | 
				
			|||||||
// Issue represents an issue or pull request of repository.
 | 
					// Issue represents an issue or pull request of repository.
 | 
				
			||||||
type Issue struct {
 | 
					type Issue struct {
 | 
				
			||||||
	ID              int64 `xorm:"pk autoincr"`
 | 
						ID              int64 `xorm:"pk autoincr"`
 | 
				
			||||||
	RepoId          int64 `xorm:"INDEX"`
 | 
						RepoID          int64 `xorm:"INDEX"`
 | 
				
			||||||
	Index           int64 // Index in one repository.
 | 
						Index           int64 // Index in one repository.
 | 
				
			||||||
	Name            string
 | 
						Name            string
 | 
				
			||||||
	Repo            *Repository `xorm:"-"`
 | 
						Repo            *Repository `xorm:"-"`
 | 
				
			||||||
	PosterId        int64
 | 
						PosterID        int64
 | 
				
			||||||
	Poster          *User    `xorm:"-"`
 | 
						Poster          *User    `xorm:"-"`
 | 
				
			||||||
	LabelIds        string   `xorm:"TEXT"`
 | 
						LabelIds        string   `xorm:"TEXT"`
 | 
				
			||||||
	Labels          []*Label `xorm:"-"`
 | 
						Labels          []*Label `xorm:"-"`
 | 
				
			||||||
	MilestoneId     int64
 | 
						MilestoneID     int64
 | 
				
			||||||
	AssigneeId      int64
 | 
						Milestone       *Milestone `xorm:"-"`
 | 
				
			||||||
 | 
						AssigneeID      int64
 | 
				
			||||||
	Assignee        *User `xorm:"-"`
 | 
						Assignee        *User `xorm:"-"`
 | 
				
			||||||
	IsRead          bool  `xorm:"-"`
 | 
						IsRead          bool  `xorm:"-"`
 | 
				
			||||||
	IsPull          bool  // Indicates whether is a pull request or not.
 | 
						IsPull          bool  // Indicates whether is a pull request or not.
 | 
				
			||||||
@@ -55,8 +56,24 @@ type Issue struct {
 | 
				
			|||||||
	Updated         time.Time `xorm:"UPDATED"`
 | 
						Updated         time.Time `xorm:"UPDATED"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (i *Issue) BeforeSet(colName string, val xorm.Cell) {
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						switch colName {
 | 
				
			||||||
 | 
						case "milestone_id":
 | 
				
			||||||
 | 
							mid := (*val).(int64)
 | 
				
			||||||
 | 
							if mid <= 0 {
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							i.Milestone, err = GetMilestoneById(mid)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Error(3, "GetMilestoneById: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (i *Issue) GetPoster() (err error) {
 | 
					func (i *Issue) GetPoster() (err error) {
 | 
				
			||||||
	i.Poster, err = GetUserById(i.PosterId)
 | 
						i.Poster, err = GetUserById(i.PosterID)
 | 
				
			||||||
	if err == ErrUserNotExist {
 | 
						if err == ErrUserNotExist {
 | 
				
			||||||
		i.Poster = &User{Name: "FakeUser"}
 | 
							i.Poster = &User{Name: "FakeUser"}
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
@@ -88,10 +105,10 @@ func (i *Issue) GetLabels() error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (i *Issue) GetAssignee() (err error) {
 | 
					func (i *Issue) GetAssignee() (err error) {
 | 
				
			||||||
	if i.AssigneeId == 0 {
 | 
						if i.AssigneeID == 0 {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	i.Assignee, err = GetUserById(i.AssigneeId)
 | 
						i.Assignee, err = GetUserById(i.AssigneeID)
 | 
				
			||||||
	if err == ErrUserNotExist {
 | 
						if err == ErrUserNotExist {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -121,7 +138,7 @@ func NewIssue(issue *Issue) (err error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if _, err = sess.Insert(issue); err != nil {
 | 
						if _, err = sess.Insert(issue); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	} else if _, err = sess.Exec("UPDATE `repository` SET num_issues = num_issues + 1 WHERE id = ?", issue.RepoId); err != nil {
 | 
						} else if _, err = sess.Exec("UPDATE `repository` SET num_issues = num_issues + 1 WHERE id = ?", issue.RepoID); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -129,9 +146,9 @@ func NewIssue(issue *Issue) (err error) {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if issue.MilestoneId > 0 {
 | 
						if issue.MilestoneID > 0 {
 | 
				
			||||||
		// FIXES(280): Update milestone counter.
 | 
							// FIXES(280): Update milestone counter.
 | 
				
			||||||
		return ChangeMilestoneAssign(0, issue.MilestoneId, issue)
 | 
							return ChangeMilestoneAssign(0, issue.MilestoneID, issue)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
@@ -162,7 +179,7 @@ func GetIssueByRef(ref string) (issue *Issue, err error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// GetIssueByIndex returns issue by given index in repository.
 | 
					// GetIssueByIndex returns issue by given index in repository.
 | 
				
			||||||
func GetIssueByIndex(rid, index int64) (*Issue, error) {
 | 
					func GetIssueByIndex(rid, index int64) (*Issue, error) {
 | 
				
			||||||
	issue := &Issue{RepoId: rid, Index: index}
 | 
						issue := &Issue{RepoID: rid, Index: index}
 | 
				
			||||||
	has, err := x.Get(issue)
 | 
						has, err := x.Get(issue)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
@@ -683,8 +700,8 @@ func NewMilestone(m *Milestone) (err error) {
 | 
				
			|||||||
	return sess.Commit()
 | 
						return sess.Commit()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MilestoneById returns the milestone by given ID.
 | 
					// GetMilestoneById returns the milestone by given ID.
 | 
				
			||||||
func MilestoneById(id int64) (*Milestone, error) {
 | 
					func GetMilestoneById(id int64) (*Milestone, error) {
 | 
				
			||||||
	m := &Milestone{ID: id}
 | 
						m := &Milestone{ID: id}
 | 
				
			||||||
	has, err := x.Get(m)
 | 
						has, err := x.Get(m)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -707,6 +724,12 @@ func GetMilestoneByIndex(repoId, idx int64) (*Milestone, error) {
 | 
				
			|||||||
	return m, nil
 | 
						return m, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetAllRepoMilestones returns all milestones of given repository.
 | 
				
			||||||
 | 
					func GetAllRepoMilestones(repoID int64) ([]*Milestone, error) {
 | 
				
			||||||
 | 
						miles := make([]*Milestone, 0, 10)
 | 
				
			||||||
 | 
						return miles, x.Where("repo_id=?", repoID).Find(&miles)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetMilestones returns a list of milestones of given repository and status.
 | 
					// GetMilestones returns a list of milestones of given repository and status.
 | 
				
			||||||
func GetMilestones(repoID int64, page int, isClosed bool) ([]*Milestone, error) {
 | 
					func GetMilestones(repoID int64, page int, isClosed bool) ([]*Milestone, error) {
 | 
				
			||||||
	miles := make([]*Milestone, 0, setting.IssuePagingNum)
 | 
						miles := make([]*Milestone, 0, setting.IssuePagingNum)
 | 
				
			||||||
@@ -718,22 +741,40 @@ func GetMilestones(repoID int64, page int, isClosed bool) ([]*Milestone, error)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UpdateMilestone updates information of given milestone.
 | 
					func updateMilestone(e Engine, m *Milestone) error {
 | 
				
			||||||
func UpdateMilestone(m *Milestone) error {
 | 
						_, err := e.Id(m.ID).AllCols().Update(m)
 | 
				
			||||||
	_, err := x.Id(m.ID).AllCols().Update(m)
 | 
					 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CountClosedMilestones returns number of closed milestones in given repository.
 | 
					// UpdateMilestone updates information of given milestone.
 | 
				
			||||||
func CountClosedMilestones(repoID int64) int64 {
 | 
					func UpdateMilestone(m *Milestone) error {
 | 
				
			||||||
	closed, _ := x.Where("repo_id=? AND is_closed=?", repoID, true).Count(new(Milestone))
 | 
						return updateMilestone(x, m)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func countRepoMilestones(e Engine, repoID int64) int64 {
 | 
				
			||||||
 | 
						count, _ := e.Where("repo_id=?", repoID).Count(new(Milestone))
 | 
				
			||||||
 | 
						return count
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CountRepoMilestones returns number of milestones in given repository.
 | 
				
			||||||
 | 
					func CountRepoMilestones(repoID int64) int64 {
 | 
				
			||||||
 | 
						return countRepoMilestones(x, repoID)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func countRepoClosedMilestones(e Engine, repoID int64) int64 {
 | 
				
			||||||
 | 
						closed, _ := e.Where("repo_id=? AND is_closed=?", repoID, true).Count(new(Milestone))
 | 
				
			||||||
	return closed
 | 
						return closed
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CountRepoClosedMilestones returns number of closed milestones in given repository.
 | 
				
			||||||
 | 
					func CountRepoClosedMilestones(repoID int64) int64 {
 | 
				
			||||||
 | 
						return countRepoClosedMilestones(x, repoID)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MilestoneStats returns number of open and closed milestones of given repository.
 | 
					// MilestoneStats returns number of open and closed milestones of given repository.
 | 
				
			||||||
func MilestoneStats(repoID int64) (open int64, closed int64) {
 | 
					func MilestoneStats(repoID int64) (open int64, closed int64) {
 | 
				
			||||||
	open, _ = x.Where("repo_id=? AND is_closed=?", repoID, false).Count(new(Milestone))
 | 
						open, _ = x.Where("repo_id=? AND is_closed=?", repoID, false).Count(new(Milestone))
 | 
				
			||||||
	return open, CountClosedMilestones(repoID)
 | 
						return open, CountRepoClosedMilestones(repoID)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ChangeMilestoneStatus changes the milestone open/closed status.
 | 
					// ChangeMilestoneStatus changes the milestone open/closed status.
 | 
				
			||||||
@@ -750,11 +791,12 @@ func ChangeMilestoneStatus(m *Milestone, isClosed bool) (err error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m.IsClosed = isClosed
 | 
						m.IsClosed = isClosed
 | 
				
			||||||
	if err = UpdateMilestone(m); err != nil {
 | 
						if err = updateMilestone(sess, m); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	repo.NumClosedMilestones = int(CountClosedMilestones(repo.Id))
 | 
						repo.NumMilestones = int(countRepoMilestones(sess, repo.Id))
 | 
				
			||||||
 | 
						repo.NumClosedMilestones = int(countRepoClosedMilestones(sess, repo.Id))
 | 
				
			||||||
	if _, err = sess.Id(repo.Id).AllCols().Update(repo); err != nil {
 | 
						if _, err = sess.Id(repo.Id).AllCols().Update(repo); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -764,11 +806,11 @@ func ChangeMilestoneStatus(m *Milestone, isClosed bool) (err error) {
 | 
				
			|||||||
// ChangeMilestoneIssueStats updates the open/closed issues counter and progress
 | 
					// ChangeMilestoneIssueStats updates the open/closed issues counter and progress
 | 
				
			||||||
// for the milestone associated witht the given issue.
 | 
					// for the milestone associated witht the given issue.
 | 
				
			||||||
func ChangeMilestoneIssueStats(issue *Issue) error {
 | 
					func ChangeMilestoneIssueStats(issue *Issue) error {
 | 
				
			||||||
	if issue.MilestoneId == 0 {
 | 
						if issue.MilestoneID == 0 {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m, err := MilestoneById(issue.MilestoneId)
 | 
						m, err := GetMilestoneById(issue.MilestoneID)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -795,7 +837,7 @@ func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if oldMid > 0 {
 | 
						if oldMid > 0 {
 | 
				
			||||||
		m, err := MilestoneById(oldMid)
 | 
							m, err := GetMilestoneById(oldMid)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -823,7 +865,7 @@ func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if mid > 0 {
 | 
						if mid > 0 {
 | 
				
			||||||
		m, err := MilestoneById(mid)
 | 
							m, err := GetMilestoneById(mid)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -853,34 +895,40 @@ func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) {
 | 
				
			|||||||
	return sess.Commit()
 | 
						return sess.Commit()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// DeleteMilestone deletes a milestone.
 | 
					// DeleteMilestoneByID deletes a milestone by given ID.
 | 
				
			||||||
func DeleteMilestone(m *Milestone) (err error) {
 | 
					func DeleteMilestoneByID(mid int64) error {
 | 
				
			||||||
 | 
						m, err := GetMilestoneById(mid)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							if IsErrMilestoneNotExist(err) {
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						repo, err := GetRepositoryById(m.RepoID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sess := x.NewSession()
 | 
						sess := x.NewSession()
 | 
				
			||||||
	defer sess.Close()
 | 
						defer sessionRelease(sess)
 | 
				
			||||||
	if err = sess.Begin(); err != nil {
 | 
						if err = sess.Begin(); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if _, err = sess.Delete(m); err != nil {
 | 
						if _, err = sess.Id(m.ID).Delete(m); err != nil {
 | 
				
			||||||
		sess.Rollback()
 | 
					 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rawSql := "UPDATE `repository` SET num_milestones = num_milestones - 1 WHERE id = ?"
 | 
						repo.NumMilestones = int(countRepoMilestones(sess, repo.Id))
 | 
				
			||||||
	if _, err = sess.Exec(rawSql, m.RepoID); err != nil {
 | 
						repo.NumClosedMilestones = int(countRepoClosedMilestones(sess, repo.Id))
 | 
				
			||||||
		sess.Rollback()
 | 
						if _, err = sess.Id(repo.Id).AllCols().Update(repo); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rawSql = "UPDATE `issue` SET milestone_id = 0 WHERE milestone_id = ?"
 | 
						if _, err = sess.Exec("UPDATE `issue` SET milestone_id=0 WHERE milestone_id=?", m.ID); err != nil {
 | 
				
			||||||
	if _, err = sess.Exec(rawSql, m.ID); err != nil {
 | 
					 | 
				
			||||||
		sess.Rollback()
 | 
					 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						} else if _, err = sess.Exec("UPDATE `issue_user` SET milestone_id=0 WHERE milestone_id=?", m.ID); err != nil {
 | 
				
			||||||
 | 
					 | 
				
			||||||
	rawSql = "UPDATE `issue_user` SET milestone_id = 0 WHERE milestone_id = ?"
 | 
					 | 
				
			||||||
	if _, err = sess.Exec(rawSql, m.ID); err != nil {
 | 
					 | 
				
			||||||
		sess.Rollback()
 | 
					 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return sess.Commit()
 | 
						return sess.Commit()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -886,7 +886,7 @@ func DeleteRepository(uid, repoID int64, userName string) error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if _, err = sess.Delete(&Issue{RepoId: repoID}); err != nil {
 | 
						if _, err = sess.Delete(&Issue{RepoID: repoID}); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								public/css/gogs.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								public/css/gogs.min.css
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -51,21 +51,6 @@ function initRepository() {
 | 
				
			|||||||
            $('.color-picker').val(color_hex);
 | 
					            $('.color-picker').val(color_hex);
 | 
				
			||||||
            $('.minicolors-swatch-color').css("background-color", color_hex);
 | 
					            $('.minicolors-swatch-color').css("background-color", color_hex);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        $('.delete-label-button').click(function () {
 | 
					 | 
				
			||||||
            var $this = $(this);
 | 
					 | 
				
			||||||
            $('.delete-label.modal').modal({
 | 
					 | 
				
			||||||
                closable: false,
 | 
					 | 
				
			||||||
                onApprove: function () {
 | 
					 | 
				
			||||||
                    $.post($this.data('url'), {
 | 
					 | 
				
			||||||
                        "_csrf": csrf,
 | 
					 | 
				
			||||||
                        "id": $this.data("id")
 | 
					 | 
				
			||||||
                    }).done(function (data) {
 | 
					 | 
				
			||||||
                        window.location.href = data.redirect;
 | 
					 | 
				
			||||||
                    });
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }).modal('show');
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        $('.edit-label-button').click(function () {
 | 
					        $('.edit-label-button').click(function () {
 | 
				
			||||||
            $('#label-modal-id').val($(this).data('id'));
 | 
					            $('#label-modal-id').val($(this).data('id'));
 | 
				
			||||||
            $('#label-modal-title').val($(this).data('title'));
 | 
					            $('#label-modal-title').val($(this).data('title'));
 | 
				
			||||||
@@ -81,6 +66,9 @@ function initRepository() {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Milestones
 | 
					    // Milestones
 | 
				
			||||||
 | 
					    if ($('.repository.milestones').length > 0) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if ($('.repository.new.milestone').length > 0) {
 | 
					    if ($('.repository.new.milestone').length > 0) {
 | 
				
			||||||
        var $datepicker = $('.milestone.datepicker')
 | 
					        var $datepicker = $('.milestone.datepicker')
 | 
				
			||||||
        $datepicker.datetimepicker({
 | 
					        $datepicker.datetimepicker({
 | 
				
			||||||
@@ -118,6 +106,23 @@ $(document).ready(function () {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
    $('.poping.up').popup();
 | 
					    $('.poping.up').popup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Helpers.
 | 
				
			||||||
 | 
					    $('.delete-button').click(function () {
 | 
				
			||||||
 | 
					        var $this = $(this);
 | 
				
			||||||
 | 
					        $('.delete.modal').modal({
 | 
				
			||||||
 | 
					            closable: false,
 | 
				
			||||||
 | 
					            onApprove: function () {
 | 
				
			||||||
 | 
					                $.post($this.data('url'), {
 | 
				
			||||||
 | 
					                    "_csrf": csrf,
 | 
				
			||||||
 | 
					                    "id": $this.data("id")
 | 
				
			||||||
 | 
					                }).done(function (data) {
 | 
				
			||||||
 | 
					                    window.location.href = data.redirect;
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }).modal('show');
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    initInstall();
 | 
					    initInstall();
 | 
				
			||||||
    initRepository();
 | 
					    initRepository();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
@@ -94,11 +94,12 @@
 | 
				
			|||||||
		.menu {
 | 
							.menu {
 | 
				
			||||||
			max-height: 300px;
 | 
								max-height: 300px;
 | 
				
			||||||
			overflow-x: auto;
 | 
								overflow-x: auto;
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	.type.item .menu {
 | 
					 | 
				
			||||||
		  right: 0!important;
 | 
							  right: 0!important;
 | 
				
			||||||
  		left: auto!important;
 | 
					  		left: auto!important;
 | 
				
			||||||
 | 
					  		.clickable .name {
 | 
				
			||||||
 | 
					  			padding-left: 15px!important;
 | 
				
			||||||
 | 
					  		}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.page.buttons {
 | 
						.page.buttons {
 | 
				
			||||||
@@ -127,6 +128,13 @@
 | 
				
			|||||||
			.desc {
 | 
								.desc {
 | 
				
			||||||
				padding-top: 5px;
 | 
									padding-top: 5px;
 | 
				
			||||||
				color: #999;
 | 
									color: #999;
 | 
				
			||||||
 | 
									a.milestone {
 | 
				
			||||||
 | 
										padding-left: 5px;
 | 
				
			||||||
 | 
										color: #999!important;
 | 
				
			||||||
 | 
										&:hover {
 | 
				
			||||||
 | 
											color: #000!important;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -150,11 +150,20 @@ func Issues(ctx *middleware.Context) {
 | 
				
			|||||||
			issues[i].IsRead = true
 | 
								issues[i].IsRead = true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						ctx.Data["Issues"] = issues
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get milestones.
 | 
				
			||||||
 | 
						miles, err := models.GetAllRepoMilestones(repo.Id)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							ctx.Handle(500, "GetAllRepoMilestones: %v", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ctx.Data["Milestones"] = miles
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.Data["IssueStats"] = issueStats
 | 
						ctx.Data["IssueStats"] = issueStats
 | 
				
			||||||
	ctx.Data["SelectLabels"] = com.StrTo(selectLabels).MustInt64()
 | 
						ctx.Data["SelectLabels"] = com.StrTo(selectLabels).MustInt64()
 | 
				
			||||||
	ctx.Data["ViewType"] = viewType
 | 
						ctx.Data["ViewType"] = viewType
 | 
				
			||||||
	ctx.Data["Issues"] = issues
 | 
						ctx.Data["MilestoneID"] = milestoneID
 | 
				
			||||||
	ctx.Data["IsShowClosed"] = isShowClosed
 | 
						ctx.Data["IsShowClosed"] = isShowClosed
 | 
				
			||||||
	if isShowClosed {
 | 
						if isShowClosed {
 | 
				
			||||||
		ctx.Data["State"] = "closed"
 | 
							ctx.Data["State"] = "closed"
 | 
				
			||||||
@@ -247,12 +256,12 @@ func CreateIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) {
 | 
				
			|||||||
		form.AssigneeId = 0
 | 
							form.AssigneeId = 0
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	issue := &models.Issue{
 | 
						issue := &models.Issue{
 | 
				
			||||||
		RepoId:      ctx.Repo.Repository.Id,
 | 
							RepoID:      ctx.Repo.Repository.Id,
 | 
				
			||||||
		Index:       int64(ctx.Repo.Repository.NumIssues) + 1,
 | 
							Index:       int64(ctx.Repo.Repository.NumIssues) + 1,
 | 
				
			||||||
		Name:        form.IssueName,
 | 
							Name:        form.IssueName,
 | 
				
			||||||
		PosterId:    ctx.User.Id,
 | 
							PosterID:    ctx.User.Id,
 | 
				
			||||||
		MilestoneId: form.MilestoneId,
 | 
							MilestoneID: form.MilestoneId,
 | 
				
			||||||
		AssigneeId:  form.AssigneeId,
 | 
							AssigneeID:  form.AssigneeId,
 | 
				
			||||||
		LabelIds:    form.Labels,
 | 
							LabelIds:    form.Labels,
 | 
				
			||||||
		Content:     form.Content,
 | 
							Content:     form.Content,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -372,8 +381,8 @@ func ViewIssue(ctx *middleware.Context) {
 | 
				
			|||||||
	ctx.Data["Labels"] = labels
 | 
						ctx.Data["Labels"] = labels
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get assigned milestone.
 | 
						// Get assigned milestone.
 | 
				
			||||||
	if issue.MilestoneId > 0 {
 | 
						if issue.MilestoneID > 0 {
 | 
				
			||||||
		ctx.Data["Milestone"], err = models.MilestoneById(issue.MilestoneId)
 | 
							ctx.Data["Milestone"], err = models.GetMilestoneById(issue.MilestoneID)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			if models.IsErrMilestoneNotExist(err) {
 | 
								if models.IsErrMilestoneNotExist(err) {
 | 
				
			||||||
				log.Warn("GetMilestoneById: %v", err)
 | 
									log.Warn("GetMilestoneById: %v", err)
 | 
				
			||||||
@@ -447,7 +456,7 @@ func ViewIssue(ctx *middleware.Context) {
 | 
				
			|||||||
	ctx.Data["Title"] = issue.Name
 | 
						ctx.Data["Title"] = issue.Name
 | 
				
			||||||
	ctx.Data["Issue"] = issue
 | 
						ctx.Data["Issue"] = issue
 | 
				
			||||||
	ctx.Data["Comments"] = comments
 | 
						ctx.Data["Comments"] = comments
 | 
				
			||||||
	ctx.Data["IsIssueOwner"] = ctx.Repo.IsOwner() || (ctx.IsSigned && issue.PosterId == ctx.User.Id)
 | 
						ctx.Data["IsIssueOwner"] = ctx.Repo.IsOwner() || (ctx.IsSigned && issue.PosterID == ctx.User.Id)
 | 
				
			||||||
	ctx.Data["IsRepoToolbarIssues"] = true
 | 
						ctx.Data["IsRepoToolbarIssues"] = true
 | 
				
			||||||
	ctx.Data["IsRepoToolbarIssuesList"] = false
 | 
						ctx.Data["IsRepoToolbarIssuesList"] = false
 | 
				
			||||||
	ctx.HTML(200, ISSUE_VIEW)
 | 
						ctx.HTML(200, ISSUE_VIEW)
 | 
				
			||||||
@@ -470,7 +479,7 @@ func UpdateIssue(ctx *middleware.Context, form auth.CreateIssueForm) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ctx.User.Id != issue.PosterId && !ctx.Repo.IsOwner() {
 | 
						if ctx.User.Id != issue.PosterID && !ctx.Repo.IsOwner() {
 | 
				
			||||||
		ctx.Error(403)
 | 
							ctx.Error(403)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -595,7 +604,7 @@ func UpdateIssueMilestone(ctx *middleware.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	oldMid := issue.MilestoneId
 | 
						oldMid := issue.MilestoneID
 | 
				
			||||||
	mid := com.StrTo(ctx.Query("milestoneid")).MustInt64()
 | 
						mid := com.StrTo(ctx.Query("milestoneid")).MustInt64()
 | 
				
			||||||
	if oldMid == mid {
 | 
						if oldMid == mid {
 | 
				
			||||||
		ctx.JSON(200, map[string]interface{}{
 | 
							ctx.JSON(200, map[string]interface{}{
 | 
				
			||||||
@@ -605,7 +614,7 @@ func UpdateIssueMilestone(ctx *middleware.Context) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Not check for invalid milestone id and give responsibility to owners.
 | 
						// Not check for invalid milestone id and give responsibility to owners.
 | 
				
			||||||
	issue.MilestoneId = mid
 | 
						issue.MilestoneID = mid
 | 
				
			||||||
	if err = models.ChangeMilestoneAssign(oldMid, mid, issue); err != nil {
 | 
						if err = models.ChangeMilestoneAssign(oldMid, mid, issue); err != nil {
 | 
				
			||||||
		ctx.Handle(500, "issue.UpdateIssueMilestone(ChangeMilestoneAssign)", err)
 | 
							ctx.Handle(500, "issue.UpdateIssueMilestone(ChangeMilestoneAssign)", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@@ -643,7 +652,7 @@ func UpdateAssignee(ctx *middleware.Context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	aid := com.StrTo(ctx.Query("assigneeid")).MustInt64()
 | 
						aid := com.StrTo(ctx.Query("assigneeid")).MustInt64()
 | 
				
			||||||
	// Not check for invalid assignee id and give responsibility to owners.
 | 
						// Not check for invalid assignee id and give responsibility to owners.
 | 
				
			||||||
	issue.AssigneeId = aid
 | 
						issue.AssigneeID = aid
 | 
				
			||||||
	if err = models.UpdateIssueUserPairByAssignee(aid, issue.ID); err != nil {
 | 
						if err = models.UpdateIssueUserPairByAssignee(aid, issue.ID); err != nil {
 | 
				
			||||||
		ctx.Handle(500, "UpdateIssueUserPairByAssignee: %v", err)
 | 
							ctx.Handle(500, "UpdateIssueUserPairByAssignee: %v", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@@ -766,7 +775,7 @@ func Comment(ctx *middleware.Context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// Check if issue owner changes the status of issue.
 | 
						// Check if issue owner changes the status of issue.
 | 
				
			||||||
	var newStatus string
 | 
						var newStatus string
 | 
				
			||||||
	if ctx.Repo.IsOwner() || issue.PosterId == ctx.User.Id {
 | 
						if ctx.Repo.IsOwner() || issue.PosterID == ctx.User.Id {
 | 
				
			||||||
		newStatus = ctx.Query("change_status")
 | 
							newStatus = ctx.Query("change_status")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(newStatus) > 0 {
 | 
						if len(newStatus) > 0 {
 | 
				
			||||||
@@ -800,7 +809,7 @@ func Comment(ctx *middleware.Context) {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Change open/closed issue counter for the associated milestone
 | 
								// Change open/closed issue counter for the associated milestone
 | 
				
			||||||
			if issue.MilestoneId > 0 {
 | 
								if issue.MilestoneID > 0 {
 | 
				
			||||||
				if err = models.ChangeMilestoneIssueStats(issue); err != nil {
 | 
									if err = models.ChangeMilestoneIssueStats(issue); err != nil {
 | 
				
			||||||
					send(500, nil, err)
 | 
										send(500, nil, err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -951,13 +960,10 @@ func UpdateLabel(ctx *middleware.Context, form auth.CreateLabelForm) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func DeleteLabel(ctx *middleware.Context) {
 | 
					func DeleteLabel(ctx *middleware.Context) {
 | 
				
			||||||
	id := ctx.QueryInt64("id")
 | 
						if err := models.DeleteLabel(ctx.Repo.Repository.Id, ctx.QueryInt64("id")); err != nil {
 | 
				
			||||||
	if id > 0 {
 | 
							ctx.Flash.Error("DeleteLabel: " + err.Error())
 | 
				
			||||||
		if err := models.DeleteLabel(ctx.Repo.Repository.Id, id); err != nil {
 | 
						} else {
 | 
				
			||||||
			ctx.Flash.Error("DeleteLabel: " + err.Error())
 | 
							ctx.Flash.Success(ctx.Tr("repo.issues.label_deletion_success"))
 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			ctx.Flash.Success(ctx.Tr("repo.issues.label_deletion_success"))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.JSON(200, map[string]interface{}{
 | 
						ctx.JSON(200, map[string]interface{}{
 | 
				
			||||||
@@ -1116,18 +1122,8 @@ func EditMilestonePost(ctx *middleware.Context, form auth.CreateMilestoneForm) {
 | 
				
			|||||||
	ctx.Redirect(ctx.Repo.RepoLink + "/milestones")
 | 
						ctx.Redirect(ctx.Repo.RepoLink + "/milestones")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func MilestoneActions(ctx *middleware.Context) {
 | 
					func ChangeMilestonStatus(ctx *middleware.Context) {
 | 
				
			||||||
	ctx.Data["Title"] = "Update Milestone"
 | 
						m, err := models.GetMilestoneByIndex(ctx.Repo.Repository.Id, ctx.ParamsInt64(":index"))
 | 
				
			||||||
	ctx.Data["IsRepoToolbarIssues"] = true
 | 
					 | 
				
			||||||
	ctx.Data["IsRepoToolbarIssuesList"] = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	idx := ctx.ParamsInt64(":index")
 | 
					 | 
				
			||||||
	if idx == 0 {
 | 
					 | 
				
			||||||
		ctx.Handle(404, "get milestone index", nil)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	mile, err := models.GetMilestoneByIndex(ctx.Repo.Repository.Id, idx)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		if models.IsErrMilestoneNotExist(err) {
 | 
							if models.IsErrMilestoneNotExist(err) {
 | 
				
			||||||
			ctx.Handle(404, "GetMilestoneByIndex", err)
 | 
								ctx.Handle(404, "GetMilestoneByIndex", err)
 | 
				
			||||||
@@ -1137,88 +1133,39 @@ func MilestoneActions(ctx *middleware.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	action := ctx.Params(":action")
 | 
						switch ctx.Params(":action") {
 | 
				
			||||||
	if len(action) > 0 {
 | 
						case "open":
 | 
				
			||||||
		switch action {
 | 
							if m.IsClosed {
 | 
				
			||||||
		case "open":
 | 
								if err = models.ChangeMilestoneStatus(m, false); err != nil {
 | 
				
			||||||
			if mile.IsClosed {
 | 
									ctx.Handle(500, "ChangeMilestoneStatus", err)
 | 
				
			||||||
				if err = models.ChangeMilestoneStatus(mile, false); err != nil {
 | 
					 | 
				
			||||||
					ctx.Handle(500, "ChangeMilestoneStatus", err)
 | 
					 | 
				
			||||||
					return
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		case "close":
 | 
					 | 
				
			||||||
			if !mile.IsClosed {
 | 
					 | 
				
			||||||
				mile.ClosedDate = time.Now()
 | 
					 | 
				
			||||||
				if err = models.ChangeMilestoneStatus(mile, true); err != nil {
 | 
					 | 
				
			||||||
					ctx.Handle(500, "ChangeMilestoneStatus", err)
 | 
					 | 
				
			||||||
					return
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		case "delete":
 | 
					 | 
				
			||||||
			if err = models.DeleteMilestone(mile); err != nil {
 | 
					 | 
				
			||||||
				ctx.Handle(500, "DeleteMilestone", err)
 | 
					 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							ctx.Redirect(ctx.Repo.RepoLink + "/milestones?state=open")
 | 
				
			||||||
 | 
						case "close":
 | 
				
			||||||
 | 
							if !m.IsClosed {
 | 
				
			||||||
 | 
								m.ClosedDate = time.Now()
 | 
				
			||||||
 | 
								if err = models.ChangeMilestoneStatus(m, true); err != nil {
 | 
				
			||||||
 | 
									ctx.Handle(500, "ChangeMilestoneStatus", err)
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ctx.Redirect(ctx.Repo.RepoLink + "/milestones?state=closed")
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
		ctx.Redirect(ctx.Repo.RepoLink + "/milestones")
 | 
							ctx.Redirect(ctx.Repo.RepoLink + "/milestones")
 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	mile.DeadlineString = mile.Deadline.UTC().Format("01/02/2006")
 | 
					 | 
				
			||||||
	if mile.DeadlineString == "12/31/9999" {
 | 
					 | 
				
			||||||
		mile.DeadlineString = ""
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ctx.Data["Milestone"] = mile
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ctx.HTML(200, MILESTONE_EDIT)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func UpdateMilestonePost(ctx *middleware.Context, form auth.CreateMilestoneForm) {
 | 
					func DeleteMilestone(ctx *middleware.Context) {
 | 
				
			||||||
	ctx.Data["Title"] = "Update Milestone"
 | 
						if err := models.DeleteMilestoneByID(ctx.QueryInt64("id")); err != nil {
 | 
				
			||||||
	ctx.Data["IsRepoToolbarIssues"] = true
 | 
							ctx.Flash.Error("DeleteMilestone: " + err.Error())
 | 
				
			||||||
	ctx.Data["IsRepoToolbarIssuesList"] = true
 | 
						} else {
 | 
				
			||||||
 | 
							ctx.Flash.Success(ctx.Tr("repo.milestones.deletion_success"))
 | 
				
			||||||
	idx := ctx.ParamsInt64(":index")
 | 
					 | 
				
			||||||
	if idx == 0 {
 | 
					 | 
				
			||||||
		ctx.Handle(404, "issue.UpdateMilestonePost", nil)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mile, err := models.GetMilestoneByIndex(ctx.Repo.Repository.Id, idx)
 | 
						ctx.JSON(200, map[string]interface{}{
 | 
				
			||||||
	if err != nil {
 | 
							"redirect": ctx.Repo.RepoLink + "/milestones",
 | 
				
			||||||
		if models.IsErrMilestoneNotExist(err) {
 | 
						})
 | 
				
			||||||
			ctx.Handle(404, "GetMilestoneByIndex", err)
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			ctx.Handle(500, "GetMilestoneByIndex", err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ctx.HasError() {
 | 
					 | 
				
			||||||
		ctx.HTML(200, MILESTONE_EDIT)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var deadline time.Time
 | 
					 | 
				
			||||||
	if len(form.Deadline) == 0 {
 | 
					 | 
				
			||||||
		form.Deadline = "12/31/9999"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	deadline, err = time.Parse("01/02/2006", form.Deadline)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		ctx.Handle(500, "time.Parse", err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	mile.Name = form.Title
 | 
					 | 
				
			||||||
	mile.Content = form.Content
 | 
					 | 
				
			||||||
	mile.Deadline = deadline
 | 
					 | 
				
			||||||
	if err = models.UpdateMilestone(mile); err != nil {
 | 
					 | 
				
			||||||
		ctx.Handle(500, "UpdateMilestone", err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ctx.Redirect(ctx.Repo.RepoLink + "/milestones")
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func IssueGetAttachment(ctx *middleware.Context) {
 | 
					func IssueGetAttachment(ctx *middleware.Context) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -350,13 +350,13 @@ func Issues(ctx *middleware.Context) {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		issues[i].Repo, err = models.GetRepositoryById(issues[i].RepoId)
 | 
							issues[i].Repo, err = models.GetRepositoryById(issues[i].RepoID)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			if models.IsErrRepoNotExist(err) {
 | 
								if models.IsErrRepoNotExist(err) {
 | 
				
			||||||
				log.Warn("user.Issues(GetRepositoryById #%d): repository not exist", issues[i].RepoId)
 | 
									log.Warn("GetRepositoryById[%d]: repository not exist", issues[i].RepoID)
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				ctx.Handle(500, fmt.Sprintf("user.Issues(GetRepositoryById #%d)", issues[i].RepoId), err)
 | 
									ctx.Handle(500, fmt.Sprintf("GetRepositoryById[%d]", issues[i].RepoID), err)
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
0.6.3.0805 Beta
 | 
					0.6.4.0805 Beta
 | 
				
			||||||
@@ -69,7 +69,7 @@
 | 
				
			|||||||
                                            {{else}}
 | 
					                                            {{else}}
 | 
				
			||||||
                                            <ul class="list-unstyled">
 | 
					                                            <ul class="list-unstyled">
 | 
				
			||||||
                                                {{range .ClosedMilestones}}
 | 
					                                                {{range .ClosedMilestones}}
 | 
				
			||||||
                                                <li class="milestone-item" data-id="{{.Id}}">
 | 
					                                                <li class="milestone-item" data-id="{{.ID}}">
 | 
				
			||||||
                                                    <p><strong>{{.Name}}</strong></p>
 | 
					                                                    <p><strong>{{.Name}}</strong></p>
 | 
				
			||||||
                                                    <p>Closed {{TimeSince .ClosedDate $.Lang}}</p>
 | 
					                                                    <p>Closed {{TimeSince .ClosedDate $.Lang}}</p>
 | 
				
			||||||
                                                </li>
 | 
					                                                </li>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,7 +38,7 @@
 | 
				
			|||||||
				<li class="item">
 | 
									<li class="item">
 | 
				
			||||||
					<div class="ui label" style="background-color: {{.Color}}"><i class="octicon octicon-tag"></i> {{.Name}}</div>
 | 
										<div class="ui label" style="background-color: {{.Color}}"><i class="octicon octicon-tag"></i> {{.Name}}</div>
 | 
				
			||||||
					{{if $.IsRepositoryAdmin}}
 | 
										{{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 delete-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>
 | 
										<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}}
 | 
										{{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>
 | 
										<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>
 | 
				
			||||||
@@ -50,7 +50,7 @@
 | 
				
			|||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{if .IsRepositoryAdmin}}
 | 
					{{if .IsRepositoryAdmin}}
 | 
				
			||||||
<div class="ui basic delete-label modal">
 | 
					<div class="ui basic delete modal">
 | 
				
			||||||
  <div class="header">
 | 
					  <div class="header">
 | 
				
			||||||
    {{.i18n.Tr "repo.issues.label_deletion"}}
 | 
					    {{.i18n.Tr "repo.issues.label_deletion"}}
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,11 +11,11 @@
 | 
				
			|||||||
		<div class="ui divider"></div>
 | 
							<div class="ui divider"></div>
 | 
				
			||||||
		<div class="ui left">
 | 
							<div class="ui left">
 | 
				
			||||||
			<div class="ui tiny buttons">
 | 
								<div class="ui tiny buttons">
 | 
				
			||||||
			  <a class="ui green basic button {{if not .IsShowClosed}}active{{end}}" href="{{.RepoLink}}/issues?type={{$.ViewType}}&state=open&labels={{.SelectLabels}}">
 | 
								  <a class="ui green basic button {{if not .IsShowClosed}}active{{end}}" href="{{.RepoLink}}/issues?type={{$.ViewType}}&state=open&labels={{.SelectLabels}}&milestone={{.MilestoneID}}">
 | 
				
			||||||
			  	<i class="octicon octicon-issue-opened"></i>
 | 
								  	<i class="octicon octicon-issue-opened"></i>
 | 
				
			||||||
			  	{{.i18n.Tr "repo.issues.open_tab" .IssueStats.OpenCount}}
 | 
								  	{{.i18n.Tr "repo.issues.open_tab" .IssueStats.OpenCount}}
 | 
				
			||||||
			  </a>
 | 
								  </a>
 | 
				
			||||||
			  <a class="ui red basic button {{if .IsShowClosed}}active{{end}}" href="{{.RepoLink}}/issues?type={{.ViewType}}&state=closed&labels={{.SelectLabels}}">
 | 
								  <a class="ui red basic button {{if .IsShowClosed}}active{{end}}" href="{{.RepoLink}}/issues?type={{.ViewType}}&state=closed&labels={{.SelectLabels}}&milestone={{.MilestoneID}}">
 | 
				
			||||||
			  	<i class="octicon octicon-issue-closed"></i>
 | 
								  	<i class="octicon octicon-issue-closed"></i>
 | 
				
			||||||
			  	{{.i18n.Tr "repo.issues.close_tab" .IssueStats.ClosedCount}}
 | 
								  	{{.i18n.Tr "repo.issues.close_tab" .IssueStats.ClosedCount}}
 | 
				
			||||||
			  </a>
 | 
								  </a>
 | 
				
			||||||
@@ -28,23 +28,24 @@
 | 
				
			|||||||
					<i class="dropdown icon"></i>
 | 
										<i class="dropdown icon"></i>
 | 
				
			||||||
				</span>
 | 
									</span>
 | 
				
			||||||
        <div class="menu">
 | 
					        <div class="menu">
 | 
				
			||||||
        	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}">{{.i18n.Tr "repo.issues.filter_label_no_select"}}</a>
 | 
					        	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&milestone={{$.MilestoneID}}">{{.i18n.Tr "repo.issues.filter_label_no_select"}}</a>
 | 
				
			||||||
        	{{range .Labels}}
 | 
					        	{{range .Labels}}
 | 
				
			||||||
        	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}"><span class="octicon {{if eq $.SelectLabels .ID}}octicon-check{{end}}"></span><span class="label color" style="background-color: {{.Color}}"></span> {{.Name}}</a>
 | 
					        	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}"><span class="octicon {{if eq $.SelectLabels .ID}}octicon-check{{end}}"></span><span class="label color" style="background-color: {{.Color}}"></span> {{.Name}}</a>
 | 
				
			||||||
          {{end}}
 | 
					          {{end}}
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
			<!-- <div class="ui {{if not .Milestones}}disabled{{end}} pointing dropdown jump item">
 | 
								<div class="ui {{if not .Milestones}}disabled{{end}} pointing dropdown jump item">
 | 
				
			||||||
				<span class="text">
 | 
									<span class="text">
 | 
				
			||||||
					{{.i18n.Tr "repo.issues.filter_milestone"}}
 | 
										{{.i18n.Tr "repo.issues.filter_milestone"}}
 | 
				
			||||||
					<i class="dropdown icon"></i>
 | 
										<i class="dropdown icon"></i>
 | 
				
			||||||
				</span>
 | 
									</span>
 | 
				
			||||||
        <div class="menu">
 | 
					        <div class="menu">
 | 
				
			||||||
 | 
					        	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{.SelectLabels}}">{{.i18n.Tr "repo.issues.filter_milestone_no_select"}}</a>
 | 
				
			||||||
        	{{range .Milestones}}
 | 
					        	{{range .Milestones}}
 | 
				
			||||||
        	<a class="item" href="{{$.RepoLink}}/issues">{{.Name}}</a>
 | 
					        	<a class="clickable item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{.ID}}"><span class="octicon {{if eq $.MilestoneID .ID}}octicon-check{{end}}"></span> <span class="name">{{.Name}}</span></a>
 | 
				
			||||||
          {{end}}
 | 
					          {{end}}
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div> -->
 | 
								</div>
 | 
				
			||||||
			<!-- <div class="ui {{if not .Assignees}}disabled{{end}} pointing dropdown jump item">
 | 
								<!-- <div class="ui {{if not .Assignees}}disabled{{end}} pointing dropdown jump item">
 | 
				
			||||||
				<span class="text">
 | 
									<span class="text">
 | 
				
			||||||
					{{.i18n.Tr "repo.issues.filter_assignee"}}
 | 
										{{.i18n.Tr "repo.issues.filter_assignee"}}
 | 
				
			||||||
@@ -62,10 +63,10 @@
 | 
				
			|||||||
					<i class="dropdown icon"></i>
 | 
										<i class="dropdown icon"></i>
 | 
				
			||||||
				</span>
 | 
									</span>
 | 
				
			||||||
        <div class="menu">
 | 
					        <div class="menu">
 | 
				
			||||||
        	<a class="{{if eq .ViewType "all"}}active{{end}} item" href="{{$.RepoLink}}/issues?type=all&state={{$.State}}&labels={{.SelectLabels}}">{{.i18n.Tr "repo.issues.filter_type.all_issues"}}</a>
 | 
					        	<a class="{{if eq .ViewType "all"}}active{{end}} item" href="{{$.RepoLink}}/issues?type=all&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}">{{.i18n.Tr "repo.issues.filter_type.all_issues"}}</a>
 | 
				
			||||||
        	<a class="{{if eq .ViewType "assigned"}}active{{end}} item" href="{{$.RepoLink}}/issues?type=assigned&state={{$.State}}&labels={{.SelectLabels}}">{{.i18n.Tr "repo.issues.filter_type.assigned_to_you"}}</a>
 | 
					        	<a class="{{if eq .ViewType "assigned"}}active{{end}} item" href="{{$.RepoLink}}/issues?type=assigned&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}">{{.i18n.Tr "repo.issues.filter_type.assigned_to_you"}}</a>
 | 
				
			||||||
        	<a class="{{if eq .ViewType "created_by"}}active{{end}} item" href="{{$.RepoLink}}/issues?type=created_by&state={{$.State}}&labels={{.SelectLabels}}">{{.i18n.Tr "repo.issues.filter_type.created_by_you"}}</a>
 | 
					        	<a class="{{if eq .ViewType "created_by"}}active{{end}} item" href="{{$.RepoLink}}/issues?type=created_by&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}">{{.i18n.Tr "repo.issues.filter_type.created_by_you"}}</a>
 | 
				
			||||||
        	<a class="{{if eq .ViewType "mentioned"}}active{{end}} item" href="{{$.RepoLink}}/issues?type=mentioned&state={{$.State}}&labels={{.SelectLabels}}">{{.i18n.Tr "repo.issues.filter_type.mentioning_you"}}</a>
 | 
					        	<a class="{{if eq .ViewType "mentioned"}}active{{end}} item" href="{{$.RepoLink}}/issues?type=mentioned&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}">{{.i18n.Tr "repo.issues.filter_type.mentioning_you"}}</a>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
@@ -79,11 +80,23 @@
 | 
				
			|||||||
	      	<a class="title" href="{{$.RepoLink}}/issues/{{.Index}}">{{.Name}}</a>
 | 
						      	<a class="title" href="{{$.RepoLink}}/issues/{{.Index}}">{{.Name}}</a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	      	{{range .Labels}}
 | 
						      	{{range .Labels}}
 | 
				
			||||||
					<a class="ui label" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}" style="background-color: {{.Color}}">{{.Name}}</a>
 | 
										<a class="ui label" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}" style="background-color: {{.Color}}">{{.Name}}</a>
 | 
				
			||||||
	      	{{end}}
 | 
						      	{{end}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	      	{{if .NumComments}}<span class="comment ui right"><i class="octicon octicon-comment"></i> {{.NumComments}}</span>{{end}}
 | 
						      	{{if .NumComments}}
 | 
				
			||||||
	        <p class="desc">{{$.i18n.Tr "repo.issues.opened_by" $timeStr .Poster.Name|Str2html}}</p>
 | 
						      	<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}}
 | 
				
			||||||
 | 
							        {{if .Milestone}}
 | 
				
			||||||
 | 
											{{with .Milestone}}
 | 
				
			||||||
 | 
											<a class="milestone" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{.ID}}">
 | 
				
			||||||
 | 
												<span class="octicon octicon-milestone"></span> {{.Name}}
 | 
				
			||||||
 | 
											</a>
 | 
				
			||||||
 | 
											{{end}}
 | 
				
			||||||
 | 
							        {{end}}
 | 
				
			||||||
 | 
						        </p>
 | 
				
			||||||
	      </li>
 | 
						      </li>
 | 
				
			||||||
	      {{end}}
 | 
						      {{end}}
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
@@ -91,17 +104,17 @@
 | 
				
			|||||||
				{{if gt .TotalPages 1}}
 | 
									{{if gt .TotalPages 1}}
 | 
				
			||||||
				<div class="center page buttons">
 | 
									<div class="center page buttons">
 | 
				
			||||||
					<div class="ui borderless pagination menu">
 | 
										<div class="ui borderless pagination menu">
 | 
				
			||||||
					  <a class="{{if not .HasPrevious}}disabled{{end}} item" {{if .HasPrevious}}href="{{$.Link}}?type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&page={{.Previous}}"{{end}}>
 | 
										  <a class="{{if not .HasPrevious}}disabled{{end}} item" {{if .HasPrevious}}href="{{$.Link}}?type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&page={{.Previous}}"{{end}}>
 | 
				
			||||||
					    <i class="left arrow icon"></i> {{$.i18n.Tr "repo.issues.previous"}}
 | 
										    <i class="left arrow icon"></i> {{$.i18n.Tr "repo.issues.previous"}}
 | 
				
			||||||
					  </a>
 | 
										  </a>
 | 
				
			||||||
						{{range .Pages}}
 | 
											{{range .Pages}}
 | 
				
			||||||
						{{if eq .Num -1}}
 | 
											{{if eq .Num -1}}
 | 
				
			||||||
						<a class="disabled item">...</a>
 | 
											<a class="disabled item">...</a>
 | 
				
			||||||
						{{else}}
 | 
											{{else}}
 | 
				
			||||||
						<a class="{{if .IsCurrent}}active{{end}} item" {{if not .IsCurrent}}href="{{$.Link}}?type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&page={{.Num}}"{{end}}>{{.Num}}</a>
 | 
											<a class="{{if .IsCurrent}}active{{end}} item" {{if not .IsCurrent}}href="{{$.Link}}?type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&page={{.Num}}"{{end}}>{{.Num}}</a>
 | 
				
			||||||
						{{end}}
 | 
											{{end}}
 | 
				
			||||||
						{{end}}
 | 
											{{end}}
 | 
				
			||||||
					  <a class="{{if not .HasNext}}disabled{{end}} item" {{if .HasNext}}href="{{$.Link}}?type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&page={{.Next}}"{{end}}>
 | 
										  <a class="{{if not .HasNext}}disabled{{end}} item" {{if .HasNext}}href="{{$.Link}}?type={{$.ViewType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&page={{.Next}}"{{end}}>
 | 
				
			||||||
					    {{$.i18n.Tr "repo.issues.next"}} <i class="icon right arrow"></i>
 | 
										    {{$.i18n.Tr "repo.issues.next"}} <i class="icon right arrow"></i>
 | 
				
			||||||
					  </a>
 | 
										  </a>
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,12 @@
 | 
				
			|||||||
{{template "base/head" .}}
 | 
					{{template "base/head" .}}
 | 
				
			||||||
<div class="repository">
 | 
					<div class="repository milestones">
 | 
				
			||||||
	{{template "repo/header" .}}
 | 
						{{template "repo/header" .}}
 | 
				
			||||||
	<div class="ui middle page grid body">
 | 
						<div class="ui middle page grid body">
 | 
				
			||||||
		<div class="navbar">
 | 
							<div class="navbar">
 | 
				
			||||||
			{{template "repo/issue/navbar" .}}
 | 
								{{template "repo/issue/navbar" .}}
 | 
				
			||||||
			{{if .IsRepositoryAdmin}}
 | 
								{{if .IsRepositoryAdmin}}
 | 
				
			||||||
			<div class="ui right floated secondary menu">
 | 
								<div class="ui right floated secondary menu">
 | 
				
			||||||
				<a class="ui green button" href="{{$.RepoLink}}/milestones/new">{{.i18n.Tr "repo.milestones.new"}}</a>
 | 
									<a class="ui green button" href="{{$.Link}}/new">{{.i18n.Tr "repo.milestones.new"}}</a>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
			{{end}}
 | 
								{{end}}
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
@@ -29,7 +29,7 @@
 | 
				
			|||||||
			<div class="milestone list">
 | 
								<div class="milestone list">
 | 
				
			||||||
				{{range .Milestones}}
 | 
									{{range .Milestones}}
 | 
				
			||||||
				<li class="item">
 | 
									<li class="item">
 | 
				
			||||||
					<i class="octicon octicon-milestone"></i> <a href="{{$.RepoLink}}/issues?state={{$.State}}&midx={{.Index}}">{{.Name}}</a>
 | 
										<i class="octicon octicon-milestone"></i> <a href="{{$.RepoLink}}/issues?state={{$.State}}&milestone={{.ID}}">{{.Name}}</a>
 | 
				
			||||||
					<div class="ui right blue progress" data-percent="{{.Completeness}}">
 | 
										<div class="ui right blue progress" data-percent="{{.Completeness}}">
 | 
				
			||||||
				    <div class="bar" {{if not .Completeness}}style="background-color: transparent"{{end}}>
 | 
									    <div class="bar" {{if not .Completeness}}style="background-color: transparent"{{end}}>
 | 
				
			||||||
				      <div class="progress"></div>
 | 
									      <div class="progress"></div>
 | 
				
			||||||
@@ -54,13 +54,13 @@
 | 
				
			|||||||
					</div>
 | 
										</div>
 | 
				
			||||||
					{{if $.IsRepositoryAdmin}}
 | 
										{{if $.IsRepositoryAdmin}}
 | 
				
			||||||
					<div class="ui right operate">
 | 
										<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>
 | 
											<a href="{{$.Link}}/{{.Index}}/edit" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-pencil"></i> {{$.i18n.Tr "repo.issues.label_edit"}}</a>
 | 
				
			||||||
						{{if .IsClosed}}
 | 
											{{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>
 | 
											<a href="{{$.Link}}/{{.Index}}/open" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-check"></i> {{$.i18n.Tr "repo.milestones.open"}}</a>
 | 
				
			||||||
						{{else}}
 | 
											{{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>
 | 
											<a href="{{$.Link}}/{{.Index}}/close" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-x"></i> {{$.i18n.Tr "repo.milestones.close"}}</a>
 | 
				
			||||||
						{{end}}
 | 
											{{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>
 | 
											<a class="delete-button" href="#" data-url="{{$.RepoLink}}/milestones/delete" data-id="{{.ID}}"><i class="octicon octicon-trashcan"></i> {{$.i18n.Tr "repo.issues.label_delete"}}</a>
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
					{{if .Content}}
 | 
										{{if .Content}}
 | 
				
			||||||
					<div class="content">
 | 
										<div class="content">
 | 
				
			||||||
@@ -96,4 +96,32 @@
 | 
				
			|||||||
		</div>
 | 
							</div>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{{if .IsRepositoryAdmin}}
 | 
				
			||||||
 | 
					<div class="ui basic delete modal">
 | 
				
			||||||
 | 
					  <div class="header">
 | 
				
			||||||
 | 
					    {{.i18n.Tr "repo.milestones.deletion"}}
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					  <div class="content">
 | 
				
			||||||
 | 
					    <div class="image">
 | 
				
			||||||
 | 
					      <i class="trash icon"></i>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="description">
 | 
				
			||||||
 | 
					      <p>{{.i18n.Tr "repo.milestones.deletion_desc"}}</p>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					  <div class="actions">
 | 
				
			||||||
 | 
					    <div class="two fluid ui inverted buttons">
 | 
				
			||||||
 | 
					      <div class="ui red basic inverted button">
 | 
				
			||||||
 | 
					        <i class="remove icon"></i>
 | 
				
			||||||
 | 
					        {{.i18n.Tr "modal.no"}}
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="ui green basic inverted positive button">
 | 
				
			||||||
 | 
					        <i class="checkmark icon"></i>
 | 
				
			||||||
 | 
					        {{.i18n.Tr "modal.yes"}}
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					{{end}}
 | 
				
			||||||
{{template "base/footer" .}}
 | 
					{{template "base/footer" .}}
 | 
				
			||||||
@@ -234,7 +234,7 @@
 | 
				
			|||||||
                                            {{else}}
 | 
					                                            {{else}}
 | 
				
			||||||
                                            <ul class="list-unstyled">
 | 
					                                            <ul class="list-unstyled">
 | 
				
			||||||
                                                {{range .ClosedMilestones}}
 | 
					                                                {{range .ClosedMilestones}}
 | 
				
			||||||
                                                <li class="milestone-item" data-id="{{.Id}}">
 | 
					                                                <li class="milestone-item" data-id="{{.ID}}">
 | 
				
			||||||
                                                    <p><strong>{{.Name}}</strong></p>
 | 
					                                                    <p><strong>{{.Name}}</strong></p>
 | 
				
			||||||
                                                    <p>Closed {{TimeSince .ClosedDate $.Lang}}</p>
 | 
					                                                    <p>Closed {{TimeSince .ClosedDate $.Lang}}</p>
 | 
				
			||||||
                                                </li>
 | 
					                                                </li>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user