Skip to content

feat(web): jump from Timeline to Source tab on chunk/file click#676

Merged
memtomem merged 1 commit intomainfrom
feat/web-timeline-source-jump
May 2, 2026
Merged

feat(web): jump from Timeline to Source tab on chunk/file click#676
memtomem merged 1 commit intomainfrom
feat/web-timeline-source-jump

Conversation

@memtomem
Copy link
Copy Markdown
Owner

@memtomem memtomem commented May 2, 2026

Summary

Timeline tab's chunk/file clicks now jump to the Source tab instead of
opening Search's detail panel. Search's left-side results pane stays empty
unless the user actually ran a search, so jumping there from Timeline left
a populated detail floating next to a "Enter a query to search" placeholder
— readable as orphaned. Source already has Copy / Edit / Delete on every
chunk, and the cross-tab navigation plumbing landed in #673 + #674
(_navigateToSource(path), vendor sub-tab follow-through, pending-activate
handoff). This PR reuses it from Timeline.

  • _navigateToSource gains an optional chunkId. STATE.pendingActivate ChunkId is consumed in browseSource after the chunk list lands —
    scrolls the matching .chunk-card[data-chunk-id="…"] into view, expands
    it if collapsible, pulses .tl-target-flash for ~1.4s. Empty chunkId =
    source-level jump only (no flash) — keeps the Home-recent and
    command-palette callers behaving exactly as before.
  • Timeline call sites:
    • Chunks view "Open" button → _navigateToSource(c.source_file, c.id).
      Label moves from hard-coded "Open" to timeline.open_in_source (en
      "Open in source" / ko "소스에서 보기").
    • Files view file header gets a small ghost-style .tl-file-open- source button on the right edge — stopPropagation'd so the row's
      existing expand/collapse still works for header non-button clicks.
      No chunkId (file headers don't carry a single canonical chunk).
    • Files view per-chunk row click → _navigateToSource(c.source_file, c.id).
  • showDetailFromChunk is keptapp.js:4834 still uses it for
    the Source-chunks side panel inside Search detail (intra-detail "jump to
    a sibling chunk in the same source"), which is a separate flow. Timeline
    call sites are the only ones moving.

Cache-bust per feedback_static_asset_cache_bust.mdstyle.css v=72→73,
app.js v=87→88, timeline.js v=1→2 (all three have body changes).

Test plan

  • uv run pytest packages/memtomem/tests/test_i18n.py -q — 12 passed
    (locale parity holds: new key in both en + ko).
  • uv run ruff check + ruff format --check clean.
  • Manual via Playwright MCP against mm web:
    • Chunks-view "Open in source" → tab=sources, exactly one
      .chunk-card.tl-target-flash on the matching data-chunk-id, first
      flash observed ~205ms after click then auto-removed at 1.4s.
    • Files-view header button → tab=sources, no chunk flash (intended).
    • Files-view header non-button click → expand/collapse only, tab
      unchanged. stopPropagation on the new button confirmed.
    • KO label "소스에서 보기" rendered on first paint via data-i18n +
      langchange wiring (already covered since feat(web): Index tab — surface hard-to-discover behaviors (static, 7-item bundle) (#579) #587).
  • Cross-vendor smoke (claude / openai sources from Timeline) — same
    _navigateToSource path used by fix(web): vendor sub-tab follow-through on cross-tab source navigation #673; verified above on user-vendor
    sources, confidence-by-symmetry on the other two but worth a manual
    eyeball post-merge.
  • Cold-load (Source tab never visited in this session) — same
    pendingActivate handoff path proved out for the Home-recent flow in
    fix(web): activate the clicked source on Home recent navigation #674; mechanically identical here.

🤖 Generated with Claude Code

Timeline's "Open" button (chunks view) and chunk-row clicks (files view)
went to ``showDetailFromChunk`` → Search tab's detail panel. But the
user landing on Search after clicking a Timeline chunk sees an empty
left-side results pane ("Enter a query to search") next to a populated
detail on the right — the panel reads as orphaned. The Source tab
already exposes Copy / Edit / Delete on every chunk (the same
operations Search detail offers), and the two preceding PRs (#673
vendor sub-tab follow-through, #674 Home-recent activation) built the
``_navigateToSource(path)`` plumbing — pending-activate handoff plus
eager vendor resolve — for exactly this kind of cross-tab jump.

Reuses that plumbing from Timeline:

  - ``_navigateToSource`` gains an optional ``chunkId`` argument and
    sets ``STATE.pendingActivateChunkId`` alongside the existing
    ``pendingActivatePath``. Empty-string chunkId means "source-level
    only, no card highlight" — keeps the Home-recent and command-
    palette callers behaving exactly as before.
  - ``browseSource`` consumes ``pendingActivateChunkId`` after
    ``content`` lands in the DOM: queries by ``data-chunk-id``
    (already set on every ``.chunk-card`` since the existing browse
    code path), scrolls into view, expands the accordion if the card
    is collapsible, and pulses a ~1.4s ``.tl-target-flash``. Cleared
    unconditionally so a follow-up Load-All re-render of the same
    source doesn't re-flash an old target.
  - Timeline rewrites three call sites:
      * Chunks view "Open" button → ``_navigateToSource(c.source_file,
        c.id)``. Button label moves from hard-coded "Open" to
        ``timeline.open_in_source`` (en: "Open in source", ko:
        "소스에서 보기").
      * Files view file header gains a small ghost-style
        ``.tl-file-open-source`` button on the right edge that
        ``stopPropagation``'s the row's expand/collapse and navigates
        to the source path (no chunk highlight — file headers don't
        carry a single canonical chunk).
      * Files view per-chunk row click → ``_navigateToSource(c.source
        _file, c.id)``.

``showDetailFromChunk`` is kept: ``app.js:4834`` still uses it for the
Source-chunks side panel inside the Search detail (intra-detail "jump
to a sibling chunk in the same source"), which is a different flow.
The Timeline call sites are the only ones changing.

Cache-bust: ``style.css?v=72→v=73``, ``app.js?v=87→v=88``,
``timeline.js?v=1→v=2`` per ``feedback_static_asset_cache_bust.md`` —
all three files have body changes.

i18n parity verified by ``test_i18n.py`` (12 passed); ruff +
ruff-format clean. Manual verification with Playwright MCP against a
live ``mm web`` against the developer's real DB:

  - Chunks-view "Open in source" → tab=sources, exactly one
    ``.chunk-card.tl-target-flash`` on the matching ``data-chunk-id``,
    flash visible ~205ms after click then auto-removed.
  - Files-view header button → tab=sources, no chunk flash (intended).
  - Files-view header non-button click → expand/collapse only, tab
    unchanged. ``stopPropagation`` on the new button confirmed.
  - KO label "소스에서 보기" rendered on first paint (``data-i18n``
    + langchange wiring already covers this since PR #587).

Co-Authored-By: Claude <[email protected]>
@memtomem memtomem merged commit 522390d into main May 2, 2026
8 of 9 checks passed
@memtomem memtomem deleted the feat/web-timeline-source-jump branch May 2, 2026 00:28
@github-actions github-actions Bot locked and limited conversation to collaborators May 2, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants