/**
* HistoryManager – Frontend for conversion history
* Renders paginated table, detail view, stats, and filters.
*/
window.EDIBridge = window.EDIBridge || {};
class HistoryManager {
constructor(app) {
this.app = app;
this.currentPage = 1;
this.pageSize = 20;
this.statusFilter = 'ALL';
this.dateFilter = 'ALL';
this.searchTerm = '';
this.totalRows = 0;
}
/**
* Called when the History page becomes visible.
*/
async activate() {
await this.loadStats();
await this.loadTable();
}
/**
* Load and render statistics cards.
*/
async loadStats() {
if (!window.electronAPI) return;
const stats = await window.electronAPI.dbGetStats();
const container = document.getElementById('historyStats');
if (!container) return;
container.innerHTML = `
| ${row.id} |
${ts} |
${this._escapeHtml(row.dateiname)}
${row.ausgangsdateiname ? `→ ${this._escapeHtml(row.ausgangsdateiname)} ` : ''}
|
${modus} |
${statusIcon} ${source} |
|
`;
}).join('');
}
if (pagination) {
pagination.innerHTML = `
Zeitstempel
${this._formatTimestamp(record.zeitstempel)}
Status
${statusBadge}
Eingangsdatei
${this._escapeHtml(record.dateiname)}
Ausgangsdatei
${this._escapeHtml(record.ausgangsdateiname || '-')}
Quellformat
${this._escapeHtml(record.quellformat || '-')}
Zielformat
${this._escapeHtml(record.zielformat || '-')}
Konvertierungsmodus
${this._escapeHtml(record.konvertierungsmodus || '-')}
Kunden-ID
${this._escapeHtml(record.kunden_id || '-')}
Quelle
${record.quelle === 'WATCHER' ? '🤖 Automatisch (Watcher)' : '👤 Manuell (GUI)'}
${record.fehlermeldung ? `
${this._escapeHtml(record.eingang_daten || 'Keine Eingangsdaten gespeichert.')}
${this._escapeHtml(record.ausgang_daten || 'Keine Ausgangsdaten gespeichert.')}
`;
modal.style.display = 'flex';
if (window.lucide) {
try { lucide.createIcons(); } catch (e) { }
}
}
switchTab(tab) {
const eingang = document.getElementById('historyTabEingang');
const ausgang = document.getElementById('historyTabAusgang');
const buttons = document.querySelectorAll('.history-tab-btn');
buttons.forEach(btn => {
btn.classList.toggle('active', btn.dataset.tab === tab);
});
if (tab === 'eingang') {
if (eingang) eingang.style.display = 'block';
if (ausgang) ausgang.style.display = 'none';
} else {
if (eingang) eingang.style.display = 'none';
if (ausgang) ausgang.style.display = 'block';
}
}
async openInViewer(id) {
const record = await window.electronAPI.dbGetById(id);
if (!record || !record.ausgang_daten) return;
this.closeDetail();
// Switch to viewer page and process the content
if (this.app) {
this.app.showPage('viewer');
if (this.app.viewer) {
this.app.viewer.processContent(record.ausgang_daten);
}
}
}
closeDetail() {
const modal = document.getElementById('historyDetailModal');
if (modal) modal.style.display = 'none';
}
async deleteEntry(id) {
if (!confirm('Eintrag wirklich löschen?')) return;
await window.electronAPI.dbDelete(id);
await this.loadStats();
await this.loadTable();
}
goToPage(page) {
if (page < 1) return;
this.currentPage = page;
this.loadTable();
}
setFilter(status) {
this.statusFilter = status;
this.dateFilter = 'ALL';
this.searchTerm = ''; // Clear search when picking a card
this.currentPage = 1;
// Reset search input
const searchInput = document.getElementById('historySearch');
if (searchInput) searchInput.value = '';
// Update active button state
document.querySelectorAll('.history-filter-btn').forEach(btn => {
btn.classList.toggle('active', btn.dataset.filter === status);
});
this.loadStats();
this.loadTable();
}
setDateFilter(dateType) {
this.dateFilter = dateType;
this.statusFilter = 'ALL'; // Reset status when picking date
this.searchTerm = ''; // Clear search when picking a card
this.currentPage = 1;
// Reset filter bar buttons
document.querySelectorAll('.history-filter-btn').forEach(btn => {
btn.classList.toggle('active', false);
});
// Reset search input
const searchInput = document.getElementById('historySearch');
if (searchInput) searchInput.value = '';
this.loadStats();
this.loadTable();
}
onSearch(value) {
this.searchTerm = value;
this.currentPage = 1;
// Debounce
clearTimeout(this._searchTimer);
this._searchTimer = setTimeout(() => this.loadTable(), 300);
}
async exportCSV() {
if (!window.electronAPI) return;
// Fetch all rows (no pagination)
const result = await window.electronAPI.dbGetAll({
limit: 99999,
offset: 0,
statusFilter: this.statusFilter,
search: this.searchTerm
});
if (!result.rows || result.rows.length === 0) {
alert('Keine Daten zum Exportieren.');
return;
}
const headers = ['ID', 'Zeitstempel', 'Dateiname', 'Ausgangsdatei', 'Quellformat', 'Zielformat', 'Modus', 'Kunden-ID', 'Status', 'Fehlermeldung', 'Quelle'];
const csvRows = [headers.join(';')];
result.rows.forEach(row => {
csvRows.push([
row.id,
row.zeitstempel,
`"${(row.dateiname || '').replace(/"/g, '""')}"`,
`"${(row.ausgangsdateiname || '').replace(/"/g, '""')}"`,
row.quellformat || '',
row.zielformat || '',
row.konvertierungsmodus || '',
row.kunden_id || '',
row.status,
`"${(row.fehlermeldung || '').replace(/"/g, '""')}"`,
row.quelle
].join(';'));
});
const csv = csvRows.join('\n');
const blob = new Blob(['\ufeff' + csv], { type: 'text/csv;charset=utf-8;' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `konvertierungen_${new Date().toISOString().slice(0, 10)}.csv`;
a.click();
URL.revokeObjectURL(url);
}
// ─── Helpers ─────────────────────────────────────────────────────
_formatTimestamp(ts) {
if (!ts) return '-';
try {
const d = new Date(ts.replace(' ', 'T'));
return d.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })
+ ' ' + d.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit', second: '2-digit' });
} catch (e) {
return ts;
}
}
_shortModus(modus, quellformat, zielformat) {
if (quellformat && zielformat) {
// Shorten for display
const qf = quellformat.replace('EDIFACT ', '').replace('D04A', '').trim();
const zf = zielformat.replace('EDIFACT ', '').trim();
return `