// De track-editor (beheer > audio) (partials/track-editor.ejs) -- verplaatst uit inline script, shaer-bqr. // // Inline script in een pagina wordt door de CSP geweigerd zodra je die pagina via // een link BINNEN de site opent: de nonce rouleert per verzoek (shaer-0i6). Dit // bestand wordt door de bootstrap in shell.ejs geladen en heeft dat probleem niet. // // Alles hier hoort GEDELEGEERD te luisteren (op document, niet op een element dat // er nu staat) en tegen een tweede aanroep te kunnen. (function() { function esc(s) { return String(s == null ? '' : s) .replace(/&/g, '&').replace(//g, '>') .replace(/"/g, '"').replace(/'/g, '''); } async function api(method, url, body) { const opts = { method, credentials: 'same-origin', headers: {} }; if (body !== undefined) { if (body instanceof FormData) { opts.body = body; } else { opts.headers['Content-Type'] = 'application/json'; opts.body = JSON.stringify(body); } } const res = await fetch(url, opts); let data; try { data = await res.json(); } catch (_) { throw new Error('Onverwacht antwoord (' + res.status + ')'); } if (!res.ok) data.ok = false; return data; } /** * Open the track editor. * @param {object} opts * @param {string} opts.id β track id to edit * @param {function?} opts.onSaved β called with updated track on success */ window.openTrackEditor = async function openTrackEditor({ id, onSaved }) { if (!id) return; let track, albumSuggestions = []; try { const [trackJson, listJson] = await Promise.all([ api('GET', '/admin/audio/api/' + encodeURIComponent(id)), api('GET', '/admin/audio/api/albums'), ]); if (!trackJson.ok) throw new Error(trackJson.error || 'Track niet gevonden'); track = trackJson.track; if (listJson.ok && Array.isArray(listJson.albums)) { albumSuggestions = listJson.albums.filter(Boolean); } } catch (err) { alert('Track ophalen mislukt: ' + err.message); return; } const backdrop = document.createElement('div'); backdrop.className = 'te-backdrop'; backdrop.innerHTML = `