Watch
0
0
Fork
You've already forked hyperhive
0

swarm ui: the PR report's approvals column filters on whether the rule is met

The report had an approvals column (1/2) and a separate approved column.
They are one fact, so approvals now carries the filter, complete or missing,
and the approved column is gone.
This commit is contained in:
iris 2026-11-09 22:44:10 +01:00
commit 71a4d1d255
4 changed files with 27 additions and 12 deletions

View file

@ -607,9 +607,9 @@ and base branch, and what a reviewer or merger filters on:
rule asks for (`1/2`). An approval counts when it stands as the reviewer's latest rule asks for (`1/2`). An approval counts when it stands as the reviewer's latest
decision, on the PR's current head, neither stale nor dismissed, and from a decision, on the PR's current head, neither stale nor dismissed, and from a
reviewer whose approval the rule accepts. A reviewer whose latest review asks for changes shows **changes reviewer whose approval the rule accepts. A reviewer whose latest review asks for changes shows **changes
requested**. requested**. Filter the column to **complete** for the PRs whose approvals meet
- **approved**: the approvals meet the rule. A PR into a branch with no the rule, or **missing** for the rest. A PR into a branch with no protection
protection rule has nothing to approve, so it counts as approved. rule has nothing to approve, so it counts as complete.
- **diff**: the lines the PR adds and removes (`+120 −8`), as the forge counts them. - **diff**: the lines the PR adds and removes (`+120 −8`), as the forge counts them.
- **conflicts**: the forge can't merge the PR as it stands. - **conflicts**: the forge can't merge the PR as it stands.
- **protected base**: the base branch has a protection rule. A stacked PR targets a - **protected base**: the base branch has a protection rule. A stacked PR targets a

View file

@ -26,7 +26,7 @@ import {
approvalsText, approvalsText,
diffSize, diffSize,
diffText, diffText,
hasAllApprovals, approvalsState,
prReportUrl, prReportUrl,
yesNo, yesNo,
type PrReportRow, type PrReportRow,
@ -125,14 +125,7 @@ const COLUMNS: TableColumn<PrReportRow>[] = [
</> </>
), ),
sortBy: (r) => r.approvals, sortBy: (r) => r.approvals,
}, filterValues: (r) => [approvalsState(r)],
{
key: "approved",
header: "approved",
render: (r) =>
hasAllApprovals(r) ? <Badge tone="positive" value="yes" /> : "no",
sortBy: (r) => Number(hasAllApprovals(r)),
filterValues: (r) => [yesNo(hasAllApprovals(r))],
filterMode: "multiselect", filterMode: "multiselect",
}, },
{ {

View file

@ -55,6 +55,12 @@ export function hasAllApprovals(row: PrReportRow): boolean {
return row.approvals >= row.required_approvals; return row.approvals >= row.required_approvals;
} }
/** What the approvals column filters on: whether the PR has all the approvals
* its base branch asks for. */
export function approvalsState(row: PrReportRow): "complete" | "missing" {
return hasAllApprovals(row) ? "complete" : "missing";
}
/** The diff size cell: lines added and removed, `+120 −8`. A count the forge /** The diff size cell: lines added and removed, `+120 −8`. A count the forge
* did not give reads as a dash. */ * did not give reads as a dash. */
export function diffText(row: PrReportRow): string { export function diffText(row: PrReportRow): string {

View file

@ -2,6 +2,7 @@
import assert from "node:assert/strict"; import assert from "node:assert/strict";
import { test } from "node:test"; import { test } from "node:test";
import { import {
approvalsState,
approvalsText, approvalsText,
diffSize, diffSize,
diffText, diffText,
@ -78,3 +79,18 @@ test("a PR has all approvals when it meets the rule, and an unprotected base alw
true, true,
); );
}); });
test("the approvals column filters on whether the rule is met", () => {
assert.equal(approvalsState(row({})), "missing");
assert.equal(approvalsState(row({ approvals: 2 })), "complete");
assert.equal(
approvalsState(
row({
targets_protected_branch: false,
required_approvals: 0,
approvals: 0,
}),
),
"complete",
);
});