diff --git a/server/src/services/plugin-loader.ts b/server/src/services/plugin-loader.ts index 82494bf0..1ceadd19 100644 --- a/server/src/services/plugin-loader.ts +++ b/server/src/services/plugin-loader.ts @@ -1302,6 +1302,7 @@ export function pluginLoader( const plugin = (await registry.getById(pluginId)) as { id: string; packageName: string; + packagePath: string | null; manifestJson: PaperclipPluginManifestV1; } | null; if (!plugin) throw new Error(`Plugin not found: ${pluginId}`); @@ -1309,7 +1310,10 @@ export function pluginLoader( const oldManifest = plugin.manifestJson; const { packageName = plugin.packageName, - localPath, + // For local-path installs, fall back to the stored packagePath so + // `upgradePlugin` can re-read the manifest from disk without needing + // the caller to re-supply the path every time. + localPath = plugin.packagePath ?? undefined, version, } = upgradeOptions; diff --git a/ui/src/components/BreadcrumbBar.tsx b/ui/src/components/BreadcrumbBar.tsx index 104bbf68..01a01e8d 100644 --- a/ui/src/components/BreadcrumbBar.tsx +++ b/ui/src/components/BreadcrumbBar.tsx @@ -13,8 +13,22 @@ import { BreadcrumbSeparator, } from "@/components/ui/breadcrumb"; import { Fragment, useMemo } from "react"; -import { PluginSlotOutlet } from "@/plugins/slots"; -import { PluginLauncherOutlet } from "@/plugins/launchers"; +import { PluginSlotOutlet, usePluginSlots } from "@/plugins/slots"; +import { PluginLauncherOutlet, usePluginLaunchers } from "@/plugins/launchers"; + +type GlobalToolbarContext = { companyId: string | null; companyPrefix: string | null }; + +function GlobalToolbarPlugins({ context }: { context: GlobalToolbarContext }) { + const { slots } = usePluginSlots({ slotTypes: ["globalToolbarButton"], companyId: context.companyId }); + const { launchers } = usePluginLaunchers({ placementZones: ["globalToolbarButton"], companyId: context.companyId }); + if (slots.length === 0 && launchers.length === 0) return null; + return ( +
+ + +
+ ); +} export function BreadcrumbBar() { const { breadcrumbs } = useBreadcrumbs(); @@ -29,20 +43,7 @@ export function BreadcrumbBar() { [selectedCompanyId, selectedCompany?.issuePrefix], ); - const globalToolbarSlots = ( -
- - -
- ); + const globalToolbarSlots = ; if (breadcrumbs.length === 0) { return ( diff --git a/ui/src/plugins/launchers.tsx b/ui/src/plugins/launchers.tsx index aa7f899a..6b1bb682 100644 --- a/ui/src/plugins/launchers.tsx +++ b/ui/src/plugins/launchers.tsx @@ -196,6 +196,9 @@ function launcherTriggerClassName(placementZone: PluginLauncherPlacementZone): s case "sidebar": case "sidebarPanel": return "justify-start h-8 w-full"; + case "toolbarButton": + case "globalToolbarButton": + return "h-8"; default: return "h-8"; } @@ -733,7 +736,7 @@ function DefaultLauncherTrigger({ return (