| @@ -1584,6 +1584,18 @@ func (s *Server) labelColors(repoID int64) map[string]template.CSS { |
| 1584 | 1584 | return out |
| 1585 | 1585 | } |
| 1586 | 1586 | |
| 1587 | // listPage is how many issues or merge requests a list page shows before |
| 1588 | // it offers the older ones (#118). Keyset paging on the number, the same |
| 1589 | // cursor the commands use, so every filter carries across pages. |
| 1590 | const listPage = 50 |
| 1591 | |
| 1592 | // olderLink is the current URL with before=<number> set. |
| 1593 | func olderLink(r *http.Request, before int64) string { |
| 1594 | q := r.URL.Query() |
| 1595 | q.Set("before", strconv.FormatInt(before, 10)) |
| 1596 | return "?" + q.Encode() |
| 1597 | } |
| 1598 | |
| 1587 | 1599 | func (s *Server) issues(w http.ResponseWriter, r *http.Request) { |
| 1588 | 1600 | p, ok := s.repoFor(w, r, "") |
| 1589 | 1601 | if !ok { |
| @@ -1598,12 +1610,18 @@ func (s *Server) issues(w http.ResponseWriter, r *http.Request) { |
| 1598 | 1610 | // label chips and author links point here. |
| 1599 | 1611 | qv := r.URL.Query() |
| 1600 | 1612 | f := store.IssueFilter{State: state, Label: qv.Get("label"), Assignee: qv.Get("assignee"), |
| 1601 | | Author: qv.Get("author"), Milestone: qv.Get("milestone")} |
| 1613 | Author: qv.Get("author"), Milestone: qv.Get("milestone"), Limit: listPage + 1} |
| 1614 | f.Before, _ = strconv.ParseInt(qv.Get("before"), 10, 64) |
| 1602 | 1615 | issues, err := s.st.QueryIssues(p.Repo.ID, f) |
| 1603 | 1616 | if err != nil { |
| 1604 | 1617 | http.Error(w, "internal error", http.StatusInternalServerError) |
| 1605 | 1618 | return |
| 1606 | 1619 | } |
| 1620 | older := "" |
| 1621 | if len(issues) > listPage { |
| 1622 | issues = issues[:listPage] |
| 1623 | older = olderLink(r, issues[len(issues)-1].Number) |
| 1624 | } |
| 1607 | 1625 | if labels, err := s.st.ListIssueLabels(p.Repo.ID); err == nil { |
| 1608 | 1626 | for i := range issues { |
| 1609 | 1627 | issues[i].Labels = labels[issues[i].ID] |
| @@ -1616,8 +1634,9 @@ func (s *Server) issues(w http.ResponseWriter, r *http.Request) { |
| 1616 | 1634 | Filters []listFilter |
| 1617 | 1635 | Issues []store.Issue |
| 1618 | 1636 | LabelColors map[string]template.CSS |
| 1637 | Older string |
| 1619 | 1638 | }{p, state, f.Label, activeFilters(state, [][2]string{{"label", f.Label}, {"assignee", f.Assignee}, {"author", f.Author}, {"milestone", f.Milestone}}), |
| 1620 | | issues, s.labelColors(p.Repo.ID)}) |
| 1639 | issues, s.labelColors(p.Repo.ID), older}) |
| 1621 | 1640 | } |
| 1622 | 1641 | |
| 1623 | 1642 | func (s *Server) issue(w http.ResponseWriter, r *http.Request) { |
| @@ -1703,18 +1722,25 @@ func (s *Server) mrs(w http.ResponseWriter, r *http.Request) { |
| 1703 | 1722 | state = "open" |
| 1704 | 1723 | } |
| 1705 | 1724 | qv := r.URL.Query() |
| 1706 | | mf := store.MRFilter{State: state, Author: qv.Get("author"), Milestone: qv.Get("milestone")} |
| 1725 | mf := store.MRFilter{State: state, Author: qv.Get("author"), Milestone: qv.Get("milestone"), Limit: listPage + 1} |
| 1726 | mf.Before, _ = strconv.ParseInt(qv.Get("before"), 10, 64) |
| 1707 | 1727 | mrs, err := s.st.QueryMRs(p.Repo.ID, mf) |
| 1708 | 1728 | if err != nil { |
| 1709 | 1729 | http.Error(w, "internal error", http.StatusInternalServerError) |
| 1710 | 1730 | return |
| 1711 | 1731 | } |
| 1732 | older := "" |
| 1733 | if len(mrs) > listPage { |
| 1734 | mrs = mrs[:listPage] |
| 1735 | older = olderLink(r, mrs[len(mrs)-1].Number) |
| 1736 | } |
| 1712 | 1737 | s.render(w, "mrs.html", struct { |
| 1713 | 1738 | repoPage |
| 1714 | 1739 | State string |
| 1715 | 1740 | Filters []listFilter |
| 1716 | 1741 | MRs []store.MR |
| 1717 | | }{p, state, activeFilters(state, [][2]string{{"author", mf.Author}, {"milestone", mf.Milestone}}), mrs}) |
| 1742 | Older string |
| 1743 | }{p, state, activeFilters(state, [][2]string{{"author", mf.Author}, {"milestone", mf.Milestone}}), mrs, older}) |
| 1718 | 1744 | } |
| 1719 | 1745 | |
| 1720 | 1746 | func (s *Server) mr(w http.ResponseWriter, r *http.Request) { |