feat: Add Search to Releases Page
This commit is contained in:
		
					parent
					
						
							
								e5e2860221
							
						
					
				
			
			
				commit
				
					
						86546fe63e
					
				
			
		
					 7 changed files with 69 additions and 3 deletions
				
			
		| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								templates/swagger/v1_json.tmpl
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								templates/swagger/v1_json.tmpl
									
										
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -14163,6 +14163,12 @@
 | 
			
		|||
            "name": "pre-release",
 | 
			
		||||
            "in": "query"
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "string",
 | 
			
		||||
            "description": "Search string",
 | 
			
		||||
            "name": "q",
 | 
			
		||||
            "in": "query"
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "integer",
 | 
			
		||||
            "description": "page number of results to return (1-based)",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue