diff --git a/ui/admin/app/components/tools/toolGrid/ToolGrid.tsx b/ui/admin/app/components/tools/toolGrid/ToolGrid.tsx index f9f08f4d..fe73b512 100644 --- a/ui/admin/app/components/tools/toolGrid/ToolGrid.tsx +++ b/ui/admin/app/components/tools/toolGrid/ToolGrid.tsx @@ -1,57 +1,59 @@ import { useMemo } from "react"; import { ToolReference } from "~/lib/model/toolReferences"; +import { ToolCategoryMap } from "~/lib/service/api/toolreferenceService"; import { CategoryHeader } from "~/components/tools/toolGrid/CategoryHeader"; import { CategoryTools } from "~/components/tools/toolGrid/CategoryTools"; interface ToolGridProps { - tools: ToolReference[]; + toolCategories: ToolCategoryMap; filter: string; onDelete: (id: string) => void; } -export function ToolGrid({ tools, filter, onDelete }: ToolGridProps) { - const filteredTools = useMemo(() => { - return tools?.filter( - (tool) => - tool.name?.toLowerCase().includes(filter.toLowerCase()) || - tool.metadata?.category - ?.toLowerCase() - .includes(filter.toLowerCase()) || - tool.description?.toLowerCase().includes(filter.toLowerCase()) - ); - }, [tools, filter]); - - const sortedCategories = useMemo(() => { - const categorizedTools = filteredTools?.reduce( - (acc, tool) => { - const category = tool.metadata?.category ?? "Uncategorized"; - if (!acc[category]) { - acc[category] = []; - } - acc[category].push(tool); - return acc; - }, - {} as Record - ); - - // Sort categories to put "Uncategorized" first - return Object.entries(categorizedTools).sort(([a], [b]) => { - if (a === "Uncategorized") return -1; - if (b === "Uncategorized") return 1; - return a.localeCompare(b); - }); - }, [filteredTools]); +export function ToolGrid({ toolCategories, filter, onDelete }: ToolGridProps) { + const filteredCategories = useMemo(() => { + const result: ToolCategoryMap = {}; + for (const [category, { tools, bundleTool }] of Object.entries( + toolCategories + )) { + const filteredTools = tools.filter( + (tool) => + tool.name?.toLowerCase().includes(filter.toLowerCase()) || + tool.metadata?.category + ?.toLowerCase() + .includes(filter.toLowerCase()) || + tool.description + ?.toLowerCase() + .includes(filter.toLowerCase()) + ); + if (filteredTools.length > 0 || bundleTool) { + result[category] = { + tools: filteredTools, + bundleTool: bundleTool, + }; + } + } + return result; + }, [toolCategories, filter]); return (
- {sortedCategories.map(([category, categoryTools]) => ( -
- - -
- ))} + {Object.entries(filteredCategories).map( + ([category, { tools, bundleTool }]) => ( +
+ + +
+ ) + )}
); } diff --git a/ui/admin/app/lib/service/api/toolreferenceService.ts b/ui/admin/app/lib/service/api/toolreferenceService.ts index aa35441b..103c6cfb 100644 --- a/ui/admin/app/lib/service/api/toolreferenceService.ts +++ b/ui/admin/app/lib/service/api/toolreferenceService.ts @@ -55,6 +55,7 @@ async function getToolReferencesCategoryMap(type?: ToolReferenceType) { getToolReferencesCategoryMap.key = (type?: ToolReferenceType) => ({ url: ApiRoutes.toolReferences.base({ type }).path, + responseType: "map", }) as const; const getToolReferenceById = async (toolReferenceId: string) => { diff --git a/ui/admin/app/routes/_auth.tools._index.tsx b/ui/admin/app/routes/_auth.tools._index.tsx index e4866b86..c530fae2 100644 --- a/ui/admin/app/routes/_auth.tools._index.tsx +++ b/ui/admin/app/routes/_auth.tools._index.tsx @@ -19,17 +19,19 @@ import { Input } from "~/components/ui/input"; export async function clientLoader() { await Promise.all([ - preload(ToolReferenceService.getToolReferences.key("tool"), () => - ToolReferenceService.getToolReferences("tool") + preload( + ToolReferenceService.getToolReferencesCategoryMap.key("tool"), + () => ToolReferenceService.getToolReferencesCategoryMap("tool") ), ]); return null; } export default function Tools() { - const { data: tools, mutate } = useSWR( - ToolReferenceService.getToolReferences.key("tool"), - () => ToolReferenceService.getToolReferences("tool") + const { data: toolCategories, mutate } = useSWR( + ToolReferenceService.getToolReferencesCategoryMap.key("tool"), + () => ToolReferenceService.getToolReferencesCategoryMap("tool"), + { fallbackData: {} } ); const [isDialogOpen, setIsDialogOpen] = useState(false); @@ -79,9 +81,9 @@ export default function Tools() { - {tools && ( + {toolCategories && (