54 lines
1.9 KiB
TypeScript
54 lines
1.9 KiB
TypeScript
import { ref } from 'vue'
|
|
import type { AnyObject } from '~/shared/composables/useApi'
|
|
|
|
/**
|
|
* Réponse JSON-LD de POST /api/uploaded_documents (groupe `uploaded_document:read`).
|
|
* Seul l'IRI (`@id`) est exploité pour le poser sur la relation cible.
|
|
*/
|
|
export interface UploadedDocumentResponse {
|
|
'@id': string
|
|
originalFilename?: string
|
|
mimeType?: string
|
|
}
|
|
|
|
/**
|
|
* Upload d'un document générique vers l'infra partagée (ERP-154) :
|
|
* POST /api/uploaded_documents en multipart/form-data, champ « file », via
|
|
* `useApi()` (cookie JWT, parsing Hydra/erreurs). Renvoie l'IRI du document créé,
|
|
* à poser sur la relation cible (ex: `carrier.dischargeDocument` — RG-4.02).
|
|
*
|
|
* Les erreurs (MIME hors whitelist / fichier trop volumineux → 422) sont relayées
|
|
* (rethrow) à l'appelant pour un affichage inline sous le champ. `toast: false` par
|
|
* défaut : pas de toast fourre-tout, le formulaire mappe le message au bon champ.
|
|
*/
|
|
export function useUpload() {
|
|
// Indicateur d'upload en cours (désactivation UI / spinner éventuel).
|
|
const uploading = ref(false)
|
|
|
|
/**
|
|
* Envoie `file` et renvoie l'IRI du `UploadedDocument` créé.
|
|
* @throws relaie l'erreur réseau / 422 (MIME, taille) à l'appelant.
|
|
*/
|
|
async function upload(file: File, options: { toast?: boolean } = {}): Promise<string> {
|
|
const formData = new FormData()
|
|
formData.append('file', file)
|
|
|
|
uploading.value = true
|
|
try {
|
|
// useApi() détecte le FormData et n'impose pas de Content-Type JSON :
|
|
// le navigateur pose lui-même la frontière multipart.
|
|
const doc = await useApi().post<UploadedDocumentResponse>(
|
|
'/uploaded_documents',
|
|
formData as unknown as AnyObject,
|
|
{ toast: options.toast ?? false },
|
|
)
|
|
|
|
return doc['@id']
|
|
} finally {
|
|
uploading.value = false
|
|
}
|
|
}
|
|
|
|
return { uploading, upload }
|
|
}
|