1
0
Fork 0
mirror of https://codeberg.org/forgejo/forgejo.git synced 2025-06-27 16:35:57 +00:00

feat(ui): add links to milestones and projects in issue comments (#7992)

add links to the comments that appear in issue when changing milestones and projects

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7992
Reviewed-by: Beowulf <beowulf@beocode.eu>
Co-authored-by: Robert Wolff <mahlzahn@posteo.de>
Co-committed-by: Robert Wolff <mahlzahn@posteo.de>
This commit is contained in:
Robert Wolff 2025-06-23 23:31:51 +02:00 committed by Beowulf
parent 049cda526b
commit 0b24915271
4 changed files with 60 additions and 29 deletions

View file

@ -67,6 +67,13 @@ type Milestone struct {
TotalTrackedTime int64 `xorm:"-"`
}
// Ghost milestone is a milestone which has been deleted
const GhostMilestoneID = -1
func (m *Milestone) IsGhost() bool {
return m.ID == GhostMilestoneID
}
func init() {
db.RegisterModel(new(Milestone))
}

View file

@ -1693,7 +1693,7 @@ func ViewIssue(ctx *context.Context) {
return
}
ghostMilestone := &issues_model.Milestone{
ID: -1,
ID: issues_model.GhostMilestoneID,
Name: ctx.Locale.TrString("repo.issues.deleted_milestone"),
}
if comment.OldMilestoneID > 0 && comment.OldMilestone == nil {

View file

@ -191,7 +191,31 @@
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="text grey muted-links">
{{template "shared/user/authorlink" .Poster}}
{{if gt .OldMilestoneID 0}}{{if gt .MilestoneID 0}}{{ctx.Locale.Tr "repo.issues.change_milestone_at" .OldMilestone.Name .Milestone.Name $createdStr}}{{else}}{{ctx.Locale.Tr "repo.issues.remove_milestone_at" .OldMilestone.Name $createdStr}}{{end}}{{else if gt .MilestoneID 0}}{{ctx.Locale.Tr "repo.issues.add_milestone_at" .Milestone.Name $createdStr}}{{end}}
{{$newMilestoneDisplayHtml := ""}}
{{if gt .MilestoneID 0}}
{{if .Milestone.IsGhost}}
{{$newMilestoneDisplayHtml = .Milestone.Name}}
{{else}}
{{$newMilestoneDisplayHtml = HTMLFormat `<a href='%s/milestone/%d' rel='nofollow'>%s</a>` $.RepoLink .MilestoneID .Milestone.Name}}
{{end}}
{{end}}
{{$oldMilestoneDisplayHtml := ""}}
{{if gt .OldMilestoneID 0}}
{{if .OldMilestone.IsGhost}}
{{$oldMilestoneDisplayHtml = .OldMilestone.Name}}
{{else}}
{{$oldMilestoneDisplayHtml = HTMLFormat `<a href='%s/milestone/%d' rel='nofollow'>%s</a>` $.RepoLink .OldMilestoneID .OldMilestone.Name}}
{{end}}
{{end}}
{{if gt .OldMilestoneID 0}}
{{if gt .MilestoneID 0}}
{{ctx.Locale.Tr "repo.issues.change_milestone_at" $oldMilestoneDisplayHtml $newMilestoneDisplayHtml $createdStr}}
{{else}}
{{ctx.Locale.Tr "repo.issues.remove_milestone_at" $oldMilestoneDisplayHtml $createdStr}}
{{end}}
{{else}}
{{ctx.Locale.Tr "repo.issues.add_milestone_at" $newMilestoneDisplayHtml $createdStr}}
{{end}}
</span>
</div>
{{else if and (eq .Type 9) (gt .AssigneeID 0)}}
@ -574,27 +598,33 @@
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="text grey muted-links">
{{template "shared/user/authorlink" .Poster}}
{{$oldProjectDisplayHtml := "Unknown Project"}}
{{$oldProjectDisplayHtml := ""}}
{{if .OldProject}}
{{$tooltip := ctx.Locale.Tr "projects.deleted.display_name"}}
{{if not .OldProject.IsGhost}}
{{$tooltip = ctx.Locale.Tr (printf "projects.type-%d.display_name" .OldProject.Type)}}
{{if .OldProject.IsGhost}}
{{$tooltip := ctx.Locale.Tr "projects.deleted.display_name"}}
{{$oldProjectDisplayHtml = HTMLFormat `<span data-tooltip-content="%s">%s</span>` $tooltip .OldProject.Title}}
{{else}}
{{$tooltip := ctx.Locale.Tr (printf "projects.type-%d.display_name" .OldProject.Type)}}
{{$oldProjectDisplayHtml = HTMLFormat `<a href="%s/projects/%d" rel="nofollow"><span data-tooltip-content="%s">%s</span></a>` $.RepoLink .OldProjectID $tooltip .OldProject.Title}}
{{end}}
{{$oldProjectDisplayHtml = HTMLFormat `<span data-tooltip-content="%s">%s</span>` $tooltip .OldProject.Title}}
{{end}}
{{$newProjectDisplayHtml := "Unknown Project"}}
{{$newProjectDisplayHtml := ""}}
{{if .Project}}
{{$tooltip := ctx.Locale.Tr "projects.deleted.display_name"}}
{{if not .Project.IsGhost}}
{{$tooltip = ctx.Locale.Tr (printf "projects.type-%d.display_name" .Project.Type)}}
{{if .Project.IsGhost}}
{{$tooltip := ctx.Locale.Tr "projects.deleted.display_name"}}
{{$newProjectDisplayHtml = HTMLFormat `<span data-tooltip-content="%s">%s</span>` $tooltip .Project.Title}}
{{else}}
{{$tooltip := ctx.Locale.Tr (printf "projects.type-%d.display_name" .Project.Type)}}
{{$newProjectDisplayHtml = HTMLFormat `<a href="%s/projects/%d" rel="nofollow"><span data-tooltip-content="%s">%s</span></a>` $.RepoLink .ProjectID $tooltip .Project.Title}}
{{end}}
{{$newProjectDisplayHtml = HTMLFormat `<span data-tooltip-content="%s">%s</span>` $tooltip .Project.Title}}
{{end}}
{{if and (gt .OldProjectID 0) (gt .ProjectID 0)}}
{{ctx.Locale.Tr "repo.issues.change_project_at" $oldProjectDisplayHtml $newProjectDisplayHtml $createdStr}}
{{else if gt .OldProjectID 0}}
{{ctx.Locale.Tr "repo.issues.remove_project_at" $oldProjectDisplayHtml $createdStr}}
{{else if gt .ProjectID 0}}
{{if .OldProject}}
{{if .Project}}
{{ctx.Locale.Tr "repo.issues.change_project_at" $oldProjectDisplayHtml $newProjectDisplayHtml $createdStr}}
{{else}}
{{ctx.Locale.Tr "repo.issues.remove_project_at" $oldProjectDisplayHtml $createdStr}}
{{end}}
{{else}}
{{ctx.Locale.Tr "repo.issues.add_project_at" $newProjectDisplayHtml $createdStr}}
{{end}}
</span>

View file

@ -88,22 +88,19 @@ func TestIssueCommentChangeMilestone(t *testing.T) {
testIssueCommentChangeEvent(t, htmlDoc, "2000",
"octicon-milestone", "User One", "/user1",
[]string{"user1 added this to the milestone1 milestone"},
[]string{"/user1"})
// []string{"/user1", "/user2/repo1/milestone/1"})
[]string{"/user1", "/user2/repo1/milestone/1"})
// Modify milestone
testIssueCommentChangeEvent(t, htmlDoc, "2001",
"octicon-milestone", "User One", "/user1",
[]string{"user1 modified the milestone from milestone1 to milestone2"},
[]string{"/user1"})
// []string{"/user1", "/user2/repo1/milestone/1", "/user2/repo1/milestone/2"})
[]string{"/user1", "/user2/repo1/milestone/1", "/user2/repo1/milestone/2"})
// Remove milestone
testIssueCommentChangeEvent(t, htmlDoc, "2002",
"octicon-milestone", "User One", "/user1",
[]string{"user1 removed this from the milestone2 milestone"},
[]string{"/user1"})
// []string{"/user1", "/user2/repo1/milestone/2"})
[]string{"/user1", "/user2/repo1/milestone/2"})
// Deleted milestone
testIssueCommentChangeEvent(t, htmlDoc, "2003",
@ -123,22 +120,19 @@ func TestIssueCommentChangeProject(t *testing.T) {
testIssueCommentChangeEvent(t, htmlDoc, "2010",
"octicon-project", "User One", "/user1",
[]string{"user1 added this to the First project project"},
[]string{"/user1"})
// []string{"/user1", "/user2/repo1/projects/1"})
[]string{"/user1", "/user2/repo1/projects/1"})
// Modify project
testIssueCommentChangeEvent(t, htmlDoc, "2011",
"octicon-project", "User One", "/user1",
[]string{"user1 modified the project from First project to second project"},
[]string{"/user1"})
// []string{"/user1", "/user2/repo1/projects/1", "/user2/repo1/projects/2"})
[]string{"/user1", "/user2/repo1/projects/1", "/user2/repo1/projects/2"})
// Remove project
testIssueCommentChangeEvent(t, htmlDoc, "2012",
"octicon-project", "User One", "/user1",
[]string{"user1 removed this from the second project project"},
[]string{"/user1"})
// []string{"/user1", "/user2/repo1/projects/2"})
[]string{"/user1", "/user2/repo1/projects/2"})
// Deleted project
testIssueCommentChangeEvent(t, htmlDoc, "2013",