diff --git a/portal/templates/app/orgs.html b/portal/templates/app/orgs.html index fbb18e1..b9225a9 100644 --- a/portal/templates/app/orgs.html +++ b/portal/templates/app/orgs.html @@ -280,6 +280,17 @@ btn.disabled = true; btn.textContent = 'Saving...'; errEl.classList.add('hidden'); try { const version = parseInt(document.getElementById('eVersion').value) || 1; + // Single write: details + members together via members endpoint first, then details + // Actually: save details (which preserves existing members in orgData), then members + // To avoid version race, save members FIRST then details (or combine) + // Simplest: save members first with current version, details second with version+1 + const mRes = await fetchAPI('/api/orgs/' + editingOrgId + '/members', { + method: 'PUT', + body: JSON.stringify({ members: editingMembers, version }) + }); + const mData = await mRes.json(); + if (!mRes.ok) throw new Error(mData.error || 'Failed to save members'); + const newVersion = mData.version || version + 1; const res = await fetchAPI('/api/orgs/' + editingOrgId, { method: 'PUT', body: JSON.stringify({ @@ -293,25 +304,16 @@ address: document.getElementById('eAddress').value.trim(), state: document.getElementById('eState').value.trim(), logo: document.getElementById('eLogo').value.trim(), - version, + version: newVersion, }) }); const data = await res.json(); - if (!res.ok) throw new Error(data.error || 'Failed to save'); - // Also save members separately - await saveMembersToServer(data.version || version + 1); + if (!res.ok) throw new Error(data.error || 'Failed to save details'); closeEditModal(); loadOrgs(); } catch(e) { errEl.textContent = e.message; errEl.classList.remove('hidden'); btn.disabled = false; btn.textContent = 'Save Changes'; } } - async function saveMembersToServer(version) { - await fetchAPI('/api/orgs/' + editingOrgId + '/members', { - method: 'PUT', - body: JSON.stringify({ members: editingMembers, version }) - }); - } - // ---- Members Tab ---- function renderMemberList() { const list = document.getElementById('memberList'); @@ -463,12 +465,13 @@ + '

They may have left the organization. Review and remove individually if confirmed.

' + '
'; notFound.forEach((p, i) => { - html += '
' + html += '
' + '
' + '
' + escHtml(p.name || p.email) + '
' + (p.title ? '
' + escHtml(p.title) + '
' : '') + '
' - + 'Not on site' + + 'Not on site' + + '' + '' + '
'; }); @@ -491,6 +494,12 @@ const sa = document.getElementById('rescrapeSelectAll'); if (sa) sa.checked = all.length > 0 && checked.length === all.length; } + function ignoreInactive(idx) { + const row = document.getElementById('nf-row-' + idx); + if (row) row.remove(); + if (window._rescrapeNotFound) window._rescrapeNotFound[idx] = null; + } + function confirmRemoveInactive(idx) { const people = window._rescrapeNotFound || []; const p = people[idx];