(props: { pathname: string; onNavigate?: () => void })
| 60 | // slash stripped. |
| 61 | |
| 62 | function PluginNav(props: { pathname: string; onNavigate?: () => void }) { |
| 63 | const plugins = useClientPlugins(); |
| 64 | const entries = plugins.flatMap((plugin) => |
| 65 | (plugin.pages ?? []) |
| 66 | .filter((page) => page.nav) |
| 67 | .map((page) => { |
| 68 | const splat = page.path.replace(/^\//, ""); |
| 69 | const href = `/plugins/${plugin.id}${splat ? `/${splat}` : "/"}`; |
| 70 | return { |
| 71 | key: `${plugin.id}:${page.path}`, |
| 72 | pluginId: plugin.id, |
| 73 | splat, |
| 74 | href, |
| 75 | label: page.nav!.label, |
| 76 | }; |
| 77 | }), |
| 78 | ); |
| 79 | if (entries.length === 0) return null; |
| 80 | return ( |
| 81 | <> |
| 82 | {entries.map((entry) => ( |
| 83 | <Link |
| 84 | key={entry.key} |
| 85 | to="/{-$orgSlug}/plugins/$pluginId/$" |
| 86 | params={{ pluginId: entry.pluginId, _splat: entry.splat }} |
| 87 | onClick={props.onNavigate} |
| 88 | className={[ |
| 89 | "flex items-center gap-2.5 rounded-md px-2.5 py-1.5 text-sm transition-colors", |
| 90 | props.pathname === entry.href || props.pathname.startsWith(`${entry.href}/`) |
| 91 | ? "bg-sidebar-active text-foreground font-medium" |
| 92 | : "text-sidebar-foreground hover:bg-sidebar-active/60 hover:text-foreground", |
| 93 | ].join(" ")} |
| 94 | > |
| 95 | {entry.label} |
| 96 | </Link> |
| 97 | ))} |
| 98 | </> |
| 99 | ); |
| 100 | } |
| 101 | |
| 102 | // ── IntegrationList ─────────────────────────────────────────────────────────── |
| 103 |
nothing calls this directly
no test coverage detected