feat: add valueLabel support and implement snake_case to Title Case formatting for profile field values
This commit is contained in:
@@ -62,6 +62,7 @@ export interface FieldValueResponse {
|
|||||||
sectionSlug: string;
|
sectionSlug: string;
|
||||||
sectionName: string;
|
sectionName: string;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
|
valueLabel?: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GetFieldValuesResponse {
|
export interface GetFieldValuesResponse {
|
||||||
|
|||||||
@@ -376,13 +376,24 @@ function getFieldIcon(fieldSlug: string): string {
|
|||||||
function valueToStringArray(value: unknown): string[] {
|
function valueToStringArray(value: unknown): string[] {
|
||||||
if (!value) return [];
|
if (!value) return [];
|
||||||
|
|
||||||
|
// Format snake_case values to Title Case when they look like raw keys
|
||||||
|
// (labels from backend already have spaces, so this only affects unresolved values)
|
||||||
|
const formatIfSnakeCase = (s: string): string => {
|
||||||
|
const trimmed = s.trim();
|
||||||
|
// If it contains underscores and only letters/digits, treat as snake_case
|
||||||
|
if (/^[a-z0-9]+(_[a-z0-9]+)+$/i.test(trimmed)) {
|
||||||
|
return formatSnakeCaseToTitleCase(trimmed);
|
||||||
|
}
|
||||||
|
return trimmed;
|
||||||
|
};
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
// Deduplicate values
|
// Deduplicate values
|
||||||
return [...new Set(value.map(v => String(v)).filter(v => v.trim() !== ''))];
|
return [...new Set(value.map(v => formatIfSnakeCase(String(v))).filter(v => v !== ''))];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof value === 'string' && value.trim()) {
|
if (typeof value === 'string' && value.trim()) {
|
||||||
return [value];
|
return [formatIfSnakeCase(value)];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof value === 'number' || typeof value === 'boolean') {
|
if (typeof value === 'number' || typeof value === 'boolean') {
|
||||||
@@ -408,7 +419,10 @@ export function mapFieldValuesToSpecializationFields(fieldValues: FieldValueResp
|
|||||||
const seenSlugs = new Set<string>();
|
const seenSlugs = new Set<string>();
|
||||||
|
|
||||||
for (const field of specializationFields) {
|
for (const field of specializationFields) {
|
||||||
const { fieldSlug, fieldName, value } = field;
|
const { fieldSlug, fieldName, value, valueLabel } = field;
|
||||||
|
|
||||||
|
// Prefer resolved labels from backend; fallback to raw value
|
||||||
|
const displayValue = valueLabel ?? value;
|
||||||
|
|
||||||
// Skip if no field info or no value
|
// Skip if no field info or no value
|
||||||
if (!fieldSlug || !fieldName) continue;
|
if (!fieldSlug || !fieldName) continue;
|
||||||
@@ -417,7 +431,7 @@ export function mapFieldValuesToSpecializationFields(fieldValues: FieldValueResp
|
|||||||
if (seenSlugs.has(fieldSlug)) continue;
|
if (seenSlugs.has(fieldSlug)) continue;
|
||||||
seenSlugs.add(fieldSlug);
|
seenSlugs.add(fieldSlug);
|
||||||
|
|
||||||
const values = valueToStringArray(value);
|
const values = valueToStringArray(displayValue);
|
||||||
if (values.length === 0) continue;
|
if (values.length === 0) continue;
|
||||||
|
|
||||||
fields.push({
|
fields.push({
|
||||||
|
|||||||
Reference in New Issue
Block a user