From d568961eb33de97c31acc2f01e037ffb4ac44608 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Thu, 26 Mar 2026 16:51:58 +0100 Subject: [PATCH] feat(machine) : single save button + link versioning with restore Backend: - Enrich machine snapshot with componentLinks/pieceLinks/productLinks - Detect link add/remove in MachineAuditSubscriber onFlush - Add link diff comparison in restore preview - Add link restoration in applyRestore for machines - Add integrity warnings for missing linked entities Frontend (submodule update): - Single save button replacing auto-save-on-blur - Link versioning display in version list and restore modal Co-Authored-By: Claude Opus 4.6 (1M context) --- Inventory_frontend | 2 +- .../plans/2026-03-26-machine-single-save.md | 1074 +++++++++++++++++ .../2026-03-26-machine-single-save-design.md | 117 ++ migrations/Version20260326120000.php | 30 + .../MachineAuditSubscriber.php | 153 +++ src/Service/EntityVersionService.php | 165 +++ 6 files changed, 1540 insertions(+), 1 deletion(-) create mode 100644 docs/superpowers/plans/2026-03-26-machine-single-save.md create mode 100644 docs/superpowers/specs/2026-03-26-machine-single-save-design.md create mode 100644 migrations/Version20260326120000.php diff --git a/Inventory_frontend b/Inventory_frontend index 767c9a7..a741596 160000 --- a/Inventory_frontend +++ b/Inventory_frontend @@ -1 +1 @@ -Subproject commit 767c9a7424cdc4f66c6d77fa1377fe93bdfdb837 +Subproject commit a7415964a718bef7c08af6d6399afd778e45b841 diff --git a/docs/superpowers/plans/2026-03-26-machine-single-save.md b/docs/superpowers/plans/2026-03-26-machine-single-save.md new file mode 100644 index 0000000..7f16058 --- /dev/null +++ b/docs/superpowers/plans/2026-03-26-machine-single-save.md @@ -0,0 +1,1074 @@ +# Machine Single Save Button + Link Versioning — Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Replace the machine page's auto-save-on-blur with a single "Enregistrer les modifications" button (matching composant/pièce/produit pages), and add versioning for machine link add/remove operations. + +**Architecture:** Frontend changes remove all `@blur` save triggers from MachineInfoCard, consolidate saves into a single `submitEdition()` method in the orchestrator composable, and add Save/Cancel buttons at the bottom of the page. MachineInfoCard exposes `saveFieldDefinitions()` via `defineExpose` so the parent can call it during submit. Backend changes extend `MachineAuditSubscriber`'s `onFlush` to detect link entity insertions/deletions and create audit entries on the parent machine. + +**Tech Stack:** Vue 3 / Nuxt 4, Symfony 8, Doctrine ORM, PHP 8.4 + +--- + +## File Structure + +| Action | File | Responsibility | +|--------|------|----------------| +| Modify | `Inventory_frontend/app/components/machine/MachineInfoCard.vue` | Remove blur-triggered saves, expose saveFieldDefinitions via defineExpose | +| Modify | `Inventory_frontend/app/components/machine/MachineCustomFieldDefEditor.vue` | Remove standalone save button | +| Modify | `Inventory_frontend/app/pages/machine/[id].vue` | Add Save/Cancel buttons, wire submitEdition via template ref | +| Modify | `Inventory_frontend/app/composables/useMachineDetailData.ts` | Add submitEdition, cancelEdition, saving, canSubmit | +| Modify | `Inventory_frontend/app/composables/useMachineDetailUpdates.ts` | Remove auto-save from handleMachineConstructeurChange | +| Modify | `Inventory_frontend/app/composables/useMachineDetailCustomFields.ts` | Add saveAllMachineCustomFields batch method | +| Modify | `src/EventSubscriber/MachineAuditSubscriber.php` | Enrich snapshot with links + detect link changes in onFlush | + +--- + +### Task 1: Remove blur-triggered saves from MachineInfoCard + +**Files:** +- Modify: `Inventory_frontend/app/components/machine/MachineInfoCard.vue` + +- [ ] **Step 1: Remove `@blur` from name input (line 17)** + +Replace: +```vue + @input="$emit('update:machine-name', ($event.target as HTMLInputElement).value)" + @blur="$emit('blur-field')" +``` +With: +```vue + @input="$emit('update:machine-name', ($event.target as HTMLInputElement).value)" +``` + +- [ ] **Step 2: Remove `$emit('blur-field')` from site select (line 31)** + +Replace: +```vue + @change="$emit('update:machine-site-id', ($event.target as HTMLSelectElement).value); $emit('blur-field')" +``` +With: +```vue + @change="$emit('update:machine-site-id', ($event.target as HTMLSelectElement).value)" +``` + +- [ ] **Step 3: Remove `@blur` from reference input (line 57)** + +Replace: +```vue + @input="$emit('update:machine-reference', ($event.target as HTMLInputElement).value)" + @blur="$emit('blur-field')" +``` +With: +```vue + @input="$emit('update:machine-reference', ($event.target as HTMLInputElement).value)" +``` + +- [ ] **Step 4: Remove `@blur` from all custom field inputs** + +For each custom field input, remove the `@blur="$emit('update-custom-field', field)"` line: +- text input (line 118) +- number input (line 127) +- select (line 135) +- boolean checkbox (line 152) +- date input (line 163) + +- [ ] **Step 5: Remove `@save` handler from MachineCustomFieldDefEditor usage (line 187)** + +Replace: +```vue + +``` +With: +```vue + +``` + +- [ ] **Step 6: Remove unused emit declarations and add defineExpose** + +Replace the `defineEmits` block (lines 222-231): +```ts +const emit = defineEmits<{ + 'update:machine-name': [value: string] + 'update:machine-reference': [value: string] + 'update:machine-site-id': [value: string] + 'update:constructeur-ids': [ids: unknown] + 'blur-field': [] + 'set-custom-field-value': [field: any, value: unknown] + 'update-custom-field': [field: any] + 'custom-fields-saved': [] +}>() +``` +With: +```ts +const emit = defineEmits<{ + 'update:machine-name': [value: string] + 'update:machine-reference': [value: string] + 'update:machine-site-id': [value: string] + 'update:constructeur-ids': [ids: unknown] + 'set-custom-field-value': [field: any, value: unknown] + 'custom-fields-saved': [] +}>() +``` + +Then, at the end of the `