Produktion: Inline-PDF/Bild-Vorschau im Dateien-Dialog (kein Download noetig)

This commit is contained in:
Lucas Orth
2026-08-27 08:49:46 +02:00
parent 41459ddd9e
commit 939f7f13c6

View File

@@ -165,7 +165,9 @@ const Board = defineComponent({
const expandedCharges = ref(new Set());
const bulk = reactive({ open: false, mode: 'queue', gruppen: [], msg: '', err: '' });
// Vom Kunden hochgeladene Original-Dokumente (kein generiertes SVG).
const dateien = reactive({ open: false, order: null, items: [], laden: false, err: '' });
const dateien = reactive({ open: false, order: null, items: [], laden: false, err: '',
// Inline-Vorschau der gewählten Datei (Blob-URL, authentifiziert geladen).
pvId: null, pvUrl: '', pvType: '', pvLaden: false, pvErr: '' });
// ── Laden ──
// Basis-Felder ohne die evtl. noch nicht gebootstrapten Felder – diese
@@ -661,6 +663,7 @@ const Board = defineComponent({
const orderDateiIds = (o) => (Array.isArray(o.source_files) && o.source_files.length)
? o.source_files : (o.source_file ? [o.source_file] : []);
async function openDateien(order) {
pvClear();
dateien.open = true; dateien.order = order; dateien.items = []; dateien.err = ''; dateien.laden = true;
try {
const items = [];
@@ -684,6 +687,22 @@ const Board = defineComponent({
setTimeout(() => URL.revokeObjectURL(url), 4000);
} catch (e) { dateien.err = 'Download fehlgeschlagen.'; }
}
// Inline-Vorschau der gewählten Datei (PDF/Bild) – Blob authentifiziert laden.
function pvClear() {
if (dateien.pvUrl) { try { URL.revokeObjectURL(dateien.pvUrl); } catch { /* egal */ } }
dateien.pvId = null; dateien.pvUrl = ''; dateien.pvType = ''; dateien.pvErr = '';
}
async function vorschauDatei(item) {
if (dateien.pvId === item.id) { pvClear(); return; } // nochmal klicken schließt
pvClear(); dateien.pvId = item.id; dateien.pvLaden = true;
try {
const res = await api.get('/assets/' + item.id, { responseType: 'blob' });
dateien.pvUrl = URL.createObjectURL(res.data);
dateien.pvType = res.data.type || item.type || '';
} catch (e) { dateien.pvErr = 'Vorschau fehlgeschlagen.'; dateien.pvId = null; }
finally { dateien.pvLaden = false; }
}
function closeDateien() { pvClear(); dateien.open = false; }
// ── Render-Bausteine ──────────────────────────────────────────────────
function actionButtons(order) {
@@ -1053,20 +1072,36 @@ const Board = defineComponent({
}
function dateienModal() {
if (!dateien.open) return null;
const istPdf = (dateien.pvType || '').includes('pdf');
const istBild = (dateien.pvType || '').startsWith('image/');
const vorschauArea = dateien.pvLaden ? subdued('Vorschau wird geladen …', 'margin-top:12px;')
: dateien.pvErr ? h('div', { style: 'color:var(--danger,#c62828);font-size:13px;margin-top:12px;' }, dateien.pvErr)
: dateien.pvUrl ? h('div', { style: 'margin-top:14px;border:1px solid var(--border-subdued);border-radius:8px;overflow:hidden;background:#fff;' }, [
istPdf ? h('iframe', { src: dateien.pvUrl, style: 'width:100%;height:70vh;border:none;display:block;' })
: istBild ? h('img', { src: dateien.pvUrl, style: 'display:block;max-width:100%;max-height:70vh;margin:0 auto;' })
: h('div', { style: 'padding:16px;display:flex;flex-direction:column;gap:10px;align-items:flex-start;' }, [
subdued('Für diesen Dateityp gibt es keine Inline-Vorschau.'),
btn('↗ In neuem Tab öffnen', () => window.open(dateien.pvUrl, '_blank')),
]),
]) : null;
const body = h('div', { style: 'padding:16px 20px;' }, [
subdued('Vom Kunden hochgeladene Original-Dokumente (keine generierten SVGs).', 'margin-bottom:12px;'),
dateien.laden ? subdued('Wird geladen …')
: dateien.err ? subdued(dateien.err)
: h('div', { style: 'display:flex;flex-direction:column;gap:8px;' }, dateien.items.map((it) =>
h('div', { style: CARD + 'display:flex;justify-content:space-between;align-items:center;gap:12px;' }, [
h('div', { style: CARD + 'display:flex;justify-content:space-between;align-items:center;gap:12px;' + (dateien.pvId === it.id ? `border-color:${ACCENT};` : '') }, [
h('div', { style: 'min-width:0;' }, [
h('div', { style: 'font-weight:600;word-break:break-all;' }, it.name),
it.type ? subdued(it.type) : null,
]),
btn('⤓ Herunterladen', () => dlDatei(it), 'primary'),
h('div', { style: 'display:flex;gap:8px;flex-shrink:0;' }, [
btn(dateien.pvId === it.id ? '👁 Vorschau schließen' : '👁 Vorschau', () => vorschauDatei(it)),
btn('⤓ Herunterladen', () => dlDatei(it), 'primary'),
]),
]))),
vorschauArea,
]);
return overlay([modalKopf(`Dateien · #${dateien.order?.order_number || ''}`, () => { dateien.open = false; }), body], () => { dateien.open = false; }, '620px');
return overlay([modalKopf(`Dateien · #${dateien.order?.order_number || ''}`, closeDateien), body], closeDateien, '900px');
}
// ── Gesamt-Render ─────────────────────────────────────────────────────