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:
Matthieu
2026-03-26 16:51:34 +01:00
parent 767c9a7424
commit a7415964a7
8 changed files with 166 additions and 33 deletions

View File

@@ -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 {
// State
machineCustomFields,
@@ -392,5 +444,6 @@ export function useMachineDetailCustomFields(deps: MachineDetailCustomFieldsDeps
setMachineCustomFieldValue,
updateMachineCustomField,
updatePieceCustomField,
saveAllMachineCustomFields,
}
}

View File

@@ -62,6 +62,7 @@ export function useMachineDetailData(machineId: string) {
const machine = ref<AnyRecord | null>(null)
const productDocumentsMap = ref<Map<string, AnyRecord[]>>(new Map())
const printAreaRef = ref<HTMLElement | null>(null)
const saving = ref(false)
// Machine fields
const machineName = ref('')
@@ -108,6 +109,12 @@ export function useMachineDetailData(machineId: string) {
// UI state
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 componentsCollapsed = ref(true)
@@ -146,6 +153,7 @@ export function useMachineDetailData(machineId: string) {
setMachineCustomFieldValue,
updateMachineCustomField,
updatePieceCustomField,
saveAllMachineCustomFields,
} = useMachineDetailCustomFields({
machine,
isEditMode,
@@ -302,6 +310,37 @@ export function useMachineDetailData(machineId: string) {
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
const ensurePrintSelectionEntries = () =>
_ensurePrintEntries(components.value, machinePieces.value)
@@ -451,6 +490,7 @@ export function useMachineDetailData(machineId: string) {
updateMachineInfo, updateComponent, updatePieceFromComponent,
updatePieceInfo, handleMachineConstructeurChange, editComponent, editPiece,
toggleEditMode, toggleAllComponents, collapseAllComponents, toggleAllPieces,
saving, canSubmit, submitEdition, cancelEdition,
// Print
printModalOpen, printSelection, ensurePrintSelectionEntries,

View File

@@ -208,9 +208,8 @@ export function useMachineDetailUpdates(deps: UseMachineDetailUpdatesDeps) {
}
}
const handleMachineConstructeurChange = async (value: unknown) => {
const handleMachineConstructeurChange = (value: unknown) => {
machineConstructeurIds.value = uniqueConstructeurIds(value)
await updateMachineInfo()
}
const editComponent = () => {