Feature: Beleg-Vorschau als Split-Panel statt Tooltip in Bank-Zuordnung

This commit is contained in:
fds2610-bot 2026-05-14 20:21:29 +02:00
parent 99aa823d0f
commit b4967a9f18

View file

@ -81,116 +81,105 @@ $vorschauHoehe = (int)($settings['beleg_vorschau_hoehe'] ?? 300);
</div> </div>
</div> </div>
<!-- Offene Belege verknüpfen --> <!-- Offene Belege + Vorschau nebeneinander -->
<div class="card"> <div style="display:flex;gap:1rem;align-items:flex-start">
<div class="card-header">
<div class="card-title">Offene Belege</div>
<span class="text-muted text-sm"><?= count($offeneBelege) ?> ungebuchte Belege</span>
</div>
<?php if (empty($offeneBelege)): ?>
<div class="card-body text-muted">Keine offenen Belege vorhanden.</div>
<?php else: ?>
<div class="table-wrap">
<table>
<thead>
<tr>
<th>Belegnr.</th>
<th>Datum</th>
<th>Typ</th>
<th>Lieferant / Notiz</th>
<th class="td-right">Brutto</th>
<th></th>
</tr>
</thead>
<tbody>
<?php foreach ($offeneBelege as $b): ?>
<tr>
<td class="td-mono">
<a href="/belege/<?= (int)$b['id'] ?>" target="_blank"
class="beleg-preview-trigger"
data-beleg-id="<?= (int)$b['id'] ?>"><?= $h($b['beleg_nr']) ?></a>
</td>
<td class="td-mono"><?= $h(View::formatDate($b['beleg_datum'])) ?></td>
<td><span class="badge badge-gray"><?= $h($b['belegtyp']) ?></span></td>
<td>
<?= $b['supplier_name'] ? $h($b['supplier_name']) : '<span class="text-muted">–</span>' ?>
<?php if ($b['notes']): ?>
<span class="text-muted text-sm"> · <?= $h(mb_substr($b['notes'], 0, 40)) ?></span>
<?php endif; ?>
</td>
<td class="td-right td-mono">
<?= $b['betrag_brutto'] ? $fmt($b['betrag_brutto']) : '<span class="text-muted">–</span>' ?>
</td>
<td>
<form method="post" action="/bank/<?= (int)$transaction['id'] ?>/link" style="display:inline">
<input type="hidden" name="beleg_id" value="<?= (int)$b['id'] ?>">
<button type="submit" class="btn btn-primary btn-sm">Verknüpfen</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
<!-- Beleg-Vorschau Tooltip --> <!-- Linke Hälfte: Tabelle -->
<div id="beleg-tooltip" style=" <div class="card" style="flex:1;min-width:0">
display:none; <div class="card-header">
position:fixed; <div class="card-title">Offene Belege</div>
z-index:9999; <span class="text-muted text-sm"><?= count($offeneBelege) ?> ungebuchte Belege</span>
pointer-events:none; </div>
border:1px solid var(--color-border,#e2e8f0); <?php if (empty($offeneBelege)): ?>
border-radius:var(--radius,6px); <div class="card-body text-muted">Keine offenen Belege vorhanden.</div>
background:#fff; <?php else: ?>
box-shadow:0 4px 20px rgba(0,0,0,.18); <div class="table-wrap">
overflow:hidden; <table>
width:<?= $vorschauBreite ?>px; <thead>
height:<?= $vorschauHoehe ?>px; <tr>
"></div> <th>Belegnr.</th>
<th>Datum</th>
<th>Typ</th>
<th>Lieferant</th>
<th class="td-right">Brutto</th>
<th></th>
</tr>
</thead>
<tbody>
<?php foreach ($offeneBelege as $b): ?>
<tr class="beleg-row"
data-beleg-id="<?= (int)$b['id'] ?>"
style="cursor:pointer"
title="Klicken zum Vorschau anzeigen">
<td class="td-mono" onclick="event.stopPropagation()">
<a href="/belege/<?= (int)$b['id'] ?>" target="_blank"><?= $h($b['beleg_nr']) ?></a>
</td>
<td class="td-mono"><?= $h(View::formatDate($b['beleg_datum'])) ?></td>
<td><span class="badge badge-gray"><?= $h($b['belegtyp']) ?></span></td>
<td>
<?= $b['supplier_name'] ? $h($b['supplier_name']) : '<span class="text-muted">–</span>' ?>
</td>
<td class="td-right td-mono">
<?= $b['betrag_brutto'] ? $fmt($b['betrag_brutto']) : '<span class="text-muted">–</span>' ?>
</td>
<td onclick="event.stopPropagation()">
<form method="post" action="/bank/<?= (int)$transaction['id'] ?>/link" style="display:inline">
<input type="hidden" name="beleg_id" value="<?= (int)$b['id'] ?>">
<button type="submit" class="btn btn-primary btn-sm">Verknüpfen</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
<!-- Rechte Hälfte: Vorschau-Panel -->
<div id="beleg-preview-panel" style="
flex:1;
min-width:0;
position:sticky;
top:1rem;
border:1px solid var(--color-border,#e2e8f0);
border-radius:var(--radius,6px);
background:var(--color-surface,#f8fafc);
overflow:hidden;
height:<?= $vorschauHoehe ?>px;
display:flex;
align-items:center;
justify-content:center;
">
<span class="text-muted text-sm" id="beleg-preview-hint">Zeile anklicken für Vorschau</span>
<iframe id="beleg-preview-frame"
style="display:none;width:100%;height:100%;border:none"
src=""></iframe>
</div>
</div>
<script> <script>
(function () { (function () {
const tooltip = document.getElementById('beleg-tooltip'); const frame = document.getElementById('beleg-preview-frame');
const W = <?= $vorschauBreite ?>; const hint = document.getElementById('beleg-preview-hint');
const H = <?= $vorschauHoehe ?>; let activeRow = null;
let currentId = null;
let timer = null;
document.querySelectorAll('.beleg-preview-trigger').forEach(function (link) { document.querySelectorAll('.beleg-row').forEach(function (row) {
link.addEventListener('mouseenter', function (e) { row.addEventListener('click', function () {
const id = link.dataset.belegId; const id = row.dataset.belegId;
if (!id) return; if (!id) return;
timer = setTimeout(function () { // Hervorhebung wechseln
if (currentId !== id) { if (activeRow) activeRow.style.background = '';
currentId = id; activeRow = row;
tooltip.innerHTML = '<iframe src="/belege/' + id + '/file" style="width:100%;height:100%;border:none" loading="lazy"></iframe>'; row.style.background = 'var(--color-primary-light, #eff6ff)';
}
positionTooltip(e);
tooltip.style.display = 'block';
}, 120);
});
link.addEventListener('mousemove', positionTooltip); // Vorschau laden
hint.style.display = 'none';
link.addEventListener('mouseleave', function () { frame.style.display = 'block';
clearTimeout(timer); frame.src = '/belege/' + id + '/file';
tooltip.style.display = 'none';
}); });
}); });
function positionTooltip(e) {
const margin = 12;
let x = e.clientX + margin;
let y = e.clientY + margin;
if (x + W > window.innerWidth - margin) x = e.clientX - W - margin;
if (y + H > window.innerHeight - margin) y = e.clientY - H - margin;
tooltip.style.left = Math.max(0, x) + 'px';
tooltip.style.top = Math.max(0, y) + 'px';
}
})(); })();
</script> </script>