UI: basic label list

- create new label
pull/197/head
Unknwon 9 years ago
parent 86dbda0b42
commit ac95f6d50f
  1. 1
      .gitignore
  2. 7
      cmd/web.go
  3. 9
      conf/locale/locale_en-US.ini
  4. 1989
      config.codekit
  5. 2
      gogs.go
  6. 10
      models/action.go
  7. 24
      models/issue.go
  8. 2
      models/repo.go
  9. 8
      modules/auth/auth.go
  10. 4
      modules/auth/repo_form.go
  11. 6
      modules/bindata/bindata.go
  12. 1144
      public/css/gogs.min.css
  13. 278
      public/css/jquery.minicolors.css
  14. 19
      public/js/gogs.js
  15. 11
      public/js/libs/jquery.minicolors.min.js
  16. BIN
      public/js/libs/jquery.minicolors.png
  17. 1
      public/js/min/gogs-min.js
  18. 60
      public/less/_repository.less
  19. 108
      routers/repo/issue.go
  20. 2
      templates/.VERSION
  21. 6
      templates/base/head.tmpl
  22. 5
      templates/repo/issue/alert.tmpl
  23. 64
      templates/repo/issue/labels.tmpl
  24. 6
      templates/repo/issue/list.tmpl
  25. 2
      templates/repo/issue/navbar.tmpl
  26. 10
      templates/repo/issue/view.tmpl
  27. 74
      templates/repo/issue2/labels.tmpl

1
.gitignore vendored

@ -29,7 +29,6 @@ profile/
__pycache__
*.pem
output*
config.codekit
.brackets.json
docker/fig.yml
docker/docker/Dockerfile

@ -80,7 +80,7 @@ func checkVersion() {
// Check dependency version.
checkers := []VerChecker{
{"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/csrf", csrf.Version, "0.0.3"},
{"github.com/macaron-contrib/i18n", i18n.Version, "0.0.7"},
@ -442,15 +442,14 @@ func runWeb(ctx *cli.Context) {
m.Group("/:username/:reponame", func() {
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("/labels/", repo.RetrieveLabels, repo.Labels)
m.Get("/milestones", repo.Milestones)
m.Get("/pulls", repo.Pulls)
m.Get("/branches", repo.Branches)
m.Get("/archive/*", repo.Download)
m.Get("/issues2/", repo.Issues2)
m.Get("/pulls2/", repo.PullRequest2)
m.Get("/labels2/", repo.Labels2)
m.Get("/milestone2/", repo.Milestones2)
m.Group("", func() {

@ -159,6 +159,7 @@ AdminEmail = Admin E-mail
require_error = ` cannot be empty.`
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.`
size_error = ` must be size %s.`
min_size_error = ` must contain at least %s characters.`
max_size_error = ` must contain at most %s characters.`
email_error = ` is not a valid e-mail address.`
@ -358,6 +359,8 @@ commits.older = Older
commits.newer = Newer
issues.new = New Issue
issues.new_label = New Label
issues.new_label_placeholder = Label name...
issues.open_tab = %d Open
issues.close_tab = %d Closed
issues.filter_label = Label
@ -369,6 +372,12 @@ issues.filter_type.assigned_to_you = Assigned to you
issues.filter_type.created_by_you = Created by you
issues.filter_type.mentioning_you = Mentioning you
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.next = Next Page

File diff suppressed because it is too large Load Diff

@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting"
)
const APP_VER = "0.6.1.0724 Beta"
const APP_VER = "0.6.2.0724 Beta"
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())

@ -153,7 +153,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
url := fmt.Sprintf("%s/%s/%s/commit/%s", setting.AppSubUrl, repoUserName, repoName, c.Sha1)
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
}
}
@ -202,7 +202,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
if err = UpdateIssue(issue); err != nil {
return err
} else if err = UpdateIssueUserPairsByStatus(issue.Id, issue.IsClosed); err != nil {
} else if err = UpdateIssueUserPairsByStatus(issue.ID, issue.IsClosed); err != nil {
return err
}
@ -211,7 +211,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
}
// 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
}
}
@ -261,7 +261,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
if err = UpdateIssue(issue); err != nil {
return err
} else if err = UpdateIssueUserPairsByStatus(issue.Id, issue.IsClosed); err != nil {
} else if err = UpdateIssueUserPairsByStatus(issue.ID, issue.IsClosed); err != nil {
return err
}
@ -270,7 +270,7 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
}
// 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
}
}

@ -32,7 +32,7 @@ var (
// Issue represents an issue or pull request of repository.
type Issue struct {
Id int64
ID int64 `xorm:"pk autoincr"`
RepoId int64 `xorm:"INDEX"`
Index int64 // Index in one repository.
Name string
@ -100,15 +100,15 @@ func (i *Issue) GetAssignee() (err error) {
}
func (i *Issue) Attachments() []*Attachment {
a, _ := GetAttachmentsForIssue(i.Id)
a, _ := GetAttachmentsForIssue(i.ID)
return a
}
func (i *Issue) AfterDelete() {
_, err := DeleteAttachmentsByIssue(i.Id, true)
_, err := DeleteAttachmentsByIssue(i.ID, true)
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)
}
}
@ -175,7 +175,7 @@ func GetIssueByIndex(rid, index int64) (*Issue, error) {
// GetIssueById returns an issue by ID.
func GetIssueById(id int64) (*Issue, error) {
issue := &Issue{Id: id}
issue := &Issue{ID: id}
has, err := x.Get(issue)
if err != nil {
return nil, err
@ -456,7 +456,7 @@ func GetUserIssueStats(uid int64, filterMode int) *IssueStats {
// UpdateIssue updates information of issue.
func UpdateIssue(issue *Issue) error {
_, err := x.Id(issue.Id).AllCols().Update(issue)
_, err := x.Id(issue.ID).AllCols().Update(issue)
if err != nil {
return err
@ -526,7 +526,7 @@ func UpdateIssueUserPairsByMentions(uids []int64, iid int64) error {
// Label represents a label of repository for issues.
type Label struct {
Id int64
ID int64 `xorm:"pk autoincr"`
RepoId int64 `xorm:"INDEX"`
Name string
Color string `xorm:"VARCHAR(7)"`
@ -553,7 +553,7 @@ func GetLabelById(id int64) (*Label, error) {
return nil, ErrLabelNotExist
}
l := &Label{Id: id}
l := &Label{ID: id}
has, err := x.Get(l)
if err != nil {
return nil, err
@ -572,7 +572,7 @@ func GetLabels(repoId int64) ([]*Label, error) {
// UpdateLabel updates label information.
func UpdateLabel(l *Label) error {
_, err := x.Id(l.Id).AllCols().Update(l)
_, err := x.Id(l.ID).AllCols().Update(l)
return err
}
@ -600,7 +600,7 @@ func DeleteLabel(repoId int64, strId string) error {
for _, issue := range issues {
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()
return err
}
@ -788,7 +788,7 @@ func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) {
}
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()
return err
}
@ -816,7 +816,7 @@ func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) {
}
rawSql := "UPDATE `issue_user` SET milestone_id = ? WHERE issue_id = ?"
if _, err = sess.Exec(rawSql, m.Id, issue.Id); err != nil {
if _, err = sess.Exec(rawSql, m.Id, issue.ID); err != nil {
sess.Rollback()
return err
}

@ -876,7 +876,7 @@ func DeleteRepository(uid, repoID int64, userName string) error {
return err
}
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
}
}

@ -171,12 +171,16 @@ func AssignForm(form interface{}, data map[string]interface{}) {
func getSize(field reflect.StructField, prefix string) string {
for _, rule := range strings.Split(field.Tag.Get("binding"), ";") {
if strings.HasPrefix(rule, prefix) {
return rule[8 : len(rule)-1]
return rule[len(prefix) : len(rule)-1]
}
}
return ""
}
func GetSize(field reflect.StructField) string {
return getSize(field, "Size(")
}
func GetMinSize(field reflect.StructField) string {
return getSize(field, "MinSize(")
}
@ -227,6 +231,8 @@ func validate(errs binding.Errors, data map[string]interface{}, f Form, l macaro
data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_error")
case binding.ERR_ALPHA_DASH_DOT:
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:
data["ErrorMsg"] = trName + l.Tr("form.min_size_error", GetMinSize(field))
case binding.ERR_MAX_SIZE:

@ -134,8 +134,8 @@ func (f *CreateMilestoneForm) Validate(ctx *macaron.Context, errs binding.Errors
// \/ \/ \/ \/
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 {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -32,6 +32,24 @@ function initInstall() {
});
};
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 () {
// Semantic UI modules.
$('.dropdown').dropdown();
@ -46,4 +64,5 @@ $(document).ready(function () {
$('.poping.up').popup();
initInstall();
initRepository();
});

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

@ -1 +0,0 @@
$(document).ready(function(){$(".dropdown").dropdown({transition:"slide up"})});

@ -41,6 +41,42 @@
.navbar {
height: 60px;
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 {
padding: 0 8px;
@ -50,9 +86,10 @@
left: auto!important;
}
.issue.list {
clear: both;
list-style: none;
font-size: 13px;
padding-top: 45px;
padding-top: 15px;
.item {
padding-top: 15px;
padding-bottom: 10px;
@ -79,4 +116,25 @@
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;
}
}
}
}
}

@ -30,6 +30,8 @@ const (
ISSUE_CREATE base.TplName = "repo/issue/create"
ISSUE_VIEW base.TplName = "repo/issue/view"
LABELS base.TplName = "repo/issue/labels"
MILESTONE base.TplName = "repo/issue/milestone"
MILESTONE_NEW base.TplName = "repo/issue/milestone_new"
MILESTONE_EDIT base.TplName = "repo/issue/milestone_edit"
@ -40,6 +42,19 @@ var (
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) {
ctx.Data["Title"] = ctx.Tr("repo.issues")
ctx.Data["PageIsIssueList"] = true
@ -85,17 +100,6 @@ func Issues(ctx *middleware.Context) {
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")
if page <= 1 {
page = 1
@ -107,6 +111,8 @@ func Issues(ctx *middleware.Context) {
ctx.Data["NextPage"] = page + 1
}
selectLabels := ctx.Query("labels")
// Get issues.
issues, err := models.GetIssues(assigneeId, repo.Id, posterId, mid, page,
isShowClosed, selectLabels, ctx.Query("sortType"))
@ -125,24 +131,26 @@ func Issues(ctx *middleware.Context) {
// Get posters.
for i := range issues {
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
}
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 {
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
}
}
@ -257,14 +265,14 @@ func CreateIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) {
if err := models.NewIssue(issue); err != nil {
send(500, nil, err)
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 {
send(500, nil, err)
return
}
if setting.AttachmentEnabled {
uploadFiles(ctx, issue.Id, 0)
uploadFiles(ctx, issue.ID, 0)
}
// Update mentions.
@ -274,7 +282,7 @@ func CreateIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) {
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)
return
}
@ -321,7 +329,7 @@ func CreateIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) {
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)
}
@ -329,7 +337,7 @@ func CreateIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) {
func checkLabels(labels, allLabels []*models.Label) {
for _, l := range labels {
for _, l2 := range allLabels {
if l.Id == l2.Id {
if l.ID == l2.ID {
l2.IsChecked = true
break
}
@ -403,7 +411,7 @@ func ViewIssue(ctx *middleware.Context) {
if ctx.IsSigned {
// 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)
return
}
@ -420,7 +428,7 @@ func ViewIssue(ctx *middleware.Context) {
issue.RenderedContent = string(base.RenderMarkdown([]byte(issue.Content), ctx.Repo.RepoLink))
// Get comments.
comments, err := models.GetIssueComments(issue.Id)
comments, err := models.GetIssueComments(issue.ID)
if err != nil {
ctx.Handle(500, "issue.ViewIssue(GetIssueComments): %v", err)
return
@ -642,7 +650,7 @@ func UpdateAssignee(ctx *middleware.Context) {
aid := com.StrTo(ctx.Query("assigneeid")).MustInt64()
// Not check for invalid assignee id and give responsibility to owners.
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)
return
} else if err = models.UpdateIssue(issue); err != nil {
@ -774,7 +782,7 @@ func Comment(ctx *middleware.Context) {
if err = models.UpdateIssue(issue); err != nil {
send(500, nil, err)
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)
return
}
@ -809,11 +817,11 @@ func Comment(ctx *middleware.Context) {
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)
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)
}
}
@ -825,7 +833,7 @@ func Comment(ctx *middleware.Context) {
if len(content) > 0 || len(ctx.Req.MultipartForm.File["attachments"]) > 0 {
switch ctx.Params(":action") {
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)
return
}
@ -837,13 +845,13 @@ func Comment(ctx *middleware.Context) {
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)
return
}
}
log.Trace("%s Comment created: %d", ctx.Req.RequestURI, issue.Id)
log.Trace("%s Comment created: %d", ctx.Req.RequestURI, issue.ID)
default:
ctx.Handle(404, "issue.Comment", err)
return
@ -851,7 +859,7 @@ func Comment(ctx *middleware.Context) {
}
if comment != nil {
uploadFiles(ctx, issue.Id, comment.Id)
uploadFiles(ctx, issue.ID, comment.Id)
}
// Notify watchers.
@ -899,9 +907,19 @@ func Comment(ctx *middleware.Context) {
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) {
ctx.Data["Title"] = ctx.Tr("repo.labels")
ctx.Data["PageIsLabels"] = true
if ctx.HasError() {
Issues(ctx)
ctx.Flash.Error(ctx.Data["ErrorMsg"].(string))
ctx.Redirect(ctx.Repo.RepoLink + "/labels")
return
}
@ -911,10 +929,10 @@ func NewLabel(ctx *middleware.Context, form auth.CreateLabelForm) {
Color: form.Color,
}
if err := models.NewLabel(l); err != nil {
ctx.Handle(500, "issue.NewLabel(NewLabel)", err)
ctx.Handle(500, "NewLabel", err)
return
}
ctx.Redirect(ctx.Repo.RepoLink + "/issues")
ctx.Redirect(ctx.Repo.RepoLink + "/labels")
}
func UpdateLabel(ctx *middleware.Context, form auth.CreateLabelForm) {
@ -925,7 +943,7 @@ func UpdateLabel(ctx *middleware.Context, form auth.CreateLabelForm) {
}
l := &models.Label{
Id: id,
ID: id,
Name: form.Title,
Color: form.Color,
}
@ -1151,20 +1169,10 @@ func IssueGetAttachment(ctx *middleware.Context) {
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) {
ctx.HTML(200, "repo/pr2/list")
}
func Labels2(ctx *middleware.Context) {
ctx.HTML(200, "repo/issue2/labels")
}
func Milestones2(ctx *middleware.Context) {
ctx.HTML(200, "repo/milestone2/list")
}

@ -1 +1 @@
0.6.1.0724 Beta
0.6.2.0724 Beta

@ -29,6 +29,12 @@
<script src="{{AppSubUrl}}/js/semantic.min.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>
</head>
<body>

@ -0,0 +1,5 @@
{{if .Flash}}
<div class="sixteen wide center aligned centered column">
{{template "base/alert" .}}
</div>
{{end}}

@ -0,0 +1,64 @@
{{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" .}}

@ -4,9 +4,11 @@
<div class="ui middle page grid body">
<div class="navbar">
{{template "repo/issue/navbar" .}}
{{if .IsRepositoryAdmin}}
<div class="ui right floated secondary menu">
<a class="ui green button" href="{{$.RepoLink}}/issues/new">{{.i18n.Tr "repo.issues.new"}}</a>
</div>
{{end}}
</div>
<div class="ui divider"></div>
<div class="ui left">
@ -29,7 +31,7 @@
</span>
<div class="menu">
{{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}}
</div>
</div>
@ -73,7 +75,7 @@
{{range .Issues}}
{{ $timeStr:= TimeSince .Created $.Lang }}
<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>
{{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>

@ -1,7 +1,7 @@
<div class="ui left">
<div class="ui compact menu">
<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>
</div>
</div>

@ -3,15 +3,15 @@
{{template "repo/nav" .}}
{{template "repo/toolbar" .}}
<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-head clearfix">
<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>
<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 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">
{{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>
@ -178,7 +178,7 @@
<div class="dropdown-menu dropdown-menu-right no">
<ul class="list-unstyled">
{{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}}
<span class="color" style="background-color: {{.Color}}"></span>
<span class="name">{{.Name}}</span>
@ -191,7 +191,7 @@
<h4>Labels</h4>
{{if .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}}
{{else}}
<p>None yet</p>

@ -1,74 +0,0 @@
{{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" .}}
Loading…
Cancel
Save