From b1729c7ba3c0b7f760d2e0b67645b7c2e7332b5a Mon Sep 17 00:00:00 2001 From: oppiliappan Date: Mon, 29 Sep 2025 12:21:20 +0100 Subject: [PATCH] appview/pages: add labels to pulls Change-Id: nwrnkztxkovltzpkwzxvxpqypkrryqlm Signed-off-by: oppiliappan --- appview/db/pulls.go | 20 ++++++++- appview/issues/issues.go | 6 ++- appview/models/pull.go | 45 ++++++++++++++++++- appview/pages/pages.go | 3 ++ .../templates/repo/fragments/labelPanel.html | 2 +- .../repo/fragments/participants.html | 26 +++++++++++ .../pages/templates/repo/issues/issue.html | 28 +----------- appview/pages/templates/repo/pulls/pull.html | 42 ++++++++++++----- appview/pages/templates/repo/pulls/pulls.html | 7 +++ appview/pulls/pulls.go | 35 +++++++++++++++ 10 files changed, 171 insertions(+), 43 deletions(-) create mode 100644 appview/pages/templates/repo/fragments/participants.html diff --git a/appview/db/pulls.go b/appview/db/pulls.go index 7bc6a2af..bb321980 100644 --- a/appview/db/pulls.go +++ b/appview/db/pulls.go @@ -1,6 +1,7 @@ package db import ( + "cmp" "database/sql" "fmt" "maps" @@ -229,6 +230,16 @@ func GetPullsWithLimit(e Execer, limit int, filters ...filter) ([]*models.Pull, p.Submissions = submissions } } + // collect allLabels for each issue + allLabels, err := GetLabels(e, FilterIn("subject", pullAts)) + if err != nil { + return nil, fmt.Errorf("failed to query labels: %w", err) + } + for pullAt, labels := range allLabels { + if p, ok := pulls[pullAt]; ok { + p.Labels = labels + } + } orderedByPullId := []*models.Pull{} for _, p := range pulls { @@ -339,12 +350,19 @@ func GetPullSubmissions(e Execer, filters ...filter) (map[syntax.ATURI][]*models } } - // order the submissions by pull_at + // group the submissions by pull_at m := make(map[syntax.ATURI][]*models.PullSubmission) for _, s := range submissionMap { m[s.PullAt] = append(m[s.PullAt], s) } + // sort each one by round number + for _, s := range m { + slices.SortFunc(s, func(a, b *models.PullSubmission) int { + return cmp.Compare(a.RoundNumber, b.RoundNumber) + }) + } + return m, nil } diff --git a/appview/issues/issues.go b/appview/issues/issues.go index 88984e44..8e4ed732 100644 --- a/appview/issues/issues.go +++ b/appview/issues/issues.go @@ -798,7 +798,11 @@ func (rp *Issues) RepoIssues(w http.ResponseWriter, r *http.Request) { return } - labelDefs, err := db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", f.Repo.Labels)) + labelDefs, err := db.GetLabelDefinitions( + rp.db, + db.FilterIn("at_uri", f.Repo.Labels), + db.FilterContains("scope", tangled.RepoIssueNSID), + ) if err != nil { log.Println("failed to fetch labels", err) rp.pages.Error503(w) diff --git a/appview/models/pull.go b/appview/models/pull.go index e17f96ae..39a7dcbb 100644 --- a/appview/models/pull.go +++ b/appview/models/pull.go @@ -77,7 +77,8 @@ type Pull struct { PullSource *PullSource // optionally, populate this when querying for reverse mappings - Repo *Repo + Labels LabelState + Repo *Repo } func (p Pull) AsRecord() tangled.RepoPull { @@ -206,6 +207,28 @@ func (p *Pull) IsStacked() bool { return p.StackId != "" } +func (p *Pull) Participants() []string { + participantSet := make(map[string]struct{}) + participants := []string{} + + addParticipant := func(did string) { + if _, exists := participantSet[did]; !exists { + participantSet[did] = struct{}{} + participants = append(participants, did) + } + } + + addParticipant(p.OwnerDid) + + for _, s := range p.Submissions { + for _, sp := range s.Participants() { + addParticipant(sp) + } + } + + return participants +} + func (s PullSubmission) IsFormatPatch() bool { return patchutil.IsFormatPatch(s.Patch) } @@ -220,6 +243,26 @@ func (s PullSubmission) AsFormatPatch() []types.FormatPatch { return patches } +func (s *PullSubmission) Participants() []string { + participantSet := make(map[string]struct{}) + participants := []string{} + + addParticipant := func(did string) { + if _, exists := participantSet[did]; !exists { + participantSet[did] = struct{}{} + participants = append(participants, did) + } + } + + addParticipant(s.PullAt.Authority().String()) + + for _, c := range s.Comments { + addParticipant(c.OwnerDid) + } + + return participants +} + type Stack []*Pull // position of this pull in the stack diff --git a/appview/pages/pages.go b/appview/pages/pages.go index aea80769..700d6759 100644 --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -1083,6 +1083,7 @@ type RepoPullsParams struct { FilteringBy models.PullState Stacks map[string]models.Stack Pipelines map[string]models.Pipeline + LabelDefs map[string]*models.LabelDefinition } func (p *Pages) RepoPulls(w io.Writer, params RepoPullsParams) error { @@ -1122,6 +1123,8 @@ type RepoSinglePullParams struct { OrderedReactionKinds []models.ReactionKind Reactions map[models.ReactionKind]int UserReacted map[models.ReactionKind]bool + + LabelDefs map[string]*models.LabelDefinition } func (p *Pages) RepoSinglePull(w io.Writer, params RepoSinglePullParams) error { diff --git a/appview/pages/templates/repo/fragments/labelPanel.html b/appview/pages/templates/repo/fragments/labelPanel.html index f475bdb8..e735d186 100644 --- a/appview/pages/templates/repo/fragments/labelPanel.html +++ b/appview/pages/templates/repo/fragments/labelPanel.html @@ -1,5 +1,5 @@ {{ define "repo/fragments/labelPanel" }} -
+
{{ template "basicLabels" . }} {{ template "kvLabels" . }}
diff --git a/appview/pages/templates/repo/fragments/participants.html b/appview/pages/templates/repo/fragments/participants.html new file mode 100644 index 00000000..7539cca9 --- /dev/null +++ b/appview/pages/templates/repo/fragments/participants.html @@ -0,0 +1,26 @@ +{{ define "repo/fragments/participants" }} + {{ $all := . }} + {{ $ps := take $all 5 }} +
+
+ Participants + {{ len $all }} +
+
+ {{ $c := "z-50 z-40 z-30 z-20 z-10" }} + {{ range $i, $p := $ps }} + + {{ end }} + + {{ if gt (len $all) 5 }} + + +{{ sub (len $all) 5 }} + + {{ end }} +
+
+{{ end }} diff --git a/appview/pages/templates/repo/issues/issue.html b/appview/pages/templates/repo/issues/issue.html index 23abf66b..7fa50d46 100644 --- a/appview/pages/templates/repo/issues/issue.html +++ b/appview/pages/templates/repo/issues/issue.html @@ -22,7 +22,7 @@ "Defs" $.LabelDefs "Subject" $.Issue.AtUri "State" $.Issue.Labels) }} - {{ template "issueParticipants" . }} + {{ template "repo/fragments/participants" $.Issue.Participants }}
{{ end }} @@ -122,32 +122,6 @@ {{ end }} -{{ define "issueParticipants" }} - {{ $all := .Issue.Participants }} - {{ $ps := take $all 5 }} -
-
- Participants - {{ len $all }} -
-
- {{ $c := "z-50 z-40 z-30 z-20 z-10" }} - {{ range $i, $p := $ps }} - - {{ end }} - - {{ if gt (len $all) 5 }} - - +{{ sub (len $all) 5 }} - - {{ end }} -
-
-{{ end }} {{ define "repoAfter" }}
diff --git a/appview/pages/templates/repo/pulls/pull.html b/appview/pages/templates/repo/pulls/pull.html index 087e0834..7873be1d 100644 --- a/appview/pages/templates/repo/pulls/pull.html +++ b/appview/pages/templates/repo/pulls/pull.html @@ -9,6 +9,24 @@ {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }} {{ end }} +{{ define "repoContentLayout" }} +
+
+
+ {{ block "repoContent" . }}{{ end }} +
+ {{ block "repoAfter" . }}{{ end }} +
+
+ {{ template "repo/fragments/labelPanel" + (dict "RepoInfo" $.RepoInfo + "Defs" $.LabelDefs + "Subject" $.Pull.PullAt + "State" $.Pull.Labels) }} + {{ template "repo/fragments/participants" $.Pull.Participants }} +
+
+{{ end }} {{ define "repoContent" }} {{ template "repo/pulls/fragments/pullHeader" . }} @@ -39,13 +57,13 @@ {{ with $item }}
-
+
{{ i "hash" "w-4 h-4" }}{{ .RoundNumber }}
-
+
{{ $owner := resolve $.Pull.OwnerDid }} {{ $re := "re" }} @@ -72,16 +90,16 @@ {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} - {{ if not (eq .RoundNumber 0) }} - - {{ i "chevrons-left-right-ellipsis" "w-4 h-4 rotate-90" }} - - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} - - + {{ if ne $idx 0 }} + + {{ i "chevrons-left-right-ellipsis" "w-4 h-4 rotate-90" }} + + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} + {{ end }} +
@@ -146,7 +164,7 @@
{{ range $cidx, $c := .Comments }} -
+
{{ if gt $cidx 0 }}
{{ end }} diff --git a/appview/pages/templates/repo/pulls/pulls.html b/appview/pages/templates/repo/pulls/pulls.html index bdc0b065..6541a54c 100644 --- a/appview/pages/templates/repo/pulls/pulls.html +++ b/appview/pages/templates/repo/pulls/pulls.html @@ -108,6 +108,13 @@ {{ template "repo/pipelines/fragments/pipelineSymbol" $pipeline }} {{ end }} + + {{ $state := .Labels }} + {{ range $k, $d := $.LabelDefs }} + {{ range $v, $s := $state.GetValSet $d.AtUri.String }} + {{ template "labels/fragments/label" (dict "def" $d "val" $v "withPrefix" true) }} + {{ end }} + {{ end }}
{{ if .StackId }} diff --git a/appview/pulls/pulls.go b/appview/pulls/pulls.go index 77f35577..e5900d4b 100644 --- a/appview/pulls/pulls.go +++ b/appview/pulls/pulls.go @@ -200,6 +200,22 @@ func (s *Pulls) RepoSinglePull(w http.ResponseWriter, r *http.Request) { userReactions = db.GetReactionStatusMap(s.db, user.Did, pull.PullAt()) } + labelDefs, err := db.GetLabelDefinitions( + s.db, + db.FilterIn("at_uri", f.Repo.Labels), + db.FilterContains("scope", tangled.RepoPullNSID), + ) + if err != nil { + log.Println("failed to fetch labels", err) + s.pages.Error503(w) + return + } + + defs := make(map[string]*models.LabelDefinition) + for _, l := range labelDefs { + defs[l.AtUri().String()] = &l + } + s.pages.RepoSinglePull(w, pages.RepoSinglePullParams{ LoggedInUser: user, RepoInfo: repoInfo, @@ -213,6 +229,8 @@ func (s *Pulls) RepoSinglePull(w http.ResponseWriter, r *http.Request) { OrderedReactionKinds: models.OrderedReactionKinds, Reactions: reactionCountMap, UserReacted: userReactions, + + LabelDefs: defs, }) } @@ -557,10 +575,27 @@ func (s *Pulls) RepoPulls(w http.ResponseWriter, r *http.Request) { m[p.Sha] = p } + labelDefs, err := db.GetLabelDefinitions( + s.db, + db.FilterIn("at_uri", f.Repo.Labels), + db.FilterContains("scope", tangled.RepoPullNSID), + ) + if err != nil { + log.Println("failed to fetch labels", err) + s.pages.Error503(w) + return + } + + defs := make(map[string]*models.LabelDefinition) + for _, l := range labelDefs { + defs[l.AtUri().String()] = &l + } + s.pages.RepoPulls(w, pages.RepoPullsParams{ LoggedInUser: s.oauth.GetUser(r), RepoInfo: f.RepoInfo(user), Pulls: pulls, + LabelDefs: defs, FilteringBy: state, Stacks: stacks, Pipelines: m, -- 2.43.0