Skip to content

fix: newsletter editor formatting and working group activity#2000

Open
bokelley wants to merge 2 commits intomainfrom
bokelley/newsletter-editor-fix
Open

fix: newsletter editor formatting and working group activity#2000
bokelley wants to merge 2 commits intomainfrom
bokelley/newsletter-editor-fix

Conversation

@bokelley
Copy link
Copy Markdown
Contributor

@bokelley bokelley commented Apr 8, 2026

Summary

  • Editor's note paste fix: Pasting rich text into the editor's note field no longer produces a blob of text. The paste handler preserves paragraph breaks and converts links to Slack format. Uses innerText instead of textContent so line breaks survive save/render.
  • Email rendering: Editor's note newlines now render as <br> in the email template.
  • From the Inside: Working group cards now show meeting recaps (linked titles, dates, summaries) and active Slack threads (linked summaries, reply/participant counts) — data that was already being collected but not displayed.
  • Activity filter: Working groups only appear if they have actual recent meetings or threads. Stale AI summaries alone no longer qualify a group for inclusion.
  • Security: Added safeHref() protocol validation on all dynamic href attributes to prevent javascript: URI injection.

Test plan

  • All 563 unit tests pass
  • TypeScript compiles clean
  • Playwright browser tests pass for paste handler, WG card rendering, and renderSlackLinks
  • Code review: no must-fix findings
  • Security review: no must-fix findings; should-fix (protocol validation) addressed

🤖 Generated with Claude Code

Editor's note was losing all formatting when pasting rich text because
the save function used textContent which strips line breaks. Now uses
innerText and a paste handler that preserves paragraph structure and
converts links to Slack format.

Working groups in "From the Inside" now show meeting recaps and active
threads instead of just a summary description. Groups without actual
recent activity (meetings or threads) are filtered out.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
const html = e.clipboardData.getData('text/html');
let text;
if (html) {
const doc = new DOMParser().parseFromString(html, 'text/html');
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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