Fix reference links

This commit is contained in:
Ian Keane 2026-06-11 16:06:21 -04:00
parent 5812d3cc76
commit 13042bcfa3
2 changed files with 46 additions and 10 deletions

41
app.js
View file

@ -16,6 +16,7 @@ let sortDir = 'asc';
// editing state
let editingTuneId = null; // null = add mode
let editingEntryId = null; // null = no existing instrument entry
let editingOriginalRefIds = []; // ref IDs present when edit modal opened
// notes modal state
let notesTuneId = null;
@ -501,6 +502,7 @@ btnAddTune.addEventListener('click', openAdd);
function openAdd() {
editingTuneId = null;
editingEntryId = null;
editingOriginalRefIds = [];
$('modal-title').textContent = 'Add tune';
tuneForm.reset();
refsList.innerHTML = '';
@ -552,6 +554,7 @@ async function openEdit(tuneId, entryId) {
tuneForm.elements.inst_difficulty.value = entry.difficulty ?? '';
}
editingOriginalRefIds = (fullTune.references ?? []).map(r => r.id);
(fullTune.references ?? []).forEach(r => addRefRow(r.link, r.site?.name ?? '', r.id, r.site_id, r.musicians ?? []));
}
@ -716,6 +719,35 @@ async function saveTune() {
});
}
}
// Sync references
const formRows = [...refsList.querySelectorAll('.ref-row')];
const formRefIds = new Set(formRows.map(r => r.dataset.refId).filter(Boolean));
// Delete refs removed from the form
for (const refId of editingOriginalRefIds) {
if (!formRefIds.has(String(refId))) {
await apiFetch(`/tunes/${tuneId}/references/${refId}`, { method: 'DELETE' });
}
}
// Create new refs; patch existing ones (link + site)
for (const row of formRows) {
const refId = row.dataset.refId;
const link = row.querySelector('.ref-link').value.trim() || null;
const siteId = row.querySelector('.ref-site').value ? parseInt(row.querySelector('.ref-site').value) : null;
if (!link && !siteId) continue;
if (refId) {
await apiFetch(`/tunes/${tuneId}/references/${refId}`, {
method: 'PATCH', body: JSON.stringify({ link, site_id: siteId }),
});
} else {
const musicians = row._getMusicians ? row._getMusicians() : [];
await apiFetch(`/tunes/${tuneId}/references`, {
method: 'POST', body: JSON.stringify({ link, site_id: siteId, musicians }),
});
}
}
}
tuneModal.close();
@ -904,9 +936,14 @@ async function openRefsModal(tuneId) {
const musicians = r.musicians?.map(m => m.name).join(', ') ?? '';
const siteName = r.site?.name ?? '';
const meta = [siteName, musicians].filter(Boolean).join(' · ');
// Use meta as link text; fall back to hostname so raw URL is never shown
let displayText = meta;
if (!displayText && r.link) {
try { displayText = new URL(r.link).hostname.replace(/^www\./, ''); } catch { displayText = 'link'; }
}
if (!displayText) displayText = 'link';
item.innerHTML = `
<a href="${esc(r.link ?? '')}" target="_blank" rel="noopener" class="ref-link-anchor">${esc(r.link ?? r.site?.name ?? 'link')}</a>
${meta ? `<span class="ref-meta">${esc(meta)}</span>` : ''}`;
<a href="${esc(r.link ?? '')}" target="_blank" rel="noopener" class="ref-link-anchor">${esc(displayText)}</a>`;
refsModalList.appendChild(item);
});
}

View file

@ -787,7 +787,6 @@ fieldset.active .fs-body { display: contents; }
.ref-link-anchor {
color: var(--accent);
font-size: .875rem;
word-break: break-all;
text-decoration: none;
}
.ref-link-anchor:hover { text-decoration: underline; }