This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
breakpilot-pwa/backend/frontend/static/js/modules/mindmap-module.js
Benjamin Admin bfdaf63ba9 fix: Restore all files lost during destructive rebase
A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.

This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).

Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 09:51:32 +01:00

224 lines
6.5 KiB
JavaScript

/**
* BreakPilot Studio - Mindmap Module
*
* Mindmap/Lernplakat-Generierung aus Arbeitsblättern:
* - Generieren von Mindmaps aus analysierten Arbeitsblättern
* - Vorschau und Anzeige
* - Druck-Funktion (A4/A3)
*
* Refactored: 2026-01-19
*/
import { t } from './i18n.js';
import { setStatus, setStatusWorking, setStatusError, setStatusSuccess, fetchJSON } from './api-helpers.js';
// State
let currentMindmapData = null;
// DOM References
let mindmapPreview = null;
let mindmapBadge = null;
let btnMindmapGenerate = null;
let btnMindmapShow = null;
let btnMindmapPrint = null;
// Callback für aktuelle Datei
let getCurrentFileCallback = null;
/**
* Initialisiert das Mindmap-Modul
* @param {Object} options - Konfiguration
* @param {Function} options.getCurrentFile - Callback um die aktuelle Datei zu bekommen
*/
export function initMindmapModule(options = {}) {
getCurrentFileCallback = options.getCurrentFile || (() => null);
mindmapPreview = document.getElementById('mindmap-preview') || options.previewEl;
mindmapBadge = document.getElementById('mindmap-badge') || options.badgeEl;
btnMindmapGenerate = document.getElementById('btn-mindmap-generate') || options.generateBtn;
btnMindmapShow = document.getElementById('btn-mindmap-show') || options.showBtn;
btnMindmapPrint = document.getElementById('btn-mindmap-print') || options.printBtn;
// Event-Listener
if (btnMindmapGenerate) {
btnMindmapGenerate.addEventListener('click', generateMindmap);
}
if (btnMindmapShow) {
btnMindmapShow.addEventListener('click', openMindmapView);
}
if (btnMindmapPrint) {
btnMindmapPrint.addEventListener('click', openMindmapPrint);
}
// Event für Datei-Wechsel
window.addEventListener('fileSelected', (ev) => {
loadMindmapData();
});
}
/**
* Generiert eine Mindmap für die aktuelle Datei
*/
export async function generateMindmap() {
const currentFile = getCurrentFileCallback();
if (!currentFile) {
alert(t('select_file_first') || 'Bitte zuerst eine Datei auswählen.');
return;
}
try {
setStatusWorking(t('mindmap_generating') || 'Generiere Mindmap...');
if (mindmapBadge) {
mindmapBadge.textContent = t('generating') || 'Generiert...';
mindmapBadge.className = 'card-badge';
}
const resp = await fetch('/api/generate-mindmap/' + encodeURIComponent(currentFile), {
method: 'POST'
});
if (!resp.ok) {
throw new Error('HTTP ' + resp.status);
}
const data = await resp.json();
if (data.status === 'OK') {
if (mindmapBadge) {
mindmapBadge.textContent = t('ready') || 'Fertig';
mindmapBadge.className = 'card-badge badge-success';
}
setStatusSuccess(t('mindmap_generated') || 'Mindmap erstellt!');
// Lade Mindmap-Daten
await loadMindmapData();
} else if (data.status === 'NOT_FOUND') {
if (mindmapBadge) {
mindmapBadge.textContent = t('no_analysis') || 'Keine Analyse';
mindmapBadge.className = 'card-badge badge-error';
}
setStatusError(t('analyze_first') || 'Bitte zuerst analysieren (Neuaufbau starten)');
} else {
throw new Error(data.message || 'Fehler bei der Mindmap-Generierung');
}
} catch (err) {
console.error('Mindmap error:', err);
if (mindmapBadge) {
mindmapBadge.textContent = t('error') || 'Fehler';
mindmapBadge.className = 'card-badge badge-error';
}
setStatusError(t('error') || 'Fehler', err.message);
}
}
/**
* Lädt die Mindmap-Daten für die aktuelle Datei
*/
export async function loadMindmapData() {
const currentFile = getCurrentFileCallback();
if (!currentFile) {
if (mindmapPreview) mindmapPreview.innerHTML = '';
return;
}
try {
const resp = await fetch('/api/mindmap-data/' + encodeURIComponent(currentFile));
const data = await resp.json();
if (data.status === 'OK' && data.data) {
currentMindmapData = data.data;
renderMindmapPreview();
if (btnMindmapShow) btnMindmapShow.style.display = 'inline-block';
if (btnMindmapPrint) btnMindmapPrint.style.display = 'inline-block';
if (mindmapBadge) {
mindmapBadge.textContent = t('ready') || 'Fertig';
mindmapBadge.className = 'card-badge badge-success';
}
} else {
currentMindmapData = null;
if (mindmapPreview) mindmapPreview.innerHTML = '';
if (btnMindmapShow) btnMindmapShow.style.display = 'none';
if (btnMindmapPrint) btnMindmapPrint.style.display = 'none';
if (mindmapBadge) {
mindmapBadge.textContent = t('ready') || 'Bereit';
mindmapBadge.className = 'card-badge';
}
}
} catch (err) {
console.error('Error loading mindmap:', err);
}
}
/**
* Rendert die Mindmap-Vorschau
*/
function renderMindmapPreview() {
if (!mindmapPreview) return;
if (!currentMindmapData) {
mindmapPreview.innerHTML = '';
return;
}
const topic = currentMindmapData.topic || 'Thema';
const categories = currentMindmapData.categories || [];
const categoryCount = categories.length;
const termCount = categories.reduce((sum, cat) => sum + (cat.terms ? cat.terms.length : 0), 0);
mindmapPreview.innerHTML = `
<div style="margin-top:10px;padding:12px;background:linear-gradient(135deg,#f0f9ff,#e0f2fe);border-radius:10px;text-align:center;">
<div style="font-size:18px;font-weight:bold;color:#0369a1;margin-bottom:8px;">${escapeHtml(topic)}</div>
<div style="font-size:12px;color:#64748b;">
${categoryCount} ${t('categories') || 'Kategorien'} | ${termCount} ${t('terms') || 'Begriffe'}
</div>
</div>
`;
}
/**
* Öffnet die Mindmap-Ansicht (A4)
*/
export function openMindmapView() {
const currentFile = getCurrentFileCallback();
if (!currentFile) return;
window.open('/api/mindmap-html/' + encodeURIComponent(currentFile) + '?format=a4', '_blank');
}
/**
* Öffnet die Mindmap-Druckansicht (A3)
*/
export function openMindmapPrint() {
const currentFile = getCurrentFileCallback();
if (!currentFile) return;
window.open('/api/mindmap-html/' + encodeURIComponent(currentFile) + '?format=a3', '_blank');
}
/**
* Gibt die aktuellen Mindmap-Daten zurück
* @returns {Object|null}
*/
export function getMindmapData() {
return currentMindmapData;
}
/**
* Setzt die Mindmap-Daten
* @param {Object} data
*/
export function setMindmapData(data) {
currentMindmapData = data;
renderMindmapPreview();
}
/**
* Helper: HTML-Escape
*/
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}