From 82728d903dbaca1452b0d1fb2234115d182631c2 Mon Sep 17 00:00:00 2001 From: Lucas Schwiderski Date: Thu, 4 Sep 2025 23:29:34 +0200 Subject: [PATCH] fix(ui): show participants in mention suggestions in pr review (#8363) Closes: #5035 Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8363 Reviewed-by: Gusted Co-authored-by: Lucas Schwiderski Co-committed-by: Lucas Schwiderski --- models/issues/issue.go | 4 +-- modules/indexer/issues/indexer_test.go | 2 +- routers/web/repo/issue.go | 46 ++++++++++++++++++++++++++ routers/web/repo/pull.go | 7 ++++ tests/e2e/pr-review.test.e2e.ts | 20 +++++++++++ 5 files changed, 76 insertions(+), 3 deletions(-) diff --git a/models/issues/issue.go b/models/issues/issue.go index 8c0ddb8ddf..14848e4c98 100644 --- a/models/issues/issue.go +++ b/models/issues/issue.go @@ -237,7 +237,7 @@ func (issue *Issue) LoadPullRequest(ctx context.Context) (err error) { return nil } -func (issue *Issue) loadComments(ctx context.Context) (err error) { +func (issue *Issue) LoadComments(ctx context.Context) (err error) { return issue.loadCommentsByType(ctx, CommentTypeUndefined) } @@ -341,7 +341,7 @@ func (issue *Issue) LoadAttributes(ctx context.Context) (err error) { return err } - if err = issue.loadComments(ctx); err != nil { + if err = issue.LoadComments(ctx); err != nil { return err } diff --git a/modules/indexer/issues/indexer_test.go b/modules/indexer/issues/indexer_test.go index d3b3494672..21daea3d45 100644 --- a/modules/indexer/issues/indexer_test.go +++ b/modules/indexer/issues/indexer_test.go @@ -84,7 +84,7 @@ func searchIssueWithKeyword(t *testing.T) { issueIDs, _, err := SearchIssues(t.Context(), &test.opts) require.NoError(t, err) - assert.Equal(t, test.expectedIDs, issueIDs) + assert.Equal(t, test.expectedIDs, issueIDs, test.opts.Keyword) } } diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 715f5dca8f..f445ce4a1a 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -3777,3 +3777,49 @@ func issuePosters(ctx *context.Context, isPullList bool) { } ctx.JSON(http.StatusOK, resp) } + +func getIssueParticipants(ctx *context.Context, issue *issues_model.Issue) []*user_model.User { + var ( + participants = make([]*user_model.User, 1, 10) + comment *issues_model.Comment + ) + + participants[0] = issue.Poster + + if err := issue.LoadComments(ctx); err != nil { + ctx.ServerError("loadComments", err) + return nil + } + + if err := issue.Comments.LoadPosters(ctx); err != nil { + ctx.ServerError("LoadPosters", err) + return nil + } + + for _, comment = range issue.Comments { + if comment.Type == issues_model.CommentTypeComment || + comment.Type == issues_model.CommentTypeReview || + comment.Type == issues_model.CommentTypePullRequestPush { + participants = addParticipant(comment.Poster, participants) + } else if comment.Type.HasContentSupport() { + participants = addParticipant(comment.Poster, participants) + + if comment.Review == nil { + continue + } + if err := comment.Review.LoadCodeComments(ctx); err != nil { + ctx.ServerError("Review.LoadCodeComments", err) + return nil + } + for _, codeComments := range comment.Review.CodeComments { + for _, lineComments := range codeComments { + for _, c := range lineComments { + participants = addParticipant(c.Poster, participants) + } + } + } + } + } + + return participants +} diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 65772086bc..e484187b54 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -1167,6 +1167,13 @@ func viewPullFiles(ctx *context.Context, specifiedStartCommit, specifiedEndCommi } ctx.Data["Assignees"] = MakeSelfOnTop(ctx.Doer, assigneeUsers) + participants := getIssueParticipants(ctx, issue) + if ctx.Written() { + return + } + ctx.Data["Participants"] = participants + ctx.Data["NumParticipants"] = len(participants) + handleTeamMentions(ctx) if ctx.Written() { return diff --git a/tests/e2e/pr-review.test.e2e.ts b/tests/e2e/pr-review.test.e2e.ts index 03f3a3d8b3..4e95e0aa69 100644 --- a/tests/e2e/pr-review.test.e2e.ts +++ b/tests/e2e/pr-review.test.e2e.ts @@ -112,3 +112,23 @@ test('PR: Navigate by single commit', async ({page}) => { await expect(nextButton).toHaveClass(/disabled/); await expect(prevButton).toHaveAttribute('href', '/user2/repo1/pulls/3/commits/4a357436d925b5c974181ff12a994538ddc5a269'); }); + +test('PR: Test mentions values', async ({page}) => { + const response = await page.goto('/user2/repo1/pulls/5/files'); + expect(response?.status()).toBe(200); + + await page.locator('#review-box .js-btn-review').click(); + await expect(page.locator('.tippy-box .review-box-panel')).toBeVisible(); + + await page.locator('.review-box-panel textarea#_combo_markdown_editor_0') + .fill('@'); + await save_visual(page); + + await expect(page.locator('ul.suggestions li span:first-of-type')).toContainText([ + 'user1', + 'user2', + ]); + + await page.locator("ul.suggestions li[data-value='@user1']").click(); + await expect(page.locator('.review-box-panel textarea#_combo_markdown_editor_0')).toHaveValue('@user1 '); +});