// Admin tab bar. Separate file because the site's CSP is script-src 'self'. // // The admin page had fourteen panels in a fixed 1.5fr/.75fr split — ten tall // ones on the left, four short forms on the right. The right column ran out a // quarter of the way down and you scrolled past dead space for the rest. // Grouping them into tabs lets every panel use the full width. (function () { 'use strict'; var KEY = 'rmc.admin.tab'; function panes() { return [].slice.call(document.querySelectorAll('.tabpane')); } function tabs() { return [].slice.call(document.querySelectorAll('#adminTabs .tab')); } function show(key) { var found = false; panes().forEach(function (p) { var on = p.getAttribute('data-pane') === key; p.classList.toggle('on', on); if (on) found = true; }); if (!found) return false; tabs().forEach(function (t) { var on = t.getAttribute('data-tab') === key; t.classList.toggle('on', on); t.setAttribute('aria-selected', on ? 'true' : 'false'); }); try { localStorage.setItem(KEY, key); } catch (e) {} return true; } document.addEventListener('DOMContentLoaded', function () { var bar = document.getElementById('adminTabs'); if (!bar) return; bar.addEventListener('click', function (e) { var t = e.target.closest('.tab'); if (t) show(t.getAttribute('data-tab')); }); // Left/right arrows move between tabs, as a tablist should. bar.addEventListener('keydown', function (e) { if (e.key !== 'ArrowLeft' && e.key !== 'ArrowRight') return; var all = tabs(); var i = all.indexOf(document.activeElement); if (i < 0) return; var next = all[(i + (e.key === 'ArrowRight' ? 1 : all.length - 1)) % all.length]; next.focus(); show(next.getAttribute('data-tab')); e.preventDefault(); }); // Come back to whichever tab was last open. var saved = null; try { saved = localStorage.getItem(KEY); } catch (e) {} if (!saved || !show(saved)) { var first = tabs()[0]; if (first) show(first.getAttribute('data-tab')); } }); })();