refactor(machines) : remove TypeMachine skeleton system, simplify machine creation
- Remove TypeEdit*, TypeInfoDisplay, MachineSkeletonSummary, MachineCreatePreview components - Remove machine-skeleton pages and type pages - Remove useMachineTypesApi, useMachineSkeletonEditor, useMachineCreateSelections composables - Add AddEntityToMachineModal for direct entity linking - Update machine detail/create pages for direct custom fields - Fix SearchSelect, category display, and ipartial search filters Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,29 +1,55 @@
|
||||
<template>
|
||||
<div class="card bg-base-100 shadow-lg">
|
||||
<div class="card-body space-y-4">
|
||||
<DocumentPreviewModal
|
||||
:document="previewDocument"
|
||||
:visible="previewVisible"
|
||||
:documents="previewDocumentList"
|
||||
@close="closePreview"
|
||||
/>
|
||||
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<h2 class="card-title">Produits associés</h2>
|
||||
<p class="text-xs text-gray-500">
|
||||
Produits sélectionnés directement pour cette machine selon le squelette.
|
||||
Produits sélectionnés directement pour cette machine.
|
||||
</p>
|
||||
</div>
|
||||
<span class="badge badge-outline" v-if="products.length">
|
||||
{{ products.length }} produit{{ products.length > 1 ? 's' : '' }}
|
||||
</span>
|
||||
<div class="flex items-center gap-2">
|
||||
<button
|
||||
v-if="isEditMode"
|
||||
type="button"
|
||||
class="btn btn-sm md:btn-md btn-primary"
|
||||
@click="$emit('add-product')"
|
||||
>
|
||||
Ajouter un produit
|
||||
</button>
|
||||
<span class="badge badge-outline" v-if="products.length">
|
||||
{{ products.length }} produit{{ products.length > 1 ? 's' : '' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="products.length" class="space-y-3">
|
||||
<div
|
||||
v-for="product in products"
|
||||
:key="product.id || product.name"
|
||||
class="rounded border border-base-200 bg-base-200/60 p-3 text-sm space-y-1"
|
||||
class="rounded border border-base-200 bg-base-200/60 p-3 text-sm space-y-2 relative"
|
||||
>
|
||||
<button
|
||||
v-if="isEditMode"
|
||||
type="button"
|
||||
class="btn btn-error btn-xs absolute top-2 right-2"
|
||||
title="Supprimer ce produit"
|
||||
@click="$emit('remove-product', (product.linkId || product.id) as string)"
|
||||
>
|
||||
Supprimer
|
||||
</button>
|
||||
<div class="flex items-center justify-between flex-wrap gap-2">
|
||||
<p class="font-semibold text-base-content">
|
||||
{{ product.name }}
|
||||
</p>
|
||||
<span class="badge badge-ghost badge-sm">
|
||||
<span v-if="product.groupLabel" class="badge badge-ghost badge-sm">
|
||||
{{ product.groupLabel }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -39,6 +65,53 @@
|
||||
<span class="font-medium">Prix indicatif :</span>
|
||||
<span class="ml-1">{{ product.priceLabel }}</span>
|
||||
</p>
|
||||
|
||||
<!-- Documents liés au produit -->
|
||||
<div v-if="product.documents?.length" class="mt-2 space-y-1">
|
||||
<p class="text-xs font-medium text-base-content/70">Documents :</p>
|
||||
<div
|
||||
v-for="doc in product.documents"
|
||||
:key="doc.id || doc.name"
|
||||
class="flex items-center justify-between gap-3 rounded border border-base-200 bg-base-100 px-3 py-2"
|
||||
>
|
||||
<div class="flex items-center gap-3 text-xs">
|
||||
<div
|
||||
class="flex-shrink-0 overflow-hidden rounded-md border border-base-200 bg-base-200/70 flex items-center justify-center h-8 w-6"
|
||||
>
|
||||
<component
|
||||
:is="documentIcon(doc).component"
|
||||
class="h-4 w-4"
|
||||
:class="documentIcon(doc).colorClass"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-medium text-base-content">{{ doc.name }}</div>
|
||||
<div class="text-xs text-base-content/60">
|
||||
{{ doc.mimeType || 'Inconnu' }} • {{ formatSize(doc.size) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-xs">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-ghost btn-xs"
|
||||
:disabled="!canPreviewDocument(doc)"
|
||||
:title="canPreviewDocument(doc) ? 'Consulter le document' : 'Aucun aperçu disponible pour ce type'"
|
||||
@click="openPreview(doc, product.documents || [])"
|
||||
>
|
||||
Consulter
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-ghost btn-xs"
|
||||
@click="downloadDocument(doc)"
|
||||
>
|
||||
Télécharger
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p v-else class="text-xs text-gray-500">
|
||||
@@ -49,14 +122,53 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import DocumentPreviewModal from '~/components/DocumentPreviewModal.vue'
|
||||
import { canPreviewDocument } from '~/utils/documentPreview'
|
||||
import {
|
||||
formatSize,
|
||||
documentIcon,
|
||||
downloadDocument,
|
||||
} from '~/shared/utils/documentDisplayUtils'
|
||||
|
||||
defineProps<{
|
||||
products: Array<{
|
||||
id?: string | null
|
||||
linkId?: string | null
|
||||
name?: string
|
||||
reference?: string | null
|
||||
supplierLabel?: string | null
|
||||
priceLabel?: string | null
|
||||
groupLabel?: string
|
||||
documents?: Array<{
|
||||
id?: string
|
||||
name?: string
|
||||
mimeType?: string
|
||||
size?: number
|
||||
fileUrl?: string
|
||||
downloadUrl?: string
|
||||
}>
|
||||
}>
|
||||
isEditMode: boolean
|
||||
}>()
|
||||
|
||||
defineEmits<{
|
||||
'add-product': []
|
||||
'remove-product': [linkId: string]
|
||||
}>()
|
||||
|
||||
const previewDocument = ref<any>(null)
|
||||
const previewVisible = ref(false)
|
||||
const previewDocumentList = ref<any[]>([])
|
||||
|
||||
const openPreview = (doc: any, docs: any[]) => {
|
||||
previewDocument.value = doc
|
||||
previewDocumentList.value = docs
|
||||
previewVisible.value = true
|
||||
}
|
||||
|
||||
const closePreview = () => {
|
||||
previewVisible.value = false
|
||||
previewDocument.value = null
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user