refactor: update orphan value filtering and availability type logic in profile data mapper
This commit is contained in:
@@ -291,21 +291,21 @@ export function mapFieldValuesToAvailability(fieldValues: FieldValueResponse[]):
|
|||||||
return trimmed;
|
return trimmed;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use backend-resolved labels only. Drop stale/orphan values whose option is no longer
|
// Drop stale/orphan options. Backend returns `valueLabel[i]` equal to the raw `value[i]`
|
||||||
// defined in the profile field (backend returns no label for them) — prevents old
|
// when no option match is found (admin renamed/removed the option). Those are orphans —
|
||||||
// selections from lingering when admin renames/removes options.
|
// skip them entirely so old selections don't linger on the public profile.
|
||||||
const resolvedLabels: string[] = [];
|
const resolvedLabels: string[] = [];
|
||||||
rawValues.forEach((val, i) => {
|
rawValues.forEach((val, i) => {
|
||||||
const fromBackend = labelValues[i];
|
|
||||||
if (fromBackend && typeof fromBackend === 'string' && fromBackend.trim()) {
|
|
||||||
resolvedLabels.push(formatIfSnakeCase(fromBackend));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// No backend label → likely a stale option; skip unless it's already a human-readable string
|
|
||||||
const raw = String(val || '').trim();
|
const raw = String(val || '').trim();
|
||||||
if (!raw) return;
|
if (!raw) return;
|
||||||
if (/^[a-z0-9]+(_[a-z0-9]+)+$/i.test(raw)) return; // skip snake_case orphans
|
const fromBackend = labelValues[i];
|
||||||
resolvedLabels.push(formatIfSnakeCase(raw));
|
const hasResolvedLabel =
|
||||||
|
fromBackend &&
|
||||||
|
typeof fromBackend === 'string' &&
|
||||||
|
fromBackend.trim() &&
|
||||||
|
fromBackend !== raw; // backend-resolved label must DIFFER from raw value
|
||||||
|
if (!hasResolvedLabel) return; // orphan — drop
|
||||||
|
resolvedLabels.push(formatIfSnakeCase(fromBackend));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Deduplicate by normalized comparison (case/whitespace insensitive)
|
// Deduplicate by normalized comparison (case/whitespace insensitive)
|
||||||
@@ -319,16 +319,19 @@ export function mapFieldValuesToAvailability(fieldValues: FieldValueResponse[]):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine availability type based on values OR resolved labels
|
// Determine availability type from resolved labels only (orphan values were already dropped).
|
||||||
const allValues = [...rawValues.map(v => String(v)), ...resolvedLabels];
|
// If nothing valid remains, don't fabricate a type.
|
||||||
let type = 'Available';
|
let type = '';
|
||||||
if (allValues.some(v => matchesKeyword(v, fullTimeKeywords))) {
|
if (resolvedLabels.length > 0) {
|
||||||
|
type = 'Available';
|
||||||
|
if (resolvedLabels.some(v => matchesKeyword(v, fullTimeKeywords))) {
|
||||||
type = 'Full-time';
|
type = 'Full-time';
|
||||||
} else if (allValues.some(v => matchesKeyword(v, partTimeKeywords))) {
|
} else if (resolvedLabels.some(v => matchesKeyword(v, partTimeKeywords))) {
|
||||||
type = 'Part-time';
|
type = 'Part-time';
|
||||||
} else if (allValues.some(v => matchesKeyword(v, flexibleKeywords))) {
|
} else if (resolvedLabels.some(v => matchesKeyword(v, flexibleKeywords))) {
|
||||||
type = 'Flexible';
|
type = 'Flexible';
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return { type, schedule, label };
|
return { type, schedule, label };
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user