fix(catalog) : replace blocking delete guard with confirmation dialog

Show cascade-delete impact (documents, machine links, custom fields)
in a confirmation modal instead of blocking deletion entirely.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Matthieu
2026-03-06 10:58:41 +01:00
parent 032b3b33c9
commit 6c2f84dd3a
2 changed files with 24 additions and 32 deletions

View File

@@ -147,13 +147,11 @@ import { computed, onMounted } from 'vue'
import DataTable from '~/components/common/DataTable.vue'
import { usePieces } from '~/composables/usePieces'
import { usePieceTypes } from '~/composables/usePieceTypes'
import { useToast } from '~/composables/useToast'
import { useDataTable } from '~/composables/useDataTable'
import DocumentThumbnail from '~/components/DocumentThumbnail.vue'
import { isImageDocument, isPdfDocument } from '~/utils/documentPreview'
const { canEdit } = usePermissions()
const { showError } = useToast()
const { pieces, total, loadPieces, loading: loadingPiecesRef, deletePiece } = usePieces()
const { pieceTypes, loadPieceTypes } = usePieceTypes()
const loadingPieces = computed(() => loadingPiecesRef.value)
@@ -280,29 +278,27 @@ const buildPieceSuppliersDisplay = (piece: Record<string, any>) => {
return { suppliers, visible, overflow, tooltip: suppliers.length ? suppliers.join(', ') : '' }
}
const resolveDeleteGuard = (piece: Record<string, any>) => {
const blockingReasons: string[] = []
const resolveDeleteImpact = (piece: Record<string, any>) => {
const impacts: string[] = []
const machineLinks = Array.isArray(piece?.machineLinks) ? piece.machineLinks.length : piece?.machineLinksCount ?? 0
const documents = Array.isArray(piece?.documents) ? piece.documents.length : piece?.documentsCount ?? 0
const customFields = Array.isArray(piece?.customFieldValues) ? piece.customFieldValues.length : piece?.customFieldValuesCount ?? 0
if (machineLinks > 0) blockingReasons.push(`${machineLinks} liaison${machineLinks > 1 ? 's' : ''} machine`)
if (documents > 0) blockingReasons.push(`${documents} document${documents > 1 ? 's' : ''}`)
return { blockingReasons, hasCustomFields: customFields > 0 }
if (machineLinks > 0) impacts.push(`${machineLinks} liaison${machineLinks > 1 ? 's' : ''} machine`)
if (documents > 0) impacts.push(`${documents} document${documents > 1 ? 's' : ''}`)
if (customFields > 0) impacts.push(`${customFields} valeur${customFields > 1 ? 's' : ''} de champs personnalisés`)
return impacts
}
const handleDeletePiece = async (piece: Record<string, any>) => {
const { blockingReasons, hasCustomFields } = resolveDeleteGuard(piece)
if (blockingReasons.length) {
showError(`Impossible de supprimer cette pièce car elle possède encore: ${blockingReasons.join(', ')}. Supprimez ou détachez ces éléments avant de réessayer.`)
return
}
const pieceName = piece?.name || 'cette pièce'
const confirmLines = [`Voulez-vous vraiment supprimer ${pieceName} ?`]
if (hasCustomFields) {
confirmLines.push('Les valeurs de champs personnalisés associées seront également supprimées.')
const impacts = resolveDeleteImpact(piece)
const lines = [`Voulez-vous vraiment supprimer « ${pieceName} » ?`]
if (impacts.length) {
lines.push(`Cela supprimera également :\n• ${impacts.join('\n• ')}`)
}
lines.push('Cette action est irréversible.')
const { confirm } = useConfirm()
const confirmed = await confirm({ message: confirmLines.join('\n\n') })
const confirmed = await confirm({ title: 'Supprimer la pièce', message: lines.join('\n\n'), dangerous: true })
if (!confirmed) return
await deletePiece(piece.id)
fetchPieces()