Skip to content

Analysis catalog: read-only panel, command, and jump-to-usage navigation #193

Description

@alex-rawlings-yyc

The user-facing read-only catalog for #186: command, menu column, panel shell, rows, search / sort / filter controls, windowing, and jump-to-usage navigation. No mutations — those are a separate issue.

Depends on the store hoist and focus seam, and on the pure query core.

Placement

A panel inside the existing interlinearizer.mainWebView, beside the interlinear view. Not a modal (jump-to-usage must keep it open), and not a separate WebView tab (a separate iframe means a separate Redux store and no live sync — that path needs the query API in #128).

Wiring

  • interlinearizer.openAnalysisCatalog registered in main.ts alongside the other WebView-handled commands (the /* v8 ignore next */ async () => {} pattern), added to context.registrations.
  • contributions/menus.json: a new top-menu column. The existing interlinearizer.project column holds project / file / draft actions and this is none of those. New interlinearizer.view column, order 2, one group, one item.
  • contributions/localizedStrings.json: %interlinearizer_menu_column_view%, %interlinearizer_openAnalysisCatalog%, plus the panel's own strings.
  • __mocks__/platform-bible-react.tsx: stub Table, Badge, Checkbox, Select, Command, Separator, ToggleGroup as each is first used — not all up front. Add MOCK_OPEN_ANALYSIS_CATALOG_MENU_ITEM and a tab-toolbar-analysis-catalog button, matching the existing per-command pattern.

State

Open/closed and panel width go in useWebViewState — tab-scoped, so they restore with the tab. Deliberately not project settings, which are shared by every tab on that project.

Search, sort, and filter state stays ephemeral useState. Persisting a filter across a reload is the classic "where did my data go" bug.

Row display

Surface form, gloss in the active analysis language, morpheme breakdown as row detail, total usage count, usage count in the current book, and the usage locations parsed from tokenAnalysisLinks[].token.tokenRef. The inline usage list is capped with an expander.

Windowing

Follow the useSegmentWindow / IntersectionObserver precedent (src/hooks/useSegmentWindow.ts) but do not reuse that hook — it is scroll-anchored around a scripture reference, which a row list has no analogue for. A much smaller useRowWindow is the right size. No new dependency.

Behaviors to test

  1. The menu command opens the panel; the interlinear view stays mounted beside it.
  2. Open state round-trips through useWebViewState (restores on remount).
  3. Panel width round-trips through useWebViewState.
  4. A row renders surface form, gloss, and both usage counts.
  5. Typing in search filters the visible rows.
  6. Search state does not survive a panel close/reopen — ephemeral by design.
  7. Changing the sort reorders the rows.
  8. A filter with fewer than two distinct values does not render its control.
  9. Clicking a usage navigates the interlinear view to that verse and focuses that exact token (the ref carries charStart).
  10. Clicking a usage in another book triggers the book load and focuses the token once it arrives.
  11. The panel stays open and the row stays selected after a usage click.
  12. Only the windowed slice of rows is in the DOM for a large row set; scrolling extends it.
  13. The inline usage list is capped, and the expander reveals the rest.

Cross-book clicks retarget the shared scroll group, which propagates to other tabs in that group — that is the intended behavior, not a bug.

Metadata

Metadata

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions