refactor(frontend) : split useMachineDetailData into focused composables
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
146
app/composables/useMachineDetailDocuments.ts
Normal file
146
app/composables/useMachineDetailDocuments.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
* Machine detail — document management sub-composable.
|
||||
*
|
||||
* Handles document loading, upload, delete and preview state.
|
||||
*/
|
||||
|
||||
import { ref, computed } from 'vue'
|
||||
import { useDocuments } from '~/composables/useDocuments'
|
||||
import { canPreviewDocument } from '~/utils/documentPreview'
|
||||
|
||||
type AnyRecord = Record<string, unknown>
|
||||
|
||||
interface MachineDetailDocumentsDeps {
|
||||
machine: Ref<AnyRecord | null>
|
||||
}
|
||||
|
||||
export function useMachineDetailDocuments(deps: MachineDetailDocumentsDeps) {
|
||||
const { machine } = deps
|
||||
const {
|
||||
uploadDocuments,
|
||||
deleteDocument,
|
||||
loadDocumentsByMachine,
|
||||
loadDocumentsByProduct,
|
||||
} = useDocuments()
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// State
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const machineDocumentFiles = ref<File[]>([])
|
||||
const machineDocumentsUploading = ref(false)
|
||||
const machineDocumentsLoaded = ref(false)
|
||||
const previewDocument = ref<AnyRecord | null>(null)
|
||||
const previewVisible = ref(false)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Computed
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const machineDocumentsList = computed(
|
||||
() => ((machine.value as AnyRecord)?.documents as AnyRecord[]) || [],
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Methods
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const refreshMachineDocuments = async () => {
|
||||
if (!machine.value?.id) return
|
||||
const result: any = await loadDocumentsByMachine(machine.value.id as string, { updateStore: false })
|
||||
if (result.success && machine.value) {
|
||||
machine.value.documents = result.data || []
|
||||
machineDocumentsLoaded.value = true
|
||||
}
|
||||
}
|
||||
|
||||
const handleMachineFilesAdded = async (files: File[]) => {
|
||||
if (!files.length || !machine.value?.id) return
|
||||
machineDocumentsUploading.value = true
|
||||
try {
|
||||
const result: any = await uploadDocuments(
|
||||
{ files, context: { machineId: machine.value.id } } as any,
|
||||
{ updateStore: false },
|
||||
)
|
||||
if (result.success && machine.value) {
|
||||
const newDocs = (result.data as AnyRecord[]) || []
|
||||
machine.value.documents = [
|
||||
...newDocs,
|
||||
...((machine.value.documents as AnyRecord[]) || []),
|
||||
]
|
||||
machineDocumentFiles.value = []
|
||||
}
|
||||
} finally {
|
||||
machineDocumentsUploading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const removeMachineDocument = async (documentId: string) => {
|
||||
if (!documentId) return
|
||||
const result: any = await deleteDocument(documentId, { updateStore: false })
|
||||
if (result.success && machine.value) {
|
||||
machine.value.documents = ((machine.value.documents as AnyRecord[]) || []).filter(
|
||||
(doc) => doc.id !== documentId,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const openPreview = (doc: AnyRecord) => {
|
||||
if (!canPreviewDocument(doc)) return
|
||||
previewDocument.value = doc
|
||||
previewVisible.value = true
|
||||
}
|
||||
|
||||
const closePreview = () => {
|
||||
previewVisible.value = false
|
||||
previewDocument.value = null
|
||||
}
|
||||
|
||||
const loadProductDocuments = async (machineProductLinks: AnyRecord[]) => {
|
||||
const productIds = machineProductLinks
|
||||
.map((link) => {
|
||||
const p = link.product as AnyRecord | string | null
|
||||
if (typeof p === 'string') return p.split('/').pop() || null
|
||||
return (p as AnyRecord)?.id as string | null
|
||||
})
|
||||
.filter((id): id is string => !!id)
|
||||
|
||||
const results = await Promise.allSettled(
|
||||
productIds.map(async (id) => {
|
||||
const result: any = await loadDocumentsByProduct(id, { updateStore: false })
|
||||
if (result.success && Array.isArray(result.data)) {
|
||||
return { id, docs: result.data as AnyRecord[] }
|
||||
}
|
||||
return { id, docs: [] }
|
||||
}),
|
||||
)
|
||||
|
||||
const map = new Map<string, AnyRecord[]>()
|
||||
results.forEach((r) => {
|
||||
if (r.status === 'fulfilled' && r.value.docs.length) {
|
||||
map.set(r.value.id, r.value.docs)
|
||||
}
|
||||
})
|
||||
return map
|
||||
}
|
||||
|
||||
return {
|
||||
// State
|
||||
machineDocumentFiles,
|
||||
machineDocumentsUploading,
|
||||
machineDocumentsLoaded,
|
||||
previewDocument,
|
||||
previewVisible,
|
||||
|
||||
// Computed
|
||||
machineDocumentsList,
|
||||
|
||||
// Methods
|
||||
refreshMachineDocuments,
|
||||
handleMachineFilesAdded,
|
||||
removeMachineDocument,
|
||||
openPreview,
|
||||
closePreview,
|
||||
loadProductDocuments,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user