feat(catalog): add description column with hover popover + skeleton edit guard
- Add description column to pieces and component catalog tables - Show full text in a popover on hover for truncated descriptions - Block skeleton editing when machines are linked (warning alert) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -116,6 +116,7 @@
|
|||||||
<th class="w-24">Aperçu</th>
|
<th class="w-24">Aperçu</th>
|
||||||
<th>Nom</th>
|
<th>Nom</th>
|
||||||
<th>Référence</th>
|
<th>Référence</th>
|
||||||
|
<th>Description</th>
|
||||||
<th>Type de composant</th>
|
<th>Type de composant</th>
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -130,6 +131,15 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>{{ component.name || 'Composant sans nom' }}</td>
|
<td>{{ component.name || 'Composant sans nom' }}</td>
|
||||||
<td>{{ component.reference || '—' }}</td>
|
<td>{{ component.reference || '—' }}</td>
|
||||||
|
<td class="max-w-xs">
|
||||||
|
<div v-if="component.description" class="group relative">
|
||||||
|
<span class="block cursor-help truncate">{{ component.description }}</span>
|
||||||
|
<div class="pointer-events-none invisible absolute left-0 top-full z-50 mt-1 max-w-sm overflow-hidden rounded-lg border border-base-300 bg-base-100 p-3 text-sm shadow-lg group-hover:pointer-events-auto group-hover:visible">
|
||||||
|
<p class="break-words whitespace-pre-wrap">{{ component.description }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span v-else>—</span>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<NuxtLink
|
<NuxtLink
|
||||||
v-if="component.typeComposant?.id"
|
v-if="component.typeComposant?.id"
|
||||||
|
|||||||
@@ -115,6 +115,7 @@
|
|||||||
<th class="w-24">Aperçu</th>
|
<th class="w-24">Aperçu</th>
|
||||||
<th>Nom</th>
|
<th>Nom</th>
|
||||||
<th>Référence</th>
|
<th>Référence</th>
|
||||||
|
<th>Description</th>
|
||||||
<th>Fournisseurs</th>
|
<th>Fournisseurs</th>
|
||||||
<th>Type de pièce</th>
|
<th>Type de pièce</th>
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
@@ -130,6 +131,15 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>{{ row.piece.name || 'Pièce sans nom' }}</td>
|
<td>{{ row.piece.name || 'Pièce sans nom' }}</td>
|
||||||
<td>{{ row.piece.reference || '—' }}</td>
|
<td>{{ row.piece.reference || '—' }}</td>
|
||||||
|
<td class="max-w-xs">
|
||||||
|
<div v-if="row.piece.description" class="group relative">
|
||||||
|
<span class="block cursor-help truncate">{{ row.piece.description }}</span>
|
||||||
|
<div class="pointer-events-none invisible absolute left-0 top-full z-50 mt-1 max-w-sm overflow-hidden rounded-lg border border-base-300 bg-base-100 p-3 text-sm shadow-lg group-hover:pointer-events-auto group-hover:visible">
|
||||||
|
<p class="break-words whitespace-pre-wrap">{{ row.piece.description }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span v-else>—</span>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div
|
<div
|
||||||
v-if="row.suppliers.visible.length"
|
v-if="row.suppliers.visible.length"
|
||||||
|
|||||||
@@ -8,6 +8,26 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Locked: machines linked -->
|
||||||
|
<div v-else-if="type && hasMachines" class="my-8">
|
||||||
|
<div class="card bg-base-100 shadow-xl">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="flex items-center justify-between mb-6">
|
||||||
|
<h2 class="card-title text-2xl">
|
||||||
|
{{ type.name }}
|
||||||
|
</h2>
|
||||||
|
<NuxtLink to="/machine-skeleton" class="btn btn-outline">
|
||||||
|
Retour
|
||||||
|
</NuxtLink>
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
<IconLucideTriangleAlert class="w-5 h-5" />
|
||||||
|
<span>Ce squelette ne peut pas être modifié car des machines y sont rattachées.</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Edit Form -->
|
<!-- Edit Form -->
|
||||||
<div v-else-if="type" class="my-8">
|
<div v-else-if="type" class="my-8">
|
||||||
<div class="card bg-base-100 shadow-xl">
|
<div class="card bg-base-100 shadow-xl">
|
||||||
@@ -48,11 +68,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, computed, onMounted } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { useMachineTypesApi } from '~/composables/useMachineTypesApi'
|
import { useMachineTypesApi } from '~/composables/useMachineTypesApi'
|
||||||
import { useToast } from '~/composables/useToast'
|
import { useToast } from '~/composables/useToast'
|
||||||
import { extractRelationId } from '~/shared/apiRelations'
|
import { extractRelationId } from '~/shared/apiRelations'
|
||||||
|
import IconLucideTriangleAlert from '~icons/lucide/triangle-alert'
|
||||||
|
|
||||||
const { canEdit } = usePermissions()
|
const { canEdit } = usePermissions()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@@ -63,6 +84,10 @@ const { showSuccess, showError } = useToast()
|
|||||||
const type = ref(null)
|
const type = ref(null)
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const saving = ref(false)
|
const saving = ref(false)
|
||||||
|
const hasMachines = computed(() => {
|
||||||
|
const machines = type.value?.machines
|
||||||
|
return Array.isArray(machines) && machines.length > 0
|
||||||
|
})
|
||||||
|
|
||||||
// Données éditées du type
|
// Données éditées du type
|
||||||
const editedType = ref({
|
const editedType = ref({
|
||||||
|
|||||||
Reference in New Issue
Block a user