(() => { function initSearchDbAnalyzer() { const form = document.getElementById('analyzer-form'); if (!form || form.dataset.bound) return; form.dataset.bound = '1'; const dataScript = document.getElementById('search-db-analyzer-data'); let foldersUrl = ''; let queryUrl = ''; if (dataScript) { try { const parsed = JSON.parse(dataScript.textContent || '{}'); foldersUrl = parsed.folders_url || ''; queryUrl = parsed.query_url || ''; } catch (err) { console.error('Failed to parse analyzer data', err); } } const feedback = document.getElementById('analyzer-feedback'); const resultWrapper = document.getElementById('analyzer-result'); const resultBody = document.getElementById('result-body'); const filetypeBody = document.getElementById('filetype-body'); const totalCount = document.getElementById('totalCount'); const levelsContainer = document.getElementById('folder-levels'); const levelSelects = []; const createSelect = (level, options) => { const wrapper = document.createElement('div'); wrapper.className = 'folder-level'; const select = document.createElement('select'); select.className = 'form-select'; select.dataset.level = level; select.required = level === 0; const placeholder = document.createElement('option'); placeholder.value = ''; placeholder.textContent = level === 0 ? 'Bitte auswählen' : 'Optionaler Unterordner'; select.appendChild(placeholder); options.forEach((opt) => { const option = document.createElement('option'); option.value = opt; option.textContent = opt; select.appendChild(option); }); select.addEventListener('change', () => { removeLevelsFrom(level + 1); updateControlButtons(); }); const controls = document.createElement('div'); controls.className = 'd-flex gap-2 align-items-center'; const btnGroup = document.createElement('div'); btnGroup.className = 'btn-group btn-group-sm'; const addBtn = document.createElement('button'); addBtn.type = 'button'; addBtn.className = 'btn btn-outline-secondary'; addBtn.textContent = '+'; addBtn.addEventListener('click', () => handleAddLevel()); btnGroup.appendChild(addBtn); let removeBtn = null; if (level > 0) { removeBtn = document.createElement('button'); removeBtn.type = 'button'; removeBtn.className = 'btn btn-outline-danger'; removeBtn.textContent = '-'; removeBtn.addEventListener('click', () => { removeLevelsFrom(level); updateControlButtons(); }); btnGroup.appendChild(removeBtn); } controls.append(select, btnGroup); wrapper.append(controls); levelsContainer.appendChild(wrapper); levelSelects.push({ wrapper, select, addBtn, removeBtn, btnGroup }); }; const removeLevelsFrom = (startIndex) => { while (levelSelects.length > startIndex) { const item = levelSelects.pop(); levelsContainer.removeChild(item.wrapper); } }; const currentPath = () => { const parts = levelSelects .map(({ select }) => select.value) .filter((v) => v && v.trim() !== ''); return parts.join('/'); }; const fetchChildren = async (parentPath = '') => { if (!foldersUrl) throw new Error('Ordner-Endpoint fehlt.'); const params = parentPath ? `?parent=${encodeURIComponent(parentPath)}` : ''; const response = await fetch(`${foldersUrl}${params}`); const data = await response.json(); if (!response.ok) { throw new Error(data.error || 'Ordner konnten nicht geladen werden.'); } return data.children || []; }; const updateControlButtons = () => { if (!levelSelects.length) { return; } levelSelects.forEach((item, idx) => { const isLast = idx === levelSelects.length - 1; if (item.btnGroup) { item.btnGroup.classList.toggle('d-none', !isLast); } if (item.addBtn) { item.addBtn.disabled = !item.select.value; } if (item.removeBtn) { const hideRemove = !isLast || idx === 0; item.removeBtn.classList.toggle('d-none', hideRemove); item.removeBtn.disabled = hideRemove; } }); }; const initBaseLevel = async () => { try { const children = await fetchChildren(''); if (!children.length) { feedback.textContent = 'Keine Ordner in der Datenbank gefunden.'; feedback.style.display = 'block'; return; } createSelect(0, children); updateControlButtons(); } catch (error) { feedback.textContent = error.message; feedback.style.display = 'block'; } }; const handleAddLevel = async () => { feedback.style.display = 'none'; const path = currentPath(); if (!path) { feedback.textContent = 'Bitte zuerst einen Hauptordner auswählen.'; feedback.style.display = 'block'; return; } try { const children = await fetchChildren(path); if (!children.length) { feedback.textContent = 'Keine weiteren Unterordner vorhanden.'; feedback.style.display = 'block'; return; } createSelect(levelSelects.length, children); updateControlButtons(); } catch (error) { feedback.textContent = error.message; feedback.style.display = 'block'; } }; initBaseLevel(); form.addEventListener('submit', async (event) => { event.preventDefault(); feedback.style.display = 'none'; resultWrapper.style.display = 'none'; const folderPath = currentPath(); if (!folderPath) { feedback.textContent = 'Bitte einen Ordner auswählen.'; feedback.style.display = 'block'; return; } const submitButton = form.querySelector('button[type="submit"]'); submitButton.disabled = true; submitButton.textContent = 'Wird geladen...'; try { if (!queryUrl) throw new Error('Abfrage-Endpoint fehlt.'); const response = await fetch(queryUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ folder_path: folderPath }) }); const data = await response.json(); if (!response.ok) { throw new Error(data.error || 'Abfrage fehlgeschlagen.'); } resultBody.innerHTML = ''; if (filetypeBody) { filetypeBody.innerHTML = ''; } if (data.categories && data.categories.length) { data.categories.forEach((row) => { const tr = document.createElement('tr'); const cat = document.createElement('td'); const cnt = document.createElement('td'); cat.textContent = row.category || 'Keine Kategorie'; cnt.textContent = row.count; tr.append(cat, cnt); resultBody.appendChild(tr); }); } else { const tr = document.createElement('tr'); const td = document.createElement('td'); td.colSpan = 2; td.textContent = 'Keine Treffer gefunden.'; tr.appendChild(td); resultBody.appendChild(tr); } if (filetypeBody) { if (data.filetypes && data.filetypes.length) { data.filetypes.forEach((row) => { const tr = document.createElement('tr'); const type = document.createElement('td'); const cnt = document.createElement('td'); type.textContent = row.type || 'Misc'; cnt.textContent = row.count; tr.append(type, cnt); filetypeBody.appendChild(tr); }); } else { const tr = document.createElement('tr'); const td = document.createElement('td'); td.colSpan = 2; td.textContent = 'Keine Datei-Typen gefunden.'; tr.appendChild(td); filetypeBody.appendChild(tr); } } totalCount.textContent = `${data.total || 0} Dateien`; resultWrapper.style.display = 'block'; } catch (error) { feedback.textContent = error.message; feedback.style.display = 'block'; } finally { submitButton.disabled = false; submitButton.textContent = 'Abfrage starten'; } }); } if (window.PageRegistry && typeof window.PageRegistry.register === 'function') { window.PageRegistry.register('search_db_analyzer', { init: initSearchDbAnalyzer }); } })();