fix(inbox): keep detail back link pointing at the tab you came from - #2867
Conversation
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
|
React Doctor found no issues in the changed files. 🎉 Reviewed by React Doctor for commit |
|
Reviews (1): Last reviewed commit: "fix(inbox): keep detail back link pointi..." | Re-trigger Greptile |
| const INBOX_LIST_ROUTES = new Set<InboxListRoute>([ | ||
| "/code/inbox/pulls", | ||
| "/code/inbox/reports", | ||
| "/code/inbox/runs", | ||
| "/code/inbox/dismissed", | ||
| ]); |
There was a problem hiding this comment.
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.
| 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!
4ddf820 to
f2ba5c3
Compare
Address review feedback: the four inbox list routes were listed twice (once for the InboxListRoute union, once for the runtime Set). Derive the type from a single as-const array so a new route only needs one edit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
f2ba5c3 to
c7dd774
Compare
New commits pushed (delta classified non_linear_history) — stamphog approval dismissed; re-review running automatically.
There was a problem hiding this comment.
Focused inbox navigation fix entirely within @posthog/ui with proper defensive validation of untrusted history state, tests for edge cases, and no architecture violations. The greptile bot's outdated inline suggestion is already addressed in the current code.

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, andInboxReportDetailGateredirects (replace: true) from/code/inbox/reports/$reportIdto/code/inbox/dismissed/$reportId. That route mountsDismissedReportDetail, which hard-codesbackTo="/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
useInboxBackTargethook — owns theInboxListRoute/InboxBackTargettypes, augments TanStack Router'sHistoryStatewith aninboxBackOriginfield, 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 navigationstateon the to-Archive redirect. Gains optional display-onlybackLinkTo/backLinkLabel;backTostays 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".InboxDetailFrame—backTowidened to the sharedInboxListRouteunion.Behavior
Verification
pnpm typecheck/tests locally — the sandbox's network is throttled to single-digit KiB/s andpnpm installgets OOM-killed before@tanstack/react-routerandvitestare installed. Verified by manual review. Two things worth a CI/reviewer eye:declare module "@tanstack/react-router" { interface HistoryState }augmentation (documented TanStack v1 pattern; mirrors the existingRegisteraugmentation inrouter.ts).useLocation({ select })typing.🤖 Generated with Claude Code