Skip to content

feat: Publication Export Studio — annotations, inset lens, style dedup#231

Closed
jcoludar wants to merge 50 commits into
mainfrom
feat/publication-export-studio
Closed

feat: Publication Export Studio — annotations, inset lens, style dedup#231
jcoludar wants to merge 50 commits into
mainfrom
feat/publication-export-studio

Conversation

@jcoludar
Copy link
Copy Markdown
Collaborator

Summary

  • Export Studio: direct open from Export button, live preview with annotations rendered on canvas, Publication/Screen modes, legend font/width sliders (locked/flexible), IDs + Parquet export in studio
  • Canvas annotations: context menu (light theme, composedPath fix), indicator arrows, lens inset tool (drag/resize/zoom/pin), selection mode wiring
  • Style dedup: ~130 lines removed — export-studio/query-builder use shared mixins, dead code deleted
  • Bug fixes: shadow DOM event doubling, inset coordinate mapping, annotation double-drawing prevention

Status

Draft — exploratory work. Next step: redesign as export-studio-only architecture (no canvas annotations) per design discussion.

Test plan

  • 837 unit tests pass
  • 12 Playwright e2e tests pass (context menu, indicators, inset, export studio, visual smoke)
  • Type-check clean
  • Lint clean

🤖 Generated with Claude Code

t03i and others added 30 commits March 20, 2026 14:40
- Add mm-based layout, typography, legend draw, scatter capture, composer
- Add buildPublicationLegendModel for selection-aware counts
- Export canvas-limits for shared max dimension/area checks
- Extend PersistedExportOptions with publication preset and legend placement
- Validate optional publication fields in bundle settings

Made-with: Cursor
- Remove PNG/PDF and raster fallbacks; keep createExporter for IDs only
- Add generateProtspaceExportBasename for publication filenames
- Add jsdom devDependency for export-utils tests (vitest environment)
- Drop html2canvas-pro from deps and Rollup externals

Made-with: Cursor
- Replace pixel sliders with figure preset and legend placement
- Emit publication mode on PNG/PDF export; persist preset fields
- Use MAX_CANVAS_DIMENSION / MAX_CANVAS_AREA from @protspace/utils in renderer
- Update control bar and persistence tests; clarify legend export docstring

Made-with: Cursor
- Route PNG/PDF through exportPublicationFigure and scatter capture
- Add publication-export-bridge for selection-aware legend model
- Preload Roboto Condensed for export canvas; protein IDs via exportUtils

Made-with: Cursor
- Document mm presets, legend placement, 300 DPI, and legend caps
- Note captureAtResolution requirement and selection-aware counts

Made-with: Cursor
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s async

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rrel

Add LegendGrid to the publication-export barrel re-export so all presets
types are available from the package root.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Captures the agreed design for fixing legend cell proportions,
dynamic scatter aspect ratio, deselected point desaturation, and
scatter-only layout presets.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…unt styling

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…blication capture

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
t03i and others added 20 commits April 14, 2026 12:22
…derer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds one_column_scatter_only, two_column_scatter_only, and full_page_scatter_only
layout presets with LegendPlacement 'none', a 'none' branch in computePublicationLayout
that derives figure height from the scatter aspect ratio, and finite legend caps for
the new IDs so all existing downstream tests continue to pass.
Design spec and 12-task implementation plan for:
- Right-click context menu (Indicate, Select, Copy ID, UniProt)
- Indicator arrows (zoom-invariant, draggable, editable)
- Inset tool (frame → snap → position)
- Export Studio modal (WYSIWYG preview, layout presets, legend tuning)

Builds on PR #224 (t03i/issue177).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…nsets, and context menu

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Factory function createAnnotationController manages indicator and inset
lifecycle (add/remove/update, framing state machine, snapshot serialisation)
with optional onChange callback, following the interaction-controller pattern.
Adds knip ignoreIssues for the exported AnnotationController interface
(consumed by future tasks in this feature branch).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements resolveMenuItems pure logic and ProtspaceContextMenu Lit element with keyboard/click-outside dismissal, separator support, and disabled state for non-UniProt IDs. Exports added to package barrel.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds ProtspaceIndicatorLayer web component with draggable arrow indicators,
editable labels, and computeArrowScreenPosition utility that applies D3 zoom
transforms. Dispatches indicator-update and indicator-remove events.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…o runtime

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… workflow

Implements ProtspaceInsetTool (protspace-inset-tool) — a Lit element that
renders positioned insets with drag-to-reposition, keyboard confirm/cancel,
and framing/snapped state badges. Exports computeConnectorLines for connector
line geometry (2 tests). Wired into scatter-plot as a z-index-5 child with
insets and inset-step properties.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…anel

Implements the Export Studio modal component (Task 8/12): fixed overlay with
checkerboard preview area on the left, 280px controls sidebar on the right.
Receives indicators and insets as properties and lists them. Exports
computePreviewDimensions for aspect-ratio-preserving preview scaling (3 tests).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…to studio modal

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tion

Wire the Export Studio modal to the publication-export pipeline:
- Create export-studio-preview.ts component that displays a composed canvas
  scaled to fit its container
- Rewrite export-studio.ts with real controls: layout preset grid using
  FIGURE_LAYOUTS, legend info display, DPI selector, and working download
  buttons that call exportPublicationFigure() / downloadPng()
- Update export-handler.ts to pass scatterCapture, legendModel,
  viewportAspect, and fileNameBase to the studio when opening it
- Preview renders via composePublicationFigureRaster() at reduced DPI
  (150) with 300ms debounce for responsiveness

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Native and Freeform modes alongside the publication presets:
- Native mode exports at current screen pixel dimensions (scatter only)
- Freeform mode provides custom W x H inputs with quick-pick presets
  (HD 1920x1080, 4K 3840x2160, Square 2000x2000, Poster 4000x3000,
  Slide 4:3 2048x1536)
- Both modes bypass the publication layout pipeline and render scatter
  directly at the target pixel dimensions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ort studio

11 tests covering:
- Right-click context menu (point actions, empty space, Escape dismiss)
- Indicator arrows (add via Indicate, multiple indicators)
- Export Studio (open/close, layout presets, indicator sync)
- Select via context menu

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…dedup

Export Studio:
- Direct open from Export button (no dropdown menu)
- Live preview with indicators + insets rendered on canvas
- Publication/Screen modes, legend font/width sliders (locked/flexible)
- IDs + Parquet export buttons in studio

Canvas annotations:
- Context menu: light theme, correct positioning (composedPath fix)
- Indicator arrows: create via right-click, draggable, rendered in export
- Lens inset tool: magnifying glass button, drag/resize/zoom, corner resize
- Inset zoom preserved on pin, insets draggable after confirmation
- Select via context menu activates selection mode + Escape clears

Style dedup:
- export-studio uses overlayMixins + buttonMixin + inputMixin (light theme)
- query-builder uses overlayMixins, consolidated picker styles
- Dead code removed: ProtSpaceExporter class, createExporter factory
- Token normalization across context-menu, inset-tool

Bug fixes:
- Shadow DOM event doubling (e.stopPropagation on context-menu-action)
- Inset annotation coordinate mapping (normalized 0-1 → canvas px)
- skipAnnotations flag prevents double-drawing in inset captures

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jcoludar
Copy link
Copy Markdown
Collaborator Author

Closing in favour of #232 (Tobi's feat/publish-editor), which is the path we're taking forward for the publication editor.

The one piece from this PR that was genuinely orthogonal — the right-click context menu on the scatter-plot — has been carved out as #233 (feat/scatter-context-menu). Everything else here is superseded by #232.

Leaving the branch up for reference / posterity. The brainstorming docs and Playwright e2e specs in this branch may still be useful as inspiration when extending #232 later.

@jcoludar jcoludar closed this Apr 27, 2026
@tsenoner tsenoner deleted the feat/publication-export-studio branch April 28, 2026 17:35
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.

2 participants