Context-sensitive preview for Sub/Lnk tabs#55
Merged
textfuel merged 9 commits intotextfuel:mainfrom Apr 18, 2026
Merged
Conversation
A new jiratest sub-package provides a fake that implements the Jira client interface. Every method fails the test on an unexpected call, so each test opts in explicitly to the traffic it expects. The first consumer locks in the current refresh behavior: pressing the refresh action fetches the currently selected issue. This opens a path to fast, precise tests for keyboard-driven actions, which previously only surfaced in slow E2E runs. Upcoming preview work needs a safety net at this level.
Refresh and the detail view now follow a single preview target instead of peeking at the list cursor or the detail's own state. This keeps the right-hand views coherent when the preview diverges from the list selection. Previewing a sub-issue is the motivating case.
Switching the info panel to the Subtasks or Links tab previews the tab's first entry right away, and moving the cursor through the list updates the preview as you go. The Fields tab stays quiet: navigation there never changes the preview target, and empty lists dispatch nothing.
Preview requests debounce for 150 ms before hitting the network, so scrolling through sub-tasks or links does not trigger a fetch per row. A monotonic request counter rides along with each fetch; any response whose counter is stale by the time it arrives is dropped, so a slow answer for an earlier row cannot overwrite a later selection. Bubbletea has no native command cancellation, so the counter acts as the cancel substitute. Cache hits short-circuit the debounce entirely and update the detail view synchronously, so revisiting an already-loaded issue feels instant. Cache misses land on the debounced path. Non-preview paths (refresh, main-list selection on cache miss, comment updates) keep the existing direct-fetch behavior.
Deletes the issueCache entry for the previewed key synchronously in the ActRefresh handler, before the fetch cmd is returned. Any cache read between the keypress and the fetch response now sees a miss instead of stale data. Adds TestActRefresh_InvalidatesCacheBeforeFetch to pin the invariant.
When the user presses Esc (ActFocusLeft) while the InfoPanel has focus with the Sub or Lnk tab active, previewKey now snaps back to the current list selection via previewSelectedIssue(). The same reset fires when switching the InfoPanel tab to Fields via PrevTab or NextTab. Empty Sub/Lnk lists never dispatch PreviewRequestMsg (confirmed by test; no production change needed). Added package-level subKey1 constant and migrated all "SUB-1" literals in pkg/tui tests to use it (goconst lint fix).
Previewing a sub-issue now only updates the right-side detail view. The info panel keeps its tab and cursor on the main list issue, as the user's navigation context should. Before, a detail response for a previewed sub-issue overwrote the info panel. Because the panel's SetIssue resets cursor and active tab when the key changes, the sub/link tab snapped back to fields and the cursor jumped to the top, making the whole pane feel like it was flying away from under the user. The detail view and info panel now have independent guards. The detail view follows previewKey, which is the source of truth for what is shown on the right. The info panel follows the list selection, matching user intent for navigation context.
Selecting a task in the list, and switching back into the list view, fires a single JQL batch for the task's parent, subtasks and linked issues. By the time the user moves into the Sub or Lnk tab, those issues are already in the cache and the preview renders without a network round-trip. The parent joins the batch so future drill-up navigation benefits from the same warm cache.
Edit, copy URL, open in browser, transition, priority, assignee, duplicate, create branch, and custom commands all now act on the issue currently shown in the detail view. Previously they followed the list cursor, which surprised the user after drilling into a sub or linked issue via the info panel. A new currentIssue helper resolves to the cached previewed issue when one is active, falling back to the list selection otherwise. The info panel's Fields tab still edits the main list issue, because that is what the Fields tab shows.
60a222a to
22cf077
Compare
textfuel
approved these changes
Apr 18, 2026
Owner
textfuel
left a comment
There was a problem hiding this comment.
Great work!
The debounce + epoch approach is a clean solution
Thanks for improving the navigation experience 👍
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #54
Moving the cursor to an issue in the Subtasks or Links tab now
previews that issue in the main pane, and contextual actions
(refresh, edit, transition, open in browser, comments, custom
commands) act on it. Entering a Sub/Lnk tab previews its first
entry immediately; leaving the tab resets the preview back to
the main issue.
The effect: the Sub/Lnk tab behaves like any other selection
pane in a lazy*-style layout. You can browse related issues
without losing your place, and key actions always target the
issue the cursor currently points to.
Implementation notes
A new
jiratest.FakeClientprovides handler-level testcoverage. Writing tests at this level surfaced a pre-existing
bug where refresh read stale data from the cache before
dispatching the fetch; it is also fixed in this branch.
App.previewKeyholds the key of the issue currently shown inthe right-hand views. Selection, cursor moves in the info
panel and tab-leave paths all write it; the detail view and
action handlers read it.
Preview fetches debounce for 150 ms and carry a monotonic
counter. Responses whose counter is stale by the time they
arrive are dropped, so a slow response for an earlier
selection cannot overwrite a later one. Bubbletea has no
native
tea.Cmdcancellation, which is why the counter isneeded. Cache hits bypass the debounce and update the detail
view synchronously.
On task selection, a single JQL batch warms the cache for the
task's parent, subtasks and linked issues, so entering a Sub
or Lnk tab usually lands on a cache hit.
To test:
SuborLnktab: the main pane previews the highlighteditem. The info panel stays put.
target the previewed issue.