docs : fix task ordering — category editor before machine page
normalizeStructureForEditor is used by useMachineDetailCustomFields. Must clean it (Task 6) before migrating the machine page (Task 7). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -753,7 +753,56 @@ git commit -m "refactor(custom-fields) : migrate product and piece pages to unif
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Task 6: Migrate machine page — `MachineCustomFieldsCard`, `MachineInfoCard`, `useMachineDetailCustomFields`
|
## Task 6: Clean category editor files (`componentStructure*.ts`)
|
||||||
|
|
||||||
|
**WHY BEFORE MACHINE PAGE:** `normalizeStructureForEditor` is used by `useMachineDetailCustomFields.ts`. If we change it after migrating the machine page, the machine page would break. So clean this first.
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `frontend/app/shared/model/componentStructure.ts`
|
||||||
|
- Modify: `frontend/app/shared/model/componentStructureSanitize.ts`
|
||||||
|
- Modify: `frontend/app/shared/model/componentStructureHydrate.ts`
|
||||||
|
|
||||||
|
- [ ] **Step 1: Read the three files and identify custom field code**
|
||||||
|
|
||||||
|
The custom field code in these files handles the category editor (defining fields on a ModelType skeleton). It's the `sanitizeCustomFields` and `hydrateCustomFields` functions, plus custom field handling in `normalizeStructureForEditor` and `normalizeStructureForSave`.
|
||||||
|
|
||||||
|
- [ ] **Step 2: Replace custom field sanitize/hydrate with the unified module**
|
||||||
|
|
||||||
|
In `componentStructure.ts`, replace the custom field handling in `normalizeStructureForEditor`:
|
||||||
|
```typescript
|
||||||
|
// OLD
|
||||||
|
const sanitizedCustomFields = sanitizeCustomFields(source.customFields)
|
||||||
|
const customFields = sanitizedCustomFields.map((field) => { ... })
|
||||||
|
// NEW
|
||||||
|
import { mergeDefinitionsWithValues } from '~/shared/utils/customFields'
|
||||||
|
const customFields = mergeDefinitionsWithValues(source.customFields, [])
|
||||||
|
```
|
||||||
|
|
||||||
|
**`optionsText` is now included** in `CustomFieldInput` (added in the type definition). `mergeDefinitionsWithValues` already computes `optionsText` from `options.join('\n')`, so all category editor textareas (`v-model="field.optionsText"`) will work without changes.
|
||||||
|
|
||||||
|
- [ ] **Step 3: Run lint + typecheck**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd frontend && npm run lint:fix && npx nuxi typecheck
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 4: Verify TWO things**
|
||||||
|
|
||||||
|
1. Open `/component-category/{id}/edit` — check that custom fields are displayed, can be added/removed/reordered, and save correctly.
|
||||||
|
2. Open `/machine/{id}` — check that the machine page still works (it uses `normalizeStructureForEditor` via `useMachineDetailCustomFields.ts`).
|
||||||
|
|
||||||
|
- [ ] **Step 5: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add frontend/app/shared/model/componentStructure.ts frontend/app/shared/model/componentStructureSanitize.ts frontend/app/shared/model/componentStructureHydrate.ts
|
||||||
|
git commit -m "refactor(custom-fields) : clean category editor structure files"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 7: Migrate machine page — `MachineCustomFieldsCard`, `MachineInfoCard`, `useMachineDetailCustomFields`
|
||||||
|
|
||||||
|
**Depends on:** Task 6 (category editor cleaned — `normalizeStructureForEditor` already uses new types)
|
||||||
|
|
||||||
**Files:**
|
**Files:**
|
||||||
- Modify: `frontend/app/components/machine/MachineCustomFieldsCard.vue`
|
- Modify: `frontend/app/components/machine/MachineCustomFieldsCard.vue`
|
||||||
@@ -811,13 +860,13 @@ const customFields = filterByContext(
|
|||||||
|
|
||||||
Keep recursive calls (lines 201-209) and constructeur/product/document logic (lines 212-263) unchanged.
|
Keep recursive calls (lines 201-209) and constructeur/product/document logic (lines 212-263) unchanged.
|
||||||
|
|
||||||
- [ ] **Step 3: Run lint + typecheck**
|
- [ ] **Step 4: Run lint + typecheck**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd frontend && npm run lint:fix && npx nuxi typecheck
|
cd frontend && npm run lint:fix && npx nuxi typecheck
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 4: Verify**
|
- [ ] **Step 5: Verify**
|
||||||
|
|
||||||
Open a machine page (`/machine/{id}`) that has:
|
Open a machine page (`/machine/{id}`) that has:
|
||||||
- Machine-level custom fields
|
- Machine-level custom fields
|
||||||
@@ -825,7 +874,7 @@ Open a machine page (`/machine/{id}`) that has:
|
|||||||
- Components with machineContextOnly fields
|
- Components with machineContextOnly fields
|
||||||
Check display, edit, and save for all three.
|
Check display, edit, and save for all three.
|
||||||
|
|
||||||
- [ ] **Step 5: Commit**
|
- [ ] **Step 6: Commit**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add frontend/app/components/machine/MachineCustomFieldsCard.vue frontend/app/components/machine/MachineInfoCard.vue frontend/app/composables/useMachineDetailCustomFields.ts
|
git add frontend/app/components/machine/MachineCustomFieldsCard.vue frontend/app/components/machine/MachineInfoCard.vue frontend/app/composables/useMachineDetailCustomFields.ts
|
||||||
@@ -834,9 +883,11 @@ git commit -m "refactor(custom-fields) : migrate machine page to unified module"
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Task 7: Migrate hierarchy components (`ComponentItem.vue`, `PieceItem.vue`)
|
## Task 8: Migrate hierarchy components (`ComponentItem.vue`, `PieceItem.vue`)
|
||||||
|
|
||||||
**Data contract decision:** The parent (`useMachineDetailCustomFields.transformComponentCustomFields`) already pre-merges custom fields into `component.customFields` (a `CustomFieldInput[]`). The Item components should NOT re-merge — they display the pre-merged data directly and use the API composable only for saves/updates.
|
**Depends on:** Task 7 (machine page — parent pre-merges custom fields into `CustomFieldInput[]`)
|
||||||
|
|
||||||
|
**Data contract:** The parent (`useMachineDetailCustomFields.transformComponentCustomFields`) already pre-merges custom fields into `component.customFields` (a `CustomFieldInput[]`). The Item components should NOT re-merge — they display the pre-merged data directly and use the API composable only for saves/updates.
|
||||||
|
|
||||||
**Files:**
|
**Files:**
|
||||||
- Modify: `frontend/app/components/ComponentItem.vue`
|
- Modify: `frontend/app/components/ComponentItem.vue`
|
||||||
@@ -852,11 +903,11 @@ import { resolveFieldKey, resolveFieldName, ... } from '~/shared/utils/entityCus
|
|||||||
With:
|
With:
|
||||||
```typescript
|
```typescript
|
||||||
import { useCustomFields } from '~/composables/useCustomFields'
|
import { useCustomFields } from '~/composables/useCustomFields'
|
||||||
import { fieldKey, formatValueForDisplay, hasDisplayableValue, type CustomFieldInput } from '~/shared/utils/customFields'
|
import { fieldKey, formatValueForDisplay, hasDisplayableValue, mergeDefinitionsWithValues, type CustomFieldInput } from '~/shared/utils/customFields'
|
||||||
```
|
```
|
||||||
|
|
||||||
Key changes:
|
Key changes:
|
||||||
1. **Remove `useEntityCustomFields`** — the parent already pre-merges. Use `props.component.customFields` directly (already `CustomFieldInput[]` after Task 6)
|
1. **Remove `useEntityCustomFields`** — the parent already pre-merges. Use `props.component.customFields` directly (already `CustomFieldInput[]` after Task 7)
|
||||||
2. **For display:** use `hasDisplayableValue(field)` and `formatValueForDisplay(field)` instead of `resolveFieldXxx()` wrappers
|
2. **For display:** use `hasDisplayableValue(field)` and `formatValueForDisplay(field)` instead of `resolveFieldXxx()` wrappers
|
||||||
3. **For edits/saves:** use `useCustomFields()` directly (the HTTP layer) instead of `useEntityCustomFields().updateCustomField`
|
3. **For edits/saves:** use `useCustomFields()` directly (the HTTP layer) instead of `useEntityCustomFields().updateCustomField`
|
||||||
4. **For context fields** (`component.contextCustomFields` + `component.contextCustomFieldValues`): merge locally with `mergeDefinitionsWithValues` — these are NOT pre-merged by the parent since they come as separate arrays
|
4. **For context fields** (`component.contextCustomFields` + `component.contextCustomFieldValues`): merge locally with `mergeDefinitionsWithValues` — these are NOT pre-merged by the parent since they come as separate arrays
|
||||||
@@ -886,52 +937,6 @@ git commit -m "refactor(custom-fields) : migrate ComponentItem and PieceItem to
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Task 8: Clean category editor files (`componentStructure*.ts`)
|
|
||||||
|
|
||||||
**Files:**
|
|
||||||
- Modify: `frontend/app/shared/model/componentStructure.ts`
|
|
||||||
- Modify: `frontend/app/shared/model/componentStructureSanitize.ts`
|
|
||||||
- Modify: `frontend/app/shared/model/componentStructureHydrate.ts`
|
|
||||||
|
|
||||||
- [ ] **Step 1: Read the three files and identify custom field code**
|
|
||||||
|
|
||||||
The custom field code in these files handles the category editor (defining fields on a ModelType skeleton). It's the `sanitizeCustomFields` and `hydrateCustomFields` functions, plus custom field handling in `normalizeStructureForEditor` and `normalizeStructureForSave`.
|
|
||||||
|
|
||||||
- [ ] **Step 2: Replace custom field sanitize/hydrate with `normalizeDefinitions` from the unified module**
|
|
||||||
|
|
||||||
In `componentStructure.ts`, replace the custom field handling in `normalizeStructureForEditor`:
|
|
||||||
```typescript
|
|
||||||
// OLD
|
|
||||||
const sanitizedCustomFields = sanitizeCustomFields(source.customFields)
|
|
||||||
const customFields = sanitizedCustomFields.map((field) => { ... })
|
|
||||||
// NEW
|
|
||||||
import { mergeDefinitionsWithValues } from '~/shared/utils/customFields'
|
|
||||||
const customFields = mergeDefinitionsWithValues(source.customFields, [])
|
|
||||||
```
|
|
||||||
|
|
||||||
**`optionsText` is now included** in `CustomFieldInput` (added in the type definition). `mergeDefinitionsWithValues` already computes `optionsText` from `options.join('\n')`, so all category editor textareas (`v-model="field.optionsText"`) will work without changes.
|
|
||||||
|
|
||||||
**Important:** `normalizeStructureForEditor` is also used by `useMachineDetailCustomFields.ts` (imported as `normalizeStructureForEditor` from `~/shared/modelUtils`). Make sure the change doesn't break the machine detail page — it should be fine since the new output includes the same `options` array plus the `optionsText` string.
|
|
||||||
|
|
||||||
- [ ] **Step 3: Run lint + typecheck**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd frontend && npm run lint:fix && npx nuxi typecheck
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Step 4: Verify**
|
|
||||||
|
|
||||||
Open `/component-category/{id}/edit` — check that custom fields are displayed, can be added/removed/reordered, and save correctly.
|
|
||||||
|
|
||||||
- [ ] **Step 5: Commit**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git add frontend/app/shared/model/componentStructure.ts frontend/app/shared/model/componentStructureSanitize.ts frontend/app/shared/model/componentStructureHydrate.ts
|
|
||||||
git commit -m "refactor(custom-fields) : clean category editor structure files"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Task 9: Delete old files + final cleanup
|
## Task 9: Delete old files + final cleanup
|
||||||
|
|
||||||
**Files:**
|
**Files:**
|
||||||
|
|||||||
Reference in New Issue
Block a user