{{/* Pull Requests Page Content */}} {{/* Named templates for the actionability PR tables. Defined at top level because Hugo requires {{ define }} outside control structures. Called via {{ template }} below. Column layout kept identical across all call sites so rows align. */}} {{/* Auth badge — #92ad2d matches the GitHub area:auth label. Inline style because tailwind doesn't ship an arbitrary-hex class and the purge would drop it. */}} {{ define "act-auth-badge" }}{{ . }}{{ end }} {{ define "act-sla-badge" }}{{ . }}{{ end }} {{ define "act-pr-row" }} #{{ .number }} {{ if .is_maintainer }}{{ .author }}{{ else }}{{ .author }}{{ end }} {{ with .sla_kind }}{{ template "act-sla-badge" . }}{{ end }}{{ if .is_auth }}{{ template "act-auth-badge" "auth" }}{{ end }}{{ .title }} {{ .short_reason }} +{{ .additions }}-{{ .deletions }} {{ .age_days | lang.FormatNumber 0 }}d {{ end }} {{/* Per-section ⊕/⊖ toggle — low-contrast until hover so it doesn't compete with the tier name. Paired with actToggle() defined inline below. */}} {{ define "act-tier-toggle" }} {{ end }} {{ define "act-state-detail" }}
{{ with (len (where .prs "sla_breach" true)) }}{{ if gt . 0 }}{{ template "act-sla-badge" (printf "%d SLA" .) }}{{ end }}{{ end }}{{ with (len (where .prs "is_auth" true)) }}{{ if gt . 0 }}{{ template "act-auth-badge" (printf "%d auth" .) }}{{ end }}{{ end }} {{ .name }} ({{ len .prs }}){{ .desc }} {{ range .prs }}{{ template "act-pr-row" . }}{{ end }}
{{ end }} {{/* Support both direct context and dict with context/repoKey */}} {{ $context := . }} {{ $repoKey := "" }} {{ if reflect.IsMap . }} {{ with .context }}{{ $context = . }}{{ end }} {{ with .repoKey }}{{ $repoKey = . }}{{ end }} {{ end }} {{ $data := partial "load-metrics.html" (dict "context" $context "repoKey" $repoKey) }} {{ $m := $data.metrics }} {{ $snapshots := $data.snapshots }} {{ if not $m }}
No data available. Run the aggregation script.
{{ else }} {{/* Extract sparkline data for PR metrics */}} {{ $pullsOpenSparkline := partial "get-sparkline.html" (dict "snapshots" $snapshots "path" "pulls.open") }} {{ $pullsAwaitingSparkline := partial "get-sparkline.html" (dict "snapshots" $snapshots "path" "pulls.without_review_24h") }} {{ $pullsReviewMedianSparkline := partial "get-sparkline.html" (dict "snapshots" $snapshots "path" "pulls.review_time.median_hours") }} {{ $pullsMergeMedianSparkline := partial "get-sparkline.html" (dict "snapshots" $snapshots "path" "pulls.merge_time.median_hours") }} {{/* Calculate trends from sparkline data */}} {{ $pullsOpenTrend := partial "calc-trend.html" (dict "sparkline" $pullsOpenSparkline) }} {{ $pullsAwaitingTrend := partial "calc-trend.html" (dict "sparkline" $pullsAwaitingSparkline) }} {{ $pullsReviewTrend := partial "calc-trend.html" (dict "sparkline" $pullsReviewMedianSparkline) }} {{ $pullsMergeTrend := partial "calc-trend.html" (dict "sparkline" $pullsMergeMedianSparkline) }} {{/* Build GitHub filter URLs for PRs */}} {{ $repoKey := $data.repoKey }} {{ $openPRsLink := printf "https://github.com/%s/pulls?q=is:pr+is:open" $repoKey }} {{ $draftPRsLink := printf "https://github.com/%s/pulls?q=is:pr+is:open+draft:true" $repoKey }} {{ $opened7dLink := printf "https://github.com/%s/pulls?q=is:pr+created:>%s" $repoKey (now.AddDate 0 0 -7 | time.Format "2006-01-02") }} {{ $opened30dLink := printf "https://github.com/%s/pulls?q=is:pr+created:>%s" $repoKey (now.AddDate 0 0 -30 | time.Format "2006-01-02") }} {{ $opened90dLink := printf "https://github.com/%s/pulls?q=is:pr+created:>%s" $repoKey (now.AddDate 0 0 -90 | time.Format "2006-01-02") }} {{ $merged7dLink := printf "https://github.com/%s/pulls?q=is:pr+is:merged+merged:>=%s" $repoKey (now.AddDate 0 0 -7 | time.Format "2006-01-02") }} {{ $merged30dLink := printf "https://github.com/%s/pulls?q=is:pr+is:merged+merged:>=%s" $repoKey (now.AddDate 0 0 -30 | time.Format "2006-01-02") }} {{ $merged90dLink := printf "https://github.com/%s/pulls?q=is:pr+is:merged+merged:>=%s" $repoKey (now.AddDate 0 0 -90 | time.Format "2006-01-02") }} {{ $closedUnmerged90dLink := printf "https://github.com/%s/pulls?q=is:pr+is:closed+is:unmerged+closed:>%s" $repoKey (now.AddDate 0 0 -90 | time.Format "2006-01-02") }} {{/* Actionability — from scripts/pr-actionable classifier. Only exists for typescript-sdk/python-sdk. */}} {{ $a := $data.actionability }} {{ if $a }} {{/* ────────────────────────────────────────────────────────────────────────── HEADLINE — 4 cards, always visible. Sparklines show trend once snapshots accumulate (actionability.* paths in snapshots/YYYY-MM-DD.json). ────────────────────────────────────────────────────────────────────────── */}} {{ $actCountSpark := partial "get-sparkline.html" (dict "snapshots" $snapshots "path" "actionability.actionable_count") }} {{ $actHoursSpark := partial "get-sparkline.html" (dict "snapshots" $snapshots "path" "actionability.effort_hours") }} {{ $actAuthSpark := partial "get-sparkline.html" (dict "snapshots" $snapshots "path" "actionability.auth_count") }} {{ $actCountTrend := partial "calc-trend.html" (dict "sparkline" $actCountSpark) }} {{ $actHoursTrend := partial "calc-trend.html" (dict "sparkline" $actHoursSpark) }} {{ $actionedSpark := partial "get-sparkline.html" (dict "snapshots" $snapshots "path" "actionability.actioned") }} {{ $actionedTrend := partial "calc-trend.html" (dict "sparkline" $actionedSpark) }} {{/* ────────────────────────────────────────────────────────────────────────── HEADLINE + SLA — two card rows. Row 1 = queue health, row 2 = SLA breaches. Scoped inside `with .sla` so repos pre-dating the classifier fall through. ────────────────────────────────────────────────────────────────────────── */}} {{ with $a.summary.sla }} {{ $s := . }} {{ $act := $a.summary.actionable_count }} {{ $auth := $a.summary.auth_count }} {{ $hrs := $a.summary.effort_hours }} {{/* Actionable: ≤25 green / ≤50 yellow / >50 red. Hours: <5 green / <10 yellow / ≥10 red. */}} {{ $actClr := cond (le $act 25) "text-success" (cond (le $act 50) "text-warning" "text-error") }} {{ $hrsClr := cond (lt $hrs 5.0) "text-success" (cond (lt $hrs 10.0) "text-warning" "text-error") }} {{ $actPct := div (mul 100.0 $act) $s.actionable_target }} {{ $authPct := cond (gt $act 0) (div (mul 100.0 $auth) $act) 0.0 }} {{/* SLA breach counts — directly actionable: review one old PR → number drops by one. First/re-review: <5 green / <10 yellow / 10+ red (volume-driven, weekends cause noise). Maintainer: 0-1 green / 2-3 yellow / 4+ red (tighter — these are teammates blocked). */}} {{ $firstClr := cond (lt $s.first_review_7d_breach 5) "text-success" (cond (lt $s.first_review_7d_breach 10) "text-warning" "text-error") }} {{ $reClr := cond (lt $s.re_review_24h_breach 5) "text-success" (cond (lt $s.re_review_24h_breach 10) "text-warning" "text-error") }} {{ $maintClr := cond (le $s.maint_24h_breach 1) "text-success" (cond (le $s.maint_24h_breach 3) "text-warning" "text-error") }} {{ $firstSpark := partial "get-sparkline.html" (dict "snapshots" $snapshots "path" "actionability.sla.first_review_7d_breach") }} {{ $reSpark := partial "get-sparkline.html" (dict "snapshots" $snapshots "path" "actionability.sla.re_review_24h_breach") }} {{ $maintSpark := partial "get-sparkline.html" (dict "snapshots" $snapshots "path" "actionability.sla.maint_24h_breach") }}
{{ partial "metric-card.html" (dict "label" "Actionable vs target" "value" $act "valueClass" $actClr "total" $s.actionable_target "percent" $actPct "percentLabel" "of target" "sparkline" $actCountSpark "sparklineColor" (cond $s.actionable_over_target "rgb(220, 53, 69)" "rgb(40, 167, 69)") "trend" $actCountTrend "trendGoodDirection" "down" "info" (printf "PRs where the ball is in our court.\n\nGreen: ≤ 25\nYellow: 26–50\nRed: > 50")) }}
{{ partial "metric-card.html" (dict "label" "Auth" "value" $auth "total" $act "percent" $authPct "percentLabel" "of actionable" "sparkline" $actAuthSpark "sparklineColor" "rgb(255, 193, 7)" "info" (printf "Actionable PRs touching auth code.\nClick to filter to these PRs.\n\nNo target — informational.")) }}
{{ if isset $a.summary "actioned_7d" }} {{ partial "metric-card.html" (dict "label" "Actioned (7d)" "value" $a.summary.actioned_7d "descriptor" (printf "%d in last 30d" (int ($a.summary.actioned_30d | default 0))) "sparkline" $actionedSpark "sparklineColor" "rgb(40, 167, 69)" "trend" $actionedTrend "trendGoodDirection" "up" "info" "Throughput: actionable→non-actionable transitions per day. A PR that cycles review→author→re-review counts each cycle. Sparkline shows daily values.") }} {{ end }} {{ $mergedSpark := partial "get-sparkline.html" (dict "snapshots" $snapshots "path" "pulls.merged_7d") }} {{ partial "metric-card.html" (dict "label" "Merged (7d)" "value" $m.pulls.merged_7d "descriptor" (printf "%d in last 30d" (int ($m.pulls.merged_30d | default 0))) "sparkline" $mergedSpark "sparklineColor" "rgb(108, 117, 125)" "info" "PRs merged in the last 7 days — the terminal-outcome subset of Actioned. Rolling 7×24h window from last data refresh.") }} {{ partial "metric-card.html" (dict "label" "Hours to clear" "value" (printf "~%s" ($hrs | lang.FormatNumber 1)) "valueClass" $hrsClr "sparkline" $actHoursSpark "sparklineColor" "rgb(108, 117, 125)" "trend" $actHoursTrend "trendGoodDirection" "down" "info" (printf "Estimated maintainer hours to clear all actionable PRs.\n\nGreen: < 5h\nYellow: 5–10h\nRed: ≥ 10h")) }}
{{ partial "metric-card.html" (dict "label" "1st review > 7d" "value" $s.first_review_7d_breach "valueClass" $firstClr "descriptor" (printf "of %d eligible" (int ($s.first_review_eligible | default 0))) "sparkline" $firstSpark "sparklineColor" "rgb(220, 53, 69)" "trendGoodDirection" "down" "info" (printf "Community PRs past 7 days with no maintainer review — across all pressing states, not just the first-review bucket.\nClick to filter to these PRs.\n\nGreen: < 5\nYellow: 5–9\nRed: ≥ 10")) }}
{{ partial "metric-card.html" (dict "label" "Re-review > 24h" "value" $s.re_review_24h_breach "valueClass" $reClr "descriptor" (printf "of %d eligible" (int ($s.re_review_eligible | default 0))) "sparkline" $reSpark "sparklineColor" "rgb(220, 53, 69)" "trendGoodDirection" "down" "info" (printf "PRs where the author acted (pushed/commented) after our review, past 24h — across all pressing states.\nClick to filter to these PRs.\n\nGreen: < 5\nYellow: 5–9\nRed: ≥ 10")) }}
{{ partial "metric-card.html" (dict "label" "Maintainer > 24h" "value" $s.maint_24h_breach "valueClass" $maintClr "descriptor" (printf "of %d eligible" (int ($s.maint_eligible | default 0))) "sparkline" $maintSpark "sparklineColor" "rgb(220, 53, 69)" "trendGoodDirection" "down" "info" (printf "PRs from maintainers past 24 hours — across all pressing states. A maintainer PR in a cluster still counts.\nClick to filter to these PRs.\n\nGreen: 0–1\nYellow: 2–3\nRed: ≥ 4")) }}
{{ end }} {{/* ────────────────────────────────────────────────────────────────────────── ALL STATS — collapsed by default. Volume, Review/Merge time, Size dist. ────────────────────────────────────────────────────────────────────────── */}}
Stats — volume, timing, size distribution

Volume

{{ partial "metric-card.html" (dict "label" "Open PRs" "value" $m.pulls.open_count "sparkline" $pullsOpenSparkline "sparklineColor" "rgb(40, 167, 69)" "trend" $pullsOpenTrend "trendGoodDirection" "down" "link" $openPRsLink) }} {{ partial "metric-card.html" (dict "label" "Draft PRs" "value" $m.pulls.draft_count "link" $draftPRsLink) }} {{ partial "metric-card.html" (dict "label" "Opened" "value" $m.pulls.opened_7d "descriptor" "last 7 days" "link" $opened7dLink) }} {{ partial "metric-card.html" (dict "label" "Opened" "value" $m.pulls.opened_30d "descriptor" "last 30 days" "link" $opened30dLink) }} {{ partial "metric-card.html" (dict "label" "Opened" "value" $m.pulls.opened_90d "descriptor" "last 90 days" "link" $opened90dLink) }} {{ partial "metric-card.html" (dict "label" "Merged" "value" $m.pulls.merged_7d "descriptor" "last 7 days" "link" $merged7dLink) }} {{ partial "metric-card.html" (dict "label" "Merged" "value" $m.pulls.merged_30d "descriptor" "last 30 days" "link" $merged30dLink) }} {{ partial "metric-card.html" (dict "label" "Merged" "value" $m.pulls.merged_90d "descriptor" "last 90 days" "link" $merged90dLink) }} {{ partial "metric-card.html" (dict "label" "Closed Unmerged" "value" $m.pulls.closed_not_merged_90d "descriptor" "last 90 days" "link" $closedUnmerged90dLink) }}

Time to First Review

{{ partial "metric-card.html" (dict "label" "Average" "value" (partial "format-hours.html" $m.pulls.review_time.avg_hours)) }} {{ partial "metric-card.html" (dict "label" "Median" "value" (partial "format-hours.html" $m.pulls.review_time.median_hours) "sparkline" $pullsReviewMedianSparkline "sparklineColor" "rgb(108, 117, 125)" "trend" $pullsReviewTrend "trendGoodDirection" "down") }} {{ partial "metric-card.html" (dict "label" "P90" "value" (partial "format-hours.html" $m.pulls.review_time.p90_hours)) }} {{ partial "metric-card.html" (dict "label" "P95" "value" (partial "format-hours.html" $m.pulls.review_time.p95_hours)) }}

Merge Time

{{ partial "metric-card.html" (dict "label" "Average" "value" (partial "format-hours.html" $m.pulls.merge_time.avg_hours)) }} {{ partial "metric-card.html" (dict "label" "Median" "value" (partial "format-hours.html" $m.pulls.merge_time.median_hours) "sparkline" $pullsMergeMedianSparkline "sparklineColor" "rgb(108, 117, 125)" "trend" $pullsMergeTrend "trendGoodDirection" "down") }}

PR Size Distribution

Open PRs by lines changed

{{ partial "metric-card.html" (dict "label" "Small" "value" $m.pulls.by_size.small "descriptor" "<100 lines") }} {{ partial "metric-card.html" (dict "label" "Medium" "value" $m.pulls.by_size.medium "descriptor" "100-500 lines") }} {{ partial "metric-card.html" (dict "label" "Large" "value" $m.pulls.by_size.large "descriptor" ">500 lines") }}
{{/* end Stats */}} {{/* ────────────────────────────────────────────────────────────────────────── TIER BREAKDOWN — its own collapse, above the tier sections. ────────────────────────────────────────────────────────────────────────── */}}
Breakdown by tier
{{ range $a.summary.by_tier }} {{ end }} {{ $totN := 0 }}{{ $totA := 0 }}{{ $totM := 0 }}{{ $totMins := 0.0 }} {{ range $a.summary.by_tier }}{{ $totN = add $totN .count }}{{ $totA = add $totA .auth }}{{ $totM = add $totM .maint }}{{ $totMins = add $totMins .mins }}{{ end }}
TierCount AuthMaint. ~Time
{{ if and (ge .idx 0) (lt .idx 99) }}{{ .idx }} — {{ end }}{{ .name }} {{ .count }} {{ .auth }} {{ .maint }} {{ if ge .mins 60.0 }}{{ div .mins 60.0 | lang.FormatNumber 1 }}h{{ else if gt .mins 0.0 }}{{ .mins | lang.FormatNumber 0 }}m{{ else }}—{{ end }}
total actionable {{ $totN }} {{ $totA }} {{ $totM }} {{ if ge $totMins 60.0 }}{{ div $totMins 60.0 | lang.FormatNumber 1 }}h{{ else }}{{ $totMins | lang.FormatNumber 0 }}m{{ end }}
not our move {{ $a.summary.not_our_move_count }}
{{/* ────────────────────────────────────────────────────────────────────────── LIVE FILTER — type to filter rows; cascades to hide empty states/tiers. ────────────────────────────────────────────────────────────────────────── */}}
{{/* ────────────────────────────────────────────────────────────────────────── TIER SECTIONS — per-state
like the gist. No State column; the state IS the . Tier 0 opens by default (fastest wins). ────────────────────────────────────────────────────────────────────────── */}} {{ range $a.tiers }}

{{ .name }} ({{ .count }}) {{ template "act-tier-toggle" }}

{{ .blurb }}

{{ $tierIdx := .idx }} {{ range .states }} {{ if eq .name "duplicate-cluster" }} {{/* Clusters: nested
per cluster (gist-style). Summary shows issue link, member count, ⭐ pick. Members use the same row template so columns align. */}}
{{- $cSla := 0 }}{{ $cAuth := 0 }}{{ $cN := 0 }}{{ range .clusters }}{{ range .members }}{{ $cN = add $cN 1 }}{{ $cSla = add $cSla (cond .sla_breach 1 0) }}{{ $cAuth = add $cAuth (cond .is_auth 1 0) }}{{ end }}{{ end -}} {{ if gt $cSla 0 }}{{ template "act-sla-badge" (printf "%d SLA" $cSla) }}{{ end }}{{ if gt $cAuth 0 }}{{ template "act-auth-badge" (printf "%d auth" $cAuth) }}{{ end }} {{ .name }} ({{ len .clusters }} clusters, {{ $cN }} PRs){{ .desc }}
{{ range .clusters }}
{{ if eq .kind "issue" }} Issue #{{ .id }} {{ else }} Semantic: {{ .desc }} {{ end }} — {{ len .members }} PRs {{ with .pick }}⭐ #{{ . }}{{ end }} {{ with .pick_reason }}({{ . }}){{ end }} {{ range .members }}{{ template "act-pr-row" . }}{{ end }}
{{ end }}
{{ else }}
{{ with (len (where .prs "sla_breach" true)) }}{{ if gt . 0 }}{{ template "act-sla-badge" (printf "%d SLA" .) }}{{ end }}{{ end }}{{ with (len (where .prs "is_auth" true)) }}{{ if gt . 0 }}{{ template "act-auth-badge" (printf "%d auth" .) }}{{ end }}{{ end }} {{ .name }} ({{ len .prs }}){{ .desc }} {{ range .prs }}{{ template "act-pr-row" . }}{{ end }}
{{ end }} {{ end }}
{{ end }} {{/* ────────────────────────────────────────────────────────────────────────── BOT CORNER / UNTRIAGED / NOT OUR MOVE — rendered identically to tiers:
+

+

+ per-state

. ────────────────────────────────────────────────────────────────────────── */}} {{ with $a.bot_corner }} {{ $n := 0 }}{{ range . }}{{ $n = add $n (len .prs) }}{{ end }}

Bot corner ({{ $n }}) {{ template "act-tier-toggle" }}

Dependabot/renovate PRs that need human attention.

{{ range . }}{{ template "act-state-detail" . }}{{ end }}
{{ end }} {{ with $a.untriaged }} {{ $n := 0 }}{{ range . }}{{ $n = add $n (len .prs) }}{{ end }}

Unclassified ({{ $n }}) {{ template "act-tier-toggle" }}

Classifier couldn't determine a state — needs manual triage.

{{ range . }}{{ template "act-state-detail" . }}{{ end }}
{{ end }} {{ if $a.not_our_move }}

Not our move ({{ $a.summary.not_our_move_count }}) {{ template "act-tier-toggle" }}

Clock is on the author or blocked externally. No action owed today.

{{ range $a.not_our_move }}{{ template "act-state-detail" . }}{{ end }}
{{ end }} {{ else }}{{/* No actionability.json — csharp-sdk/spec keep the original layout unchanged */}}

Volume

{{ partial "metric-card.html" (dict "label" "Open PRs" "value" $m.pulls.open_count "sparkline" $pullsOpenSparkline "sparklineColor" "rgb(40, 167, 69)" "trend" $pullsOpenTrend "trendGoodDirection" "down" "link" $openPRsLink) }} {{ partial "metric-card.html" (dict "label" "Draft PRs" "value" $m.pulls.draft_count "link" $draftPRsLink) }} {{ partial "metric-card.html" (dict "label" "Opened" "value" $m.pulls.opened_7d "descriptor" "last 7 days" "link" $opened7dLink) }} {{ partial "metric-card.html" (dict "label" "Opened" "value" $m.pulls.opened_30d "descriptor" "last 30 days" "link" $opened30dLink) }} {{ partial "metric-card.html" (dict "label" "Opened" "value" $m.pulls.opened_90d "descriptor" "last 90 days" "link" $opened90dLink) }} {{ partial "metric-card.html" (dict "label" "Merged" "value" $m.pulls.merged_7d "descriptor" "last 7 days" "link" $merged7dLink) }} {{ partial "metric-card.html" (dict "label" "Merged" "value" $m.pulls.merged_30d "descriptor" "last 30 days" "link" $merged30dLink) }} {{ partial "metric-card.html" (dict "label" "Merged" "value" $m.pulls.merged_90d "descriptor" "last 90 days" "link" $merged90dLink) }} {{ partial "metric-card.html" (dict "label" "Closed Unmerged" "value" $m.pulls.closed_not_merged_90d "descriptor" "last 90 days" "link" $closedUnmerged90dLink) }}

Time to First Review

{{ partial "metric-card.html" (dict "label" "Average" "value" (partial "format-hours.html" $m.pulls.review_time.avg_hours)) }} {{ partial "metric-card.html" (dict "label" "Median" "value" (partial "format-hours.html" $m.pulls.review_time.median_hours) "sparkline" $pullsReviewMedianSparkline "sparklineColor" "rgb(108, 117, 125)" "trend" $pullsReviewTrend "trendGoodDirection" "down") }} {{ partial "metric-card.html" (dict "label" "P90" "value" (partial "format-hours.html" $m.pulls.review_time.p90_hours)) }} {{ partial "metric-card.html" (dict "label" "P95" "value" (partial "format-hours.html" $m.pulls.review_time.p95_hours)) }}

Merge Time

{{ partial "metric-card.html" (dict "label" "Average" "value" (partial "format-hours.html" $m.pulls.merge_time.avg_hours)) }} {{ partial "metric-card.html" (dict "label" "Median" "value" (partial "format-hours.html" $m.pulls.merge_time.median_hours) "sparkline" $pullsMergeMedianSparkline "sparklineColor" "rgb(108, 117, 125)" "trend" $pullsMergeTrend "trendGoodDirection" "down") }}
{{/* Links for PRs needing review - using review:none filter */}} {{ $noReview24hLink := printf "https://github.com/%s/pulls?q=is:pr+is:open+review:none+created:<=%s+sort:created-asc" $repoKey (now.AddDate 0 0 -1 | time.Format "2006-01-02") }} {{ $noReview7dLink := printf "https://github.com/%s/pulls?q=is:pr+is:open+review:none+created:<=%s+sort:created-asc" $repoKey (now.AddDate 0 0 -7 | time.Format "2006-01-02") }}

PRs Needing Maintainer Review

Open PRs with no maintainer review (excludes drafts from counts)

{{ partial "metric-card.html" (dict "label" "No Maintainer Review" "value" $m.pulls.without_review_24h "descriptor" ">24 hours" "sparkline" $pullsAwaitingSparkline "sparklineColor" "rgb(220, 53, 69)" "trend" $pullsAwaitingTrend "trendGoodDirection" "down") }} {{ partial "metric-card.html" (dict "label" "No Maintainer Review" "value" $m.pulls.without_review_7d "descriptor" ">7 days") }}
{{ if $m.pulls.prs_without_maintainer_review }}

PRs Awaiting Maintainer Review

Sorted by longest wait time first

{{ range $m.pulls.prs_without_maintainer_review }} {{ end }}
PR Title Author Size Reviews Waiting
#{{ .number }} {{ if .isDraft }}(draft){{ end }} {{ .title }} {{ if .author }}{{ .author }}{{ else }}unknown{{ end }} +{{ .additions }} -{{ .deletions }} {{ if gt .reviewCount 0 }} {{ .reviewCount }} {{ else }} 0 {{ end }} {{ if .isDraft }} {{ .daysWaiting }}d {{ else if gt .daysWaiting 7 }} {{ .daysWaiting }}d {{ else if gt .daysWaiting 1 }} {{ .daysWaiting }}d {{ else }} {{ .daysWaiting }}d {{ end }}
{{ end }}

PR Size Distribution

Open PRs by lines changed

{{ partial "metric-card.html" (dict "label" "Small" "value" $m.pulls.by_size.small "descriptor" "<100 lines") }} {{ partial "metric-card.html" (dict "label" "Medium" "value" $m.pulls.by_size.medium "descriptor" "100-500 lines") }} {{ partial "metric-card.html" (dict "label" "Large" "value" $m.pulls.by_size.large "descriptor" ">500 lines") }}
{{ end }}{{/* end: if $a / else */}} {{ end }}