feat(frontend): Export-Buttons fuer Voelker, Honigchargen (Modul 21)
CSV-Export in den Listen-Views (Voelker, Honigchargen) und PDF-Rueckverfolgbarkeitsbericht auf der Honigcharge-Detailseite. apiFetchBlob() im API-Client ergaenzt fuer authentifizierte Blob-Downloads (JWT im Authorization-Header statt Cookie).
This commit is contained in:
1 parent
c281d04b16
commit
ed108045af
6 files changed
+114
-9
No files matched your search
@@ -25,6 +25,39 @@ async function rawFetch(path: string, init: RequestInit): Promise<Response> {
|
||||
});
|
||||
}
|
||||
|
||||
export interface BlobDownload {
|
||||
blob: Blob;
|
||||
filename: string;
|
||||
}
|
||||
|
||||
function filenameFromContentDisposition(header: string | null, fallback: string): string {
|
||||
const match = header ? /filename="([^"]+)"/.exec(header) : null;
|
||||
return match?.[1] ?? fallback;
|
||||
}
|
||||
|
||||
export async function apiFetchBlob(path: string, fallbackFilename: string): Promise<BlobDownload> {
|
||||
let response = await rawFetch(path, {});
|
||||
|
||||
if (response.status === 401) {
|
||||
const refreshed = await refreshRequest();
|
||||
if (refreshed) {
|
||||
setAccessToken(refreshed.accessToken);
|
||||
response = await rawFetch(path, {});
|
||||
}
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new ApiError(response.status, 'Export fehlgeschlagen');
|
||||
}
|
||||
|
||||
const blob = await response.blob();
|
||||
const filename = filenameFromContentDisposition(
|
||||
response.headers.get('Content-Disposition'),
|
||||
fallbackFilename,
|
||||
);
|
||||
return { blob, filename };
|
||||
}
|
||||
|
||||
export async function apiFetch<T>(path: string, init: RequestInit = {}): Promise<T> {
|
||||
let response = await rawFetch(path, init);
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { apiFetchBlob } from "@/lib/auth/api-client";
|
||||
|
||||
export function downloadBlob(blob: Blob, filename: string): void {
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.download = filename;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
export async function exportColoniesCsv(): Promise<void> {
|
||||
const { blob, filename } = await apiFetchBlob("/export/colonies.csv", "colonies.csv");
|
||||
downloadBlob(blob, filename);
|
||||
}
|
||||
|
||||
export async function exportHoneyBatchesCsv(): Promise<void> {
|
||||
const { blob, filename } = await apiFetchBlob(
|
||||
"/export/honey-batches.csv",
|
||||
"honey-batches.csv",
|
||||
);
|
||||
downloadBlob(blob, filename);
|
||||
}
|
||||
|
||||
export async function exportHoneyBatchTraceabilityPdf(honeyBatchId: string): Promise<void> {
|
||||
const { blob, filename } = await apiFetchBlob(
|
||||
`/export/honey-batch-traceability.pdf?honeyBatchId=${honeyBatchId}`,
|
||||
"honey-batch-traceability.pdf",
|
||||
);
|
||||
downloadBlob(blob, filename);
|
||||
}
|
||||
Reference in new issue
Block a user