nextalys-file-upload
v1.2.0
Published
Composant Angular **standalone** d'upload de fichiers, sans dépendance externe d'upload (l'envoi se fait via `XMLHttpRequest` interne, avec progression et abort), avec :
Readme
NextalysFileUploader
Composant Angular standalone d'upload de fichiers, sans dépendance externe d'upload (l'envoi se fait via XMLHttpRequest interne, avec progression et abort), avec :
- drop zone + sélection de fichiers
- liste des fichiers avec aperçu image et métadonnées éditables
- redimensionnement d'image avant upload via
nxs-image-resizer - barre de progression
- filtres par type MIME / extension, taille max
- gestion d'auth token (header personnalisable)
- traductions optionnelles via
@ngx-translate/core - UI sans Material — boutons, inputs et icônes intégrés
Installation
npm install nextalys-file-upload nxs-image-resizer nextalys-js-helpers @ngx-translate/coreUtilisation (standalone)
Le composant est standalone: true. Plus de NxsFileUploadModule.forRoot(...).
1. Importer le composant et fournir la configuration
Application standalone (bootstrapApplication)
import { bootstrapApplication } from '@angular/platform-browser';
import { provideNxsFileUpload } from 'nextalys-file-upload';
bootstrapApplication(AppComponent, {
providers: [
provideNxsFileUpload({
fileUploadUrl: 'https://api.example.com/upload',
resizeImageConfig: { maxWidth: 1600, quality: 90 },
useTranslations: false,
usePica: true,
debugMode: false,
}),
],
});NgModule classique
import { NxsFileUpload, provideNxsFileUpload } from 'nextalys-file-upload';
@NgModule({
imports: [NxsFileUpload, /* ... */],
providers: [
provideNxsFileUpload({
fileUploadUrl: 'https://api.example.com/upload',
resizeImageConfig: { maxWidth: 1600, quality: 90 },
}),
],
})
export class AppModule {}Alternative : tu peux aussi fournir les tokens un par un (
fileUploadUrl_Token,nxsFileUploadResizeImageConfig_Token, etc.) sans passer parprovideNxsFileUpload. Tous sont exportés.
2. Utiliser le composant dans un template
<nxs-file-upload
[options]="uploadOptions"
[(data)]="uploadData"
(onCompleteAllItems)="onUploadDone($event)"
(onAddingFileFailed)="onFileRejected($event)">
</nxs-file-upload>import { FileUploadOptions, FileUploadData } from 'nextalys-file-upload';
uploadData: FileUploadData = {};
uploadOptions: FileUploadOptions = {
filesCount: 5,
fileMaxSize: 5 * 1024 * 1024, // 5 Mo
allowedFileTypes: ['image'],
maxWidth: 1600,
imageResizeQuality: 85,
};API
provideNxsFileUpload(options)
| Option | Type | Description |
|---------------------|-----------------------|------------------------------------------------------------|
| fileUploadUrl | string | URL par défaut d'upload (peut être surchargée par options) |
| resizeImageConfig | NxsResizeImageConfig| Configuration globale de redimensionnement d'image |
| useTranslations | boolean | Active @ngx-translate/core pour les libellés |
| usePica | boolean | Utilise Pica pour le resize |
| debugMode | boolean | Active les logs |
| authToken | string | Token d'auth envoyé en header |
| authTokenHeader | string | Nom du header (Authorization par défaut) |
| authTokenPrefix | string | Préfixe du token (Bearer par défaut) |
Composant <nxs-file-upload>
Inputs
| Input | Type | Défaut |
|--------------------|---------------------|---------------------------------|
| data | FileUploadData | — |
| options | FileUploadOptions | — |
| name | string | '' |
| title | string | 'Fichier(s) à télécharger' |
| hasDropZone | boolean | true |
| showUploadButton | boolean | true |
| showFilesList | boolean | true |
| showProgressBar | boolean | true |
| disabled | boolean | false |
| required | boolean | false |
Outputs
| Output | Payload |
|-----------------------|----------------------------------|
| beforeResizeImages | FileItemWithData[] |
| afterFileAddingAll | FileItemWithData[] |
| beforeUploadItem | FileItem |
| onCompleteItem | FileItem |
| onCompleteAllItems | FileUploadData |
| onAddingFileFailed | AddingFileFailedData |
| metaChange | { file, meta, value } |
FileUploadOptions (sélection)
| Champ | Type | Description |
|----------------------------|-----------------------------------------------------|-----------------------------------------------------------------------------|
| url | string \| null | Surcharge l'URL d'upload (mettre null pour désactiver l'upload réseau) |
| filesCount | number | Nombre maximum de fichiers |
| allowedFileTypes | FileTypesList[] | 'image' \| 'doc' \| 'pdf' \| 'compress' \| 'xls' \| 'ppt' \| 'audio' \| 'video' \| 'application' |
| allowedMimeTypes | FileMimeTypesList[] | Liste de types MIME autorisés |
| fileMaxSize | number | Taille max en octets |
| maxFileSizeBeforeResize | number | Seuil de taille au-delà duquel le resize est sauté |
| maxWidth | number | Largeur max après resize |
| imageResizeQuality | number | Qualité JPEG (0-100) |
| preventResize | boolean | Désactive le resize |
| singleLocalFileMode | boolean | Mode "1 seul fichier, pas d'upload réseau" (pratique pour preview local) |
| resetFilesOnFileSelect | boolean | Vide la queue à chaque ouverture du picker |
| alwaysShowUploadButton | boolean | Force l'affichage du bouton même quand la queue est pleine |
| fileNameEditable | boolean | Permet de renommer chaque fichier dans la liste |
| filesMetaData | NxsFileMetaData[] | Champs de métadonnées affichés après upload (texte ou liste déroulante) |
| headers | { name; value }[] | Headers HTTP statiques |
| getHeaders | (file) => { name; value }[] | Headers dynamiques par fichier |
| additionalParameter | { [key]: any } | Paramètres POST additionnels |
| withCredentials | boolean | Envoie les cookies cross-origin |
| authToken / authTokenHeader / authTokenPrefix | string | Surcharge l'auth fournie globalement |
| tus | boolean \| NxsTusOptions | Active l'upload résumable via tus.io. Voir section dédiée |
| retryDelays | number[] | Backoff (ms) en mode XHR. Attend online si offline. Défaut : pas de retry |
| uploadBtnLabel | string | Texte du bouton |
| dropZoneLabel | string | Texte de la drop zone |
| dropZoneOverLabel | string | Texte quand on survole la drop zone avec un fichier |
Métadonnées de fichiers
options.filesMetaData = [
{ fieldName: 'category', fieldLabel: 'Catégorie', fieldType: 'list',
possibleValues: [{ value: 'a', label: 'A' }, { value: 'b', label: 'B' }] },
{ fieldName: 'comment', fieldLabel: 'Commentaire', fieldType: 'string' },
];Les champs s'affichent à côté de chaque fichier une fois uploadé, et les valeurs sont stockées dans item.meta.
Retry automatique en mode XHR
Sans tus, tu peux activer un retry exponentiel sur erreurs réseau (xhr.onerror) et 5xx :
uploadOptions: FileUploadOptions = {
url: '/upload',
retryDelays: [0, 1000, 3000, 5000, 10000], // jusqu'à 5 tentatives
};Comportement :
- Chaque entrée est l'attente (ms) avant la tentative correspondante.
[]ou option absente = aucun retry (comportement par défaut). - Si
navigator.onLine === falseau moment d'un retry, on attend l'eventonlinedu navigateur avant de démarrer le timer (le compteur ne tombe pas pendant cette attente). item.cancel()/fileUploader.cancelItem(item)annule un retry en attente.- Sur succès, l'item est marqué
isSuccess. Sur épuisement des tentatives,isError.
Pour un retry manuel après échec final, le composant et NxsFileItem exposent item.retry() : reset complet de l'état et relance via le flow complet (onBeforeUploadItem ré-émis, formdata reconstruite).
En mode
tus, c'est tus-js-client qui gère les retries via son propreretryDelays(voir section suivante).retryDelaysau niveauFileUploadOptionsne s'applique qu'au mode XHR.
Upload résumable (tus.io)
Si ton serveur supporte le protocole tus, tu peux activer un upload résumable avec retry intégré et reprise automatique en cas de coupure (y compris après reload de la page si le même fichier est resélectionné).
Installe le client tus dans ton app :
npm install tus-js-clientPuis active-le via les options :
uploadOptions: FileUploadOptions = {
url: 'https://files.example.com/files/', // endpoint tus
tus: true,
};Ou avec une config fine :
uploadOptions: FileUploadOptions = {
tus: {
endpoint: 'https://files.example.com/files/',
chunkSize: 5 * 1024 * 1024, // 5 Mo
retryDelays: [0, 3000, 5000, 10000, 20000], // ms
metadata: { folder: 'invoices' }, // ajoute aux entrées Upload-Metadata
parallelUploads: 1,
storeFingerprintForResuming: true, // permet la reprise après reload
removeFingerprintOnSuccess: true,
},
};tus-js-client est une peer dependency optionnelle — il n'est chargé (via import() dynamique) que si tu actives effectivement tus. Les apps qui n'en ont pas besoin n'ont pas à l'installer.
Quand tus est actif :
- Le retry exponentiel est géré par
tus-js-client(retryDelays). - L'upload reprend automatiquement où il s'était arrêté après une coupure réseau.
- Si
storeFingerprintForResumingesttrue(défaut), un fingerprint est stocké dans le localStorage : si l'utilisateur reload puis ressélectionne le même fichier, l'upload reprend à partir du dernier chunk validé par le serveur. - L'URL finale du fichier (retournée par le serveur tus) est exposée sur
item.uploadUrl.
Headers et auth (authToken, headers statiques, getHeaders dynamiques) sont transmis à tus. allowedFileType / allowedMimeType / fileMaxSize continuent de filtrer en amont comme en mode XHR.
Piloter le composant de l'extérieur
Le composant expose directement les méthodes publiques openFileSelect(), reset(), cancelAll(), clearQueue(). Utilise une template ref :
<nxs-file-upload #fu [options]="opts" [data]="data"></nxs-file-upload>
<button (click)="fu.openFileSelect()">Ouvrir le picker</button>
<button (click)="fu.reset()">Réinitialiser</button>Pour piloter depuis un endroit éloigné dans le template, utilise @ViewChild / @ViewChildren(NxsFileUpload) côté TypeScript.
Personnalisation visuelle
Les couleurs et arrondis sont exposés via des variables CSS sur le sélecteur du composant. Surcharge-les depuis ta feuille globale ou un wrapper :
nxs-file-upload {
--nxs-primary: #6366f1;
--nxs-primary-hover: #4f46e5;
--nxs-success: #16a34a;
--nxs-error: #dc2626;
--nxs-radius: 12px;
--nxs-border: #e5e7eb;
}Variables disponibles : --nxs-primary, --nxs-primary-hover, --nxs-primary-soft, --nxs-success, --nxs-warn, --nxs-error, --nxs-border, --nxs-border-strong, --nxs-bg-soft, --nxs-bg-hover, --nxs-text, --nxs-text-muted, --nxs-radius, --nxs-radius-sm, --nxs-shadow-focus.
Migration depuis NxsFileUploadModule.forRoot(...)
Le NgModule a été supprimé au profit du composant standalone.
Avant :
imports: [
NxsFileUploadModule.forRoot({
fileUploadUrl: '...',
resizeImageConfig: { maxWidth: 1600, quality: 90 },
}),
]Après :
imports: [NxsFileUpload],
providers: [
provideNxsFileUpload({
fileUploadUrl: '...',
resizeImageConfig: { maxWidth: 1600, quality: 90 },
}),
]Types bas-niveau
Si tu veux piloter la queue d'upload toi-même (sans le composant), les classes sont exposées :
import {
NxsFileUploaderQueue,
NxsFileItem,
NxsFileLike,
NxsFileUploaderOptions,
NxsFileDropDirective,
NxsFileSelectDirective,
} from 'nextalys-file-upload';NxsFileUploaderQueue propose addToQueue, removeFromQueue, uploadAll, uploadItem, cancelAll, cancelItem, clearQueue, et les callbacks onAfterAddingAll, onBeforeUploadItem, onCompleteItem, onCompleteAll, onWhenAddingFileFailed. Les directives [nxsFileDrop] et [nxsFileSelect] câblent respectivement les événements DOM drop/dragover/dragleave et change.
Build
ng build nextalys-file-uploaderLes artefacts sont écrits dans projects/nextalys-file-uploader/dist.
