Merge pull request #1140 from bbassie/fix/remove-web-plugin-column

Remove the web UI status column from the plugin pages
This commit is contained in:
Cooldude2606 authored and GitHub committed 2026-10-28 23:54:46 +00:00
commit 2fb5300ec5
2 files changed
+37 -92

No files matched your search

@@ -48,70 +48,40 @@ function PluginMachines(props: PluginMachinesProps) {
type ControllerPluginProps = {
pluginMeta: PluginWebApi,
pluginInfo?: lib.PluginWebEnvInfo,
loadedPlugin?: lib.PluginWebEnvInfo,
title: string,
};
/** What the controller and web UI have loaded of the plugin */
function ControllerPlugin(props: ControllerPluginProps) {
const { pluginMeta, pluginInfo, loadedPlugin } = props;
const pluginError = pluginMeta.web.error ?? pluginInfo?.error;
const hasWebModule = Boolean(pluginMeta.web.main || pluginMeta.web.error);
if (!loadedPlugin) {
return <>
<Descriptions bordered size="small" title={props.title}>
<Descriptions.Item label="Version">{pluginMeta.version}</Descriptions.Item>
<Descriptions.Item label="Loaded in Web UI" span={2}>
{hasWebModule ? "No" : "No web module"}
</Descriptions.Item>
</Descriptions>
{pluginError && <Alert
style={{
marginTop: "1em",
}}
message={pluginError}
description={
"The web interface was unable to load the web module for this plugin. This is "+
"usually due to an incorrect or missing web build for the plugin. Due to the "+
"module not being loaded, the configs and web controls defined by this plugin may "+
"not be available in the web interface."
}
type="error"
showIcon
/>}
</>;
}
const homepageUrl = lib.safeExternalUrl(loadedPlugin.package.homepage);
const { pluginMeta, pluginInfo } = props;
const pkg = pluginInfo?.package;
const pluginError = pluginMeta.enabled ? pluginMeta.web.error ?? pluginInfo?.error : undefined;
const homepageUrl = lib.safeExternalUrl(pkg?.homepage);
return <>
<Descriptions bordered size="small" title={props.title}>
<Descriptions.Item label="Version">{pluginMeta.version}</Descriptions.Item>
<Descriptions.Item label="Loaded in Web UI" span={2}>Yes</Descriptions.Item>
<Descriptions.Item label="Description" span={3}>{loadedPlugin.description}</Descriptions.Item>
{loadedPlugin.package.homepage ? <Descriptions.Item label="Homepage" span={3}>
{homepageUrl
? <a href={homepageUrl}>{loadedPlugin.package.homepage}</a>
: loadedPlugin.package.homepage}
<Descriptions.Item label="Version" span={3}>{pluginMeta.version}</Descriptions.Item>
{pluginInfo?.description ? <Descriptions.Item label="Description" span={3}>
{pluginInfo.description}
</Descriptions.Item> : null}
{loadedPlugin.package.author ? <Descriptions.Item label="Author" span={3}>
{loadedPlugin.package.author}
{pkg?.homepage ? <Descriptions.Item label="Homepage" span={3}>
{homepageUrl ? <a href={homepageUrl}>{pkg.homepage}</a> : pkg.homepage}
</Descriptions.Item> : null}
<Descriptions.Item label="License" span={3}>{loadedPlugin.package.license}</Descriptions.Item>
{pkg?.author ? <Descriptions.Item label="Author" span={3}>{pkg.author}</Descriptions.Item> : null}
{pkg?.license ? <Descriptions.Item label="License" span={3}>{pkg.license}</Descriptions.Item> : null}
</Descriptions>
{pluginMeta.version !== loadedPlugin.package.version ? <Alert
{pluginError && <Alert
style={{
marginTop: "1em",
}}
message="Version missmatch detected"
message={pluginError}
description={
`The version of the web interface module for this plugin (${loadedPlugin.package.version}) `+
`does not match the version running on the controller (${pluginMeta.version}), `+
"spurious errors may occur. This usually happens when the plugin is updated but the "+
"controller has not been restarted yet, but may also be due to an outdated build."
"The web interface was unable to load the web module for this plugin. This is "+
"usually due to an incorrect or missing web build for the plugin. Due to the "+
"module not being loaded, the configs and web controls defined by this plugin may "+
"not be available in the web interface."
}
type="warning"
type="error"
showIcon
/> : null}
/>}
</>;
}
@@ -160,7 +130,6 @@ export default function PluginViewPage() {
? <ControllerPlugin
pluginMeta={pluginMeta}
pluginInfo={pluginInfo}
loadedPlugin={control.loadedPlugins.get(pluginName)}
title={pluginTitle}
/>
: <Descriptions bordered size="small" title={pluginTitle}>
+18 -42
View File
@@ -1,9 +1,8 @@
import React, { useContext, useEffect, useState } from "react";
import { Space, Table, Typography } from "antd";
import { Space, Table, Tooltip, Typography } from "antd";
import CloseCircleFilled from "@ant-design/icons/CloseCircleFilled";
import InfoCircleFilled from "@ant-design/icons/InfoCircleFilled";
import type { PluginWebApi, PluginWebEnvInfo } from "@clusterio/lib";
import type { PluginWebApi } from "@clusterio/lib";
import notify from "../util/notify";
import { useAccount } from "../model/account";
@@ -28,8 +27,7 @@ type PluginRow = {
title: string;
/** Not present for plugins the controller hasn't loaded */
meta?: PluginWebApi;
info?: PluginWebEnvInfo;
package?: any;
webError?: string;
status?: PluginStatus;
};
@@ -38,31 +36,15 @@ function pluginPath(plugin: PluginRow) {
return `/plugins/${encodeURIComponent(plugin.meta?.name ?? plugin.key)}/view`;
}
function WebUiStatus(props: { plugin: PluginRow }) {
const control = useContext(ControlContext);
const { meta } = props.plugin;
if (!meta) {
return <Typography.Text type="secondary">Not on controller</Typography.Text>;
}
if (!meta.enabled) {
return <><InfoCircleFilled style={{ color: "#1668dc" }} /> Disabled on controller</>;
}
if (!meta.web.main && !meta.web.error) {
return <Typography.Text type="secondary">No web module</Typography.Text>;
}
if (!meta.web.error && !control.pluginInfos.has(meta.name)) {
return <><InfoCircleFilled style={{ color: "#1668dc" }} /> Reload page to load</>;
}
if (!props.plugin.package) {
return <><CloseCircleFilled style={{ color: "#dc4446" }} /> Error loading module</>;
}
if (props.plugin.package.version !== meta.version) {
return <><CloseCircleFilled style={{ color: "#dc4446" }} /> Version mis-matched</>;
}
return <>Loaded {meta.version}</>;
/** Shown with the versions when the plugin's web code failed to load */
function WebError(props: { error: string }) {
return <div>
<Tooltip title={props.error}>
<Typography.Text type="danger"><CloseCircleFilled /> Web interface failed to load</Typography.Text>
</Tooltip>
</div>;
}
export default function PluginsPage() {
const control = useContext(ControlContext);
const account = useAccount();
@@ -95,14 +77,12 @@ export default function PluginsPage() {
let tableContents: PluginRow[] = [];
for (let meta of pluginList) {
const key = pluginStatusKey(meta);
const loaded = control.loadedPlugins.get(meta.name);
const info = loaded ?? control.pluginInfos.get(meta.name);
const info = control.pluginInfos.get(meta.name);
tableContents.push({
key,
title: info ? info.title : meta.name,
meta,
info,
package: loaded?.package,
webError: meta.enabled ? meta.web.error ?? info?.error : undefined,
status: statuses.get(key),
});
}
@@ -151,16 +131,12 @@ export default function PluginsPage() {
{
title: "Versions",
key: "versions",
render: (_, plugin) => (plugin.status
? <PluginVersions status={plugin.status} latest={latestOf(plugin)} />
: plugin.meta?.version
),
},
{
title: "Web UI Status",
key: "web",
render: (_, plugin) => <WebUiStatus plugin={plugin} />,
responsive: ["sm"],
render: (_, plugin) => <>
{plugin.status
? <PluginVersions status={plugin.status} latest={latestOf(plugin)} />
: plugin.meta?.version}
{plugin.webError && <WebError error={plugin.webError} />}
</>,
},
{
key: "actions",