Erster Commit

This commit is contained in:
zed
2026-03-13 09:53:40 +01:00
commit 5ebcad02ed
3945 changed files with 974582 additions and 0 deletions

787
index.html Normal file
View File

@@ -0,0 +1,787 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ERP EDI Bridge | VDA ↔ EDIFACT</title>
<link rel="stylesheet" href="styles.css">
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800&family=Fira+Code&display=swap"
rel="stylesheet">
<!-- Icons (External) - Error Handled -->
<script src="https://unpkg.com/lucide@latest"></script>
<script>
window.onerror = function (msg, url, line) {
console.error('Global Error: ' + msg + '\nline: ' + line);
return false;
};
</script>
</head>
<body>
<div class="dashboard">
<header>
<h1>ERP EDI Bridge</h1>
<p class="subtitle">Konvertieren Sie VDA 4913, 4905 und EDIFACT Nachrichten</p>
</header>
<!-- ═══ Page Navigation ═══ -->
<nav class="page-nav">
<button class="page-nav-btn active" data-page="converter" onclick="app.showPage('converter')">
<i data-lucide="repeat"></i>
Converter
</button>
<button class="page-nav-btn" data-page="viewer" onclick="app.showPage('viewer')">
<i data-lucide="file-text"></i>
EDI Viewer
</button>
<button class="page-nav-btn" data-page="editor" onclick="app.showPage('editor')">
<i data-lucide="edit-3"></i>
Editor
</button>
<button class="page-nav-btn" data-page="history" onclick="app.showPage('history')">
<i data-lucide="database"></i>
Historie
</button>
<button class="page-nav-btn" data-page="settings" onclick="app.showPage('settings')">
<i data-lucide="settings"></i>
Settings
</button>
</nav>
<!-- Config Upload (Global) -->
<div class="config-bar" style="max-width: 1200px; margin: 0 auto 20px auto;">
<div class="config-status" id="configStatus">
<i data-lucide="settings-2"></i>
<span>Keine Konfiguration geladen</span>
</div>
<button class="btn-secondary" onclick="document.getElementById('configInput').click()">
<i data-lucide="upload"></i>
Konfig laden
</button>
<button class="btn-secondary" id="btnSaveConfig" onclick="app.saveConfig()" style="display:none">
<i data-lucide="save"></i>
Konfig speichern
</button>
<input type="file" id="configInput" accept=".txt,.ini,.cfg" class="hidden">
</div>
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- PAGE: CONVERTER -->
<!-- ═══════════════════════════════════════════════════════════ -->
<main class="main-card page-content" id="pageConverter">
<!-- Mode Toggle 4 modes -->
<div class="mode-toggle">
<button id="btnOutboundBosch" class="mode-btn active" onclick="app.setMode('outbound-bosch')">
<i data-lucide="arrow-up-right"></i>
VDA 4913 → Bosch DESADV
</button>
<button id="btnOutboundZf" class="mode-btn" onclick="app.setMode('outbound-zf')">
<i data-lucide="arrow-up-right"></i>
VDA 4913 → ZF DESADV
</button>
<button id="btnOutboundIfm" class="mode-btn" onclick="app.setMode('outbound-ifm')">
<i data-lucide="arrow-up-right"></i>
VDA 4913 → IFM DELVRY03
</button>
<button id="btnInboundBosch" class="mode-btn" onclick="app.setMode('inbound-bosch')">
<i data-lucide="arrow-down-left"></i>
DELFOR → VDA 4905
</button>
<button id="btnInboundIfm" class="mode-btn" onclick="app.setMode('inbound-ifm')">
<i data-lucide="arrow-down-left"></i>
IFM DELFOR → VDA 4905
</button>
<button id="btnInboundInvrpt" class="mode-btn" onclick="app.setMode('inbound-invrpt')">
<i data-lucide="arrow-down-left"></i>
INVRPT → VDA 4913
</button>
<button id="btnValidateEdifact" class="mode-btn" onclick="app.setMode('validate-edifact')">
<i data-lucide="check-circle"></i>
EDIFACT Validieren
</button>
</div>
<!-- Drop Zone -->
<div id="dropZone" class="drop-zone">
<i data-lucide="upload-cloud"></i>
<h3>Datei hier ablegen oder klicken</h3>
<p id="dropText">VDA 4913 Datei auswählen für Konvertierung</p>
<input type="file" id="fileInput" class="hidden">
</div>
<!-- Enrichment Section (shown after VDA upload in outbound-bosch mode) -->
<div id="enrichmentSection" class="enrichment-section">
<!-- NAD Segment Editor -->
<div class="preview-header" style="margin-bottom: 20px;">
<h2>Partneradressen (NAD Segmente)</h2>
<span class="badge badge-edi" id="nadSourceBadge">Manuell</span>
</div>
<div class="nad-grid">
<!-- Buyer (BY) -->
<div class="nad-card">
<div class="nad-card-header"><span class="nad-qualifier">BY</span><span>Käufer (Buyer)</span>
</div>
<label>ID <input type="text" id="nad-by-id" class="nad-input" value="5060"></label>
<label>Qualifier <input type="text" id="nad-by-qual" class="nad-input" value="92"></label>
<label>Firma <input type="text" id="nad-by-name" class="nad-input wide"
value="Robert Bosch spol. s.r.o."></label>
<label>Firma 2 <input type="text" id="nad-by-name2" class="nad-input wide" value=""></label>
<label>Straße <input type="text" id="nad-by-street" class="nad-input wide"
value="Roberta Bosche 2678"></label>
<label>Stadt <input type="text" id="nad-by-city" class="nad-input"
value="Ceske Budejovicen"></label>
<label>PLZ <input type="text" id="nad-by-zip" class="nad-input" value="37004"></label>
<label>Land <input type="text" id="nad-by-country" class="nad-input" value="CZ"
maxlength="2"></label>
</div>
<!-- Seller (SE) -->
<div class="nad-card">
<div class="nad-card-header"><span class="nad-qualifier">SE</span><span>Lieferant
(Seller)</span></div>
<label>ID <input type="text" id="nad-se-id" class="nad-input" value="0000062671"></label>
<label>Qualifier <input type="text" id="nad-se-qual" class="nad-input" value="92"></label>
<label>Firma <input type="text" id="nad-se-name" class="nad-input wide"
value="Roechling Precision Components"></label>
<label>Firma 2 <input type="text" id="nad-se-name2" class="nad-input wide" value=""></label>
<label>Straße <input type="text" id="nad-se-street" class="nad-input wide"
value="Winter-Ring 3"></label>
<label>Stadt <input type="text" id="nad-se-city" class="nad-input" value="Weidenberg"></label>
<label>PLZ <input type="text" id="nad-se-zip" class="nad-input" value="95466"></label>
<label>Land <input type="text" id="nad-se-country" class="nad-input" value="DE"
maxlength="2"></label>
</div>
<!-- Ship-To (ST) -->
<div class="nad-card">
<div class="nad-card-header"><span class="nad-qualifier">ST</span><span>Warenempfänger
(Ship-To)</span></div>
<label>ID <input type="text" id="nad-st-id" class="nad-input" value="5060"></label>
<label>Qualifier <input type="text" id="nad-st-qual" class="nad-input" value="92"></label>
<label>Firma <input type="text" id="nad-st-name" class="nad-input wide"
value="Robert Bosch spol. s.r.o."></label>
<label>Firma 2 <input type="text" id="nad-st-name2" class="nad-input wide" value=""></label>
<label>Straße <input type="text" id="nad-st-street" class="nad-input wide"
value="Roberta Bosche 2678"></label>
<label>Stadt <input type="text" id="nad-st-city" class="nad-input"
value="Ceske Budejovicen"></label>
<label>PLZ <input type="text" id="nad-st-zip" class="nad-input" value="37004"></label>
<label>Land <input type="text" id="nad-st-country" class="nad-input" value="CZ"
maxlength="2"></label>
</div>
<!-- Ship-From (SF) -->
<div class="nad-card">
<div class="nad-card-header"><span class="nad-qualifier">SF</span><span>Versender
(Ship-From)</span></div>
<label>ID <input type="text" id="nad-sf-id" class="nad-input" value="0000062671"></label>
<label>Qualifier <input type="text" id="nad-sf-qual" class="nad-input" value="92"></label>
<label>Firma <input type="text" id="nad-sf-name" class="nad-input wide"
value="Roechling Precision Components"></label>
<label>Firma 2 <input type="text" id="nad-sf-name2" class="nad-input wide" value=""></label>
<label>Straße <input type="text" id="nad-sf-street" class="nad-input wide"
value="Winter-Ring 3"></label>
<label>Stadt <input type="text" id="nad-sf-city" class="nad-input" value="Weidenberg"></label>
<label>PLZ <input type="text" id="nad-sf-zip" class="nad-input" value="95466"></label>
<label>Land <input type="text" id="nad-sf-country" class="nad-input" value="DE"
maxlength="2"></label>
</div>
</div>
<!-- Material & Weight Enrichment -->
<div class="preview-header" style="margin-top: 40px;">
<h2>Positionen & Gewichte</h2>
<span class="badge badge-vda">VDA 4913</span>
</div>
<p class="subtitle">Artikel- und Packmittelgewichte können hier angepasst werden.</p>
<div class="table-container">
<table id="enrichmentTable">
<thead>
<tr>
<th>Kunden-Mat.</th>
<th>Lieferanten-Mat.</th>
<th>Menge</th>
<th>Einheit</th>
<th>Artikelgewicht (kg/Stk)</th>
<th>Status</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<!-- Packaging Weight & Dimensions Table -->
<div class="preview-header" style="margin-top: 30px;">
<h2>Packmittel (Gewichte & Maße)</h2>
</div>
<p class="subtitle">Alle Felder sind pflicht in DESADV. Fehlende Werte über Konfig-Datei ergänzen.</p>
<div class="table-container">
<table id="packagingTable">
<thead>
<tr>
<th>Packmittel (Kd)</th>
<th>Packmittel (Lief)</th>
<th>Anz.</th>
<th>Gewicht (kg)</th>
<th>Länge (cm)</th>
<th>Breite (cm)</th>
<th>Höhe (cm)</th>
<th>Status</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div style="margin-top: 30px; text-align: right;">
<button class="btn-primary" onclick="app.generateOutput()">
<i data-lucide="zap"></i>
JETZT KONVERTIEREN
</button>
</div>
</div>
<!-- Result Section -->
<div id="resultSection" class="result-section">
<!-- Stats Grid -->
<div id="stats-grid" class="stats-grid"></div>
<div class="preview-header">
<h2 id="resultTitle">Konvertierungsergebnis</h2>
<div class="viewer-actions">
<button class="btn-secondary" onclick="app.viewResult()">
<i data-lucide="eye"></i>
View
</button>
<button class="btn-secondary" onclick="app.editResult()">
<i data-lucide="edit-3"></i>
Edit
</button>
<button class="btn-primary" onclick="app.downloadResult()">
<i data-lucide="download"></i>
Download
</button>
</div>
</div>
<pre id="previewArea"></pre>
</div>
</main>
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- PAGE: SETTINGS -->
<!-- ═══════════════════════════════════════════════════════════ -->
<main class="main-card page-content" id="pageSettings" style="display:none">
<h2 class="settings-title">
<i data-lucide="folder-search"></i>
Ankommende Dateien (Folder Watch)
</h2>
<p class="subtitle" style="margin-bottom: 30px;">Überwacht einen Netzwerkordner auf neue Dateien,
konvertiert sie automatisch und schreibt die Ergebnisse in den Output-Ordner.</p>
<!-- General Settings & ID Mapping -->
<div class="log-section" style="margin-top: 40px;">
<h2 class="settings-title">
<i data-lucide="user-check"></i>
VDA 711 ID-Umschlüsselung
</h2>
<p class="subtitle" style="margin-bottom: 20px;">
Weisen Sie extrahierten IDs (Datenempfänger) eine eigene Kundennummer für den VDA 711 Header zu.
</p>
<div class="mapping-editor">
<div class="folder-input-row" style="margin-bottom: 20px;">
<input type="text" id="newIdMapOriginal" class="folder-path-input"
placeholder="Alt (z.B. 8810)" style="max-width: 200px;">
<input type="text" id="newIdMapTarget" class="folder-path-input"
placeholder="Neu (z.B. 10305)" style="max-width: 200px;">
<button class="btn-primary" onclick="app.addIdMapping711()">
<i data-lucide="plus"></i>
Hinzufügen
</button>
</div>
<div class="table-container">
<table id="idMapping711Table">
<thead>
<tr>
<th>Extrahierte ID (Alt)</th>
<th>Eigene ID (Neu)</th>
<th style="width: 100px;">Aktion</th>
</tr>
</thead>
<tbody>
<!-- Populated by JS -->
</tbody>
</table>
</div>
</div>
</div>
<!-- Electron notice -->
<div id="electronNotice" class="electron-notice" style="display:none">
<i data-lucide="alert-triangle"></i>
<span>Ordnerüberwachung ist nur in der Electron-App verfügbar. Bitte starten Sie die App mit
<code>npm start</code>.</span>
</div>
<!-- Folder Config -->
<div class="settings-grid">
<div class="settings-card">
<div class="settings-card-header">
<i data-lucide="folder-input"></i>
<span>Input-Ordner</span>
</div>
<div class="folder-input-row">
<input type="text" id="inputDirPath" class="folder-path-input"
placeholder="z.B. \\server\edi\input" readonly>
<button class="btn-secondary" id="btnSelectInput" onclick="app.selectInputFolder()">
<i data-lucide="folder-open"></i>
Wählen
</button>
</div>
</div>
<div class="settings-card">
<div class="settings-card-header">
<i data-lucide="folder-output"></i>
<span>Output-Ordner</span>
</div>
<div class="folder-input-row">
<input type="text" id="outputDirPath" class="folder-path-input"
placeholder="z.B. \\server\edi\output" readonly>
<button class="btn-secondary" id="btnSelectOutput" onclick="app.selectOutputFolder()">
<i data-lucide="folder-open"></i>
Wählen
</button>
</div>
</div>
</div>
<!-- Watcher Controls -->
<div class="watcher-controls">
<div class="watcher-status-display">
<span class="watcher-status-dot" id="watcherDot"></span>
<span id="watcherStatusText">Gestoppt</span>
</div>
<div class="watcher-buttons">
<button class="btn-primary btn-start" id="btnStartWatcher" onclick="app.startWatcher()">
<i data-lucide="play"></i>
Starten
</button>
<button class="btn-secondary btn-pause" id="btnPauseWatcher" onclick="app.pauseWatcher()" disabled>
<i data-lucide="pause"></i>
Pausieren
</button>
<button class="btn-secondary btn-resume" id="btnResumeWatcher" onclick="app.resumeWatcher()"
style="display:none">
<i data-lucide="play"></i>
Fortsetzen
</button>
<button class="btn-secondary btn-stop" id="btnStopWatcher" onclick="app.stopWatcher()" disabled>
<i data-lucide="square"></i>
Stoppen
</button>
</div>
</div>
<!-- Outbound Folder Config -->
<div class="log-section" style="margin-top: 40px;">
<h2 class="settings-title">
<i data-lucide="folder-search"></i>
Ausgehende Dateien (Folder Watch)
</h2>
<p class="subtitle" style="margin-bottom: 20px;">
Überwacht einen Netzwerkordner auf ausgehende Dateien, konvertiert sie automatisch und schreibt die Ergebnisse in den Output-Ordner.
</p>
<div class="settings-grid">
<div class="settings-card">
<div class="settings-card-header">
<i data-lucide="folder-input"></i>
<span>Input-Ordner (Ausgehend)</span>
</div>
<div class="folder-input-row">
<input type="text" id="outboundInputPath" class="folder-path-input"
placeholder="z.B. \\server\edi\outbound_in" readonly>
<button class="btn-secondary" onclick="app.selectOutboundInput()">
<i data-lucide="folder-open"></i>
Wählen
</button>
</div>
</div>
<div class="settings-card">
<div class="settings-card-header">
<i data-lucide="folder-output"></i>
<span>Output-Ordner (Ausgehend)</span>
</div>
<div class="folder-input-row">
<input type="text" id="outboundOutputPath" class="folder-path-input"
placeholder="z.B. \\server\edi\outbound_out" readonly>
<button class="btn-secondary" onclick="app.selectOutboundOutput()">
<i data-lucide="folder-open"></i>
Wählen
</button>
</div>
</div>
</div>
<div class="watcher-controls">
<div class="watcher-status-display">
<span class="watcher-status-dot" id="outboundWatcherDot"></span>
<span id="outboundWatcherStatusText">Gestoppt</span>
</div>
<div class="watcher-buttons">
<button class="btn-primary btn-start" id="btnStartOutboundWatcher"
onclick="app.startOutboundWatcher()">
<i data-lucide="play"></i>
Starten
</button>
<button class="btn-secondary btn-pause" id="btnPauseOutboundWatcher"
onclick="app.pauseOutboundWatcher()" disabled>
<i data-lucide="pause"></i>
Pausieren
</button>
<button class="btn-secondary btn-resume" id="btnResumeOutboundWatcher"
onclick="app.resumeOutboundWatcher()" style="display:none">
<i data-lucide="play"></i>
Fortsetzen
</button>
<button class="btn-secondary btn-stop" id="btnStopOutboundWatcher" onclick="app.stopOutboundWatcher()"
disabled>
<i data-lucide="square"></i>
Stoppen
</button>
</div>
</div>
</div>
<!-- Werksnummer Watcher Controls (New Section) -->
<div class="log-section" style="margin-top: 40px;">
<h2 class="settings-title">
<i data-lucide="file-text"></i>
Werksnummer Umbenennung
</h2>
<p class="subtitle" style="margin-bottom: 20px;">
Überwacht VDA-Dateien (RA_VDA*) und benennt sie basierend auf der Werksnummer in Satzart 512 um
(100 → LEIFERS, 280 → PITESTI).
</p>
<div class="settings-grid">
<div class="settings-card">
<div class="settings-card-header">
<i data-lucide="folder-input"></i>
<span>Input-Ordner (Werksnummer)</span>
</div>
<div class="folder-input-row">
<input type="text" id="werksInputPath" class="folder-path-input"
placeholder="Input für Umbenennung" readonly>
<button class="btn-secondary" onclick="app.selectWerksInput()">
<i data-lucide="folder-open"></i>
Wählen
</button>
</div>
</div>
<div class="settings-card">
<div class="settings-card-header">
<i data-lucide="folder-output"></i>
<span>Output-Ordner (Werksnummer)</span>
</div>
<div class="folder-input-row">
<input type="text" id="werksOutputPath" class="folder-path-input"
placeholder="Output für Umbenennung" readonly>
<button class="btn-secondary" onclick="app.selectWerksOutput()">
<i data-lucide="folder-open"></i>
Wählen
</button>
</div>
</div>
</div>
<div class="watcher-controls">
<div class="watcher-status-display">
<span class="watcher-status-dot" id="werksWatcherDot"></span>
<span id="werksWatcherStatusText">Gestoppt</span>
</div>
<div class="watcher-buttons">
<button class="btn-primary btn-start" id="btnStartWerksWatcher"
onclick="app.startWerksWatcher()">
<i data-lucide="play"></i>
Starten
</button>
<button class="btn-secondary btn-pause" id="btnPauseWerksWatcher"
onclick="app.pauseWerksWatcher()" disabled>
<i data-lucide="pause"></i>
Pausieren
</button>
<button class="btn-secondary btn-resume" id="btnResumeWerksWatcher"
onclick="app.resumeWerksWatcher()" style="display:none">
<i data-lucide="play"></i>
Fortsetzen
</button>
<button class="btn-secondary btn-stop" id="btnStopWerksWatcher" onclick="app.stopWerksWatcher()"
disabled>
<i data-lucide="square"></i>
Stoppen
</button>
</div>
</div>
</div>
<!-- Customer Mappings -->
<div class="log-section" style="margin-top: 40px;">
<div class="preview-header">
<h2>
<i data-lucide="map"></i>
Kundennummern-Zuordnung
</h2>
</div>
<p class="subtitle" style="margin-bottom: 20px;">Weisen Sie Kundennummern automatisch einer
Konvertierung zu.</p>
<div class="mapping-editor">
<div class="folder-input-row" style="margin-bottom: 20px;">
<input type="text" id="newMappingId" class="folder-path-input"
placeholder="Kundennummer (z.B. 5060)" style="max-width: 200px;">
<select id="newMappingMode" class="folder-path-input" style="max-width: 250px;">
<option value="outbound-bosch">VDA 4913 → Bosch DESADV</option>
<option value="outbound-zf">VDA 4913 → ZF DESADV</option>
<option value="outbound-ifm">VDA 4913 → IFM DELVRY03</option>
<option value="inbound-bosch">DELFOR → VDA 4905</option>
<option value="inbound-ifm">IFM DELFOR → VDA 4905</option>
<option value="inbound-invrpt">INVRPT → VDA 4913</option>
<option value="validate-edifact">EDIFACT Validieren</option>
</select>
<button class="btn-primary" onclick="app.addMapping()">
<i data-lucide="plus"></i>
Hinzufügen
</button>
</div>
<div class="table-container">
<table id="mappingTable">
<thead>
<tr>
<th>Kundennummer</th>
<th>Konvertierungs-Modus</th>
<th style="width: 100px;">Aktion</th>
</tr>
</thead>
<tbody>
<!-- Will be populated by JS -->
</tbody>
</table>
</div>
</div>
</div>
<!-- Conversion Log -->
<div class="log-section">
<div class="preview-header">
<h2>Konvertierungs-Log</h2>
<button class="btn-secondary" onclick="app.clearLog()">
<i data-lucide="trash-2"></i>
Leeren
</button>
</div>
<div class="log-container" id="logContainer">
<div class="log-empty">Noch keine Aktivitäten.</div>
</div>
</div>
</main>
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- PAGE: VIEWER -->
<!-- ═══════════════════════════════════════════════════════════ -->
<main class="main-card page-content" id="pageViewer" style="display:none">
<div class="preview-header no-print">
<h2>EDI Dokument Viewer</h2>
<div class="viewer-actions">
<button class="btn-secondary" onclick="app.viewer.reset()" id="btnViewerBack" style="display:none">
<i data-lucide="arrow-left"></i>
Zurück
</button>
<button class="btn-primary" onclick="app.viewer.printDocument()" id="btnViewerPrint"
style="display:none">
<i data-lucide="printer"></i>
Als PDF speichern / Drucken
</button>
</div>
</div>
<div id="viewerDropZone" class="drop-zone no-print">
<i data-lucide="file-search"></i>
<h3>Datei hier ablegen oder klicken zur Anzeige</h3>
<p id="viewerDropText">Unterstützt DELFOR und VDA 4905/4913 Dateien</p>
<input type="file" id="viewerFileInput" class="hidden">
</div>
<!-- This container will hold the rendered HTML document -->
<div id="viewerDocumentRender" class="document-render-area">
<!-- Content injected by JS -->
</div>
</main>
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- PAGE: EDITOR -->
<!-- ═══════════════════════════════════════════════════════════ -->
<main class="main-card page-content" id="pageEditor" style="display:none">
<div class="preview-header no-print">
<h2>EDI Dokument Editor</h2>
<div class="viewer-actions">
<button class="btn-secondary" onclick="app.editor.reset()" id="btnEditorBack" style="display:none">
<i data-lucide="arrow-left"></i>
Zurück
</button>
<button class="btn-primary" onclick="app.editor.downloadDocument()" id="btnEditorDownload"
style="display:none">
<i data-lucide="download"></i>
Speichern / Download
</button>
</div>
</div>
<div id="editorDropZone" class="drop-zone no-print">
<i data-lucide="edit"></i>
<h3>EDI Datei hier ablegen oder klicken zur Bearbeitung</h3>
<p id="editorDropText">Unterstützt EDIFACT und VDA Dateien</p>
<input type="file" id="editorFileInput" class="hidden">
</div>
<!-- This container will hold the editable segments -->
<div id="editorDocumentRender" class="editor-render-area" style="display:none;">
<!-- Content injected by JS -->
</div>
</main>
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- PAGE: HISTORY -->
<!-- ═══════════════════════════════════════════════════════════ -->
<main class="main-card page-content" id="pageHistory" style="display:none">
<h2 class="settings-title">
<i data-lucide="database"></i>
Konvertierungs-Historie
</h2>
<p class="subtitle" style="margin-bottom: 20px;">Vollständige Nachverfolgung aller durchgeführten
Konvertierungen.</p>
<!-- Stats -->
<div class="stats-grid" id="historyStats">
<div class="stat-card">
<div class="stat-value">-</div>
<div class="stat-label">Gesamt</div>
</div>
<div class="stat-card">
<div class="stat-value">-</div>
<div class="stat-label">Erfolgreich</div>
</div>
<div class="stat-card">
<div class="stat-value">-</div>
<div class="stat-label">Fehlerhaft</div>
</div>
<div class="stat-card">
<div class="stat-value">-</div>
<div class="stat-label">Heute</div>
</div>
</div>
<!-- Filter Bar -->
<div class="history-filter-bar">
<div class="history-filter-buttons">
<button class="btn-secondary history-filter-btn active" data-filter="ALL"
onclick="app.historyManager.setFilter('ALL')">
Alle
</button>
<button class="btn-secondary history-filter-btn" data-filter="ERFOLGREICH"
onclick="app.historyManager.setFilter('ERFOLGREICH')">
✅ Erfolgreich
</button>
<button class="btn-secondary history-filter-btn" data-filter="FEHLERHAFT"
onclick="app.historyManager.setFilter('FEHLERHAFT')">
❌ Fehlerhaft
</button>
</div>
<div class="history-search-row">
<input type="text" id="historySearch" class="folder-path-input"
placeholder="🔍 Suche nach Dateiname, Kunden-ID..."
oninput="app.historyManager.onSearch(this.value)" style="max-width:350px;">
<button class="btn-secondary" onclick="app.historyManager.exportCSV()">
<i data-lucide="download" style="width:14px;height:14px;"></i> CSV Export
</button>
</div>
</div>
<!-- Table -->
<div class="history-table-wrapper">
<table class="history-table">
<thead>
<tr>
<th style="width:50px;">ID</th>
<th style="width:140px;">Zeitstempel</th>
<th>Dateiname</th>
<th style="width:180px;">Modus</th>
<th style="width:90px;">Status</th>
<th style="width:50px;"></th>
</tr>
</thead>
<tbody id="historyTableBody">
<tr>
<td colspan="6"
style="text-align:center; padding:40px; color: var(--text-dim); font-style:italic;">Lade
Daten...</td>
</tr>
</tbody>
</table>
</div>
<!-- Pagination -->
<div class="history-pagination" id="historyPagination"></div>
</main>
<!-- History Detail Modal -->
<div id="historyDetailModal" class="history-detail-modal" style="display:none;">
<div class="history-detail-modal-content">
<div id="historyDetailContent"></div>
</div>
</div>
</div>
<!-- SCRIPTS -->
<script src="js/vda-parser.js"></script>
<script src="js/edifact-logic.js"></script>
<script src="js/config-parser.js"></script>
<script src="js/vda4913-to-desadv.js"></script>
<script src="js/vda4913-to-desadv-zf.js"></script>
<script src="js/vda4913-to-delvry03.js"></script>
<script src="js/delfor-parser.js"></script>
<script src="js/vda4905-generator.js"></script>
<script src="js/ifm_delfor-vda4905.js"></script>
<script src="js/invrpt-to-vda4913.js"></script>
<script src="js/watcher-bridge.js"></script>
<script src="js/outbound-watcher-bridge.js"></script>
<script src="js/werks-watcher-bridge.js"></script>
<script src="js/viewer.js"></script>
<script src="js/editor.js"></script>
<script src="js/history.js"></script>
<script src="js/app.js"></script>
<script>
// Init App safely
try {
window.app = new window.EDIBridge.App();
if (window.lucide) {
try { lucide.createIcons(); } catch (e) { console.warn("Lucide Error", e); }
}
} catch (e) {
console.error("App Fatal Error:", e);
alert("App Fatal Error: " + e.message);
}
</script>
</body>
</html>