Skip to content

feat: add mailer, Spanish language support, and UX improvements#1434

Closed
thomasbeaudry wants to merge 1 commit into
mainfrom
addMailer
Closed

feat: add mailer, Spanish language support, and UX improvements#1434
thomasbeaudry wants to merge 1 commit into
mainfrom
addMailer

Conversation

@thomasbeaudry

Copy link
Copy Markdown
Collaborator

Summary

This PR adds email/mailer functionality, Spanish language support, and several UX improvements to Open Data Capture.

Mailer

  • Email remote assignments: after creating a remote assignment, clinicians can email the link directly to a participant with a selected template and language
  • Email new users: welcome emails can be sent to newly created users with a configurable template
  • Admin mail settings page: admins can configure SMTP settings and test the connection
  • Group email templates page: group managers can create, edit, and delete email templates for remote assignments and information categories
  • Default template viewer: built-in default template can be previewed with a language dropdown toggle
  • Template validation: duplicate template names are rejected; missing translation warnings prompt confirmation before saving
  • "Email language" tooltip: explains that emails and assignments are sent in the selected language when available, and subjects can still choose their preferred language on the gateway
  • Email language dropdown filtered by instrument: only shows languages the selected instrument supports
  • Set default / Default labels: replaced "Active" / "Set active" with "Default" / "Set default" on template rows
  • SaveStatus autosave indicator on the email templates page
  • Scroll to top after adding a new template
  • Email Templates nav item hidden when mail is not enabled

Spanish Language Support

  • Added Spanish (es) translations throughout all new and existing components using the inline t({ en: '...', es: '...', fr: '...' }) pattern
  • Added admin settings page to enable/disable individual languages via an activeLanguages array on setup state
  • Language picker across the app respects the active languages setting
  • Added Spanish support to the gateway (shows available languages for the form being completed)
  • Adding future languages requires adding translations to inline t() calls and the ALL_LANGUAGES map — no schema or architecture changes needed

UX Improvements

  • Auto-focus search bar on the administer instrument and remote assignment pages
  • Keyboard navigation on instrument showcase: arrow keys move highlight, Enter selects the highlighted instrument
  • Create Remote Assignment dialog submits on Enter (replaced date picker Form component with a plain text input)
  • Admin panel auto-collapses when navigating to non-admin pages
  • Gateway language detection from the ?lang= URL parameter so remote assignments open in the correct language

Other

  • Remote assignment URL now sets the form language automatically on the gateway

Test plan

  • Configure SMTP settings on the admin mail page and send a test email
  • Create a remote assignment and email the link to a participant — verify email arrives in the selected language
  • Create a new user with a welcome email — verify it sends
  • Create, edit, and delete email templates as a group manager
  • Verify duplicate template names are rejected
  • Verify missing translation warning appears when creating a template without all active languages
  • Toggle languages on/off in admin settings — verify language picker and template editors respect the change
  • Verify Spanish translations appear throughout the app when Spanish is enabled
  • Verify arrow keys + Enter work on instrument showcase pages
  • Verify search bar auto-focuses on remote assignment and administer instrument pages
  • Verify admin panel collapses when navigating away from admin pages
  • Open a remote assignment URL with ?lang=es — verify gateway starts in Spanish
  • Run pnpm lint and pnpm test — both pass

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@thomasbeaudry
thomasbeaudry requested a review from joshunrau as a code owner July 23, 2026 05:42
Comment on lines +343 to +347
const response = await fetch(request.url, {
body: request.body,
headers: request.headers,
method: request.method
});
/** Validate HTTP-transport credentials (and Mailgun domain/region) without sending a message. */
private async verifyHttp(config: MailConfig): Promise<void> {
const request = buildVerifyRequest(config);
const response = await fetch(request.url, { headers: request.headers, method: request.method });
@gdevenyi

Copy link
Copy Markdown
Contributor

This needs to be split into separate topic PRs, even if their changes are stacked.

@thomasbeaudry

Copy link
Copy Markdown
Collaborator Author

This needs to be split into separate topic PRs, even if their changes are stacked.

Yeah i was thinking that this should be split but Claude was saying i shouldn't split it because it'd be messy. I'm going to do the 3 stacked PRs instead

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.

3 participants