@@ -31,7 +31,9 @@ import (
3131 "code.gitea.io/gitea/modules/markup/markdown"
3232 "code.gitea.io/gitea/modules/optional"
3333 "code.gitea.io/gitea/modules/setting"
34+ "code.gitea.io/gitea/modules/util"
3435 "code.gitea.io/gitea/routers/web/feed"
36+ "code.gitea.io/gitea/routers/web/shared/user"
3537 "code.gitea.io/gitea/services/context"
3638 feed_service "code.gitea.io/gitea/services/feed"
3739 issue_service "code.gitea.io/gitea/services/issue"
@@ -375,16 +377,8 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
375377 return
376378 }
377379
378- var (
379- viewType string
380- sortType = ctx .FormString ("sort" )
381- filterMode int
382- )
383-
384380 // Default to recently updated, unlike repository issues list
385- if sortType == "" {
386- sortType = "recentupdate"
387- }
381+ sortType := util .IfZero (ctx .FormString ("sort" ), "recentupdate" )
388382
389383 // --------------------------------------------------------------------------------
390384 // Distinguish User from Organization.
@@ -399,7 +393,8 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
399393
400394 // TODO: distinguish during routing
401395
402- viewType = ctx .FormString ("type" )
396+ viewType := ctx .FormString ("type" )
397+ var filterMode int
403398 switch viewType {
404399 case "assigned" :
405400 filterMode = issues_model .FilterModeAssign
@@ -443,6 +438,14 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
443438 Team : team ,
444439 User : ctx .Doer ,
445440 }
441+ // Get filter by author id & assignee id
442+ // FIXME: this feature doesn't work at the moment, because frontend can't use a "user-remote-search" dropdown directly
443+ // the existing "/posters" handlers doesn't work for this case, it is unable to list the related users correctly.
444+ // In the future, we need something like github: "author:user1" to accept usernames directly.
445+ posterUsername := ctx .FormString ("poster" )
446+ opts .PosterID = user .GetFilterUserIDByName (ctx , posterUsername )
447+ // TODO: "assignee" should also use GetFilterUserIDByName in the future to support usernames directly
448+ opts .AssigneeID , _ = strconv .ParseInt (ctx .FormString ("assignee" ), 10 , 64 )
446449
447450 isFuzzy := ctx .FormBool ("fuzzy" )
448451
@@ -573,8 +576,22 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
573576 // -------------------------------
574577 // Fill stats to post to ctx.Data.
575578 // -------------------------------
576- issueStats , err := getUserIssueStats (ctx , ctxUser , filterMode , issue_indexer .ToSearchOptions (keyword , opts ).Copy (
577- func (o * issue_indexer.SearchOptions ) { o .IsFuzzyKeyword = isFuzzy },
579+ issueStats , err := getUserIssueStats (ctx , filterMode , issue_indexer .ToSearchOptions (keyword , opts ).Copy (
580+ func (o * issue_indexer.SearchOptions ) {
581+ o .IsFuzzyKeyword = isFuzzy
582+ // If the doer is the same as the context user, which means the doer is viewing his own dashboard,
583+ // it's not enough to show the repos that the doer owns or has been explicitly granted access to,
584+ // because the doer may create issues or be mentioned in any public repo.
585+ // So we need search issues in all public repos.
586+ o .AllPublic = ctx .Doer .ID == ctxUser .ID
587+ // TODO: to make it work with poster/assignee filter, then these IDs should be kept
588+ o .AssigneeID = nil
589+ o .PosterID = nil
590+
591+ o .MentionID = nil
592+ o .ReviewRequestedID = nil
593+ o .ReviewedID = nil
594+ },
578595 ))
579596 if err != nil {
580597 ctx .ServerError ("getUserIssueStats" , err )
@@ -630,6 +647,8 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
630647 ctx .Data ["IsShowClosed" ] = isShowClosed
631648 ctx .Data ["SelectLabels" ] = selectedLabels
632649 ctx .Data ["IsFuzzy" ] = isFuzzy
650+ ctx .Data ["SearchFilterPosterID" ] = util .Iif [any ](opts .PosterID != 0 , opts .PosterID , nil )
651+ ctx .Data ["SearchFilterAssigneeID" ] = util .Iif [any ](opts .AssigneeID != 0 , opts .AssigneeID , nil )
633652
634653 if isShowClosed {
635654 ctx .Data ["State" ] = "closed"
@@ -643,7 +662,11 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
643662 pager .AddParamString ("sort" , sortType )
644663 pager .AddParamString ("state" , fmt .Sprint (ctx .Data ["State" ]))
645664 pager .AddParamString ("labels" , selectedLabels )
646- pager .AddParamString ("fuzzy" , fmt .Sprintf ("%v" , isFuzzy ))
665+ pager .AddParamString ("fuzzy" , fmt .Sprint (isFuzzy ))
666+ pager .AddParamString ("poster" , posterUsername )
667+ if opts .AssigneeID != 0 {
668+ pager .AddParamString ("assignee" , fmt .Sprint (opts .AssigneeID ))
669+ }
647670 ctx .Data ["Page" ] = pager
648671
649672 ctx .HTML (http .StatusOK , tplIssues )
@@ -768,27 +791,10 @@ func UsernameSubRoute(ctx *context.Context) {
768791 }
769792}
770793
771- func getUserIssueStats (ctx * context.Context , ctxUser * user_model.User , filterMode int , opts * issue_indexer.SearchOptions ) (* issues_model.IssueStats , error ) {
794+ func getUserIssueStats (ctx * context.Context , filterMode int , opts * issue_indexer.SearchOptions ) (ret * issues_model.IssueStats , err error ) {
795+ ret = & issues_model.IssueStats {}
772796 doerID := ctx .Doer .ID
773797
774- opts = opts .Copy (func (o * issue_indexer.SearchOptions ) {
775- // If the doer is the same as the context user, which means the doer is viewing his own dashboard,
776- // it's not enough to show the repos that the doer owns or has been explicitly granted access to,
777- // because the doer may create issues or be mentioned in any public repo.
778- // So we need search issues in all public repos.
779- o .AllPublic = doerID == ctxUser .ID
780- o .AssigneeID = nil
781- o .PosterID = nil
782- o .MentionID = nil
783- o .ReviewRequestedID = nil
784- o .ReviewedID = nil
785- })
786-
787- var (
788- err error
789- ret = & issues_model.IssueStats {}
790- )
791-
792798 {
793799 openClosedOpts := opts .Copy ()
794800 switch filterMode {
0 commit comments