feat: scope filterable fields by agent type and update filters dynamically on selection change
This commit is contained in:
@@ -460,14 +460,11 @@ function ProfilesPageContent() {
|
||||
}
|
||||
}, [typeFromUrl, nameFromUrl, filtersFromUrl]);
|
||||
|
||||
// Fetch agent types and filter fields on mount
|
||||
// Fetch agent types on mount
|
||||
useEffect(() => {
|
||||
const fetchInitialData = async () => {
|
||||
const fetchAgentTypesOnly = async () => {
|
||||
try {
|
||||
const [types, fields] = await Promise.all([
|
||||
agentsService.getAgentTypes(),
|
||||
profileSectionsService.getFilterableFields(),
|
||||
]);
|
||||
const types = await agentsService.getAgentTypes();
|
||||
setAgentTypes(types);
|
||||
|
||||
// If listing param is set, auto-select the matching agent type
|
||||
@@ -478,8 +475,19 @@ function ProfilesPageContent() {
|
||||
setActiveTypeId(matchedType.id);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch agent types:', error);
|
||||
}
|
||||
};
|
||||
fetchAgentTypesOnly();
|
||||
}, []);
|
||||
|
||||
// Convert FilterableField to FilterField format
|
||||
// Re-fetch filter fields whenever the selected agent type changes so the Filters modal
|
||||
// only shows options relevant to that agent type (plus globals).
|
||||
useEffect(() => {
|
||||
const fetchFilters = async () => {
|
||||
try {
|
||||
const fields = await profileSectionsService.getFilterableFields(activeTypeId);
|
||||
const filterFieldsData: FilterField[] = fields.map((f: FilterableField) => ({
|
||||
slug: f.slug,
|
||||
name: f.name,
|
||||
@@ -487,12 +495,21 @@ function ProfilesPageContent() {
|
||||
options: f.options,
|
||||
}));
|
||||
setFilterFields(filterFieldsData);
|
||||
// Drop any selected filter keys that no longer exist in the new field list
|
||||
setFilters((prev) => {
|
||||
const validSlugs = new Set(filterFieldsData.map((f) => f.slug));
|
||||
const next: typeof prev = {};
|
||||
for (const [k, v] of Object.entries(prev)) {
|
||||
if (validSlugs.has(k)) next[k] = v;
|
||||
}
|
||||
return next;
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch initial data:', error);
|
||||
console.error('Failed to fetch filter fields:', error);
|
||||
}
|
||||
};
|
||||
fetchInitialData();
|
||||
}, []);
|
||||
fetchFilters();
|
||||
}, [activeTypeId]);
|
||||
|
||||
// Fetch agents based on filters
|
||||
const fetchAgents = useCallback(async () => {
|
||||
|
||||
@@ -128,10 +128,13 @@ class ProfileSectionsService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all filterable fields with options (for search filters)
|
||||
* Get all filterable fields with options (for search filters).
|
||||
* When `agentTypeId` is provided, filters are scoped to that agent type's sections plus globals.
|
||||
*/
|
||||
async getFilterableFields(): Promise<FilterableField[]> {
|
||||
const response = await api.get<ApiResponse<FilterableField[]>>('/profile-fields/filterable');
|
||||
async getFilterableFields(agentTypeId?: string | null): Promise<FilterableField[]> {
|
||||
const response = await api.get<ApiResponse<FilterableField[]>>('/profile-fields/filterable', {
|
||||
params: agentTypeId ? { agentTypeId } : undefined,
|
||||
});
|
||||
return response.data.data;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user