Allow package version sorting (#21453)
This commit is contained in:
		
							parent
							
								
									63ebb53fd5
								
							
						
					
					
						commit
						876ee8c3cd
					
				| @ -165,6 +165,7 @@ type ImageTagsSearchOptions struct { | |||||||
| 	PackageID int64 | 	PackageID int64 | ||||||
| 	Query     string | 	Query     string | ||||||
| 	IsTagged  bool | 	IsTagged  bool | ||||||
|  | 	Sort      packages.VersionSort | ||||||
| 	db.Paginator | 	db.Paginator | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -195,12 +196,26 @@ func (opts *ImageTagsSearchOptions) toConds() builder.Cond { | |||||||
| 	return cond | 	return cond | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (opts *ImageTagsSearchOptions) configureOrderBy(e db.Engine) { | ||||||
|  | 	switch opts.Sort { | ||||||
|  | 	case packages.SortVersionDesc: | ||||||
|  | 		e.Desc("package_version.version") | ||||||
|  | 	case packages.SortVersionAsc: | ||||||
|  | 		e.Asc("package_version.version") | ||||||
|  | 	case packages.SortCreatedAsc: | ||||||
|  | 		e.Asc("package_version.created_unix") | ||||||
|  | 	default: | ||||||
|  | 		e.Desc("package_version.created_unix") | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // SearchImageTags gets a sorted list of the tags of an image | // SearchImageTags gets a sorted list of the tags of an image | ||||||
| func SearchImageTags(ctx context.Context, opts *ImageTagsSearchOptions) ([]*packages.PackageVersion, int64, error) { | func SearchImageTags(ctx context.Context, opts *ImageTagsSearchOptions) ([]*packages.PackageVersion, int64, error) { | ||||||
| 	sess := db.GetEngine(ctx). | 	sess := db.GetEngine(ctx). | ||||||
| 		Join("INNER", "package", "package.id = package_version.package_id"). | 		Join("INNER", "package", "package.id = package_version.package_id"). | ||||||
| 		Where(opts.toConds()). | 		Where(opts.toConds()) | ||||||
| 		Desc("package_version.created_unix") | 
 | ||||||
|  | 	opts.configureOrderBy(sess) | ||||||
| 
 | 
 | ||||||
| 	if opts.Paginator != nil { | 	if opts.Paginator != nil { | ||||||
| 		sess = db.SetSessionPagination(sess, opts) | 		sess = db.SetSessionPagination(sess, opts) | ||||||
|  | |||||||
| @ -163,6 +163,17 @@ type SearchValue struct { | |||||||
| 	ExactMatch bool | 	ExactMatch bool | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | type VersionSort = string | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	SortNameAsc     VersionSort = "name_asc" | ||||||
|  | 	SortNameDesc    VersionSort = "name_desc" | ||||||
|  | 	SortVersionAsc  VersionSort = "version_asc" | ||||||
|  | 	SortVersionDesc VersionSort = "version_desc" | ||||||
|  | 	SortCreatedAsc  VersionSort = "created_asc" | ||||||
|  | 	SortCreatedDesc VersionSort = "created_desc" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| // PackageSearchOptions are options for SearchXXX methods | // PackageSearchOptions are options for SearchXXX methods | ||||||
| // Besides IsInternal are all fields optional and are not used if they have their default value (nil, "", 0) | // Besides IsInternal are all fields optional and are not used if they have their default value (nil, "", 0) | ||||||
| type PackageSearchOptions struct { | type PackageSearchOptions struct { | ||||||
| @ -176,7 +187,7 @@ type PackageSearchOptions struct { | |||||||
| 	IsInternal      util.OptionalBool | 	IsInternal      util.OptionalBool | ||||||
| 	HasFileWithName string            // only results are found which are associated with a file with the specific name | 	HasFileWithName string            // only results are found which are associated with a file with the specific name | ||||||
| 	HasFiles        util.OptionalBool // only results are found which have associated files | 	HasFiles        util.OptionalBool // only results are found which have associated files | ||||||
| 	Sort            string | 	Sort            VersionSort | ||||||
| 	db.Paginator | 	db.Paginator | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -254,15 +265,15 @@ func (opts *PackageSearchOptions) toConds() builder.Cond { | |||||||
| 
 | 
 | ||||||
| func (opts *PackageSearchOptions) configureOrderBy(e db.Engine) { | func (opts *PackageSearchOptions) configureOrderBy(e db.Engine) { | ||||||
| 	switch opts.Sort { | 	switch opts.Sort { | ||||||
| 	case "alphabetically": | 	case SortNameAsc: | ||||||
| 		e.Asc("package.name") | 		e.Asc("package.name") | ||||||
| 	case "reversealphabetically": | 	case SortNameDesc: | ||||||
| 		e.Desc("package.name") | 		e.Desc("package.name") | ||||||
| 	case "highestversion": | 	case SortVersionDesc: | ||||||
| 		e.Desc("package_version.version") | 		e.Desc("package_version.version") | ||||||
| 	case "lowestversion": | 	case SortVersionAsc: | ||||||
| 		e.Asc("package_version.version") | 		e.Asc("package_version.version") | ||||||
| 	case "oldest": | 	case SortCreatedAsc: | ||||||
| 		e.Asc("package_version.created_unix") | 		e.Asc("package_version.created_unix") | ||||||
| 	default: | 	default: | ||||||
| 		e.Desc("package_version.created_unix") | 		e.Desc("package_version.created_unix") | ||||||
|  | |||||||
| @ -106,6 +106,10 @@ never = Never | |||||||
| 
 | 
 | ||||||
| rss_feed = RSS Feed | rss_feed = RSS Feed | ||||||
| 
 | 
 | ||||||
|  | [filter] | ||||||
|  | string.asc = A - Z | ||||||
|  | string.desc = Z - A | ||||||
|  | 
 | ||||||
| [error] | [error] | ||||||
| occurred = An error occurred | occurred = An error occurred | ||||||
| report_message = If you are sure this is a Gitea bug, please search for issues on <a href="https://github.com/go-gitea/gitea/issues" target="_blank">GitHub</a> or open a new issue if necessary. | report_message = If you are sure this is a Gitea bug, please search for issues on <a href="https://github.com/go-gitea/gitea/issues" target="_blank">GitHub</a> or open a new issue if necessary. | ||||||
|  | |||||||
| @ -233,6 +233,7 @@ func ListPackageVersions(ctx *context.Context) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	query := ctx.FormTrim("q") | 	query := ctx.FormTrim("q") | ||||||
|  | 	sort := ctx.FormTrim("sort") | ||||||
| 
 | 
 | ||||||
| 	ctx.Data["Title"] = ctx.Tr("packages.title") | 	ctx.Data["Title"] = ctx.Tr("packages.title") | ||||||
| 	ctx.Data["IsPackagesPage"] = true | 	ctx.Data["IsPackagesPage"] = true | ||||||
| @ -243,9 +244,11 @@ func ListPackageVersions(ctx *context.Context) { | |||||||
| 		Owner:   ctx.Package.Owner, | 		Owner:   ctx.Package.Owner, | ||||||
| 	} | 	} | ||||||
| 	ctx.Data["Query"] = query | 	ctx.Data["Query"] = query | ||||||
|  | 	ctx.Data["Sort"] = sort | ||||||
| 
 | 
 | ||||||
| 	pagerParams := map[string]string{ | 	pagerParams := map[string]string{ | ||||||
| 		"q": query, | 		"q":    query, | ||||||
|  | 		"sort": sort, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var ( | 	var ( | ||||||
| @ -264,6 +267,7 @@ func ListPackageVersions(ctx *context.Context) { | |||||||
| 			PackageID: p.ID, | 			PackageID: p.ID, | ||||||
| 			Query:     query, | 			Query:     query, | ||||||
| 			IsTagged:  tagged == "" || tagged == "tagged", | 			IsTagged:  tagged == "" || tagged == "tagged", | ||||||
|  | 			Sort:      sort, | ||||||
| 		}) | 		}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.ServerError("SearchImageTags", err) | 			ctx.ServerError("SearchImageTags", err) | ||||||
| @ -278,6 +282,7 @@ func ListPackageVersions(ctx *context.Context) { | |||||||
| 				Value:      query, | 				Value:      query, | ||||||
| 			}, | 			}, | ||||||
| 			IsInternal: util.OptionalBoolFalse, | 			IsInternal: util.OptionalBoolFalse, | ||||||
|  | 			Sort:       sort, | ||||||
| 		}) | 		}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.ServerError("SearchVersions", err) | 			ctx.ServerError("SearchVersions", err) | ||||||
|  | |||||||
| @ -37,20 +37,20 @@ | |||||||
| 						<th>ID</th> | 						<th>ID</th> | ||||||
| 						<th>{{.locale.Tr "admin.packages.owner"}}</th> | 						<th>{{.locale.Tr "admin.packages.owner"}}</th> | ||||||
| 						<th>{{.locale.Tr "admin.packages.type"}}</th> | 						<th>{{.locale.Tr "admin.packages.type"}}</th> | ||||||
| 						<th data-sortt-asc="alphabetically" data-sortt-desc="reversealphabetically"> | 						<th data-sortt-asc="name_asc" data-sortt-desc="name_desc"> | ||||||
| 							{{.locale.Tr "admin.packages.name"}} | 							{{.locale.Tr "admin.packages.name"}} | ||||||
| 							{{SortArrow "alphabetically" "reversealphabetically" .SortType false}} | 							{{SortArrow "name_asc" "name_desc" .SortType false}} | ||||||
| 						</th> | 						</th> | ||||||
| 						<th data-sortt-asc="highestversion" data-sortt-desc="lowestversion"> | 						<th data-sortt-asc="version_desc" data-sortt-desc="version_asc"> | ||||||
| 							{{.locale.Tr "admin.packages.version"}} | 							{{.locale.Tr "admin.packages.version"}} | ||||||
| 							{{SortArrow "highestversion" "lowestversion" .SortType false}} | 							{{SortArrow "version_desc" "version_asc" .SortType false}} | ||||||
| 						</th> | 						</th> | ||||||
| 						<th>{{.locale.Tr "admin.packages.creator"}}</th> | 						<th>{{.locale.Tr "admin.packages.creator"}}</th> | ||||||
| 						<th>{{.locale.Tr "admin.packages.repository"}}</th> | 						<th>{{.locale.Tr "admin.packages.repository"}}</th> | ||||||
| 						<th>{{.locale.Tr "admin.packages.size"}}</th> | 						<th>{{.locale.Tr "admin.packages.size"}}</th> | ||||||
| 						<th data-sortt-asc="oldest" data-sortt-desc="newest"> | 						<th data-sortt-asc="created_asc" data-sortt-desc="created_desc"> | ||||||
| 							{{.locale.Tr "admin.packages.published"}} | 							{{.locale.Tr "admin.packages.published"}} | ||||||
| 							{{SortArrow "oldest" "newest" .SortType true}} | 							{{SortArrow "created_asc" "created_desc" .SortType true}} | ||||||
| 						</th> | 						</th> | ||||||
| 						<th>{{.locale.Tr "admin.notices.op"}}</th> | 						<th>{{.locale.Tr "admin.notices.op"}}</th> | ||||||
| 					</tr> | 					</tr> | ||||||
|  | |||||||
| @ -3,11 +3,17 @@ | |||||||
| 	<form class="ui form ignore-dirty"> | 	<form class="ui form ignore-dirty"> | ||||||
| 		<div class="ui fluid action input"> | 		<div class="ui fluid action input"> | ||||||
| 			<input name="q" value="{{.Query}}" placeholder="{{.locale.Tr "explore.search"}}..." autofocus> | 			<input name="q" value="{{.Query}}" placeholder="{{.locale.Tr "explore.search"}}..." autofocus> | ||||||
|  | 			<select class="ui dropdown" name="sort"> | ||||||
|  | 				<option value="version_asc"{{if eq .Sort "version_asc"}} selected="selected"{{end}}>{{.locale.Tr "filter.string.asc"}}</option> | ||||||
|  | 				<option value="version_desc"{{if eq .Sort "version_desc"}} selected="selected"{{end}}>{{.locale.Tr "filter.string.desc"}}</option> | ||||||
|  | 				<option value="created_asc"{{if eq .Sort "created_asc"}} selected="selected"{{end}}>{{.locale.Tr "repo.issues.filter_sort.oldest"}}</option> | ||||||
|  | 				<option value="created_desc"{{if or (eq .Sort "") (eq .Sort "created_desc")}} selected="selected"{{end}}>{{.locale.Tr "repo.issues.filter_sort.latest"}}</option> | ||||||
|  | 			</select> | ||||||
| 			{{if eq .PackageDescriptor.Package.Type "container"}} | 			{{if eq .PackageDescriptor.Package.Type "container"}} | ||||||
| 			<select class="ui dropdown" name="tagged"> | 			<select class="ui dropdown" name="tagged"> | ||||||
| 				{{$isTagged := or (eq .Tagged "") (eq .Tagged "tagged")}} | 				{{$isTagged := or (eq .Tagged "") (eq .Tagged "tagged")}} | ||||||
| 				<option value="tagged" {{if $isTagged}}selected="selected"{{end}}>{{.locale.Tr "packages.filter.container.tagged"}}</option> | 				<option value="tagged"{{if $isTagged}} selected="selected"{{end}}>{{.locale.Tr "packages.filter.container.tagged"}}</option> | ||||||
| 				<option value="untagged" {{if not $isTagged}}selected="selected"{{end}}>{{.locale.Tr "packages.filter.container.untagged"}}</option> | 				<option value="untagged"{{if not $isTagged}} selected="selected"{{end}}>{{.locale.Tr "packages.filter.container.untagged"}}</option> | ||||||
| 			</select> | 			</select> | ||||||
| 			{{end}} | 			{{end}} | ||||||
| 			<button class="ui primary button">{{.locale.Tr "explore.search"}}</button> | 			<button class="ui primary button">{{.locale.Tr "explore.search"}}</button> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user