Skip to content

fix(inbox): keep detail back link pointing at the tab you came from#2867

Open
rafaeelaudibert wants to merge 1 commit into
mainfrom
posthog-code/inbox-back-link-remembers-origin
Open

fix(inbox): keep detail back link pointing at the tab you came from#2867
rafaeelaudibert wants to merge 1 commit into
mainfrom
posthog-code/inbox-back-link-remembers-origin

Conversation

@rafaeelaudibert

Copy link
Copy Markdown
Member

Problem

After archiving a report while viewing it, the back button flipped from "Back to reports" to "Back to archive". The usual flow is: open Reports → open a report → maybe archive → go back. So you'd expect to land back in Reports, not Archive.

This wasn't a label being swapped — the architecture flips it implicitly. Archiving sets the report's status to suppressed, and InboxReportDetailGate redirects (replace: true) from /code/inbox/reports/$reportId to /code/inbox/dismissed/$reportId. That route mounts DismissedReportDetail, which hard-codes backTo="/code/inbox/dismissed" / "Back to archive". So the back link followed the report's new state instead of the path you took in.

The redirect is load-bearing (it keeps archived reports off the triage view), so it's kept — but it now remembers where you came from.

Change

  • New useInboxBackTarget hook — owns the InboxListRoute / InboxBackTarget types, augments TanStack Router's HistoryState with an inboxBackOrigin field, and resolves the back link from history state (validating the untyped state at the boundary), with a fallback.
  • InboxReportDetailGate — stamps the origin ({ to, label }, always a pipeline route at that point) into navigation state on the to-Archive redirect. Gains optional display-only backLinkTo/backLinkLabel; backTo stays the route identity that drives the redirect and engagement tracking.
  • DismissedReportDetail — reads the recorded origin and uses it for both the missing-shell link and the header link; defaults to "Back to archive".
  • InboxDetailFramebackTo widened to the shared InboxListRoute union.
  • Unit test for the history-state validator.

Behavior

Path in Back link
Reports → open → archive Back to reports → Reports list
Pulls → open → archive Back to pull requests
Runs → open → archive Back to runs
Archive tab / deep link / refresh Back to archive (fallback)

Verification

⚠️ I could not run pnpm typecheck/tests locally — the sandbox's network is throttled to single-digit KiB/s and pnpm install gets OOM-killed before @tanstack/react-router and vitest are installed. Verified by manual review. Two things worth a CI/reviewer eye:

  • The declare module "@tanstack/react-router" { interface HistoryState } augmentation (documented TanStack v1 pattern; mirrors the existing Register augmentation in router.ts).
  • useLocation({ select }) typing.

🤖 Generated with Claude Code

Archiving a report while viewing it flipped the back link from "Back to
reports" to "Back to archive": the gate redirects the now-suppressed report
to /code/inbox/dismissed/$reportId, whose detail view hard-codes the Archive
back target. The link followed the report's new state instead of the path the
user took in.

Carry the origin tab through the status↔route redirect in navigation state so
the Archive detail's back link returns to Reports/Pulls/Runs (whichever the
user came from), falling back to "Back to archive" only when arriving directly
(deep link, Archive-tab click, or a refresh that drops history state). The
redirect itself is unchanged, so archived reports still stay off the triage
view.

- New useInboxBackTarget hook: owns the back-target types, augments
  TanStack Router HistoryState with inboxBackOrigin, and validates the untyped
  state at the boundary.
- InboxReportDetailGate stamps the origin on the to-Archive redirect and gains
  display-only backLinkTo/backLinkLabel overrides; backTo stays the route
  identity driving the redirect and engagement tracking.
- DismissedReportDetail resolves and uses the recorded origin.
- Widen InboxDetailFrame backTo to the shared InboxListRoute union.
- Unit-test the history-state validator.

Generated-By: PostHog Code
Task-Id: 5e171745-ab49-45aa-82e7-c7b7e3ec7584
@github-actions

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit 4ddf820.

@rafaeelaudibert rafaeelaudibert requested a review from a team June 23, 2026 16:24
@greptile-apps

greptile-apps Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "fix(inbox): keep detail back link pointi..." | Re-trigger Greptile

Comment on lines +30 to +35
const INBOX_LIST_ROUTES = new Set<InboxListRoute>([
"/code/inbox/pulls",
"/code/inbox/reports",
"/code/inbox/runs",
"/code/inbox/dismissed",
]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The four route strings are listed twice: once to build the InboxListRoute union and once to populate INBOX_LIST_ROUTES. Adding a fifth inbox list route requires touching both places. Using as const on a single array lets InboxListRoute be derived from it, keeping a single source of truth.

Suggested change
const INBOX_LIST_ROUTES = new Set<InboxListRoute>([
"/code/inbox/pulls",
"/code/inbox/reports",
"/code/inbox/runs",
"/code/inbox/dismissed",
]);
const INBOX_LIST_ROUTE_VALUES = [
"/code/inbox/pulls",
"/code/inbox/reports",
"/code/inbox/runs",
"/code/inbox/dismissed",
] as const;
export type InboxListRoute = (typeof INBOX_LIST_ROUTE_VALUES)[number];
const INBOX_LIST_ROUTES = new Set<InboxListRoute>(INBOX_LIST_ROUTE_VALUES);

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant