Skip to content

components/action/**: 同一真值可见性门在动作面上未收口 —— action:group / action:menu 成员动作声明 visible: false 照样渲染(#3758 的同族部分) #3812

Description

@yinlianghui

现象与机理

packages/components/src/renderers/action/** 的可见性门与 objectui#3758 修掉的行动作门同形:用真值判断,于是 visible: false —— 最明确的「永不显示」—— 落进「未声明门」分支,动作照样渲染。

if (action.visible && !isVisible) return null;   // false && … 为假 → 不 return null → 渲染

#3758 只裁了动作两处(plugin-gridRowActionMenucomponentsdata-table,均已收敛成 isCustomRowActionVisible),动作面(action:group / action:menu / action:bar / action:button / action:icon)这一族没有一起收口。

锚点(origin/main@d9ce38529,全部在)

成员动作门(可达性最高——见下)

  • packages/components/src/renderers/action/action-group.tsx:94 —— InlineActionButton(inline 模式的成员动作)
  • packages/components/src/renderers/action/action-group.tsx:141 —— DropdownActionItem(dropdown 模式的成员动作)
  • packages/components/src/renderers/action/action-menu.tsx:84 —— action:menu 的菜单项

组件级门schema.visible,见「可达性」第 2 条):

  • action-group.tsx:230action-menu.tsx:169action-bar.tsx:223action-button.tsx:148action-icon.tsx:82

可达性(老实说,两条结论不同)

  1. 成员动作门确实可达。 InlineActionButton / DropdownActionItem / action:menu 的项是从组件自己的 actions 数组直接 .map() 渲染的:既不经 SchemaRenderer(那是按节点走的),也不经 ActionEngine.getActionsForLocationActionEngine 的布尔 visible 是正确的,见 packages/core/src/actions/__tests__/ActionEngine.visibility.test.ts:60)。所以数组成员上写 visible: false,真值门是唯一的门,动作渲染。
  2. 组件级门大概率被上游遮住。 packages/react/src/SchemaRenderer.tsx:288schema.visible !== undefined 统一求值并隐藏(SchemaRenderer.expressions.test.tsx:39 已钉「visible: false 不渲染」),所以经 SchemaRenderer 路由的组件根本不会渲染到自己的门。这五处更像休眠的防御层而非活缺陷——但我没有穷举是否存在绕过 SchemaRenderer 直接挂载这些组件的宿主,请分诊按此复核。

#3758 同理:ActionSchema.visibleExpressionInputSchema(无 boolean 成员),objectstack build 产不出这个形状;手写视图 JSON 与进程内构造 def 可以 —— #3492 正文记录了这两条路径确实发生过。故为低可达性的具体缺陷,严重度请分诊裁。

#3492 / #3758 的关系

objectui#3492 已把这条不变量钉死在批量选择栏:声明检测用 != null && !== '',不用真值(packages/plugin-grid/src/bulkEligibility.tshasVisibilityGate 注释原文:「Truthiness cannot answer this: visible: false is a declared gate that excludes everything」)。#3758 把行动作两处收口到同一不变量。动作面这一族是同一形状里剩下的部分,修法已裁,不是新决定

建议

  1. 成员动作的三处门统一到 != null && !== '',并把布尔短路交给求值入口(useCondition 已按布尔短路,无需改它);
  2. 每处加钉子测试:visible: false 的成员动作不渲染,并按对称性补 visible: true(声明门、恒真)与未声明(渲染)的对照断言 —— 否则「声明检测」很容易被写成「恒隐藏」而测试全绿(行动作声明 visible: false 仍然渲染该菜单项——可见性门用真值判断(#3492 在行菜单上的未收口部分) #3758 的三条钉子就是按这个对称性写的);
  3. 组件级五处先按可达性第 2 条复核:若确认被 SchemaRenderer 完全遮住,则属休眠代码(finding 类),可与本单分开处置。

发现自 objectui#3758 的实施过程(消费半径扫描);未认领,未在 #3758 的 PR 里改动。

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions