polish server deployment workflow

This commit is contained in:
npc0-hue
2026-07-25 10:57:22 +08:00
parent 4e2bff4639
commit bb12137c4e
7 changed files with 74 additions and 26 deletions
+6
View File
@@ -186,6 +186,12 @@ describe("first-party console pages", () => {
expect(serverDeploymentWorkflowSource).toContain("全部 4 步通过才算安装成功");
expect(serverDeploymentWorkflowSource).toContain("已有服务器目录");
expect(serverDeploymentWorkflowSource).toContain("不会重装或覆盖现有游戏配置");
expect(serverDeploymentWorkflowSource).toContain("接管已有服务器执行流程");
expect(serverDeploymentWorkflowSource).toContain("不需要填写 SteamCMD 目录");
expect(serverDeploymentWorkflowSource).toContain("当前平台尚未提供 SCUM 服务端的受控升级任务");
expect(serverDeploymentWorkflowSource).toContain("已绑定服务器编辑时会直接进入相关配置");
expect(serverDeploymentWorkflowSource).toContain("可在此调整部署方式;不会重复要求选择已绑定的运行节点");
expect(serversPageSource).toContain('onNavigate("serverDetail", { serverId: result.instance.id, routeKey: "run-builder" })');
expect(serverDeploymentWorkflowSource).toContain("运行连接设置");
expect(serverDeploymentWorkflowSource).toContain('type={field.sensitive ? "password" : "text"}');
expect(serversPageSource).toContain("serverCreateRequestFromForm(nextForm)");
@@ -75,6 +75,9 @@ describe("ServerDetailPage config write approval", () => {
});
it("surfaces run distribution and client-manager workflows through platform-mediated APIs", () => {
expect(serverDetailPageSource).toContain('params.routeKey !== "run-builder"');
expect(serverDetailPageSource).toContain('id="run-builder"');
expect(serverDetailPageSource).toContain("scrollIntoView");
expect(serverDetailPageSource).toContain("getServerRuntimeActions");
expect(serverDetailPageSource).toContain("generateRunDistribution");
expect(serverDetailPageSource).toContain("downloadLatestRunDistribution");
+11 -1
View File
@@ -167,6 +167,16 @@ export function ServerDetailPage({ session, params, operations, onNavigate }: Pa
void refresh();
}, [refresh]);
useEffect(() => {
if (params.routeKey !== "run-builder" || instance.status !== "ready" || typeof document === "undefined") return;
const frame = window.requestAnimationFrame(() => {
const target = document.getElementById("run-builder");
target?.scrollIntoView({ behavior: "smooth", block: "start" });
target?.focus({ preventScroll: true });
});
return () => window.cancelAnimationFrame(frame);
}, [instance.status, params.routeKey]);
const serverOperations = useMemo(
() => operations.operations.filter((operation) => operation.targetId === serverId || operation.targetId.startsWith(`${serverId}:`)),
[operations.operations, serverId]
@@ -1007,7 +1017,7 @@ function RuntimeDistributionSection({ instance, runtimeActions, session, operati
}
return (
<article className="console-panel" aria-label="run distribution controls">
<article id="run-builder" className="console-panel" aria-label="run distribution controls" tabIndex={-1}>
<div className="panel-header">
<h2>
<PackageOpen size={16} style={{ verticalAlign: "-2px" }} />
+2 -1
View File
@@ -157,10 +157,11 @@ export function ServersPage({ session, operations, onNavigate }: PageComponentPr
const operationId = operations.begin({ intent: "创建服务器", targetKind: "server", targetId: "platform", requester: session.displayName });
try {
const result = await platformApiClient.createServerWorkflow(serverCreateRequestFromForm(nextForm));
operations.succeed(operationId, result.job.id ? `已创建实例 ${result.instance.id},安装任务 ${result.job.id} 已派发` : `已保存草稿 ${result.instance.id};可在 Run 注册后绑定并部署。`, result.job.id ? result.job : undefined);
operations.succeed(operationId, result.job.id ? `已创建实例 ${result.instance.id},安装任务 ${result.job.id} 已派发` : `已保存草稿 ${result.instance.id};可在 Run 注册后绑定并部署。`, result.job.id ? result.job : undefined);
setForm(defaultServerCreateForm(plugins, endpoints));
setShowCreate(false);
await refresh();
if (result.job.id) onNavigate("serverDetail", { serverId: result.instance.id, routeKey: "run-builder" });
} catch (error) {
operations.fail(operationId, error instanceof Error ? error.message : "创建失败", operationId);
}