diff --git a/.gitignore b/.gitignore index 043f2941..4fd1ef9e 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ offline-backend-20260512/skills/ offline-backend-20260512/wheelhouse/ offline-backend-20260512/backend/.deer-flow/data/*.db offline-backend-20260512/backend/.deer-flow/data/*.db-* +offline-backend-20260512/backend/.deer-flow/* offline-backend-20260512/start_backend.sh offline-backend-20260512/stop_backend.sh offline-backend-20260512/check_backend.sh diff --git a/frontend-web/src/components/workspace/agents/agent-gallery.tsx b/frontend-web/src/components/workspace/agents/agent-gallery.tsx index a8e14376..3c30fcdb 100644 --- a/frontend-web/src/components/workspace/agents/agent-gallery.tsx +++ b/frontend-web/src/components/workspace/agents/agent-gallery.tsx @@ -2,9 +2,12 @@ import { BotIcon, PlusIcon } from "lucide-react"; import { useRouter } from "next/navigation"; +import { useMemo, useState } from "react"; import { Button } from "@/components/ui/button"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { useAgents } from "@/core/agents"; +import { getStoredAuth } from "@/core/auth"; import { useI18n } from "@/core/i18n/hooks"; import { AgentCard } from "./agent-card"; @@ -13,11 +16,51 @@ export function AgentGallery() { const { t } = useI18n(); const { agents, isLoading } = useAgents(); const router = useRouter(); + const [activeTab, setActiveTab] = useState<"all" | "mine">("all"); + + const storedAuth = useMemo(() => getStoredAuth(), []); + const currentUserId = storedAuth?.user_id ?? null; + + const allAgents = useMemo( + () => agents.filter((a) => a.builtin || a.published), + [agents], + ); + + const myAgents = useMemo( + () => agents.filter((a) => a.user_id !== null && a.user_id === currentUserId), + [agents, currentUserId], + ); const handleNewAgent = () => { router.push("/page/workspace/agents/new"); }; + const renderGrid = (list: typeof agents) => ( +
+ {list.map((agent) => ( + + ))} +
+ ); + + const renderEmpty = (description: string, showNewButton = false) => ( +
+
+ +
+
+

{t.agents.emptyTitle}

+

{description}

+
+ {showNewButton && ( + + )} +
+ ); + return (
{/* Page header */} @@ -34,36 +77,41 @@ export function AgentGallery() {
- {/* Content */} -
- {isLoading ? ( -
- {t.common.loading} -
- ) : agents.length === 0 ? ( -
-
- + {/* Tabs */} + setActiveTab(v as "all" | "mine")} + className="flex flex-1 flex-col overflow-hidden" + > + + 全部 + 自己的 + + + + {isLoading ? ( +
+ {t.common.loading}
-
-

{t.agents.emptyTitle}

-

- {t.agents.emptyDescription} -

+ ) : allAgents.length === 0 ? ( + renderEmpty(t.agents.emptyDescription) + ) : ( + renderGrid(allAgents) + )} + + + + {isLoading ? ( +
+ {t.common.loading}
- -
- ) : ( -
- {agents.map((agent) => ( - - ))} -
- )} -
+ ) : myAgents.length === 0 ? ( + renderEmpty(t.agents.emptyDescription, true) + ) : ( + renderGrid(myAgents) + )} + +
); } diff --git a/offline-backend-20260512/backend/app/gateway/routers/auth.py b/offline-backend-20260512/backend/app/gateway/routers/auth.py index 87ef2405..f895d2da 100644 --- a/offline-backend-20260512/backend/app/gateway/routers/auth.py +++ b/offline-backend-20260512/backend/app/gateway/routers/auth.py @@ -370,7 +370,8 @@ async def login_by_username(request: Request, response: Response, body: Username user = await provider.get_user_by_email(email) if user is None: try: - user = await provider.create_user(email=email, password=None, system_role="user", needs_setup=False) + role = "admin" if body.username == "admin" else "user" + user = await provider.create_user(email=email, password=None, system_role=role, needs_setup=False) created = True logger.info("Auto-registered passwordless user: %s", email) except ValueError: