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>
This commit is contained in:
223
backend/frontend/static/js/modules/mindmap-module.js
Normal file
223
backend/frontend/static/js/modules/mindmap-module.js
Normal file
@@ -0,0 +1,223 @@
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
Reference in New Issue
Block a user