refactor(custom-fields) : unify 3 parallel implementations into 1 module
Replace ~2900 lines across 9 files with ~400 lines in 2 files: - shared/utils/customFields.ts (types + pure helpers) - composables/useCustomFieldInputs.ts (reactive composable) Migrated all consumers: - Backend: add defaultValue to API Platform serialization groups - Standalone pages: component edit/create, piece edit/create, product edit/create/detail - Machine page: MachineCustomFieldsCard, MachineInfoCard, useMachineDetailCustomFields - Hierarchy: ComponentItem, PieceItem - Shared: CustomFieldDisplay, CustomFieldInputGrid - Category editor: componentStructure.ts Deleted: - entityCustomFieldLogic.ts (335 lines) - customFieldUtils.ts (440 lines) - customFieldFormUtils.ts (404 lines) - useEntityCustomFields.ts (181 lines) - customFieldFormUtils.test.ts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,6 @@ import { usePieceTypes } from '~/composables/usePieceTypes'
|
||||
import { useProductTypes } from '~/composables/useProductTypes'
|
||||
import { usePieces } from '~/composables/usePieces'
|
||||
import { useProducts } from '~/composables/useProducts'
|
||||
import { useCustomFields } from '~/composables/useCustomFields'
|
||||
import { useApi } from '~/composables/useApi'
|
||||
import { useToast } from '~/composables/useToast'
|
||||
import { extractRelationId } from '~/shared/apiRelations'
|
||||
@@ -29,12 +28,7 @@ import {
|
||||
import type { ComponentModelStructure } from '~/shared/types/inventory'
|
||||
import type { ModelType } from '~/services/modelTypes'
|
||||
import { canPreviewDocument } from '~/utils/documentPreview'
|
||||
import {
|
||||
type CustomFieldInput,
|
||||
buildCustomFieldInputs,
|
||||
requiredCustomFieldsFilled as _requiredCustomFieldsFilled,
|
||||
saveCustomFieldValues as _saveCustomFieldValues,
|
||||
} from '~/shared/utils/customFieldFormUtils'
|
||||
import { useCustomFieldInputs, type CustomFieldInput } from '~/composables/useCustomFieldInputs'
|
||||
import { collectStructureSelections } from '~/shared/utils/structureSelectionUtils'
|
||||
|
||||
interface ComponentCatalogType extends ModelType {
|
||||
@@ -64,7 +58,6 @@ export function useComponentEdit(componentId: string) {
|
||||
const { products } = useProducts()
|
||||
const { ensureConstructeurs } = useConstructeurs()
|
||||
const { fetchLinks, syncLinks } = useConstructeurLinks()
|
||||
const { upsertCustomFieldValue, updateCustomFieldValue } = useCustomFields()
|
||||
const toast = useToast()
|
||||
const { loadDocumentsByComponent, uploadDocuments, deleteDocument } = useDocuments()
|
||||
const {
|
||||
@@ -96,7 +89,23 @@ export function useComponentEdit(componentId: string) {
|
||||
const originalConstructeurLinks = ref<ConstructeurLinkEntry[]>([])
|
||||
const constructeurIdsFromForm = computed(() => constructeurIdsFromLinks(constructeurLinks.value))
|
||||
|
||||
const customFieldInputs = ref<CustomFieldInput[]>([])
|
||||
const {
|
||||
fields: customFieldInputs,
|
||||
requiredFilled: requiredCustomFieldsFilled,
|
||||
saveAll: saveAllCustomFields,
|
||||
refresh: refreshCustomFieldInputs,
|
||||
} = useCustomFieldInputs({
|
||||
definitions: computed(() => selectedTypeStructure.value?.customFields ?? []),
|
||||
values: computed(() => component.value?.customFieldValues ?? []),
|
||||
entityType: 'composant',
|
||||
entityId: computed(() => component.value?.id ?? null),
|
||||
onValueCreated: (newValue) => {
|
||||
if (component.value && Array.isArray(component.value.customFieldValues)) {
|
||||
component.value.customFieldValues.push(newValue)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const fetchedPieceTypeMap = ref<Record<string, string>>({})
|
||||
const pieceTypeLabelMap = computed(() =>
|
||||
buildTypeLabelMap(pieceTypes.value, fetchedPieceTypeMap.value),
|
||||
@@ -207,19 +216,6 @@ export function useComponentEdit(componentId: string) {
|
||||
return structure ? normalizeStructureForEditor(structure) : null
|
||||
})
|
||||
|
||||
const refreshCustomFieldInputs = (
|
||||
structureOverride?: ComponentModelStructure | null,
|
||||
valuesOverride?: any[] | null,
|
||||
) => {
|
||||
const structure = structureOverride ?? selectedTypeStructure.value ?? null
|
||||
const values = valuesOverride ?? component.value?.customFieldValues ?? null
|
||||
customFieldInputs.value = buildCustomFieldInputs(structure, values)
|
||||
}
|
||||
|
||||
const requiredCustomFieldsFilled = computed(() =>
|
||||
_requiredCustomFieldsFilled(customFieldInputs.value),
|
||||
)
|
||||
|
||||
const canSubmit = computed(() => Boolean(
|
||||
canEdit.value
|
||||
&& component.value
|
||||
@@ -239,8 +235,7 @@ export function useComponentEdit(componentId: string) {
|
||||
component.value = result.data
|
||||
componentDocuments.value = Array.isArray(result.data?.documents) ? result.data.documents : []
|
||||
|
||||
const customValues = Array.isArray(result.data?.customFieldValues) ? result.data.customFieldValues : []
|
||||
refreshCustomFieldInputs(undefined, customValues)
|
||||
// The watcher on useCustomFieldInputs will auto-refresh when component.value changes
|
||||
|
||||
loadHistory(result.data.id).catch(() => {})
|
||||
}
|
||||
@@ -392,14 +387,10 @@ export function useComponentEdit(componentId: string) {
|
||||
const result = await updateComposant(component.value.id, payload)
|
||||
if (result.success && result.data) {
|
||||
const updatedComponent = result.data as Record<string, any>
|
||||
await _saveCustomFieldValues(
|
||||
'composant',
|
||||
updatedComponent.id,
|
||||
[
|
||||
updatedComponent?.typeComposant?.structure?.customFields,
|
||||
],
|
||||
{ customFieldInputs, upsertCustomFieldValue, updateCustomFieldValue, toast },
|
||||
)
|
||||
const failedFields = await saveAllCustomFields()
|
||||
if (failedFields.length) {
|
||||
toast.showError(`Erreur sur les champs : ${failedFields.join(', ')}`)
|
||||
}
|
||||
|
||||
// Save slot edits
|
||||
const slotPromises: Promise<any>[] = []
|
||||
@@ -499,7 +490,7 @@ export function useComponentEdit(componentId: string) {
|
||||
initialized.value = true
|
||||
}
|
||||
|
||||
refreshCustomFieldInputs(selectedTypeStructure.value ?? currentStructure, currentComponent.customFieldValues)
|
||||
// useCustomFieldInputs auto-refreshes via its watcher on definitions + values
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user