diff options
author | Gusted <gusted@noreply.codeberg.org> | 2024-11-02 23:33:30 +0100 |
---|---|---|
committer | Gusted <gusted@noreply.codeberg.org> | 2024-11-02 23:33:30 +0100 |
commit | d5426b0626f415875ac184d8c1a72a5b2cf113c1 (patch) | |
tree | 9a78ebff5d840f92d6dcb5b0e9d7d0dad5a3280e | |
parent | Merge pull request 'Update module github.com/yuin/goldmark to v1.7.8 (forgejo... (diff) | |
parent | feat: Add Search to Releases Page (diff) | |
download | forgejo-d5426b0626f415875ac184d8c1a72a5b2cf113c1.tar.xz forgejo-d5426b0626f415875ac184d8c1a72a5b2cf113c1.zip |
Merge pull request 'feat: Add Search to Releases Page' (#5777) from JakobDev/forgejo:releasesearch into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5777
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-by: Shiny Nematoda <snematoda@noreply.codeberg.org>
-rw-r--r-- | models/repo/release.go | 10 | ||||
-rw-r--r-- | routers/api/v1/repo/release.go | 5 | ||||
-rw-r--r-- | routers/web/repo/release.go | 10 | ||||
-rw-r--r-- | templates/repo/release_tag_header.tmpl | 11 | ||||
-rw-r--r-- | templates/swagger/v1_json.tmpl | 6 | ||||
-rw-r--r-- | tests/integration/api_releases_test.go | 1 | ||||
-rw-r--r-- | tests/integration/release_test.go | 29 |
7 files changed, 69 insertions, 3 deletions
diff --git a/models/repo/release.go b/models/repo/release.go index e2cd7d7ed3..d96eac0d19 100644 --- a/models/repo/release.go +++ b/models/repo/release.go @@ -249,6 +249,7 @@ type FindReleasesOptions struct { IsDraft optional.Option[bool] TagNames []string HasSha1 optional.Option[bool] // useful to find draft releases which are created with existing tags + Keyword string } func (opts FindReleasesOptions) ToConds() builder.Cond { @@ -276,6 +277,15 @@ func (opts FindReleasesOptions) ToConds() builder.Cond { cond = cond.And(builder.Eq{"sha1": ""}) } } + + if opts.Keyword != "" { + keywordCond := builder.NewCond() + keywordCond = keywordCond.Or(builder.Like{"lower_tag_name", strings.ToLower(opts.Keyword)}) + keywordCond = keywordCond.Or(db.BuildCaseInsensitiveLike("title", opts.Keyword)) + keywordCond = keywordCond.Or(db.BuildCaseInsensitiveLike("note", opts.Keyword)) + cond = cond.And(keywordCond) + } + return cond } diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index 5ea4dc8cfc..2fc5f095cb 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -136,6 +136,10 @@ func ListReleases(ctx *context.APIContext) { // in: query // description: filter (exclude / include) pre-releases // type: boolean + // - name: q + // in: query + // description: Search string + // type: string // - name: page // in: query // description: page number of results to return (1-based) @@ -158,6 +162,7 @@ func ListReleases(ctx *context.APIContext) { IsDraft: ctx.FormOptionalBool("draft"), IsPreRelease: ctx.FormOptionalBool("pre-release"), RepoID: ctx.Repo.Repository.ID, + Keyword: ctx.FormTrim("q"), } releases, err := db.Find[repo_model.Release](ctx, opts) diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go index 2266debd6e..65d526d2f2 100644 --- a/routers/web/repo/release.go +++ b/routers/web/repo/release.go @@ -168,6 +168,10 @@ func Releases(ctx *context.Context) { // Disable the showCreateNewBranch form in the dropdown on this page. ctx.Data["CanCreateBranch"] = false ctx.Data["HideBranchesInDropdown"] = true + ctx.Data["ShowReleaseSearch"] = true + + keyword := ctx.FormTrim("q") + ctx.Data["Keyword"] = keyword listOptions := db.ListOptions{ Page: ctx.FormInt("page"), @@ -188,6 +192,7 @@ func Releases(ctx *context.Context) { // only show draft releases for users who can write, read-only users shouldn't see draft releases. IncludeDrafts: writeAccess, RepoID: ctx.Repo.Repository.ID, + Keyword: keyword, }) if err != nil { ctx.ServerError("getReleaseInfos", err) @@ -258,6 +263,10 @@ func TagsList(ctx *context.Context) { ctx.Data["CanCreateBranch"] = false ctx.Data["HideBranchesInDropdown"] = true ctx.Data["CanCreateRelease"] = ctx.Repo.CanWrite(unit.TypeReleases) && !ctx.Repo.Repository.IsArchived + ctx.Data["ShowReleaseSearch"] = true + + keyword := ctx.FormTrim("q") + ctx.Data["Keyword"] = keyword listOptions := db.ListOptions{ Page: ctx.FormInt("page"), @@ -278,6 +287,7 @@ func TagsList(ctx *context.Context) { IncludeTags: true, HasSha1: optional.Some(true), RepoID: ctx.Repo.Repository.ID, + Keyword: keyword, } releases, err := db.Find[repo_model.Release](ctx, opts) diff --git a/templates/repo/release_tag_header.tmpl b/templates/repo/release_tag_header.tmpl index dafe9f2fa6..63d0689c50 100644 --- a/templates/repo/release_tag_header.tmpl +++ b/templates/repo/release_tag_header.tmpl @@ -5,15 +5,20 @@ <div class="tw-flex"> <div class="tw-flex-1 tw-flex tw-items-center"> <h2 class="ui compact small menu small-menu-items"> - <a class="{{if and .PageIsReleaseList (not .PageIsSingleTag)}}active {{end}}item" href="{{.RepoLink}}/releases">{{ctx.Locale.TrN .NumReleases "repo.n_release_one" "repo.n_release_few" (ctx.Locale.PrettyNumber .NumReleases)}}</a> + <a class="{{if and .PageIsReleaseList (not .PageIsSingleTag)}}active {{end}}item" href="{{.RepoLink}}/releases{{if .Keyword}}?q={{.Keyword}}{{end}}">{{ctx.Locale.TrN .NumReleases "repo.n_release_one" "repo.n_release_few" (ctx.Locale.PrettyNumber .NumReleases)}}</a> {{if $canReadCode}} - <a class="{{if or .PageIsTagList .PageIsSingleTag}}active {{end}}item" href="{{.RepoLink}}/tags">{{ctx.Locale.TrN .NumTags "repo.n_tag_one" "repo.n_tag_few" (ctx.Locale.PrettyNumber .NumTags)}}</a> + <a class="{{if or .PageIsTagList .PageIsSingleTag}}active {{end}}item" href="{{.RepoLink}}/tags{{if .Keyword}}?q={{.Keyword}}{{end}}">{{ctx.Locale.TrN .NumTags "repo.n_tag_one" "repo.n_tag_few" (ctx.Locale.PrettyNumber .NumTags)}}</a> {{end}} </h2> </div> + {{if .ShowReleaseSearch}} + <form class="ignore-dirty tw-w-1/5 tw-mr-3" method="get"> + {{template "shared/search/combo" dict "Value" .Keyword}} + </form> + {{end}} <div class="button-row"> {{if .EnableFeed}} - <a class="ui small button" href="{{.RepoLink}}/{{if .PageIsTagList}}tags{{else}}releases{{end}}.rss"> + <a class="ui small button tw-h-full" href="{{.RepoLink}}/{{if .PageIsTagList}}tags{{else}}releases{{end}}.rss"> {{svg "octicon-rss" 16}} {{ctx.Locale.Tr "rss_feed"}} </a> {{end}} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index dcf505cc7d..8e64c68f89 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -14164,6 +14164,12 @@ "in": "query" }, { + "type": "string", + "description": "Search string", + "name": "q", + "in": "query" + }, + { "type": "integer", "description": "page number of results to return (1-based)", "name": "page", diff --git a/tests/integration/api_releases_test.go b/tests/integration/api_releases_test.go index 1bd8a643ad..1327daf57e 100644 --- a/tests/integration/api_releases_test.go +++ b/tests/integration/api_releases_test.go @@ -76,6 +76,7 @@ func TestAPIListReleases(t *testing.T) { testFilterByLen(true, url.Values{"draft": {"false"}, "pre-release": {"false"}}, 1, "exclude drafts and pre-releases") testFilterByLen(true, url.Values{"pre-release": {"true"}}, 1, "only get pre-release") testFilterByLen(true, url.Values{"draft": {"true"}, "pre-release": {"true"}}, 0, "there is no pre-release draft") + testFilterByLen(true, url.Values{"q": {"release"}}, 3, "keyword") } func createNewReleaseUsingAPI(t *testing.T, token string, owner *user_model.User, repo *repo_model.Repository, name, target, title, desc string) *api.Release { diff --git a/tests/integration/release_test.go b/tests/integration/release_test.go index 48c2b37c91..c535c6c93d 100644 --- a/tests/integration/release_test.go +++ b/tests/integration/release_test.go @@ -272,6 +272,35 @@ func TestViewReleaseListLogin(t *testing.T) { }, links) } +func TestViewReleaseListKeyword(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + + link := repo.Link() + "/releases?q=testing" + + session := loginUser(t, "user1") + req := NewRequest(t, "GET", link) + rsp := session.MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, rsp.Body) + releases := htmlDoc.Find("#release-list li.ui.grid") + assert.Equal(t, 1, releases.Length()) + + links := make([]string, 0, 5) + releases.Each(func(i int, s *goquery.Selection) { + link, exist := s.Find(".release-list-title a").Attr("href") + if !exist { + return + } + links = append(links, link) + }) + + assert.EqualValues(t, []string{ + "/user2/repo1/releases/tag/v1.1", + }, links) +} + func TestReleaseOnCommit(t *testing.T) { defer tests.PrepareTestEnv(t)() |