# Reduce Frontend Files Under 500 Lines — Implementation Plan > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **Goal:** Reduce all 14 frontend files currently over 500 lines to under 500 lines each, without changing any functionality. **Architecture:** Extract shared UI sections into reusable components, split large composables/utilities into focused modules, and extract page-level script logic into dedicated composables. Each extraction is a pure refactor — no behavior changes. **Tech Stack:** Vue 3 Composition API, TypeScript, Nuxt 4 (auto-imports for composables and components) --- ## Inventory of files to reduce | # | File | Lines | Target strategy | |---|------|------:|-----------------| | 1 | `composables/useMachineDetailData.ts` | 1353 | Split into 4 focused composables | | 2 | `components/StructureNodeEditor.vue` | 926 | Extract type-map + sync logic into composable | | 3 | `pages/component/[id]/edit.vue` | 911 | Extract shared component + composable | | 4 | `pages/component/create.vue` | 852 | Extract structure assignment helpers | | 5 | `pages/pieces/[id]/edit.vue` | 821 | Extract page composable | | 6 | `shared/model/componentStructure.ts` | 794 | Split into 3 focused modules | | 7 | `components/PieceItem.vue` | 757 | Extract document list + custom fields template | | 8 | `components/ComponentStructureAssignmentNode.vue` | 722 | Extract fetch/options logic | | 9 | `pages/index.vue` | 584 | Extract modal components | | 10 | `components/PieceModelStructureEditor.vue` | 578 | Extract drag-reorder + field logic | | 11 | `components/model-types/ManagementView.vue` | 577 | Extract related-items modal | | 12 | `components/ComponentItem.vue` | 573 | Extract document list template | | 13 | `pages/product/[id]/edit.vue` | 570 | Extract page composable | | 14 | `pages/pieces/create.vue` | 540 | Extract product-selection logic | ## Shared extractions (do these FIRST — they reduce multiple files) ### Task 1: Extract `DocumentListInline.vue` shared component **Rationale:** The document list display (thumbnail + name + mimeType + size + Consulter/Télécharger/Supprimer buttons) is duplicated identically in: - `PieceItem.vue` (lines 401-477) - `ComponentItem.vue` (lines 312-379) - `pages/component/[id]/edit.vue` (lines 307-375) - `pages/pieces/[id]/edit.vue` (lines 254-325) - `pages/product/[id]/edit.vue` (lines 165-232) **Files:** - Create: `app/components/common/DocumentListInline.vue` - Modify: all 5 files above **Step 1: Create `DocumentListInline.vue`** ```vue {{ document.name }} {{ document.mimeType || 'Inconnu' }} • {{ formatSize(document.size) }} Consulter Télécharger Supprimer {{ emptyText }} ``` **Step 2: Run lint** Run: `cd Inventory_frontend && npm run lint:fix` **Step 3: Replace document list in each of the 5 files** In each file, replace the `v-for` document list block with: ```vue ``` Remove the now-unused imports (`documentIcon`, `formatSize`, `shouldInlinePdf`, etc.) from each file. **Step 4: Run lint + typecheck** Run: `cd Inventory_frontend && npm run lint:fix && npx nuxi typecheck` **Step 5: Commit** ```bash git add app/components/common/DocumentListInline.vue app/components/PieceItem.vue app/components/ComponentItem.vue app/pages/component/\[id\]/edit.vue app/pages/pieces/\[id\]/edit.vue app/pages/product/\[id\]/edit.vue git commit -m "refactor(frontend) : extract DocumentListInline shared component" ``` **Expected savings:** ~60 lines per file × 5 files = ~300 lines total --- ### Task 2: Extract `StructureSkeletonPreview.vue` shared component **Rationale:** The "Squelette sélectionné" details section (collapsible, shows custom fields / pieces / products / subcomponents) is duplicated in: - `pages/component/[id]/edit.vue` (lines 141-225) - `pages/component/create.vue` (lines 112-189) - `pages/pieces/[id]/edit.vue` (lines 185-216) - `pages/pieces/create.vue` (lines 156-187) **Files:** - Create: `app/components/common/StructureSkeletonPreview.vue` - Modify: all 4 pages above **Step 1: Create the component** Extract the common `` collapse + custom fields list + pieces list + products list + subcomponents list into a single component with props: - `structure` — the normalized structure object - `description` — optional description text - `previewBadge` — the badge text (e.g., from `formatStructurePreview`) - `pieceTypeLabelMap`, `productTypeLabelMap` — for label resolution (component pages only) - `variant` — `'component'` or `'piece'` to control which sections display **Step 2: Replace in each page** **Step 3: Run lint + typecheck** **Step 4: Commit** ```bash git commit -m "refactor(frontend) : extract StructureSkeletonPreview shared component" ``` **Expected savings:** ~50 lines per file × 4 files = ~200 lines total --- ### Task 3: Split `shared/model/componentStructure.ts` (794 lines → 3 files) **Files:** - Create: `app/shared/model/componentStructureSanitize.ts` - Create: `app/shared/model/componentStructureHydrate.ts` - Modify: `app/shared/model/componentStructure.ts` (keep only normalize + format + extract) **Step 1: Create `componentStructureSanitize.ts`** Move these functions (lines 88-362): - `sanitizeCustomFields` - `sanitizePieces` - `sanitizeProducts` - `sanitizeSubcomponents` (make it exported) - Helper: `extractFieldValueObject`, `toStringArray` ~275 lines → new file **Step 2: Create `componentStructureHydrate.ts`** Move these functions (lines 364-495, 654-739): - `hydrateCustomFields` - `hydratePieces` - `hydrateProducts` - `hydrateSubcomponents` - `mapComponentCustomFields` - `mapComponentPieces` - `mapComponentProducts` - `mapSubcomponents` ~250 lines → new file **Step 3: Update `componentStructure.ts`** Keep only: - `isPlainObject`, `ModelStructurePreview`, `defaultStructure`, `ensureStructureShape`, `cloneStructure` - `normalizeStructureForEditor`, `normalizeStructureForSave` - `hydrateStructureForEditor`, `extractStructureFromComponent` - `computeStructureStats`, `formatStructurePreview` Import sanitize/hydrate functions from the new files. File should end up ~270 lines. **Step 4: Verify all imports across the codebase still work** Run: `cd Inventory_frontend && npx nuxi typecheck` **Step 5: Commit** ```bash git commit -m "refactor(frontend) : split componentStructure.ts into focused modules" ``` --- ### Task 4: Split `composables/useMachineDetailData.ts` (1353 lines → 4 composables) **Files:** - Create: `app/composables/useMachineDetailDocuments.ts` (~200 lines) - Create: `app/composables/useMachineDetailCustomFields.ts` (~150 lines) - Create: `app/composables/useMachineDetailHierarchy.ts` (~200 lines) - Create: `app/composables/useMachineDetailProducts.ts` (~150 lines) - Modify: `app/composables/useMachineDetailData.ts` (should end up ~400 lines) **Step 1: Identify extraction boundaries** Read the full file and map which functions/refs belong to which domain: - **Documents:** document loading, upload, delete, preview state - **Custom fields:** custom field value management, display logic - **Hierarchy:** machine hierarchy building, component/piece tree resolution - **Products:** product display, resolution, supplier info **Step 2: Extract `useMachineDetailDocuments.ts`** Move all document-related refs, functions, and watchers. The composable accepts `machineId` and returns `{ documents, loadDocuments, uploadDocuments, ... }`. **Step 3: Extract `useMachineDetailCustomFields.ts`** Move custom field resolution, display filtering, and update logic. **Step 4: Extract `useMachineDetailHierarchy.ts`** Move `buildMachineHierarchyFromLinks` usage, component/piece tree construction. **Step 5: Extract `useMachineDetailProducts.ts`** Move product display resolution, supplier info formatting. **Step 6: Update `useMachineDetailData.ts`** Import and compose the 4 sub-composables. Keep only the orchestration logic (data loading sequence, top-level state). **Step 7: Run lint + typecheck** **Step 8: Commit** ```bash git commit -m "refactor(frontend) : split useMachineDetailData into focused composables" ``` --- ### Task 5: Extract composable from `StructureNodeEditor.vue` (926 → <500) **Files:** - Create: `app/composables/useStructureNodeLogic.ts` - Modify: `app/components/StructureNodeEditor.vue` **Step 1: Create `useStructureNodeLogic.ts`** Extract from the `
{{ emptyText }}