feat: declare and execute SCUM guided installs
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { jobCapabilityLabel } from "./jobPresentation";
|
||||
|
||||
describe("jobCapabilityLabel", () => {
|
||||
it("keeps Run routing identifiers out of operator task titles", () => {
|
||||
expect(jobCapabilityLabel("process.install")).toBe("安装服务端");
|
||||
expect(jobCapabilityLabel("dependencies.install")).toBe("安装运行依赖");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
export function jobCapabilityLabel(capability: string): string {
|
||||
switch (capability) {
|
||||
case "process.install": return "安装服务端";
|
||||
case "process.start": return "启动服务器";
|
||||
case "process.stop": return "停止服务器";
|
||||
case "process.status": return "检查服务器状态";
|
||||
case "dependencies.check": return "检查运行依赖";
|
||||
case "dependencies.install": return "安装运行依赖";
|
||||
default: return capability;
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import { UsageMeter } from "../components/OperationControls";
|
||||
import { ProductionGovernancePanel } from "../components/ProductionGovernancePanel";
|
||||
import { EmptyState, ErrorState, LoadingState } from "../components/StateViews";
|
||||
import { jobBuckets, moduleFreshnessLabel, summarizeEndpointOperations, type OperationsModuleState } from "../contracts/operationsConsole";
|
||||
import { jobCapabilityLabel } from "../contracts/jobPresentation";
|
||||
import type { PageComponentProps } from "../contracts/page";
|
||||
import type { GameTypeDistributionEntry, PlatformOverviewSignal } from "../contracts/workspace";
|
||||
import { serverIsOnline } from "../contracts/workspace";
|
||||
@@ -249,7 +250,7 @@ export function HomePage({ session, onNavigate, initialState }: HomePageProps) {
|
||||
className={cx("console-row console-row-button", job.state === "failed" && "console-row-danger")}
|
||||
onClick={() => onNavigate(job.serverInstanceId ? "serverDetail" : "maintenance", job.serverInstanceId ? { serverId: job.serverInstanceId } : undefined)}
|
||||
>
|
||||
<span><strong>{job.capability}</strong><small>{job.serverInstanceId ? `服务器 ${job.serverInstanceId}` : "平台任务"}</small></span>
|
||||
<span><strong>{jobCapabilityLabel(job.capability)}</strong><small>{job.serverInstanceId ? `服务器 ${job.serverInstanceId}` : "平台任务"}</small></span>
|
||||
<span>{job.state === "retrying" ? `重试 ${job.attempt}/${job.retryPolicy.maxAttempts}` : jobStateLabel(job.state)}</span>
|
||||
<span>{Math.round(job.progress.percent)}%</span>
|
||||
</button>
|
||||
@@ -382,7 +383,7 @@ function buildOverviewSignals(
|
||||
collected.push({ id: `fault-${instance.id}`, kind: "fault", summary: `服务器 ${instance.name} 处于异常状态`, detail: `实例 ${instance.id} 需要排查`, targetPage: "servers", targetId: instance.id, tone: "error", at: instance.updatedAt });
|
||||
}
|
||||
for (const job of jobBuckets(core.data.jobs).failed.slice(0, 5)) {
|
||||
collected.push({ id: `job-${job.id}`, kind: "job", summary: `任务 ${job.capability} 失败`, detail: job.serverInstanceId ? `服务器 ${job.serverInstanceId} 的任务执行失败` : "平台任务执行失败", targetPage: job.serverInstanceId ? "servers" : "maintenance", targetId: job.serverInstanceId, tone: "error", at: job.updatedAt });
|
||||
collected.push({ id: `job-${job.id}`, kind: "job", summary: `任务 ${jobCapabilityLabel(job.capability)} 失败`, detail: job.serverInstanceId ? `服务器 ${job.serverInstanceId} 的任务执行失败` : "平台任务执行失败", targetPage: job.serverInstanceId ? "servers" : "maintenance", targetId: job.serverInstanceId, tone: "error", at: job.updatedAt });
|
||||
}
|
||||
}
|
||||
if (providers.status === "ready") {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { platformApiClient } from "../api/client";
|
||||
import type { AuditEventResponse, JobResponse, RunEndpointResponse, ServerInstanceResponse } from "../api/types";
|
||||
import { EmptyState, ErrorState, LoadingState, ResultBadge } from "../components/StateViews";
|
||||
import { ProductionGovernancePanel } from "../components/ProductionGovernancePanel";
|
||||
import { jobCapabilityLabel } from "../contracts/jobPresentation";
|
||||
import type { PageComponentProps } from "../contracts/page";
|
||||
import { cx } from "../utils/classes";
|
||||
|
||||
@@ -227,7 +228,7 @@ export function MaintenancePage({ session, operations, onNavigate }: PageCompone
|
||||
return (
|
||||
<div key={job.id} className="console-record">
|
||||
<div className="console-record-head">
|
||||
<strong>{job.capability}</strong>
|
||||
<strong>{jobCapabilityLabel(job.capability)}</strong>
|
||||
<span className="status-pill status-error">{jobStateLabel(job.state)}</span>
|
||||
</div>
|
||||
<div className="console-record-meta">
|
||||
|
||||
@@ -48,6 +48,7 @@ import {
|
||||
} from "../components/RuntimeTaskProgress";
|
||||
import { DiagnosticSummary, EmptyState, ErrorState, LoadingState, ResultBadge } from "../components/StateViews";
|
||||
import type { PageComponentProps } from "../contracts/page";
|
||||
import { jobCapabilityLabel } from "../contracts/jobPresentation";
|
||||
import type { PluginBridgeAction, PluginBridgeManifestContract } from "../contracts/pluginBridge";
|
||||
import { canStartServer, canStopServer, defaultServerCreateForm, endpointLabel, pluginCreateInputDefaults, pluginLabel, runtimeBindingFields, serverMetadataFormFromInstance, type ServerCreateFormState, type ServerMetadataFormState } from "../contracts/serverManagement";
|
||||
import {
|
||||
@@ -2348,7 +2349,7 @@ function HistorySection({ serverId, serverOperations, jobs, artifacts, metricHis
|
||||
{jobs.slice(0, 20).map((job) => (
|
||||
<div key={job.id} className="console-record">
|
||||
<div className="console-record-head">
|
||||
<strong>{job.capability}</strong>
|
||||
<strong>{jobCapabilityLabel(job.capability)}</strong>
|
||||
<span className={cx("status-pill", job.state === "succeeded" ? "status-active" : job.state === "failed" ? "status-error" : "status-disabled")}>
|
||||
{job.state}
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user