// Invite-member modal. Mirrors workspace-rename-modal.js's structure // (overlay + listeners + close + esc/click-outside/enter) with two key // differences: // // 1. On success calls an onSuccess(result) callback instead of // window.location.reload(). The parent view (workspace-members.js) // re-fetches and re-renders just the pending-invites section - no // full-page flash for a single row addition. // // 2. Server errors map to translated strings via a mapError callback // passed by the parent (mapMutationError lives in workspace-members.js). // That keeps a single error mapper for ALL slice 2B mutations rather // than scattering modal-specific copies. Inline display below the form // (not toast) so user can correct + resubmit without closing. import { api } from '../api.js'; import { t } from '../i18n.js'; const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; // open the modal. // workspace: { id, name } - id used for the API call, name shown in title // opts.onSuccess: (result) => void - fires on 200; result is the server // response body { id, email, role, expires_at } // opts.mapError: (err) => string - translates server error to display text export function openInviteMemberModal(workspace, opts = {}) { const { onSuccess, mapError } = opts; const overlay = document.createElement('div'); overlay.className = 'modal-overlay'; overlay.innerHTML = `