From 0b1a3eaa5291f046b32d9e6a34c4e442c5f683d0 Mon Sep 17 00:00:00 2001 From: Dolev Hadar Date: Fri, 13 Jan 2023 20:40:47 +0200 Subject: [PATCH] feat(issues): add pagination Signed-off-by: Dolev Hadar --- data/issueapi.go | 31 ++++++++--- ui/components/issuessection/issuessection.go | 54 +++++++++++--------- 2 files changed, 55 insertions(+), 30 deletions(-) diff --git a/data/issueapi.go b/data/issueapi.go index 2844b0d7..942789f1 100644 --- a/data/issueapi.go +++ b/data/issueapi.go @@ -69,11 +69,11 @@ func makeIssuesQuery(query string) string { return fmt.Sprintf("is:issue %s", query) } -func FetchIssues(query string, limit int) ([]IssueData, error) { +func FetchIssues(query string, limit int, pageInfo *PageInfo) (IssuesResponse, error) { var err error client, err := gh.GQLClient(nil) if err != nil { - return nil, err + return IssuesResponse{}, err } var queryResult struct { @@ -81,20 +81,37 @@ func FetchIssues(query string, limit int) ([]IssueData, error) { Nodes []struct { Issue IssueData `graphql:"... on Issue"` } - } `graphql:"search(type: ISSUE, first: $limit, query: $query)"` + IssueCount int + PageInfo PageInfo + } `graphql:"search(type: ISSUE, first: $limit, after: $endCursor, query: $query)"` + } + var endCursor *string + if pageInfo != nil { + endCursor = &pageInfo.EndCursor } variables := map[string]interface{}{ - "query": graphql.String(makeIssuesQuery(query)), - "limit": graphql.Int(limit), + "query": graphql.String(makeIssuesQuery(query)), + "limit": graphql.Int(limit), + "endCursor": (*graphql.String)(endCursor), } err = client.Query("SearchIssues", &queryResult, variables) if err != nil { - return nil, err + return IssuesResponse{}, err } issues := make([]IssueData, 0, len(queryResult.Search.Nodes)) for _, node := range queryResult.Search.Nodes { issues = append(issues, node.Issue) } - return issues, nil + return IssuesResponse{ + Issues: issues, + TotalCount: queryResult.Search.IssueCount, + PageInfo: queryResult.Search.PageInfo, + }, nil +} + +type IssuesResponse struct { + Issues []IssueData + TotalCount int + PageInfo PageInfo } diff --git a/ui/components/issuessection/issuessection.go b/ui/components/issuessection/issuessection.go index ad1bcd3e..3406231f 100644 --- a/ui/components/issuessection/issuessection.go +++ b/ui/components/issuessection/issuessection.go @@ -97,10 +97,16 @@ func (m Model) Update(msg tea.Msg) (section.Section, tea.Cmd) { } case SectionIssuesFetchedMsg: - m.Issues = msg.Issues + if m.PageInfo != nil { + m.Issues = append(m.Issues, msg.Issues...) + } else { + m.Issues = msg.Issues + } + m.TotalCount = msg.TotalCount + m.PageInfo = &msg.PageInfo m.Table.SetRows(m.BuildRows()) m.UpdateLastUpdated(time.Now()) - + m.UpdateTotalItemsCount(m.TotalCount) } search, searchCmd := m.SearchBar.Update(msg) @@ -183,20 +189,6 @@ func (m *Model) NumRows() int { return len(m.Issues) } -type SectionIssuesFetchedMsg struct { - SectionId int - Issues []data.IssueData - Err error -} - -func (msg SectionIssuesFetchedMsg) GetSectionId() int { - return msg.SectionId -} - -func (msg SectionIssuesFetchedMsg) GetSectionType() string { - return SectionType -} - func (m *Model) GetCurrRow() data.RowData { if len(m.Issues) == 0 { return nil @@ -209,11 +201,18 @@ func (m *Model) FetchNextPageSectionRows() []tea.Cmd { if m == nil { return nil } - m.Issues = nil - m.Table.Rows = nil + + if m.PageInfo != nil && !m.PageInfo.HasNextPage { + return nil + } + var cmds []tea.Cmd - taskId := fmt.Sprintf("fetching_issues_%d", m.Id) + startCursor := time.Now().String() + if m.PageInfo != nil { + startCursor = m.PageInfo.StartCursor + } + taskId := fmt.Sprintf("fetching_issues_%d_%s", m.Id, startCursor) task := context.Task{ Id: taskId, StartText: fmt.Sprintf(`Fetching issues for "%s"`, m.Config.Title), @@ -229,7 +228,7 @@ func (m *Model) FetchNextPageSectionRows() []tea.Cmd { if limit == nil { limit = &m.Ctx.Config.Defaults.IssuesLimit } - fetchedIssues, err := data.FetchIssues(m.GetFilters(), *limit) + res, err := data.FetchIssues(m.GetFilters(), *limit, m.PageInfo) if err != nil { return constants.TaskFinishedMsg{ SectionId: m.Id, @@ -238,9 +237,10 @@ func (m *Model) FetchNextPageSectionRows() []tea.Cmd { Err: err, } } + issues := res.Issues - sort.Slice(fetchedIssues, func(i, j int) bool { - return fetchedIssues[i].UpdatedAt.After(fetchedIssues[j].UpdatedAt) + sort.Slice(issues, func(i, j int) bool { + return issues[i].UpdatedAt.After(issues[j].UpdatedAt) }) return constants.TaskFinishedMsg{ @@ -248,7 +248,9 @@ func (m *Model) FetchNextPageSectionRows() []tea.Cmd { SectionType: m.Type, TaskId: taskId, Msg: SectionIssuesFetchedMsg{ - Issues: fetchedIssues, + Issues: issues, + TotalCount: res.TotalCount, + PageInfo: res.PageInfo, }, } @@ -281,6 +283,12 @@ func FetchAllSections(ctx context.ProgramContext) (sections []section.Section, f return sections, tea.Batch(fetchIssuesCmds...) } +type SectionIssuesFetchedMsg struct { + Issues []data.IssueData + TotalCount int + PageInfo data.PageInfo +} + type UpdateIssueMsg struct { IssueNumber int NewComment *data.Comment