Vue Attachment
Cos'è @pzeta/vue-attachment
@pzeta/vue-attachment è una libreria di componenti Vue 3 per la gestione completa di file allegati associati a entità di business: upload, lista (grid/list), preview popover e download/eliminazione. Backend di riferimento: API REST + storage MinIO/S3.
Funzionalità principali
- Componenti Presentational + Connected: usa quelli puri (props in, eventi out) o le varianti che fanno il fetch da sole via
useAttachments - Adapter Strategy: backend pluggable.
createAxiosAdapterdi default; implementaAttachmentAdapterper GraphQL, fetch o mock - Composables:
useAttachments(CRUD),useFileIcon(MIME → icona PrimeIcons),useFileSize(formattazione bytes IEC) - Plugin Vue:
VueAttachmentPluginregistra globalmente i componenti e fornisce l'adapterviaprovide/inject - Mapper opzionale: backend con schema diverso da
Attachment(camelCase)? Passamapper.toAttachmentalcreateAxiosAdaptersenza toccare la logica di trasporto - Admin endpoint:
findOrphaned()/cleanOrphaned()per pulizia file orfani - i18n: dizionari
it/en/de/es/frlazy via@pzeta/vue-i18n
Architettura
@pzeta/vue-attachment
├── components/ # AttachmentsManager(+Connected) · AttachmentPopover(+Connected)
│ # AttachmentDialog · AttachmentsList/Grid/Toolbar · AttachmentCard/Row
├── composables/ # useAttachments · useFileIcon · useFileSize
├── services/ # AxiosAttachmentAdapter · createAxiosAdapter
├── types/ # Attachment (dominio) · AttachmentAdapter (Strategy) · AttachmentQuery · ...
├── plugins/ # VueAttachmentPlugin · ATTACHMENT_ADAPTER_KEY
└── i18n/ # locales
Modello di dominio
interface Attachment {
id: string
fileName: string
fileType: string // MIME type
size: number // bytes
uploadDate: string // ISO 8601
thumbnailUrl?: string
}
Il modello è indipendente dal trasporto e dallo schema DB. Backend con campi diversi (es. idallegato/nomefile) si integrano tramite mapper.toAttachment.
Sotto-pagine
Components
Componenti UI per la gestione allegati. Architettura Presentational + Connected, decoupled dal trasporto via AttachmentAdapter.
Services
Adapter Strategy per il data source. AttachmentAdapter è l'interfaccia, createAxiosAdapter è l'implementazione di default basata su axios.
Quick start
// main.ts
import { createApp } from 'vue'
import axios from 'axios'
import {
VueAttachmentPlugin,
createAxiosAdapter
} from '@pzeta/vue-attachment'
import '@pzeta/vue-attachment/style.css'
const http = axios.create({ baseURL: '/api/storage' })
createApp(App)
.use(VueAttachmentPlugin, {
adapter: createAxiosAdapter(http, { storagePath: 'attachments/tickets' })
})
.mount('#app')
<!-- in qualsiasi pagina: il container fetcha autonomamente -->
<template>
<AttachmentsManagerConnected
reference-table="tickets"
reference-column="idticket"
:reference-value="42"
:max-size="10485760"
:allowed-types="['image/png', 'image/jpeg', 'application/pdf']"
/>
</template>
Quando usare cosa
| Scenario | Componente / API |
|---|---|
| Pagina dettaglio entità con allegati | AttachmentsManagerConnected |
| Indicatore compatto allegati nell'header (Ticket, Anagrafica, ...) | AttachmentPopoverConnected |
| Modal di gestione allegati | AttachmentDialog (wrappa AttachmentsManagerConnected) |
| Lista già in memoria (cache, SSR, Storybook, demo) | AttachmentsManager / AttachmentPopover (presentational) |
| CRUD custom in uno script setup | composable useAttachments |
| Backend non-axios (GraphQL, fetch, tRPC, mock) | implementa AttachmentAdapter |
| Backend axios con schema legacy snake_case | createAxiosAdapter(http, { mapper }) |
Migration v1 → v2
| Cambiamento | v1 | v2 |
|---|---|---|
| Configurazione | ConfigService (singleton legato a import.meta.env) | app.use(VueAttachmentPlugin, { adapter }) |
| HTTP client | new AttachmentService(http) | createAxiosAdapter(http) |
| DB mapping | AttachmentDB + mapDbToAttachment in libreria | Backend deve restituire Attachment (camelCase). Per backend legacy: opzione mapper |
| Componenti smart | AttachmentsManager faceva fetch internamente con configService | AttachmentsManager è presentational; per fetch automatico → AttachmentsManagerConnected |
AttachmentPopover | Riceveva referenceTable/Column/Value e fetchava | Presentational: riceve attachments via prop. Per fetch → AttachmentPopoverConnected |
Tipo Attachment | esportato da services/AttachmentService | esportato da types |
Simboli rimossi
ConfigService, configService, AttachmentService (classe), mapDbToAttachment, mapAttachmentToDb, AttachmentDB. Chi li importava direttamente deve riscrivere usando createAxiosAdapter / AxiosAttachmentAdapter / mapper opzionale.