feat(pr create, issue create): search-based assignee selection in MetadataSurvey

Wire up MultiSelectWithSearch for assignees in MetadataSurvey, replacing
the static MultiSelect that required bulk fetching all assignable actors.
This applies to both gh pr create and gh issue create interactive flows
when selecting assignees via the 'Add metadata' prompt.

Changes:
- Add assigneeSearchFunc parameter to MetadataSurvey
- Skip assignee bulk fetch when search func is available
- New SearchRepoAssignableActors API function for repo-level search
  (create flows have no issue/PR node ID yet)
- New RepoAssigneeSearchFunc in shared editable.go
- Refactor actorsToSearchResult helper shared by both search functions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Kynan Ware 2026-03-23 18:45:09 -06:00
parent 33783748f3
commit 11f177a8c3
7 changed files with 151 additions and 62 deletions

View file

@ -1298,6 +1298,69 @@ func RepoAssignableActors(client *Client, repo ghrepo.Interface) ([]AssignableAc
return actors, nil
}
// SearchRepoAssignableActors searches assignable actors for a repository with an optional
// query string. Unlike RepoAssignableActors which fetches all actors with pagination, this
// returns up to 10 results matching the query, suitable for search-based selection.
func SearchRepoAssignableActors(client *Client, repo ghrepo.Interface, query string) ([]AssignableActor, int, error) {
type responseData struct {
Repository struct {
AssignableUsers struct {
TotalCount int
}
SuggestedActors struct {
Nodes []struct {
User struct {
ID string
Login string
Name string
TypeName string `graphql:"__typename"`
} `graphql:"... on User"`
Bot struct {
ID string
Login string
TypeName string `graphql:"__typename"`
} `graphql:"... on Bot"`
}
} `graphql:"suggestedActors(first: 10, query: $query, capabilities: CAN_BE_ASSIGNED)"`
} `graphql:"repository(owner: $owner, name: $name)"`
}
var q *githubv4.String
if query != "" {
v := githubv4.String(query)
q = &v
}
variables := map[string]interface{}{
"owner": githubv4.String(repo.RepoOwner()),
"name": githubv4.String(repo.RepoName()),
"query": q,
}
var result responseData
if err := client.Query(repo.RepoHost(), "SearchRepoAssignableActors", &result, variables); err != nil {
return nil, 0, err
}
var actors []AssignableActor
for _, node := range result.Repository.SuggestedActors.Nodes {
if node.User.TypeName == "User" {
actors = append(actors, AssignableUser{
id: node.User.ID,
login: node.User.Login,
name: node.User.Name,
})
} else if node.Bot.TypeName == "Bot" {
actors = append(actors, AssignableBot{
id: node.Bot.ID,
login: node.Bot.Login,
})
}
}
return actors, result.Repository.AssignableUsers.TotalCount, nil
}
type RepoLabel struct {
ID string
Name string