1
0
mirror of https://github.com/go-gitea/gitea.git synced 2024-06-26 01:15:32 +00:00

Compare commits

...

17 Commits

Author SHA1 Message Date
Lunny Xiao
fdadd2f4b6
Merge cdcf2c313b into 129206da45 2024-06-17 02:28:23 +02:00
GiteaBot
129206da45 [skip ci] Updated licenses and gitignores 2024-06-17 00:27:39 +00:00
wxiaoguang
f446e3b4ab
Fix JS error when creating new issue (#31383)
Fix #31336
2024-06-16 02:07:21 +00:00
Lunny Xiao
cdcf2c313b Merge branch 'main' into lunny/add_comment_move_issue_column 2024-06-13 09:29:06 +08:00
Lunny Xiao
45905a8440 Merge branch 'main' into lunny/add_comment_move_issue_column 2024-06-13 09:24:09 +08:00
Lunny Xiao
b1a2f40e1f Follow yp05327's suggestion 2024-05-28 11:20:58 +08:00
Lunny Xiao
c43f7ed0ca Fix lint 2024-05-28 11:20:58 +08:00
Lunny Xiao
2118c6b678 Update models/migrations/v1_23/v297.go
Co-authored-by: yp05327 <576951401@qq.com>
2024-05-28 11:20:58 +08:00
Lunny Xiao
58b4698ad5 Fix metadata name 2024-05-28 11:20:58 +08:00
wxiaoguang
45ac27e28a Update templates/repo/issue/view_content/comments.tmpl 2024-05-28 11:20:58 +08:00
wxiaoguang
8b4cc81ce5 Apply suggestions from code review 2024-05-28 11:20:58 +08:00
Lunny Xiao
67dfeb2b50 Ignore the fields on database when it's empty 2024-05-28 11:20:57 +08:00
Lunny Xiao
e4798b90e8 Use new template HTML method 2024-05-28 11:20:57 +08:00
Lunny Xiao
d7f48be02f Use Escape 2024-05-28 11:20:57 +08:00
Lunny Xiao
8bd1218e8b Fix possible xss bug 2024-05-28 11:20:57 +08:00
Lunny Xiao
bb8fac8492 Fix bug 2024-05-28 11:20:57 +08:00
Lunny Xiao
5f5212ca60 Add issue comment when moving issues from one column to another of the project 2024-05-28 11:20:57 +08:00
15 changed files with 226 additions and 65 deletions

View File

@ -222,6 +222,13 @@ func (r RoleInRepo) LocaleHelper(lang translation.Locale) string {
return lang.TrString("repo.issues.role." + string(r) + "_helper")
}
// CommentMetaData stores metadata for a comment, these data will not be changed once inserted into database
type CommentMetaData struct {
ProjectColumnID int64 `json:"project_column_id,omitempty"`
ProjectColumnTitle string `json:"project_column_title,omitempty"`
ProjectTitle string `json:"project_title,omitempty"`
}
// Comment represents a comment in commit and issue page.
type Comment struct {
ID int64 `xorm:"pk autoincr"`
@ -295,6 +302,8 @@ type Comment struct {
RefAction references.XRefAction `xorm:"SMALLINT"` // What happens if RefIssueID resolves
RefIsPull bool
CommentMetaData *CommentMetaData `xorm:"JSON TEXT"` // put all non-index metadata in a single field
RefRepo *repo_model.Repository `xorm:"-"`
RefIssue *Issue `xorm:"-"`
RefComment *Comment `xorm:"-"`
@ -797,6 +806,15 @@ func CreateComment(ctx context.Context, opts *CreateCommentOptions) (_ *Comment,
LabelID = opts.Label.ID
}
var commentMetaData *CommentMetaData
if opts.ProjectColumnTitle != "" {
commentMetaData = &CommentMetaData{
ProjectColumnID: opts.ProjectColumnID,
ProjectColumnTitle: opts.ProjectColumnTitle,
ProjectTitle: opts.ProjectTitle,
}
}
comment := &Comment{
Type: opts.Type,
PosterID: opts.Doer.ID,
@ -830,6 +848,7 @@ func CreateComment(ctx context.Context, opts *CreateCommentOptions) (_ *Comment,
RefIsPull: opts.RefIsPull,
IsForcePush: opts.IsForcePush,
Invalidated: opts.Invalidated,
CommentMetaData: commentMetaData,
}
if _, err = e.Insert(comment); err != nil {
return nil, err
@ -982,34 +1001,37 @@ type CreateCommentOptions struct {
Issue *Issue
Label *Label
DependentIssueID int64
OldMilestoneID int64
MilestoneID int64
OldProjectID int64
ProjectID int64
TimeID int64
AssigneeID int64
AssigneeTeamID int64
RemovedAssignee bool
OldTitle string
NewTitle string
OldRef string
NewRef string
CommitID int64
CommitSHA string
Patch string
LineNum int64
TreePath string
ReviewID int64
Content string
Attachments []string // UUIDs of attachments
RefRepoID int64
RefIssueID int64
RefCommentID int64
RefAction references.XRefAction
RefIsPull bool
IsForcePush bool
Invalidated bool
DependentIssueID int64
OldMilestoneID int64
MilestoneID int64
OldProjectID int64
ProjectID int64
ProjectTitle string
ProjectColumnID int64
ProjectColumnTitle string
TimeID int64
AssigneeID int64
AssigneeTeamID int64
RemovedAssignee bool
OldTitle string
NewTitle string
OldRef string
NewRef string
CommitID int64
CommitSHA string
Patch string
LineNum int64
TreePath string
ReviewID int64
Content string
Attachments []string // UUIDs of attachments
RefRepoID int64
RefIssueID int64
RefCommentID int64
RefAction references.XRefAction
RefIsPull bool
IsForcePush bool
Invalidated bool
}
// GetCommentByID returns the comment by given ID.

View File

@ -441,6 +441,7 @@ func (issues IssueList) loadComments(ctx context.Context, cond builder.Cond) (er
Join("INNER", "issue", "issue.id = comment.issue_id").
In("issue.id", issuesIDs[:limit]).
Where(cond).
NoAutoCondition().
Rows(new(Comment))
if err != nil {
return err

View File

@ -591,6 +591,8 @@ var migrations = []Migration{
// v299 -> v300
NewMigration("Add content version to issue and comment table", v1_23.AddContentVersionToIssueAndComment),
// v300 -> v301
NewMigration("Add metadata column for comment table", v1_23.AddCommentMetaDataColumn),
}
// GetCurrentDBVersion returns the current db version

View File

@ -0,0 +1,23 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_23 //nolint
import (
"xorm.io/xorm"
)
// CommentMetaData stores metadata for a comment, these data will not be changed once inserted into database
type CommentMetaData struct {
ProjectColumnID int64 `json:"project_column_id"`
ProjectColumnTitle string `json:"project_column_title"`
ProjectTitle string `json:"project_title"`
}
func AddCommentMetaDataColumn(x *xorm.Engine) error {
type Comment struct {
CommentMetaData *CommentMetaData `xorm:"JSON TEXT"` // put all non-index metadata in a single field
}
return x.Sync(new(Comment))
}

View File

@ -76,30 +76,6 @@ func (p *Project) NumOpenIssues(ctx context.Context) int {
return int(c)
}
// MoveIssuesOnProjectColumn moves or keeps issues in a column and sorts them inside that column
func MoveIssuesOnProjectColumn(ctx context.Context, column *Column, sortedIssueIDs map[int64]int64) error {
return db.WithTx(ctx, func(ctx context.Context) error {
sess := db.GetEngine(ctx)
issueIDs := util.ValuesOfMap(sortedIssueIDs)
count, err := sess.Table(new(ProjectIssue)).Where("project_id=?", column.ProjectID).In("issue_id", issueIDs).Count()
if err != nil {
return err
}
if int(count) != len(sortedIssueIDs) {
return fmt.Errorf("all issues have to be added to a project first")
}
for sorting, issueID := range sortedIssueIDs {
_, err = sess.Exec("UPDATE `project_issue` SET project_board_id=?, sorting=? WHERE issue_id=?", column.ID, sorting, issueID)
if err != nil {
return err
}
}
return nil
})
}
func (c *Column) moveIssuesToAnotherColumn(ctx context.Context, newColumn *Column) error {
if c.ProjectID != newColumn.ProjectID {
return fmt.Errorf("columns have to be in the same project")

47
options/gitignore/IAR Normal file
View File

@ -0,0 +1,47 @@
# Compiled binaries
*.o
*.bin
*.elf
*.hex
*.map
*.out
*.obj
# Trash
*.bak
thumbs.db
*.~*
# IAR Settings
**/settings/*.crun
**/settings/*.dbgdt
**/settings/*.cspy
**/settings/*.cspy.*
**/settings/*.xcl
**/settings/*.dni
**/settings/*.wsdt
**/settings/*.wspos
# IAR Debug Exe
**/Exe/*.sim
# IAR Debug Obj
**/Obj/*.pbd
**/Obj/*.pbd.*
**/Obj/*.pbi
**/Obj/*.pbi.*
# IAR project "Debug" directory
Debug/
# IAR project "Release" directory
Release/
# IAR project settings directory
settings/
# IAR backup files
Backup*
# IAR .dep files
*.dep

View File

@ -42,10 +42,3 @@ fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output
# Code Injection
#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode
iOSInjectionProject/

View File

@ -35,6 +35,3 @@ override.tf.json
# Ignore CLI configuration files
.terraformrc
terraform.rc
# Ignore hcl file
.terraform.lock.hcl

View File

@ -1471,6 +1471,7 @@ issues.remove_labels = removed the %s labels %s
issues.add_remove_labels = added %s and removed %s labels %s
issues.add_milestone_at = `added this to the <b>%s</b> milestone %s`
issues.add_project_at = `added this to the <b>%s</b> project %s`
issues.move_to_column_of_project = `moved this to %s in %s on %s`
issues.change_milestone_at = `modified the milestone from <b>%s</b> to <b>%s</b> %s`
issues.change_project_at = `modified the project from <b>%s</b> to <b>%s</b> %s`
issues.remove_milestone_at = `removed this from the <b>%s</b> milestone %s`

View File

@ -23,6 +23,7 @@ import (
shared_user "code.gitea.io/gitea/routers/web/shared/user"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/forms"
project_service "code.gitea.io/gitea/services/projects"
)
const (
@ -601,7 +602,7 @@ func MoveIssues(ctx *context.Context) {
}
}
if err = project_model.MoveIssuesOnProjectColumn(ctx, column, sortedIssueIDs); err != nil {
if err = project_service.MoveIssuesOnProjectColumn(ctx, ctx.Doer, column, sortedIssueIDs); err != nil {
ctx.ServerError("MoveIssuesOnProjectColumn", err)
return
}

View File

@ -1682,6 +1682,11 @@ func ViewIssue(ctx *context.Context) {
if comment.ProjectID > 0 && comment.Project == nil {
comment.Project = ghostProject
}
} else if comment.Type == issues_model.CommentTypeProjectColumn {
if err = comment.LoadProject(ctx); err != nil {
ctx.ServerError("LoadProject", err)
return
}
} else if comment.Type == issues_model.CommentTypeAssignees || comment.Type == issues_model.CommentTypeReviewRequest {
if err = comment.LoadAssigneeUserAndTeam(ctx); err != nil {
ctx.ServerError("LoadAssigneeUserAndTeam", err)

View File

@ -25,6 +25,7 @@ import (
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/forms"
project_service "code.gitea.io/gitea/services/projects"
)
const (
@ -664,7 +665,7 @@ func MoveIssues(ctx *context.Context) {
}
}
if err = project_model.MoveIssuesOnProjectColumn(ctx, column, sortedIssueIDs); err != nil {
if err = project_service.MoveIssuesOnProjectColumn(ctx, ctx.Doer, column, sortedIssueIDs); err != nil {
ctx.ServerError("MoveIssuesOnProjectColumn", err)
return
}

View File

@ -0,0 +1,76 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package project
import (
"context"
"fmt"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
project_model "code.gitea.io/gitea/models/project"
user_model "code.gitea.io/gitea/models/user"
)
// MoveIssuesOnProjectColumn moves or keeps issues in a column and sorts them inside that column
func MoveIssuesOnProjectColumn(ctx context.Context, doer *user_model.User, column *project_model.Column, sortedIssueIDs map[int64]int64) error {
return db.WithTx(ctx, func(ctx context.Context) error {
issueIDs := make([]int64, 0, len(sortedIssueIDs))
for _, issueID := range sortedIssueIDs {
issueIDs = append(issueIDs, issueID)
}
count, err := db.GetEngine(ctx).
Where("project_id=?", column.ProjectID).
In("issue_id", issueIDs).
Count(new(project_model.ProjectIssue))
if err != nil {
return err
}
if int(count) != len(sortedIssueIDs) {
return fmt.Errorf("all issues have to be added to a project first")
}
issues, err := issues_model.GetIssuesByIDs(ctx, issueIDs)
if err != nil {
return err
}
if _, err := issues.LoadRepositories(ctx); err != nil {
return err
}
project, err := project_model.GetProjectByID(ctx, column.ProjectID)
if err != nil {
return err
}
issuesMap := make(map[int64]*issues_model.Issue, len(issues))
for _, issue := range issues {
issuesMap[issue.ID] = issue
}
for sorting, issueID := range sortedIssueIDs {
_, err = db.Exec(ctx, "UPDATE `project_issue` SET project_board_id=?, sorting=? WHERE issue_id=?", column.ID, sorting, issueID)
if err != nil {
return err
}
curIssue := issuesMap[issueID]
// add timeline to issue
if _, err := issues_model.CreateComment(ctx, &issues_model.CreateCommentOptions{
Type: issues_model.CommentTypeProjectColumn,
Doer: doer,
Repo: curIssue.Repo,
Issue: curIssue,
ProjectID: column.ProjectID,
ProjectTitle: project.Title,
ProjectColumnID: column.ID,
ProjectColumnTitle: column.Title,
}); err != nil {
return err
}
}
return nil
})
}

View File

@ -600,6 +600,22 @@
</span>
</div>
{{end}}
{{else if eq .Type 31}}
{{if not $.UnitProjectsGlobalDisabled}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-project"}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="text grey muted-links">
{{template "shared/user/authorlink" .Poster}}
{{$newProjectDisplay := .CommentMetaData.ProjectTitle}}
{{if .Project}}
{{$trKey := printf "projects.type-%d.display_name" .Project.Type}}
{{$newProjectDisplay = HTMLFormat `%s <a href="%s"><span data-tooltip-content="%s">%s</span></a>` (svg .Project.IconName) (.Project.Link ctx) (ctx.Locale.Tr $trKey) .Project.Title}}
{{end}}
{{ctx.Locale.Tr "repo.issues.move_to_column_of_project" .CommentMetaData.ProjectColumnTitle $newProjectDisplay $createdStr}}
</span>
</div>
{{end}}
{{else if eq .Type 32}}
<div class="timeline-item-group">
<div class="timeline-item event" id="{{.HashTag}}">

View File

@ -272,7 +272,7 @@ export function initRepoCommentForm() {
}
$list.find('.selected').html(`
<a class="item muted sidebar-item-link" href=${htmlEscape(this.getAttribute('href'))}>
<a class="item muted sidebar-item-link" href="${htmlEscape(this.getAttribute('data-href'))}">
${icon}
${htmlEscape(this.textContent)}
</a>