- introduce product catalogue pages, management view entries and shared product composables\n- wire product selection into component/piece flows and machine skeleton requirements\n- display linked product metadata and documents across machine, component and piece views\n- generalize model type tooling to handle PRODUCT category
153 lines
4.9 KiB
JavaScript
153 lines
4.9 KiB
JavaScript
import { ref } from 'vue'
|
|
import { useApi } from './useApi'
|
|
import { useToast } from './useToast'
|
|
|
|
const documents = ref([])
|
|
const loading = ref(false)
|
|
|
|
const fileToBase64 = file =>
|
|
new Promise((resolve, reject) => {
|
|
const reader = new FileReader()
|
|
reader.onload = () => resolve(reader.result)
|
|
reader.onerror = () => reject(new Error(`Lecture du fichier ${file.name} impossible`))
|
|
reader.readAsDataURL(file)
|
|
})
|
|
|
|
export function useDocuments () {
|
|
const { get, post, delete: del } = useApi()
|
|
const { showError, showSuccess } = useToast()
|
|
|
|
const loadFromEndpoint = async (endpoint, { updateStore = false } = {}) => {
|
|
loading.value = true
|
|
try {
|
|
const result = await get(endpoint)
|
|
if (result.success) {
|
|
const data = result.data || []
|
|
if (updateStore) {
|
|
documents.value = data
|
|
}
|
|
return { success: true, data }
|
|
}
|
|
if (result.error) {
|
|
showError(result.error)
|
|
}
|
|
return result
|
|
} catch (error) {
|
|
console.error(`Erreur lors du chargement des documents (${endpoint}):`, error)
|
|
showError('Impossible de charger les documents')
|
|
return { success: false, error: error.message }
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
const loadDocuments = async (options = {}) => {
|
|
return loadFromEndpoint('/documents', { updateStore: options.updateStore ?? true })
|
|
}
|
|
|
|
const loadDocumentsBySite = async (siteId, options = {}) => {
|
|
if (!siteId) { return { success: false, error: 'Aucun site sélectionné' } }
|
|
return loadFromEndpoint(`/documents/site/${siteId}`, { updateStore: options.updateStore ?? false })
|
|
}
|
|
|
|
const loadDocumentsByMachine = async (machineId, options = {}) => {
|
|
if (!machineId) { return { success: false, error: 'Aucune machine sélectionnée' } }
|
|
return loadFromEndpoint(`/documents/machine/${machineId}`, { updateStore: options.updateStore ?? false })
|
|
}
|
|
|
|
const loadDocumentsByComponent = async (componentId, options = {}) => {
|
|
if (!componentId) { return { success: false, error: 'Aucun composant sélectionné' } }
|
|
return loadFromEndpoint(`/documents/composant/${componentId}`, { updateStore: options.updateStore ?? false })
|
|
}
|
|
|
|
const loadDocumentsByProduct = async (productId, options = {}) => {
|
|
if (!productId) { return { success: false, error: 'Aucun produit sélectionné' } }
|
|
return loadFromEndpoint(`/documents/product/${productId}`, { updateStore: options.updateStore ?? false })
|
|
}
|
|
|
|
const loadDocumentsByPiece = async (pieceId, options = {}) => {
|
|
if (!pieceId) { return { success: false, error: 'Aucune pièce sélectionnée' } }
|
|
return loadFromEndpoint(`/documents/piece/${pieceId}`, { updateStore: options.updateStore ?? false })
|
|
}
|
|
|
|
const uploadDocuments = async ({ files = [], context = {} }, { updateStore = false } = {}) => {
|
|
if (!files.length) { return { success: false, error: 'Aucun fichier sélectionné' } }
|
|
|
|
loading.value = true
|
|
const created = []
|
|
|
|
try {
|
|
for (const file of files) {
|
|
const dataUrl = await fileToBase64(file)
|
|
|
|
const payload = {
|
|
name: file.name,
|
|
filename: file.name,
|
|
mimeType: file.type || 'application/octet-stream',
|
|
size: file.size,
|
|
path: dataUrl,
|
|
...context
|
|
}
|
|
|
|
const result = await post('/documents', payload)
|
|
if (result.success) {
|
|
created.push(result.data)
|
|
showSuccess(`Document "${file.name}" ajouté`)
|
|
} else if (result.error) {
|
|
showError(`Erreur sur ${file.name} : ${result.error}`)
|
|
}
|
|
}
|
|
|
|
if (created.length) {
|
|
if (updateStore) {
|
|
documents.value = [...created, ...documents.value]
|
|
}
|
|
return { success: true, data: created }
|
|
}
|
|
|
|
return { success: false, error: 'Aucun document ajouté' }
|
|
} catch (error) {
|
|
console.error('Erreur lors de l\'upload des documents:', error)
|
|
showError("Échec de l'ajout des documents")
|
|
return { success: false, error: error.message }
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
const deleteDocument = async (id, { updateStore = false } = {}) => {
|
|
if (!id) { return { success: false, error: 'Identifiant manquant' } }
|
|
|
|
loading.value = true
|
|
try {
|
|
const result = await del(`/documents/${id}`)
|
|
if (result.success) {
|
|
if (updateStore) {
|
|
documents.value = documents.value.filter(doc => doc.id !== id)
|
|
}
|
|
showSuccess('Document supprimé')
|
|
}
|
|
return result
|
|
} catch (error) {
|
|
console.error('Erreur lors de la suppression du document:', error)
|
|
showError('Impossible de supprimer le document')
|
|
return { success: false, error: error.message }
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
return {
|
|
documents,
|
|
loading,
|
|
loadDocuments,
|
|
loadDocumentsBySite,
|
|
loadDocumentsByMachine,
|
|
loadDocumentsByComponent,
|
|
loadDocumentsByPiece,
|
|
loadDocumentsByProduct,
|
|
uploadDocuments,
|
|
deleteDocument
|
|
}
|
|
}
|