feat: improve machine component hierarchy handling

This commit is contained in:
Matthieu
2025-10-13 09:01:19 +02:00
parent 95c2a82689
commit 06ae0ca7aa
9 changed files with 1184 additions and 408 deletions

View File

@@ -25,6 +25,12 @@
</div>
</div>
<div class="flex flex-wrap items-center gap-2 text-xs">
<span
v-if="piece.skeletonOnly"
class="badge badge-warning badge-sm"
>
Défini dans le catalogue
</span>
<span
v-if="piece.typeMachinePieceRequirement"
class="badge badge-outline badge-sm"
@@ -387,6 +393,33 @@ function fieldKeyFromNameAndType(name, type) {
return normalizedName ? `${normalizedName}::${normalizedType}` : null;
}
function deduplicateFieldDefinitions(definitions) {
const result = [];
const seen = new Set();
(Array.isArray(definitions) ? definitions : []).forEach((field) => {
if (!field || typeof field !== 'object') {
return;
}
const id =
field.id ??
field.customFieldId ??
field.customField?.id ??
null;
const nameKey = fieldKeyFromNameAndType(field.name, field.type);
const key = id || nameKey;
if (key && seen.has(key)) {
return;
}
if (key) {
seen.add(key);
}
result.push(field);
});
return result;
}
function mergeFieldDefinitionsWithValues(definitions, values) {
const definitionList = Array.isArray(definitions) ? definitions : [];
const valueList = Array.isArray(values) ? values : [];
@@ -494,6 +527,72 @@ function mergeFieldDefinitionsWithValues(definitions, values) {
return merged;
}
function dedupeMergedFields(fields) {
if (!Array.isArray(fields) || fields.length <= 1) {
return Array.isArray(fields) ? fields : [];
}
const seen = new Map();
const result = [];
fields.forEach((field) => {
if (!field || typeof field !== 'object') {
return;
}
const rawName = resolveFieldName(field);
const normalizedName =
typeof rawName === 'string' ? rawName.trim() : '';
if (!normalizedName) {
return;
}
field.type = field.type || 'text';
if (typeof field.name === 'string') {
field.name = field.name.trim();
} else {
field.name = normalizedName;
}
const fieldId = resolveCustomFieldId(field);
const nameKey = fieldKeyFromNameAndType(
normalizedName,
resolveFieldType(field),
);
const key = fieldId || nameKey;
if (!key) {
result.push(field);
return;
}
const existing = seen.get(key);
if (!existing) {
seen.set(key, field);
result.push(field);
return;
}
const existingHasValue =
existing.value !== undefined &&
existing.value !== null &&
String(existing.value).trim().length > 0;
const incomingHasValue =
field.value !== undefined &&
field.value !== null &&
String(field.value).trim().length > 0;
if (!existingHasValue && incomingHasValue) {
Object.assign(existing, field);
seen.set(key, existing);
}
});
return result;
}
const pieceDefinitionSources = computed(() => {
const requirement = props.piece.typeMachinePieceRequirement || {};
const type = requirement.typePiece || props.piece.typePiece || {};
@@ -528,13 +627,15 @@ const pieceDefinitionSources = computed(() => {
}
});
return definitions;
return deduplicateFieldDefinitions(definitions);
});
const displayedCustomFields = computed(() =>
mergeFieldDefinitionsWithValues(
pieceDefinitionSources.value,
props.piece.customFieldValues,
dedupeMergedFields(
mergeFieldDefinitionsWithValues(
pieceDefinitionSources.value,
props.piece.customFieldValues,
),
),
);