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}