diff --git a/frontend/textbooks.html b/frontend/textbooks.html index cbba5d0..b219108 100644 --- a/frontend/textbooks.html +++ b/frontend/textbooks.html @@ -454,16 +454,28 @@ return String(s || '').replace(/[&<>"']/g, c => ({ '&':'&','<':'<','>':'>','"':'"',"'":''' }[c])); } + let labLinks = {}; // { textbook_slug: [{id,title,cat}] } — связанные симуляции (Фаза 5) async function loadTextbooks() { try { - const r = await LS.api('/api/textbooks'); + const [r, labRes] = await Promise.all([ + LS.api('/api/textbooks'), + LS.api('/api/lab/links/all?kind=textbook').catch(() => ({ byRef: {} })), + ]); textbooks = r.textbooks || []; + labLinks = (labRes && labRes.byRef) || {}; render(); } catch (e) { document.getElementById('tb-grid').innerHTML = `
Не удалось загрузить: ${esc(e.message)}
`; } } + /* Фаза 5: открыть связанную симуляцию из карточки учебника (не уходя в учебник). */ + function openLabSim(simId, ev) { + if (ev) ev.stopPropagation(); + location.href = '/lab?sim=' + encodeURIComponent(simId); + } + window.openLabSim = openLabSim; + function render() { const grid = document.getElementById('tb-grid'); if (!textbooks.length) { @@ -509,6 +521,10 @@ ${isTeacher ? `` : ''} + ${(labLinks[t.slug] && labLinks[t.slug].length) ? `` : ''} `;