From 73edd64c5888d77acd4902e2ff5b95276e7d1286 Mon Sep 17 00:00:00 2001 From: testvalue Date: Wed, 8 Apr 2026 21:32:01 -0400 Subject: [PATCH 1/7] fix(scope): shows tracked user items in default involves_me scope MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The scope filter's isUserInvolved() tier 1 checked whether the main user's login was in surfacedBy, hiding items surfaced only by tracked users. Since surfacedBy is exclusively populated by involves: searches (main user or tracked users), any surfacedBy presence means someone the user chose to track is involved — always relevant. Changes tier 1 from surfacedBy.includes(login) to surfacedBy.length > 0. Monitored repo items (no surfacedBy) still use field-based fallback. Updates 4 tests that modeled tracked user items as community items by using surfacedBy with a non-main-user login — an unrealistic fixture since surfacedBy is only set for tracked user search results. --- src/app/lib/grouping.ts | 5 +++-- tests/components/dashboard/IssuesTab.test.tsx | 10 +++++----- tests/components/dashboard/PullRequestsTab.test.tsx | 10 +++++----- tests/lib/grouping.test.ts | 8 ++++++-- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/app/lib/grouping.ts b/src/app/lib/grouping.ts index f0f49cf6..3e771a8e 100644 --- a/src/app/lib/grouping.ts +++ b/src/app/lib/grouping.ts @@ -77,7 +77,8 @@ export function orderRepoGroups( * Three-tier involvement check for scope filtering. * Shared by IssuesTab and PullRequestsTab — keep both call sites in sync. * - * Tier 1: surfacedBy annotation present → check if user is included + * Tier 1: surfacedBy annotation present → pass (item was found via an involves: + * search for the main user or a tracked user — always relevant) * Tier 2: monitored repo (no surfacedBy) → field-based fallback (author/assignee) * Pass reviewerLogins for PRs (only when enriched — unenriched PRs have []) * Tier 3: non-monitored, no surfacedBy → pass (fetched via involves:{user}) @@ -89,7 +90,7 @@ export function isUserInvolved( reviewerLogins?: string[], ): boolean { const surfacedBy = item.surfacedBy ?? []; - if (surfacedBy.length > 0) return surfacedBy.includes(login); + if (surfacedBy.length > 0) return true; if (monitoredRepos.has(item.repoFullName)) { return item.userLogin.toLowerCase() === login || item.assigneeLogins.some(a => a.toLowerCase() === login) || diff --git a/tests/components/dashboard/IssuesTab.test.tsx b/tests/components/dashboard/IssuesTab.test.tsx index c10acd25..f962243a 100644 --- a/tests/components/dashboard/IssuesTab.test.tsx +++ b/tests/components/dashboard/IssuesTab.test.tsx @@ -322,10 +322,10 @@ describe("IssuesTab — monitored repos filter bypass", () => { // ── IssuesTab — scope filter ─────────────────────────────────────────────────── describe("IssuesTab — scope filter", () => { - it("default scope shows only items involving the user (surfacedBy includes userLogin)", () => { + it("default scope shows items surfaced by tracked users (surfacedBy present)", () => { const issues = [ makeIssue({ id: 1, title: "My issue", repoFullName: "org/repo", surfacedBy: ["me"] }), - makeIssue({ id: 2, title: "Community issue", repoFullName: "org/repo", surfacedBy: ["other"] }), + makeIssue({ id: 2, title: "Tracked User issue", repoFullName: "org/repo", surfacedBy: ["other"] }), ]; setAllExpanded("issues", ["org/repo"], true); @@ -339,7 +339,7 @@ describe("IssuesTab — scope filter", () => { )); screen.getByText("My issue"); - expect(screen.queryByText("Community issue")).toBeNull(); + screen.getByText("Tracked User issue"); }); it("scope 'all' shows all items including community items", () => { @@ -437,9 +437,9 @@ describe("IssuesTab — left border accent in 'all' scope", () => { expect(listitem?.className).toContain("border-l-primary"); }); - it("does not add border-l-2 to community items in 'all' scope", () => { + it("does not add border-l-2 to untracked monitored repo items in 'all' scope", () => { const issues = [ - makeIssue({ id: 1, title: "Community issue", repoFullName: "org/monitored", surfacedBy: ["other"], userLogin: "other", assigneeLogins: [] }), + makeIssue({ id: 1, title: "Community issue", repoFullName: "org/monitored", userLogin: "other", assigneeLogins: [] }), ]; setTabFilter("issues", "scope", "all"); setAllExpanded("issues", ["org/monitored"], true); diff --git a/tests/components/dashboard/PullRequestsTab.test.tsx b/tests/components/dashboard/PullRequestsTab.test.tsx index 4ef55da8..3e1be912 100644 --- a/tests/components/dashboard/PullRequestsTab.test.tsx +++ b/tests/components/dashboard/PullRequestsTab.test.tsx @@ -272,10 +272,10 @@ describe("PullRequestsTab — monitored repos filter bypass", () => { // ── PullRequestsTab — scope filter ──────────────────────────────────────────── describe("PullRequestsTab — scope filter", () => { - it("default scope shows only items involving the user (surfacedBy includes userLogin)", () => { + it("default scope shows items surfaced by tracked users (surfacedBy present)", () => { const prs = [ makePullRequest({ id: 1, title: "My PR", repoFullName: "org/repo", surfacedBy: ["me"] }), - makePullRequest({ id: 2, title: "Community PR", repoFullName: "org/repo", surfacedBy: ["other"] }), + makePullRequest({ id: 2, title: "Tracked User PR", repoFullName: "org/repo", surfacedBy: ["other"] }), ]; setAllExpanded("pullRequests", ["org/repo"], true); @@ -289,7 +289,7 @@ describe("PullRequestsTab — scope filter", () => { )); screen.getByText("My PR"); - expect(screen.queryByText("Community PR")).toBeNull(); + screen.getByText("Tracked User PR"); }); it("scope 'all' shows all PRs including community items", () => { @@ -387,9 +387,9 @@ describe("PullRequestsTab — left border accent in 'all' scope", () => { expect(listitem?.className).toContain("border-l-primary"); }); - it("does not add border-l-primary to community PRs in 'all' scope", () => { + it("does not add border-l-primary to untracked monitored repo PRs in 'all' scope", () => { const prs = [ - makePullRequest({ id: 1, title: "Community PR", repoFullName: "org/monitored", surfacedBy: ["other"], userLogin: "other", assigneeLogins: [], reviewerLogins: [] }), + makePullRequest({ id: 1, title: "Community PR", repoFullName: "org/monitored", userLogin: "other", assigneeLogins: [], reviewerLogins: [] }), ]; setTabFilter("pullRequests", "scope", "all"); setAllExpanded("pullRequests", ["org/monitored"], true); diff --git a/tests/lib/grouping.test.ts b/tests/lib/grouping.test.ts index 08da07a7..9afbb611 100644 --- a/tests/lib/grouping.test.ts +++ b/tests/lib/grouping.test.ts @@ -67,8 +67,12 @@ describe("isUserInvolved", () => { expect(isUserInvolved({ ...base, surfacedBy: ["me"] }, "me", monitored)).toBe(true); }); - it("returns false when surfacedBy excludes user", () => { - expect(isUserInvolved({ ...base, surfacedBy: ["other"] }, "me", monitored)).toBe(false); + it("returns true when surfacedBy contains only a tracked user (not the main user)", () => { + expect(isUserInvolved({ ...base, surfacedBy: ["tracked-bot[bot]"] }, "me", monitored)).toBe(true); + }); + + it("returns true when surfacedBy contains multiple tracked users but not the main user", () => { + expect(isUserInvolved({ ...base, surfacedBy: ["bot1[bot]", "bot2"] }, "me", monitored)).toBe(true); }); it("returns true for non-monitored item with no surfacedBy (fetched via involves:{user})", () => { From 9ff0c4d834afa86401e57c18cb840d49d5b3f810 Mon Sep 17 00:00:00 2001 From: testvalue Date: Wed, 8 Apr 2026 21:47:15 -0400 Subject: [PATCH 2/7] docs: updates scope filter description to reflect tracked user behavior --- docs/USER_GUIDE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/USER_GUIDE.md b/docs/USER_GUIDE.md index 6f1c80d4..e7fa1861 100644 --- a/docs/USER_GUIDE.md +++ b/docs/USER_GUIDE.md @@ -110,7 +110,7 @@ When a group is collapsed, a brief preview of any status change detected by the The **Scope** filter chip appears on the Issues and Pull Requests tabs when you have tracked users configured or monitor-all repos enabled. It has two options: -- **Involves me** (default) — shows only items where you (the signed-in user) are the author, assignee, reviewer, or mentioned. For monitored repos, all activity in that repo is always shown regardless of scope. +- **Involves me** (default) — shows items where you or any of your tracked users are involved (author, assignee, reviewer, or mentioned). For monitored repos, all activity in that repo is always shown regardless of scope. - **All activity** — shows every open item across your selected repos. Items that involve you are highlighted with a blue left border. The scope filter is hidden (and always set to "Involves me") when you have no tracked users and no monitor-all repos, because in that configuration all fetched data already involves you. @@ -447,7 +447,7 @@ These are UI preferences that persist across sessions but are not included in th **Items I expect to see are not showing up.** -- Check that the Scope filter is set correctly. "Involves me" hides items where you have no direct involvement. Switch to "All activity" to see everything. +- Check that the Scope filter is set correctly. "Involves me" shows items involving you or your tracked users; items from monitored repos where nobody you track is involved are hidden. Switch to "All activity" to see everything. - Verify the repo is in your selected repo list (Settings > Repositories). - Check if the item was accidentally ignored (toolbar Ignored badge). - If you recently added the repo, wait for the next full refresh or click the manual refresh button. From a65260b241f2ba345867c29afabbc77fcd4b6152 Mon Sep 17 00:00:00 2001 From: testvalue Date: Wed, 8 Apr 2026 21:56:38 -0400 Subject: [PATCH 3/7] test: adds tier-ordering and border accent tests for tracked user items --- tests/components/dashboard/IssuesTab.test.tsx | 19 +++++++++++++++++++ .../dashboard/PullRequestsTab.test.tsx | 19 +++++++++++++++++++ tests/lib/grouping.test.ts | 6 +++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/tests/components/dashboard/IssuesTab.test.tsx b/tests/components/dashboard/IssuesTab.test.tsx index f962243a..310cfca3 100644 --- a/tests/components/dashboard/IssuesTab.test.tsx +++ b/tests/components/dashboard/IssuesTab.test.tsx @@ -456,6 +456,25 @@ describe("IssuesTab — left border accent in 'all' scope", () => { expect(listitem?.className).not.toContain("border-l-primary"); }); + it("adds border-l-primary to tracked user issue in monitored repo in 'all' scope", () => { + const issues = [ + makeIssue({ id: 1, title: "Bot issue", repoFullName: "org/monitored", surfacedBy: ["tracked-bot[bot]"] }), + ]; + setTabFilter("issues", "scope", "all"); + setAllExpanded("issues", ["org/monitored"], true); + + const { container } = render(() => ( + + )); + + const listitem = container.querySelector('[role="listitem"]'); + expect(listitem?.className).toContain("border-l-primary"); + }); + it("does not add border-l-2 in default 'involves_me' scope", () => { const issues = [ makeIssue({ id: 1, title: "My issue", repoFullName: "org/repo", surfacedBy: ["me"] }), diff --git a/tests/components/dashboard/PullRequestsTab.test.tsx b/tests/components/dashboard/PullRequestsTab.test.tsx index 3e1be912..7007fe9c 100644 --- a/tests/components/dashboard/PullRequestsTab.test.tsx +++ b/tests/components/dashboard/PullRequestsTab.test.tsx @@ -406,6 +406,25 @@ describe("PullRequestsTab — left border accent in 'all' scope", () => { expect(listitem?.className).not.toContain("border-l-primary"); }); + it("adds border-l-primary to tracked user PR in monitored repo in 'all' scope", () => { + const prs = [ + makePullRequest({ id: 1, title: "Bot PR", repoFullName: "org/monitored", surfacedBy: ["tracked-bot[bot]"] }), + ]; + setTabFilter("pullRequests", "scope", "all"); + setAllExpanded("pullRequests", ["org/monitored"], true); + + const { container } = render(() => ( + + )); + + const listitem = container.querySelector('[role="listitem"]'); + expect(listitem?.className).toContain("border-l-primary"); + }); + it("does not add border-l-primary in default 'involves_me' scope", () => { const prs = [ makePullRequest({ id: 1, title: "My PR", repoFullName: "org/repo", surfacedBy: ["me"] }), diff --git a/tests/lib/grouping.test.ts b/tests/lib/grouping.test.ts index 9afbb611..79165c94 100644 --- a/tests/lib/grouping.test.ts +++ b/tests/lib/grouping.test.ts @@ -63,7 +63,7 @@ describe("isUserInvolved", () => { const base = { repoFullName: "org/repo", userLogin: "author", assigneeLogins: [] as string[] }; const monitored = new Set(["org/monitored"]); - it("returns true when surfacedBy includes user", () => { + it("returns true when surfacedBy is non-empty (main user)", () => { expect(isUserInvolved({ ...base, surfacedBy: ["me"] }, "me", monitored)).toBe(true); }); @@ -75,6 +75,10 @@ describe("isUserInvolved", () => { expect(isUserInvolved({ ...base, surfacedBy: ["bot1[bot]", "bot2"] }, "me", monitored)).toBe(true); }); + it("returns true for monitored repo item with surfacedBy (tier 1 before tier 2)", () => { + expect(isUserInvolved({ ...base, repoFullName: "org/monitored", surfacedBy: ["tracked-bot[bot]"] }, "me", monitored)).toBe(true); + }); + it("returns true for non-monitored item with no surfacedBy (fetched via involves:{user})", () => { expect(isUserInvolved(base, "me", monitored)).toBe(true); }); From 57c4b1d0820023cbaea85059a803edabe5b0f4ea Mon Sep 17 00:00:00 2001 From: testvalue Date: Thu, 9 Apr 2026 08:36:27 -0400 Subject: [PATCH 4/7] docs: fixes border accent and monitored repo scope filter wording --- docs/USER_GUIDE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/USER_GUIDE.md b/docs/USER_GUIDE.md index e7fa1861..30526874 100644 --- a/docs/USER_GUIDE.md +++ b/docs/USER_GUIDE.md @@ -111,7 +111,7 @@ When a group is collapsed, a brief preview of any status change detected by the The **Scope** filter chip appears on the Issues and Pull Requests tabs when you have tracked users configured or monitor-all repos enabled. It has two options: - **Involves me** (default) — shows items where you or any of your tracked users are involved (author, assignee, reviewer, or mentioned). For monitored repos, all activity in that repo is always shown regardless of scope. -- **All activity** — shows every open item across your selected repos. Items that involve you are highlighted with a blue left border. +- **All activity** — shows every open item across your selected repos. Items involving you or your tracked users are highlighted with a blue left border. The scope filter is hidden (and always set to "Involves me") when you have no tracked users and no monitor-all repos, because in that configuration all fetched data already involves you. @@ -447,7 +447,7 @@ These are UI preferences that persist across sessions but are not included in th **Items I expect to see are not showing up.** -- Check that the Scope filter is set correctly. "Involves me" shows items involving you or your tracked users; items from monitored repos where nobody you track is involved are hidden. Switch to "All activity" to see everything. +- Check that the Scope filter is set correctly. "Involves me" shows items involving you or your tracked users; items from monitored repos where you are not directly involved (author, assignee, or reviewer) are hidden. Switch to "All activity" to see everything. - Verify the repo is in your selected repo list (Settings > Repositories). - Check if the item was accidentally ignored (toolbar Ignored badge). - If you recently added the repo, wait for the next full refresh or click the manual refresh button. From 23bb78c69c63559bd844b15029e5b1fddd39773a Mon Sep 17 00:00:00 2001 From: testvalue Date: Thu, 9 Apr 2026 08:40:12 -0400 Subject: [PATCH 5/7] docs: fixes incorrect monitored repo claim in scope filter description --- docs/USER_GUIDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/USER_GUIDE.md b/docs/USER_GUIDE.md index 30526874..7fafe675 100644 --- a/docs/USER_GUIDE.md +++ b/docs/USER_GUIDE.md @@ -110,7 +110,7 @@ When a group is collapsed, a brief preview of any status change detected by the The **Scope** filter chip appears on the Issues and Pull Requests tabs when you have tracked users configured or monitor-all repos enabled. It has two options: -- **Involves me** (default) — shows items where you or any of your tracked users are involved (author, assignee, reviewer, or mentioned). For monitored repos, all activity in that repo is always shown regardless of scope. +- **Involves me** (default) — shows items where you or any of your tracked users are involved (author, assignee, reviewer, or mentioned). For monitored repos, only items where you are the author, assignee, or reviewer are shown. - **All activity** — shows every open item across your selected repos. Items involving you or your tracked users are highlighted with a blue left border. The scope filter is hidden (and always set to "Involves me") when you have no tracked users and no monitor-all repos, because in that configuration all fetched data already involves you. From f0159bc27c65768a013f953c13156dcf94d53b49 Mon Sep 17 00:00:00 2001 From: testvalue Date: Thu, 9 Apr 2026 08:45:00 -0400 Subject: [PATCH 6/7] docs: fixes duplicate monitored repo claim in monitor-all section --- docs/USER_GUIDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/USER_GUIDE.md b/docs/USER_GUIDE.md index 7fafe675..7d969eec 100644 --- a/docs/USER_GUIDE.md +++ b/docs/USER_GUIDE.md @@ -251,7 +251,7 @@ Normally, the dashboard shows only issues and PRs that involve you (or a tracked **How to enable:** In **Settings > Repositories**, expand the repo panel. Each repo has an eye icon toggle. Enabling it adds the repo to the monitored list (maximum 10 monitored repos). -**Effect on display:** Repo groups for monitored repos show a **Monitoring all** badge in their header. Items from monitored repos are always visible even when the Scope filter is set to "Involves me", and they bypass the User filter. +**Effect on display:** Repo groups for monitored repos show a **Monitoring all** badge in their header. In "Involves me" scope, monitored repo items are shown when you are the author, assignee, or reviewer; switch to "All activity" to see all monitored repo items. Monitored repo items bypass the User filter. Upstream repos cannot be monitored (only selected repos are eligible). From 0c193d2cb5a7cc9313406d3b75225ce3d1a76998 Mon Sep 17 00:00:00 2001 From: testvalue Date: Thu, 9 Apr 2026 09:38:14 -0400 Subject: [PATCH 7/7] docs: removes theme-specific color from border accent description --- docs/USER_GUIDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/USER_GUIDE.md b/docs/USER_GUIDE.md index 7d969eec..949b4ea6 100644 --- a/docs/USER_GUIDE.md +++ b/docs/USER_GUIDE.md @@ -111,7 +111,7 @@ When a group is collapsed, a brief preview of any status change detected by the The **Scope** filter chip appears on the Issues and Pull Requests tabs when you have tracked users configured or monitor-all repos enabled. It has two options: - **Involves me** (default) — shows items where you or any of your tracked users are involved (author, assignee, reviewer, or mentioned). For monitored repos, only items where you are the author, assignee, or reviewer are shown. -- **All activity** — shows every open item across your selected repos. Items involving you or your tracked users are highlighted with a blue left border. +- **All activity** — shows every open item across your selected repos. Items involving you or your tracked users are highlighted with a colored left border. The scope filter is hidden (and always set to "Involves me") when you have no tracked users and no monitor-all repos, because in that configuration all fetched data already involves you.