Bladeren bron

UI: create issue with title and content

Unknwon 9 jaren geleden
bovenliggende
commit
590c464c56

+ 2 - 2
cmd/web.go

@@ -419,8 +419,8 @@ func runWeb(ctx *cli.Context) {
 		m.Get("/action/:action", repo.Action)
 
 		m.Group("/issues", func() {
-			m.Get("/new", repo.CreateIssue)
-			m.Post("/new", bindIgnErr(auth.CreateIssueForm{}), repo.CreateIssuePost)
+			m.Combo("/new").Get(repo.NewIssue).
+				Post(bindIgnErr(auth.CreateIssueForm{}), repo.NewIssuePost)
 			m.Post("/:index", bindIgnErr(auth.CreateIssueForm{}), repo.UpdateIssue)
 			m.Post("/:index/label", repo.UpdateIssueLabel)
 			m.Post("/:index/milestone", repo.UpdateIssueMilestone)

+ 1 - 0
conf/locale/locale_en-US.ini

@@ -367,6 +367,7 @@ commits.older = Older
 commits.newer = Newer
 
 issues.new = New Issue
+issues.create = Create Issue
 issues.new_label = New Label
 issues.new_label_placeholder = Label name...
 issues.open_tab = %d Open

+ 20 - 0
config.codekit

@@ -388,6 +388,26 @@
 		"strictMath": 0,
 		"strictUnits": 0
 		},
+	"\/public\/less\/_markdown.less": {
+		"allowInsecureImports": 0,
+		"createSourceMap": 0,
+		"disableJavascript": 0,
+		"fileType": 1,
+		"ieCompatibility": 1,
+		"ignore": 1,
+		"ignoreWasSetByUser": 0,
+		"inputAbbreviatedPath": "\/public\/less\/_markdown.less",
+		"outputAbbreviatedPath": "\/public\/css\/_markdown.css",
+		"outputPathIsOutsideProject": 0,
+		"outputPathIsSetByUser": 0,
+		"outputStyle": 0,
+		"relativeURLS": 0,
+		"shouldRunAutoprefixer": 0,
+		"shouldRunBless": 0,
+		"strictImports": 0,
+		"strictMath": 0,
+		"strictUnits": 0
+		},
 	"\/public\/less\/_octicons.less": {
 		"allowInsecureImports": 0,
 		"createSourceMap": 0,

+ 1 - 1
gogs.go

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

+ 13 - 13
models/issue.go

@@ -38,7 +38,7 @@ type Issue struct {
 	Repo            *Repository `xorm:"-"`
 	PosterID        int64
 	Poster          *User    `xorm:"-"`
-	LabelIds        string   `xorm:"TEXT"`
+	LabelIDs        string   `xorm:"label_ids TEXT"`
 	Labels          []*Label `xorm:"-"`
 	MilestoneID     int64
 	Milestone       *Milestone `xorm:"-"`
@@ -77,11 +77,11 @@ func (i *Issue) GetPoster() (err error) {
 }
 
 func (i *Issue) GetLabels() error {
-	if len(i.LabelIds) < 3 {
+	if len(i.LabelIDs) < 3 {
 		return nil
 	}
 
-	strIds := strings.Split(strings.TrimSuffix(i.LabelIds[1:], "|"), "|$")
+	strIds := strings.Split(strings.TrimSuffix(i.LabelIDs[1:], "|"), "|$")
 	i.Labels = make([]*Label, 0, len(strIds))
 	for _, strId := range strIds {
 		id := com.StrTo(strId).MustInt64()
@@ -134,7 +134,7 @@ func NewIssue(issue *Issue) (err error) {
 
 	if _, err = sess.Insert(issue); err != nil {
 		return err
-	} else if _, err = sess.Exec("UPDATE `repository` SET num_issues = num_issues + 1 WHERE id = ?", issue.RepoID); err != nil {
+	} else if _, err = sess.Exec("UPDATE `repository` SET num_issues=num_issues+1 WHERE id=?", issue.RepoID); err != nil {
 		return err
 	}
 
@@ -296,14 +296,14 @@ type IssueUser struct {
 
 // FIXME: organization
 // NewIssueUserPairs adds new issue-user pairs for new issue of repository.
-func NewIssueUserPairs(repo *Repository, issueID, orgID, posterID, assigneeID int64) error {
+func NewIssueUserPairs(repo *Repository, issue *Issue) error {
 	users, err := repo.GetCollaborators()
 	if err != nil {
 		return err
 	}
 
 	iu := &IssueUser{
-		IssueId: issueID,
+		IssueId: issue.ID,
 		RepoId:  repo.ID,
 	}
 
@@ -311,30 +311,30 @@ func NewIssueUserPairs(repo *Repository, issueID, orgID, posterID, assigneeID in
 	for _, u := range users {
 		iu.Id = 0
 		iu.Uid = u.Id
-		iu.IsPoster = iu.Uid == posterID
+		iu.IsPoster = iu.Uid == issue.PosterID
 		if isNeedAddPoster && iu.IsPoster {
 			isNeedAddPoster = false
 		}
-		iu.IsAssigned = iu.Uid == assigneeID
+		iu.IsAssigned = iu.Uid == issue.AssigneeID
 		if _, err = x.Insert(iu); err != nil {
 			return err
 		}
 	}
 	if isNeedAddPoster {
 		iu.Id = 0
-		iu.Uid = posterID
+		iu.Uid = issue.PosterID
 		iu.IsPoster = true
-		iu.IsAssigned = iu.Uid == assigneeID
+		iu.IsAssigned = iu.Uid == issue.AssigneeID
 		if _, err = x.Insert(iu); err != nil {
 			return err
 		}
 	}
 
 	// Add owner's as well.
-	if repo.OwnerID != posterID {
+	if repo.OwnerID != issue.PosterID {
 		iu.Id = 0
 		iu.Uid = repo.OwnerID
-		iu.IsAssigned = iu.Uid == assigneeID
+		iu.IsAssigned = iu.Uid == issue.AssigneeID
 		if _, err = x.Insert(iu); err != nil {
 			return err
 		}
@@ -621,7 +621,7 @@ func DeleteLabel(repoID, labelID int64) error {
 	}
 
 	for _, issue := range issues {
-		issue.LabelIds = strings.Replace(issue.LabelIds, "$"+com.ToStr(labelID)+"|", "", -1)
+		issue.LabelIDs = strings.Replace(issue.LabelIDs, "$"+com.ToStr(labelID)+"|", "", -1)
 		if _, err = sess.Id(issue.ID).AllCols().Update(issue); err != nil {
 			return err
 		}

+ 3 - 3
modules/auth/apiv1/miscellaneous.go

@@ -14,9 +14,9 @@ import (
 )
 
 type MarkdownForm struct {
-	Text    string `form:"text"`
-	Mode    string `form:"mode"`
-	Context string `form:"context"`
+	Text    string
+	Mode    string
+	Context string
 }
 
 func (f *MarkdownForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {

+ 5 - 5
modules/auth/repo_form.go

@@ -98,11 +98,11 @@ func (f *NewSlackHookForm) Validate(ctx *macaron.Context, errs binding.Errors) b
 //          \/     \/            \/
 
 type CreateIssueForm struct {
-	IssueName   string `form:"title" binding:"Required;MaxSize(255)"`
-	MilestoneId int64  `form:"milestoneid"`
-	AssigneeId  int64  `form:"assigneeid"`
-	Labels      string `form:"labels"`
-	Content     string `form:"content"`
+	Title       string  `binding:"Required;MaxSize(255)"`
+	LabelIDs    []int64 `form:"label_id"`
+	MilestoneID int64
+	AssigneeID  int64
+	Content     string
 }
 
 func (f *CreateIssueForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {

File diff suppressed because it is too large
+ 0 - 0
modules/bindata/bindata.go


File diff suppressed because it is too large
+ 0 - 0
public/css/gogs.min.css


+ 20 - 0
public/js/gogs.js

@@ -123,6 +123,26 @@ $(document).ready(function () {
     });
     $('.poping.up').popup();
 
+    // Comment form
+    $('.comment.form .tabular.menu .item').tab();
+    $('.comment.form .tabular.menu .item[data-tab="preview"]').click(function () {
+        var $this = $(this);
+        console.log($('.comment.form .tab.segment[data-tab="write"] textarea').val())
+        console.log($('.comment.form .tab.segment[data-tab="preview"]').html())
+        $.post($this.data('url'), {
+                "_csrf": csrf,
+                "mode": "gfm",
+                "context": $this.data('context'),
+                "text": $('.comment.form .tab.segment[data-tab="write"] textarea').val()
+            },
+            function (data) {
+                console.log(data)
+                $('.comment.form .tab.segment[data-tab="preview"]').html(data);
+            }
+        )
+        ;
+    })
+
     // Helpers.
     $('.delete-button').click(function () {
         var $this = $(this);

+ 594 - 0
public/less/_markdown.less

@@ -0,0 +1,594 @@
+.markdown {
+  overflow:hidden;
+  font-family:"Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
+  font-size:16px;
+  line-height:1.6;
+  word-wrap:break-word;
+
+  >*:first-child {
+    margin-top:0 !important;
+  }
+
+  >*:last-child {
+    margin-bottom:0 !important;
+  }
+
+  a:not([href]) {
+    color:inherit;
+    text-decoration:none;
+  }
+
+  .absent {
+    color:#c00;
+  }
+
+  .anchor {
+    position:absolute;
+    top:0;
+    left:0;
+    display:block;
+    padding-right:6px;
+    padding-left:30px;
+    margin-left:-30px;
+  }
+
+  .anchor:focus {
+    outline:none;
+  }
+
+  h1,
+  h2,
+  h3,
+  h4,
+  h5,
+  h6 {
+    position:relative;
+    margin-top:1em;
+    margin-bottom:16px;
+    font-weight:bold;
+    line-height:1.4;
+  }
+
+  h1 .octicon-link,
+  h2 .octicon-link,
+  h3 .octicon-link,
+  h4 .octicon-link,
+  h5 .octicon-link,
+  h6 .octicon-link {
+    display:none;
+    color:#000;
+    vertical-align:middle;
+  }
+
+  h1:hover .anchor,
+  h2:hover .anchor,
+  h3:hover .anchor,
+  h4:hover .anchor,
+  h5:hover .anchor,
+  h6:hover .anchor {
+    padding-left:8px;
+    margin-left:-30px;
+    text-decoration:none;
+  }
+
+  h1:hover .anchor .octicon-link,
+  h2:hover .anchor .octicon-link,
+  h3:hover .anchor .octicon-link,
+  h4:hover .anchor .octicon-link,
+  h5:hover .anchor .octicon-link,
+  h6:hover .anchor .octicon-link {
+    display:inline-block;
+  }
+
+  h1 tt,
+  h1 code,
+  h2 tt,
+  h2 code,
+  h3 tt,
+  h3 code,
+  h4 tt,
+  h4 code,
+  h5 tt,
+  h5 code,
+  h6 tt,
+  h6 code {
+    font-size:inherit;
+  }
+
+  h1 {
+    padding-bottom:0.3em;
+    font-size:2.25em;
+    line-height:1.2;
+    border-bottom:1px solid #eee;
+  }
+
+  h1 .anchor {
+    line-height:1;
+  }
+
+  h2 {
+    padding-bottom:0.3em;
+    font-size:1.75em;
+    line-height:1.225;
+    border-bottom:1px solid #eee;
+  }
+
+  h2 .anchor {
+    line-height:1;
+  }
+
+  h3 {
+    font-size:1.5em;
+    line-height:1.43;
+  }
+
+  h3 .anchor {
+    line-height:1.2;
+  }
+
+  h4 {
+    font-size:1.25em;
+  }
+
+  h4 .anchor {
+    line-height:1.2;
+  }
+
+  h5 {
+    font-size:1em;
+  }
+
+  h5 .anchor {
+    line-height:1.1;
+  }
+
+  h6 {
+    font-size:1em;color:#777;
+  }
+
+  h6 .anchor {
+    line-height:1.1;
+  }
+
+  p,
+  blockquote,
+  ul,
+  ol,
+  dl,
+  table,
+  pre {
+    margin-top:0;
+    margin-bottom:16px;
+  }
+
+  hr {
+    height:4px;
+    padding:0;
+    margin:16px 0;
+    background-color:#e7e7e7;
+    border:0 none;
+  }
+
+  ul,
+  ol {
+    padding-left:2em;
+  }
+
+  ul.no-list,
+  ol.no-list {
+    padding:0;
+    list-style-type:none;
+  }
+
+  ul ul,
+  ul ol,
+  ol ol,
+  ol ul {
+    margin-top:0;
+    margin-bottom:0;
+  }
+
+  ol ol,
+  ul ol {
+    list-style-type: lower-roman;
+  }
+
+  li>p {
+    margin-top:16px;
+  }
+
+  dl {
+    padding:0;
+  }
+
+  dl dt {
+    padding:0;
+    margin-top:16px;
+    font-size:1em;
+    font-style:italic;
+    font-weight:bold;
+  }
+
+  dl dd {
+    padding:0 16px;
+    margin-bottom:16px;
+  }
+
+  blockquote {
+    padding:0 15px;
+    color:#777;
+    border-left:4px solid #ddd;
+  }
+
+  blockquote>:first-child {
+    margin-top:0;
+  }
+
+  blockquote>:last-child {
+    margin-bottom:0;
+  }
+
+  table {
+    display:block;
+    width:100%;
+    overflow:auto;
+    word-break:normal;
+    word-break:keep-all;
+  }
+
+  table th {
+    font-weight:bold;
+  }
+
+  table th,
+  table td {
+    padding:6px 13px !important;
+    border:1px solid #ddd;
+  }
+
+  table tr {
+    background-color:#fff;
+    border-top:1px solid #ccc;
+  }
+
+  table tr:nth-child(2n) {
+    background-color:#f8f8f8;
+  }
+
+  img {
+    max-width:100%;
+    box-sizing:border-box;
+  }
+
+  .emoji {
+    max-width:none;
+  }
+
+  span.frame {
+    display:block;
+    overflow:hidden;
+  }
+
+  span.frame>span {
+    display:block;
+    float:left;
+    width:auto;
+    padding:7px;
+    margin:13px 0 0;
+    overflow:hidden;
+    border:1px solid #ddd;
+  }
+
+  span.frame span img {
+    display:block;
+    float:left;
+  }
+
+  span.frame span span {
+    display:block;
+    padding:5px 0 0;
+    clear:both;
+    color:#333;
+  }
+
+  span.align-center {
+    display:block;
+    overflow:hidden;
+    clear:both;
+  }
+
+  span.align-center>span {
+    display:block;
+    margin:13px auto 0;
+    overflow:hidden;
+    text-align:center;
+  }
+
+  span.align-center span img {
+    margin:0 auto;
+    text-align:center;
+  }
+
+  span.align-right {
+    display:block;
+    overflow:hidden;
+    clear:both;
+  }
+
+  span.align-right>span {
+    display:block;
+    margin:13px 0 0;
+    overflow:hidden;
+    text-align:right;
+  }
+
+  span.align-right span img {
+    margin:0;
+    text-align:right;
+  }
+
+  span.float-left {
+    display:block;
+    float:left;
+    margin-right:13px;
+    overflow:hidden;
+  }
+
+  span.float-left span {
+    margin:13px 0 0;
+  }
+
+  span.float-right {
+    display:block;
+    float:right;
+    margin-left:13px;
+    overflow:hidden;
+  }
+
+  span.float-right>span {
+    display:block;
+    margin:13px auto 0;
+    overflow:hidden;
+    text-align:right;
+  }
+
+  code,
+  tt {
+    padding:0;
+    padding-top:0.2em;
+    padding-bottom:0.2em;
+    margin:0;
+    font-size:85%;
+    background-color:rgba(0,0,0,0.04);
+    border-radius:3px;
+  }
+
+  code:before,
+  code:after,
+  tt:before,
+  tt:after {
+    letter-spacing:-0.2em;
+    content:"\00a0";
+  }
+
+  code br,
+  tt br {
+    display:none;
+  }
+
+  del code {
+    text-decoration:inherit;
+  }
+
+  pre>code {
+    padding:0;
+    margin:0;
+    font-size:100%;
+    word-break:normal;
+    white-space:pre;
+    background:transparent;
+    border:0;
+  }
+
+  .highlight {
+    margin-bottom:16px;
+  }
+
+  .highlight pre,
+  pre {
+    padding:16px;
+    overflow:auto;
+    font-size:85%;
+    line-height:1.45;
+    background-color:#f7f7f7;
+    border-radius:3px;
+  }
+
+  .highlight pre {
+    margin-bottom:0;
+    word-break:normal;
+  }
+
+  pre {
+    word-wrap:normal;
+  }
+
+  pre code,
+  pre tt {
+    display:inline;
+    max-width:initial;
+    padding:0;
+    margin:0;
+    overflow:initial;
+    line-height:inherit;
+    word-wrap:normal;
+    background-color:transparent;
+    border:0;
+  }
+
+  pre code:before,
+  pre code:after,
+  pre tt:before,
+  pre tt:after {
+    content:normal;
+  }
+
+  kbd {
+    display:inline-block;
+    padding:3px 5px;
+    font-size:11px;
+    line-height:10px;
+    color:#555;
+    vertical-align:middle;
+    background-color:#fcfcfc;
+    border:solid 1px #ccc;
+    border-bottom-color:#bbb;
+    border-radius:3px;
+    box-shadow:inset 0 -1px 0 #bbb;
+  }
+
+  .csv-data td,
+  .csv-data th {
+    padding:5px;
+    overflow:hidden;
+    font-size:12px;
+    line-height:1;
+    text-align:left;
+    white-space:nowrap;
+  }
+
+  .csv-data .blob-num {
+    padding:10px 8px 9px;
+    text-align:right;
+    background:#fff;border:0;
+  }
+
+  .csv-data tr {
+    border-top:0;
+  }
+
+  .csv-data th {
+    font-weight:bold;
+    background:#f8f8f8;border-top:0;
+  }
+
+}
+
+/* Author: jmblog */
+
+/* Project: https://github.com/jmblog/color-themes-for-google-code-prettify */
+
+/* GitHub Theme */
+
+/* Pretty printing styles. Used with prettify.js. */
+
+/* SPAN elements with the classes below are added by prettyprint. */
+
+/* plain text */
+
+.pln {
+    color: #333333;
+}
+@media screen {
+    /* string content */
+    .str {
+        color: #dd1144;
+    }
+    /* a keyword */
+    .kwd {
+        color: #333333;
+    }
+    /* a comment */
+    .com {
+        color: #999988;
+        font-style: italic;
+    }
+    /* a type name */
+    .typ {
+        color: #445588;
+    }
+    /* a literal value */
+    .lit {
+        color: #445588;
+    }
+    /* punctuation */
+    .pun {
+        color: #333333;
+    }
+    /* lisp open bracket */
+    .opn {
+        color: #333333;
+    }
+    /* lisp close bracket */
+    .clo {
+        color: #333333;
+    }
+    /* a markup tag name */
+    .tag {
+        color: navy;
+    }
+    /* a markup attribute name */
+    .atn {
+        color: teal;
+    }
+    /* a markup attribute value */
+    .atv {
+        color: #dd1144;
+    }
+    /* a declaration */
+    .dec {
+        color: #333333;
+    }
+    /* a variable name */
+    .var {
+        color: teal;
+    }
+    /* a function name */
+    .fun {
+        color: #990000;
+    }
+}
+/* Use higher contrast and text-weight for printable form. */
+
+@media print,
+projection {
+    .str {
+        color: #006600;
+    }
+    .kwd {
+        color: #006;
+        font-weight: bold;
+    }
+    .com {
+        color: #600;
+        font-style: italic;
+    }
+    .typ {
+        color: #404;
+        font-weight: bold;
+    }
+    .lit {
+        color: #004444;
+    }
+    .pun,
+    .opn,
+    .clo {
+        color: #444400;
+    }
+    .tag {
+        color: #006;
+        font-weight: bold;
+    }
+    .atn {
+        color: #440044;
+    }
+    .atv {
+        color: #006600;
+    }
+}
+/* Specify class=linenums on a pre to get line numbering */
+
+ol.linenums {
+    margin-top: 0;
+    margin-bottom: 0;
+}

+ 27 - 0
public/less/_repository.less

@@ -105,6 +105,7 @@
 	.page.buttons {
 		padding-top: 15px;
 	}
+
 	.issue.list {
 		clear: both;
 		list-style: none;
@@ -138,6 +139,32 @@
 			}
 		}
 	}
+	&.new.issue {
+		.comment.form {
+			.metas {
+				min-width: 220px;
+			}
+		}
+	}
+	.comment.form {
+		.ui.comments {
+			margin-top: -12px;
+			max-width: 750px!important;
+		}
+		.content {
+			.field:first-child {
+				clear: none;
+			}
+			.tab.segment {
+				border: none;
+		    padding: 0;
+		    padding-top: 10px;
+			}
+			textarea {
+				height: 200px;
+			}
+		}
+	}
 
 	.label.list {
 		clear: both;

+ 1 - 0
public/less/gogs.less

@@ -1,5 +1,6 @@
 @import "_octicons";
 @import "_base";
+@import "_markdown";
 @import "_home";
 @import "_install";
 @import "_form";

+ 184 - 153
routers/repo/issue.go

@@ -27,9 +27,9 @@ import (
 )
 
 const (
-	ISSUES       base.TplName = "repo/issue/list"
-	ISSUE_CREATE base.TplName = "repo/issue/create"
-	ISSUE_VIEW   base.TplName = "repo/issue/view"
+	ISSUES     base.TplName = "repo/issue/list"
+	ISSUE_NEW  base.TplName = "repo/issue/new"
+	ISSUE_VIEW base.TplName = "repo/issue/view"
 
 	LABELS base.TplName = "repo/issue/labels"
 
@@ -174,167 +174,198 @@ func Issues(ctx *middleware.Context) {
 	ctx.HTML(200, ISSUES)
 }
 
-func CreateIssue(ctx *middleware.Context) {
-	ctx.Data["Title"] = "Create issue"
-	ctx.Data["IsRepoToolbarIssues"] = true
-	ctx.Data["IsRepoToolbarIssuesList"] = false
-	ctx.Data["AttachmentsEnabled"] = setting.AttachmentEnabled
-
-	var (
-		repo = ctx.Repo.Repository
-		err  error
-	)
-	// Get all milestones.
-	ctx.Data["OpenMilestones"], err = models.GetMilestones(repo.ID, -1, false)
-	if err != nil {
-		ctx.Handle(500, "GetMilestones.1: %v", err)
-		return
-	}
-	ctx.Data["ClosedMilestones"], err = models.GetMilestones(repo.ID, -1, true)
-	if err != nil {
-		ctx.Handle(500, "GetMilestones.2: %v", err)
-		return
-	}
-
-	us, err := repo.GetCollaborators()
-	if err != nil {
-		ctx.Handle(500, "GetCollaborators", err)
-		return
-	}
-
-	ctx.Data["AllowedTypes"] = setting.AttachmentAllowedTypes
-	ctx.Data["Collaborators"] = us
-
-	ctx.HTML(200, ISSUE_CREATE)
+func NewIssue(ctx *middleware.Context) {
+	ctx.Data["Title"] = ctx.Tr("repo.issues.new")
+	ctx.Data["PageIsIssueList"] = true
+	ctx.Data["IsAttachmentEnabled"] = setting.AttachmentEnabled
+	ctx.Data["AttachmentAllowedTypes"] = setting.AttachmentAllowedTypes
+
+	// var (
+	// 	repo = ctx.Repo.Repository
+	// 	err  error
+	// )
+	// // Get all milestones.
+	// ctx.Data["OpenMilestones"], err = models.GetMilestones(repo.ID, -1, false)
+	// if err != nil {
+	// 	ctx.Handle(500, "GetMilestones.1: %v", err)
+	// 	return
+	// }
+	// ctx.Data["ClosedMilestones"], err = models.GetMilestones(repo.ID, -1, true)
+	// if err != nil {
+	// 	ctx.Handle(500, "GetMilestones.2: %v", err)
+	// 	return
+	// }
+
+	// us, err := repo.GetCollaborators()
+	// if err != nil {
+	// 	ctx.Handle(500, "GetCollaborators", err)
+	// 	return
+	// }
+
+	// ctx.Data["Collaborators"] = us
+
+	ctx.HTML(200, ISSUE_NEW)
 }
 
-func CreateIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) {
-	send := func(status int, data interface{}, err error) {
-		if err != nil {
-			log.Error(4, "issue.CreateIssuePost(?): %s", err)
-
-			ctx.JSON(status, map[string]interface{}{
-				"ok":     false,
-				"status": status,
-				"error":  err.Error(),
-			})
-		} else {
-			ctx.JSON(status, map[string]interface{}{
-				"ok":     true,
-				"status": status,
-				"data":   data,
-			})
-		}
-	}
-
-	var err error
-	// Get all milestones.
-	_, err = models.GetMilestones(ctx.Repo.Repository.ID, -1, false)
-	if err != nil {
-		send(500, nil, err)
-		return
-	}
-	_, err = models.GetMilestones(ctx.Repo.Repository.ID, -1, true)
-	if err != nil {
-		send(500, nil, err)
-		return
-	}
-
-	_, err = ctx.Repo.Repository.GetCollaborators()
-	if err != nil {
-		send(500, nil, err)
-		return
-	}
+func NewIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) {
+	ctx.Data["Title"] = ctx.Tr("repo.issues.new")
+	ctx.Data["PageIsIssueList"] = true
+	ctx.Data["IsAttachmentEnabled"] = setting.AttachmentEnabled
+	ctx.Data["AttachmentAllowedTypes"] = setting.AttachmentAllowedTypes
 
 	if ctx.HasError() {
-		send(400, nil, errors.New(ctx.Flash.ErrorMsg))
+		ctx.HTML(200, ISSUE_NEW)
 		return
 	}
 
-	// Only collaborators can assign.
-	if !ctx.Repo.IsOwner() {
-		form.AssigneeId = 0
-	}
 	issue := &models.Issue{
-		RepoID:      ctx.Repo.Repository.ID,
-		Index:       int64(ctx.Repo.Repository.NumIssues) + 1,
-		Name:        form.IssueName,
-		PosterID:    ctx.User.Id,
-		MilestoneID: form.MilestoneId,
-		AssigneeID:  form.AssigneeId,
-		LabelIds:    form.Labels,
-		Content:     form.Content,
+		RepoID:   ctx.Repo.Repository.ID,
+		Index:    int64(ctx.Repo.Repository.NumIssues) + 1,
+		Name:     form.Title,
+		PosterID: ctx.User.Id,
+		// MilestoneID: form.MilestoneID,
+		// AssigneeID:  form.AssigneeID,
+		// LabelIDs:    "$" + strings.Join(form.LabelIDs, "|$") + "|",
+		Content: form.Content,
 	}
 	if err := models.NewIssue(issue); err != nil {
-		send(500, nil, err)
+		ctx.Handle(500, "NewIssue", err)
 		return
-	} 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)
+	} else if err := models.NewIssueUserPairs(ctx.Repo.Repository, issue); err != nil {
+		ctx.Handle(500, "NewIssue", err)
 		return
 	}
 
-	if setting.AttachmentEnabled {
-		uploadFiles(ctx, issue.ID, 0)
-	}
-
-	// Update mentions.
-	ms := base.MentionPattern.FindAllString(issue.Content, -1)
-	if len(ms) > 0 {
-		for i := range ms {
-			ms[i] = ms[i][1:]
-		}
-
-		if err := models.UpdateMentions(ms, issue.ID); err != nil {
-			send(500, nil, err)
-			return
-		}
-	}
-
-	act := &models.Action{
-		ActUserID:    ctx.User.Id,
-		ActUserName:  ctx.User.Name,
-		ActEmail:     ctx.User.Email,
-		OpType:       models.CREATE_ISSUE,
-		Content:      fmt.Sprintf("%d|%s", issue.Index, issue.Name),
-		RepoID:       ctx.Repo.Repository.ID,
-		RepoUserName: ctx.Repo.Owner.Name,
-		RepoName:     ctx.Repo.Repository.Name,
-		RefName:      ctx.Repo.BranchName,
-		IsPrivate:    ctx.Repo.Repository.IsPrivate,
-	}
-	// Notify watchers.
-	if err := models.NotifyWatchers(act); err != nil {
-		send(500, nil, err)
-		return
-	}
-
-	// Mail watchers and mentions.
-	if setting.Service.EnableNotifyMail {
-		tos, err := mailer.SendIssueNotifyMail(ctx.User, ctx.Repo.Owner, ctx.Repo.Repository, issue)
-		if err != nil {
-			send(500, nil, err)
-			return
-		}
-
-		tos = append(tos, ctx.User.LowerName)
-		newTos := make([]string, 0, len(ms))
-		for _, m := range ms {
-			if com.IsSliceContainsStr(tos, m) {
-				continue
-			}
-
-			newTos = append(newTos, m)
-		}
-		if err = mailer.SendIssueMentionMail(ctx.Render, ctx.User, ctx.Repo.Owner,
-			ctx.Repo.Repository, issue, models.GetUserEmailsByNames(newTos)); err != nil {
-			send(500, nil, err)
-			return
-		}
-	}
-	log.Trace("%d Issue created: %d", ctx.Repo.Repository.ID, issue.ID)
+	ctx.Redirect(ctx.Repo.RepoLink + "/issues/" + com.ToStr(issue.Index))
+}
 
-	send(200, fmt.Sprintf("%s/%s/%s/issues/%d", setting.AppSubUrl, ctx.Params(":username"), ctx.Params(":reponame"), issue.Index), nil)
+func CreateIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) {
+	// send := func(status int, data interface{}, err error) {
+	// 	if err != nil {
+	// 		log.Error(4, "issue.CreateIssuePost(?): %s", err)
+
+	// 		ctx.JSON(status, map[string]interface{}{
+	// 			"ok":     false,
+	// 			"status": status,
+	// 			"error":  err.Error(),
+	// 		})
+	// 	} else {
+	// 		ctx.JSON(status, map[string]interface{}{
+	// 			"ok":     true,
+	// 			"status": status,
+	// 			"data":   data,
+	// 		})
+	// 	}
+	// }
+
+	// var err error
+	// // Get all milestones.
+	// _, err = models.GetMilestones(ctx.Repo.Repository.ID, -1, false)
+	// if err != nil {
+	// 	send(500, nil, err)
+	// 	return
+	// }
+	// _, err = models.GetMilestones(ctx.Repo.Repository.ID, -1, true)
+	// if err != nil {
+	// 	send(500, nil, err)
+	// 	return
+	// }
+
+	// _, err = ctx.Repo.Repository.GetCollaborators()
+	// if err != nil {
+	// 	send(500, nil, err)
+	// 	return
+	// }
+
+	// if ctx.HasError() {
+	// 	send(400, nil, errors.New(ctx.Flash.ErrorMsg))
+	// 	return
+	// }
+
+	// // Only collaborators can assign.
+	// if !ctx.Repo.IsOwner() {
+	// 	form.AssigneeId = 0
+	// }
+	// issue := &models.Issue{
+	// 	RepoID:      ctx.Repo.Repository.ID,
+	// 	Index:       int64(ctx.Repo.Repository.NumIssues) + 1,
+	// 	Name:        form.IssueName,
+	// 	PosterID:    ctx.User.Id,
+	// 	MilestoneID: form.MilestoneId,
+	// 	AssigneeID:  form.AssigneeId,
+	// 	LabelIds:    form.Labels,
+	// 	Content:     form.Content,
+	// }
+	// 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,
+	// 	ctx.User.Id, form.AssigneeId); err != nil {
+	// 	send(500, nil, err)
+	// 	return
+	// }
+
+	// if setting.AttachmentEnabled {
+	// 	uploadFiles(ctx, issue.ID, 0)
+	// }
+
+	// // Update mentions.
+	// ms := base.MentionPattern.FindAllString(issue.Content, -1)
+	// if len(ms) > 0 {
+	// 	for i := range ms {
+	// 		ms[i] = ms[i][1:]
+	// 	}
+
+	// 	if err := models.UpdateMentions(ms, issue.ID); err != nil {
+	// 		send(500, nil, err)
+	// 		return
+	// 	}
+	// }
+
+	// act := &models.Action{
+	// 	ActUserID:    ctx.User.Id,
+	// 	ActUserName:  ctx.User.Name,
+	// 	ActEmail:     ctx.User.Email,
+	// 	OpType:       models.CREATE_ISSUE,
+	// 	Content:      fmt.Sprintf("%d|%s", issue.Index, issue.Name),
+	// 	RepoID:       ctx.Repo.Repository.ID,
+	// 	RepoUserName: ctx.Repo.Owner.Name,
+	// 	RepoName:     ctx.Repo.Repository.Name,
+	// 	RefName:      ctx.Repo.BranchName,
+	// 	IsPrivate:    ctx.Repo.Repository.IsPrivate,
+	// }
+	// // Notify watchers.
+	// if err := models.NotifyWatchers(act); err != nil {
+	// 	send(500, nil, err)
+	// 	return
+	// }
+
+	// // Mail watchers and mentions.
+	// if setting.Service.EnableNotifyMail {
+	// 	tos, err := mailer.SendIssueNotifyMail(ctx.User, ctx.Repo.Owner, ctx.Repo.Repository, issue)
+	// 	if err != nil {
+	// 		send(500, nil, err)
+	// 		return
+	// 	}
+
+	// 	tos = append(tos, ctx.User.LowerName)
+	// 	newTos := make([]string, 0, len(ms))
+	// 	for _, m := range ms {
+	// 		if com.IsSliceContainsStr(tos, m) {
+	// 			continue
+	// 		}
+
+	// 		newTos = append(newTos, m)
+	// 	}
+	// 	if err = mailer.SendIssueMentionMail(ctx.Render, ctx.User, ctx.Repo.Owner,
+	// 		ctx.Repo.Repository, issue, models.GetUserEmailsByNames(newTos)); err != nil {
+	// 		send(500, nil, err)
+	// 		return
+	// 	}
+	// }
+	// 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)
 }
 
 func checkLabels(labels, allLabels []*models.Label) {
@@ -484,7 +515,7 @@ func UpdateIssue(ctx *middleware.Context, form auth.CreateIssueForm) {
 		return
 	}
 
-	issue.Name = form.IssueName
+	issue.Name = form.Title
 	//issue.MilestoneId = form.MilestoneId
 	//issue.AssigneeId = form.AssigneeId
 	//issue.LabelIds = form.Labels
@@ -540,16 +571,16 @@ func UpdateIssueLabel(ctx *middleware.Context) {
 		return
 	}
 
-	isHad := strings.Contains(issue.LabelIds, "$"+labelStrId+"|")
+	isHad := strings.Contains(issue.LabelIDs, "$"+labelStrId+"|")
 	isNeedUpdate := false
 	if isAttach {
 		if !isHad {
-			issue.LabelIds += "$" + labelStrId + "|"
+			issue.LabelIDs += "$" + labelStrId + "|"
 			isNeedUpdate = true
 		}
 	} else {
 		if isHad {
-			issue.LabelIds = strings.Replace(issue.LabelIds, "$"+labelStrId+"|", "", -1)
+			issue.LabelIDs = strings.Replace(issue.LabelIDs, "$"+labelStrId+"|", "", -1)
 			isNeedUpdate = true
 		}
 	}

+ 1 - 1
templates/.VERSION

@@ -1 +1 @@
-0.6.4.0808 Beta
+0.6.4.0809 Beta

+ 14 - 0
templates/repo/issue/new.tmpl

@@ -0,0 +1,14 @@
+{{template "base/head" .}}
+<div class="repository new issue">
+	{{template "repo/header" .}}
+	<div class="ui middle page grid body">
+		<div class="navbar">
+			{{template "repo/issue/navbar" .}}
+		</div>
+		<div class="ui divider"></div>
+		<div class="sixteen wide column page grid">
+			{{template "repo/issue/new_form" .}}
+		</div>
+	</div>
+</div>
+{{template "base/footer" .}}

+ 88 - 0
templates/repo/issue/new_form.tmpl

@@ -0,0 +1,88 @@
+<form class="ui comment form grid" action="{{.Link}}" method="post">
+  {{.CsrfTokenHtml}}
+  {{if .Flash}}
+	<div class="sixteen wide column">
+  	{{template "base/alert" .}}
+  </div>
+  {{end}}
+  <div class="twelve wide column">
+		<div class="ui comments">
+		  <div class="comment">
+		    <a class="avatar">
+		      <img src="{{.SignedUser.AvatarLink}}">
+		    </a>
+		    <div class="ui segment content">
+		      <div class="field">
+		      	<input name="title" placeholder="{{.i18n.Tr "repo.milestones.title"}}" value="{{.title}}" autofocus required>
+		      </div>
+		      <div class="field">
+			      <div class="ui top attached tabular menu">
+			          <a class="active item" data-tab="write">{{.i18n.Tr "repo.release.write"}}</a>
+			          <a class="item" data-tab="preview" data-url="/api/v1/markdown" data-context="{{.RepoLink}}">{{.i18n.Tr "repo.release.preview"}}</a>
+			      </div>
+			      <div class="ui bottom attached active tab segment" data-tab="write">
+		          <textarea name="content"></textarea>
+		        </div>
+			      <div class="ui bottom attached tab segment markdown" data-tab="preview">
+			         {{.i18n.Tr "repo.release.loading"}}
+			      </div>
+		      </div>
+					<button class="ui right green button">
+						{{.i18n.Tr "repo.issues.create"}}
+					</button>
+		    </div>
+		  </div>
+		</div>
+	</div>
+	<div class="four wide column">
+		<div class="ui segment metas">
+			<div class="ui {{if .Labels}}disabled{{end}} pointing dropdown jump item">
+				<span class="text">
+					<strong>{{.i18n.Tr "repo.issues.new.labels"}}</strong>
+					<span class="octicon octicon-gear"></span>
+				</span>
+        <div class="menu">
+        	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&milestone={{$.MilestoneID}}">{{.i18n.Tr "repo.issues.filter_label_no_select"}}</a>
+        	{{range .Labels}}
+        	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}"><span class="octicon {{if eq $.SelectLabels .ID}}octicon-check{{end}}"></span><span class="label color" style="background-color: {{.Color}}"></span> {{.Name}}</a>
+          {{end}}
+				</div>
+			</div>
+			<div class="ui list">
+				<span class="item">filter_label_no_select</span>
+			</div>
+			<div class="ui divider"></div>
+			<div class="ui {{if .Labels}}disabled{{end}} pointing dropdown jump item">
+				<span class="text">
+					<strong>{{.i18n.Tr "repo.issues.new.labels"}}</strong>
+					<span class="octicon octicon-gear"></span>
+				</span>
+        <div class="menu">
+        	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&milestone={{$.MilestoneID}}">{{.i18n.Tr "repo.issues.filter_label_no_select"}}</a>
+        	{{range .Labels}}
+        	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}"><span class="octicon {{if eq $.SelectLabels .ID}}octicon-check{{end}}"></span><span class="label color" style="background-color: {{.Color}}"></span> {{.Name}}</a>
+          {{end}}
+				</div>
+			</div>
+			<div class="ui list">
+				<span class="item">filter_label_no_select</span>
+			</div>
+			<div class="ui divider"></div>
+			<div class="ui {{if .Labels}}disabled{{end}} pointing dropdown jump item">
+				<span class="text">
+					<strong>{{.i18n.Tr "repo.issues.new.labels"}}</strong>
+					<span class="octicon octicon-gear"></span>
+				</span>
+        <div class="menu">
+        	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&milestone={{$.MilestoneID}}">{{.i18n.Tr "repo.issues.filter_label_no_select"}}</a>
+        	{{range .Labels}}
+        	<a class="item" href="{{$.RepoLink}}/issues?type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}"><span class="octicon {{if eq $.SelectLabels .ID}}octicon-check{{end}}"></span><span class="label color" style="background-color: {{.Color}}"></span> {{.Name}}</a>
+          {{end}}
+				</div>
+			</div>
+			<div class="ui list">
+				<span class="item">filter_label_no_select</span>
+			</div>
+		</div>
+	</div>
+</form>

+ 1 - 0
templates/repo/pulls/compare.tmpl

@@ -45,6 +45,7 @@
 					</div>
 			 	</div>
 			</div>
+			{{template "repo/issue/new_form" .}}
 		</div>
 	</div>
 </div>

Some files were not shown because too many files changed in this diff