Merge pull request 'feat: add backend pagination for infinite scroll in issues and pulls' (#66) from feature/pagination-infinite-scroll into master
Build and Push / test (push) Has been cancelled
Build and Push / build (push) Has been cancelled

This commit was merged in pull request #66.
This commit is contained in:
2026-03-27 04:05:57 +00:00
4 changed files with 324 additions and 185 deletions
+60 -4
View File
@@ -245,6 +245,10 @@ func (h *Handler) ListIssues(w http.ResponseWriter, r *http.Request) {
if selectedState == "" {
selectedState = "open"
}
page, _ := strconv.Atoi(r.URL.Query().Get("page"))
if page < 1 {
page = 1
}
data := issuesData{
Orgs: orgNames,
@@ -261,15 +265,38 @@ func (h *Handler) ListIssues(w http.ResponseWriter, r *http.Request) {
queryOrgs = []string{selectedOrg}
}
issues, err := h.Client.ListAllIssues(r.Context(), token, queryOrgs)
result, err := h.Client.ListAllIssues(r.Context(), token, queryOrgs, selectedState, page)
if err != nil {
slog.Error("failed to list issues", "error", err)
data.Error = "Error loading issues."
} else {
data.Issues = issues
data.Issues = result.Issues
data.HasMore = result.HasMore
if result.HasMore {
data.NextPage = page + 1
}
}
}
// For HTMX infinite-scroll requests (page > 1), return only the card fragment.
if isHTMX(r) && page > 1 {
tmpl, err := template.ParseFiles("internal/templates/issues.html")
if err != nil {
slog.Error("failed to parse issues template", "error", err)
http.Error(w, "template error", http.StatusInternalServerError)
return
}
var buf strings.Builder
if err := tmpl.ExecuteTemplate(&buf, "cards", data); err != nil {
slog.Error("failed to execute issues cards template", "error", err)
http.Error(w, "template error", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprint(w, buf.String())
return
}
tmpl, err := template.ParseFiles("internal/templates/issues.html")
if err != nil {
slog.Error("failed to parse issues template", "error", err)
@@ -296,10 +323,16 @@ func (h *Handler) ListPulls(w http.ResponseWriter, r *http.Request) {
Pulls []giteaclient.PullRequest
Orgs []string
SelectedOrg string
HasMore bool
NextPage int
Error string
}
selectedOrg := r.URL.Query().Get("org")
page, _ := strconv.Atoi(r.URL.Query().Get("page"))
if page < 1 {
page = 1
}
data := pullsData{
Orgs: orgNames,
@@ -314,15 +347,38 @@ func (h *Handler) ListPulls(w http.ResponseWriter, r *http.Request) {
queryOrgs = []string{selectedOrg}
}
prs, err := h.Client.ListAllPullRequests(r.Context(), token, queryOrgs)
result, err := h.Client.ListAllPullRequests(r.Context(), token, queryOrgs, "open", page)
if err != nil {
slog.Error("failed to list pull requests", "error", err)
data.Error = "Error loading pull requests."
} else {
data.Pulls = prs
data.Pulls = result.Pulls
data.HasMore = result.HasMore
if result.HasMore {
data.NextPage = page + 1
}
}
}
// For HTMX infinite-scroll requests (page > 1), return only the card fragment.
if isHTMX(r) && page > 1 {
tmpl, err := template.ParseFiles("internal/templates/pulls.html")
if err != nil {
slog.Error("failed to parse pulls template", "error", err)
http.Error(w, "template error", http.StatusInternalServerError)
return
}
var buf strings.Builder
if err := tmpl.ExecuteTemplate(&buf, "cards", data); err != nil {
slog.Error("failed to execute pulls cards template", "error", err)
http.Error(w, "template error", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprint(w, buf.String())
return
}
tmpl, err := template.ParseFiles("internal/templates/pulls.html")
if err != nil {
slog.Error("failed to parse pulls template", "error", err)