Skip to content

feat(scatter-plot): right-click context menu (Copy ID, View in UniProt) - #233

Draft
jcoludar wants to merge 1 commit into
mainfrom
feat/scatter-context-menu
Draft

feat(scatter-plot): right-click context menu (Copy ID, View in UniProt)#233
jcoludar wants to merge 1 commit into
mainfrom
feat/scatter-context-menu

Conversation

@jcoludar

Copy link
Copy Markdown
Collaborator

Summary

  • Adds protspace-context-menu Lit element registered in packages/core/src/components/scatter-plot/.
  • Wires it into protspace-scatterplot via a @contextmenu listener on the plot container; right-clicking a point opens a small menu.
  • Two built-in actions, no app changes required:
    • Copy IDnavigator.clipboard.writeText(proteinId)
    • View in UniProt — opens https://www.uniprot.org/uniprotkb/{id}/entry in a new tab; disabled when the id is not a UniProt accession.
  • Also dispatches a context-menu-action CustomEvent on the host for consumers that want to extend with app-level actions later.
  • Click-outside detection uses event.composedPath() so it works correctly across nested shadow DOMs (the host scatter-plot lives inside its own shadow root).

Why this PR

Spun out of #231. After taking #232 as the path forward for the publication-export work, the right-click context menu is the one piece from #231 that's orthogonal to the export modal and useful on its own. Everything else in #231 is being dropped.

Test plan

  • pnpm type-check (clean)
  • pnpm test — added 3-test suite for resolveMenuItems (hit / no-hit / no-accession), 588 tests total pass
  • pnpm lint — no new warnings
  • pnpm build and pnpm docs:build (pre-commit)
  • Manual: right-click a point, verify menu appears at cursor; click "Copy ID" and paste; click "View in UniProt" and confirm tab opens; right-click empty space and confirm no menu; click outside menu and confirm it closes; press Escape and confirm it closes.

Adds a `protspace-context-menu` Lit element wired into `protspace-scatterplot`
via a `@contextmenu` listener on the plot container. Right-clicking a point
opens a small menu with two actions:

- Copy ID — writes the protein id to the clipboard
- View in UniProt — opens the UniProt entry in a new tab (disabled when the
  id is not a UniProt accession)

The menu also dispatches a `context-menu-action` CustomEvent on the host so
consumers can extend with app-level actions later. Click-outside detection
uses `composedPath()` to work correctly across nested shadow DOMs.

Includes a unit test for `resolveMenuItems` covering hit/no-hit and
disabled-on-no-accession paths.
@tsenoner
tsenoner marked this pull request as draft May 6, 2026 13:42
tsenoner added a commit that referenced this pull request Jul 28, 2026
The sweep that qualified refs in the source and tests stopped there, leaving
roughly 45 siblings across eight design docs -- including four hyperlinks
pointing at `tsenoner/protspace/issues/<N>`, which is worse than a bare ref
because it renders as an authoritative link to an unrelated frontend item.

Checking each number against the live API turned up something the first pass
had wrong: three issues were **transferred** into the monorepo rather than
merely stranded, so they have new numbers here. Only #59 was known.

    legacy#31 -> #324    legacy#59 -> #320    legacy#64 -> #318

Those are renumbered everywhere, since the old numbers are now simply wrong.
Everything else is qualified at each document's definitional line ("**Issues:**",
"**Refs:**", "**Trigger:**") rather than in every sentence -- fully qualifying
prose turns headings into "### 2.3 tsenoner/protspace-legacy#57: ...", which
trades one readability problem for another. Two docs that carried bare refs
with no definitional line at all get one.

Deliberately untouched: `#1`-`#6` in the EAT-UX docs are list markers, not
issue refs; `#296`/`#306`/`#295`/`#233` are frontend numbers this repo
inherited, so bare is already correct; and `CHANGELOG.md` is regenerated
wholesale by semantic-release, so editing it would not survive.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019TxEAVCkBQmh3Yy6bPXPSE
tsenoner added a commit that referenced this pull request Aug 13, 2026
Three bookkeeping fixes found reviewing the archive:

- `#66`/`#55`/`#60` in the monorepo change's reconciled tasks are protspace-legacy
  PRs, but bare `#N` autolinks against this repo. `#66` is the silent case: it
  resolves to a merged, unrelated frontend PR ("enhance StructureService with 3D
  Beacons API integration") rather than 404ing, so the link looks fine and points
  somewhere wrong. The intended one is "bundle format v2 — lossless annotation name
  encoding", which is what the surrounding text describes. `#306`/`#295`/`#233`/`#445`
  are genuine refs here and stay bare.
- design.md still described `_INCOMPATIBLE` as (blocked set, why, remedy); 3cdacf9
  collapsed it to (blocked set, note). The archive commit landed before that refactor
  and nothing re-reconciled after.
- A 5.3 checkbox was ticked while its own text read "carried forward to #447 rather
  than ticked". Reworded so the box and the sentence agree.

openspec validate --all --strict: 20 passed, 0 failed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ar6ME3o6VYLYsie3J4kxE5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant