this repo has no description

more progress on patches

- fix up filters
- fix missing icons bug
- fix missing close button

Akshay 55a428df 92bf740c

Changed files
+111 -56
appview
db
pages
templates
state
+1 -1
appview/db/db.go
··· 114 114 pull_at text, 115 115 rkey text not null, 116 116 target_branch text not null, 117 - open integer not null default 1, 117 + state integer not null default 0 check (state in (0, 1, 2)), -- open, merged, closed 118 118 created text not null default (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), 119 119 unique(repo_at, pull_id), 120 120 foreign key (repo_at) references repos(at_uri) on delete cascade
+70 -15
appview/db/pulls.go
··· 7 7 "github.com/bluesky-social/indigo/atproto/syntax" 8 8 ) 9 9 10 + type PullState int 11 + 12 + const ( 13 + PullOpen PullState = iota 14 + PullMerged 15 + PullClosed 16 + ) 17 + 18 + func (p PullState) String() string { 19 + switch p { 20 + case PullOpen: 21 + return "open" 22 + case PullMerged: 23 + return "merged" 24 + case PullClosed: 25 + return "closed" 26 + default: 27 + return "closed" 28 + } 29 + } 30 + 31 + func (p PullState) IsOpen() bool { 32 + return p == PullOpen 33 + } 34 + func (p PullState) IsMerged() bool { 35 + return p == PullMerged 36 + } 37 + func (p PullState) IsClosed() bool { 38 + return p == PullClosed 39 + } 40 + 10 41 type Pull struct { 11 42 ID int 12 43 OwnerDid string ··· 17 48 PullId int 18 49 Title string 19 50 Body string 20 - Open int 51 + State PullState 21 52 Created time.Time 22 53 Rkey string 23 54 } ··· 89 120 return pullId - 1, err 90 121 } 91 122 92 - func GetPulls(e Execer, repoAt syntax.ATURI) ([]Pull, error) { 123 + func GetPulls(e Execer, repoAt syntax.ATURI, state PullState) ([]Pull, error) { 93 124 var pulls []Pull 94 125 95 - rows, err := e.Query(`select owner_did, pull_id, created, title, open, target_branch, pull_at, body, patch, rkey from pulls where repo_at = ? order by created desc`, repoAt) 126 + rows, err := e.Query(` 127 + select 128 + owner_did, 129 + pull_id, 130 + created, 131 + title, 132 + state, 133 + target_branch, 134 + pull_at, 135 + body, 136 + patch, 137 + rkey 138 + from 139 + pulls 140 + where 141 + repo_at = ? and state = ? 142 + order by 143 + created desc`, repoAt, state) 96 144 if err != nil { 97 145 return nil, err 98 146 } ··· 101 149 for rows.Next() { 102 150 var pull Pull 103 151 var createdAt string 104 - err := rows.Scan(&pull.OwnerDid, &pull.PullId, &createdAt, &pull.Title, &pull.Open, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey) 152 + err := rows.Scan(&pull.OwnerDid, &pull.PullId, &createdAt, &pull.Title, &pull.State, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey) 105 153 if err != nil { 106 154 return nil, err 107 155 } ··· 123 171 } 124 172 125 173 func GetPull(e Execer, repoAt syntax.ATURI, pullId int) (*Pull, error) { 126 - query := `select owner_did, created, title, open, target_branch, pull_at, body, patch, rkey from pulls where repo_at = ? and pull_id = ?` 174 + query := `select owner_did, created, title, state, target_branch, pull_at, body, patch, rkey from pulls where repo_at = ? and pull_id = ?` 127 175 row := e.QueryRow(query, repoAt, pullId) 128 176 129 177 var pull Pull 130 178 var createdAt string 131 - err := row.Scan(&pull.OwnerDid, &createdAt, &pull.Title, &pull.Open, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey) 179 + err := row.Scan(&pull.OwnerDid, &createdAt, &pull.Title, &pull.State, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey) 132 180 if err != nil { 133 181 return nil, err 134 182 } ··· 143 191 } 144 192 145 193 func GetPullWithComments(e Execer, repoAt syntax.ATURI, pullId int) (*Pull, []PullComment, error) { 146 - query := `select owner_did, pull_id, created, title, open, target_branch, pull_at, body, patch, rkey from pulls where repo_at = ? and pull_id = ?` 194 + query := `select owner_did, pull_id, created, title, state, target_branch, pull_at, body, patch, rkey from pulls where repo_at = ? and pull_id = ?` 147 195 row := e.QueryRow(query, repoAt, pullId) 148 196 149 197 var pull Pull 150 198 var createdAt string 151 - err := row.Scan(&pull.OwnerDid, &pull.PullId, &createdAt, &pull.Title, &pull.Open, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey) 199 + err := row.Scan(&pull.OwnerDid, &pull.PullId, &createdAt, &pull.Title, &pull.State, &pull.TargetBranch, &pull.PullAt, &pull.Body, &pull.Patch, &pull.Rkey) 152 200 if err != nil { 153 201 return nil, nil, err 154 202 } ··· 217 265 return comments, nil 218 266 } 219 267 268 + func SetPullState(e Execer, repoAt syntax.ATURI, pullId int, pullState PullState) error { 269 + _, err := e.Exec(`update pulls set state = ? where repo_at = ? and pull_id = ?`, pullState, repoAt, pullId) 270 + return err 271 + } 272 + 220 273 func ClosePull(e Execer, repoAt syntax.ATURI, pullId int) error { 221 - _, err := e.Exec(`update pulls set open = 0 where repo_at = ? and pull_id = ?`, repoAt, pullId) 274 + err := SetPullState(e, repoAt, pullId, PullClosed) 222 275 return err 223 276 } 224 277 225 278 func ReopenPull(e Execer, repoAt syntax.ATURI, pullId int) error { 226 - _, err := e.Exec(`update pulls set open = 1 where repo_at = ? and pull_id = ?`, repoAt, pullId) 279 + err := SetPullState(e, repoAt, pullId, PullOpen) 227 280 return err 228 281 } 229 282 230 283 func MergePull(e Execer, repoAt syntax.ATURI, pullId int) error { 231 - _, err := e.Exec(`update pulls set open = 2 where repo_at = ? and pull_id = ?`, repoAt, pullId) 284 + err := SetPullState(e, repoAt, pullId, PullMerged) 232 285 return err 233 286 } 234 287 235 288 type PullCount struct { 236 289 Open int 290 + Merged int 237 291 Closed int 238 292 } 239 293 240 294 func GetPullCount(e Execer, repoAt syntax.ATURI) (PullCount, error) { 241 295 row := e.QueryRow(` 242 296 select 243 - count(case when open = 1 then 1 end) as open_count, 244 - count(case when open = 0 then 1 end) as closed_count 297 + count(case when state = 0 then 1 end) as open_count, 298 + count(case when state = 1 then 1 end) as merged_count, 299 + count(case when state = 2 then 1 end) as closed_count 245 300 from pulls 246 301 where repo_at = ?`, 247 302 repoAt, 248 303 ) 249 304 250 305 var count PullCount 251 - if err := row.Scan(&count.Open, &count.Closed); err != nil { 252 - return PullCount{0, 0}, err 306 + if err := row.Scan(&count.Open, &count.Merged, &count.Closed); err != nil { 307 + return PullCount{0, 0, 0}, err 253 308 } 254 309 255 310 return count, nil
+1
appview/db/repos.go
··· 246 246 type RepoStats struct { 247 247 StarCount int 248 248 IssueCount IssueCount 249 + PullCount PullCount 249 250 } 250 251 251 252 func scanRepo(rows *sql.Rows, did, name, knot, rkey, description *string, created *time.Time) error {
+2 -9
appview/pages/pages.go
··· 272 272 meta := make(map[string]any) 273 273 274 274 meta["issues"] = r.Stats.IssueCount.Open 275 + meta["pulls"] = r.Stats.PullCount.Open 275 276 276 277 // more stuff? 277 278 ··· 524 525 Pulls []db.Pull 525 526 Active string 526 527 DidHandleMap map[string]string 528 + FilteringBy db.PullState 527 529 } 528 530 529 531 func (p *Pages) RepoPulls(w io.Writer, params RepoPullsParams) error { ··· 536 538 RepoInfo RepoInfo 537 539 DidHandleMap map[string]string 538 540 Pull db.Pull 539 - State string 540 541 PullOwnerHandle string 541 542 Comments []db.PullComment 542 543 Active string ··· 544 545 } 545 546 546 547 func (p *Pages) RepoSinglePull(w io.Writer, params RepoSinglePullParams) error { 547 - switch params.Pull.Open { 548 - case 0: 549 - params.State = "close" 550 - case 1: 551 - params.State = "open" 552 - case 2: 553 - params.State = "merged" 554 - } 555 548 params.Active = "pulls" 556 549 return p.executeRepo("repo/pulls/pull", w, params) 557 550 }
+1 -1
appview/pages/templates/repo/pulls/new.html
··· 15 15 <p class="text-gray-500"> 16 16 The branch you want to make your change against. 17 17 </p> 18 - <select class="p-1 border border-gray-200 bg-white"> 18 + <select name="targetBranch" class="p-1 border border-gray-200 bg-white"> 19 19 <option disabled selected>Select a branch</option> 20 20 {{ range .Branches }} 21 21 <option
+9 -7
appview/pages/templates/repo/pulls/pull.html
··· 14 14 15 15 {{ $bgColor := "bg-gray-800" }} 16 16 {{ $icon := "ban" }} 17 - {{ if eq .State "open" }} 17 + 18 + {{ if .Pull.State.IsOpen }} 18 19 {{ $bgColor = "bg-green-600" }} 19 20 {{ $icon = "circle-dot" }} 20 - {{ else if eq .State "merged" }} 21 + {{ else if .Pull.State.IsMerged }} 21 22 {{ $bgColor = "bg-purple-600" }} 22 23 {{ $icon = "git-merge" }} 23 24 {{ end }} ··· 33 34 data-lucide="{{ $icon }}" 34 35 class="w-4 h-4 mr-1.5 text-white" 35 36 ></i> 36 - <span class="text-white">{{ .State }}</span> 37 + <span class="text-white">{{ .Pull.State.String }}</span> 37 38 </div> 38 39 <span class="text-gray-400 text-sm"> 39 40 opened by ··· 41 42 <a href="/{{ $owner }}" class="no-underline hover:underline" 42 43 >{{ $owner }}</a 43 44 > 44 - <span class="px-1 select-none before:content-['\00B7']"></span> 45 + <span class="select-none before:content-['\00B7']"></span> 45 46 <time>{{ .Pull.Created | timeFmt }}</time> 47 + <span class="select-none before:content-['\00B7']"></span> 48 + <time>targeting branch {{ .Pull.TargetBranch }}</time> 46 49 </span> 47 50 </div> 48 51 ··· 257 260 {{ $action := "close" }} 258 261 {{ $icon := "circle-x" }} 259 262 {{ $hoverColor := "red" }} 260 - {{ if eq .State "closed" }} 263 + {{ if .Pull.State.IsClosed }} 261 264 {{ $action = "reopen" }} 262 265 {{ $icon = "circle-dot" }} 263 266 {{ $hoverColor = "green" }} ··· 265 268 <form 266 269 hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/{{ $action }}" 267 270 hx-swap="none" 268 - class="mt-8" 269 - > 271 + class="mt-8"> 270 272 <button type="submit" class="btn hover:bg-{{ $hoverColor }}-300"> 271 273 <i 272 274 data-lucide="{{ $icon }}"
+9 -21
appview/pages/templates/repo/pulls/pulls.html
··· 8 8 class="border px-1 bg-white border-gray-200" 9 9 onchange="window.location.href = '/{{ .RepoInfo.FullName }}/pulls?state=' + this.value" 10 10 > 11 - <option value="open" {{ if .FilteringByOpen }}selected{{ end }}> 11 + <option value="open" {{ if .FilteringBy.IsOpen }}selected{{ end }}> 12 12 open 13 13 </option> 14 - <option 15 - value="closed" 16 - {{ if eq .FilteringState "closed" }}selected{{ end }} 17 - > 18 - closed 19 - </option> 20 - <option 21 - value="merged" 22 - {{ if eq .FilteringState "merged" }}selected{{ end }} 23 - > 14 + <option value="merged" {{ if .FilteringBy.IsMerged }}selected{{ end }}> 24 15 merged 25 16 </option> 17 + <option value="closed" {{ if .FilteringBy.IsClosed }}selected{{ end }}> 18 + closed 19 + </option> 26 20 </select> 27 21 pull requests 28 22 </p> ··· 42 36 {{ range .Pulls }} 43 37 <div class="rounded drop-shadow-sm bg-white px-6 py-4"> 44 38 <div class="pb-2"> 45 - <a 46 - href="/{{ $.RepoInfo.FullName }}/pulls/{{ .PullId }}" 47 - class="no-underline hover:underline" 48 - > 39 + <a href="/{{ $.RepoInfo.FullName }}/pulls/{{ .PullId }}"> 49 40 {{ .Title }} 50 41 <span class="text-gray-500">#{{ .PullId }}</span> 51 42 </a> ··· 53 44 <p class="text-sm text-gray-500"> 54 45 {{ $bgColor := "bg-gray-800" }} 55 46 {{ $icon := "ban" }} 56 - {{ $state := "closed" }} 57 47 58 - {{ if eq .Open 1 }} 48 + {{ if .State.IsOpen }} 59 49 {{ $bgColor = "bg-green-600" }} 60 50 {{ $icon = "git-pull-request" }} 61 - {{ $state = "open" }} 62 - {{ else if eq .Open 2 }} 51 + {{ else if .State.IsMerged }} 63 52 {{ $bgColor = "bg-purple-600" }} 64 53 {{ $icon = "git-merge" }} 65 - {{ $state = "merged" }} 66 54 {{ end }} 67 55 68 56 ··· 73 61 data-lucide="{{ $icon }}" 74 62 class="w-3 h-3 mr-1.5 text-white" 75 63 ></i> 76 - <span class="text-white">{{ $state }}</span> 64 + <span class="text-white">{{ .State.String }}</span> 77 65 </span> 78 66 79 67 <span>
+18 -2
appview/state/repo.go
··· 413 413 targetBranch := r.FormValue("targetBranch") 414 414 patch := r.FormValue("patch") 415 415 416 - if title == "" || body == "" || patch == "" { 416 + if title == "" || body == "" || patch == "" || targetBranch == "" { 417 417 s.pages.Notice(w, "pull", "Title, body and patch diff are required.") 418 418 return 419 419 } ··· 990 990 if err != nil { 991 991 log.Println("failed to get issue count for ", f.RepoAt) 992 992 } 993 + pullCount, err := db.GetPullCount(s.db, f.RepoAt) 994 + if err != nil { 995 + log.Println("failed to get issue count for ", f.RepoAt) 996 + } 993 997 994 998 knot := f.Knot 995 999 if knot == "knot1.tangled.sh" { ··· 1008 1012 Stats: db.RepoStats{ 1009 1013 StarCount: starCount, 1010 1014 IssueCount: issueCount, 1015 + PullCount: pullCount, 1011 1016 }, 1012 1017 } 1013 1018 } ··· 1399 1404 1400 1405 func (s *State) RepoPulls(w http.ResponseWriter, r *http.Request) { 1401 1406 user := s.auth.GetUser(r) 1407 + params := r.URL.Query() 1408 + 1409 + state := db.PullOpen 1410 + switch params.Get("state") { 1411 + case "closed": 1412 + state = db.PullClosed 1413 + case "merged": 1414 + state = db.PullMerged 1415 + } 1416 + 1402 1417 f, err := fullyResolvedRepo(r) 1403 1418 if err != nil { 1404 1419 log.Println("failed to get repo and knot", err) 1405 1420 return 1406 1421 } 1407 1422 1408 - pulls, err := db.GetPulls(s.db, f.RepoAt) 1423 + pulls, err := db.GetPulls(s.db, f.RepoAt, state) 1409 1424 if err != nil { 1410 1425 log.Println("failed to get pulls", err) 1411 1426 s.pages.Notice(w, "pulls", "Failed to load pulls. Try again later.") ··· 1431 1446 RepoInfo: f.RepoInfo(s, user), 1432 1447 Pulls: pulls, 1433 1448 DidHandleMap: didHandleMap, 1449 + FilteringBy: state, 1434 1450 }) 1435 1451 return 1436 1452 }