deer-flow/frontend/src/components/workspace/plugin-navigation.tsx
Wenchao An e2f19d8335
feat(plugins): full-stack plugin APIs and bookmarks (#5647)
* feat(plugins): add full-stack contributions and bookmarks example

* ci(plugins): provision bookmark gateway for browser tests

* fix(plugins): authenticate module downloads through configured backend

* fix(plugins): isolate contributions and localize extension UI

* fix(plugins): preserve bookmark agent routing and contain async callbacks

* fix(plugins): pin durable batch workers to app extension snapshots
2026-09-22 11:18:57 +08:00

52 lines
1.5 KiB
TypeScript

"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import {
SidebarGroup,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/components/ui/sidebar";
import { useFrontendExtensions } from "@/core/extensions/hooks";
import { pluginPages, pluginPageTitle } from "@/core/extensions/pages";
import { extensionIcon } from "@/core/extensions/registry";
import { useI18n } from "@/core/i18n/hooks";
export function PluginNavigation() {
const query = useFrontendExtensions();
const pathname = usePathname();
const { locale, t } = useI18n();
const pages = pluginPages(query.data ?? []).filter(
({ surface }) => surface.navigation,
);
if (!pages.length) return null;
return (
<SidebarGroup>
<SidebarGroupLabel>{t.extensions.navigation}</SidebarGroupLabel>
<SidebarMenu>
{pages.map(({ surface, href, icon }) => {
const Icon = extensionIcon(icon);
const title = pluginPageTitle(surface, locale);
return (
<SidebarMenuItem key={href}>
<SidebarMenuButton
asChild
isActive={pathname === href}
tooltip={title}
>
<Link href={href}>
<Icon />
<span>{title}</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
);
})}
</SidebarMenu>
</SidebarGroup>
);
}