[FEAT] expose fuzzy search for issues/repo (#4160)

Ports fuzzy search for `/issues` and `/pulls` from gitea.
Adds fuzzy search for `/user/repo/issues` and `/user/repo/pulls`.

---
## Notes
### Port: [`gitea#be5be0ac81`](be5be0ac81)

- CONFLICT (content): Merge conflict in routers/web/user/home.go

Conflict resolved by
  1. keeping both `PageIsOrgIssues` and the newly introduced `IsFuzzy`
  2. using `pager.AddParam(ctx, "fuzzy", "IsFuzzy")` rather than `pager.AddParamString("fuzzy", fmt.Sprintf("%v", isFuzzy))`

- CONFLICT (content): Merge conflict in templates/user/dashboard/issues.tmpl

Conflict resolved by keeping the changes from #4096, and picking the `&fuzzy=${{.IsFuzzy}}` inclusion to all urls and `{{if .PageIsPulls}}...`

### Port: [`gitea#fede3cbada`](fede3cbada)

- CONFLICT (content): Merge conflict in templates/user/dashboard/issues.tmpl

Conflict resolved by keeping previous changes and picking the replacement of `{{if .PageIsPulls}}...` with `{{template "shared/search/combo_fuzzy"...` which contains the replacement of `explorer.go` to `explorer.go_to`

### Fixup commit

replaces `Iif` with `if` which was introduced in gitea#fede3cbada

### Feature commit

adds in support for /user/repo/(issues|pulls) + test

Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: Kerwin Bryant <kerwin612@qq.com>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/4160
Reviewed-by: twenty-panda <twenty-panda@noreply.codeberg.org>
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Shiny Nematoda <snematoda.751k2@aleeas.com>
Co-committed-by: Shiny Nematoda <snematoda.751k2@aleeas.com>
This commit is contained in:
Shiny Nematoda 2024-06-17 18:58:24 +00:00 committed by Earl Warren
parent bd23b8c75f
commit b5d96e7db7
9 changed files with 79 additions and 34 deletions

View file

@ -201,6 +201,8 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
keyword = ""
}
isFuzzy := ctx.FormBool("fuzzy")
var mileIDs []int64
if milestoneID > 0 || milestoneID == db.NoConditionID { // -1 to get those issues which have no any milestone assigned
mileIDs = []int64{milestoneID}
@ -221,7 +223,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
IssueIDs: nil,
}
if keyword != "" {
allIssueIDs, err := issueIDsFromSearch(ctx, keyword, statsOpts)
allIssueIDs, err := issueIDsFromSearch(ctx, keyword, isFuzzy, statsOpts)
if err != nil {
if issue_indexer.IsAvailable(ctx) {
ctx.ServerError("issueIDsFromSearch", err)
@ -289,7 +291,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
var issues issues_model.IssueList
{
ids, err := issueIDsFromSearch(ctx, keyword, &issues_model.IssuesOptions{
ids, err := issueIDsFromSearch(ctx, keyword, isFuzzy, &issues_model.IssuesOptions{
Paginator: &db.ListOptions{
Page: pager.Paginater.Current(),
PageSize: setting.UI.IssuePagingNum,
@ -465,6 +467,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
ctx.Data["ProjectID"] = projectID
ctx.Data["AssigneeID"] = assigneeID
ctx.Data["PosterID"] = posterID
ctx.Data["IsFuzzy"] = isFuzzy
ctx.Data["Keyword"] = keyword
switch {
case isShowClosed.Value():
@ -486,12 +489,17 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
pager.AddParam(ctx, "assignee", "AssigneeID")
pager.AddParam(ctx, "poster", "PosterID")
pager.AddParam(ctx, "archived", "ShowArchivedLabels")
pager.AddParam(ctx, "fuzzy", "IsFuzzy")
ctx.Data["Page"] = pager
}
func issueIDsFromSearch(ctx *context.Context, keyword string, opts *issues_model.IssuesOptions) ([]int64, error) {
ids, _, err := issue_indexer.SearchIssues(ctx, issue_indexer.ToSearchOptions(keyword, opts))
func issueIDsFromSearch(ctx *context.Context, keyword string, fuzzy bool, opts *issues_model.IssuesOptions) ([]int64, error) {
ids, _, err := issue_indexer.SearchIssues(ctx, issue_indexer.ToSearchOptions(keyword, opts).Copy(
func(o *issue_indexer.SearchOptions) {
o.IsFuzzyKeyword = fuzzy
},
))
if err != nil {
return nil, fmt.Errorf("SearchIssues: %w", err)
}

View file

@ -447,6 +447,8 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
User: ctx.Doer,
}
isFuzzy := ctx.FormBool("fuzzy")
// Search all repositories which
//
// As user:
@ -576,7 +578,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
// USING FINAL STATE OF opts FOR A QUERY.
var issues issues_model.IssueList
{
issueIDs, _, err := issue_indexer.SearchIssues(ctx, issue_indexer.ToSearchOptions(keyword, opts))
issueIDs, _, err := issue_indexer.SearchIssues(ctx, issue_indexer.ToSearchOptions(keyword, opts).Copy(
func(o *issue_indexer.SearchOptions) { o.IsFuzzyKeyword = isFuzzy },
))
if err != nil {
ctx.ServerError("issueIDsFromSearch", err)
return
@ -597,7 +601,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
// -------------------------------
// Fill stats to post to ctx.Data.
// -------------------------------
issueStats, err := getUserIssueStats(ctx, ctxUser, filterMode, issue_indexer.ToSearchOptions(keyword, opts))
issueStats, err := getUserIssueStats(ctx, ctxUser, filterMode, issue_indexer.ToSearchOptions(keyword, opts).Copy(
func(o *issue_indexer.SearchOptions) { o.IsFuzzyKeyword = isFuzzy },
))
if err != nil {
ctx.ServerError("getUserIssueStats", err)
return
@ -652,6 +658,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
ctx.Data["IsShowClosed"] = isShowClosed
ctx.Data["SelectLabels"] = selectedLabels
ctx.Data["PageIsOrgIssues"] = org != nil
ctx.Data["IsFuzzy"] = isFuzzy
if isShowClosed {
ctx.Data["State"] = "closed"
@ -667,6 +674,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
pager.AddParam(ctx, "labels", "SelectLabels")
pager.AddParam(ctx, "milestone", "MilestoneID")
pager.AddParam(ctx, "assignee", "AssigneeID")
pager.AddParam(ctx, "fuzzy", "IsFuzzy")
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplIssues)