PWA: PDF-Download über API (Content-Disposition, kein Dialog) [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 5s

This commit is contained in:
Eddy 2026-04-17 12:56:22 +02:00
parent 0294509ee5
commit e579523020

19
app.js
View file

@ -458,7 +458,7 @@ router.on('/orders/:id', async (args) => {
const res = await api.getFileBlobUrl(rel); const res = await api.getFileBlobUrl(rel);
el.classList.remove('loading'); el.classList.remove('loading');
if (!res) { showToast('Datei konnte nicht geladen werden', 'error'); return; } if (!res) { showToast('Datei konnte nicht geladen werden', 'error'); return; }
openFileViewer(res, filename); openFileViewer(res, filename, rel);
}); });
}); });
@ -1792,12 +1792,12 @@ function formatShortDate(ts) {
return d.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: '2-digit' }); return d.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: '2-digit' });
} }
function openFileViewer({ url, blob, mime }, filename) { function openFileViewer({ url, blob, mime }, filename, relpath) {
const isImage = (mime || '').startsWith('image/'); const isImage = (mime || '').startsWith('image/');
const isPdf = (mime || '').includes('pdf') || /\.pdf$/i.test(filename); const isPdf = (mime || '').includes('pdf') || /\.pdf$/i.test(filename);
if (isPdf && typeof pdfjs !== 'undefined') { if (isPdf && typeof pdfjs !== 'undefined') {
openPdfViewer(blob, filename, url); openPdfViewer(blob, filename, relpath);
return; return;
} }
@ -1833,7 +1833,7 @@ function openFileViewer({ url, blob, mime }, filename) {
modal.querySelector('#dv-close').onclick = cleanup; modal.querySelector('#dv-close').onclick = cleanup;
} }
async function openPdfViewer(blob, filename, blobUrl) { async function openPdfViewer(blob, filename, relpath) {
const modal = document.createElement('div'); const modal = document.createElement('div');
modal.className = 'fullscreen-modal pdf-viewer-modal'; modal.className = 'fullscreen-modal pdf-viewer-modal';
modal.innerHTML = ` modal.innerHTML = `
@ -1874,11 +1874,11 @@ async function openPdfViewer(blob, filename, blobUrl) {
await renderPage(1); await renderPage(1);
modal.querySelector('#pdf-prev').onclick = () => renderPage(currentPage - 1); modal.querySelector('#pdf-prev').onclick = () => renderPage(currentPage - 1);
modal.querySelector('#pdf-next').onclick = () => renderPage(currentPage + 1); modal.querySelector('#pdf-next').onclick = () => renderPage(currentPage + 1);
modal.querySelector('#pdf-download').onclick = () => { modal.querySelector('#pdf-download').onclick = async () => {
const a = document.createElement('a'); // Download über API mit Content-Disposition: attachment (kein Dialog-Spam)
a.href = blobUrl; const t = await api.getToken();
a.download = filename || 'download.pdf'; const params = new URLSearchParams({ relpath, jwt: t, download: 1 });
a.click(); window.location.href = window.location.origin + '/custom/bericht/api/photo.php?' + params.toString();
}; };
modal.querySelector('#pdf-prev').disabled = false; modal.querySelector('#pdf-prev').disabled = false;
modal.querySelector('#pdf-next').disabled = pdf.numPages === 1; modal.querySelector('#pdf-next').disabled = pdf.numPages === 1;
@ -1888,7 +1888,6 @@ async function openPdfViewer(blob, filename, blobUrl) {
} }
modal.querySelector('#pdf-close').onclick = () => { modal.querySelector('#pdf-close').onclick = () => {
URL.revokeObjectURL(blobUrl);
modal.remove(); modal.remove();
}; };
} }