mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-04 01:10:49 +01:00
Allow to filter repositories by language in explore, user and organization repositories lists (#18430)
This commit is contained in:
parent
401e5c8174
commit
604ce77628
6 changed files with 43 additions and 11 deletions
|
@ -136,6 +136,8 @@ type SearchRepoOptions struct {
|
||||||
Archived util.OptionalBool
|
Archived util.OptionalBool
|
||||||
// only search topic name
|
// only search topic name
|
||||||
TopicOnly bool
|
TopicOnly bool
|
||||||
|
// only search repositories with specified primary language
|
||||||
|
Language string
|
||||||
// include description in keyword search
|
// include description in keyword search
|
||||||
IncludeDescription bool
|
IncludeDescription bool
|
||||||
// None -> include has milestones AND has no milestone
|
// None -> include has milestones AND has no milestone
|
||||||
|
@ -439,6 +441,13 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
|
||||||
cond = cond.And(keywordCond)
|
cond = cond.And(keywordCond)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opts.Language != "" {
|
||||||
|
cond = cond.And(builder.In("id", builder.
|
||||||
|
Select("repo_id").
|
||||||
|
From("language_stat").
|
||||||
|
Where(builder.Eq{"language": opts.Language}).And(builder.Eq{"is_primary": true})))
|
||||||
|
}
|
||||||
|
|
||||||
if opts.Fork != util.OptionalBoolNone {
|
if opts.Fork != util.OptionalBoolNone {
|
||||||
cond = cond.And(builder.Eq{"is_fork": opts.Fork == util.OptionalBoolTrue})
|
cond = cond.And(builder.Eq{"is_fork": opts.Fork == util.OptionalBoolTrue})
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,9 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
|
||||||
topicOnly := ctx.FormBool("topic")
|
topicOnly := ctx.FormBool("topic")
|
||||||
ctx.Data["TopicOnly"] = topicOnly
|
ctx.Data["TopicOnly"] = topicOnly
|
||||||
|
|
||||||
|
language := ctx.FormTrim("language")
|
||||||
|
ctx.Data["Language"] = language
|
||||||
|
|
||||||
repos, count, err = models.SearchRepository(&models.SearchRepoOptions{
|
repos, count, err = models.SearchRepository(&models.SearchRepoOptions{
|
||||||
ListOptions: db.ListOptions{
|
ListOptions: db.ListOptions{
|
||||||
Page: page,
|
Page: page,
|
||||||
|
@ -91,6 +94,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
|
||||||
AllPublic: true,
|
AllPublic: true,
|
||||||
AllLimited: true,
|
AllLimited: true,
|
||||||
TopicOnly: topicOnly,
|
TopicOnly: topicOnly,
|
||||||
|
Language: language,
|
||||||
IncludeDescription: setting.UI.SearchRepoDescription,
|
IncludeDescription: setting.UI.SearchRepoDescription,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -105,6 +109,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
|
||||||
pager := context.NewPagination(int(count), opts.PageSize, page, 5)
|
pager := context.NewPagination(int(count), opts.PageSize, page, 5)
|
||||||
pager.SetDefaultParams(ctx)
|
pager.SetDefaultParams(ctx)
|
||||||
pager.AddParam(ctx, "topic", "TopicOnly")
|
pager.AddParam(ctx, "topic", "TopicOnly")
|
||||||
|
pager.AddParam(ctx, "language", "Language")
|
||||||
ctx.Data["Page"] = pager
|
ctx.Data["Page"] = pager
|
||||||
|
|
||||||
ctx.HTML(http.StatusOK, opts.TplName)
|
ctx.HTML(http.StatusOK, opts.TplName)
|
||||||
|
|
|
@ -83,6 +83,9 @@ func Home(ctx *context.Context) {
|
||||||
keyword := ctx.FormTrim("q")
|
keyword := ctx.FormTrim("q")
|
||||||
ctx.Data["Keyword"] = keyword
|
ctx.Data["Keyword"] = keyword
|
||||||
|
|
||||||
|
language := ctx.FormTrim("language")
|
||||||
|
ctx.Data["Language"] = language
|
||||||
|
|
||||||
page := ctx.FormInt("page")
|
page := ctx.FormInt("page")
|
||||||
if page <= 0 {
|
if page <= 0 {
|
||||||
page = 1
|
page = 1
|
||||||
|
@ -103,6 +106,7 @@ func Home(ctx *context.Context) {
|
||||||
OrderBy: orderBy,
|
OrderBy: orderBy,
|
||||||
Private: ctx.IsSigned,
|
Private: ctx.IsSigned,
|
||||||
Actor: ctx.User,
|
Actor: ctx.User,
|
||||||
|
Language: language,
|
||||||
IncludeDescription: setting.UI.SearchRepoDescription,
|
IncludeDescription: setting.UI.SearchRepoDescription,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -148,6 +152,7 @@ func Home(ctx *context.Context) {
|
||||||
|
|
||||||
pager := context.NewPagination(int(count), setting.UI.User.RepoPagingNum, page, 5)
|
pager := context.NewPagination(int(count), setting.UI.User.RepoPagingNum, page, 5)
|
||||||
pager.SetDefaultParams(ctx)
|
pager.SetDefaultParams(ctx)
|
||||||
|
pager.AddParam(ctx, "language", "Language")
|
||||||
ctx.Data["Page"] = pager
|
ctx.Data["Page"] = pager
|
||||||
|
|
||||||
ctx.HTML(http.StatusOK, tplOrgHome)
|
ctx.HTML(http.StatusOK, tplOrgHome)
|
||||||
|
|
|
@ -232,6 +232,10 @@ func Profile(ctx *context.Context) {
|
||||||
|
|
||||||
keyword := ctx.FormTrim("q")
|
keyword := ctx.FormTrim("q")
|
||||||
ctx.Data["Keyword"] = keyword
|
ctx.Data["Keyword"] = keyword
|
||||||
|
|
||||||
|
language := ctx.FormTrim("language")
|
||||||
|
ctx.Data["Language"] = language
|
||||||
|
|
||||||
switch tab {
|
switch tab {
|
||||||
case "followers":
|
case "followers":
|
||||||
items, err := user_model.GetUserFollowers(ctxUser, db.ListOptions{
|
items, err := user_model.GetUserFollowers(ctxUser, db.ListOptions{
|
||||||
|
@ -283,6 +287,7 @@ func Profile(ctx *context.Context) {
|
||||||
StarredByID: ctxUser.ID,
|
StarredByID: ctxUser.ID,
|
||||||
Collaborate: util.OptionalBoolFalse,
|
Collaborate: util.OptionalBoolFalse,
|
||||||
TopicOnly: topicOnly,
|
TopicOnly: topicOnly,
|
||||||
|
Language: language,
|
||||||
IncludeDescription: setting.UI.SearchRepoDescription,
|
IncludeDescription: setting.UI.SearchRepoDescription,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -314,6 +319,7 @@ func Profile(ctx *context.Context) {
|
||||||
WatchedByID: ctxUser.ID,
|
WatchedByID: ctxUser.ID,
|
||||||
Collaborate: util.OptionalBoolFalse,
|
Collaborate: util.OptionalBoolFalse,
|
||||||
TopicOnly: topicOnly,
|
TopicOnly: topicOnly,
|
||||||
|
Language: language,
|
||||||
IncludeDescription: setting.UI.SearchRepoDescription,
|
IncludeDescription: setting.UI.SearchRepoDescription,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -335,6 +341,7 @@ func Profile(ctx *context.Context) {
|
||||||
Private: ctx.IsSigned,
|
Private: ctx.IsSigned,
|
||||||
Collaborate: util.OptionalBoolFalse,
|
Collaborate: util.OptionalBoolFalse,
|
||||||
TopicOnly: topicOnly,
|
TopicOnly: topicOnly,
|
||||||
|
Language: language,
|
||||||
IncludeDescription: setting.UI.SearchRepoDescription,
|
IncludeDescription: setting.UI.SearchRepoDescription,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -349,6 +356,9 @@ func Profile(ctx *context.Context) {
|
||||||
|
|
||||||
pager := context.NewPagination(total, setting.UI.User.RepoPagingNum, page, 5)
|
pager := context.NewPagination(total, setting.UI.User.RepoPagingNum, page, 5)
|
||||||
pager.SetDefaultParams(ctx)
|
pager.SetDefaultParams(ctx)
|
||||||
|
if tab != "followers" && tab != "following" && tab != "activity" && tab != "projects" {
|
||||||
|
pager.AddParam(ctx, "language", "Language")
|
||||||
|
}
|
||||||
ctx.Data["Page"] = pager
|
ctx.Data["Page"] = pager
|
||||||
|
|
||||||
ctx.Data["ShowUserEmail"] = len(ctxUser.Email) > 0 && ctx.IsSigned && (!ctxUser.KeepEmailPrivate || ctxUser.ID == ctx.User.ID)
|
ctx.Data["ShowUserEmail"] = len(ctxUser.Email) > 0 && ctx.IsSigned && (!ctxUser.KeepEmailPrivate || ctxUser.ID == ctx.User.ID)
|
||||||
|
|
|
@ -40,7 +40,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="metas df ac">
|
<div class="metas df ac">
|
||||||
{{if .PrimaryLanguage }}
|
{{if .PrimaryLanguage }}
|
||||||
<span class="text grey df ac mr-3"><i class="color-icon mr-3" style="background-color: {{.PrimaryLanguage.Color}}"></i>{{ .PrimaryLanguage.Language }}</span>
|
<a href="{{$.Link}}?tab={{$.TabName}}&q={{$.Keyword}}&sort={{$.SortType}}&language={{.PrimaryLanguage.Language}}">
|
||||||
|
<span class="text grey df ac mr-3"><i class="color-icon mr-3" style="background-color: {{.PrimaryLanguage.Color}}"></i>{{ .PrimaryLanguage.Language }}</span>
|
||||||
|
</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if not $.DisableStars}}
|
{{if not $.DisableStars}}
|
||||||
<span class="text grey df ac mr-3">{{svg "octicon-star" 16 "mr-3"}}{{.NumStars}}</span>
|
<span class="text grey df ac mr-3">{{svg "octicon-star" 16 "mr-3"}}{{.NumStars}}</span>
|
||||||
|
|
|
@ -6,24 +6,25 @@
|
||||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||||
</span>
|
</span>
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
<a class="{{if eq .SortType "newest"}}active{{end}} item" href="{{$.Link}}?sort=newest&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.latest"}}</a>
|
<a class="{{if eq .SortType "newest"}}active{{end}} item" href="{{$.Link}}?sort=newest&q={{$.Keyword}}&tab={{$.TabName}}&language={{$.Language}}">{{.i18n.Tr "repo.issues.filter_sort.latest"}}</a>
|
||||||
<a class="{{if eq .SortType "oldest"}}active{{end}} item" href="{{$.Link}}?sort=oldest&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.oldest"}}</a>
|
<a class="{{if eq .SortType "oldest"}}active{{end}} item" href="{{$.Link}}?sort=oldest&q={{$.Keyword}}&tab={{$.TabName}}&language={{$.Language}}">{{.i18n.Tr "repo.issues.filter_sort.oldest"}}</a>
|
||||||
<a class="{{if eq .SortType "alphabetically"}}active{{end}} item" href="{{$.Link}}?sort=alphabetically&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.label.filter_sort.alphabetically"}}</a>
|
<a class="{{if eq .SortType "alphabetically"}}active{{end}} item" href="{{$.Link}}?sort=alphabetically&q={{$.Keyword}}&tab={{$.TabName}}&language={{$.Language}}">{{.i18n.Tr "repo.issues.label.filter_sort.alphabetically"}}</a>
|
||||||
<a class="{{if eq .SortType "reversealphabetically"}}active{{end}} item" href="{{$.Link}}?sort=reversealphabetically&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.label.filter_sort.reverse_alphabetically"}}</a>
|
<a class="{{if eq .SortType "reversealphabetically"}}active{{end}} item" href="{{$.Link}}?sort=reversealphabetically&q={{$.Keyword}}&tab={{$.TabName}}&language={{$.Language}}">{{.i18n.Tr "repo.issues.label.filter_sort.reverse_alphabetically"}}</a>
|
||||||
<a class="{{if eq .SortType "recentupdate"}}active{{end}} item" href="{{$.Link}}?sort=recentupdate&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.recentupdate"}}</a>
|
<a class="{{if eq .SortType "recentupdate"}}active{{end}} item" href="{{$.Link}}?sort=recentupdate&q={{$.Keyword}}&tab={{$.TabName}}&language={{$.Language}}">{{.i18n.Tr "repo.issues.filter_sort.recentupdate"}}</a>
|
||||||
<a class="{{if eq .SortType "leastupdate"}}active{{end}} item" href="{{$.Link}}?sort=leastupdate&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.leastupdate"}}</a>
|
<a class="{{if eq .SortType "leastupdate"}}active{{end}} item" href="{{$.Link}}?sort=leastupdate&q={{$.Keyword}}&tab={{$.TabName}}&language={{$.Language}}">{{.i18n.Tr "repo.issues.filter_sort.leastupdate"}}</a>
|
||||||
{{if not .DisableStars}}
|
{{if not .DisableStars}}
|
||||||
<a class="{{if eq .SortType "moststars"}}active{{end}} item" href="{{$.Link}}?sort=moststars&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.moststars"}}</a>
|
<a class="{{if eq .SortType "moststars"}}active{{end}} item" href="{{$.Link}}?sort=moststars&q={{$.Keyword}}&tab={{$.TabName}}&language={{$.Language}}">{{.i18n.Tr "repo.issues.filter_sort.moststars"}}</a>
|
||||||
<a class="{{if eq .SortType "feweststars"}}active{{end}} item" href="{{$.Link}}?sort=feweststars&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.feweststars"}}</a>
|
<a class="{{if eq .SortType "feweststars"}}active{{end}} item" href="{{$.Link}}?sort=feweststars&q={{$.Keyword}}&tab={{$.TabName}}&language={{$.Language}}">{{.i18n.Tr "repo.issues.filter_sort.feweststars"}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
<a class="{{if eq .SortType "mostforks"}}active{{end}} item" href="{{$.Link}}?sort=mostforks&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.mostforks"}}</a>
|
<a class="{{if eq .SortType "mostforks"}}active{{end}} item" href="{{$.Link}}?sort=mostforks&q={{$.Keyword}}&tab={{$.TabName}}&language={{$.Language}}">{{.i18n.Tr "repo.issues.filter_sort.mostforks"}}</a>
|
||||||
<a class="{{if eq .SortType "fewestforks"}}active{{end}} item" href="{{$.Link}}?sort=fewestforks&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.fewestforks"}}</a>
|
<a class="{{if eq .SortType "fewestforks"}}active{{end}} item" href="{{$.Link}}?sort=fewestforks&q={{$.Keyword}}&tab={{$.TabName}}&language={{$.Language}}">{{.i18n.Tr "repo.issues.filter_sort.fewestforks"}}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form class="ui form ignore-dirty" style="max-width: 90%">
|
<form class="ui form ignore-dirty" style="max-width: 90%">
|
||||||
<input type="hidden" name="tab" value="{{$.TabName}}">
|
<input type="hidden" name="tab" value="{{$.TabName}}">
|
||||||
<input type="hidden" name="sort" value="{{$.SortType}}">
|
<input type="hidden" name="sort" value="{{$.SortType}}">
|
||||||
|
<input type="hidden" name="language" value="{{$.Language}}">
|
||||||
<div class="ui fluid action input">
|
<div class="ui fluid action input">
|
||||||
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus>
|
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus>
|
||||||
<button class="ui blue button">{{.i18n.Tr "explore.search"}}</button>
|
<button class="ui blue button">{{.i18n.Tr "explore.search"}}</button>
|
||||||
|
|
Loading…
Reference in a new issue