46 lines
2.6 KiB
TypeScript
46 lines
2.6 KiB
TypeScript
export const pluginPageBundle = { key: "dev-game-plugin", version: "1.0.0", integritySha256: "sha256:1111111111111111111111111111111111111111111111111111111111111111" };
|
|
|
|
type ReactLike = { createElement: (...args: any[]) => any };
|
|
|
|
export function renderPluginPage(react: ReactLike, input: any) {
|
|
const e = react.createElement;
|
|
const pageKey = input.page?.key ?? "overview";
|
|
if (pageKey === "config") return renderConfigPage(e, input);
|
|
if (pageKey === "logs") return renderLogsPage(e, input);
|
|
return renderOverviewPage(e, input);
|
|
}
|
|
|
|
function renderOverviewPage(e: ReactLike["createElement"], input: any) {
|
|
return renderPanel(e, "插件概览", "Example 插件声明的服务器概览页面。", input, [
|
|
["服务器", input.context?.serverInstanceId ?? "未绑定"],
|
|
["桥接动作", (input.context?.bridgeActions ?? []).join(" / ") || "未声明"],
|
|
["页面来源", "dev-game-plugin 页面 bundle"]
|
|
]);
|
|
}
|
|
|
|
function renderConfigPage(e: ReactLike["createElement"], input: any) {
|
|
return renderPanel(e, "配置工作台", "配置入口由插件页面声明,平台只提供运行上下文。", input, [
|
|
["文件权限", (input.context?.permissions ?? []).filter((value: string) => value.includes("files")).join(" / ") || "未声明"],
|
|
["AI 能力", (input.context?.permissions ?? []).includes("ai.invoke") ? "可请求平台 AI" : "未声明"],
|
|
["写入策略", "平台校验后直接派发"]
|
|
]);
|
|
}
|
|
|
|
function renderLogsPage(e: ReactLike["createElement"], input: any) {
|
|
return renderPanel(e, "日志视图", "日志入口由插件声明并通过平台日志通道读取。", input, [
|
|
["日志权限", (input.context?.permissions ?? []).includes("server.logs.read") ? "可读" : "未声明"],
|
|
["桥接状态", input.availability?.available ? "可用" : input.availability?.reason ?? "等待运行端"],
|
|
["桥接", (input.context?.bridgeActions ?? []).includes("logs.query") ? "logs.query" : "未声明"]
|
|
]);
|
|
}
|
|
|
|
function renderPanel(e: ReactLike["createElement"], title: string, summary: string, input: any, rows: Array<[string, string]>) {
|
|
return e("section", { className: "console-panel", "aria-label": title },
|
|
e("div", { className: "panel-header" },
|
|
e("div", null, e("h2", null, title), e("p", { className: "provider-id" }, summary)),
|
|
e("span", { className: "page-status" }, input.context?.serverInstanceId ? "已绑定服务器" : "未绑定服务器")
|
|
),
|
|
e("div", { className: "console-row-list" }, rows.map(([label, value]) => e("div", { key: label, className: "console-row" }, e("span", null, label), e("strong", null, value))))
|
|
);
|
|
}
|