feat(Sheets): open in new tab if not sheets - #3615
Conversation
📊 Code Quality Score: 6/100
Was this score accurate? 👍 Yes · 👎 No Scored by GitVelocity · How are scores calculated? |
There was a problem hiding this comment.
Pull request overview
This PR updates link navigation behavior within the Sheets UI so that links to other sheets (and to the Voices module) navigate in the current tab, while other links open in a new tab—aligning Sheets with the intended cross-module navigation UX.
Changes:
- Added URL parsing and routing logic in Sheets click-handling to decide between same-tab navigation vs. opening a new tab.
- Passed
handleClickinto the non-editorSheetContentpath so the same link behavior applies in reader mode.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| try { | ||
| url = new URL(fullUrl, window.location.href); // second arg resolves relative paths against the current page | ||
| } catch (err) { | ||
| Sefaria.util.openInNewTab(fullUrl); | ||
| return; |
|
(Claude writing on Daniel's behalf — these review comments were AI-generated and Daniel reviewed them before posting. Posted as one comment because a pending draft review blocks inline comments.) The approach looks sound and the fallbacks (try/catch around 1. A link to const isSheetLink = Sefaria.isSefariaURL(url) && /^\/sheets\/\d+/.test(url.pathname);2. Modifier clicks are overridden (line 65) Because if (e.metaKey || e.ctrlKey || e.shiftKey) { return; }(The old code hijacked everything into a new tab too, but it never forced a same-tab navigation, so this branch makes it newly noticeable.) 3. The Voices hostname comparison is interface-language-scoped (line 62) Two edge cases, since
Comparing against |
dcschreiber
left a comment
There was a problem hiding this comment.
These comments are small, but Claude should have left one or two comments that should actually be fixed.
| try { | ||
| url = new URL(fullUrl, window.location.href); // second arg resolves relative paths against the current page | ||
| } catch (err) { | ||
| Sefaria.util.openInNewTab(fullUrl); |
There was a problem hiding this comment.
I think your indentation is off.
Great points, thanks. I addressed each of these three issues. |
dcschreiber
left a comment
There was a problem hiding this comment.
(Claude writing on Daniel's behalf — these review comments were AI-generated and Daniel reviewed them before posting.)
Re-reviewed. The three earlier points are properly fixed: the hostname check is real now, both languages' Voices domains match, and splitting getDomainHostnames into three getters is a clean way to get there. Both old callers were updated, so nothing else reads the old helper.
One thing I want to flag as checked rather than as a problem: this PR newly wires handleClick into reader mode, so a link inside sheet content no longer opens a new panel and does a full page navigation instead. I went looking for the reasoning and found it in sc-46102 — the stacking, uncloseable panels are the bug being fixed, and Mickey's acceptance criteria ask for exactly this. So no change wanted there.
Two small items inline, one of which I would like changed before merge.
| const allModuleUrls = Object.values(Sefaria.domainModules || {}).flatMap(langModules => Object.values(langModules || {})); | ||
| return Sefaria._hostnamesFromModuleURLs(allModuleUrls); | ||
| }, | ||
| getCurrentModuleHostnames: function(module) { |
There was a problem hiding this comment.
(Claude writing on Daniel's behalf)
The name reads as the opposite of what the function does. getCurrentLangHostnames returns the current language, so getCurrentModuleHostnames sounds like it returns the current module — but it takes a module as an argument and deliberately spans every language.
getModuleHostnames(module) would say it plainly, and the contrast with getCurrentLangHostnames then does real work: one is scoped to what the reader is using, the other is not scoped at all.
| const fullUrl = Sefaria.util.fullURL(href, moduleTarget); // Ignores moduleTarget if it's null | ||
| if (!target) { return; } | ||
| // Cmd/ctrl/shift-click is the user explicitly asking for a new tab or window -- let the browser do its thing. | ||
| if (e.metaKey || e.ctrlKey || e.shiftKey) { return; } |
There was a problem hiding this comment.
(Claude writing on Daniel's behalf)
No change needed, just so you know it is belt-and-braces: ReaderApp already installs handleInAppClickWithModifiers as a capture-phase listener on document, and it calls stopImmediatePropagation() on any modifier click. Since document sits above React's root container, that fires first and the event never reaches this handler.
So this line is unreachable for Sheet as rendered from ReaderPanel. Harmless, and arguably worth keeping in case the component is ever mounted outside ReaderApp. Flagging it only so nobody later reads it as the thing that makes cmd-click work.
📊 Code Quality Score: 16/100
Was this score accurate? 👍 Yes · 👎 No Scored by GitVelocity · How are scores calculated? |
Description
Links in sheets will open in the current window if they are links to other sheets or to voices. Otherwise we open them in a new tab.