feat(documents) : wire DocumentEditModal and type select in all entity pages
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,12 @@
|
|||||||
:documents="componentDocuments"
|
:documents="componentDocuments"
|
||||||
@close="closePreview"
|
@close="closePreview"
|
||||||
/>
|
/>
|
||||||
|
<DocumentEditModal
|
||||||
|
:visible="editModalVisible"
|
||||||
|
:document="editingDocument"
|
||||||
|
@close="editModalVisible = false"
|
||||||
|
@updated="handleDocumentUpdated"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Component Header -->
|
<!-- Component Header -->
|
||||||
<div class="flex items-center gap-3 p-3 bg-base-200 rounded-lg cursor-pointer" @click="toggleCollapse">
|
<div class="flex items-center gap-3 p-3 bg-base-200 rounded-lg cursor-pointer" @click="toggleCollapse">
|
||||||
@@ -208,9 +214,11 @@
|
|||||||
<DocumentListInline
|
<DocumentListInline
|
||||||
:documents="componentDocuments"
|
:documents="componentDocuments"
|
||||||
:can-delete="isEditMode"
|
:can-delete="isEditMode"
|
||||||
|
:can-edit="isEditMode"
|
||||||
:delete-disabled="uploadingDocuments"
|
:delete-disabled="uploadingDocuments"
|
||||||
empty-text="Aucun document lié à ce composant."
|
empty-text="Aucun document lié à ce composant."
|
||||||
@preview="openPreview"
|
@preview="openPreview"
|
||||||
|
@edit="openEditModal"
|
||||||
@delete="removeDocument"
|
@delete="removeDocument"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -319,6 +327,7 @@ const {
|
|||||||
ensureDocumentsLoaded,
|
ensureDocumentsLoaded,
|
||||||
handleFilesAdded,
|
handleFilesAdded,
|
||||||
removeDocument,
|
removeDocument,
|
||||||
|
editDocument,
|
||||||
} = useEntityDocuments({ entity: () => props.component, entityType: 'composant' })
|
} = useEntityDocuments({ entity: () => props.component, entityType: 'composant' })
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -333,6 +342,21 @@ const {
|
|||||||
updateCustomField: updateComponentCustomField,
|
updateCustomField: updateComponentCustomField,
|
||||||
} = useEntityCustomFields({ entity: () => props.component, entityType: 'composant' })
|
} = useEntityCustomFields({ entity: () => props.component, entityType: 'composant' })
|
||||||
|
|
||||||
|
// --- Document edit modal ---
|
||||||
|
const editingDocument = ref(null)
|
||||||
|
const editModalVisible = ref(false)
|
||||||
|
|
||||||
|
const openEditModal = (doc) => {
|
||||||
|
editingDocument.value = doc
|
||||||
|
editModalVisible.value = true
|
||||||
|
}
|
||||||
|
const handleDocumentUpdated = async (data) => {
|
||||||
|
if (!editingDocument.value?.id) return
|
||||||
|
await editDocument(editingDocument.value.id, data)
|
||||||
|
editModalVisible.value = false
|
||||||
|
editingDocument.value = null
|
||||||
|
}
|
||||||
|
|
||||||
// --- Collapse state ---
|
// --- Collapse state ---
|
||||||
const isCollapsed = ref(true)
|
const isCollapsed = ref(true)
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,12 @@
|
|||||||
:documents="pieceDocuments"
|
:documents="pieceDocuments"
|
||||||
@close="closePreview"
|
@close="closePreview"
|
||||||
/>
|
/>
|
||||||
|
<DocumentEditModal
|
||||||
|
:visible="editModalVisible"
|
||||||
|
:document="editingDocument"
|
||||||
|
@close="editModalVisible = false"
|
||||||
|
@updated="handleDocumentUpdated"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Piece Header (collapsible, same pattern as ComponentItem) -->
|
<!-- Piece Header (collapsible, same pattern as ComponentItem) -->
|
||||||
<div class="flex items-start justify-between p-4 bg-base-200 rounded-lg">
|
<div class="flex items-start justify-between p-4 bg-base-200 rounded-lg">
|
||||||
@@ -247,9 +253,11 @@
|
|||||||
<DocumentListInline
|
<DocumentListInline
|
||||||
:documents="pieceDocuments"
|
:documents="pieceDocuments"
|
||||||
:can-delete="isEditMode"
|
:can-delete="isEditMode"
|
||||||
|
:can-edit="isEditMode"
|
||||||
:delete-disabled="uploadingDocuments"
|
:delete-disabled="uploadingDocuments"
|
||||||
empty-text="Aucun document lié à cette pièce."
|
empty-text="Aucun document lié à cette pièce."
|
||||||
@preview="openPreview"
|
@preview="openPreview"
|
||||||
|
@edit="openEditModal"
|
||||||
@delete="removeDocument"
|
@delete="removeDocument"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -329,6 +337,7 @@ const {
|
|||||||
refreshDocuments,
|
refreshDocuments,
|
||||||
handleFilesAdded,
|
handleFilesAdded,
|
||||||
removeDocument,
|
removeDocument,
|
||||||
|
editDocument,
|
||||||
} = useEntityDocuments({ entity: () => props.piece, entityType: 'piece' })
|
} = useEntityDocuments({ entity: () => props.piece, entityType: 'piece' })
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -343,6 +352,21 @@ const {
|
|||||||
updateCustomField,
|
updateCustomField,
|
||||||
} = useEntityCustomFields({ entity: () => props.piece, entityType: 'piece' })
|
} = useEntityCustomFields({ entity: () => props.piece, entityType: 'piece' })
|
||||||
|
|
||||||
|
// --- Document edit modal ---
|
||||||
|
const editingDocument = ref(null)
|
||||||
|
const editModalVisible = ref(false)
|
||||||
|
|
||||||
|
const openEditModal = (doc) => {
|
||||||
|
editingDocument.value = doc
|
||||||
|
editModalVisible.value = true
|
||||||
|
}
|
||||||
|
const handleDocumentUpdated = async (data) => {
|
||||||
|
if (!editingDocument.value?.id) return
|
||||||
|
await editDocument(editingDocument.value.id, data)
|
||||||
|
editModalVisible.value = false
|
||||||
|
editingDocument.value = null
|
||||||
|
}
|
||||||
|
|
||||||
// --- Collapse state ---
|
// --- Collapse state ---
|
||||||
const isCollapsed = ref(true)
|
const isCollapsed = ref(true)
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,12 @@
|
|||||||
:documents="componentDocuments"
|
:documents="componentDocuments"
|
||||||
@close="closePreview"
|
@close="closePreview"
|
||||||
/>
|
/>
|
||||||
|
<DocumentEditModal
|
||||||
|
:visible="editModalVisible"
|
||||||
|
:document="editingDocument"
|
||||||
|
@close="editModalVisible = false"
|
||||||
|
@updated="handleDocumentUpdated"
|
||||||
|
/>
|
||||||
<main class="container mx-auto px-6 py-10">
|
<main class="container mx-auto px-6 py-10">
|
||||||
<div v-if="loading" class="flex flex-col items-center gap-4 py-20 text-center">
|
<div v-if="loading" class="flex flex-col items-center gap-4 py-20 text-center">
|
||||||
<span class="loading loading-spinner loading-lg" aria-hidden="true" />
|
<span class="loading loading-spinner loading-lg" aria-hidden="true" />
|
||||||
@@ -294,9 +300,11 @@
|
|||||||
v-else
|
v-else
|
||||||
:documents="componentDocuments"
|
:documents="componentDocuments"
|
||||||
:can-delete="canEdit"
|
:can-delete="canEdit"
|
||||||
|
:can-edit="true"
|
||||||
:delete-disabled="uploadingDocuments"
|
:delete-disabled="uploadingDocuments"
|
||||||
empty-text="Aucun document n'est associé à ce composant pour le moment."
|
empty-text="Aucun document n'est associé à ce composant pour le moment."
|
||||||
@preview="openPreview"
|
@preview="openPreview"
|
||||||
|
@edit="openEditModal"
|
||||||
@delete="removeDocument"
|
@delete="removeDocument"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -334,10 +342,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
import { useRoute } from '#imports'
|
import { useRoute } from '#imports'
|
||||||
import { useComponentEdit } from '~/composables/useComponentEdit'
|
import { useComponentEdit } from '~/composables/useComponentEdit'
|
||||||
|
import { useDocuments } from '~/composables/useDocuments'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
const { updateDocument } = useDocuments()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
component,
|
component,
|
||||||
@@ -379,4 +390,24 @@ const {
|
|||||||
resolveSubcomponentLabel,
|
resolveSubcomponentLabel,
|
||||||
formatStructurePreview,
|
formatStructurePreview,
|
||||||
} = useComponentEdit(String(route.params.id))
|
} = useComponentEdit(String(route.params.id))
|
||||||
|
|
||||||
|
const editingDocument = ref<any | null>(null)
|
||||||
|
const editModalVisible = ref(false)
|
||||||
|
|
||||||
|
const openEditModal = (doc: any) => {
|
||||||
|
editingDocument.value = doc
|
||||||
|
editModalVisible.value = true
|
||||||
|
}
|
||||||
|
const handleDocumentUpdated = async (data: { name?: string; type?: string }) => {
|
||||||
|
if (!editingDocument.value?.id) return
|
||||||
|
const result = await updateDocument(editingDocument.value.id, data)
|
||||||
|
if (result.success) {
|
||||||
|
const idx = componentDocuments.value.findIndex((d: any) => d.id === editingDocument.value?.id)
|
||||||
|
if (idx !== -1) {
|
||||||
|
componentDocuments.value[idx] = { ...componentDocuments.value[idx], ...data }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
editModalVisible.value = false
|
||||||
|
editingDocument.value = null
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -6,6 +6,12 @@
|
|||||||
:documents="pieceDocuments"
|
:documents="pieceDocuments"
|
||||||
@close="closePreview"
|
@close="closePreview"
|
||||||
/>
|
/>
|
||||||
|
<DocumentEditModal
|
||||||
|
:visible="editModalVisible"
|
||||||
|
:document="editingDocument"
|
||||||
|
@close="editModalVisible = false"
|
||||||
|
@updated="handleDocumentUpdated"
|
||||||
|
/>
|
||||||
<main class="container mx-auto px-6 py-10">
|
<main class="container mx-auto px-6 py-10">
|
||||||
<div v-if="loading" class="flex flex-col items-center gap-4 py-20 text-center">
|
<div v-if="loading" class="flex flex-col items-center gap-4 py-20 text-center">
|
||||||
<span class="loading loading-spinner loading-lg" aria-hidden="true" />
|
<span class="loading loading-spinner loading-lg" aria-hidden="true" />
|
||||||
@@ -231,9 +237,11 @@
|
|||||||
v-else
|
v-else
|
||||||
:documents="pieceDocuments"
|
:documents="pieceDocuments"
|
||||||
:can-delete="canEdit"
|
:can-delete="canEdit"
|
||||||
|
:can-edit="true"
|
||||||
:delete-disabled="uploadingDocuments"
|
:delete-disabled="uploadingDocuments"
|
||||||
empty-text="Aucun document n'est associé à cette pièce pour le moment."
|
empty-text="Aucun document n'est associé à cette pièce pour le moment."
|
||||||
@preview="openPreview"
|
@preview="openPreview"
|
||||||
|
@edit="openEditModal"
|
||||||
@delete="removeDocument"
|
@delete="removeDocument"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -271,10 +279,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
import { useRoute } from '#imports'
|
import { useRoute } from '#imports'
|
||||||
import { usePieceEdit } from '~/composables/usePieceEdit'
|
import { usePieceEdit } from '~/composables/usePieceEdit'
|
||||||
|
import { useDocuments } from '~/composables/useDocuments'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
const { updateDocument } = useDocuments()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
piece,
|
piece,
|
||||||
@@ -310,4 +321,24 @@ const {
|
|||||||
submitEdition,
|
submitEdition,
|
||||||
formatPieceStructurePreview,
|
formatPieceStructurePreview,
|
||||||
} = usePieceEdit(String(route.params.id))
|
} = usePieceEdit(String(route.params.id))
|
||||||
|
|
||||||
|
const editingDocument = ref<any | null>(null)
|
||||||
|
const editModalVisible = ref(false)
|
||||||
|
|
||||||
|
const openEditModal = (doc: any) => {
|
||||||
|
editingDocument.value = doc
|
||||||
|
editModalVisible.value = true
|
||||||
|
}
|
||||||
|
const handleDocumentUpdated = async (data: { name?: string; type?: string }) => {
|
||||||
|
if (!editingDocument.value?.id) return
|
||||||
|
const result = await updateDocument(editingDocument.value.id, data)
|
||||||
|
if (result.success) {
|
||||||
|
const idx = pieceDocuments.value.findIndex((d: any) => d.id === editingDocument.value?.id)
|
||||||
|
if (idx !== -1) {
|
||||||
|
pieceDocuments.value[idx] = { ...pieceDocuments.value[idx], ...data }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
editModalVisible.value = false
|
||||||
|
editingDocument.value = null
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -6,6 +6,12 @@
|
|||||||
:documents="productDocuments"
|
:documents="productDocuments"
|
||||||
@close="closePreview"
|
@close="closePreview"
|
||||||
/>
|
/>
|
||||||
|
<DocumentEditModal
|
||||||
|
:visible="editModalVisible"
|
||||||
|
:document="editingDocument"
|
||||||
|
@close="editModalVisible = false"
|
||||||
|
@updated="handleDocumentUpdated"
|
||||||
|
/>
|
||||||
<main class="container mx-auto px-6 py-10">
|
<main class="container mx-auto px-6 py-10">
|
||||||
<div v-if="loading" class="flex flex-col items-center gap-4 py-16 text-center">
|
<div v-if="loading" class="flex flex-col items-center gap-4 py-16 text-center">
|
||||||
<span class="loading loading-spinner loading-lg" aria-hidden="true" />
|
<span class="loading loading-spinner loading-lg" aria-hidden="true" />
|
||||||
@@ -167,9 +173,11 @@
|
|||||||
v-else
|
v-else
|
||||||
:documents="productDocuments"
|
:documents="productDocuments"
|
||||||
:can-delete="canEdit"
|
:can-delete="canEdit"
|
||||||
|
:can-edit="true"
|
||||||
:delete-disabled="uploadingDocuments || saving"
|
:delete-disabled="uploadingDocuments || saving"
|
||||||
empty-text="Aucun document n'est associé à ce produit pour le moment."
|
empty-text="Aucun document n'est associé à ce produit pour le moment."
|
||||||
@preview="openPreview"
|
@preview="openPreview"
|
||||||
|
@edit="openEditModal"
|
||||||
@delete="removeDocument"
|
@delete="removeDocument"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -244,6 +252,7 @@ const {
|
|||||||
loadDocumentsByProduct,
|
loadDocumentsByProduct,
|
||||||
uploadDocuments: uploadProductDocuments,
|
uploadDocuments: uploadProductDocuments,
|
||||||
deleteDocument: deleteProductDocument,
|
deleteDocument: deleteProductDocument,
|
||||||
|
updateDocument,
|
||||||
} = useDocuments()
|
} = useDocuments()
|
||||||
const { ensureConstructeurs } = useConstructeurs()
|
const { ensureConstructeurs } = useConstructeurs()
|
||||||
const {
|
const {
|
||||||
@@ -265,6 +274,8 @@ const loadingDocuments = ref(false)
|
|||||||
const productDocuments = ref<any[]>([])
|
const productDocuments = ref<any[]>([])
|
||||||
const previewDocument = ref<any | null>(null)
|
const previewDocument = ref<any | null>(null)
|
||||||
const previewVisible = ref(false)
|
const previewVisible = ref(false)
|
||||||
|
const editingDocument = ref<any | null>(null)
|
||||||
|
const editModalVisible = ref(false)
|
||||||
|
|
||||||
const historyFieldLabels: Record<string, string> = {
|
const historyFieldLabels: Record<string, string> = {
|
||||||
name: 'Nom',
|
name: 'Nom',
|
||||||
@@ -307,6 +318,23 @@ const openPreview = (doc: any) => {
|
|||||||
}
|
}
|
||||||
const closePreview = () => { previewVisible.value = false; previewDocument.value = null }
|
const closePreview = () => { previewVisible.value = false; previewDocument.value = null }
|
||||||
|
|
||||||
|
const openEditModal = (doc: any) => {
|
||||||
|
editingDocument.value = doc
|
||||||
|
editModalVisible.value = true
|
||||||
|
}
|
||||||
|
const handleDocumentUpdated = async (data: { name?: string; type?: string }) => {
|
||||||
|
if (!editingDocument.value?.id) return
|
||||||
|
const result = await updateDocument(editingDocument.value.id, data)
|
||||||
|
if (result.success) {
|
||||||
|
const idx = productDocuments.value.findIndex((d: any) => d.id === editingDocument.value?.id)
|
||||||
|
if (idx !== -1) {
|
||||||
|
productDocuments.value[idx] = { ...productDocuments.value[idx], ...data }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
editModalVisible.value = false
|
||||||
|
editingDocument.value = null
|
||||||
|
}
|
||||||
|
|
||||||
const loadProduct = async () => {
|
const loadProduct = async () => {
|
||||||
const id = route.params.id
|
const id = route.params.id
|
||||||
if (!id || typeof id !== 'string') {
|
if (!id || typeof id !== 'string') {
|
||||||
|
|||||||
Reference in New Issue
Block a user