feat(machine) : single save button + link versioning display
- 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>
This commit is contained in:
@@ -53,6 +53,15 @@
|
|||||||
<span>{{ formatDate(entry.createdAt) }}</span>
|
<span>{{ formatDate(entry.createdAt) }}</span>
|
||||||
<span v-if="entry.actor">· {{ entry.actor.label }}</span>
|
<span v-if="entry.actor">· {{ entry.actor.label }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="entry.diff && Object.keys(entry.diff).length" class="mt-1 flex flex-wrap gap-1">
|
||||||
|
<span
|
||||||
|
v-for="(change, field) in entry.diff"
|
||||||
|
:key="field"
|
||||||
|
class="badge badge-ghost badge-xs"
|
||||||
|
>
|
||||||
|
{{ formatDiffEntry(String(field), change) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
v-if="canRestore && entry.version !== currentVersion"
|
v-if="canRestore && entry.version !== currentVersion"
|
||||||
@@ -117,6 +126,16 @@ const targetVersion = ref<number | null>(null)
|
|||||||
const actionLabel = (action: string) => historyActionLabel(action)
|
const actionLabel = (action: string) => historyActionLabel(action)
|
||||||
const formatDate = (date: string) => formatHistoryDate(date)
|
const formatDate = (date: string) => formatHistoryDate(date)
|
||||||
|
|
||||||
|
const formatDiffEntry = (field: string, change: { from: unknown; to: unknown }): string => {
|
||||||
|
const label = props.fieldLabels[field] || field
|
||||||
|
// Link changes (addedComponent, removedPiece, etc.) have {id, name} as value
|
||||||
|
const val = change.to ?? change.from
|
||||||
|
if (val && typeof val === 'object' && 'name' in (val as Record<string, unknown>)) {
|
||||||
|
return `${label}: ${(val as Record<string, unknown>).name}`
|
||||||
|
}
|
||||||
|
return label
|
||||||
|
}
|
||||||
|
|
||||||
const handleRestore = async (version: number) => {
|
const handleRestore = async (version: number) => {
|
||||||
targetVersion.value = version
|
targetVersion.value = version
|
||||||
previewData.value = null
|
previewData.value = null
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
<li>Nom, reference, prix</li>
|
<li>Nom, reference, prix</li>
|
||||||
<li>Site</li>
|
<li>Site</li>
|
||||||
<li>Fournisseurs</li>
|
<li>Fournisseurs</li>
|
||||||
|
<li>Composants, pieces et produits lies</li>
|
||||||
<li>Champs personnalises</li>
|
<li>Champs personnalises</li>
|
||||||
</ul>
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,19 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<section class="space-y-3">
|
<section class="space-y-3">
|
||||||
<div class="flex items-center justify-between">
|
<h3 class="text-sm font-semibold">
|
||||||
<h3 class="text-sm font-semibold">
|
Définitions des champs personnalisés
|
||||||
Définitions des champs personnalisés
|
</h3>
|
||||||
</h3>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-primary btn-sm"
|
|
||||||
:disabled="saving"
|
|
||||||
@click="$emit('save')"
|
|
||||||
>
|
|
||||||
<span v-if="saving" class="loading loading-spinner loading-xs" />
|
|
||||||
Enregistrer les champs
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p v-if="!fields.length" class="text-xs text-gray-500">
|
<p v-if="!fields.length" class="text-xs text-gray-500">
|
||||||
Aucun champ personnalisé défini. Cliquez sur « Ajouter » pour en créer un.
|
Aucun champ personnalisé défini. Cliquez sur « Ajouter » pour en créer un.
|
||||||
@@ -117,7 +106,6 @@ defineProps<{
|
|||||||
}>()
|
}>()
|
||||||
|
|
||||||
defineEmits<{
|
defineEmits<{
|
||||||
save: []
|
|
||||||
'add-field': []
|
'add-field': []
|
||||||
'remove-field': [index: number]
|
'remove-field': [index: number]
|
||||||
}>()
|
}>()
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
type="text"
|
type="text"
|
||||||
class="input input-bordered"
|
class="input input-bordered"
|
||||||
@input="$emit('update:machine-name', ($event.target as HTMLInputElement).value)"
|
@input="$emit('update:machine-name', ($event.target as HTMLInputElement).value)"
|
||||||
@blur="$emit('blur-field')"
|
|
||||||
/>
|
/>
|
||||||
<div v-else class="input input-bordered bg-base-200">
|
<div v-else class="input input-bordered bg-base-200">
|
||||||
{{ machineName }}
|
{{ machineName }}
|
||||||
@@ -28,7 +27,7 @@
|
|||||||
v-if="isEditMode"
|
v-if="isEditMode"
|
||||||
:value="machineSiteId"
|
:value="machineSiteId"
|
||||||
class="select select-bordered"
|
class="select select-bordered"
|
||||||
@change="$emit('update:machine-site-id', ($event.target as HTMLSelectElement).value); $emit('blur-field')"
|
@change="$emit('update:machine-site-id', ($event.target as HTMLSelectElement).value)"
|
||||||
>
|
>
|
||||||
<option value="">Sélectionner un site</option>
|
<option value="">Sélectionner un site</option>
|
||||||
<option
|
<option
|
||||||
@@ -54,7 +53,6 @@
|
|||||||
type="text"
|
type="text"
|
||||||
class="input input-bordered"
|
class="input input-bordered"
|
||||||
@input="$emit('update:machine-reference', ($event.target as HTMLInputElement).value)"
|
@input="$emit('update:machine-reference', ($event.target as HTMLInputElement).value)"
|
||||||
@blur="$emit('blur-field')"
|
|
||||||
/>
|
/>
|
||||||
<div v-else class="input input-bordered bg-base-200">
|
<div v-else class="input input-bordered bg-base-200">
|
||||||
{{ machineReference }}
|
{{ machineReference }}
|
||||||
@@ -115,7 +113,6 @@
|
|||||||
class="input input-bordered input-sm"
|
class="input input-bordered input-sm"
|
||||||
:required="field.required"
|
:required="field.required"
|
||||||
@input="$emit('set-custom-field-value', field, ($event.target as HTMLInputElement).value)"
|
@input="$emit('set-custom-field-value', field, ($event.target as HTMLInputElement).value)"
|
||||||
@blur="$emit('update-custom-field', field)"
|
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
v-else-if="field.type === 'number'"
|
v-else-if="field.type === 'number'"
|
||||||
@@ -124,7 +121,6 @@
|
|||||||
class="input input-bordered input-sm"
|
class="input input-bordered input-sm"
|
||||||
:required="field.required"
|
:required="field.required"
|
||||||
@input="$emit('set-custom-field-value', field, ($event.target as HTMLInputElement).value)"
|
@input="$emit('set-custom-field-value', field, ($event.target as HTMLInputElement).value)"
|
||||||
@blur="$emit('update-custom-field', field)"
|
|
||||||
/>
|
/>
|
||||||
<select
|
<select
|
||||||
v-else-if="field.type === 'select'"
|
v-else-if="field.type === 'select'"
|
||||||
@@ -132,7 +128,6 @@
|
|||||||
class="select select-bordered select-sm"
|
class="select select-bordered select-sm"
|
||||||
:required="field.required"
|
:required="field.required"
|
||||||
@change="$emit('set-custom-field-value', field, ($event.target as HTMLSelectElement).value)"
|
@change="$emit('set-custom-field-value', field, ($event.target as HTMLSelectElement).value)"
|
||||||
@blur="$emit('update-custom-field', field)"
|
|
||||||
>
|
>
|
||||||
<option value="">Sélectionner...</option>
|
<option value="">Sélectionner...</option>
|
||||||
<option
|
<option
|
||||||
@@ -149,7 +144,6 @@
|
|||||||
class="toggle toggle-primary toggle-sm"
|
class="toggle toggle-primary toggle-sm"
|
||||||
:checked="String(field.value).toLowerCase() === 'true'"
|
:checked="String(field.value).toLowerCase() === 'true'"
|
||||||
@change="$emit('set-custom-field-value', field, ($event.target as HTMLInputElement).checked ? 'true' : 'false')"
|
@change="$emit('set-custom-field-value', field, ($event.target as HTMLInputElement).checked ? 'true' : 'false')"
|
||||||
@blur="$emit('update-custom-field', field)"
|
|
||||||
>
|
>
|
||||||
<span class="text-sm" :class="String(field.value).toLowerCase() === 'true' ? 'text-success font-medium' : 'text-base-content/60'">{{ String(field.value).toLowerCase() === 'true' ? 'Oui' : 'Non' }}</span>
|
<span class="text-sm" :class="String(field.value).toLowerCase() === 'true' ? 'text-success font-medium' : 'text-base-content/60'">{{ String(field.value).toLowerCase() === 'true' ? 'Oui' : 'Non' }}</span>
|
||||||
</label>
|
</label>
|
||||||
@@ -160,7 +154,6 @@
|
|||||||
class="input input-bordered input-sm"
|
class="input input-bordered input-sm"
|
||||||
:required="field.required"
|
:required="field.required"
|
||||||
@input="$emit('set-custom-field-value', field, ($event.target as HTMLInputElement).value)"
|
@input="$emit('set-custom-field-value', field, ($event.target as HTMLInputElement).value)"
|
||||||
@blur="$emit('update-custom-field', field)"
|
|
||||||
/>
|
/>
|
||||||
<div v-else class="text-xs text-error">
|
<div v-else class="text-xs text-error">
|
||||||
Type de champ non pris en charge
|
Type de champ non pris en charge
|
||||||
@@ -184,7 +177,6 @@
|
|||||||
:on-drag-enter="fieldDefs.onDragEnter"
|
:on-drag-enter="fieldDefs.onDragEnter"
|
||||||
:on-drop="fieldDefs.onDrop"
|
:on-drop="fieldDefs.onDrop"
|
||||||
:on-drag-end="fieldDefs.onDragEnd"
|
:on-drag-end="fieldDefs.onDragEnd"
|
||||||
@save="fieldDefs.saveDefinitions()"
|
|
||||||
@add-field="fieldDefs.addField()"
|
@add-field="fieldDefs.addField()"
|
||||||
@remove-field="fieldDefs.removeField($event)"
|
@remove-field="fieldDefs.removeField($event)"
|
||||||
/>
|
/>
|
||||||
@@ -224,9 +216,7 @@ const emit = defineEmits<{
|
|||||||
'update:machine-reference': [value: string]
|
'update:machine-reference': [value: string]
|
||||||
'update:machine-site-id': [value: string]
|
'update:machine-site-id': [value: string]
|
||||||
'update:constructeur-ids': [ids: unknown]
|
'update:constructeur-ids': [ids: unknown]
|
||||||
'blur-field': []
|
|
||||||
'set-custom-field-value': [field: any, value: unknown]
|
'set-custom-field-value': [field: any, value: unknown]
|
||||||
'update-custom-field': [field: any]
|
|
||||||
'custom-fields-saved': []
|
'custom-fields-saved': []
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
@@ -239,4 +229,8 @@ const fieldDefs = useMachineCustomFieldDefs({
|
|||||||
watch(() => props.machineCustomFieldDefs, (newDefs) => {
|
watch(() => props.machineCustomFieldDefs, (newDefs) => {
|
||||||
fieldDefs.reinit(newDefs)
|
fieldDefs.reinit(newDefs)
|
||||||
}, { deep: true })
|
}, { deep: true })
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
saveFieldDefinitions: () => fieldDefs.saveDefinitions(),
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -376,6 +376,58 @@ export function useMachineDetailCustomFields(deps: MachineDetailCustomFieldsDeps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const saveAllMachineCustomFields = async () => {
|
||||||
|
if (!machine.value) return
|
||||||
|
|
||||||
|
const fields = Array.isArray(machineCustomFields.value) ? machineCustomFields.value : []
|
||||||
|
const fieldsToSave = fields.filter(
|
||||||
|
(field) => field.value !== undefined && field.value !== null && String(field.value).trim() !== '',
|
||||||
|
)
|
||||||
|
|
||||||
|
for (const field of fieldsToSave) {
|
||||||
|
const { id: customFieldId, customFieldValueId } = field
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (customFieldValueId) {
|
||||||
|
await updateCustomFieldValueApi(customFieldValueId as string, {
|
||||||
|
value: field.value ?? '',
|
||||||
|
} as any)
|
||||||
|
} else if (customFieldId) {
|
||||||
|
const result: any = await upsertCustomFieldValue(
|
||||||
|
customFieldId as string,
|
||||||
|
'machine',
|
||||||
|
machine.value.id as string,
|
||||||
|
field.value ?? '',
|
||||||
|
)
|
||||||
|
if (result.success) {
|
||||||
|
const createdValue = result.data as AnyRecord
|
||||||
|
if (createdValue?.id) {
|
||||||
|
field.customFieldValueId = createdValue.id
|
||||||
|
if (!createdValue.customField) {
|
||||||
|
createdValue.customField = {
|
||||||
|
id: customFieldId,
|
||||||
|
name: field.name,
|
||||||
|
type: field.type,
|
||||||
|
required: field.required,
|
||||||
|
options: field.options,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const existingValues = Array.isArray(machine.value.customFieldValues)
|
||||||
|
? (machine.value.customFieldValues as AnyRecord[]).filter(
|
||||||
|
(item) => item.id !== createdValue.id,
|
||||||
|
)
|
||||||
|
: []
|
||||||
|
machine.value.customFieldValues = [...existingValues, createdValue]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors de la sauvegarde du champ personnalisé:', error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// State
|
// State
|
||||||
machineCustomFields,
|
machineCustomFields,
|
||||||
@@ -392,5 +444,6 @@ export function useMachineDetailCustomFields(deps: MachineDetailCustomFieldsDeps
|
|||||||
setMachineCustomFieldValue,
|
setMachineCustomFieldValue,
|
||||||
updateMachineCustomField,
|
updateMachineCustomField,
|
||||||
updatePieceCustomField,
|
updatePieceCustomField,
|
||||||
|
saveAllMachineCustomFields,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ export function useMachineDetailData(machineId: string) {
|
|||||||
const machine = ref<AnyRecord | null>(null)
|
const machine = ref<AnyRecord | null>(null)
|
||||||
const productDocumentsMap = ref<Map<string, AnyRecord[]>>(new Map())
|
const productDocumentsMap = ref<Map<string, AnyRecord[]>>(new Map())
|
||||||
const printAreaRef = ref<HTMLElement | null>(null)
|
const printAreaRef = ref<HTMLElement | null>(null)
|
||||||
|
const saving = ref(false)
|
||||||
|
|
||||||
// Machine fields
|
// Machine fields
|
||||||
const machineName = ref('')
|
const machineName = ref('')
|
||||||
@@ -108,6 +109,12 @@ export function useMachineDetailData(machineId: string) {
|
|||||||
|
|
||||||
// UI state
|
// UI state
|
||||||
const isEditMode = ref(false)
|
const isEditMode = ref(false)
|
||||||
|
const canSubmit = computed(() => {
|
||||||
|
if (!machine.value) return false
|
||||||
|
if (saving.value) return false
|
||||||
|
if (!machineName.value.trim()) return false
|
||||||
|
return true
|
||||||
|
})
|
||||||
const debug = ref(false)
|
const debug = ref(false)
|
||||||
|
|
||||||
const componentsCollapsed = ref(true)
|
const componentsCollapsed = ref(true)
|
||||||
@@ -146,6 +153,7 @@ export function useMachineDetailData(machineId: string) {
|
|||||||
setMachineCustomFieldValue,
|
setMachineCustomFieldValue,
|
||||||
updateMachineCustomField,
|
updateMachineCustomField,
|
||||||
updatePieceCustomField,
|
updatePieceCustomField,
|
||||||
|
saveAllMachineCustomFields,
|
||||||
} = useMachineDetailCustomFields({
|
} = useMachineDetailCustomFields({
|
||||||
machine,
|
machine,
|
||||||
isEditMode,
|
isEditMode,
|
||||||
@@ -302,6 +310,37 @@ export function useMachineDetailData(machineId: string) {
|
|||||||
pieceCollapseToggleToken.value += 1
|
pieceCollapseToggleToken.value += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const submitEdition = async () => {
|
||||||
|
if (!machine.value || saving.value) return
|
||||||
|
saving.value = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. Save machine info (name, reference, site, constructeurs)
|
||||||
|
await updateMachineInfo()
|
||||||
|
|
||||||
|
// 2. Save all custom field values
|
||||||
|
await saveAllMachineCustomFields()
|
||||||
|
|
||||||
|
// 3. Reload machine data to get fresh state
|
||||||
|
await loadMachineData()
|
||||||
|
|
||||||
|
// 4. Exit edit mode
|
||||||
|
isEditMode.value = false
|
||||||
|
toast.showSuccess('Machine mise à jour avec succès')
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors de la sauvegarde:', error)
|
||||||
|
toast.showError('Erreur lors de la sauvegarde de la machine')
|
||||||
|
} finally {
|
||||||
|
saving.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cancelEdition = () => {
|
||||||
|
initMachineFields()
|
||||||
|
syncMachineCustomFields()
|
||||||
|
isEditMode.value = false
|
||||||
|
}
|
||||||
|
|
||||||
// Print wrappers
|
// Print wrappers
|
||||||
const ensurePrintSelectionEntries = () =>
|
const ensurePrintSelectionEntries = () =>
|
||||||
_ensurePrintEntries(components.value, machinePieces.value)
|
_ensurePrintEntries(components.value, machinePieces.value)
|
||||||
@@ -451,6 +490,7 @@ export function useMachineDetailData(machineId: string) {
|
|||||||
updateMachineInfo, updateComponent, updatePieceFromComponent,
|
updateMachineInfo, updateComponent, updatePieceFromComponent,
|
||||||
updatePieceInfo, handleMachineConstructeurChange, editComponent, editPiece,
|
updatePieceInfo, handleMachineConstructeurChange, editComponent, editPiece,
|
||||||
toggleEditMode, toggleAllComponents, collapseAllComponents, toggleAllPieces,
|
toggleEditMode, toggleAllComponents, collapseAllComponents, toggleAllPieces,
|
||||||
|
saving, canSubmit, submitEdition, cancelEdition,
|
||||||
|
|
||||||
// Print
|
// Print
|
||||||
printModalOpen, printSelection, ensurePrintSelectionEntries,
|
printModalOpen, printSelection, ensurePrintSelectionEntries,
|
||||||
|
|||||||
@@ -208,9 +208,8 @@ export function useMachineDetailUpdates(deps: UseMachineDetailUpdatesDeps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleMachineConstructeurChange = async (value: unknown) => {
|
const handleMachineConstructeurChange = (value: unknown) => {
|
||||||
machineConstructeurIds.value = uniqueConstructeurIds(value)
|
machineConstructeurIds.value = uniqueConstructeurIds(value)
|
||||||
await updateMachineInfo()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const editComponent = () => {
|
const editComponent = () => {
|
||||||
|
|||||||
@@ -54,6 +54,7 @@
|
|||||||
|
|
||||||
<!-- Machine Info Card -->
|
<!-- Machine Info Card -->
|
||||||
<MachineInfoCard
|
<MachineInfoCard
|
||||||
|
ref="machineInfoCardRef"
|
||||||
:is-edit-mode="d.isEditMode.value"
|
:is-edit-mode="d.isEditMode.value"
|
||||||
:machine-name="d.machineName.value"
|
:machine-name="d.machineName.value"
|
||||||
:machine-reference="d.machineReference.value"
|
:machine-reference="d.machineReference.value"
|
||||||
@@ -71,9 +72,7 @@
|
|||||||
@update:machine-reference="d.machineReference.value = $event"
|
@update:machine-reference="d.machineReference.value = $event"
|
||||||
@update:machine-site-id="d.machineSiteId.value = $event"
|
@update:machine-site-id="d.machineSiteId.value = $event"
|
||||||
@update:constructeur-ids="d.handleMachineConstructeurChange"
|
@update:constructeur-ids="d.handleMachineConstructeurChange"
|
||||||
@blur-field="() => { d.updateMachineInfo(); refreshVersions() }"
|
|
||||||
@set-custom-field-value="d.setMachineCustomFieldValue"
|
@set-custom-field-value="d.setMachineCustomFieldValue"
|
||||||
@update-custom-field="d.updateMachineCustomField"
|
|
||||||
@custom-fields-saved="() => { d.loadMachineData(); refreshVersions() }"
|
@custom-fields-saved="() => { d.loadMachineData(); refreshVersions() }"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -97,7 +96,7 @@
|
|||||||
:products="d.machineDirectProducts.value"
|
:products="d.machineDirectProducts.value"
|
||||||
:is-edit-mode="d.isEditMode.value"
|
:is-edit-mode="d.isEditMode.value"
|
||||||
@add-product="openAddModal('product')"
|
@add-product="openAddModal('product')"
|
||||||
@remove-product="d.removeProductLink"
|
@remove-product="async (id) => { await d.removeProductLink(id); refreshVersions() }"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Components Section -->
|
<!-- Components Section -->
|
||||||
@@ -112,7 +111,7 @@
|
|||||||
@edit-piece="d.updatePieceFromComponent"
|
@edit-piece="d.updatePieceFromComponent"
|
||||||
@custom-field-update="d.updatePieceCustomField"
|
@custom-field-update="d.updatePieceCustomField"
|
||||||
@add-component="openAddModal('component')"
|
@add-component="openAddModal('component')"
|
||||||
@remove-component="d.removeComponentLink"
|
@remove-component="async (id) => { await d.removeComponentLink(id); refreshVersions() }"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Machine Pieces Section -->
|
<!-- Machine Pieces Section -->
|
||||||
@@ -126,7 +125,7 @@
|
|||||||
@edit-piece="d.editPiece"
|
@edit-piece="d.editPiece"
|
||||||
@custom-field-update="d.updatePieceCustomField"
|
@custom-field-update="d.updatePieceCustomField"
|
||||||
@add-piece="openAddModal('piece')"
|
@add-piece="openAddModal('piece')"
|
||||||
@remove-piece="d.removePieceLink"
|
@remove-piece="async (id) => { await d.removePieceLink(id); refreshVersions() }"
|
||||||
@toggle-collapse="d.toggleAllPieces"
|
@toggle-collapse="d.toggleAllPieces"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -138,6 +137,27 @@
|
|||||||
@confirm="handleAddEntity"
|
@confirm="handleAddEntity"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- Save / Cancel buttons -->
|
||||||
|
<div v-if="d.isEditMode.value" class="flex flex-col gap-3 md:flex-row md:justify-end">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-ghost"
|
||||||
|
:class="{ 'btn-disabled': d.saving.value }"
|
||||||
|
@click="d.cancelEdition()"
|
||||||
|
>
|
||||||
|
Annuler
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-primary"
|
||||||
|
:disabled="!d.canSubmit.value"
|
||||||
|
@click="submitMachineEdition"
|
||||||
|
>
|
||||||
|
<span v-if="d.saving.value" class="loading loading-spinner loading-sm mr-2" />
|
||||||
|
Enregistrer les modifications
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Historique -->
|
<!-- Historique -->
|
||||||
<EntityHistorySection
|
<EntityHistorySection
|
||||||
:entries="history"
|
:entries="history"
|
||||||
@@ -224,6 +244,7 @@ if (!machineId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const d = useMachineDetailData(machineId)
|
const d = useMachineDetailData(machineId)
|
||||||
|
const machineInfoCardRef = ref(null)
|
||||||
const versionRefreshKey = ref(0)
|
const versionRefreshKey = ref(0)
|
||||||
const refreshVersions = () => { versionRefreshKey.value++ }
|
const refreshVersions = () => { versionRefreshKey.value++ }
|
||||||
|
|
||||||
@@ -240,6 +261,15 @@ const historyFieldLabels = {
|
|||||||
prix: 'Prix',
|
prix: 'Prix',
|
||||||
site: 'Site',
|
site: 'Site',
|
||||||
constructeurIds: 'Fournisseurs',
|
constructeurIds: 'Fournisseurs',
|
||||||
|
addedComponent: 'Composant ajouté',
|
||||||
|
removedComponent: 'Composant supprimé',
|
||||||
|
addedPiece: 'Pièce ajoutée',
|
||||||
|
removedPiece: 'Pièce supprimée',
|
||||||
|
addedProduct: 'Produit ajouté',
|
||||||
|
removedProduct: 'Produit supprimé',
|
||||||
|
componentLinks: 'Composants liés',
|
||||||
|
pieceLinks: 'Pièces liées',
|
||||||
|
productLinks: 'Produits liés',
|
||||||
}
|
}
|
||||||
|
|
||||||
const addModalOpen = ref(false)
|
const addModalOpen = ref(false)
|
||||||
@@ -258,12 +288,21 @@ const handleAddEntity = async (entityId) => {
|
|||||||
} else {
|
} else {
|
||||||
await d.addProductLink(entityId)
|
await d.addProductLink(entityId)
|
||||||
}
|
}
|
||||||
|
refreshVersions()
|
||||||
}
|
}
|
||||||
|
|
||||||
const machineViewTitle = computed(() => {
|
const machineViewTitle = computed(() => {
|
||||||
return d.isEditMode.value ? 'Modification de la machine' : 'Détails de la machine'
|
return d.isEditMode.value ? 'Modification de la machine' : 'Détails de la machine'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const submitMachineEdition = async () => {
|
||||||
|
if (machineInfoCardRef.value?.saveFieldDefinitions) {
|
||||||
|
await machineInfoCardRef.value.saveFieldDefinitions()
|
||||||
|
}
|
||||||
|
await d.submitEdition()
|
||||||
|
refreshVersions()
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
d.loadMachineData()
|
d.loadMachineData()
|
||||||
d.loadInitialData()
|
d.loadInitialData()
|
||||||
|
|||||||
Reference in New Issue
Block a user