Files
Inventory/app/composables/useEntityDocuments.ts
Matthieu 4a3bceffa1 feat(machine) : afficher quantité pièces + pièces incluses des composants
- MachinePiecesCard : passer isEditMode au PieceItem + forward event update
- useMachineHierarchy : mapper quantity depuis le backend + construire
  les pièces de structure du composant en lecture seule
- useMachineDetailUpdates : PATCH MachinePieceLink.quantity + fix reference null
- ComponentItem : séparer pièces liées / pièces incluses par défaut
- useEntityDocuments : skip chargement documents pour pièces de structure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:22:20 +01:00

123 lines
3.4 KiB
TypeScript

/**
* Reactive document management for entity items (ComponentItem, PieceItem).
*
* Handles document CRUD operations, preview modal state, and lazy loading.
* Display helpers (formatSize, shouldInlinePdf, etc.) are imported from
* shared/utils/documentDisplayUtils.ts.
*/
import { ref, computed, watch } from 'vue'
import { useDocuments } from '~/composables/useDocuments'
import { canPreviewDocument } from '~/utils/documentPreview'
export interface EntityDocumentsDeps {
entity: () => any
entityType: 'composant' | 'piece'
}
export function useEntityDocuments(deps: EntityDocumentsDeps) {
const { entity, entityType } = deps
const { uploadDocuments, deleteDocument } = useDocuments()
const loadDocumentsFn = entityType === 'composant'
? useDocuments().loadDocumentsByComponent
: useDocuments().loadDocumentsByPiece
const selectedFiles = ref<File[]>([])
const uploadingDocuments = ref(false)
const loadingDocuments = ref(false)
const documentsLoaded = ref(!!(entity().documents && entity().documents.length))
const documents = computed(() => entity().documents || [])
// Preview modal state
const previewDocument = ref<any>(null)
const previewVisible = ref(false)
const openPreview = (doc: any) => {
if (!canPreviewDocument(doc)) return
previewDocument.value = doc
previewVisible.value = true
}
const closePreview = () => {
previewVisible.value = false
previewDocument.value = null
}
// Document watchers
watch(
() => entity().documents,
(docs: any) => {
documentsLoaded.value = !!(docs && docs.length)
},
)
// CRUD operations
const refreshDocuments = async () => {
const e = entity()
if (!e?.id || e._structurePiece) return
loadingDocuments.value = true
try {
const result: any = await loadDocumentsFn(e.id, { updateStore: false })
if (result.success) {
e.documents = result.data || []
documentsLoaded.value = true
}
} finally {
loadingDocuments.value = false
}
}
const ensureDocumentsLoaded = async () => {
if (documentsLoaded.value || !entity()?.id) return
await refreshDocuments()
}
const handleFilesAdded = async (files: File[]) => {
const e = entity()
if (!files.length || !e?.id) return
uploadingDocuments.value = true
try {
const contextKey = entityType === 'composant' ? 'composantId' : 'pieceId'
const result: any = await uploadDocuments(
{ files, context: { [contextKey]: e.id } } as any,
{ updateStore: false } as any,
)
if (result.success) {
const newDocs = result.data || []
e.documents = [...newDocs, ...(e.documents || [])]
documentsLoaded.value = true
selectedFiles.value = []
}
} finally {
uploadingDocuments.value = false
}
}
const removeDocument = async (documentId: string) => {
if (!documentId) return
const result: any = await deleteDocument(documentId, { updateStore: false } as any)
if (result.success) {
const e = entity()
e.documents = (e.documents || []).filter((doc: any) => doc.id !== documentId)
}
}
return {
documents,
selectedFiles,
uploadingDocuments,
loadingDocuments,
documentsLoaded,
previewDocument,
previewVisible,
openPreview,
closePreview,
refreshDocuments,
ensureDocumentsLoaded,
handleFilesAdded,
removeDocument,
}
}