mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-26 18:00:34 +00:00
parent
5703a0d3e3
commit
9bbb4d8d6d
7 changed files with 41 additions and 30 deletions
|
@ -229,39 +229,41 @@ func (issues IssueList) loadMilestones(ctx context.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (issues IssueList) getProjectIDs() []int64 {
|
func (issues IssueList) LoadProjects(ctx context.Context) error {
|
||||||
ids := make(container.Set[int64], len(issues))
|
issueIDs := issues.getIssueIDs()
|
||||||
for _, issue := range issues {
|
projectMaps := make(map[int64]*project_model.Project, len(issues))
|
||||||
ids.Add(issue.ProjectID())
|
left := len(issueIDs)
|
||||||
}
|
|
||||||
return ids.Values()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (issues IssueList) loadProjects(ctx context.Context) error {
|
type projectWithIssueID struct {
|
||||||
projectIDs := issues.getProjectIDs()
|
*project_model.Project `xorm:"extends"`
|
||||||
if len(projectIDs) == 0 {
|
IssueID int64
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
projectMaps := make(map[int64]*project_model.Project, len(projectIDs))
|
|
||||||
left := len(projectIDs)
|
|
||||||
for left > 0 {
|
for left > 0 {
|
||||||
limit := db.DefaultMaxInSize
|
limit := db.DefaultMaxInSize
|
||||||
if left < limit {
|
if left < limit {
|
||||||
limit = left
|
limit = left
|
||||||
}
|
}
|
||||||
|
|
||||||
|
projects := make([]*projectWithIssueID, 0, limit)
|
||||||
err := db.GetEngine(ctx).
|
err := db.GetEngine(ctx).
|
||||||
In("id", projectIDs[:limit]).
|
Table("project").
|
||||||
Find(&projectMaps)
|
Select("project.*, project_issue.issue_id").
|
||||||
|
Join("INNER", "project_issue", "project.id = project_issue.project_id").
|
||||||
|
In("project_issue.issue_id", issueIDs[:limit]).
|
||||||
|
Find(&projects)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
for _, project := range projects {
|
||||||
|
projectMaps[project.IssueID] = project.Project
|
||||||
|
}
|
||||||
left -= limit
|
left -= limit
|
||||||
projectIDs = projectIDs[limit:]
|
issueIDs = issueIDs[limit:]
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, issue := range issues {
|
for _, issue := range issues {
|
||||||
issue.Project = projectMaps[issue.ProjectID()]
|
issue.Project = projectMaps[issue.ID]
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -541,7 +543,7 @@ func (issues IssueList) loadAttributes(ctx context.Context) error {
|
||||||
return fmt.Errorf("issue.loadAttributes: loadMilestones: %w", err)
|
return fmt.Errorf("issue.loadAttributes: loadMilestones: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := issues.loadProjects(ctx); err != nil {
|
if err := issues.LoadProjects(ctx); err != nil {
|
||||||
return fmt.Errorf("issue.loadAttributes: loadProjects: %w", err)
|
return fmt.Errorf("issue.loadAttributes: loadProjects: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,8 +66,12 @@ func TestIssueList_LoadAttributes(t *testing.T) {
|
||||||
}
|
}
|
||||||
if issue.ID == int64(1) {
|
if issue.ID == int64(1) {
|
||||||
assert.Equal(t, int64(400), issue.TotalTrackedTime)
|
assert.Equal(t, int64(400), issue.TotalTrackedTime)
|
||||||
|
assert.NotNil(t, issue.Project)
|
||||||
} else if issue.ID == int64(2) {
|
} else if issue.ID == int64(2) {
|
||||||
assert.Equal(t, int64(3682), issue.TotalTrackedTime)
|
assert.Equal(t, int64(3682), issue.TotalTrackedTime)
|
||||||
|
assert.Nil(t, issue.Project)
|
||||||
|
} else {
|
||||||
|
assert.Nil(t, issue.Project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,11 +27,6 @@ func (issue *Issue) LoadProject(ctx context.Context) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProjectID return project id if issue was assigned to one
|
|
||||||
func (issue *Issue) ProjectID() int64 {
|
|
||||||
return issue.projectID(db.DefaultContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (issue *Issue) projectID(ctx context.Context) int64 {
|
func (issue *Issue) projectID(ctx context.Context) int64 {
|
||||||
var ip project_model.ProjectIssue
|
var ip project_model.ProjectIssue
|
||||||
has, err := db.GetEngine(ctx).Where("issue_id=?", issue.ID).Get(&ip)
|
has, err := db.GetEngine(ctx).Where("issue_id=?", issue.ID).Get(&ip)
|
||||||
|
|
|
@ -383,7 +383,7 @@ func ViewProject(ctx *context.Context) {
|
||||||
ctx.HTML(http.StatusOK, tplProjectsView)
|
ctx.HTML(http.StatusOK, tplProjectsView)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getActionIssues(ctx *context.Context) []*issues_model.Issue {
|
func getActionIssues(ctx *context.Context) issues_model.IssueList {
|
||||||
commaSeparatedIssueIDs := ctx.FormString("issue_ids")
|
commaSeparatedIssueIDs := ctx.FormString("issue_ids")
|
||||||
if len(commaSeparatedIssueIDs) == 0 {
|
if len(commaSeparatedIssueIDs) == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
@ -429,9 +429,14 @@ func UpdateIssueProject(ctx *context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := issues.LoadProjects(ctx); err != nil {
|
||||||
|
ctx.ServerError("LoadProjects", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
projectID := ctx.FormInt64("id")
|
projectID := ctx.FormInt64("id")
|
||||||
for _, issue := range issues {
|
for _, issue := range issues {
|
||||||
oldProjectID := issue.ProjectID()
|
oldProjectID := issue.Project.ID
|
||||||
if oldProjectID == projectID {
|
if oldProjectID == projectID {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -1971,7 +1971,7 @@ func checkIssueRights(ctx *context.Context, issue *issues_model.Issue) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getActionIssues(ctx *context.Context) []*issues_model.Issue {
|
func getActionIssues(ctx *context.Context) issues_model.IssueList {
|
||||||
commaSeparatedIssueIDs := ctx.FormString("issue_ids")
|
commaSeparatedIssueIDs := ctx.FormString("issue_ids")
|
||||||
if len(commaSeparatedIssueIDs) == 0 {
|
if len(commaSeparatedIssueIDs) == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
@ -2722,7 +2722,7 @@ func UpdateIssueStatus(ctx *context.Context) {
|
||||||
log.Warn("Unrecognized action: %s", action)
|
log.Warn("Unrecognized action: %s", action)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := issues_model.IssueList(issues).LoadRepositories(ctx); err != nil {
|
if _, err := issues.LoadRepositories(ctx); err != nil {
|
||||||
ctx.ServerError("LoadRepositories", err)
|
ctx.ServerError("LoadRepositories", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -378,9 +378,14 @@ func UpdateIssueProject(ctx *context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := issues.LoadProjects(ctx); err != nil {
|
||||||
|
ctx.ServerError("LoadProjects", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
projectID := ctx.FormInt64("id")
|
projectID := ctx.FormInt64("id")
|
||||||
for _, issue := range issues {
|
for _, issue := range issues {
|
||||||
oldProjectID := issue.ProjectID()
|
oldProjectID := issue.Project.ID
|
||||||
if oldProjectID == projectID {
|
if oldProjectID == projectID {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,9 +192,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui select-project list">
|
<div class="ui select-project list">
|
||||||
<span class="no-select item {{if .Issue.ProjectID}}gt-hidden{{end}}">{{.locale.Tr "repo.issues.new.no_projects"}}</span>
|
<span class="no-select item {{if .Issue.Project}}gt-hidden{{end}}">{{.locale.Tr "repo.issues.new.no_projects"}}</span>
|
||||||
<div class="selected">
|
<div class="selected">
|
||||||
{{if .Issue.ProjectID}}
|
{{if .Issue.Project}}
|
||||||
<a class="item muted sidebar-item-link" href="{{.Issue.Project.Link}}">
|
<a class="item muted sidebar-item-link" href="{{.Issue.Project.Link}}">
|
||||||
{{svg .Issue.Project.IconName 18 "gt-mr-3"}}{{.Issue.Project.Title}}
|
{{svg .Issue.Project.IconName 18 "gt-mr-3"}}{{.Issue.Project.Title}}
|
||||||
</a>
|
</a>
|
||||||
|
|
Loading…
Reference in a new issue