feat: de-duplicate filterable fields by both slug and normalized name, merging options from fields with the same name but different slugs.
This commit is contained in:
@@ -234,6 +234,7 @@ export class ProfileFieldsService {
|
|||||||
/**
|
/**
|
||||||
* Get all filterable fields (public endpoint for search filters)
|
* Get all filterable fields (public endpoint for search filters)
|
||||||
* Returns fields with CHECKBOX_GROUP, SELECT, MULTI_SELECT types that have options
|
* Returns fields with CHECKBOX_GROUP, SELECT, MULTI_SELECT types that have options
|
||||||
|
* De-duplicates by both slug AND name to handle duplicate fields with different slugs
|
||||||
*/
|
*/
|
||||||
async getFilterableFields() {
|
async getFilterableFields() {
|
||||||
const filterableTypes: FieldType[] = [FieldType.CHECKBOX_GROUP, FieldType.SELECT, FieldType.MULTI_SELECT];
|
const filterableTypes: FieldType[] = [FieldType.CHECKBOX_GROUP, FieldType.SELECT, FieldType.MULTI_SELECT];
|
||||||
@@ -265,6 +266,7 @@ export class ProfileFieldsService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Group fields by slug to merge options from different sections (same field in different agent types)
|
// Group fields by slug to merge options from different sections (same field in different agent types)
|
||||||
|
// Also track by normalized name to de-duplicate fields with same name but different slugs
|
||||||
const mergedFields = new Map<string, {
|
const mergedFields = new Map<string, {
|
||||||
slug: string;
|
slug: string;
|
||||||
name: string;
|
name: string;
|
||||||
@@ -272,25 +274,49 @@ export class ProfileFieldsService {
|
|||||||
options: { label: string; value: string }[];
|
options: { label: string; value: string }[];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
for (const field of fields) {
|
// Map normalized names to their primary slug for de-duplication
|
||||||
const existingField = mergedFields.get(field.slug);
|
const nameToSlugMap = new Map<string, string>();
|
||||||
const fieldOptions = (field.options as { label: string; value: string }[]) || [];
|
|
||||||
|
|
||||||
if (existingField) {
|
for (const field of fields) {
|
||||||
// Merge options, avoiding duplicates by value
|
const fieldOptions = (field.options as { label: string; value: string }[]) || [];
|
||||||
const existingValues = new Set(existingField.options.map(o => o.value));
|
const normalizedName = field.name.toLowerCase().trim();
|
||||||
for (const opt of fieldOptions) {
|
|
||||||
if (!existingValues.has(opt.value)) {
|
// Check if we already have a field with this name (different slug, same name)
|
||||||
existingField.options.push(opt);
|
const existingSlugForName = nameToSlugMap.get(normalizedName);
|
||||||
|
|
||||||
|
if (existingSlugForName) {
|
||||||
|
// Merge into existing field with same name
|
||||||
|
const existingField = mergedFields.get(existingSlugForName);
|
||||||
|
if (existingField) {
|
||||||
|
const existingValues = new Set(existingField.options.map(o => o.value));
|
||||||
|
for (const opt of fieldOptions) {
|
||||||
|
if (!existingValues.has(opt.value)) {
|
||||||
|
existingField.options.push(opt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mergedFields.set(field.slug, {
|
// Check if we have an existing field with same slug
|
||||||
slug: field.slug,
|
const existingFieldBySlug = mergedFields.get(field.slug);
|
||||||
name: field.name,
|
|
||||||
fieldType: field.fieldType,
|
if (existingFieldBySlug) {
|
||||||
options: [...fieldOptions],
|
// Merge options, avoiding duplicates by value
|
||||||
});
|
const existingValues = new Set(existingFieldBySlug.options.map(o => o.value));
|
||||||
|
for (const opt of fieldOptions) {
|
||||||
|
if (!existingValues.has(opt.value)) {
|
||||||
|
existingFieldBySlug.options.push(opt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// New field - add to both maps
|
||||||
|
mergedFields.set(field.slug, {
|
||||||
|
slug: field.slug,
|
||||||
|
name: field.name,
|
||||||
|
fieldType: field.fieldType,
|
||||||
|
options: [...fieldOptions],
|
||||||
|
});
|
||||||
|
nameToSlugMap.set(normalizedName, field.slug);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user