diff --git a/apps/presentation/dashboard/docs/assets/goal-hierarchy/invalid-root-desktop.png b/apps/presentation/dashboard/docs/assets/goal-hierarchy/invalid-root-desktop.png index ae31fa3a2e..d8072d34ad 100644 Binary files a/apps/presentation/dashboard/docs/assets/goal-hierarchy/invalid-root-desktop.png and b/apps/presentation/dashboard/docs/assets/goal-hierarchy/invalid-root-desktop.png differ diff --git a/apps/presentation/dashboard/docs/assets/goal-hierarchy/invalid-root-phone.png b/apps/presentation/dashboard/docs/assets/goal-hierarchy/invalid-root-phone.png index 491e4ab4ad..70bf6ecd7c 100644 Binary files a/apps/presentation/dashboard/docs/assets/goal-hierarchy/invalid-root-phone.png and b/apps/presentation/dashboard/docs/assets/goal-hierarchy/invalid-root-phone.png differ diff --git a/apps/presentation/dashboard/src/features/personal-workspace/channel-header.tsx b/apps/presentation/dashboard/src/features/personal-workspace/channel-header.tsx index 6e87e5264b..e8f265ef31 100644 --- a/apps/presentation/dashboard/src/features/personal-workspace/channel-header.tsx +++ b/apps/presentation/dashboard/src/features/personal-workspace/channel-header.tsx @@ -41,6 +41,7 @@ export function ChannelHeader({ selectedAgentReasoningEffort, selectedGoal, selectedGoalTab, + scopeUnavailable = false, workspaceGrantLabel, }: { agents: WorkspaceAgentOption[]; @@ -81,6 +82,8 @@ export function ChannelHeader({ selectedAgentReasoningEffort?: string; selectedGoal: WorkspaceGoal | null; selectedGoalTab: WorkspaceGoalTab; + /** A requested Goal scope failed; do not present the steward as its fallback. */ + scopeUnavailable?: boolean; }) { const { locale, t } = useWorkspaceI18n(); const statusOnly = selectedAgentId === "status-only"; @@ -154,7 +157,7 @@ export function ChannelHeader({ : "header.managerAllocationConfigured") : null; - const runtimeControl = agentWorkActive ? null : readOnlySourceLabel ? ( + const runtimeControl = scopeUnavailable || agentWorkActive ? null : readOnlySourceLabel ? ( {readOnlySourceLabel}{t("common.readOnly")} ) : <> - {selectedGoal ? undefined)} /> : {t("header.manager")}} + {selectedGoal ? undefined)} /> : {t(scopeUnavailable ? "header.goalView" : "header.manager")}} {workspaceGrantLabel ? {t("workspace.conversation", { grant: workspaceGrantLabel })} : null} {stewardBindingVisible && managerChannelBinding ? ( @@ -269,12 +272,12 @@ export function ChannelHeader({ {runtimeControl} - ) : ( + ) : !scopeUnavailable ? ( {t("header.managerOverview")} {t("header.chat")} - )} + ) : null} {selectedGoal && onOpenAllWork ? : null} {selectedGoal && !selectedGoal.loadState && onRequestGoalLifecycle ? ( diff --git a/apps/presentation/dashboard/src/features/personal-workspace/personal-workspace-page.tsx b/apps/presentation/dashboard/src/features/personal-workspace/personal-workspace-page.tsx index cd150d66f3..4ca24870ce 100644 --- a/apps/presentation/dashboard/src/features/personal-workspace/personal-workspace-page.tsx +++ b/apps/presentation/dashboard/src/features/personal-workspace/personal-workspace-page.tsx @@ -2674,6 +2674,7 @@ export function PersonalWorkspacePage({ { diff --git a/examples/personal-workspace-browser/goal-hierarchy.mjs b/examples/personal-workspace-browser/goal-hierarchy.mjs index e75b910e41..da17eb4962 100644 --- a/examples/personal-workspace-browser/goal-hierarchy.mjs +++ b/examples/personal-workspace-browser/goal-hierarchy.mjs @@ -117,6 +117,9 @@ export const goalHierarchyScenario = { assert.equal(await page.getByTestId("personal-first-goal").count(), 0); assert.equal(await page.locator(".personal-manager-greeting, .personal-composer-wrap").count(), 0, "An unavailable research root must not open an unrelated steward conversation"); + assert.equal(await page.getByRole("navigation", {name: "管家视图", exact: true}).count(), 0, + "An unavailable research root cannot offer unrelated steward navigation"); + assert.notEqual(await page.locator(".personal-channel-title h1").textContent(), "LoopX 管家"); unavailable.searchParams.set("rootGoalId", "../missing"); await page.goto(unavailable.href, {waitUntil: "networkidle"}); await page.getByRole("alert").filter({hasText: "当前来源中此 Goal 范围不可用"}).waitFor(); @@ -128,6 +131,8 @@ export const goalHierarchyScenario = { await page.getByRole("alert").filter({hasText: "当前来源中此 Goal 范围不可用"}).waitFor(); assert.equal(await page.locator(".personal-goal-row").count(), 0, `${invalid}: decoded values cannot widen the scope`); assert.equal(await page.locator(".personal-manager-greeting, .personal-composer-wrap").count(), 0); + assert.equal(await page.getByRole("navigation", {name: "管家视图", exact: true}).count(), 0); + assert.notEqual(await page.locator(".personal-channel-title h1").textContent(), "LoopX 管家"); await page.getByRole("button", {name: "全部 Goals", exact: true}).click(); await row("daily").waitFor(); await page.goBack({waitUntil: "networkidle"});
{t("workspace.conversation", { grant: workspaceGrantLabel })}