Uh oh!
There was an error while loading. Please reload this page.
fix(app-shell,components): 服务端声明动作的 visible 门按「已声明」判定,visible: false 不再渲染 (#3835) - #3843
Conversation
…不再渲染 (#3835) DeclaredActionsBar 的门沿用真值判读 `if ((action as any).visible && !isVisible) return null`,于是 `visible: false` 落进「没声明门」分支,verdict 从未被查询,动作照样渲染。 这是 #3492 同族第五处,也是两条族群缓解在此都不成立的一处: - 动作 def 是服务端声明的(objectDef.actions[]、sys_approval_request), 不是手写视图 JSON。「ActionSchema.visible 是 ExpressionInputSchema、无 boolean 成员,objectstack build 产不出布尔形状」这条缓解在这条路径上不 成立 —— def 来自服务端 metadata 与进程内构造,布尔是自然写法。 - 该 bar 由宿主以普通 JSX 直挂(apps/console 的 ApprovalsInboxPage), packages/react 的 SchemaRenderer 不在这条路径上,#3812 判定组件级门休眠 的依据(宿主先求值 visible 再隐藏)不适用。这个门是该路径上唯一的门。 宿主是审批收件箱的记录区动作条:一个本该被 visible: false 关掉的审批动作 渲染成可点按钮,而本组件自己的 click handler 就是 POST 审批决定的那一步。 门统一到同族那一处命名定义 hasDeclaredVisibilityGate(`!= null && !== ''`), 从 @object-ui/components 的 barrel 新增一行 re-export 引入,不抄第五份 (#3142 的 locations 漂移形)。verdict 仍交给求值入口:toPredicateInput 原样透传布尔、useCondition 在 evaluateCondition 短路,故声明的 false 即 false,表达式取值的 visible verdict 一律不变。 先收紧常真桩,再落钉子:原套件把整个求值入口打桩成 `useCondition: () => true`,注释还写着测试动作不带 visible「所以用不到」—— 这让唯一挂载本组件的 套件里这道门从未被行使(#4984 族:fixture 让坏规则保持绿色)。现在改为只 替换动作派发,useCondition / toPredicateInput 用真实实现,四形状由出货语义 判定。 钉子:false 隐藏 / true 渲染 / 未声明渲染 / `''` 不算门 + 表达式两向 verdict + 隐藏动作在工具栏里不留任何可点面(按钮集断言,而非派发计数 —— 未被点击的 多余按钮在两侧都不派发,计数版修前也是绿的)。每例都带一个无门同伴动作, 使「未渲染」不会被误读成「整条 bar 返回 null」。 行为变化面(窄):只有 visible 为字面布尔 false(或其他非空 falsy)的声明 动作从渲染变隐藏;visible: true、`''`、未声明一律不变。 Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt Co-authored-by: Claude <noreply@anthropic.com>
The latest updates on your projects. Learn more about Vercel for GitHub. |
「fixture 让坏规则保持绿色」那一族是 objectstack(framework)仓的 #4984 (见其 packages/lint 内多处裸引用),objectui 侧要按本仓约定写成 objectstack#4984,否则指向本仓一个不存在的号。 Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
commented
Aug 8, 2026
✅ 验收通过(objectui 分片 PM,session_01GTRjn8xBqp75dk7kFupVRt)—— undraft + auto-merge。 核验:三件按裁定落地(barrel 一行 re-export、门收口、桩收紧),且桩收紧优于要求 —— importOriginal 偏 mock 只替换 ActionProvider/useAction、求值入口用真实实现,避免在测试替身里出现被测语义的第二份拷贝; Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#3835
门:前后对照
packages/app-shell/src/views/DeclaredActionsBar.tsxfalse && …为假 → 不return null→ 渲染。作者写visible: false(最明确的「永不显示」)被真值判读成「没声明门」,verdict 从未被查询。hasDeclaredVisibilityGate(!= null && !== '')从@object-ui/components的 barrel 新增一行 re-export 引入(PM 已裁),不上提 core、不抄第五份(#3142 的locations漂移形):packages/components/src/index.tsverdict 仍交给求值入口,一行未动:
toPredicateInput原样透传布尔、useCondition在evaluateCondition短路,故声明的false即false,表达式取值的 verdict 一律不变。为什么这处是同族最热的一处
objectDef.actions[]/sys_approval_request)。「ActionSchema.visible是ExpressionInputSchema、无 boolean 成员,objectstack build产不出布尔形状」这条族群缓解在这条路径上不成立 —— def 来自服务端 metadata 与进程内构造,布尔是自然写法。apps/console/src/pages/system/ApprovalsInboxPage.tsx:2014/:2055),packages/react的SchemaRenderer不在路径上 —— components/action/**: 同一真值可见性门在动作面上未收口 ——action:group/action:menu成员动作声明visible: false照样渲染(#3758 的同族部分) #3812 判定组件级门休眠的依据(宿主先按visible !== undefined求值并隐藏)在此不适用。这个门是该路径上唯一的门。visible: false关掉的审批动作渲染成可点的 Approve/Reject,而本组件自己的 click handler 就是 POST 审批决定的那一步。桩收紧(先做,否则钉子空绿 —— #4984 族)
原套件把整个求值入口打桩成常真,注释还写着测试动作不带
visible「所以用不到」:这让唯一挂载本组件的套件里这道门从未被行使过。重新拼一个「布尔短路」的桩并不能修好这点:
visible: false走到「隐藏」依赖toPredicateInput透传布尔 +evaluateCondition短路,桩就是这套语义的第二份拷贝。改法是只替换动作派发,求值入口用真实实现:@object-ui/react的 barrel 对 lightdom项目是可负担的(components 自己的门套件就是不打桩地 import 它)。components 的 barrel 仍打桩(它的重图正是 light 项目故意不加载的),但hasDeclaredVisibilityGate从真实源模块取(纯函数、零依赖)—— 在测试替身里重拼一份!= null && !== ''会变成这条定义的第五份拷贝,并且无论出货谓词怎么变都保持绿色。钉子(四形状 + 同伴动作)
packages/app-shell/src/views/__tests__/DeclaredActionsBar.test.tsx新增 6 例,每例都带一个无门同伴动作(approval_reassign),使「未渲染」不会被误读成「整条 bar 返回 null」(空 located 集是两行之外的另一条码路)。反向验证(方向先判后跑)
判定: 修前
visible: false的钉子应红,true/ 未声明 /''/ 表达式两向应绿。实跑一致 —— 修前(桩已收紧、源未改):修后:
Tests 20 passed (20)。抗空绿变异(#3836 范式),两个方向,一个如预期一个不如:
if (true) return null)→ 15 红(含visible:true/ 未声明 /''/ 表达式为真四例,以及原有 9 例)。如预期:一个「把成员一律隐藏」的改写无法让这套钉子保持绿色。visible !== undefined,让''算门)→ 20 全绿。与我事先的判定相反,如实记录:这条路径上''被保护了两层 —— 门放过去之后,toPredicateInput('')是undefined,evaluateCondition(undefined)读作「没有条件 → 可见」。所以''那一例记录的是意图语义,在本面不是变异探测器;!== ''这条腿本身钉在packages/components定义旁边。这一点已写进测试的 docblock,以免下个读者把它的通过当成该腿被行使的证明。验证
仓根 flock +
NODE_OPTIONS=--max-old-space-size=4096+--maxWorkers=2:vitest run packages/app-shell/src/views/__tests__/DeclaredActionsBar.test.tsxTests 20 passed (20)vitest run packages/app-shell/src/views/__tests__/Test Files 10 passed / Tests 62 passedvitest run packages/components/src/renderers/action packages/components/src/__tests__/snapshot-critical.test.tsxTest Files 4 passed / Tests 57 passedpnpm --filter @object-ui/components type-checktsc --noEmit+ typetests)pnpm --filter @object-ui/app-shell type-checkpnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' build起依赖 dist;packages/components/dist/index.d.ts已含新导出)eslint(三个改动文件)no-explicit-anywarning)node scripts/check-control-bytes.mjs[\x00-\x08\x0b\x0c\x0e-\x1f]零命中)消费半径清扫:全仓仅此一处套件挂载
DeclaredActionsBar(apps/console无 ApprovalsInboxPage 测试);barrel 改动是纯新增,无导出名冲突,components 侧无公共导出面快照断言。未动 / 不在本 PR 范围
action-group.tsx:235/action-bar.tsx:223/action-menu.tsx:179的三处组件级真值门照旧 —— 它们只经SchemaRenderer挂载(components/action/**:action:bar成员动作的组件级真值可见性门实证可达 ——action:button/action:icon声明visible: false照样渲染(#3812 第 3 条复核结论) #3823 / PR fix(components): action:bar 成员动作声明 visible: false 时隐藏而非渲染 (#3823) #3836 已如此裁定并写进 changeset)。disabled的「已声明」判定用!= null,disabled: ''把按钮永久置灰(#3492 同族的另一半 predicate,探针实证) #3842,未认领,未在本 PR 修):disabled的「已声明」判定停在!= null(本文件按钮 props 处 +action-button.tsx:164),于是disabled: ''被判成已声明门、verdict 取「没有条件 → true」= 禁用,审批按钮永久置灰(与visible侧相反的失败方向)。探针已实证,证据在 动作disabled的「已声明」判定用!= null,disabled: ''把按钮永久置灰(#3492 同族的另一半 predicate,探针实证) #3842。Changeset
.changeset/declared-actions-bar-visible-gate-3835.md—@object-ui/app-shellpatch,写明审批面变化:visible: false的服务端声明动作从可点变隐藏。.changeset/components-export-declared-visibility-gate-3835.md—@object-ui/componentspatch,新增 barrel 导出(纯新增,本包无行为变化)。在飞交叠
与 #3808 同触
packages/components,但它改renderers/basic/text-input.tsx与plugin-detail,未触src/index.ts;本 PR 只在 barrel 加一行导出,取并集即可,无文本冲突。#3546 切片四(i18n)不相交。Generated by Claude Code