diff --git a/api/queries_issue.go b/api/queries_issue.go index 2d4e22229..43faa7321 100644 --- a/api/queries_issue.go +++ b/api/queries_issue.go @@ -5,9 +5,14 @@ import ( ) type IssuesPayload struct { - Assigned []Issue - Mentioned []Issue - Authored []Issue + Assigned IssuesAndTotalCount + Mentioned IssuesAndTotalCount + Authored IssuesAndTotalCount +} + +type IssuesAndTotalCount struct { + Issues []Issue + TotalCount int } type Issue struct { @@ -80,13 +85,16 @@ func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPa type response struct { Repository struct { Assigned struct { - Nodes []Issue + TotalCount int + Nodes []Issue } Mentioned struct { - Nodes []Issue + TotalCount int + Nodes []Issue } Authored struct { - Nodes []Issue + TotalCount int + Nodes []Issue } HasIssuesEnabled bool } @@ -97,16 +105,19 @@ func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPa repository(owner: $owner, name: $repo) { hasIssuesEnabled assigned: issues(filterBy: {assignee: $viewer, states: OPEN}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) { + totalCount nodes { ...issue } } mentioned: issues(filterBy: {mentioned: $viewer, states: OPEN}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) { + totalCount nodes { ...issue } } authored: issues(filterBy: {createdBy: $viewer, states: OPEN}, first: $per_page, orderBy: {field: CREATED_AT, direction: DESC}) { + totalCount nodes { ...issue } @@ -133,9 +144,18 @@ func IssueStatus(client *Client, ghRepo Repo, currentUsername string) (*IssuesPa } payload := IssuesPayload{ - Assigned: resp.Repository.Assigned.Nodes, - Mentioned: resp.Repository.Mentioned.Nodes, - Authored: resp.Repository.Authored.Nodes, + Assigned: IssuesAndTotalCount{ + Issues: resp.Repository.Assigned.Nodes, + TotalCount: resp.Repository.Assigned.TotalCount, + }, + Mentioned: IssuesAndTotalCount{ + Issues: resp.Repository.Mentioned.Nodes, + TotalCount: resp.Repository.Mentioned.TotalCount, + }, + Authored: IssuesAndTotalCount{ + Issues: resp.Repository.Authored.Nodes, + TotalCount: resp.Repository.Authored.TotalCount, + }, } return &payload, nil diff --git a/api/queries_pr.go b/api/queries_pr.go index 4b8f5fcb7..22d0ec3fd 100644 --- a/api/queries_pr.go +++ b/api/queries_pr.go @@ -6,11 +6,16 @@ import ( ) type PullRequestsPayload struct { - ViewerCreated []PullRequest - ReviewRequested []PullRequest + ViewerCreated PullRequestAndTotalCount + ReviewRequested PullRequestAndTotalCount CurrentPR *PullRequest } +type PullRequestAndTotalCount struct { + TotalCount int + PullRequests []PullRequest +} + type PullRequest struct { Number int Title string @@ -123,7 +128,8 @@ type Repo interface { func PullRequests(client *Client, ghRepo Repo, currentPRNumber int, currentPRHeadRef, currentUsername string) (*PullRequestsPayload, error) { type edges struct { - Edges []struct { + TotalCount int + Edges []struct { Node PullRequest } } @@ -177,6 +183,7 @@ func PullRequests(client *Client, ghRepo Repo, currentPRNumber int, currentPRHea query($owner: String!, $repo: String!, $headRefName: String!, $viewerQuery: String!, $reviewerQuery: String!, $per_page: Int = 10) { repository(owner: $owner, name: $repo) { pullRequests(headRefName: $headRefName, states: OPEN, first: $per_page) { + totalCount edges { node { ...prWithReviews @@ -198,6 +205,7 @@ func PullRequests(client *Client, ghRepo Repo, currentPRNumber int, currentPRHea query := fragments + queryPrefix + ` viewerCreated: search(query: $viewerQuery, type: ISSUE, first: $per_page) { + totalCount: issueCount edges { node { ...prWithReviews @@ -205,6 +213,7 @@ func PullRequests(client *Client, ghRepo Repo, currentPRNumber int, currentPRHea } } reviewRequested: search(query: $reviewerQuery, type: ISSUE, first: $per_page) { + totalCount: issueCount edges { node { ...pr @@ -260,9 +269,15 @@ func PullRequests(client *Client, ghRepo Repo, currentPRNumber int, currentPRHea } payload := PullRequestsPayload{ - viewerCreated, - reviewRequested, - currentPR, + ViewerCreated: PullRequestAndTotalCount{ + PullRequests: viewerCreated, + TotalCount: resp.ViewerCreated.TotalCount, + }, + ReviewRequested: PullRequestAndTotalCount{ + PullRequests: reviewRequested, + TotalCount: resp.ReviewRequested.TotalCount, + }, + CurrentPR: currentPR, } return &payload, nil diff --git a/command/issue.go b/command/issue.go index 39c34feca..cc114d728 100644 --- a/command/issue.go +++ b/command/issue.go @@ -172,8 +172,8 @@ func issueStatus(cmd *cobra.Command, args []string) error { out := colorableOut(cmd) printHeader(out, "Issues assigned to you") - if len(issuePayload.Assigned) > 0 { - printIssues(out, " ", issuePayload.Assigned...) + if issuePayload.Assigned.TotalCount > 0 { + printIssues(out, " ", issuePayload.Assigned.TotalCount, issuePayload.Assigned.Issues) } else { message := fmt.Sprintf(" There are no issues assigned to you") printMessage(out, message) @@ -181,16 +181,16 @@ func issueStatus(cmd *cobra.Command, args []string) error { fmt.Fprintln(out) printHeader(out, "Issues mentioning you") - if len(issuePayload.Mentioned) > 0 { - printIssues(out, " ", issuePayload.Mentioned...) + if issuePayload.Mentioned.TotalCount > 0 { + printIssues(out, " ", issuePayload.Mentioned.TotalCount, issuePayload.Mentioned.Issues) } else { printMessage(out, " There are no issues mentioning you") } fmt.Fprintln(out) printHeader(out, "Issues opened by you") - if len(issuePayload.Authored) > 0 { - printIssues(out, " ", issuePayload.Authored...) + if issuePayload.Authored.TotalCount > 0 { + printIssues(out, " ", issuePayload.Authored.TotalCount, issuePayload.Authored.Issues) } else { printMessage(out, " There are no issues opened by you") } @@ -318,7 +318,7 @@ func issueCreate(cmd *cobra.Command, args []string) error { return nil } -func printIssues(w io.Writer, prefix string, issues ...api.Issue) { +func printIssues(w io.Writer, prefix string, totalCount int, issues []api.Issue) { for _, issue := range issues { number := utils.Green("#" + strconv.Itoa(issue.Number)) coloredLabels := labelList(issue) @@ -327,6 +327,10 @@ func printIssues(w io.Writer, prefix string, issues ...api.Issue) { } fmt.Fprintf(w, "%s%s %s%s\n", prefix, number, truncate(70, replaceExcessiveWhitespace(issue.Title)), coloredLabels) } + remaining := totalCount - len(issues) + if remaining > 0 { + fmt.Fprintf(w, utils.Gray("%sAnd %d more\n"), prefix, remaining) + } } func labelList(issue api.Issue) string { diff --git a/command/pr.go b/command/pr.go index d63f3379a..cdf5dd6bc 100644 --- a/command/pr.go +++ b/command/pr.go @@ -99,7 +99,7 @@ func prStatus(cmd *cobra.Command, args []string) error { printHeader(out, "Current branch") if prPayload.CurrentPR != nil { - printPrs(out, *prPayload.CurrentPR) + printPrs(out, 0, *prPayload.CurrentPR) } else { message := fmt.Sprintf(" There is no pull request associated with %s", utils.Cyan("["+currentPRHeadRef+"]")) printMessage(out, message) @@ -107,16 +107,16 @@ func prStatus(cmd *cobra.Command, args []string) error { fmt.Fprintln(out) printHeader(out, "Created by you") - if len(prPayload.ViewerCreated) > 0 { - printPrs(out, prPayload.ViewerCreated...) + if prPayload.ViewerCreated.TotalCount > 0 { + printPrs(out, prPayload.ViewerCreated.TotalCount, prPayload.ViewerCreated.PullRequests...) } else { printMessage(out, " You have no open pull requests") } fmt.Fprintln(out) printHeader(out, "Requesting a code review from you") - if len(prPayload.ReviewRequested) > 0 { - printPrs(out, prPayload.ReviewRequested...) + if prPayload.ReviewRequested.TotalCount > 0 { + printPrs(out, prPayload.ReviewRequested.TotalCount, prPayload.ReviewRequested.PullRequests...) } else { printMessage(out, " You have no pull requests to review") } @@ -435,7 +435,7 @@ func prCheckout(cmd *cobra.Command, args []string) error { return nil } -func printPrs(w io.Writer, prs ...api.PullRequest) { +func printPrs(w io.Writer, totalCount int, prs ...api.PullRequest) { for _, pr := range prs { prNumber := fmt.Sprintf("#%d", pr.Number) fmt.Fprintf(w, " %s %s %s", utils.Green(prNumber), truncate(50, replaceExcessiveWhitespace(pr.Title)), utils.Cyan("["+pr.HeadLabel()+"]")) @@ -472,6 +472,10 @@ func printPrs(w io.Writer, prs ...api.PullRequest) { fmt.Fprint(w, "\n") } + remaining := totalCount - len(prs) + if remaining > 0 { + fmt.Fprintf(w, utils.Gray(" And %d more\n"), remaining) + } } func printHeader(w io.Writer, s string) { diff --git a/test/fixtures/issueStatus.json b/test/fixtures/issueStatus.json index 265986902..318476f28 100644 --- a/test/fixtures/issueStatus.json +++ b/test/fixtures/issueStatus.json @@ -3,30 +3,33 @@ "repository": { "hasIssuesEnabled": true, "assigned": { + "totalCount": 2, "nodes": [ { - "number": 9, - "title": "corey thinks squash tastes bad" + "number": 9, + "title": "corey thinks squash tastes bad" }, { - "number": 10, - "title": "broccoli is a superfood" + "number": 10, + "title": "broccoli is a superfood" } ] }, "mentioned": { + "totalCount": 2, "nodes": [ { - "number": 8, - "title": "rabbits eat carrots" + "number": 8, + "title": "rabbits eat carrots" }, { - "number": 11, - "title": "swiss chard is neutral" + "number": 11, + "title": "swiss chard is neutral" } ] }, "authored": { + "totalCount": 0, "nodes": [] } } diff --git a/test/fixtures/prStatus.json b/test/fixtures/prStatus.json index f2b0ca5b3..514575834 100644 --- a/test/fixtures/prStatus.json +++ b/test/fixtures/prStatus.json @@ -1,52 +1,57 @@ -{"data":{ - "repository": { - "pullRequests": { +{ + "data": { + "repository": { + "pullRequests": { + "totalCount": 1, + "edges": [ + { + "node": { + "number": 10, + "title": "Blueberries are a good fruit", + "url": "https://github.com/github/gh-cli/pull/10", + "headRefName": "blueberries", + "headRepositoryOwner": { + "login": "OWNER" + }, + "isCrossRepository": false + } + } + ] + } + }, + "viewerCreated": { + "totalCount": 1, "edges": [ { "node": { - "number": 10, - "title": "Blueberries are a good fruit", - "url": "https://github.com/github/gh-cli/pull/10", - "headRefName": "blueberries", - "headRepositoryOwner": { - "login": "OWNER" - }, - "isCrossRepository": false + "number": 8, + "title": "Strawberries are not actually berries", + "url": "https://github.com/github/gh-cli/pull/8", + "headRefName": "strawberries" + } + } + ] + }, + "reviewRequested": { + "totalCount": 2, + "edges": [ + { + "node": { + "number": 9, + "title": "Apples are tasty", + "url": "https://github.com/github/gh-cli/pull/9", + "headRefName": "apples" + } + }, + { + "node": { + "number": 11, + "title": "Figs are my favorite", + "url": "https://github.com/github/gh-cli/pull/1", + "headRefName": "figs" } } ] } - }, - "viewerCreated": { - "edges": [ - { - "node": { - "number": 8, - "title": "Strawberries are not actually berries", - "url": "https://github.com/github/gh-cli/pull/8", - "headRefName": "strawberries" - } - } - ] - }, - "reviewRequested": { - "edges": [ - { - "node": { - "number": 9, - "title": "Apples are tasty", - "url": "https://github.com/github/gh-cli/pull/9", - "headRefName": "apples" - } - }, - { - "node": { - "number": 11, - "title": "Figs are my favorite", - "url": "https://github.com/github/gh-cli/pull/1", - "headRefName": "figs" - } - } - ] } -}} \ No newline at end of file +} diff --git a/test/fixtures/prStatusChecks.json b/test/fixtures/prStatusChecks.json index 620e5267d..8b7def7f9 100644 --- a/test/fixtures/prStatusChecks.json +++ b/test/fixtures/prStatusChecks.json @@ -1,11 +1,13 @@ { - "data":{ + "data": { "repository": { "pullRequests": { + "totalCount": 0, "edges": [] } }, "viewerCreated": { + "totalCount": 3, "edges": [ { "node": { @@ -15,17 +17,21 @@ "headRefName": "strawberries", "reviewDecision": "CHANGES_REQUESTED", "commits": { - "nodes": [{ - "commit": { - "statusCheckRollup": { - "contexts": { - "nodes": [{ - "state": "SUCCESS" - }] + "nodes": [ + { + "commit": { + "statusCheckRollup": { + "contexts": { + "nodes": [ + { + "state": "SUCCESS" + } + ] + } } } } - }] + ] } } }, @@ -37,18 +43,22 @@ "headRefName": "banananana", "reviewDecision": "APPROVED", "commits": { - "nodes": [{ - "commit": { - "statusCheckRollup": { - "contexts": { - "nodes": [{ - "status": "IN_PROGRESS", - "conclusion": "" - }] + "nodes": [ + { + "commit": { + "statusCheckRollup": { + "contexts": { + "nodes": [ + { + "status": "IN_PROGRESS", + "conclusion": "" + } + ] + } } } } - }] + ] } } }, @@ -60,33 +70,36 @@ "headRefName": "avo", "reviewDecision": "REVIEW_REQUIRED", "commits": { - "nodes": [{ - "commit": { - "statusCheckRollup": { - "contexts": { - "nodes": [ - { - "status": "IN_PROGRESS", - "conclusion": "" - }, - { - "state": "FAILURE" - }, - { - "status": "COMPLETED", - "conclusion": "NEUTRAL" - } - ] + "nodes": [ + { + "commit": { + "statusCheckRollup": { + "contexts": { + "nodes": [ + { + "status": "IN_PROGRESS", + "conclusion": "" + }, + { + "state": "FAILURE" + }, + { + "status": "COMPLETED", + "conclusion": "NEUTRAL" + } + ] + } } } } - }] + ] } } } ] }, "reviewRequested": { + "totalCount": 0, "edges": [] } }