feat(web): panneau Fichiers — navigation projet + téléchargements fichier/dossier ZIP — #211
This commit is contained in:
@ -39,6 +39,7 @@ export type FetchLike = (
|
||||
/** Parsed JSON body (may reject/return undefined for empty bodies). */
|
||||
json(): Promise<unknown>;
|
||||
text(): Promise<string>;
|
||||
blob?(): Promise<Blob>;
|
||||
}>;
|
||||
|
||||
/**
|
||||
@ -182,4 +183,51 @@ export class HttpInvoker {
|
||||
}
|
||||
return parsed as T;
|
||||
}
|
||||
|
||||
async download(path: string, filename: string, what = `GET ${path}`): Promise<void> {
|
||||
const headers: Record<string, string> = {};
|
||||
if (this.token) headers.Authorization = `Bearer ${this.token}`;
|
||||
|
||||
let res: Awaited<ReturnType<FetchLike>>;
|
||||
try {
|
||||
res = await this.fetchImpl(`${this.baseUrl}${path}`, {
|
||||
method: "GET",
|
||||
headers,
|
||||
credentials: "same-origin",
|
||||
});
|
||||
} catch (networkError) {
|
||||
const err: GatewayError = {
|
||||
code: "TRANSPORT_ERROR",
|
||||
message: `HTTP request for ${what} failed: ${String(networkError)}`,
|
||||
};
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (!res.ok) {
|
||||
if (res.status === 401) this.onUnauthorized?.();
|
||||
let parsed: unknown;
|
||||
try {
|
||||
parsed = await res.json();
|
||||
} catch {
|
||||
parsed = undefined;
|
||||
}
|
||||
throw toGatewayError(parsed, `${what} failed (HTTP ${res.status})`);
|
||||
}
|
||||
|
||||
const blob = res.blob ? await res.blob() : new Blob([await res.text()]);
|
||||
triggerBrowserDownload(blob, filename);
|
||||
}
|
||||
}
|
||||
|
||||
function triggerBrowserDownload(blob: Blob, filename: string): void {
|
||||
if (typeof document === "undefined" || typeof URL === "undefined") return;
|
||||
const href = URL.createObjectURL(blob);
|
||||
const link = document.createElement("a");
|
||||
link.href = href;
|
||||
link.download = filename;
|
||||
link.rel = "noopener";
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
link.remove();
|
||||
URL.revokeObjectURL(href);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user