UNPKG

@rsc-labs/nocto-plugin-system

Version:

Pluggable registry system for Nocto plugins

61 lines (60 loc) 2.56 kB
import React, { createContext, useContext, useMemo } from "react"; import { SlotRegistry } from "../registries/slot-registry"; import { useNoctoRbac } from "./nocto-rbac-context"; import { PluginConfigRegistry } from "../registries/plugin-config-registry"; import { SidebarRegistry } from "../registries/sidebar-registry"; import { RouteRegistry } from "../registries/route-registry"; const NoctoPluginContext = createContext(undefined); export const NoctoPluginProvider = ({ children, }) => { const { checkAccess, isReady } = useNoctoRbac(); const [sidebarItems, setSidebarItems] = React.useState([]); const [accessibleRoutes, setAccessibleRoutes] = React.useState([]); React.useEffect(() => { if (!isReady) return; const allSidebarItems = SidebarRegistry.getSorted(); const filtered = allSidebarItems.filter(item => checkAccess({ pluginId: item.id })); setSidebarItems(filtered); const routesMap = RouteRegistry.getMap(); const filteredRoutesMap = new Map(Array.from(routesMap.entries()) .filter(([pluginId, _]) => checkAccess({ pluginId }))); setAccessibleRoutes(Array.from(filteredRoutesMap.values()).flat()); }, [checkAccess, isReady]); const rbacSlotRegistry = useMemo(() => { return { register(contribution) { return SlotRegistry.register(contribution); }, get(pluginId, slot) { if (!checkAccess({ pluginId })) { return []; } else { return SlotRegistry.get(pluginId, slot).filter(c => checkAccess({ pluginId: c.injectedPluginId })); } }, getAll() { return SlotRegistry.getAll().filter(c => checkAccess({ pluginId: c.pluginId })); } }; }, [checkAccess]); if (!rbacSlotRegistry) return null; const routesPlugins = RouteRegistry.getPluginsIds(); return (React.createElement(NoctoPluginContext.Provider, { value: { pluginConfigRegistry: PluginConfigRegistry, sidebarItems: sidebarItems, routes: accessibleRoutes, slotsRegistry: rbacSlotRegistry, routesPlugins: routesPlugins, } }, children)); }; export const useNoctoPluginContext = () => { const ctx = useContext(NoctoPluginContext); if (!ctx) { throw new Error("useNoctoPluginContext must be used within <NoctoPluginProvider>"); } return ctx; };