__pycache__ | __pycache__ | ||||
*.pem | *.pem | ||||
output* | output* | ||||
config.codekit | |||||
.brackets.json | .brackets.json | ||||
docker/fig.yml | docker/fig.yml | ||||
docker/docker/Dockerfile | docker/docker/Dockerfile |
// Check dependency version. | // Check dependency version. | ||||
checkers := []VerChecker{ | checkers := []VerChecker{ | ||||
{"github.com/Unknwon/macaron", macaron.Version, "0.5.4"}, | {"github.com/Unknwon/macaron", macaron.Version, "0.5.4"}, | ||||
{"github.com/macaron-contrib/binding", binding.Version, "0.0.6"}, | |||||
{"github.com/macaron-contrib/binding", binding.Version, "0.1.0"}, | |||||
{"github.com/macaron-contrib/cache", cache.Version, "0.0.7"}, | {"github.com/macaron-contrib/cache", cache.Version, "0.0.7"}, | ||||
{"github.com/macaron-contrib/csrf", csrf.Version, "0.0.3"}, | {"github.com/macaron-contrib/csrf", csrf.Version, "0.0.3"}, | ||||
{"github.com/macaron-contrib/i18n", i18n.Version, "0.0.7"}, | {"github.com/macaron-contrib/i18n", i18n.Version, "0.0.7"}, | ||||
m.Group("/:username/:reponame", func() { | m.Group("/:username/:reponame", func() { | ||||
m.Get("/releases", middleware.RepoRef(), repo.Releases) | m.Get("/releases", middleware.RepoRef(), repo.Releases) | ||||
m.Get("/issues", repo.Issues) | |||||
m.Get("/issues", repo.RetrieveLabels, repo.Issues) | |||||
m.Get("/issues/:index", repo.ViewIssue) | m.Get("/issues/:index", repo.ViewIssue) | ||||
m.Get("/labels/", repo.RetrieveLabels, repo.Labels) | |||||
m.Get("/milestones", repo.Milestones) | m.Get("/milestones", repo.Milestones) | ||||
m.Get("/pulls", repo.Pulls) | m.Get("/pulls", repo.Pulls) | ||||
m.Get("/branches", repo.Branches) | m.Get("/branches", repo.Branches) | ||||
m.Get("/archive/*", repo.Download) | m.Get("/archive/*", repo.Download) | ||||
m.Get("/issues2/", repo.Issues2) | |||||
m.Get("/pulls2/", repo.PullRequest2) | m.Get("/pulls2/", repo.PullRequest2) | ||||
m.Get("/labels2/", repo.Labels2) | |||||
m.Get("/milestone2/", repo.Milestones2) | m.Get("/milestone2/", repo.Milestones2) | ||||
m.Group("", func() { | m.Group("", func() { |
require_error = ` cannot be empty.` | require_error = ` cannot be empty.` | ||||
alpha_dash_error = ` must be valid alpha or numeric or dash(-_) characters.` | alpha_dash_error = ` must be valid alpha or numeric or dash(-_) characters.` | ||||
alpha_dash_dot_error = ` must be valid alpha or numeric or dash(-_) or dot characters.` | alpha_dash_dot_error = ` must be valid alpha or numeric or dash(-_) or dot characters.` | ||||
size_error = ` must be size %s.` | |||||
min_size_error = ` must contain at least %s characters.` | min_size_error = ` must contain at least %s characters.` | ||||
max_size_error = ` must contain at most %s characters.` | max_size_error = ` must contain at most %s characters.` | ||||
email_error = ` is not a valid e-mail address.` | email_error = ` is not a valid e-mail address.` | ||||
commits.newer = Newer | commits.newer = Newer | ||||
issues.new = New Issue | issues.new = New Issue | ||||
issues.new_label = New Label | |||||
issues.new_label_placeholder = Label name... | |||||
issues.open_tab = %d Open | issues.open_tab = %d Open | ||||
issues.close_tab = %d Closed | issues.close_tab = %d Closed | ||||
issues.filter_label = Label | issues.filter_label = Label | ||||
issues.filter_type.created_by_you = Created by you | issues.filter_type.created_by_you = Created by you | ||||
issues.filter_type.mentioning_you = Mentioning you | issues.filter_type.mentioning_you = Mentioning you | ||||
issues.opened_by = opened %s by <a href="/%[2]s">%[2]s</a> | issues.opened_by = opened %s by <a href="/%[2]s">%[2]s</a> | ||||
issues.label_title = Label name | |||||
issues.label_color = Label color | |||||
issues.label_count = %d labels | |||||
issues.label_open_issues = %d open issues | |||||
issues.label_edit = Edit | |||||
issues.label_delete = Delete | |||||
issues.previous = Previous Page | issues.previous = Previous Page | ||||
issues.next = Next Page | issues.next = Next Page | ||||
"github.com/gogits/gogs/modules/setting" | "github.com/gogits/gogs/modules/setting" | ||||
) | ) | ||||
const APP_VER = "0.6.1.0724 Beta" | |||||
const APP_VER = "0.6.2.0724 Beta" | |||||
func init() { | func init() { | ||||
runtime.GOMAXPROCS(runtime.NumCPU()) | runtime.GOMAXPROCS(runtime.NumCPU()) |
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 | ||||
} | } | ||||
} | } | ||||
if err = UpdateIssue(issue); err != nil { | if err = UpdateIssue(issue); err != nil { | ||||
return err | return err | ||||
} else if err = UpdateIssueUserPairsByStatus(issue.Id, issue.IsClosed); err != nil { | |||||
} else if err = UpdateIssueUserPairsByStatus(issue.ID, issue.IsClosed); err != nil { | |||||
return err | return err | ||||
} | } | ||||
} | } | ||||
// If commit happened in the referenced repository, it means the issue can be closed. | // If commit happened in the referenced repository, it means the issue can be closed. | ||||
if _, err = CreateComment(userId, repoId, issue.Id, 0, 0, COMMENT_TYPE_CLOSE, "", nil); err != nil { | |||||
if _, err = CreateComment(userId, repoId, issue.ID, 0, 0, COMMENT_TYPE_CLOSE, "", nil); err != nil { | |||||
return err | return err | ||||
} | } | ||||
} | } | ||||
if err = UpdateIssue(issue); err != nil { | if err = UpdateIssue(issue); err != nil { | ||||
return err | return err | ||||
} else if err = UpdateIssueUserPairsByStatus(issue.Id, issue.IsClosed); err != nil { | |||||
} else if err = UpdateIssueUserPairsByStatus(issue.ID, issue.IsClosed); err != nil { | |||||
return err | return err | ||||
} | } | ||||
} | } | ||||
// If commit happened in the referenced repository, it means the issue can be closed. | // If commit happened in the referenced repository, it means the issue can be closed. | ||||
if _, err = CreateComment(userId, repoId, issue.Id, 0, 0, COMMENT_TYPE_REOPEN, "", nil); err != nil { | |||||
if _, err = CreateComment(userId, repoId, issue.ID, 0, 0, COMMENT_TYPE_REOPEN, "", nil); err != nil { | |||||
return err | return err | ||||
} | } | ||||
} | } |
// 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 `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 | ||||
} | } | ||||
func (i *Issue) Attachments() []*Attachment { | func (i *Issue) Attachments() []*Attachment { | ||||
a, _ := GetAttachmentsForIssue(i.Id) | |||||
a, _ := GetAttachmentsForIssue(i.ID) | |||||
return a | return a | ||||
} | } | ||||
func (i *Issue) AfterDelete() { | func (i *Issue) AfterDelete() { | ||||
_, err := DeleteAttachmentsByIssue(i.Id, true) | |||||
_, err := DeleteAttachmentsByIssue(i.ID, true) | |||||
if err != nil { | if err != nil { | ||||
log.Info("Could not delete files for issue #%d: %s", i.Id, err) | |||||
log.Info("Could not delete files for issue #%d: %s", i.ID, err) | |||||
} | } | ||||
} | } | ||||
// GetIssueById returns an issue by ID. | // GetIssueById returns an issue by ID. | ||||
func GetIssueById(id int64) (*Issue, error) { | func GetIssueById(id int64) (*Issue, error) { | ||||
issue := &Issue{Id: id} | |||||
issue := &Issue{ID: id} | |||||
has, err := x.Get(issue) | has, err := x.Get(issue) | ||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
// UpdateIssue updates information of issue. | // UpdateIssue updates information of issue. | ||||
func UpdateIssue(issue *Issue) error { | func UpdateIssue(issue *Issue) error { | ||||
_, err := x.Id(issue.Id).AllCols().Update(issue) | |||||
_, err := x.Id(issue.ID).AllCols().Update(issue) | |||||
if err != nil { | if err != nil { | ||||
return err | return err | ||||
// 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 `xorm:"pk autoincr"` | |||||
RepoId int64 `xorm:"INDEX"` | RepoId int64 `xorm:"INDEX"` | ||||
Name string | Name string | ||||
Color string `xorm:"VARCHAR(7)"` | Color string `xorm:"VARCHAR(7)"` | ||||
return nil, ErrLabelNotExist | return nil, ErrLabelNotExist | ||||
} | } | ||||
l := &Label{Id: id} | |||||
l := &Label{ID: id} | |||||
has, err := x.Get(l) | has, err := x.Get(l) | ||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
// UpdateLabel updates label information. | // UpdateLabel updates label information. | ||||
func UpdateLabel(l *Label) error { | func UpdateLabel(l *Label) error { | ||||
_, err := x.Id(l.Id).AllCols().Update(l) | |||||
_, err := x.Id(l.ID).AllCols().Update(l) | |||||
return err | return err | ||||
} | } | ||||
for _, issue := range issues { | for _, issue := range issues { | ||||
issue.LabelIds = strings.Replace(issue.LabelIds, "$"+strId+"|", "", -1) | issue.LabelIds = strings.Replace(issue.LabelIds, "$"+strId+"|", "", -1) | ||||
if _, err = sess.Id(issue.Id).AllCols().Update(issue); err != nil { | |||||
if _, err = sess.Id(issue.ID).AllCols().Update(issue); err != nil { | |||||
sess.Rollback() | sess.Rollback() | ||||
return err | return err | ||||
} | } | ||||
} | } | ||||
rawSql := "UPDATE `issue_user` SET milestone_id = 0 WHERE issue_id = ?" | rawSql := "UPDATE `issue_user` SET milestone_id = 0 WHERE issue_id = ?" | ||||
if _, err = sess.Exec(rawSql, issue.Id); err != nil { | |||||
if _, err = sess.Exec(rawSql, issue.ID); err != nil { | |||||
sess.Rollback() | sess.Rollback() | ||||
return err | return err | ||||
} | } | ||||
} | } | ||||
rawSql := "UPDATE `issue_user` SET milestone_id = ? WHERE issue_id = ?" | rawSql := "UPDATE `issue_user` SET milestone_id = ? WHERE issue_id = ?" | ||||
if _, err = sess.Exec(rawSql, m.Id, issue.Id); err != nil { | |||||
if _, err = sess.Exec(rawSql, m.Id, issue.ID); err != nil { | |||||
sess.Rollback() | sess.Rollback() | ||||
return err | return err | ||||
} | } |
return err | return err | ||||
} | } | ||||
for i := range issues { | for i := range issues { | ||||
if _, err = sess.Delete(&Comment{IssueId: issues[i].Id}); err != nil { | |||||
if _, err = sess.Delete(&Comment{IssueId: issues[i].ID}); err != nil { | |||||
return err | return err | ||||
} | } | ||||
} | } |
func getSize(field reflect.StructField, prefix string) string { | func getSize(field reflect.StructField, prefix string) string { | ||||
for _, rule := range strings.Split(field.Tag.Get("binding"), ";") { | for _, rule := range strings.Split(field.Tag.Get("binding"), ";") { | ||||
if strings.HasPrefix(rule, prefix) { | if strings.HasPrefix(rule, prefix) { | ||||
return rule[8 : len(rule)-1] | |||||
return rule[len(prefix) : len(rule)-1] | |||||
} | } | ||||
} | } | ||||
return "" | return "" | ||||
} | } | ||||
func GetSize(field reflect.StructField) string { | |||||
return getSize(field, "Size(") | |||||
} | |||||
func GetMinSize(field reflect.StructField) string { | func GetMinSize(field reflect.StructField) string { | ||||
return getSize(field, "MinSize(") | return getSize(field, "MinSize(") | ||||
} | } | ||||
data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_error") | data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_error") | ||||
case binding.ERR_ALPHA_DASH_DOT: | case binding.ERR_ALPHA_DASH_DOT: | ||||
data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_dot_error") | data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_dot_error") | ||||
case binding.ERR_SIZE: | |||||
data["ErrorMsg"] = trName + l.Tr("form.size_error", GetSize(field)) | |||||
case binding.ERR_MIN_SIZE: | case binding.ERR_MIN_SIZE: | ||||
data["ErrorMsg"] = trName + l.Tr("form.min_size_error", GetMinSize(field)) | data["ErrorMsg"] = trName + l.Tr("form.min_size_error", GetMinSize(field)) | ||||
case binding.ERR_MAX_SIZE: | case binding.ERR_MAX_SIZE: |
// \/ \/ \/ \/ | // \/ \/ \/ \/ | ||||
type CreateLabelForm struct { | type CreateLabelForm struct { | ||||
Title string `form:"title" binding:"Required;MaxSize(50)"` | |||||
Color string `form:"color" binding:"Required;Size(7)"` | |||||
Title string `binding:"Required;MaxSize(50)" locale:"repo.issues.label_name"` | |||||
Color string `binding:"Required;Size(7)" locale:"repo.issues.label_color"` | |||||
} | } | ||||
func (f *CreateLabelForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | func (f *CreateLabelForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { |
}); | }); | ||||
}; | }; | ||||
function initRepository(){ | |||||
if ($('.repository').length == 0) { | |||||
return; | |||||
} | |||||
if ($('.labels').length == 0) { | |||||
return; | |||||
} | |||||
$('.color-picker').each( function() { | |||||
$(this).minicolors(); | |||||
}); | |||||
$('.precolors .color').click(function(){ | |||||
var color_hex = $(this).data('color-hex') | |||||
$('.color-picker').val(color_hex); | |||||
$('.minicolors-swatch-color').css("background-color", color_hex); | |||||
}); | |||||
}; | |||||
$(document).ready(function () { | $(document).ready(function () { | ||||
// Semantic UI modules. | // Semantic UI modules. | ||||
$('.dropdown').dropdown(); | $('.dropdown').dropdown(); | ||||
$('.poping.up').popup(); | $('.poping.up').popup(); | ||||
initInstall(); | initInstall(); | ||||
initRepository(); | |||||
}); | }); |
$(document).ready(function(){$(".dropdown").dropdown({transition:"slide up"})}); |
.navbar { | .navbar { | ||||
height: 60px; | height: 60px; | ||||
padding-top: 20px; | padding-top: 20px; | ||||
.ui.secondary.menu .item { | |||||
margin-left: -10px; | |||||
margin-top: -7px; | |||||
&>.input { | |||||
.new-label-input, | |||||
.color-picker { | |||||
background-color: white; | |||||
border: 1px solid rgba(0,0,0,.15); | |||||
} | |||||
} | |||||
.new-label-input { | |||||
width: 150px; | |||||
} | |||||
.color-picker { | |||||
height: 35px; | |||||
width: auto; | |||||
padding-left: 30px; | |||||
} | |||||
.minicolors-swatch.minicolors-sprite { | |||||
top: 10px; | |||||
left: 10px; | |||||
width: 15px; | |||||
height: 15px; | |||||
} | |||||
&.precolors { | |||||
padding-left: 0; | |||||
padding-right: 0; | |||||
margin-right: 10px; | |||||
width: 120px; | |||||
.color { | |||||
float: left; | |||||
width: 15px; | |||||
height: 15px; | |||||
} | |||||
} | |||||
} | |||||
} | } | ||||
.filter.menu .label.color { | .filter.menu .label.color { | ||||
padding: 0 8px; | padding: 0 8px; | ||||
left: auto!important; | left: auto!important; | ||||
} | } | ||||
.issue.list { | .issue.list { | ||||
clear: both; | |||||
list-style: none; | list-style: none; | ||||
font-size: 13px; | font-size: 13px; | ||||
padding-top: 45px; | |||||
padding-top: 15px; | |||||
.item { | .item { | ||||
padding-top: 15px; | padding-top: 15px; | ||||
padding-bottom: 10px; | padding-bottom: 10px; | ||||
padding-top: 15px; | padding-top: 15px; | ||||
} | } | ||||
} | } | ||||
.label.list { | |||||
clear: both; | |||||
padding-top: 15px; | |||||
.item { | |||||
padding-top: 10px; | |||||
padding-bottom: 10px; | |||||
border-bottom: 1px dashed #AAA; | |||||
a { | |||||
font-size: 15px; | |||||
padding-top: 5px; | |||||
padding-right: 10px; | |||||
color: #666; | |||||
&:hover { | |||||
color: #000; | |||||
} | |||||
&.open-issues { | |||||
margin-right: 30px; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | } |
ISSUE_CREATE base.TplName = "repo/issue/create" | ISSUE_CREATE base.TplName = "repo/issue/create" | ||||
ISSUE_VIEW base.TplName = "repo/issue/view" | ISSUE_VIEW base.TplName = "repo/issue/view" | ||||
LABELS base.TplName = "repo/issue/labels" | |||||
MILESTONE base.TplName = "repo/issue/milestone" | MILESTONE base.TplName = "repo/issue/milestone" | ||||
MILESTONE_NEW base.TplName = "repo/issue/milestone_new" | MILESTONE_NEW base.TplName = "repo/issue/milestone_new" | ||||
MILESTONE_EDIT base.TplName = "repo/issue/milestone_edit" | MILESTONE_EDIT base.TplName = "repo/issue/milestone_edit" | ||||
ErrTooManyFiles = errors.New("Maximum number of files to upload exceeded") | ErrTooManyFiles = errors.New("Maximum number of files to upload exceeded") | ||||
) | ) | ||||
func RetrieveLabels(ctx *middleware.Context) { | |||||
labels, err := models.GetLabels(ctx.Repo.Repository.Id) | |||||
if err != nil { | |||||
ctx.Handle(500, "RetrieveLabels.GetLabels: %v", err) | |||||
return | |||||
} | |||||
for _, l := range labels { | |||||
l.CalOpenIssues() | |||||
} | |||||
ctx.Data["Labels"] = labels | |||||
ctx.Data["NumLabels"] = len(labels) | |||||
} | |||||
func Issues(ctx *middleware.Context) { | func Issues(ctx *middleware.Context) { | ||||
ctx.Data["Title"] = ctx.Tr("repo.issues") | ctx.Data["Title"] = ctx.Tr("repo.issues") | ||||
ctx.Data["PageIsIssueList"] = true | ctx.Data["PageIsIssueList"] = true | ||||
mid = mile.Id | mid = mile.Id | ||||
} | } | ||||
selectLabels := ctx.Query("labels") | |||||
labels, err := models.GetLabels(repo.Id) | |||||
if err != nil { | |||||
ctx.Handle(500, "GetLabels: %v", err) | |||||
return | |||||
} | |||||
for _, l := range labels { | |||||
l.CalOpenIssues() | |||||
} | |||||
ctx.Data["Labels"] = labels | |||||
page := ctx.QueryInt("page") | page := ctx.QueryInt("page") | ||||
if page <= 1 { | if page <= 1 { | ||||
page = 1 | page = 1 | ||||
ctx.Data["NextPage"] = page + 1 | ctx.Data["NextPage"] = page + 1 | ||||
} | } | ||||
selectLabels := ctx.Query("labels") | |||||
// Get issues. | // Get issues. | ||||
issues, err := models.GetIssues(assigneeId, repo.Id, posterId, mid, page, | issues, err := models.GetIssues(assigneeId, repo.Id, posterId, mid, page, | ||||
isShowClosed, selectLabels, ctx.Query("sortType")) | isShowClosed, selectLabels, ctx.Query("sortType")) | ||||
// Get posters. | // Get posters. | ||||
for i := range issues { | for i := range issues { | ||||
if err = issues[i].GetLabels(); err != nil { | if err = issues[i].GetLabels(); err != nil { | ||||
ctx.Handle(500, "GetLabels", fmt.Errorf("[#%d]%v", issues[i].Id, err)) | |||||
ctx.Handle(500, "GetLabels", fmt.Errorf("[#%d]%v", issues[i].ID, err)) | |||||
return | return | ||||
} | } | ||||
idx := models.PairsContains(pairs, issues[i].Id, ctx.User.Id) | |||||
if ctx.IsSigned { | |||||
idx := models.PairsContains(pairs, issues[i].ID, ctx.User.Id) | |||||
if filterMode == models.FM_MENTION && (idx == -1 || !pairs[idx].IsMentioned) { | |||||
continue | |||||
} | |||||
if filterMode == models.FM_MENTION && (idx == -1 || !pairs[idx].IsMentioned) { | |||||
continue | |||||
} | |||||
if idx > -1 { | |||||
issues[i].IsRead = pairs[idx].IsRead | |||||
} else { | |||||
issues[i].IsRead = true | |||||
if idx > -1 { | |||||
issues[i].IsRead = pairs[idx].IsRead | |||||
} else { | |||||
issues[i].IsRead = true | |||||
} | |||||
} | } | ||||
if err = issues[i].GetPoster(); err != nil { | if err = issues[i].GetPoster(); err != nil { | ||||
ctx.Handle(500, "GetPoster", fmt.Errorf("[#%d]%v", issues[i].Id, err)) | |||||
ctx.Handle(500, "GetPoster", fmt.Errorf("[#%d]%v", issues[i].ID, err)) | |||||
return | return | ||||
} | } | ||||
} | } | ||||
if err := models.NewIssue(issue); err != nil { | if err := models.NewIssue(issue); err != nil { | ||||
send(500, nil, err) | send(500, nil, err) | ||||
return | return | ||||
} else if err := models.NewIssueUserPairs(ctx.Repo.Repository, issue.Id, ctx.Repo.Owner.Id, | |||||
} else if err := models.NewIssueUserPairs(ctx.Repo.Repository, issue.ID, ctx.Repo.Owner.Id, | |||||
ctx.User.Id, form.AssigneeId); err != nil { | ctx.User.Id, form.AssigneeId); err != nil { | ||||
send(500, nil, err) | send(500, nil, err) | ||||
return | return | ||||
} | } | ||||
if setting.AttachmentEnabled { | if setting.AttachmentEnabled { | ||||
uploadFiles(ctx, issue.Id, 0) | |||||
uploadFiles(ctx, issue.ID, 0) | |||||
} | } | ||||
// Update mentions. | // Update mentions. | ||||
ms[i] = ms[i][1:] | ms[i] = ms[i][1:] | ||||
} | } | ||||
if err := models.UpdateMentions(ms, issue.Id); err != nil { | |||||
if err := models.UpdateMentions(ms, issue.ID); err != nil { | |||||
send(500, nil, err) | send(500, nil, err) | ||||
return | return | ||||
} | } | ||||
return | return | ||||
} | } | ||||
} | } | ||||
log.Trace("%d Issue created: %d", ctx.Repo.Repository.Id, issue.Id) | |||||
log.Trace("%d Issue created: %d", ctx.Repo.Repository.Id, issue.ID) | |||||
send(200, fmt.Sprintf("%s/%s/%s/issues/%d", setting.AppSubUrl, ctx.Params(":username"), ctx.Params(":reponame"), issue.Index), nil) | send(200, fmt.Sprintf("%s/%s/%s/issues/%d", setting.AppSubUrl, ctx.Params(":username"), ctx.Params(":reponame"), issue.Index), nil) | ||||
} | } | ||||
func checkLabels(labels, allLabels []*models.Label) { | func checkLabels(labels, allLabels []*models.Label) { | ||||
for _, l := range labels { | for _, l := range labels { | ||||
for _, l2 := range allLabels { | for _, l2 := range allLabels { | ||||
if l.Id == l2.Id { | |||||
if l.ID == l2.ID { | |||||
l2.IsChecked = true | l2.IsChecked = true | ||||
break | break | ||||
} | } | ||||
if ctx.IsSigned { | if ctx.IsSigned { | ||||
// Update issue-user. | // Update issue-user. | ||||
if err = models.UpdateIssueUserPairByRead(ctx.User.Id, issue.Id); err != nil { | |||||
if err = models.UpdateIssueUserPairByRead(ctx.User.Id, issue.ID); err != nil { | |||||
ctx.Handle(500, "issue.ViewIssue(UpdateIssueUserPairByRead): %v", err) | ctx.Handle(500, "issue.ViewIssue(UpdateIssueUserPairByRead): %v", err) | ||||
return | return | ||||
} | } | ||||
issue.RenderedContent = string(base.RenderMarkdown([]byte(issue.Content), ctx.Repo.RepoLink)) | issue.RenderedContent = string(base.RenderMarkdown([]byte(issue.Content), ctx.Repo.RepoLink)) | ||||
// Get comments. | // Get comments. | ||||
comments, err := models.GetIssueComments(issue.Id) | |||||
comments, err := models.GetIssueComments(issue.ID) | |||||
if err != nil { | if err != nil { | ||||
ctx.Handle(500, "issue.ViewIssue(GetIssueComments): %v", err) | ctx.Handle(500, "issue.ViewIssue(GetIssueComments): %v", err) | ||||
return | return | ||||
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 | ||||
} else if err = models.UpdateIssue(issue); err != nil { | } else if err = models.UpdateIssue(issue); err != nil { | ||||
if err = models.UpdateIssue(issue); err != nil { | if err = models.UpdateIssue(issue); err != nil { | ||||
send(500, nil, err) | send(500, nil, err) | ||||
return | return | ||||
} else if err = models.UpdateIssueUserPairsByStatus(issue.Id, issue.IsClosed); err != nil { | |||||
} else if err = models.UpdateIssueUserPairsByStatus(issue.ID, issue.IsClosed); err != nil { | |||||
send(500, nil, err) | send(500, nil, err) | ||||
return | return | ||||
} | } | ||||
cmtType = models.COMMENT_TYPE_REOPEN | cmtType = models.COMMENT_TYPE_REOPEN | ||||
} | } | ||||
if _, err = models.CreateComment(ctx.User.Id, ctx.Repo.Repository.Id, issue.Id, 0, 0, cmtType, "", nil); err != nil { | |||||
if _, err = models.CreateComment(ctx.User.Id, ctx.Repo.Repository.Id, issue.ID, 0, 0, cmtType, "", nil); err != nil { | |||||
send(200, nil, err) | send(200, nil, err) | ||||
return | return | ||||
} | } | ||||
log.Trace("%s Issue(%d) status changed: %v", ctx.Req.RequestURI, issue.Id, !issue.IsClosed) | |||||
log.Trace("%s Issue(%d) status changed: %v", ctx.Req.RequestURI, issue.ID, !issue.IsClosed) | |||||
} | } | ||||
} | } | ||||
if len(content) > 0 || len(ctx.Req.MultipartForm.File["attachments"]) > 0 { | if len(content) > 0 || len(ctx.Req.MultipartForm.File["attachments"]) > 0 { | ||||
switch ctx.Params(":action") { | switch ctx.Params(":action") { | ||||
case "new": | case "new": | ||||
if comment, err = models.CreateComment(ctx.User.Id, ctx.Repo.Repository.Id, issue.Id, 0, 0, models.COMMENT_TYPE_COMMENT, content, nil); err != nil { | |||||
if comment, err = models.CreateComment(ctx.User.Id, ctx.Repo.Repository.Id, issue.ID, 0, 0, models.COMMENT_TYPE_COMMENT, content, nil); err != nil { | |||||
send(500, nil, err) | send(500, nil, err) | ||||
return | return | ||||
} | } | ||||
ms[i] = ms[i][1:] | ms[i] = ms[i][1:] | ||||
} | } | ||||
if err := models.UpdateMentions(ms, issue.Id); err != nil { | |||||
if err := models.UpdateMentions(ms, issue.ID); err != nil { | |||||
send(500, nil, err) | send(500, nil, err) | ||||
return | return | ||||
} | } | ||||
} | } | ||||
log.Trace("%s Comment created: %d", ctx.Req.RequestURI, issue.Id) | |||||
log.Trace("%s Comment created: %d", ctx.Req.RequestURI, issue.ID) | |||||
default: | default: | ||||
ctx.Handle(404, "issue.Comment", err) | ctx.Handle(404, "issue.Comment", err) | ||||
return | return | ||||
} | } | ||||
if comment != nil { | if comment != nil { | ||||
uploadFiles(ctx, issue.Id, comment.Id) | |||||
uploadFiles(ctx, issue.ID, comment.Id) | |||||
} | } | ||||
// Notify watchers. | // Notify watchers. | ||||
send(200, fmt.Sprintf("%s/issues/%d", ctx.Repo.RepoLink, index), nil) | send(200, fmt.Sprintf("%s/issues/%d", ctx.Repo.RepoLink, index), nil) | ||||
} | } | ||||
func Labels(ctx *middleware.Context) { | |||||
ctx.Data["Title"] = ctx.Tr("repo.labels") | |||||
ctx.Data["PageIsLabels"] = true | |||||
ctx.HTML(200, LABELS) | |||||
} | |||||
func NewLabel(ctx *middleware.Context, form auth.CreateLabelForm) { | func NewLabel(ctx *middleware.Context, form auth.CreateLabelForm) { | ||||
ctx.Data["Title"] = ctx.Tr("repo.labels") | |||||
ctx.Data["PageIsLabels"] = true | |||||
if ctx.HasError() { | if ctx.HasError() { | ||||
Issues(ctx) | |||||
ctx.Flash.Error(ctx.Data["ErrorMsg"].(string)) | |||||
ctx.Redirect(ctx.Repo.RepoLink + "/labels") | |||||
return | return | ||||
} | } | ||||
Color: form.Color, | Color: form.Color, | ||||
} | } | ||||
if err := models.NewLabel(l); err != nil { | if err := models.NewLabel(l); err != nil { | ||||
ctx.Handle(500, "issue.NewLabel(NewLabel)", err) | |||||
ctx.Handle(500, "NewLabel", err) | |||||
return | return | ||||
} | } | ||||
ctx.Redirect(ctx.Repo.RepoLink + "/issues") | |||||
ctx.Redirect(ctx.Repo.RepoLink + "/labels") | |||||
} | } | ||||
func UpdateLabel(ctx *middleware.Context, form auth.CreateLabelForm) { | func UpdateLabel(ctx *middleware.Context, form auth.CreateLabelForm) { | ||||
} | } | ||||
l := &models.Label{ | l := &models.Label{ | ||||
Id: id, | |||||
ID: id, | |||||
Name: form.Title, | Name: form.Title, | ||||
Color: form.Color, | Color: form.Color, | ||||
} | } | ||||
ctx.ServeFile(attachment.Path, "\""+attachment.Name+"\"") | ctx.ServeFile(attachment.Path, "\""+attachment.Name+"\"") | ||||
} | } | ||||
// testing route handler for new issue ui page | |||||
// todo : move to Issue() function | |||||
func Issues2(ctx *middleware.Context) { | |||||
ctx.HTML(200, "repo/issue2/list") | |||||
} | |||||
func PullRequest2(ctx *middleware.Context) { | func PullRequest2(ctx *middleware.Context) { | ||||
ctx.HTML(200, "repo/pr2/list") | ctx.HTML(200, "repo/pr2/list") | ||||
} | } | ||||
func Labels2(ctx *middleware.Context) { | |||||
ctx.HTML(200, "repo/issue2/labels") | |||||
} | |||||
func Milestones2(ctx *middleware.Context) { | func Milestones2(ctx *middleware.Context) { | ||||
ctx.HTML(200, "repo/milestone2/list") | ctx.HTML(200, "repo/milestone2/list") | ||||
} | } |
0.6.1.0724 Beta | |||||
0.6.2.0724 Beta |
<script src="{{AppSubUrl}}/js/semantic.min.js?v={{AppVer}}"></script> | <script src="{{AppSubUrl}}/js/semantic.min.js?v={{AppVer}}"></script> | ||||
<script src="{{AppSubUrl}}/js/gogs.js?v={{AppVer}}"></script> | <script src="{{AppSubUrl}}/js/gogs.js?v={{AppVer}}"></script> | ||||
<!-- Third-party libraries --> | |||||
{{if .PageIsLabels}} | |||||
<link rel="stylesheet" href="{{AppSubUrl}}/css/jquery.minicolors.css?v={{AppVer}}"> | |||||
<script src="{{AppSubUrl}}/js/libs/jquery.minicolors.min.js?v={{AppVer}}"></script> | |||||
{{end}} | |||||
<title>{{if .Title}}{{.Title}} - {{end}}{{AppName}}</title> | <title>{{if .Title}}{{.Title}} - {{end}}{{AppName}}</title> | ||||
</head> | </head> | ||||
<body> | <body> |
{{if .Flash}} | |||||
<div class="sixteen wide center aligned centered column"> | |||||
{{template "base/alert" .}} | |||||
</div> | |||||
{{end}} |
{{template "base/head" .}} | |||||
<div class="repository labels"> | |||||
{{template "repo/header" .}} | |||||
<div class="ui middle page grid body"> | |||||
<div class="navbar"> | |||||
{{template "repo/issue/navbar" .}} | |||||
{{if .IsRepositoryAdmin}} | |||||
<form class="ui right form" action="{{$.RepoLink}}/labels/new" method="post"> | |||||
{{.CsrfTokenHtml}} | |||||
<div class="ui right floated secondary menu"> | |||||
<div class="item"> | |||||
<div class="ui large input"> | |||||
<input class="new-label-input" name="title" placeholder="{{.i18n.Tr "repo.issues.new_label_placeholder"}}" required> | |||||
</div> | |||||
</div> | |||||
<div class="item"> | |||||
<div class="ui large input"> | |||||
<input class="color-picker" name="color" value="#70c24a" required> | |||||
</div> | |||||
</div> | |||||
<div class="item precolors"> | |||||
<a class="color" style="background-color:#e11d21" data-color-hex="#e11d21"></a> | |||||
<a class="color" style="background-color:#eb6420" data-color-hex="#eb6420"></a> | |||||
<a class="color" style="background-color:#fbca04" data-color-hex="#fbca04"></a> | |||||
<a class="color" style="background-color:#009800" data-color-hex="#009800"></a> | |||||
<a class="color" style="background-color:#006b75" data-color-hex="#006b75"></a> | |||||
<a class="color" style="background-color:#207de5" data-color-hex="#207de5"></a> | |||||
<a class="color" style="background-color:#0052cc" data-color-hex="#0052cc"></a> | |||||
<a class="color" style="background-color:#53e917" data-color-hex="#53e917"></a> | |||||
<a class="color" style="background-color:#f6c6c7" data-color-hex="#f6c6c7"></a> | |||||
<a class="color" style="background-color:#fad8c7" data-color-hex="#fad8c7"></a> | |||||
<a class="color" style="background-color:#fef2c0" data-color-hex="#fef2c0"></a> | |||||
<a class="color" style="background-color:#bfe5bf" data-color-hex="#bfe5bf"></a> | |||||
<a class="color" style="background-color:#bfdadc" data-color-hex="#bfdadc"></a> | |||||
<a class="color" style="background-color:#c7def8" data-color-hex="#c7def8"></a> | |||||
<a class="color" style="background-color:#bfd4f2" data-color-hex="#bfd4f2"></a> | |||||
<a class="color" style="background-color:#d4c5f9" data-color-hex="#d4c5f9"></a> | |||||
</div> | |||||
<button class="ui green button">{{.i18n.Tr "repo.issues.new_label"}}</button> | |||||
</div> | |||||
</form> | |||||
{{end}} | |||||
</div> | |||||
<div class="ui divider"></div> | |||||
{{template "repo/issue/alert" .}} | |||||
<div class="ui left"> | |||||
<div class="ui black label">{{.i18n.Tr "repo.issues.label_count" .NumLabels}}</div> | |||||
</div> | |||||
<div class="label list"> | |||||
{{range .Labels}} | |||||
<li class="item"> | |||||
<div class="ui label" style="background-color: {{.Color}}"><i class="octicon octicon-tag"></i> {{.Name}}</div> | |||||
{{if $.IsRepositoryAdmin}} | |||||
<a class="ui right" href="#"><i class="octicon octicon-x"></i> {{$.i18n.Tr "repo.issues.label_delete"}}</a> | |||||
<a class="ui right" href="#"><i class="octicon octicon-pencil"></i> {{$.i18n.Tr "repo.issues.label_edit"}}</a> | |||||
{{end}} | |||||
<a class="ui right open-issues" href="{{$.RepoLink}}/issues?labels={{.ID}}"><i class="octicon octicon-issue-opened"></i> {{$.i18n.Tr "repo.issues.label_open_issues" .NumOpenIssues}}</a> | |||||
</li> | |||||
{{end}} | |||||
</div> | |||||
</div> | |||||
</div> | |||||
{{template "base/footer" .}} |
<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}} | |||||
<div class="ui right floated secondary menu"> | <div class="ui right floated secondary menu"> | ||||
<a class="ui green button" href="{{$.RepoLink}}/issues/new">{{.i18n.Tr "repo.issues.new"}}</a> | <a class="ui green button" href="{{$.RepoLink}}/issues/new">{{.i18n.Tr "repo.issues.new"}}</a> | ||||
</div> | </div> | ||||
{{end}} | |||||
</div> | </div> | ||||
<div class="ui divider"></div> | <div class="ui divider"></div> | ||||
<div class="ui left"> | <div class="ui left"> | ||||
</span> | </span> | ||||
<div class="menu"> | <div class="menu"> | ||||
{{range .Labels}} | {{range .Labels}} | ||||
<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{.Id}}"><span class="label color" style="background-color: {{.Color}}"></span> {{.Name}}</a> | |||||
<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}"><span class="label color" style="background-color: {{.Color}}"></span> {{.Name}}</a> | |||||
{{end}} | {{end}} | ||||
</div> | </div> | ||||
</div> | </div> | ||||
{{range .Issues}} | {{range .Issues}} | ||||
{{ $timeStr:= TimeSince .Created $.Lang }} | {{ $timeStr:= TimeSince .Created $.Lang }} | ||||
<li class="item"> | <li class="item"> | ||||
<div class="ui {{if .IsRead}}black{{else}}green{{end}} label">#{{.Id}}</div> | |||||
<div class="ui {{if .IsRead}}black{{else}}green{{end}} label">#{{.Index}}</div> | |||||
<a class="title" href="{{$.RepoLink}}/issues/{{.Index}}">{{.Name}}</a> | <a class="title" href="{{$.RepoLink}}/issues/{{.Index}}">{{.Name}}</a> | ||||
{{if .NumComments}}<span class="comment ui right"><i class="octicon octicon-comment"></i> {{.NumComments}}</span>{{end}} | {{if .NumComments}}<span class="comment ui right"><i class="octicon octicon-comment"></i> {{.NumComments}}</span>{{end}} | ||||
<p class="desc">{{$.i18n.Tr "repo.issues.opened_by" $timeStr .Poster.Name|Str2html}}</p> | <p class="desc">{{$.i18n.Tr "repo.issues.opened_by" $timeStr .Poster.Name|Str2html}}</p> |
<div class="ui left"> | <div class="ui left"> | ||||
<div class="ui compact menu"> | <div class="ui compact menu"> | ||||
<a class="{{if .PageIsIssueList}}active{{end}} item" href="{{.RepoLink}}/issues">{{.i18n.Tr "repo.issues"}}</a> | <a class="{{if .PageIsIssueList}}active{{end}} item" href="{{.RepoLink}}/issues">{{.i18n.Tr "repo.issues"}}</a> | ||||
<a class="item" href="{{.RepoLink}}/labels">{{.i18n.Tr "repo.labels"}}</a> | |||||
<a class="{{if .PageIsLabels}}active{{end}} item" href="{{.RepoLink}}/labels">{{.i18n.Tr "repo.labels"}}</a> | |||||
<a class="item" href="{{.RepoLink}}/milestones">{{.i18n.Tr "repo.milestones"}}</a> | <a class="item" href="{{.RepoLink}}/milestones">{{.i18n.Tr "repo.milestones"}}</a> | ||||
</div> | </div> | ||||
</div> | </div> |
{{template "repo/nav" .}} | {{template "repo/nav" .}} | ||||
{{template "repo/toolbar" .}} | {{template "repo/toolbar" .}} | ||||
<div id="body" class="container"> | <div id="body" class="container"> | ||||
<div id="issue" data-id="{{.Issue.Id}}"> | |||||
<div id="issue-{{.Issue.Id}}" class="issue-whole issue-is-opening"> | |||||
<div id="issue" data-id="{{.Issue.ID}}"> | |||||
<div id="issue-{{.Issue.ID}}" class="issue-whole issue-is-opening"> | |||||
<div class="issue-wrap col-md-10"> | <div class="issue-wrap col-md-10"> | ||||
<div class="issue-head clearfix"> | <div class="issue-head clearfix"> | ||||
<div class="number pull-right">#{{.Issue.Index}}</div> | <div class="number pull-right">#{{.Issue.Index}}</div> | ||||
<a class="author pull-left" href="{{AppSubUrl}}/{{.Issue.Poster.Name}}"><img class="avatar" src="{{.Issue.Poster.AvatarLink}}" alt="" width="30"/></a> | <a class="author pull-left" href="{{AppSubUrl}}/{{.Issue.Poster.Name}}"><img class="avatar" src="{{.Issue.Poster.AvatarLink}}" alt="" width="30"/></a> | ||||
<h1 class="title pull-left">{{.Issue.Name}}</h1> | <h1 class="title pull-left">{{.Issue.Name}}</h1> | ||||
<input id="issue-edit-title" class="form-control input-lg pull-left hidden" type="text" value="{{.Issue.Name}}" data-ajax-rel="issue-edit-save" data-ajax-val="val" data-ajax-field="title"/> | <input id="issue-edit-title" class="form-control input-lg pull-left hidden" type="text" value="{{.Issue.Name}}" data-ajax-rel="issue-edit-save" data-ajax-val="val" data-ajax-field="title"/> | ||||
<input type="hidden" value="{{.Issue.Id}}" data-ajax-rel="issue-edit-save" data-ajax-val="val" data-ajax-field="issue_id"/> | |||||
<input type="hidden" value="{{.Issue.ID}}" data-ajax-rel="issue-edit-save" data-ajax-val="val" data-ajax-field="issue_id"/> | |||||
<p class="info pull-left"> | <p class="info pull-left"> | ||||
{{if .IsIssueOwner}}<a class="btn btn-default pull-right issue-edit" href="#" id="issue-edit-btn">Edit</a> | {{if .IsIssueOwner}}<a class="btn btn-default pull-right issue-edit" href="#" id="issue-edit-btn">Edit</a> | ||||
<a class="btn btn-danger pull-right issue-edit-cancel hidden" href="#">Cancel</a> | <a class="btn btn-danger pull-right issue-edit-cancel hidden" href="#">Cancel</a> | ||||
<div class="dropdown-menu dropdown-menu-right no"> | <div class="dropdown-menu dropdown-menu-right no"> | ||||
<ul class="list-unstyled"> | <ul class="list-unstyled"> | ||||
{{range .Labels}} | {{range .Labels}} | ||||
<li class="{{if not .IsChecked}}no-{{end}}checked" data-id="{{.Id}}"> | |||||
<li class="{{if not .IsChecked}}no-{{end}}checked" data-id="{{.ID}}"> | |||||
{{if .IsChecked}}<span class="check pull-left"><i class="fa fa-check"></i></span>{{end}} | {{if .IsChecked}}<span class="check pull-left"><i class="fa fa-check"></i></span>{{end}} | ||||
<span class="color" style="background-color: {{.Color}}"></span> | <span class="color" style="background-color: {{.Color}}"></span> | ||||
<span class="name">{{.Name}}</span> | <span class="name">{{.Name}}</span> | ||||
<h4>Labels</h4> | <h4>Labels</h4> | ||||
{{if .Issue.Labels}} | {{if .Issue.Labels}} | ||||
{{range .Issue.Labels}} | {{range .Issue.Labels}} | ||||
<p id="label-{{.Id}}" class="label-item label-white" style="background-color: {{.Color}}"><strong>{{.Name}}</strong></p> | |||||
<p id="label-{{.ID}}" class="label-item label-white" style="background-color: {{.Color}}"><strong>{{.Name}}</strong></p> | |||||
{{end}} | {{end}} | ||||
{{else}} | {{else}} | ||||
<p>None yet</p> | <p>None yet</p> |
{{template "ng/base/head" .}} | |||||
{{template "ng/base/header" .}} | |||||
<div id="repo-wrapper"> | |||||
{{template "repo/header_old" .}} | |||||
<div class="issue-main container repo-wide-wrapper"> | |||||
<ul id="issue-list-nav" class="menu menu-line"> | |||||
<li><a href="#">Issue</a></li> | |||||
<li><a href="#">Pull Request</a></li> | |||||
<li class="current"><a href="#">Labels</a></li> | |||||
<li><a href="#">Milestones</a></li> | |||||
<li class="right" id="label-new"><a href="#"><button id="label-new-btn" class="btn btn-green text-bold">New Label</button></a></li> | |||||
</ul> | |||||
<form id="label-add-form" action="#" class="form clear hidden"> | |||||
<input type="text" class="ipt" name="name" placeholder="label name" id="label-add-name"/> | |||||
<div class="inline down drop label-color-drop"> | |||||
<label for="label-add-color"></label> | |||||
<input class="ipt" name="color" type="text" placeholder="color" id="label-add-color"/> | |||||
<div class="drop-down"> | |||||
<a href="#" class="color" style="background: red"></a> | |||||
<a href="#" class="color" style="background: green"></a> | |||||
</div> | |||||
</div> | |||||
<button class="btn btn-gray right" type="button" id="label-cancel-btn">Cancel</button> | |||||
<button class="btn btn-green right" id="label-add-btn">Create</button> | |||||
</form> | |||||
<div id="issue-list-container"> | |||||
<div id="issue-list-menu"> | |||||
<div class="left"><span class="label label-black" id="labels-num">6</span><strong>Labels</strong></div> | |||||
<div class="clear"></div> | |||||
</div> | |||||
<ul id="label-list" class="list-no-style"> | |||||
<li class="item" id="label-id"> | |||||
<a class="right delete" href="#"><i class="octicon octicon-x"></i>Delete</a> | |||||
<a class="right edit" href="#"><i class="octicon octicon-pencil"></i>Edit</a> | |||||
<a class="right issue-num" href="#"><i class="octicon octicon-issue-opened"></i><strong class="num">12</strong>Issues</a> | |||||
<a class="left label clear" href="#" style="background-color: #0052cc" data-color-hex="#0052cc"><i class="octicon octicon-tag"></i><strong>bug</strong></a> | |||||
</li> | |||||
<li class="item" id="label-id"> | |||||
<a class="right" href="#"><i class="octicon octicon-x"></i>Delete</a> | |||||
<a class="right" href="#"><i class="octicon octicon-pencil"></i>Edit</a> | |||||
<a class="right issue-num" href="#"><i class="octicon octicon-issue-opened"></i><strong class="num">12</strong>Issues</a> | |||||
<a class="left label clear" href="#" style="background-color: red"><i class="octicon octicon-tag"></i><strong>bug</strong></a> | |||||
</li> | |||||
</ul> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div id="label-edit-form-tpl" class="hidden"> | |||||
<li class="item"><form id="label-edit-form" action="#" class="form clear"> | |||||
<input type="text" class="ipt" name="name" placeholder="label name" id="label-edit-name"/> | |||||
<input type="hidden" name="id" value="id"/> | |||||
<div class="inline down drop label-color-drop"> | |||||
<label for="label-add-color"></label> | |||||
<input class="ipt" name="color" type="text" placeholder="color" id="label-edit-color"/> | |||||
<div class="drop-down"> | |||||
<a href="#" class="color" style="background: red"></a> | |||||
<a href="#" class="color" style="background: green"></a> | |||||
</div> | |||||
</div> | |||||
<button class="btn btn-gray right" type="button" id="label-edit-cancel-btn">Cancel</button> | |||||
<button class="btn btn-green right" id="label-edit-btn">Save Changes</button> | |||||
</form></li> | |||||
</div> | |||||
<div id="label-delete-form-tpl" class="hidden"> | |||||
<li class="item"> | |||||
<form id="label-delete-form" action="#"> | |||||
<input type="hidden" name="id" value="id"/> | |||||
<span><strong class="text-red">Are you sure?</strong> Deleting a label will remove it from all issues and pull requests.</span> | |||||
<button class="btn btn-gray right" type="button" id="label-del-cancel-btn">Cancel</button> | |||||
<button class="btn btn-red right" id="label-del-btn">Delete</button> | |||||
</form> | |||||
</li> | |||||
</div> | |||||
{{template "ng/base/footer" .}} |