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)
|
||||
* 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() {
|
||||
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)
|
||||
// Also track by normalized name to de-duplicate fields with same name but different slugs
|
||||
const mergedFields = new Map<string, {
|
||||
slug: string;
|
||||
name: string;
|
||||
@@ -272,25 +274,49 @@ export class ProfileFieldsService {
|
||||
options: { label: string; value: string }[];
|
||||
}>();
|
||||
|
||||
for (const field of fields) {
|
||||
const existingField = mergedFields.get(field.slug);
|
||||
const fieldOptions = (field.options as { label: string; value: string }[]) || [];
|
||||
// Map normalized names to their primary slug for de-duplication
|
||||
const nameToSlugMap = new Map<string, string>();
|
||||
|
||||
if (existingField) {
|
||||
// Merge options, avoiding duplicates by value
|
||||
const existingValues = new Set(existingField.options.map(o => o.value));
|
||||
for (const opt of fieldOptions) {
|
||||
if (!existingValues.has(opt.value)) {
|
||||
existingField.options.push(opt);
|
||||
for (const field of fields) {
|
||||
const fieldOptions = (field.options as { label: string; value: string }[]) || [];
|
||||
const normalizedName = field.name.toLowerCase().trim();
|
||||
|
||||
// Check if we already have a field with this name (different slug, same name)
|
||||
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 {
|
||||
mergedFields.set(field.slug, {
|
||||
slug: field.slug,
|
||||
name: field.name,
|
||||
fieldType: field.fieldType,
|
||||
options: [...fieldOptions],
|
||||
});
|
||||
// Check if we have an existing field with same slug
|
||||
const existingFieldBySlug = mergedFields.get(field.slug);
|
||||
|
||||
if (existingFieldBySlug) {
|
||||
// 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