(function() { 'use strict'; // Project-picker dropdown for the archive browser. // // In multi-project mode (HTTP source against zddc-server, OR ?projects= // present in the URL), this dropdown lets the user toggle which projects // are scanned. Toggling a checkbox updates window.app.projectFilter, pushes // the new ?projects= state to the URL, and triggers a re-scan. // // In single-project mode the dropdown is hidden — only one project is ever // in scope, so picking is meaningless. let isOpen = false; // The set of project names currently shown in the dropdown. function getKnownProjects() { if (window.app.availableProjects && window.app.availableProjects.length > 0) { return window.app.availableProjects.slice(); } // Fall back to whatever is in the URL filter — useful when the server's // ProjectInfo endpoint isn't reachable but ?projects= names the set. return Array.from(window.app.projectFilter || []); } // Visibility-only filter: change visibleProjects, push URL state, re-render // UI. No rescan — already-scanned data stays in memory. URL is updated via // history.replaceState (same mechanism as every other UI control). function applyVisibility(names) { window.app.visibleProjects = new Set(names); window.app.modules.urlState.push(); window.app.modules.app.updateUI(); window.app.modules.filtering.applyFilters(); renderDropdown(); } function escapeHtml(text) { var div = document.createElement('div'); div.textContent = text; return div.innerHTML; } function renderDropdown() { var dropdown = document.getElementById('presetDropdown'); if (!dropdown) return; var selected = new Set(window.app.visibleProjects || []); var known = getKnownProjects().slice().sort(); var projectsHtml = known.map(name => { var checked = selected.has(name) ? ' checked' : ''; var n = escapeHtml(name); return '
' + '' + '
'; }).join(''); if (!projectsHtml) { projectsHtml = '
No projects available
'; } dropdown.innerHTML = '
' + '
Projects:
' + '
' + projectsHtml + '
' + '
'; } function toggleDropdown() { var dropdown = document.getElementById('presetDropdown'); if (isOpen) { closeDropdown(); return; } isOpen = true; if (dropdown) dropdown.classList.remove('hidden'); renderDropdown(); } function closeDropdown() { isOpen = false; var dropdown = document.getElementById('presetDropdown'); if (dropdown) dropdown.classList.add('hidden'); } function setupDropdownDelegation() { var dropdown = document.getElementById('presetDropdown'); if (!dropdown) return; dropdown.addEventListener('click', function(e) { e.stopPropagation(); var checkbox = e.target.closest('.preset-checkbox'); if (!checkbox) return; var projectName = checkbox.getAttribute('data-name'); if (!projectName) return; var sel = new Set(window.app.visibleProjects || []); if (checkbox.checked) sel.add(projectName); else sel.delete(projectName); applyVisibility(Array.from(sel)); }); } function setupOutsideClickHandler() { document.addEventListener('click', function(e) { var section = document.getElementById('presetSection'); var dropdown = document.getElementById('presetDropdown'); if (isOpen && section && dropdown && !section.contains(e.target)) { closeDropdown(); } }); } function init() { var section = document.getElementById('presetSection'); if (!section) return; // Hide the dropdown entirely outside multi-project mode. if (!window.app.isMultiProject) { section.classList.add('hidden'); return; } section.classList.remove('hidden'); var btn = document.getElementById('presetBtn'); if (!btn || btn.dataset.presetInit) return; btn.dataset.presetInit = '1'; btn.title = 'Project picker'; btn.textContent = '▾ Projects'; btn.addEventListener('click', function(e) { e.stopPropagation(); toggleDropdown(); }); setupDropdownDelegation(); setupOutsideClickHandler(); } window.app.modules.presets = { init: init, toggleDropdown: toggleDropdown, closeDropdown: closeDropdown, // No-op kept so existing callers (events.js after grouping-folder click) // don't need to null-check; preset dirty state was removed with the // saved-presets feature. checkDirty: function() {} }; })();