// Inline tap-to-edit for .oneliner-edit blocks. Click swaps the inner // .oneliner-text for an ; Enter POSTs to /cases/{id}/oneliner; // Escape (or blur) cancels. The SSE-driven reload picks up the persisted // state, so no DOM patching is needed on success. (() => { const handleClick = (host) => { if (host.classList.contains('editing')) return; const span = host.querySelector('.oneliner-text'); if (!span) return; const original = span.textContent.trim(); host.classList.add('editing'); const input = document.createElement('input'); input.type = 'text'; input.value = original; input.maxLength = 500; input.className = 'oneliner-input'; span.replaceWith(input); input.focus(); input.select(); const restore = () => { const restoreSpan = document.createElement('span'); restoreSpan.className = 'oneliner-text'; restoreSpan.textContent = original; input.replaceWith(restoreSpan); host.classList.remove('editing', 'saving', 'error'); }; const submit = async () => { const text = input.value.trim(); if (text === '' || text === original) { restore(); return; } host.classList.remove('error'); host.classList.add('saving'); const body = new URLSearchParams({ text, csrf_token: host.dataset.csrf, }); try { const r = await fetch( `/cases/${host.dataset.caseId}/oneliner`, { method: 'POST', body, credentials: 'same-origin' } ); if (!r.ok) { host.classList.remove('saving'); host.classList.add('error'); input.focus(); return; } // SSE will trigger reload; keep input visible until then. } catch (_) { host.classList.remove('saving'); host.classList.add('error'); input.focus(); } }; input.addEventListener('keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); submit(); } else if (e.key === 'Escape') { e.preventDefault(); restore(); } }); input.addEventListener('blur', () => { // Blur acts as cancel unless we're already saving (where blur // happens implicitly when the SSE reload swaps the DOM) or in // an error state (so the user can re-focus and retry). if (host.classList.contains('saving') || host.classList.contains('error')) return; restore(); }); }; document.addEventListener('click', (e) => { const host = e.target.closest('.oneliner-edit'); if (!host) return; if (e.target.closest('a, button, input')) return; handleClick(host); }); })();