generated from mathias/template-go-web
TDD: IssueNodes parses /repos/issues/search into stage nodes (title, repo tag, clickable html_url). gitea.MyIssues() reads GITEA_TOKEN and skips gracefully when unset, mirroring the existing liveOverlay fallback pattern. Single-operator homelab, not per-visitor OAuth: a static read-only PAT gates on "cleared Authentik forward-auth", not per-user token exchange — see #4 discussion. GITEA_TOKEN provisioning in infra (ExternalSecret) is a separate follow-up; without it the overlay is inert (no crash, just no live nodes), so this ships safely ahead of that wiring. Nodes with a url now render as clickable <a class="node"> instead of <div class="node">.
33 lines
871 B
Go
33 lines
871 B
Go
package atlas
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
// IssueNodes parses a Gitea `/repos/issues/search` response (the
|
|
// authenticated user's own open issues, newest first) into one node per
|
|
// issue, linking out to the issue.
|
|
func IssueNodes(searchJSON []byte) ([]Node, error) {
|
|
var issues []struct {
|
|
Number int `json:"number"`
|
|
Title string `json:"title"`
|
|
HTMLURL string `json:"html_url"`
|
|
Repository struct {
|
|
FullName string `json:"full_name"`
|
|
} `json:"repository"`
|
|
}
|
|
if err := json.Unmarshal(searchJSON, &issues); err != nil {
|
|
return nil, fmt.Errorf("parse issues: %w", err)
|
|
}
|
|
nodes := make([]Node, 0, len(issues))
|
|
for _, i := range issues {
|
|
nodes = append(nodes, Node{
|
|
Title: fmt.Sprintf("#%d %s", i.Number, i.Title),
|
|
Tags: []string{"live · Gitea", i.Repository.FullName},
|
|
URL: i.HTMLURL,
|
|
})
|
|
}
|
|
return nodes, nil
|
|
}
|