this repo has no description
1package state
2
3import (
4 "fmt"
5 "log"
6 "net/http"
7 "sort"
8
9 "tangled.org/core/api/tangled"
10 "tangled.org/core/appview/db"
11 "tangled.org/core/appview/models"
12 "tangled.org/core/appview/pages"
13 "tangled.org/core/appview/pagination"
14 "tangled.org/core/consts"
15)
16
17func (s *State) GoodFirstIssues(w http.ResponseWriter, r *http.Request) {
18 user := s.oauth.GetUser(r)
19
20 page, ok := r.Context().Value("page").(pagination.Page)
21 if !ok {
22 page = pagination.FirstPage()
23 }
24
25 goodFirstIssueLabel := fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, "good-first-issue")
26
27 repoLabels, err := db.GetRepoLabels(s.db, db.FilterEq("label_at", goodFirstIssueLabel))
28 if err != nil {
29 log.Println("failed to get repo labels", err)
30 s.pages.Error503(w)
31 return
32 }
33
34 if len(repoLabels) == 0 {
35 s.pages.GoodFirstIssues(w, pages.GoodFirstIssuesParams{
36 LoggedInUser: user,
37 RepoGroups: []*models.RepoGroup{},
38 LabelDefs: make(map[string]*models.LabelDefinition),
39 Page: page,
40 })
41 return
42 }
43
44 repoUris := make([]string, 0, len(repoLabels))
45 for _, rl := range repoLabels {
46 repoUris = append(repoUris, rl.RepoAt.String())
47 }
48
49 allIssues, err := db.GetIssues(
50 s.db,
51 db.FilterIn("repo_at", repoUris),
52 db.FilterEq("open", 1),
53 )
54 if err != nil {
55 log.Println("failed to get issues", err)
56 s.pages.Error503(w)
57 return
58 }
59
60 var goodFirstIssues []models.Issue
61 for _, issue := range allIssues {
62 if issue.Labels.ContainsLabel(goodFirstIssueLabel) {
63 goodFirstIssues = append(goodFirstIssues, issue)
64 }
65 }
66
67 repoGroups := make(map[string]*models.RepoGroup)
68 for _, issue := range goodFirstIssues {
69 repoKey := fmt.Sprintf("%s/%s", issue.Repo.Did, issue.Repo.Name)
70 if group, exists := repoGroups[repoKey]; exists {
71 group.Issues = append(group.Issues, issue)
72 } else {
73 repoGroups[repoKey] = &models.RepoGroup{
74 Repo: issue.Repo,
75 Issues: []models.Issue{issue},
76 }
77 }
78 }
79
80 var sortedGroups []*models.RepoGroup
81 for _, group := range repoGroups {
82 sortedGroups = append(sortedGroups, group)
83 }
84
85 sort.Slice(sortedGroups, func(i, j int) bool {
86 return sortedGroups[i].Repo.Name < sortedGroups[j].Repo.Name
87 })
88
89 groupStart := page.Offset
90 groupEnd := page.Offset + page.Limit
91 if groupStart > len(sortedGroups) {
92 groupStart = len(sortedGroups)
93 }
94 if groupEnd > len(sortedGroups) {
95 groupEnd = len(sortedGroups)
96 }
97
98 paginatedGroups := sortedGroups[groupStart:groupEnd]
99
100 var allIssuesFromGroups []models.Issue
101 for _, group := range paginatedGroups {
102 allIssuesFromGroups = append(allIssuesFromGroups, group.Issues...)
103 }
104
105 var allLabelDefs []models.LabelDefinition
106 if len(allIssuesFromGroups) > 0 {
107 labelDefUris := make(map[string]bool)
108 for _, issue := range allIssuesFromGroups {
109 for labelDefUri := range issue.Labels.Inner() {
110 labelDefUris[labelDefUri] = true
111 }
112 }
113
114 uriList := make([]string, 0, len(labelDefUris))
115 for uri := range labelDefUris {
116 uriList = append(uriList, uri)
117 }
118
119 if len(uriList) > 0 {
120 allLabelDefs, err = db.GetLabelDefinitions(s.db, db.FilterIn("at_uri", uriList))
121 if err != nil {
122 log.Println("failed to fetch labels", err)
123 }
124 }
125 }
126
127 labelDefsMap := make(map[string]*models.LabelDefinition)
128 for i := range allLabelDefs {
129 labelDefsMap[allLabelDefs[i].AtUri().String()] = &allLabelDefs[i]
130 }
131
132 s.pages.GoodFirstIssues(w, pages.GoodFirstIssuesParams{
133 LoggedInUser: user,
134 RepoGroups: paginatedGroups,
135 LabelDefs: labelDefsMap,
136 Page: page,
137 })
138}