- Replace auto-save-on-blur with single "Enregistrer" button - Add Cancel button that resets local state - Expose saveFieldDefinitions via defineExpose on MachineInfoCard - Remove standalone save button from MachineCustomFieldDefEditor - Add saveAllMachineCustomFields batch method - Add submitEdition/cancelEdition/saving/canSubmit to orchestrator - Show diff summary badges in version list entries - Show link changes in restore modal description Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
199 lines
8.1 KiB
Vue
199 lines
8.1 KiB
Vue
<template>
|
|
<dialog ref="dialogRef" class="modal" :class="{ 'modal-open': visible }">
|
|
<div class="modal-box max-w-lg">
|
|
<h3 class="text-lg font-bold">Restaurer la version {{ preview?.version }}</h3>
|
|
|
|
<div v-if="!preview" class="flex justify-center py-8">
|
|
<span class="loading loading-spinner loading-md" />
|
|
</div>
|
|
|
|
<template v-else>
|
|
<div class="mt-4 space-y-4">
|
|
<!-- Restore mode explanation -->
|
|
<div
|
|
class="alert text-sm"
|
|
:class="preview.restoreMode === 'full' ? 'alert-info' : 'alert-warning'"
|
|
>
|
|
<div class="flex flex-col gap-1">
|
|
<!-- FULL MODE -->
|
|
<template v-if="preview.restoreMode === 'full'">
|
|
<span class="font-semibold">Restauration complete</span>
|
|
|
|
<!-- Machine: always full, no category -->
|
|
<template v-if="entityType === 'machine'">
|
|
<span>Tous les elements de la machine seront restaures :</span>
|
|
<ul class="ml-4 list-disc text-xs">
|
|
<li>Nom, reference, prix</li>
|
|
<li>Site</li>
|
|
<li>Fournisseurs</li>
|
|
<li>Composants, pieces et produits lies</li>
|
|
<li>Champs personnalises</li>
|
|
</ul>
|
|
</template>
|
|
|
|
<!-- Composant -->
|
|
<template v-else-if="entityType === 'composant'">
|
|
<span>La categorie est identique. Tous les elements du composant seront restaures :</span>
|
|
<ul class="ml-4 list-disc text-xs">
|
|
<li>Nom, reference, description, prix</li>
|
|
<li>Fournisseurs</li>
|
|
<li>Structure : pieces, sous-composants et produits lies</li>
|
|
<li>Champs personnalises</li>
|
|
</ul>
|
|
</template>
|
|
|
|
<!-- Piece -->
|
|
<template v-else-if="entityType === 'piece'">
|
|
<span>La categorie est identique. Tous les elements de la piece seront restaures :</span>
|
|
<ul class="ml-4 list-disc text-xs">
|
|
<li>Nom, reference, description, prix</li>
|
|
<li>Fournisseurs</li>
|
|
<li>Produits lies</li>
|
|
<li>Champs personnalises</li>
|
|
</ul>
|
|
</template>
|
|
|
|
<!-- Product -->
|
|
<template v-else-if="entityType === 'product'">
|
|
<span>La categorie est identique. Tous les elements du produit seront restaures :</span>
|
|
<ul class="ml-4 list-disc text-xs">
|
|
<li>Nom, reference, prix fournisseur</li>
|
|
<li>Fournisseurs</li>
|
|
<li>Champs personnalises</li>
|
|
</ul>
|
|
</template>
|
|
</template>
|
|
|
|
<!-- PARTIAL MODE (never for machines) -->
|
|
<template v-else>
|
|
<span class="font-semibold">Restauration partielle</span>
|
|
|
|
<!-- Composant -->
|
|
<template v-if="entityType === 'composant'">
|
|
<span>La categorie du composant a change depuis cette version. Seuls les champs de base seront restaures :</span>
|
|
<ul class="ml-4 list-disc text-xs">
|
|
<li>Nom, reference, description, prix</li>
|
|
<li>Fournisseurs</li>
|
|
</ul>
|
|
<span class="mt-1 text-xs font-medium">Ne seront PAS modifies :</span>
|
|
<ul class="ml-4 list-disc text-xs opacity-70">
|
|
<li>Structure actuelle (pieces, sous-composants, produits lies)</li>
|
|
<li>Champs personnalises actuels</li>
|
|
</ul>
|
|
</template>
|
|
|
|
<!-- Piece -->
|
|
<template v-else-if="entityType === 'piece'">
|
|
<span>La categorie de la piece a change depuis cette version. Seuls les champs de base seront restaures :</span>
|
|
<ul class="ml-4 list-disc text-xs">
|
|
<li>Nom, reference, description, prix</li>
|
|
<li>Fournisseurs</li>
|
|
</ul>
|
|
<span class="mt-1 text-xs font-medium">Ne seront PAS modifies :</span>
|
|
<ul class="ml-4 list-disc text-xs opacity-70">
|
|
<li>Produits lies actuels</li>
|
|
<li>Champs personnalises actuels</li>
|
|
</ul>
|
|
</template>
|
|
|
|
<!-- Product -->
|
|
<template v-else-if="entityType === 'product'">
|
|
<span>La categorie du produit a change depuis cette version. Seuls les champs de base seront restaures :</span>
|
|
<ul class="ml-4 list-disc text-xs">
|
|
<li>Nom, reference, prix fournisseur</li>
|
|
<li>Fournisseurs</li>
|
|
</ul>
|
|
<span class="mt-1 text-xs font-medium">Ne seront PAS modifies :</span>
|
|
<ul class="ml-4 list-disc text-xs opacity-70">
|
|
<li>Champs personnalises actuels</li>
|
|
</ul>
|
|
</template>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Diff -->
|
|
<div v-if="Object.keys(preview.diff).length" class="space-y-2">
|
|
<h4 class="text-sm font-semibold">Changements qui seront appliques</h4>
|
|
<ul class="space-y-1 text-sm">
|
|
<li
|
|
v-for="(change, field) in preview.diff"
|
|
:key="field"
|
|
class="flex flex-col rounded-md border border-base-200 px-3 py-2"
|
|
>
|
|
<span class="font-medium text-base-content">{{ fieldLabels[field] || formatFieldLabel(String(field)) }}</span>
|
|
<span class="text-xs text-error line-through">{{ formatValue(change.current) }}</span>
|
|
<span class="text-xs text-success">{{ formatValue(change.restored) }}</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div v-else class="text-sm text-base-content/60">
|
|
Aucune difference detectee — l'entite est deja dans l'etat de cette version.
|
|
</div>
|
|
|
|
<!-- Warnings -->
|
|
<div v-if="preview.warnings.length" class="space-y-1">
|
|
<h4 class="text-sm font-semibold text-warning">Avertissements</h4>
|
|
<ul class="space-y-1">
|
|
<li
|
|
v-for="(warning, i) in preview.warnings"
|
|
:key="i"
|
|
class="alert alert-warning py-2 text-xs"
|
|
>
|
|
{{ warning.message }}
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal-action">
|
|
<button class="btn btn-ghost btn-sm md:btn-md" :disabled="restoring" @click="$emit('close')">
|
|
Annuler
|
|
</button>
|
|
<button class="btn btn-primary btn-sm md:btn-md" :disabled="restoring" @click="$emit('confirm')">
|
|
<span v-if="restoring" class="loading loading-spinner loading-sm mr-2" />
|
|
Confirmer la restauration
|
|
</button>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
<form method="dialog" class="modal-backdrop" @click="$emit('close')">
|
|
<button type="button">close</button>
|
|
</form>
|
|
</dialog>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { RestorePreview } from '~/composables/useEntityVersions'
|
|
|
|
defineProps<{
|
|
visible: boolean
|
|
preview: RestorePreview | null
|
|
restoring: boolean
|
|
fieldLabels: Record<string, string>
|
|
entityType: 'machine' | 'composant' | 'piece' | 'product'
|
|
}>()
|
|
|
|
defineEmits<{
|
|
close: []
|
|
confirm: []
|
|
}>()
|
|
|
|
const formatFieldLabel = (field: string): string => {
|
|
if (field.startsWith('customField:')) {
|
|
return `Champ perso : ${field.replace('customField:', '')}`
|
|
}
|
|
return field
|
|
}
|
|
|
|
const formatValue = (value: unknown): string => {
|
|
if (value === null || value === undefined) return '—'
|
|
if (Array.isArray(value)) {
|
|
return value.map((v) => (typeof v === 'object' && v !== null ? (v as any).name || (v as any).id || JSON.stringify(v) : String(v))).join(', ') || '—'
|
|
}
|
|
if (typeof value === 'object') return JSON.stringify(value)
|
|
return String(value)
|
|
}
|
|
</script>
|