fix: Layout-Selector für Mehrfach-Übernahme aus Anhänge-Liste
All checks were successful
Deploy bericht / deploy (push) Successful in 1s

Der Layout-Dropdown in der Toolbar bezog sich nur auf die aktuell
angezeigte Seite, nicht auf die Übernahme-Aktion. Ergebnis: User
stellten 2x2 ein, kreuzten 4 Bilder an, klickten 'Übernehmen' — und
bekamen 4 einzelne Seiten statt einer Grid-Seite.

Fix: Neben dem Übernahme-Button eigener Layout-Selector mit Optionen
Einzeln / 2 / 2v / 4 / 6 / Vorher-Nachher. Bei Grid-Layout werden
die ausgewählten Bilder automatisch in Gruppen à slotCount aufgeteilt
und entsprechend viele Seiten angelegt (z.B. 10 Bilder + grid_4 = 3
Seiten mit 4+4+2). Die einzelnen ▭▭/▦/VN-Buttons entfallen damit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
[deploy]
This commit is contained in:
Eduard Wisch 2026-04-09 13:31:26 +02:00
parent f55da13234
commit bf1ad1bafa
2 changed files with 51 additions and 43 deletions

View file

@ -402,14 +402,17 @@ if (!$bericht) {
}
print '</div>';
}
print '<button type="button" id="btn-add-selected" class="butAction" title="Jedes ausgewählte Bild als eigene Seite">'.$langs->trans("BerichtAddSelectedToReport").'</button>';
print '<div class="bericht-grid-buttons" style="margin-top:6px;">';
print '<span class="opacitymedium small">Mehrere Bilder als Grid:</span><br>';
print '<button type="button" class="btn-add-grid" data-layout="grid_2" title="2 Bilder (oben/unten)">▭▭</button> ';
print '<button type="button" class="btn-add-grid" data-layout="grid_2v" title="2 Bilder (links/rechts)">▯▯</button> ';
print '<button type="button" class="btn-add-grid" data-layout="grid_4" title="2x2 Grid">▦</button> ';
print '<button type="button" class="btn-add-grid" data-layout="grid_6" title="3x2 Grid">▦▦</button>';
print ' <button type="button" class="btn-add-grid" data-layout="before_after" title="Vorher / Nachher (2 Bilder)">VN</button>';
print '<div class="bericht-add-selected" style="margin-top:6px;">';
print '<label class="opacitymedium small" style="display:block;margin-bottom:4px;">Layout für die Auswahl:</label>';
print '<select id="add-selected-layout" style="width:100%;margin-bottom:6px;">';
print '<option value="single">Einzeln (1 Bild pro Seite)</option>';
print '<option value="grid_2">2 pro Seite (oben/unten)</option>';
print '<option value="grid_2v">2 pro Seite (links/rechts)</option>';
print '<option value="grid_4">4 pro Seite (2x2)</option>';
print '<option value="grid_6">6 pro Seite (3x2)</option>';
print '<option value="before_after">Vorher / Nachher (2 pro Seite)</option>';
print '</select>';
print '<button type="button" id="btn-add-selected" class="butAction" style="width:100%;" title="Alle ausgewählten Bilder mit dem gewählten Layout in den Bericht übernehmen">'.$langs->trans("BerichtAddSelectedToReport").'</button>';
print '</div>';
}
print '<hr>';

View file

@ -814,9 +814,18 @@
/* ---------- Anhänge & Thumbs ---------- */
function bindAttachments() {
const btn = document.getElementById('btn-add-selected');
const layoutSel = document.getElementById('add-selected-layout');
if (btn) {
btn.addEventListener('click', async () => {
const checks = document.querySelectorAll('.att-check:checked');
if (!checks.length) {
alert('Bitte zuerst Bilder ankreuzen');
return;
}
const layout = layoutSel ? layoutSel.value : 'single';
if (layout === 'single') {
// Wie bisher: jedes Bild als eigene Seite
for (const c of checks) {
const fd = new FormData();
fd.append('token', cfg.token);
@ -827,38 +836,34 @@
c.checked = false;
}
location.reload();
});
return;
}
// Grid-Buttons: ausgewählte Bilder als eine Multi-Image-Seite hinzufügen
document.querySelectorAll('.btn-add-grid').forEach(b => {
b.addEventListener('click', async () => {
const layout = b.dataset.layout;
const checks = document.querySelectorAll('.att-check:checked');
if (!checks.length) {
alert('Bitte zuerst Bilder ankreuzen');
return;
}
const slotCount = { grid_2: 2, grid_2v: 2, grid_4: 4, grid_6: 6 }[layout] || 4;
const relpaths = Array.from(checks)
.filter(c => c.dataset.mime.startsWith('image'))
.slice(0, slotCount)
.map(c => c.dataset.relpath);
if (!relpaths.length) {
alert('Bitte mindestens ein Bild ankreuzen (PDFs sind in Grids nicht unterstützt)');
// Grid-Layout: in Gruppen aufteilen
const slotCount = { grid_2: 2, grid_2v: 2, grid_4: 4, grid_6: 6, before_after: 2 }[layout] || 4;
const imageChecks = Array.from(checks).filter(c => c.dataset.mime.startsWith('image'));
if (!imageChecks.length) {
alert('Bitte mindestens ein Bild ankreuzen (PDFs nicht in Grids unterstützt)');
return;
}
// In Gruppen à slotCount aufteilen
for (let i = 0; i < imageChecks.length; i += slotCount) {
const group = imageChecks.slice(i, i + slotCount).map(c => c.dataset.relpath);
const fd = new FormData();
fd.append('token', cfg.token);
fd.append('berichtid', cfg.berichtid);
fd.append('layout', layout);
fd.append('relpaths', JSON.stringify(relpaths));
fd.append('relpaths', JSON.stringify(group));
const r = await fetch(cfg.urls.create_grid_page, { method: 'POST', body: fd });
const data = await r.json().catch(() => ({}));
if (data.success) location.reload();
else alert('Fehler: ' + (data.error || 'unbekannt'));
});
if (!data.success) {
alert('Fehler bei Gruppe '+(Math.floor(i/slotCount)+1)+': '+(data.error || 'unbekannt'));
return;
}
}
location.reload();
});
}
// Lösch-Buttons in der Anhänge-Liste
document.querySelectorAll('.att-delete').forEach(btn => {