feat(scum): add file config workbench
This commit is contained in:
@@ -30,9 +30,9 @@ const plugin: GamePluginResponse = {
|
||||
lifecycleActions: {},
|
||||
bridgeActions: ["server.instances.read", "logs.query", "remote.access.request"],
|
||||
pages: [{
|
||||
key: "operations",
|
||||
title: "SCUM 运维",
|
||||
path: "/operations",
|
||||
key: "files-config",
|
||||
title: "文件与配置",
|
||||
path: "/files-config",
|
||||
permissions: ["server.game-client.read", "server.game-client.command", "server.logs.read", "server.remote.access"],
|
||||
bridgeActions: ["server.instances.read", "logs.query", "remote.access.request"]
|
||||
}],
|
||||
@@ -45,7 +45,7 @@ const plugin: GamePluginResponse = {
|
||||
queryTemplates: [{ key: "scum.player.search", title: "Search player", permission: "server.game-client.read", engine: "sqlite", transportKey: "sqlite-db", targetKey: "db/sqlite", parameterSchemaRef: "schemas/bridge/player-search.parameters.json", resultSchemaRef: "schemas/bridge/player-search.result.json", maxRows: 50, timeoutSeconds: 10 }],
|
||||
commandRetentionSeconds: 86400,
|
||||
maxCommands: 1000,
|
||||
pages: [{ pageKey: "operations", commandTypes: ["announcement.send"], snapshotTypes: ["companion.health"], queryTemplateKeys: ["scum.player.search"] }]
|
||||
pages: [{ pageKey: "files-config", commandTypes: ["announcement.send"], snapshotTypes: ["companion.health"], queryTemplateKeys: ["scum.player.search"] }]
|
||||
},
|
||||
status: "installed"
|
||||
};
|
||||
@@ -62,7 +62,7 @@ function props(serverId = "server-1"): PageComponentProps {
|
||||
};
|
||||
return {
|
||||
session,
|
||||
params: { pluginId: "game.scum", routeKey: "operations", serverId },
|
||||
params: { pluginId: "game.scum", routeKey: "files-config", serverId },
|
||||
operations,
|
||||
onNavigate: () => undefined,
|
||||
onLogout: async () => undefined,
|
||||
@@ -74,7 +74,7 @@ function props(serverId = "server-1"): PageComponentProps {
|
||||
describe("PluginPageHostPage", () => {
|
||||
it("renders SCUM operations from manifest-owned declarations", () => {
|
||||
const html = renderToStaticMarkup(<PluginPageHostPage {...props()} initialPlugin={plugin} />);
|
||||
expect(html).toContain("SCUM 运维");
|
||||
expect(html).toContain("文件与配置");
|
||||
expect(html).toContain("平台托管上下文");
|
||||
expect(html).toContain("命令目录");
|
||||
expect(html).toContain("快照目录");
|
||||
|
||||
@@ -4,11 +4,11 @@ import { useCallback, useEffect, useState } from "react";
|
||||
import { platformApiClient } from "../api/client";
|
||||
import type { GamePluginResponse } from "../api/types";
|
||||
import { PageFrame } from "../components/PageFrame";
|
||||
import { ScumOperationsPanel } from "../components/ScumOperationsPanel";
|
||||
import { ScumFileConfigWorkbench } from "../components/ScumFileConfigWorkbench";
|
||||
import { EmptyState, ErrorState, LoadingState } from "../components/StateViews";
|
||||
import type { PageComponentProps } from "../contracts/page";
|
||||
import { pluginBridgeManifestContractFromResponse } from "../contracts/pluginBridge";
|
||||
import { resolveScumOperationsPageContract, scumOperationsPluginId, scumOperationsRouteKey } from "../contracts/scumOperations";
|
||||
import { normalizeScumRouteKey, resolveScumOperationsPageContract, scumOperationsPluginId, scumOperationsRouteKey } from "../contracts/scumOperations";
|
||||
import { createPluginBridgeHostContext } from "../utils/pluginBridgeHost";
|
||||
|
||||
type PluginPageState =
|
||||
@@ -22,7 +22,7 @@ interface PluginPageHostPageProps extends PageComponentProps {
|
||||
|
||||
export function PluginPageHostPage({ params, onNavigate, initialPlugin }: PluginPageHostPageProps) {
|
||||
const pluginId = params.pluginId ?? "";
|
||||
const routeKey = params.routeKey ?? "";
|
||||
const routeKey = normalizeScumRouteKey(pluginId, params.routeKey ?? "");
|
||||
const serverId = params.serverId ?? "";
|
||||
const [state, setState] = useState<PluginPageState>(() => initialPlugin ? { status: "ready", plugin: initialPlugin } : { status: "loading" });
|
||||
|
||||
@@ -105,7 +105,7 @@ export function PluginPageHostPage({ params, onNavigate, initialPlugin }: Plugin
|
||||
/>
|
||||
)}
|
||||
</section>
|
||||
{scumResolution?.available && <ScumOperationsPanel contract={scumResolution.contract} />}
|
||||
{scumResolution?.available && state.plugin.fileWorkspace && <ScumFileConfigWorkbench contract={scumResolution.contract} workspace={state.plugin.fileWorkspace} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user