From c86bc8e061b91d3d3778d9b97ba16e373250d8f6 Mon Sep 17 00:00:00 2001 From: zeripath Date: Sat, 16 May 2020 21:07:01 +0100 Subject: [PATCH] Add paging and archive/private repository filtering to dashboard list (#11321) * Add archived options to SearchRepository Signed-off-by: Andrew Thornton * Add only-private search Signed-off-by: Andrew Thornton * Add filter options and paging to dashboard repository page Signed-off-by: Andrew Thornton * swagger generate Signed-off-by: Andrew Thornton * fix-swagger-again Signed-off-by: Andrew Thornton * as per @mrsdizzie also remember state Signed-off-by: Andrew Thornton Co-authored-by: Lauris BH --- models/repo_list.go | 37 +++- options/locale/locale_en-US.ini | 11 ++ routers/api/v1/repo/repo.go | 13 ++ templates/swagger/v1_json.tmpl | 12 ++ templates/user/dashboard/repolist.tmpl | 63 ++++++- web_src/js/index.js | 251 ++++++++++++++++++++++--- web_src/less/_base.less | 13 +- web_src/less/_dashboard.less | 5 + 8 files changed, 371 insertions(+), 34 deletions(-) diff --git a/models/repo_list.go b/models/repo_list.go index 1632e64eb92..a676ae5c46c 100644 --- a/models/repo_list.go +++ b/models/repo_list.go @@ -140,6 +140,7 @@ type SearchRepoOptions struct { PriorityOwnerID int64 OrderBy SearchOrderBy Private bool // Include private repositories in results + OnlyPrivate bool // Include only private repositories in results StarredByID int64 AllPublic bool // Include also all public repositories of users and public organisations AllLimited bool // Include also all public repositories of limited organisations @@ -159,6 +160,10 @@ type SearchRepoOptions struct { // True -> include just mirrors // False -> include just non-mirrors Mirror util.OptionalBool + // None -> include archived AND non-archived + // True -> include just archived + // False -> include just non-archived + Archived util.OptionalBool // only search topic name TopicOnly bool // include description in keyword search @@ -205,14 +210,26 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { } } else { // Not looking at private organisations - // We should be able to see all non-private repositories that either: - cond = cond.And(builder.Eq{"is_private": false}) - accessCond := builder.Or( - // A. Aren't in organisations __OR__ - builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"type": UserTypeOrganization})), - // B. Isn't a private or limited organisation. - builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Or(builder.Eq{"visibility": structs.VisibleTypeLimited}, builder.Eq{"visibility": structs.VisibleTypePrivate})))) - cond = cond.And(accessCond) + // We should be able to see all non-private repositories that + // isn't in a private or limited organisation. + cond = cond.And( + builder.Eq{"is_private": false}, + builder.NotIn("owner_id", builder.Select("id").From("`user`").Where( + builder.And( + builder.Eq{"type": UserTypeOrganization}, + builder.Or(builder.Eq{"visibility": structs.VisibleTypeLimited}, builder.Eq{"visibility": structs.VisibleTypePrivate}), + )))) + } + + if opts.OnlyPrivate { + cond = cond.And( + builder.Or( + builder.Eq{"is_private": true}, + builder.In("owner_id", builder.Select("id").From("`user`").Where( + builder.And( + builder.Eq{"type": UserTypeOrganization}, + builder.Or(builder.Eq{"visibility": structs.VisibleTypeLimited}, builder.Eq{"visibility": structs.VisibleTypePrivate}), + ))))) } if opts.Template != util.OptionalBoolNone { @@ -299,6 +316,10 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { cond = cond.And(accessibleRepositoryCondition(opts.Actor)) } + if opts.Archived != util.OptionalBoolNone { + cond = cond.And(builder.Eq{"is_archived": opts.Archived == util.OptionalBoolTrue}) + } + switch opts.HasMilestones { case util.OptionalBoolTrue: cond = cond.And(builder.Gt{"num_milestones": 0}) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index e9e185690ab..232315122c6 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -206,6 +206,17 @@ my_orgs = My Organizations my_mirrors = My Mirrors view_home = View %s search_repos = Find a repository… +filter = Other Filters + +show_archived = Archived +show_both_archived_unarchived = Showing both archived and unarchived +show_only_archived = Showing only archived +show_only_unarchived = Showing only unarchived + +show_private = Private +show_both_private_public = Showing both public and private +show_only_private = Showing only private +show_only_public = Showing only public issues.in_your_repos = In your repositories diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 5eeef9fb9d8..a724ebcc371 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -78,10 +78,18 @@ func Search(ctx *context.APIContext) { // in: query // description: include private repositories this user has access to (defaults to true) // type: boolean + // - name: onlyPrivate + // in: query + // description: only include private repositories this user has access to (defaults to false) + // type: boolean // - name: template // in: query // description: include template repositories this user has access to (defaults to true) // type: boolean + // - name: archived + // in: query + // description: show only archived, non-archived or all repositories (defaults to all) + // type: boolean // - name: mode // in: query // description: type of repository to search for. Supported values are @@ -125,6 +133,7 @@ func Search(ctx *context.APIContext) { TopicOnly: ctx.QueryBool("topic"), Collaborate: util.OptionalBoolNone, Private: ctx.IsSigned && (ctx.Query("private") == "" || ctx.QueryBool("private")), + OnlyPrivate: ctx.IsSigned && ctx.QueryBool("onlyPrivate"), Template: util.OptionalBoolNone, StarredByID: ctx.QueryInt64("starredBy"), IncludeDescription: ctx.QueryBool("includeDesc"), @@ -156,6 +165,10 @@ func Search(ctx *context.APIContext) { return } + if ctx.Query("archived") != "" { + opts.Archived = util.OptionalBoolOf(ctx.QueryBool("archived")) + } + var sortMode = ctx.Query("sort") if len(sortMode) > 0 { var sortOrder = ctx.Query("order") diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 66a07419b1b..a6b24ed970f 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -1769,12 +1769,24 @@ "name": "private", "in": "query" }, + { + "type": "boolean", + "description": "only include private repositories this user has access to (defaults to false)", + "name": "onlyPrivate", + "in": "query" + }, { "type": "boolean", "description": "include template repositories this user has access to (defaults to true)", "name": "template", "in": "query" }, + { + "type": "boolean", + "description": "show only archived, non-archived or all repositories (defaults to all)", + "name": "archived", + "in": "query" + }, { "type": "string", "description": "type of repository to search for. Supported values are \"fork\", \"source\", \"mirror\" and \"collaborative\"", diff --git a/templates/user/dashboard/repolist.tmpl b/templates/user/dashboard/repolist.tmpl index 63019e58e83..dc1507403cd 100644 --- a/templates/user/dashboard/repolist.tmpl +++ b/templates/user/dashboard/repolist.tmpl @@ -35,9 +35,46 @@ {{end}}