diff --git a/src/components/app-ui.tsx b/src/components/app-ui.tsx index 48af8bf..c4c2944 100644 --- a/src/components/app-ui.tsx +++ b/src/components/app-ui.tsx @@ -27,6 +27,8 @@ import type { } from "@/lib/thread-execution-conflict"; import { describeThreadConversationExecutionConflict, + labelForProjectConflictAllowPolicy, + labelForProjectConflictState, labelForThreadConversationExecutionConflictDecision, summarizeThreadConversationExecutionDecisionResult, } from "@/lib/thread-execution-conflict-ui"; @@ -85,14 +87,15 @@ export function buildDeviceWorkspaceDetailCards(workspace: DeviceWorkspaceView) }, conflicts: { title: "异常项目 / 文件夹冲突", + headerHint: primaryPolicy ? "已接入,可直接调整" : "当前没有异常项目", scopeLabel: "仅作用于当前异常项目 / 文件夹", actions: ["禁止", "允许本次", "永久放行"], items: { device: `设备:${selectedDevice?.name ?? selectedDevice?.id ?? "未知设备"}`, folderKey: `文件夹:${primaryPolicy?.folderKey ?? "暂无"}`, projectId: `项目:${primaryPolicy?.projectId ?? "暂无"}`, - allowPolicy: `当前策略:${primaryPolicy?.allowPolicy ?? "暂无"}`, - conflictState: `冲突态:${primaryPolicy?.conflictState ?? "暂无"}`, + allowPolicy: `当前策略:${labelForProjectConflictAllowPolicy(primaryPolicy?.allowPolicy ?? null)}`, + conflictState: `冲突态:${labelForProjectConflictState(primaryPolicy?.conflictState ?? null)}`, }, }, }; @@ -714,7 +717,7 @@ export function DeviceEditorCard({
{detailCards.conflicts.title}
-
动作后续接入
+
{detailCards.conflicts.headerHint}
{detailCards.conflicts.items.device}
diff --git a/src/lib/thread-execution-conflict-ui.ts b/src/lib/thread-execution-conflict-ui.ts index 70a882d..b8fb2e2 100644 --- a/src/lib/thread-execution-conflict-ui.ts +++ b/src/lib/thread-execution-conflict-ui.ts @@ -1,6 +1,7 @@ import type { ThreadConversationExecutionConflict, ThreadConversationExecutionConflictAction, + ThreadConversationExecutionConflictState, } from "@/lib/thread-execution-conflict"; export function describeThreadConversationExecutionConflict( @@ -46,3 +47,32 @@ export function summarizeThreadConversationExecutionDecisionResult( return "已保持禁止,这次消息没有发出。"; } } + +export function labelForProjectConflictAllowPolicy( + decision?: ThreadConversationExecutionConflictAction | null, +) { + switch (decision) { + case "allow_once": + return "允许本次"; + case "allow_always": + return "永久放行"; + case "forbid": + return "禁止"; + default: + return "暂无"; + } +} + +export function labelForProjectConflictState( + conflictState?: ThreadConversationExecutionConflictState | "none" | null, +) { + switch (conflictState) { + case "warning": + return "存在并行风险"; + case "blocked": + return "已阻断"; + case "none": + default: + return "暂无"; + } +} diff --git a/tests/device-detail-capabilities-route.test.ts b/tests/device-detail-capabilities-route.test.ts index 7590ba9..e62b4d4 100644 --- a/tests/device-detail-capabilities-route.test.ts +++ b/tests/device-detail-capabilities-route.test.ts @@ -70,11 +70,12 @@ test("device detail exposes folder and project conflict skeleton from workspace const cards = buildDeviceWorkspaceDetailCards(workspace); assert.equal(cards.conflicts.title, "异常项目 / 文件夹冲突"); + assert.equal(cards.conflicts.headerHint, "已接入,可直接调整"); assert.equal(cards.conflicts.items.device, "设备:Mac Studio"); assert.equal(cards.conflicts.items.folderKey, "文件夹:mac-studio:boss"); assert.equal(cards.conflicts.items.projectId, "项目:thread-ui"); - assert.equal(cards.conflicts.items.allowPolicy, "当前策略:allow_always"); - assert.equal(cards.conflicts.items.conflictState, "冲突态:warning"); + assert.equal(cards.conflicts.items.allowPolicy, "当前策略:永久放行"); + assert.equal(cards.conflicts.items.conflictState, "冲突态:存在并行风险"); }); test("device detail conflict card keeps project-scoped actions on the active folder only", async () => { @@ -90,8 +91,9 @@ test("device detail conflict card keeps project-scoped actions on the active fol const workspace = getDeviceWorkspaceView(await readState(), "mac-studio"); const cards = buildDeviceWorkspaceDetailCards(workspace); - assert.equal(cards.conflicts.items.allowPolicy, "当前策略:allow_once"); - assert.equal(cards.conflicts.items.conflictState, "冲突态:warning"); + assert.equal(cards.conflicts.headerHint, "已接入,可直接调整"); + assert.equal(cards.conflicts.items.allowPolicy, "当前策略:允许本次"); + assert.equal(cards.conflicts.items.conflictState, "冲突态:存在并行风险"); assert.deepEqual(cards.conflicts.actions, ["禁止", "允许本次", "永久放行"]); assert.equal(cards.conflicts.scopeLabel, "仅作用于当前异常项目 / 文件夹"); });