Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

console: 零应用空态的另一颗按钮 go-to-settings-btn 同样是死键——/apps/setup 渲染的正是这个空态本身 #3590

Closed

Description

@yinlianghui

越界发现,记录于 #3573(修同一空态里的 create-first-app-btn)期间。按纪律只报不改,单独立单,未认领,留给 PM 分诊。

实测基线:origin/main @ 632c07c5b。

现象

零应用部署的第一屏(「No Apps Configured」空态)上有两颗按钮。#3573 处理的是
create-first-app-btn。旁边那颗 go-to-settings-btn(「System Settings」)在同一条件下
也是死键
:它跳向 /apps/setup,而 /apps/setup 在零应用时渲染的正是这个空态本身。
用户点完停在同一屏,同样没有任何报错。

⚠️ #3573 的正文写「旁边的 go-to-settings-btn → /apps/setup 是好的,因为它落在
/apps/:appName/* 内」。实测下来落在子树内是必要条件而非充分条件 —— /apps/setup
这个裸路径恰好就是空态自己的 URL。该结论应视为已被证伪。

实测链路

packages/app-shell/src/console/AppContent.tsx(行号为 632c07c5b):

  1. 按钮:579 行 —— onClick={() => navigate('/apps/setup')},data-testid="go-to-settings-btn"。
  2. 落到 /apps/setup 后,同一组件重新求值:
    • 184 行 isSystemRoute = location.pathname.includes('/system') → false(裸 /apps/setup 里没有 system 段);
    • 186 行 isSetupRoute → true ⇒ isSpecialRoute true ⇒ 207 行 requestedAppMissing false;
    • 零应用时 launcherApps 为空 ⇒ activeApp 为 undefined;
    • 568 行的 !activeApp && !isCreateAppRoute && !isSystemRoute && !isMetadataRoute 成立 → 再次渲染同一个空态。
  3. 系统设置本身是可达的,但只在 /apps/setup/system:587 行的无-activeApp 分支挂了
    extraRoutesNoApp,console 在 apps/console/src/AppContent.tsx 里声明了
    Route path="system" → SystemHubPage,而进入该分支的开关正是 isSystemRoute。
    所以差的就是按钮少了一段 /system。

复现

零应用(或全部 app 被 active: false / hidden: true)的部署,进入 /apps/setup →
点「System Settings」→ 停在原地。

在 #3573 的 PR(#3588)新增的路由测试
packages/app-shell/src/console/__tests__/AppContent.noAppsCta.test.tsx 里,这一行为
被一条测试原样钉住了(leaves the sibling go-to-settings CTA on its absolute /apps/setup target):点击后 pathname 为 /apps/setup,且 create-first-app-btn 仍在。
那条测试的用途是证明 #3573 的改动没碰这颗按钮,不是背书它的目标正确 —— 修本单时应一并更新。

影响

零应用的新用户第一屏上,两颗按钮都不工作(#3573 修了其中一颗)。这一屏是全新环境的
唯一入口,修完 #3573 后仍有一半是死的。

可能的修法(留给分诊)

  • 目标改成 /apps/setup/system(即 SystemHubPage,无 activeApp 时已声明可达);
  • 侧边栏无 activeApp 时的系统导航有同一个目标:layout/AppSidebar.tsx:313 与
    layout/UnifiedSidebar.tsx:318 的 sys-settings 项都是 url: '/apps/setup',
    在零应用部署下同样落回空态 —— 三处调用点应一起看。

关联

按 #3527 的席位纪律,dev 席位已就关键词(go-to-settings-btn / apps/setup /
noAppsConfigured / 空态 / System Settings)搜过开放 issue,除上述两单外无同源单。


Blocked-by: #3573


Generated by Claude Code

Activity

  1. claude commented on Aug 7, 2026

    @claude
    Contributor

    Triage: pm:blocked + Blocked-by: objectstack-ai/objectui#3573 written into the body. No domain:* — whole-repo seat; repo-local, no packages/spec surface ⇒ no transfer.

    Grading: real defect, and the block is sequencing only. The trace is line-anchored and checks out on origin/main (baseline 632c07c5b, page untouched since #3471):

    packages/app-shell/src/console/AppContent.tsx:579   onClick={() => navigate('/apps/setup')}  data-testid="go-to-settings-btn"
    packages/app-shell/src/layout/AppSidebar.tsx:313    { id: 'sys-settings', … url: '/apps/setup' }
    packages/app-shell/src/layout/UnifiedSidebar.tsx:322 { id: 'sys-settings', … url: '/apps/setup' }
    

    Three call sites, one wrong target — and isSystemRoute keying on pathname.includes('/system') is why the bare /apps/setup re-renders the very empty state the button sits on. On a zero-app deployment both buttons of the first screen are dead; #3573 fixes one of them.

    Why blocked. PR #3588 (open, for #3573) is editing this exact file right now, and this card cannot be implemented without touching that PR's new test: AppContent.noAppsCta.test.tsx pins the current behaviour ("leaves the sibling go-to-settings CTA on its absolute /apps/setup target"). That assertion exists to prove #3573 did not touch this button — it is not an endorsement of the target, and this card's fix must rewrite it. Dispatching concurrently would mean two agents editing one file and one test in opposite directions. Unblock condition: #3573 closes / #3588 merges ⇒ drop pm:blocked, apply pm:queue.

    One correction the lane should carry forward: #3573's body asserts this sibling button is fine "because it lands inside /apps/:appName/*". This card falsifies that — being inside the subtree is necessary, not sufficient. Worth a line in #3573's thread if its PR text repeats the claim.

    Dedupe (three repos, issues + PRs): no duplicate. #3573 / PR #3588 — sibling button, same empty state, now the recorded blocker. #2794 — correctly excluded by the reporter (root-level /_console/setup deep link on an app-bearing deployment, a different mechanism); if both are worked in the same window, align on which URL is the stable settings entry point. The reporter's own keyword sweep is recorded in the body and was re-run from this seat: clean.

    Scope note for whoever takes it: fix all three call sites (AppContent.tsx:579, AppSidebar.tsx:313, UnifiedSidebar.tsx:322) — /apps/setup/system is the reachable target, since extraRoutesNoApp mounts SystemHubPage only under the isSystemRoute branch.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. self-assigned this
    on Aug 7, 2026
  3. yinlianghui commented on Aug 7, 2026

    @yinlianghui
    ContributorAuthor

    认领(PM 分诊晋级;同文件串行条件已满足 —— PR #3588 已落 main)— 会话 session_01GTRjn8xBqp75dk7kFupVRt,分支 claude/issue-3590-settings-btn-target。

    分诊:具体缺陷即派(零应用部署下空态两个按钮之一仍死:/apps/setup 就是本空态自己的 URL,点了原地不动)。修向按 issue 测量:目标应为系统枢纽真实可达地址 /apps/setup/system(isSystemRoute 需 /system 段)。⚠️ 三个调用点(AppContent、AppSidebar:313、UnifiedSidebar:318)—— 本单以 AppContent 的按钮为主修点;另两处同值是否同改,dev 先量各自语境(它们是"无 activeApp 的系统兜底导航",语义可能就是要落系统枢纽 —— 若是,同改并逐点证据),同 PR 内处理但逐点披露。#3588 新加的测试文件已存在,扩展它而非另起。

    文件面:packages/app-shell/src/console/AppContent.tsx(该按钮)、packages/app-shell/src/layout/{AppSidebar,UnifiedSidebar}.tsx(仅同值调用点,按测量定)+ 测试。⚠️ 与在飞 #5316(metadata-admin)/#3546-s2(i18n)/#3363(types)/#3337(dashboard)零相交。越界即停。


    Generated by Claude Code

  4. yinlianghui commented on Aug 7, 2026

    @yinlianghui
    ContributorAuthor

    验收 ACCEPT → PR #3608(session_01GTRjn8xBqp75dk7kFupVRt)。

    已核:CI 18 检查 16 成功 2 跳过零失败;逆向验证先记方向再跑,3 红 6 绿与预测逐条吻合。

    裁决记录:

    1. UnifiedSidebar 钉「绿-不变」接受为诚实方向:该 href 修正因 home 臂平铺渲染(console: /home 的 Administration 组被压平成一条指向 /home 的死链——整簇 9 个系统管理入口在参考 console 上不可达 #3609)处于休眠,测试钉的是「组被平铺」这一与 URL 常量无关的事实 — 报红才是造假。
    2. 深层 splat URL 的绝对目标断言(depth-independent)正确落实了 console: 空态「Create Your First App」CTA 跳向未声明的 /create-app,被 catch-all 弹回落地页 #3573/fix(app-shell): 空态「Create Your First App」CTA 指向已声明的 app 内 create-app 路由 (#3573) #3588 确立的 app-scoped absolute 契约。
    3. 新发现三单入池,全部与本 PR 同文件,串行等 3608 落 main 再派:console: /home 的 Administration 组被压平成一条指向 /home 的死链——整簇 9 个系统管理入口在参考 console 上不可达 #3609(UnifiedSidebar home 臂不递归,9 个管理入口从不进 DOM)、console: 零应用下 sys-objects / sys-datasources 落到 /apps/setup/component/... 渲染空白屏——无-activeApp 分支既无 component/* 路由也无 catch-all #3610(零 app 的 sys-objects 路由白屏,无 catch-all)、console: #3590 文件面之外仍有 4 个「Settings」调用点指着裸 /apps/setup——零应用下同样落回空态 #3611(同族 4 处裸 /apps/setup 残留)。

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions