Finish add new milestone
This commit is contained in:
parent
f1130ce5e9
commit
54e95fa367
14 changed files with 236 additions and 136 deletions
|
@ -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 a new issue