fix(custom-fields) : include orphan values with embedded definitions in edit pages
After JSON-to-tables migration, custom field definitions not linked to a ModelType were invisible on edit pages because buildCustomFieldInputs only mapped over structure definitions. Now also includes values whose embedded customField definition has no matching structure entry. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -225,7 +225,10 @@ export const buildCustomFieldInputs = (
|
|||||||
if (fieldName) mapByName.set(fieldName, entry)
|
if (fieldName) mapByName.set(fieldName, entry)
|
||||||
})
|
})
|
||||||
|
|
||||||
return definitions
|
const matchedIds = new Set<string>()
|
||||||
|
const matchedNames = new Set<string>()
|
||||||
|
|
||||||
|
const result = definitions
|
||||||
.map((definition) => {
|
.map((definition) => {
|
||||||
const definitionId = definition.customFieldId || definition.id || null
|
const definitionId = definition.customFieldId || definition.id || null
|
||||||
const matched = (definitionId ? mapById.get(definitionId) : null) || mapByName.get(definition.name)
|
const matched = (definitionId ? mapById.get(definitionId) : null) || mapByName.get(definition.name)
|
||||||
@@ -239,6 +242,11 @@ export const buildCustomFieldInputs = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const matchedFieldId = matched.customField?.id || matched.customFieldId || null
|
||||||
|
if (matchedFieldId) matchedIds.add(matchedFieldId)
|
||||||
|
const matchedFieldName = matched.customField?.name || matched.name || null
|
||||||
|
if (matchedFieldName) matchedNames.add(matchedFieldName)
|
||||||
|
|
||||||
const resolvedValue = extractStoredCustomFieldValue(matched)
|
const resolvedValue = extractStoredCustomFieldValue(matched)
|
||||||
return {
|
return {
|
||||||
...definition,
|
...definition,
|
||||||
@@ -253,7 +261,36 @@ export const buildCustomFieldInputs = (
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.sort((a, b) => (a.orderIndex ?? 0) - (b.orderIndex ?? 0))
|
|
||||||
|
// Include values with embedded definitions that didn't match any structure definition
|
||||||
|
valueList.forEach((entry, index) => {
|
||||||
|
if (!entry || typeof entry !== 'object') return
|
||||||
|
const cf = entry.customField
|
||||||
|
if (!cf || typeof cf !== 'object') return
|
||||||
|
const fieldId = cf.id || entry.customFieldId || null
|
||||||
|
const fieldName = cf.name || entry.name || null
|
||||||
|
if (fieldId && matchedIds.has(fieldId)) return
|
||||||
|
if (fieldName && matchedNames.has(fieldName)) return
|
||||||
|
|
||||||
|
const name = resolveFieldName(cf)
|
||||||
|
if (!name) return
|
||||||
|
|
||||||
|
const type = resolveFieldType(cf)
|
||||||
|
const resolvedValue = extractStoredCustomFieldValue(entry)
|
||||||
|
result.push({
|
||||||
|
id: fieldId,
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
required: resolveRequiredFlag(cf),
|
||||||
|
options: resolveOptions(cf),
|
||||||
|
value: formatDefaultValue(type, resolvedValue),
|
||||||
|
customFieldId: fieldId,
|
||||||
|
customFieldValueId: entry.id ?? null,
|
||||||
|
orderIndex: typeof cf.orderIndex === 'number' ? cf.orderIndex : definitions.length + index,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
return result.sort((a, b) => (a.orderIndex ?? 0) - (b.orderIndex ?? 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user