feat(delivery): replace deliveryEditorSlice with automat and add PDF/text attachment handling

- replace Redux deliveryEditorSlice with deliveryEditorAutomat using automat
- add Attachment and AttachmentList components in Kopfdaten
- extract PDF text via pdftotext-wasm and render PDF thumbnails with pdfjs-dist
- add TextEditorDialog to view and edit extracted text files (preformatted monospace, no wrap)
- configure Vite server.fs.allow for pdftotext.wasm
This commit is contained in:
seb
2026-09-18 01:49:59 +02:00
parent 795043fe99
commit 27f6dfdebf
15 changed files with 1369 additions and 246 deletions

7
src/utils/pdfText.js Normal file
View File

@@ -0,0 +1,7 @@
import { pdfToText } from 'pdftotext-wasm';
export async function extractPdfText(pdfSource, options = { layout: true }) {
return pdfToText(pdfSource, options);
}
export { pdfToText };

36
src/utils/pdfThumbnail.js Normal file
View File

@@ -0,0 +1,36 @@
import * as pdfjsLib from 'pdfjs-dist';
// Tells Vite/Webpack to emit the worker script as an asset file locally
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
'pdfjs-dist/build/pdf.worker.mjs',
import.meta.url
).toString();
export async function generatePdfThumbnail(pdfSource, targetWidth = 200) {
let loadingTask;
if (pdfSource instanceof File || pdfSource instanceof Blob) {
const arrayBuffer = await pdfSource.arrayBuffer();
loadingTask = pdfjsLib.getDocument({ data: arrayBuffer });
} else {
loadingTask = pdfjsLib.getDocument(pdfSource);
}
const pdf = await loadingTask.promise;
const page = await pdf.getPage(1);
const unscaledViewport = page.getViewport({ scale: 1 });
const scale = targetWidth / unscaledViewport.width;
const viewport = page.getViewport({ scale });
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.width = Math.floor(viewport.width);
canvas.height = Math.floor(viewport.height);
await page.render({
canvasContext: context,
viewport: viewport,
}).promise;
return canvas.toDataURL('image/jpeg', 0.85);
}