UI: create issue with title and content
This commit is contained in:
parent
43a87b0caf
commit
590c464c56
18 changed files with 971 additions and 174 deletions
|
@ -419,8 +419,8 @@ func runWeb(ctx *cli.Context) {
|
||||||
m.Get("/action/:action", repo.Action)
|
m.Get("/action/:action", repo.Action)
|
||||||
|
|
||||||
m.Group("/issues", func() {
|
m.Group("/issues", func() {
|
||||||
m.Get("/new", repo.CreateIssue)
|
m.Combo("/new").Get(repo.NewIssue).
|
||||||
m.Post("/new", bindIgnErr(auth.CreateIssueForm{}), repo.CreateIssuePost)
|
Post(bindIgnErr(auth.CreateIssueForm{}), repo.NewIssuePost)
|
||||||
m.Post("/:index", bindIgnErr(auth.CreateIssueForm{}), repo.UpdateIssue)
|
m.Post("/:index", bindIgnErr(auth.CreateIssueForm{}), repo.UpdateIssue)
|
||||||
m.Post("/:index/label", repo.UpdateIssueLabel)
|
m.Post("/:index/label", repo.UpdateIssueLabel)
|
||||||
m.Post("/:index/milestone", repo.UpdateIssueMilestone)
|
m.Post("/:index/milestone", repo.UpdateIssueMilestone)
|
||||||
|
|
|
@ -367,6 +367,7 @@ commits.older = Older
|
||||||
commits.newer = Newer
|
commits.newer = Newer
|
||||||
|
|
||||||
issues.new = New Issue
|
issues.new = New Issue
|
||||||
|
issues.create = Create Issue
|
||||||
issues.new_label = New Label
|
issues.new_label = New Label
|
||||||
issues.new_label_placeholder = Label name...
|
issues.new_label_placeholder = Label name...
|
||||||
issues.open_tab = %d Open
|
issues.open_tab = %d Open
|
||||||
|
|
|
@ -388,6 +388,26 @@
|
||||||
"strictMath": 0,
|
"strictMath": 0,
|
||||||
"strictUnits": 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": {
|
"\/public\/less\/_octicons.less": {
|
||||||
"allowInsecureImports": 0,
|
"allowInsecureImports": 0,
|
||||||
"createSourceMap": 0,
|
"createSourceMap": 0,
|
||||||
|
|
2
gogs.go
2
gogs.go
|
@ -17,7 +17,7 @@ import (
|
||||||
"github.com/gogits/gogs/modules/setting"
|
"github.com/gogits/gogs/modules/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
const APP_VER = "0.6.4.0808 Beta"
|
const APP_VER = "0.6.4.0809 Beta"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||||
|
|
|
@ -38,7 +38,7 @@ type Issue struct {
|
||||||
Repo *Repository `xorm:"-"`
|
Repo *Repository `xorm:"-"`
|
||||||
PosterID int64
|
PosterID int64
|
||||||
Poster *User `xorm:"-"`
|
Poster *User `xorm:"-"`
|
||||||
LabelIds string `xorm:"TEXT"`
|
LabelIDs string `xorm:"label_ids TEXT"`
|
||||||
Labels []*Label `xorm:"-"`
|
Labels []*Label `xorm:"-"`
|
||||||
MilestoneID int64
|
MilestoneID int64
|
||||||
Milestone *Milestone `xorm:"-"`
|
Milestone *Milestone `xorm:"-"`
|
||||||
|
@ -77,11 +77,11 @@ func (i *Issue) GetPoster() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Issue) GetLabels() error {
|
func (i *Issue) GetLabels() error {
|
||||||
if len(i.LabelIds) < 3 {
|
if len(i.LabelIDs) < 3 {
|
||||||
return nil
|
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))
|
i.Labels = make([]*Label, 0, len(strIds))
|
||||||
for _, strId := range strIds {
|
for _, strId := range strIds {
|
||||||
id := com.StrTo(strId).MustInt64()
|
id := com.StrTo(strId).MustInt64()
|
||||||
|
@ -134,7 +134,7 @@ func NewIssue(issue *Issue) (err error) {
|
||||||
|
|
||||||
if _, err = sess.Insert(issue); err != nil {
|
if _, err = sess.Insert(issue); err != nil {
|
||||||
return err
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,14 +296,14 @@ type IssueUser struct {
|
||||||
|
|
||||||
// FIXME: organization
|
// FIXME: organization
|
||||||
// NewIssueUserPairs adds new issue-user pairs for new issue of repository.
|
// 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()
|
users, err := repo.GetCollaborators()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
iu := &IssueUser{
|
iu := &IssueUser{
|
||||||
IssueId: issueID,
|
IssueId: issue.ID,
|
||||||
RepoId: repo.ID,
|
RepoId: repo.ID,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,30 +311,30 @@ func NewIssueUserPairs(repo *Repository, issueID, orgID, posterID, assigneeID in
|
||||||
for _, u := range users {
|
for _, u := range users {
|
||||||
iu.Id = 0
|
iu.Id = 0
|
||||||
iu.Uid = u.Id
|
iu.Uid = u.Id
|
||||||
iu.IsPoster = iu.Uid == posterID
|
iu.IsPoster = iu.Uid == issue.PosterID
|
||||||
if isNeedAddPoster && iu.IsPoster {
|
if isNeedAddPoster && iu.IsPoster {
|
||||||
isNeedAddPoster = false
|
isNeedAddPoster = false
|
||||||
}
|
}
|
||||||
iu.IsAssigned = iu.Uid == assigneeID
|
iu.IsAssigned = iu.Uid == issue.AssigneeID
|
||||||
if _, err = x.Insert(iu); err != nil {
|
if _, err = x.Insert(iu); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isNeedAddPoster {
|
if isNeedAddPoster {
|
||||||
iu.Id = 0
|
iu.Id = 0
|
||||||
iu.Uid = posterID
|
iu.Uid = issue.PosterID
|
||||||
iu.IsPoster = true
|
iu.IsPoster = true
|
||||||
iu.IsAssigned = iu.Uid == assigneeID
|
iu.IsAssigned = iu.Uid == issue.AssigneeID
|
||||||
if _, err = x.Insert(iu); err != nil {
|
if _, err = x.Insert(iu); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add owner's as well.
|
// Add owner's as well.
|
||||||
if repo.OwnerID != posterID {
|
if repo.OwnerID != issue.PosterID {
|
||||||
iu.Id = 0
|
iu.Id = 0
|
||||||
iu.Uid = repo.OwnerID
|
iu.Uid = repo.OwnerID
|
||||||
iu.IsAssigned = iu.Uid == assigneeID
|
iu.IsAssigned = iu.Uid == issue.AssigneeID
|
||||||
if _, err = x.Insert(iu); err != nil {
|
if _, err = x.Insert(iu); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -621,7 +621,7 @@ func DeleteLabel(repoID, labelID int64) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, issue := range issues {
|
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 {
|
if _, err = sess.Id(issue.ID).AllCols().Update(issue); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type MarkdownForm struct {
|
type MarkdownForm struct {
|
||||||
Text string `form:"text"`
|
Text string
|
||||||
Mode string `form:"mode"`
|
Mode string
|
||||||
Context string `form:"context"`
|
Context string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *MarkdownForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
func (f *MarkdownForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||||
|
|
|
@ -98,11 +98,11 @@ func (f *NewSlackHookForm) Validate(ctx *macaron.Context, errs binding.Errors) b
|
||||||
// \/ \/ \/
|
// \/ \/ \/
|
||||||
|
|
||||||
type CreateIssueForm struct {
|
type CreateIssueForm struct {
|
||||||
IssueName string `form:"title" binding:"Required;MaxSize(255)"`
|
Title string `binding:"Required;MaxSize(255)"`
|
||||||
MilestoneId int64 `form:"milestoneid"`
|
LabelIDs []int64 `form:"label_id"`
|
||||||
AssigneeId int64 `form:"assigneeid"`
|
MilestoneID int64
|
||||||
Labels string `form:"labels"`
|
AssigneeID int64
|
||||||
Content string `form:"content"`
|
Content string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *CreateIssueForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
func (f *CreateIssueForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||||
|
|
File diff suppressed because one or more lines are too long
2
public/css/gogs.min.css
vendored
2
public/css/gogs.min.css
vendored
File diff suppressed because one or more lines are too long
|
@ -123,6 +123,26 @@ $(document).ready(function () {
|
||||||
});
|
});
|
||||||
$('.poping.up').popup();
|
$('.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.
|
// Helpers.
|
||||||
$('.delete-button').click(function () {
|
$('.delete-button').click(function () {
|
||||||
var $this = $(this);
|
var $this = $(this);
|
||||||
|
|
594
public/less/_markdown.less
Normal file
594
public/less/_markdown.less
Normal file
|
@ -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;
|
||||||
|
}
|
|
@ -105,6 +105,7 @@
|
||||||
.page.buttons {
|
.page.buttons {
|
||||||
padding-top: 15px;
|
padding-top: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.issue.list {
|
.issue.list {
|
||||||
clear: both;
|
clear: both;
|
||||||
list-style: none;
|
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 {
|
.label.list {
|
||||||
clear: both;
|
clear: both;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
@import "_octicons";
|
@import "_octicons";
|
||||||
@import "_base";
|
@import "_base";
|
||||||
|
@import "_markdown";
|
||||||
@import "_home";
|
@import "_home";
|
||||||
@import "_install";
|
@import "_install";
|
||||||
@import "_form";
|
@import "_form";
|
||||||
|
|
|
@ -28,7 +28,7 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ISSUES base.TplName = "repo/issue/list"
|
ISSUES base.TplName = "repo/issue/list"
|
||||||
ISSUE_CREATE base.TplName = "repo/issue/create"
|
ISSUE_NEW base.TplName = "repo/issue/new"
|
||||||
ISSUE_VIEW base.TplName = "repo/issue/view"
|
ISSUE_VIEW base.TplName = "repo/issue/view"
|
||||||
|
|
||||||
LABELS base.TplName = "repo/issue/labels"
|
LABELS base.TplName = "repo/issue/labels"
|
||||||
|
@ -174,167 +174,198 @@ func Issues(ctx *middleware.Context) {
|
||||||
ctx.HTML(200, ISSUES)
|
ctx.HTML(200, ISSUES)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateIssue(ctx *middleware.Context) {
|
func NewIssue(ctx *middleware.Context) {
|
||||||
ctx.Data["Title"] = "Create issue"
|
ctx.Data["Title"] = ctx.Tr("repo.issues.new")
|
||||||
ctx.Data["IsRepoToolbarIssues"] = true
|
ctx.Data["PageIsIssueList"] = true
|
||||||
ctx.Data["IsRepoToolbarIssuesList"] = false
|
ctx.Data["IsAttachmentEnabled"] = setting.AttachmentEnabled
|
||||||
ctx.Data["AttachmentsEnabled"] = setting.AttachmentEnabled
|
ctx.Data["AttachmentAllowedTypes"] = setting.AttachmentAllowedTypes
|
||||||
|
|
||||||
var (
|
// var (
|
||||||
repo = ctx.Repo.Repository
|
// repo = ctx.Repo.Repository
|
||||||
err error
|
// err error
|
||||||
)
|
// )
|
||||||
// Get all milestones.
|
// // Get all milestones.
|
||||||
ctx.Data["OpenMilestones"], err = models.GetMilestones(repo.ID, -1, false)
|
// ctx.Data["OpenMilestones"], err = models.GetMilestones(repo.ID, -1, false)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
ctx.Handle(500, "GetMilestones.1: %v", err)
|
// ctx.Handle(500, "GetMilestones.1: %v", err)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
ctx.Data["ClosedMilestones"], err = models.GetMilestones(repo.ID, -1, true)
|
// ctx.Data["ClosedMilestones"], err = models.GetMilestones(repo.ID, -1, true)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
ctx.Handle(500, "GetMilestones.2: %v", err)
|
// ctx.Handle(500, "GetMilestones.2: %v", err)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
us, err := repo.GetCollaborators()
|
// us, err := repo.GetCollaborators()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
ctx.Handle(500, "GetCollaborators", err)
|
// ctx.Handle(500, "GetCollaborators", err)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
ctx.Data["AllowedTypes"] = setting.AttachmentAllowedTypes
|
// ctx.Data["Collaborators"] = us
|
||||||
ctx.Data["Collaborators"] = us
|
|
||||||
|
|
||||||
ctx.HTML(200, ISSUE_CREATE)
|
ctx.HTML(200, ISSUE_NEW)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) {
|
func NewIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) {
|
||||||
send := func(status int, data interface{}, err error) {
|
ctx.Data["Title"] = ctx.Tr("repo.issues.new")
|
||||||
if err != nil {
|
ctx.Data["PageIsIssueList"] = true
|
||||||
log.Error(4, "issue.CreateIssuePost(?): %s", err)
|
ctx.Data["IsAttachmentEnabled"] = setting.AttachmentEnabled
|
||||||
|
ctx.Data["AttachmentAllowedTypes"] = setting.AttachmentAllowedTypes
|
||||||
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() {
|
if ctx.HasError() {
|
||||||
send(400, nil, errors.New(ctx.Flash.ErrorMsg))
|
ctx.HTML(200, ISSUE_NEW)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only collaborators can assign.
|
|
||||||
if !ctx.Repo.IsOwner() {
|
|
||||||
form.AssigneeId = 0
|
|
||||||
}
|
|
||||||
issue := &models.Issue{
|
issue := &models.Issue{
|
||||||
RepoID: ctx.Repo.Repository.ID,
|
RepoID: ctx.Repo.Repository.ID,
|
||||||
Index: int64(ctx.Repo.Repository.NumIssues) + 1,
|
Index: int64(ctx.Repo.Repository.NumIssues) + 1,
|
||||||
Name: form.IssueName,
|
Name: form.Title,
|
||||||
PosterID: ctx.User.Id,
|
PosterID: ctx.User.Id,
|
||||||
MilestoneID: form.MilestoneId,
|
// MilestoneID: form.MilestoneID,
|
||||||
AssigneeID: form.AssigneeId,
|
// AssigneeID: form.AssigneeID,
|
||||||
LabelIds: form.Labels,
|
// LabelIDs: "$" + strings.Join(form.LabelIDs, "|$") + "|",
|
||||||
Content: form.Content,
|
Content: form.Content,
|
||||||
}
|
}
|
||||||
if err := models.NewIssue(issue); err != nil {
|
if err := models.NewIssue(issue); err != nil {
|
||||||
send(500, nil, err)
|
ctx.Handle(500, "NewIssue", 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); err != nil {
|
||||||
ctx.User.Id, form.AssigneeId); err != nil {
|
ctx.Handle(500, "NewIssue", err)
|
||||||
send(500, nil, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if setting.AttachmentEnabled {
|
ctx.Redirect(ctx.Repo.RepoLink + "/issues/" + com.ToStr(issue.Index))
|
||||||
uploadFiles(ctx, issue.ID, 0)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Update mentions.
|
func CreateIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) {
|
||||||
ms := base.MentionPattern.FindAllString(issue.Content, -1)
|
// send := func(status int, data interface{}, err error) {
|
||||||
if len(ms) > 0 {
|
// if err != nil {
|
||||||
for i := range ms {
|
// log.Error(4, "issue.CreateIssuePost(?): %s", err)
|
||||||
ms[i] = ms[i][1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := models.UpdateMentions(ms, issue.ID); err != nil {
|
// ctx.JSON(status, map[string]interface{}{
|
||||||
send(500, nil, err)
|
// "ok": false,
|
||||||
return
|
// "status": status,
|
||||||
}
|
// "error": err.Error(),
|
||||||
}
|
// })
|
||||||
|
// } else {
|
||||||
|
// ctx.JSON(status, map[string]interface{}{
|
||||||
|
// "ok": true,
|
||||||
|
// "status": status,
|
||||||
|
// "data": data,
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
act := &models.Action{
|
// var err error
|
||||||
ActUserID: ctx.User.Id,
|
// // Get all milestones.
|
||||||
ActUserName: ctx.User.Name,
|
// _, err = models.GetMilestones(ctx.Repo.Repository.ID, -1, false)
|
||||||
ActEmail: ctx.User.Email,
|
// if err != nil {
|
||||||
OpType: models.CREATE_ISSUE,
|
// send(500, nil, err)
|
||||||
Content: fmt.Sprintf("%d|%s", issue.Index, issue.Name),
|
// return
|
||||||
RepoID: ctx.Repo.Repository.ID,
|
// }
|
||||||
RepoUserName: ctx.Repo.Owner.Name,
|
// _, err = models.GetMilestones(ctx.Repo.Repository.ID, -1, true)
|
||||||
RepoName: ctx.Repo.Repository.Name,
|
// if err != nil {
|
||||||
RefName: ctx.Repo.BranchName,
|
// send(500, nil, err)
|
||||||
IsPrivate: ctx.Repo.Repository.IsPrivate,
|
// return
|
||||||
}
|
// }
|
||||||
// Notify watchers.
|
|
||||||
if err := models.NotifyWatchers(act); err != nil {
|
|
||||||
send(500, nil, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mail watchers and mentions.
|
// _, err = ctx.Repo.Repository.GetCollaborators()
|
||||||
if setting.Service.EnableNotifyMail {
|
// if err != nil {
|
||||||
tos, err := mailer.SendIssueNotifyMail(ctx.User, ctx.Repo.Owner, ctx.Repo.Repository, issue)
|
// send(500, nil, err)
|
||||||
if err != nil {
|
// return
|
||||||
send(500, nil, err)
|
// }
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tos = append(tos, ctx.User.LowerName)
|
// if ctx.HasError() {
|
||||||
newTos := make([]string, 0, len(ms))
|
// send(400, nil, errors.New(ctx.Flash.ErrorMsg))
|
||||||
for _, m := range ms {
|
// return
|
||||||
if com.IsSliceContainsStr(tos, m) {
|
// }
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
newTos = append(newTos, m)
|
// // Only collaborators can assign.
|
||||||
}
|
// if !ctx.Repo.IsOwner() {
|
||||||
if err = mailer.SendIssueMentionMail(ctx.Render, ctx.User, ctx.Repo.Owner,
|
// form.AssigneeId = 0
|
||||||
ctx.Repo.Repository, issue, models.GetUserEmailsByNames(newTos)); err != nil {
|
// }
|
||||||
send(500, nil, err)
|
// issue := &models.Issue{
|
||||||
return
|
// RepoID: ctx.Repo.Repository.ID,
|
||||||
}
|
// Index: int64(ctx.Repo.Repository.NumIssues) + 1,
|
||||||
}
|
// Name: form.IssueName,
|
||||||
log.Trace("%d Issue created: %d", ctx.Repo.Repository.ID, issue.ID)
|
// 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
|
||||||
|
// }
|
||||||
|
|
||||||
send(200, fmt.Sprintf("%s/%s/%s/issues/%d", setting.AppSubUrl, ctx.Params(":username"), ctx.Params(":reponame"), issue.Index), nil)
|
// 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) {
|
func checkLabels(labels, allLabels []*models.Label) {
|
||||||
|
@ -484,7 +515,7 @@ func UpdateIssue(ctx *middleware.Context, form auth.CreateIssueForm) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
issue.Name = form.IssueName
|
issue.Name = form.Title
|
||||||
//issue.MilestoneId = form.MilestoneId
|
//issue.MilestoneId = form.MilestoneId
|
||||||
//issue.AssigneeId = form.AssigneeId
|
//issue.AssigneeId = form.AssigneeId
|
||||||
//issue.LabelIds = form.Labels
|
//issue.LabelIds = form.Labels
|
||||||
|
@ -540,16 +571,16 @@ func UpdateIssueLabel(ctx *middleware.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
isHad := strings.Contains(issue.LabelIds, "$"+labelStrId+"|")
|
isHad := strings.Contains(issue.LabelIDs, "$"+labelStrId+"|")
|
||||||
isNeedUpdate := false
|
isNeedUpdate := false
|
||||||
if isAttach {
|
if isAttach {
|
||||||
if !isHad {
|
if !isHad {
|
||||||
issue.LabelIds += "$" + labelStrId + "|"
|
issue.LabelIDs += "$" + labelStrId + "|"
|
||||||
isNeedUpdate = true
|
isNeedUpdate = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if isHad {
|
if isHad {
|
||||||
issue.LabelIds = strings.Replace(issue.LabelIds, "$"+labelStrId+"|", "", -1)
|
issue.LabelIDs = strings.Replace(issue.LabelIDs, "$"+labelStrId+"|", "", -1)
|
||||||
isNeedUpdate = true
|
isNeedUpdate = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
0.6.4.0808 Beta
|
0.6.4.0809 Beta
|
14
templates/repo/issue/new.tmpl
Normal file
14
templates/repo/issue/new.tmpl
Normal file
|
@ -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
templates/repo/issue/new_form.tmpl
Normal file
88
templates/repo/issue/new_form.tmpl
Normal file
|
@ -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>
|
|
@ -45,6 +45,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{template "repo/issue/new_form" .}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue