diff --git a/apps/presentation/dashboard/smoke/chat-model-menu-smoke.mjs b/apps/presentation/dashboard/smoke/chat-model-menu-smoke.mjs index b7a4888164..4835f564bc 100644 --- a/apps/presentation/dashboard/smoke/chat-model-menu-smoke.mjs +++ b/apps/presentation/dashboard/smoke/chat-model-menu-smoke.mjs @@ -77,10 +77,17 @@ try { assert.doesNotMatch(goal, /goal-only-model|Fast|personal-chat-model-menu/, "The Goal reading header leaves sending choices in the single composer"); assert.doesNotMatch(goal, /gpt-6\.1-sol/, "Goal readback does not inherit the steward model"); const linked = header("idle", { readOnlySourceLabel: "Historical run", selectedGoal: { goalId: "source-case", title: "Historical run", agentLanes: [] } }); - const sourceBadge = linked.match(/class="personal-read-only-source"[^>]*>(.*?)<\/span>/)?.[1] ?? ""; - assert.match(sourceBadge, new RegExp(locale === "zh-CN" ? "只读" : "Read only")); - assert.doesNotMatch(sourceBadge, /Historical run/, "The source badge does not repeat the visible Goal title"); - assertions += 32; + // The persistent badge is its trigger name and visible text. Its disclosure + // panel is opened on demand and may explain the same source once. + const badgeStart = linked.indexOf('class="personal-read-only-source"'); + const badgeEnd = linked.indexOf('class="personal-channel-actions"', badgeStart); + const badge = linked.slice(badgeStart, badgeEnd > badgeStart ? badgeEnd : undefined) + .replace(/
]*class="context-help-popover"[\s\S]*?<\/div>/, ""); + assert.match(badge, new RegExp(locale === "zh-CN" ? "只读" : "Read only")); + assert.doesNotMatch(badge, /Historical run/, "The read-only source badge does not repeat the visible Goal title"); + const distinct = header("idle", { readOnlySourceLabel: "Remote build", selectedGoal: { goalId: "source-case", title: "Public Goal", agentLanes: [] } }); + assert.match(distinct, /class="personal-read-only-source-label"[^>]*>Remote build -

{t("header.readOnlySourceDescription", { source: readOnlySourceLabel })}

- {selectedGoal?.title === readOnlySourceLabel ? null : {readOnlySourceLabel}} +

{t("header.readOnlySourceDescription", { source: readOnlySourceLabel })}

+ {sourceNamedByTitle ? null : {readOnlySourceLabel}} {t("common.readOnly")}
) : selectedGoal && !composerVisible ? null : <> diff --git a/apps/presentation/dashboard/src/features/personal-workspace/i18n.tsx b/apps/presentation/dashboard/src/features/personal-workspace/i18n.tsx index 5cb38448ba..61593502aa 100644 --- a/apps/presentation/dashboard/src/features/personal-workspace/i18n.tsx +++ b/apps/presentation/dashboard/src/features/personal-workspace/i18n.tsx @@ -695,6 +695,7 @@ const en = { "header.managerView": "Manager view", "header.openGoalNavigation": "Open Goal navigation", "header.readOnlySourceDescription": "Original records from {source}; execution remains on its source", + "header.readOnlySourceHelp": "Read-only source help", "header.refresh": "Refresh status", "header.refreshDone": "Updated just now", "header.refreshFailed": "Refresh failed", @@ -2345,6 +2346,7 @@ const zhCN: Record = { "header.managerView": "管家视图", "header.openGoalNavigation": "打开 Goal 导航", "header.readOnlySourceDescription": "显示 {source} 的原始记录;执行控制在原运行环境", + "header.readOnlySourceHelp": "只读来源说明", "header.refresh": "刷新状态", "header.refreshDone": "刚刚更新", "header.refreshFailed": "刷新失败",