diff --git a/ui/desktop/src/components/recipes/RecipesView.tsx b/ui/desktop/src/components/recipes/RecipesView.tsx index d8e62625bcb0..3c278451df1b 100644 --- a/ui/desktop/src/components/recipes/RecipesView.tsx +++ b/ui/desktop/src/components/recipes/RecipesView.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react'; +import { useState, useEffect, useMemo } from 'react'; import { listSavedRecipes, convertToLocaleDateString } from '../../recipe/recipe_management'; import { FileText, @@ -32,6 +32,7 @@ import { generateDeepLink, Recipe } from '../../recipe'; import { useNavigation } from '../../hooks/useNavigation'; import { CronPicker } from '../schedule/CronPicker'; import { Dialog, DialogContent, DialogHeader, DialogTitle } from '../ui/dialog'; +import { SearchView } from '../conversation/SearchView'; import cronstrue from 'cronstrue'; export default function RecipesView() { @@ -57,6 +58,26 @@ export default function RecipesView() { const [slashCommand, setSlashCommand] = useState(''); const [scheduleValid, setScheduleIsValid] = useState(true); + const [searchTerm, setSearchTerm] = useState(''); + + const filteredRecipes = useMemo(() => { + if (!searchTerm) return savedRecipes; + + const searchLower = searchTerm.toLowerCase(); + return savedRecipes.filter((recipeManifest) => { + const { recipe, slash_command } = recipeManifest; + const title = recipe.title?.toLowerCase() || ''; + const description = recipe.description?.toLowerCase() || ''; + const slashCmd = slash_command?.toLowerCase() || ''; + + return ( + title.includes(searchLower) || + description.includes(searchLower) || + slashCmd.includes(searchLower) + ); + }); + }, [savedRecipes, searchTerm]); + useEffect(() => { loadSavedRecipes(); }, []); @@ -485,9 +506,19 @@ export default function RecipesView() { ); } + if (filteredRecipes.length === 0 && searchTerm) { + return ( +
+ +

No matching recipes found

+

Try adjusting your search terms

+
+ ); + } + return (
- {savedRecipes.map((recipeManifestResponse: RecipeManifest) => ( + {filteredRecipes.map((recipeManifestResponse: RecipeManifest) => (

View and manage your saved recipes to quickly start new sessions with predefined - configurations. + configurations. ⌘F/Ctrl+F to search.

-
- {renderContent()} -
+ setSearchTerm(term)} placeholder="Search recipes..."> +
+ {renderContent()} +
+