Add PluginsContext to web_ui

Add a React context to access the plugins loaded in the web interface.
The info, /api/plugins metadata and webpack container is provided for
each plugin.
This commit is contained in:
Hornwitser committed 2021-03-01 15:03:25 +01:00
1 parent d0befe5944
commit 3a3a7597bf
3 files changed
+28 -16

No files matched your search

+19 -13
View File
@@ -25,7 +25,7 @@ async function loadScript(url) {
return result;
}
async function loadPluginInfos() {
async function loadPlugins() {
let response = await fetch(`${webRoot}api/plugins`);
let pluginList;
if (response.ok) {
@@ -36,22 +36,28 @@ async function loadPluginInfos() {
pluginList = [];
}
let pluginInfos = [];
let plugins = [];
await __webpack_init_sharing__("default");
for (let plugin of pluginList) {
for (let meta of pluginList) {
try {
await loadScript(`${webRoot}plugin/${plugin.name}/remoteEntry.js`);
let container = window[`plugin_${plugin.name}`];
await loadScript(`${webRoot}plugin/${meta.name}/remoteEntry.js`);
let container = window[`plugin_${meta.name}`];
await container.init(__webpack_share_scopes__.default);
let info = (await container.get("./info"))();
info.container = container;
pluginInfos.push(info);
let pluginInfo = (await container.get("./info"))();
plugins.push({
meta,
info: pluginInfo,
container,
});
} catch (err) {
logger.error(`Failed to load plugin info for ${plugin.name}`);
logger.error(`Failed to load plugin info for ${meta.name}`);
plugins.push({
meta,
});
}
}
return pluginInfos;
return plugins;
}
async function load() {
@@ -59,8 +65,8 @@ async function load() {
level: "verbose",
format: new WebConsoleFormat(),
}));
let pluginInfos = await loadPluginInfos();
libConfig.registerPluginConfigGroups(pluginInfos);
let plugins = await loadPlugins();
libConfig.registerPluginConfigGroups(plugins.filter(p => p.info).map(p => p.info));
libConfig.finalizeConfigs();
let wsUrl = new URL(window.webRoot, document.location);
@@ -69,7 +75,7 @@ async function load() {
let controlConnector = new ControlConnector(wsUrl, 10);
let control = new Control(controlConnector, []);
ReactDOM.render(<App control={control}/>, document.getElementById("root"));
ReactDOM.render(<App control={control} plugins={plugins}/>, document.getElementById("root"));
}
load().catch((err) => logger.fatal(err.stack));
+6 -3
View File
@@ -7,6 +7,7 @@ import { logger } from "@clusterio/lib/logging";
import basename from "../basename";
import SiteLayout from "./SiteLayout";
import ControlContext from "./ControlContext";
import PluginsContext from "./PluginsContext";
import LoginForm from "./LoginForm";
import { Card, Spin } from "antd";
@@ -77,9 +78,11 @@ export default function App(props) {
return (
<ControlContext.Provider value={props.control}>
<BrowserRouter basename={basename}>
{page}
</BrowserRouter>
<PluginsContext.Provider value={props.plugins}>
<BrowserRouter basename={basename}>
{page}
</BrowserRouter>
</PluginsContext.Provider>
</ControlContext.Provider>
);
}
@@ -0,0 +1,3 @@
import React from "react";
export default React.createContext();