@rsc-labs/nocto-plugin-system
Version:
Pluggable registry system for Nocto plugins
61 lines (60 loc) • 2.56 kB
JavaScript
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;
};