diff --git a/web-app/src/components/ui/dropdown-menu.tsx b/web-app/src/components/ui/dropdown-menu.tsx index 7a527aaca..e4782cf12 100644 --- a/web-app/src/components/ui/dropdown-menu.tsx +++ b/web-app/src/components/ui/dropdown-menu.tsx @@ -229,7 +229,7 @@ function DropdownMenuSubContent({ - Add to project + {t('common:projects.addToProject')} {availableProjects.length === 0 ? ( - No projects available + {t('common:projects.noProjectsAvailable')} ) : ( @@ -262,32 +262,29 @@ const SortableItem = memo( )) )} - {thread.metadata?.project && ( - <> - - { - e.stopPropagation() - // Remove project from metadata - const projectName = thread.metadata?.project?.name - updateThread(thread.id, { - metadata: { - ...thread.metadata, - project: undefined, - }, - }) - toast.success( - `Thread removed from "${projectName}" successfully` - ) - }} - > - - Remove from project - - - )} + {thread.metadata?.project && ( + { + e.stopPropagation() + // Remove project from metadata + const projectName = thread.metadata?.project?.name + updateThread(thread.id, { + metadata: { + ...thread.metadata, + project: undefined, + }, + }) + toast.success( + `Thread removed from "${projectName}" successfully` + ) + }} + > + + {t('common:projects.removeFromProject')} + + )} >( new Set() ) + const [searchQuery, setSearchQuery] = useState('') const handleDelete = (id: string) => { setDeletingId(id) @@ -93,6 +96,16 @@ function ProjectContent() { }) } + // Filter projects based on search query + const filteredProjects = useMemo(() => { + if (!searchQuery.trim()) { + return folders + } + return folders.filter((folder) => + folder.name.toLowerCase().includes(searchQuery.toLowerCase()) + ) + }, [folders, searchQuery]) + return (
@@ -113,6 +126,33 @@ function ProjectContent() {
+ {/* Search Bar */} + {folders.length > 0 && ( +
+
+ + setSearchQuery(e.target.value)} + className="w-full pl-10 pr-4 py-2.5 bg-main-view-fg/5 border border-main-view-fg/10 rounded-lg text-main-view-fg placeholder:text-main-view-fg/50 focus:outline-none focus:ring-2 focus:ring-main-view-fg/20 focus:border-main-view-fg/20 transition-all" + /> + {searchQuery && ( + + )} +
+
+ )} + {folders.length === 0 ? (
@@ -123,9 +163,19 @@ function ProjectContent() { {t('projects.noProjectsYetDesc')}

+ ) : filteredProjects.length === 0 ? ( +
+ +

+ {t('projects.noProjectsFound')} +

+

+ {t('projects.tryDifferentSearch')} +

+
) : (
- {folders + {filteredProjects .slice() .sort((a, b) => b.updated_at - a.updated_at) .map((folder) => { @@ -172,8 +222,8 @@ function ProjectContent() { className="size-8 cursor-pointer flex items-center justify-center rounded-md hover:bg-main-view-fg/10 transition-all duration-200 ease-in-out mr-1" title={ isExpanded - ? t('projects.collapseThreads') - : t('projects.expandThreads') + ? t('projects.collapseProject') + : t('projects.expandProject') } onClick={() => toggleProjectExpansion(folder.id)} > @@ -218,7 +268,9 @@ function ProjectContent() { {/* Thread List */} {isExpanded && projectThreads.length > 0 && ( -
+