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:
@@ -319,16 +319,10 @@ import {
|
||||
uniqueConstructeurIds,
|
||||
parseConstructeurLinksFromApi,
|
||||
} from '~/shared/constructeurUtils'
|
||||
import {
|
||||
resolveFieldId,
|
||||
resolveFieldReadOnly,
|
||||
resolveCustomFieldId,
|
||||
mergeFieldDefinitionsWithValues,
|
||||
dedupeMergedFields,
|
||||
} from '~/shared/utils/entityCustomFieldLogic'
|
||||
import { mergeDefinitionsWithValues } from '~/shared/utils/customFields'
|
||||
import { useCustomFields } from '~/composables/useCustomFields'
|
||||
import { useEntityDocuments } from '~/composables/useEntityDocuments'
|
||||
import { useEntityProductDisplay } from '~/composables/useEntityProductDisplay'
|
||||
import { useEntityCustomFields } from '~/composables/useEntityCustomFields'
|
||||
|
||||
const props = defineProps({
|
||||
piece: { type: Object, required: true },
|
||||
@@ -392,25 +386,81 @@ const {
|
||||
} = useEntityProductDisplay({ entity: () => props.piece, selectedProduct })
|
||||
|
||||
const {
|
||||
displayedCustomFields,
|
||||
updateCustomField,
|
||||
} = useEntityCustomFields({ entity: () => props.piece, entityType: 'piece' })
|
||||
updateCustomFieldValue: updateCustomFieldValueApi,
|
||||
upsertCustomFieldValue,
|
||||
} = useCustomFields()
|
||||
const { showSuccess, showError } = useToast()
|
||||
|
||||
// Parent already pre-merges standalone custom fields into props.piece.customFields
|
||||
const displayedCustomFields = computed(() => {
|
||||
const fields = props.piece?.customFields
|
||||
return Array.isArray(fields) ? fields.filter((f) => !f.machineContextOnly) : []
|
||||
})
|
||||
|
||||
const updateCustomField = async (field) => {
|
||||
if (!field || field.readOnly) return
|
||||
|
||||
const e = props.piece
|
||||
const fieldValueId = field.customFieldValueId
|
||||
|
||||
if (fieldValueId) {
|
||||
const result = await updateCustomFieldValueApi(fieldValueId, { value: field.value ?? '' })
|
||||
if (result.success) {
|
||||
showSuccess(`Champ "${field.name}" mis à jour avec succès`)
|
||||
} else {
|
||||
showError(`Erreur lors de la mise à jour du champ "${field.name}"`)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (!e?.id) {
|
||||
showError('Impossible de créer la valeur pour ce champ')
|
||||
return
|
||||
}
|
||||
|
||||
const metadata = field.customFieldId ? undefined : {
|
||||
customFieldName: field.name,
|
||||
customFieldType: field.type,
|
||||
customFieldRequired: field.required,
|
||||
customFieldOptions: field.options,
|
||||
}
|
||||
const result = await upsertCustomFieldValue(
|
||||
field.customFieldId,
|
||||
'piece',
|
||||
e.id,
|
||||
field.value ?? '',
|
||||
metadata,
|
||||
)
|
||||
|
||||
if (result.success) {
|
||||
const newValue = result.data
|
||||
if (newValue?.id) {
|
||||
field.customFieldValueId = newValue.id
|
||||
field.value = newValue.value ?? field.value ?? ''
|
||||
if (newValue.customField?.id) {
|
||||
field.customFieldId = newValue.customField.id
|
||||
}
|
||||
}
|
||||
showSuccess(`Champ "${field.name}" créé avec succès`)
|
||||
} else {
|
||||
showError(`Erreur lors de la sauvegarde du champ "${field.name}"`)
|
||||
}
|
||||
}
|
||||
|
||||
// Context fields are NOT pre-merged — merge locally
|
||||
const mergedContextFields = computed(() => {
|
||||
const definitions = props.piece?.contextCustomFields ?? []
|
||||
const values = props.piece?.contextCustomFieldValues ?? []
|
||||
if (!definitions.length && !values.length) return []
|
||||
return dedupeMergedFields(
|
||||
mergeFieldDefinitionsWithValues(definitions, values),
|
||||
)
|
||||
return mergeDefinitionsWithValues(definitions, values)
|
||||
})
|
||||
|
||||
const queueContextCustomFieldUpdate = (field, value) => {
|
||||
const linkId = props.piece?.linkId
|
||||
if (!linkId || !field) return
|
||||
|
||||
const customFieldId = resolveCustomFieldId(field)
|
||||
const customFieldValueId = resolveFieldId(field)
|
||||
const customFieldId = field.customFieldId
|
||||
const customFieldValueId = field.customFieldValueId
|
||||
if (!customFieldId && !customFieldValueId) return
|
||||
|
||||
field.value = value
|
||||
@@ -420,7 +470,7 @@ const queueContextCustomFieldUpdate = (field, value) => {
|
||||
fieldId: customFieldId,
|
||||
customFieldValueId,
|
||||
value: value ?? '',
|
||||
fieldName: field.name || field.customField?.name || 'Champ contextuel',
|
||||
fieldName: field.name || 'Champ contextuel',
|
||||
})
|
||||
}
|
||||
|
||||
@@ -544,8 +594,8 @@ const handleProductChange = async (value) => {
|
||||
|
||||
// --- Custom field event handlers ---
|
||||
const handleCustomFieldInput = (field, value) => {
|
||||
if (resolveFieldReadOnly(field)) return
|
||||
const fieldValueId = resolveFieldId(field)
|
||||
if (field.readOnly) return
|
||||
const fieldValueId = field.customFieldValueId
|
||||
if (!fieldValueId) return
|
||||
const fieldValue = props.piece.customFieldValues?.find((fv) => fv.id === fieldValueId)
|
||||
if (fieldValue) fieldValue.value = value
|
||||
@@ -553,7 +603,7 @@ const handleCustomFieldInput = (field, value) => {
|
||||
|
||||
const handleCustomFieldBlur = async (field) => {
|
||||
await updateCustomField(field)
|
||||
const cfId = field?.customFieldId || field?.customField?.id || null
|
||||
const cfId = field?.customFieldId || null
|
||||
if (cfId || field?.customFieldValueId) {
|
||||
emit('custom-field-update', {
|
||||
fieldId: cfId,
|
||||
|
||||
Reference in New Issue
Block a user