mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Finish add new milestone
This commit is contained in:
		| @@ -186,7 +186,8 @@ func runWeb(*cli.Context) { | |||||||
| 		r.Post("/issues/:index", bindIgnErr(auth.CreateIssueForm{}), repo.UpdateIssue) | 		r.Post("/issues/:index", bindIgnErr(auth.CreateIssueForm{}), repo.UpdateIssue) | ||||||
| 		r.Post("/issues/:index/assignee", repo.UpdateAssignee) | 		r.Post("/issues/:index/assignee", repo.UpdateAssignee) | ||||||
| 		r.Get("/issues/milestones", repo.Milestones) | 		r.Get("/issues/milestones", repo.Milestones) | ||||||
| 		r.Get("/issues/milestones/new", repo.NewMilestones) | 		r.Get("/issues/milestones/new", repo.NewMilestone) | ||||||
|  | 		r.Post("/issues/milestones/new", bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost) | ||||||
| 		r.Get("/issues/milestones/edit", repo.UpdateMilestones) | 		r.Get("/issues/milestones/edit", repo.UpdateMilestones) | ||||||
| 		r.Post("/comment/:action", repo.Comment) | 		r.Post("/comment/:action", repo.Comment) | ||||||
| 		r.Get("/releases/new", repo.ReleasesNew) | 		r.Get("/releases/new", repo.ReleasesNew) | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							| @@ -17,7 +17,7 @@ import ( | |||||||
| 	"github.com/gogits/gogs/modules/base" | 	"github.com/gogits/gogs/modules/base" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const APP_VER = "0.3.3.0511 Alpha" | const APP_VER = "0.3.3.0512 Alpha" | ||||||
|  |  | ||||||
| func init() { | func init() { | ||||||
| 	base.AppVer = APP_VER | 	base.AppVer = APP_VER | ||||||
|   | |||||||
| @@ -20,9 +20,9 @@ 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 | 	Id              int64 | ||||||
|  | 	RepoId          int64 `xorm:"INDEX"` | ||||||
| 	Index           int64 // Index in one repository. | 	Index           int64 // Index in one repository. | ||||||
| 	Name            string | 	Name            string | ||||||
| 	RepoId          int64       `xorm:"INDEX"` |  | ||||||
| 	Repo            *Repository `xorm:"-"` | 	Repo            *Repository `xorm:"-"` | ||||||
| 	PosterId        int64 | 	PosterId        int64 | ||||||
| 	Poster          *User `xorm:"-"` | 	Poster          *User `xorm:"-"` | ||||||
| @@ -390,7 +390,7 @@ func UpdateIssueUserPairsByMentions(uids []int64, iid int64) error { | |||||||
| // Label represents a label of repository for issues. | // Label represents a label of repository for issues. | ||||||
| type Label struct { | type Label struct { | ||||||
| 	Id              int64 | 	Id              int64 | ||||||
| 	Rid             int64 `xorm:"INDEX"` | 	RepoId          int64 `xorm:"INDEX"` | ||||||
| 	Name            string | 	Name            string | ||||||
| 	Color           string | 	Color           string | ||||||
| 	NumIssues       int | 	NumIssues       int | ||||||
| @@ -401,17 +401,53 @@ type Label struct { | |||||||
| // Milestone represents a milestone of repository. | // Milestone represents a milestone of repository. | ||||||
| type Milestone struct { | type Milestone struct { | ||||||
| 	Id              int64 | 	Id              int64 | ||||||
| 	Rid             int64 `xorm:"INDEX"` | 	RepoId          int64 `xorm:"INDEX"` | ||||||
|  | 	Index           int64 | ||||||
| 	Name            string | 	Name            string | ||||||
| 	Content         string | 	Content         string | ||||||
|  | 	RenderedContent string `xorm:"-"` | ||||||
| 	IsClosed        bool | 	IsClosed        bool | ||||||
| 	NumIssues       int | 	NumIssues       int | ||||||
| 	NumClosedIssues int | 	NumClosedIssues int | ||||||
|  | 	NumOpenIssues   int `xorm:"-"` | ||||||
| 	Completeness    int // Percentage(1-100). | 	Completeness    int // Percentage(1-100). | ||||||
| 	Deadline        time.Time | 	Deadline        time.Time | ||||||
| 	ClosedDate      time.Time | 	ClosedDate      time.Time | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // CalOpenIssues calculates the open issues of milestone. | ||||||
|  | func (m *Milestone) CalOpenIssues() { | ||||||
|  | 	m.NumOpenIssues = m.NumIssues - m.NumClosedIssues | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewMilestone creates new milestone of repository. | ||||||
|  | func NewMilestone(m *Milestone) (err error) { | ||||||
|  | 	sess := orm.NewSession() | ||||||
|  | 	defer sess.Close() | ||||||
|  | 	if err = sess.Begin(); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if _, err = sess.Insert(m); err != nil { | ||||||
|  | 		sess.Rollback() | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rawSql := "UPDATE `repository` SET num_milestones = num_milestones + 1 WHERE id = ?" | ||||||
|  | 	if _, err = sess.Exec(rawSql, m.RepoId); err != nil { | ||||||
|  | 		sess.Rollback() | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return sess.Commit() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetMilestones returns a list of milestones of given repository and status. | ||||||
|  | func GetMilestones(repoId int64, isClosed bool) ([]*Milestone, error) { | ||||||
|  | 	miles := make([]*Milestone, 0, 10) | ||||||
|  | 	err := orm.Where("repo_id=?", repoId).And("is_closed=?", isClosed).Find(&miles) | ||||||
|  | 	return miles, err | ||||||
|  | } | ||||||
|  |  | ||||||
| // Issue types. | // Issue types. | ||||||
| const ( | const ( | ||||||
| 	IT_PLAIN  = iota // Pure comment. | 	IT_PLAIN  = iota // Pure comment. | ||||||
|   | |||||||
| @@ -34,7 +34,8 @@ var ( | |||||||
| func init() { | func init() { | ||||||
| 	tables = append(tables, new(User), new(PublicKey), new(Repository), new(Watch), | 	tables = append(tables, new(User), new(PublicKey), new(Repository), new(Watch), | ||||||
| 		new(Action), new(Access), new(Issue), new(Comment), new(Oauth2), new(Follow), | 		new(Action), new(Access), new(Issue), new(Comment), new(Oauth2), new(Follow), | ||||||
| 		new(Mirror), new(Release), new(LoginSource), new(Webhook), new(IssueUser)) | 		new(Mirror), new(Release), new(LoginSource), new(Webhook), new(IssueUser), | ||||||
|  | 		new(Milestone)) | ||||||
| } | } | ||||||
|  |  | ||||||
| func LoadModelsConfig() { | func LoadModelsConfig() { | ||||||
| @@ -141,7 +142,7 @@ type Statistic struct { | |||||||
| 	Counter struct { | 	Counter struct { | ||||||
| 		User, PublicKey, Repo, Watch, Action, Access, | 		User, PublicKey, Repo, Watch, Action, Access, | ||||||
| 		Issue, Comment, Mirror, Oauth, Release, | 		Issue, Comment, Mirror, Oauth, Release, | ||||||
| 		LoginSource, Webhook int64 | 		LoginSource, Webhook, Milestone int64 | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -159,6 +160,7 @@ func GetStatistic() (stats Statistic) { | |||||||
| 	stats.Counter.Release, _ = orm.Count(new(Release)) | 	stats.Counter.Release, _ = orm.Count(new(Release)) | ||||||
| 	stats.Counter.LoginSource, _ = orm.Count(new(LoginSource)) | 	stats.Counter.LoginSource, _ = orm.Count(new(LoginSource)) | ||||||
| 	stats.Counter.Webhook, _ = orm.Count(new(Webhook)) | 	stats.Counter.Webhook, _ = orm.Count(new(Webhook)) | ||||||
|  | 	stats.Counter.Milestone, _ = orm.Count(new(Milestone)) | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -92,28 +92,31 @@ func NewRepoContext() { | |||||||
|  |  | ||||||
| // Repository represents a git repository. | // Repository represents a git repository. | ||||||
| type Repository struct { | type Repository struct { | ||||||
| 	Id              int64 | 	Id                  int64 | ||||||
| 	OwnerId         int64 `xorm:"unique(s)"` | 	OwnerId             int64 `xorm:"unique(s)"` | ||||||
| 	Owner           *User `xorm:"-"` | 	Owner               *User `xorm:"-"` | ||||||
| 	ForkId          int64 | 	ForkId              int64 | ||||||
| 	LowerName       string `xorm:"unique(s) index not null"` | 	LowerName           string `xorm:"unique(s) index not null"` | ||||||
| 	Name            string `xorm:"index not null"` | 	Name                string `xorm:"index not null"` | ||||||
| 	Description     string | 	Description         string | ||||||
| 	Website         string | 	Website             string | ||||||
| 	NumWatches      int | 	NumWatches          int | ||||||
| 	NumStars        int | 	NumStars            int | ||||||
| 	NumForks        int | 	NumForks            int | ||||||
| 	NumIssues       int | 	NumIssues           int | ||||||
| 	NumClosedIssues int | 	NumClosedIssues     int | ||||||
| 	NumOpenIssues   int `xorm:"-"` | 	NumOpenIssues       int `xorm:"-"` | ||||||
| 	NumTags         int `xorm:"-"` | 	NumMilestones       int `xorm:"NOT NULL DEFAULT 0"` | ||||||
| 	IsPrivate       bool | 	NumClosedMilestones int `xorm:"NOT NULL DEFAULT 0"` | ||||||
| 	IsMirror        bool | 	NumOpenMilestones   int `xorm:"-"` | ||||||
| 	IsBare          bool | 	NumTags             int `xorm:"-"` | ||||||
| 	IsGoget         bool | 	IsPrivate           bool | ||||||
| 	DefaultBranch   string | 	IsMirror            bool | ||||||
| 	Created         time.Time `xorm:"created"` | 	IsBare              bool | ||||||
| 	Updated         time.Time `xorm:"updated"` | 	IsGoget             bool | ||||||
|  | 	DefaultBranch       string | ||||||
|  | 	Created             time.Time `xorm:"created"` | ||||||
|  | 	Updated             time.Time `xorm:"updated"` | ||||||
| } | } | ||||||
|  |  | ||||||
| func (repo *Repository) GetOwner() (err error) { | func (repo *Repository) GetOwner() (err error) { | ||||||
|   | |||||||
| @@ -1,35 +0,0 @@ | |||||||
| // Copyright 2014 The Gogs Authors. All rights reserved. |  | ||||||
| // Use of this source code is governed by a MIT-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| package auth |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"net/http" |  | ||||||
| 	"reflect" |  | ||||||
|  |  | ||||||
| 	"github.com/go-martini/martini" |  | ||||||
|  |  | ||||||
| 	"github.com/gogits/gogs/modules/base" |  | ||||||
| 	"github.com/gogits/gogs/modules/middleware/binding" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type CreateIssueForm struct { |  | ||||||
| 	IssueName   string `form:"title" binding:"Required;MaxSize(50)"` |  | ||||||
| 	MilestoneId int64  `form:"milestoneid"` |  | ||||||
| 	AssigneeId  int64  `form:"assigneeid"` |  | ||||||
| 	Labels      string `form:"labels"` |  | ||||||
| 	Content     string `form:"content"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (f *CreateIssueForm) Name(field string) string { |  | ||||||
| 	names := map[string]string{ |  | ||||||
| 		"IssueName": "Issue name", |  | ||||||
| 	} |  | ||||||
| 	return names[field] |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (f *CreateIssueForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) { |  | ||||||
| 	data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) |  | ||||||
| 	validate(errors, data, f) |  | ||||||
| } |  | ||||||
| @@ -1,36 +0,0 @@ | |||||||
| // Copyright 2014 The Gogs Authors. All rights reserved. |  | ||||||
| // Use of this source code is governed by a MIT-style |  | ||||||
| // license that can be found in the LICENSE file. |  | ||||||
|  |  | ||||||
| package auth |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"net/http" |  | ||||||
| 	"reflect" |  | ||||||
|  |  | ||||||
| 	"github.com/go-martini/martini" |  | ||||||
|  |  | ||||||
| 	"github.com/gogits/gogs/modules/base" |  | ||||||
| 	"github.com/gogits/gogs/modules/middleware/binding" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type NewReleaseForm struct { |  | ||||||
| 	TagName    string `form:"tag_name" binding:"Required"` |  | ||||||
| 	Title      string `form:"title" binding:"Required"` |  | ||||||
| 	Content    string `form:"content" binding:"Required"` |  | ||||||
| 	Prerelease bool   `form:"prerelease"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (f *NewReleaseForm) Name(field string) string { |  | ||||||
| 	names := map[string]string{ |  | ||||||
| 		"TagName": "Tag name", |  | ||||||
| 		"Title":   "Release title", |  | ||||||
| 		"Content": "Release content", |  | ||||||
| 	} |  | ||||||
| 	return names[field] |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (f *NewReleaseForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) { |  | ||||||
| 	data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) |  | ||||||
| 	validate(errors, data, f) |  | ||||||
| } |  | ||||||
| @@ -14,6 +14,13 @@ import ( | |||||||
| 	"github.com/gogits/gogs/modules/middleware/binding" | 	"github.com/gogits/gogs/modules/middleware/binding" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | // __________                           .__  __ | ||||||
|  | // \______   \ ____ ______   ____  _____|__|/  |_  ___________ ___.__. | ||||||
|  | //  |       _// __ \\____ \ /  _ \/  ___/  \   __\/  _ \_  __ <   |  | | ||||||
|  | //  |    |   \  ___/|  |_> >  <_> )___ \|  ||  | (  <_> )  | \/\___  | | ||||||
|  | //  |____|_  /\___  >   __/ \____/____  >__||__|  \____/|__|   / ____| | ||||||
|  | //         \/     \/|__|              \/                       \/ | ||||||
|  |  | ||||||
| type CreateRepoForm struct { | type CreateRepoForm struct { | ||||||
| 	RepoName    string `form:"repo" binding:"Required;AlphaDash;MaxSize(100)"` | 	RepoName    string `form:"repo" binding:"Required;AlphaDash;MaxSize(100)"` | ||||||
| 	Private     bool   `form:"private"` | 	Private     bool   `form:"private"` | ||||||
| @@ -63,7 +70,7 @@ func (f *MigrateRepoForm) Validate(errors *binding.Errors, req *http.Request, co | |||||||
| type RepoSettingForm struct { | type RepoSettingForm struct { | ||||||
| 	RepoName    string `form:"name" binding:"Required;AlphaDash;MaxSize(100)"` | 	RepoName    string `form:"name" binding:"Required;AlphaDash;MaxSize(100)"` | ||||||
| 	Description string `form:"desc" binding:"MaxSize(100)"` | 	Description string `form:"desc" binding:"MaxSize(100)"` | ||||||
| 	Website     string `form:"url" binding:"Url;MaxSize(100)"` | 	Website     string `form:"site" binding:"Url;MaxSize(100)"` | ||||||
| 	Branch      string `form:"branch"` | 	Branch      string `form:"branch"` | ||||||
| 	Interval    int    `form:"interval"` | 	Interval    int    `form:"interval"` | ||||||
| 	Private     bool   `form:"private"` | 	Private     bool   `form:"private"` | ||||||
| @@ -84,6 +91,13 @@ func (f *RepoSettingForm) Validate(errors *binding.Errors, req *http.Request, co | |||||||
| 	validate(errors, data, f) | 	validate(errors, data, f) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //  __      __      ___.   .__    .__            __ | ||||||
|  | // /  \    /  \ ____\_ |__ |  |__ |  |__   ____ |  | __ | ||||||
|  | // \   \/\/   // __ \| __ \|  |  \|  |  \ /  _ \|  |/ / | ||||||
|  | //  \        /\  ___/| \_\ \   Y  \   Y  (  <_> )    < | ||||||
|  | //   \__/\  /  \___  >___  /___|  /___|  /\____/|__|_ \ | ||||||
|  | //        \/       \/    \/     \/     \/            \/ | ||||||
|  |  | ||||||
| type NewWebhookForm struct { | type NewWebhookForm struct { | ||||||
| 	Url         string `form:"url" binding:"Required;Url"` | 	Url         string `form:"url" binding:"Required;Url"` | ||||||
| 	ContentType string `form:"content_type" binding:"Required"` | 	ContentType string `form:"content_type" binding:"Required"` | ||||||
| @@ -104,3 +118,83 @@ func (f *NewWebhookForm) Validate(errors *binding.Errors, req *http.Request, con | |||||||
| 	data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) | 	data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) | ||||||
| 	validate(errors, data, f) | 	validate(errors, data, f) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // .___ | ||||||
|  | // |   | ______ ________ __   ____ | ||||||
|  | // |   |/  ___//  ___/  |  \_/ __ \ | ||||||
|  | // |   |\___ \ \___ \|  |  /\  ___/ | ||||||
|  | // |___/____  >____  >____/  \___  > | ||||||
|  | //          \/     \/            \/ | ||||||
|  |  | ||||||
|  | type CreateIssueForm struct { | ||||||
|  | 	IssueName   string `form:"title" binding:"Required;MaxSize(50)"` | ||||||
|  | 	MilestoneId int64  `form:"milestoneid"` | ||||||
|  | 	AssigneeId  int64  `form:"assigneeid"` | ||||||
|  | 	Labels      string `form:"labels"` | ||||||
|  | 	Content     string `form:"content"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f *CreateIssueForm) Name(field string) string { | ||||||
|  | 	names := map[string]string{ | ||||||
|  | 		"IssueName": "Issue name", | ||||||
|  | 	} | ||||||
|  | 	return names[field] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f *CreateIssueForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) { | ||||||
|  | 	data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) | ||||||
|  | 	validate(errors, data, f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //    _____  .__.__                   __ | ||||||
|  | //   /     \ |__|  |   ____   _______/  |_  ____   ____   ____ | ||||||
|  | //  /  \ /  \|  |  | _/ __ \ /  ___/\   __\/  _ \ /    \_/ __ \ | ||||||
|  | // /    Y    \  |  |_\  ___/ \___ \  |  | (  <_> )   |  \  ___/ | ||||||
|  | // \____|__  /__|____/\___  >____  > |__|  \____/|___|  /\___  > | ||||||
|  | //         \/             \/     \/                   \/     \/ | ||||||
|  |  | ||||||
|  | type CreateMilestoneForm struct { | ||||||
|  | 	Title    string `form:"title" binding:"Required;MaxSize(50)"` | ||||||
|  | 	Content  string `form:"content"` | ||||||
|  | 	Deadline string `form:"due_date"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f *CreateMilestoneForm) Name(field string) string { | ||||||
|  | 	names := map[string]string{ | ||||||
|  | 		"Title": "Milestone name", | ||||||
|  | 	} | ||||||
|  | 	return names[field] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f *CreateMilestoneForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) { | ||||||
|  | 	data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) | ||||||
|  | 	validate(errors, data, f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // __________       .__ | ||||||
|  | // \______   \ ____ |  |   ____ _____    ______ ____ | ||||||
|  | //  |       _// __ \|  | _/ __ \\__  \  /  ___// __ \ | ||||||
|  | //  |    |   \  ___/|  |_\  ___/ / __ \_\___ \\  ___/ | ||||||
|  | //  |____|_  /\___  >____/\___  >____  /____  >\___  > | ||||||
|  | //         \/     \/          \/     \/     \/     \/ | ||||||
|  |  | ||||||
|  | type NewReleaseForm struct { | ||||||
|  | 	TagName    string `form:"tag_name" binding:"Required"` | ||||||
|  | 	Title      string `form:"title" binding:"Required"` | ||||||
|  | 	Content    string `form:"content" binding:"Required"` | ||||||
|  | 	Prerelease bool   `form:"prerelease"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f *NewReleaseForm) Name(field string) string { | ||||||
|  | 	names := map[string]string{ | ||||||
|  | 		"TagName": "Tag name", | ||||||
|  | 		"Title":   "Release title", | ||||||
|  | 		"Content": "Release content", | ||||||
|  | 	} | ||||||
|  | 	return names[field] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f *NewReleaseForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) { | ||||||
|  | 	data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) | ||||||
|  | 	validate(errors, data, f) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -128,6 +128,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues | 		repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues | ||||||
|  | 		repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones | ||||||
| 		ctx.Repo.Repository = repo | 		ctx.Repo.Repository = repo | ||||||
| 		ctx.Data["IsBareRepo"] = ctx.Repo.Repository.IsBare | 		ctx.Data["IsBareRepo"] = ctx.Repo.Repository.IsBare | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"strings" | 	"strings" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	"github.com/go-martini/martini" | 	"github.com/go-martini/martini" | ||||||
| @@ -144,9 +145,9 @@ func CreateIssuePost(ctx *middleware.Context, params martini.Params, form auth.C | |||||||
| 		form.AssigneeId = 0 | 		form.AssigneeId = 0 | ||||||
| 	} | 	} | ||||||
| 	issue := &models.Issue{ | 	issue := &models.Issue{ | ||||||
|  | 		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, | ||||||
| 		RepoId:      ctx.Repo.Repository.Id, |  | ||||||
| 		PosterId:    ctx.User.Id, | 		PosterId:    ctx.User.Id, | ||||||
| 		MilestoneId: form.MilestoneId, | 		MilestoneId: form.MilestoneId, | ||||||
| 		AssigneeId:  form.AssigneeId, | 		AssigneeId:  form.AssigneeId, | ||||||
| @@ -385,7 +386,6 @@ func Comment(ctx *middleware.Context, params martini.Params) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// TODO: check collaborators |  | ||||||
| 	// 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 { | ||||||
| @@ -488,15 +488,64 @@ func Milestones(ctx *middleware.Context) { | |||||||
| 	ctx.Data["IsRepoToolbarIssues"] = true | 	ctx.Data["IsRepoToolbarIssues"] = true | ||||||
| 	ctx.Data["IsRepoToolbarIssuesList"] = true | 	ctx.Data["IsRepoToolbarIssuesList"] = true | ||||||
|  |  | ||||||
|  | 	isShowClosed := ctx.Query("state") == "closed" | ||||||
|  |  | ||||||
|  | 	miles, err := models.GetMilestones(ctx.Repo.Repository.Id, isShowClosed) | ||||||
|  | 	if err != nil { | ||||||
|  | 		ctx.Handle(500, "issue.Milestones(GetMilestones)", err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	for _, m := range miles { | ||||||
|  | 		m.RenderedContent = string(base.RenderSpecialLink([]byte(m.Content), ctx.Repo.RepoLink)) | ||||||
|  | 		m.CalOpenIssues() | ||||||
|  | 	} | ||||||
|  | 	ctx.Data["Milestones"] = miles | ||||||
|  |  | ||||||
|  | 	if isShowClosed { | ||||||
|  | 		ctx.Data["State"] = "closed" | ||||||
|  | 	} else { | ||||||
|  | 		ctx.Data["State"] = "open" | ||||||
|  | 	} | ||||||
| 	ctx.HTML(200, "issue/milestone") | 	ctx.HTML(200, "issue/milestone") | ||||||
| } | } | ||||||
|  |  | ||||||
| func NewMilestones(ctx *middleware.Context) { | func NewMilestone(ctx *middleware.Context) { | ||||||
| 	ctx.Data["Title"] = "New Milestones" | 	ctx.Data["Title"] = "New Milestone" | ||||||
|  | 	ctx.Data["IsRepoToolbarIssues"] = true | ||||||
|  | 	ctx.Data["IsRepoToolbarIssuesList"] = true | ||||||
|  | 	ctx.HTML(200, "issue/milestone_new") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func NewMilestonePost(ctx *middleware.Context, form auth.CreateMilestoneForm) { | ||||||
|  | 	ctx.Data["Title"] = "New Milestone" | ||||||
| 	ctx.Data["IsRepoToolbarIssues"] = true | 	ctx.Data["IsRepoToolbarIssues"] = true | ||||||
| 	ctx.Data["IsRepoToolbarIssuesList"] = true | 	ctx.Data["IsRepoToolbarIssuesList"] = true | ||||||
|  |  | ||||||
| 	ctx.HTML(200, "issue/milestone_new") | 	var deadline time.Time | ||||||
|  | 	var err error | ||||||
|  | 	if len(form.Deadline) == 0 { | ||||||
|  | 		deadline = time.Now().AddDate(100, 0, 0) | ||||||
|  | 	} else { | ||||||
|  | 		deadline, err = time.Parse("01/02/2006", form.Deadline) | ||||||
|  | 		if err != nil { | ||||||
|  | 			ctx.Handle(500, "issue.NewMilestonePost(time.Parse)", err) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	m := &models.Milestone{ | ||||||
|  | 		RepoId:   ctx.Repo.Repository.Id, | ||||||
|  | 		Index:    int64(ctx.Repo.Repository.NumMilestones) + 1, | ||||||
|  | 		Name:     form.Title, | ||||||
|  | 		Content:  form.Content, | ||||||
|  | 		Deadline: deadline, | ||||||
|  | 	} | ||||||
|  | 	if err = models.NewMilestone(m); err != nil { | ||||||
|  | 		ctx.Handle(500, "issue.NewMilestonePost(NewMilestone)", err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ctx.Redirect(ctx.Repo.RepoLink + "/issues/milestones") | ||||||
| } | } | ||||||
|  |  | ||||||
| func UpdateMilestones(ctx *middleware.Context) { | func UpdateMilestones(ctx *middleware.Context) { | ||||||
| @@ -506,4 +555,3 @@ func UpdateMilestones(ctx *middleware.Context) { | |||||||
|  |  | ||||||
| 	ctx.HTML(200, "issue/milestone_edit") | 	ctx.HTML(200, "issue/milestone_edit") | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ | |||||||
|             </div> |             </div> | ||||||
|  |  | ||||||
|             <div class="panel-body"> |             <div class="panel-body"> | ||||||
|                 Gogs database has <b>{{.Stats.Counter.User}}</b> users, <b>{{.Stats.Counter.PublicKey}}</b> SSH keys, <b>{{.Stats.Counter.Repo}}</b> repositories, <b>{{.Stats.Counter.Watch}}</b> watches, <b>{{.Stats.Counter.Action}}</b> actions, <b>{{.Stats.Counter.Access}}</b> accesses, <b>{{.Stats.Counter.Issue}}</b> issues, <b>{{.Stats.Counter.Comment}}</b> comments, <b>{{.Stats.Counter.Mirror}}</b> mirrors, <b>{{.Stats.Counter.Oauth}}</b> oauthes, <b>{{.Stats.Counter.Release}}</b> releases, <b>{{.Stats.Counter.LoginSource}}</b> login sources, <b>{{.Stats.Counter.Webhook}}</b> webhooks. |                 Gogs database has <b>{{.Stats.Counter.User}}</b> users, <b>{{.Stats.Counter.PublicKey}}</b> SSH keys, <b>{{.Stats.Counter.Repo}}</b> repositories, <b>{{.Stats.Counter.Watch}}</b> watches, <b>{{.Stats.Counter.Action}}</b> actions, <b>{{.Stats.Counter.Access}}</b> accesses, <b>{{.Stats.Counter.Issue}}</b> issues, <b>{{.Stats.Counter.Comment}}</b> comments, <b>{{.Stats.Counter.Mirror}}</b> mirrors, <b>{{.Stats.Counter.Oauth}}</b> oauthes, <b>{{.Stats.Counter.Release}}</b> releases, <b>{{.Stats.Counter.LoginSource}}</b> login sources, <b>{{.Stats.Counter.Webhook}}</b> webhooks, <b>{{.Stats.Counter.Milestone}}</b> milestones. | ||||||
|             </div> |             </div> | ||||||
|         </div> |         </div> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,10 +6,8 @@ | |||||||
|     <div id="issue"> |     <div id="issue"> | ||||||
|         <div class="col-md-3 filter-list"> |         <div class="col-md-3 filter-list"> | ||||||
|             <ul class="list-unstyled"> |             <ul class="list-unstyled"> | ||||||
|                 <li><a href="{{.RepoLink}}/issues/milestones" class="active">Open Milestones <strong class="pull-right">1</strong></a></li> |                 <li><a href="{{.RepoLink}}/issues/milestones"{{if eq .State "open"}} class="active"{{end}}>Open Milestones <strong class="pull-right">{{.Repository.NumOpenMilestones}}</strong></a></li> | ||||||
|                 <!-- <li><a href="#">Assigned to you</a></li> --> |                 <li><a href="{{.RepoLink}}/issues/milestones?state=closed"{{if eq .State "closed"}} class="active"{{end}}>Close Milestones <strong class="pull-right">{{.Repository.NumClosedMilestones}}</strong></a></li> | ||||||
|                 <li><a href="{{.RepoLink}}/issues/milestones">Close Milestones <strong class="pull-right">0</strong></a></li> |  | ||||||
|                 <!-- <li><a href="#">Mentioned</a></li> --> |  | ||||||
|             </ul> |             </ul> | ||||||
|             <hr/> |             <hr/> | ||||||
|             <a href="{{.RepoLink}}/issues/milestones/new" class="text-center"> |             <a href="{{.RepoLink}}/issues/milestones/new" class="text-center"> | ||||||
| @@ -18,34 +16,22 @@ | |||||||
|         </div> |         </div> | ||||||
|         <div class="col-md-9"> |         <div class="col-md-9"> | ||||||
|             <div class="milestones list-group"> |             <div class="milestones list-group"> | ||||||
|  |                 {{range .Milestones}} | ||||||
|                 <div class="list-group-item milestone-item"> |                 <div class="list-group-item milestone-item"> | ||||||
|                     <h4 class="title pull-left"><a href="#">Milestone Title</a></h4> |                     <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">12</span> |                     <span class="issue-open label label-success">{{.NumClosedIssues}}</span> | ||||||
|                     <span class="issue-close label label-warning">2</span> |                     <span class="issue-close label label-warning">{{.NumOpenIssues}}</span> | ||||||
|                     <p class="actions pull-right"> |                     <p class="actions pull-right"> | ||||||
|                         <a href="{{.RepoLink}}/issues/milestones/edit">Edit</a> |                         <!-- <a href="{{$.RepoLink}}/issues/milestones/{{.Index}}/edit">Edit</a> --> | ||||||
|                         <a href="#">Open</a> |                         <!-- <a href="#">Open</a> | ||||||
|                         <a href="#">Close</a> |                         <a href="#">Close</a> --> | ||||||
|                         <a class="text-danger" href="#">Delete</a> |                         <!-- <a class="text-danger" href="#">Delete</a> --> | ||||||
|                         <a href="#">Issues</a> |                         <a href="{{$.RepoLink}}/issues?milestone={{.Index}}{{if .IsClosed}}&state=closed{{end}}">Issues</a> | ||||||
|                     </p> |                     </p> | ||||||
|                     <hr/> |                     <hr/> | ||||||
|                     <p class="description">In this version of release, users are able to register and log in/out on Gogs, setting up SSH keys and do most of Git operations through SSH with public repositories. And Web UI only for view of Git data, no extra features are supported.</p> |                     <p class="description">{{.RenderedContent | str2html}}</p> | ||||||
|                 </div> |  | ||||||
|                 <div class="list-group-item milestone-item"> |  | ||||||
|                     <h4 class="title pull-left"><a href="#">Milestone Title</a></h4> |  | ||||||
|                     <span class="issue-open label label-success">12</span> |  | ||||||
|                     <span class="issue-close label label-warning">2</span> |  | ||||||
|                     <p class="actions pull-right"> |  | ||||||
|                         <a href="{{.RepoLink}}/issues/milestones/edit">Edit</a> |  | ||||||
|                         <a href="#">Open</a> |  | ||||||
|                         <a href="#">Close</a> |  | ||||||
|                         <a class="text-danger" href="#">Delete</a> |  | ||||||
|                         <a href="#">Issues</a> |  | ||||||
|                     </p> |  | ||||||
|                     <hr/> |  | ||||||
|                     <p class="description">In this version of release, users are able to register and log in/out on Gogs, setting up SSH keys and do most of Git operations through SSH with public repositories. And Web UI only for view of Git data, no extra features are supported.</p> |  | ||||||
|                 </div> |                 </div> | ||||||
|  |                 {{end}} | ||||||
|             </div> |             </div> | ||||||
|         </div> |         </div> | ||||||
|     </div> |     </div> | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ | |||||||
|                 <div class="text-right panel-body"> |                 <div class="text-right panel-body"> | ||||||
|                     <div class="form-group"> |                     <div class="form-group"> | ||||||
|                         <input type="hidden" value="id" name="repo-id"/> |                         <input type="hidden" value="id" name="repo-id"/> | ||||||
|                         <button class="btn-success btn">Create new issue</button> |                         <button class="btn-success btn">Create new milestone</button> | ||||||
|                     </div> |                     </div> | ||||||
|                 </div> |                 </div> | ||||||
|             </div> |             </div> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user