Skip to content

条件 tab:给 page:tabs 的 item 加 visibility(CEL)—— #2579 follow-up #2606

Description

@os-zhuang

背景

这是 #2579(详情页相关子表 tab)里明确 defer 的 follow-up —— 见该 issue 的「相关 follow-up」一节。

PageComponentSchema 已有 visibility: ExpressionInputSchema(CEL 谓词,packages/spec/src/ui/page.zod.ts L109),所以页面组件可按记录状态条件显隐。但 page:tabsitem 本身没有 visibility —— 形状只有 { label, icon?, children }(packages/spec/src/ui/component.zod.ts PageTabsProps)。

后果:你能用组件级 visibility 隐藏一个 tab 的内容,但 tab 头(标签)还在,点进去是空的。无法真正「整条 tab 按记录状态显隐」。

典型企业需求:

  • "Contracts" tab 仅当 record.status == 'customer' 显示;
  • 按记录阶段 / 角色显隐的 tab。

提案

PageTabsProps.items[] 加一个可选 visibility,复用与组件级 visibility / action visible 相同的 ExpressionInputSchema(CEL):

items: z.array(z.object({
  label: I18nLabelSchema,
  icon: z.string().optional(),
  visibility: ExpressionInputSchema.optional()
    .describe('Visibility predicate (CEL). When false, the whole tab (header + panel) is omitted.'),
  children: z.array(z.unknown()).describe('Child components'),
})),

语义:visibility 求值为 false → 整条 tab(头 + 面板)从 tab 条移除,而不是留一个空头。求值上下文与组件级 visibility 一致(record + page 变量;page 变量变化时响应式重算)。

渲染器(objectui):page:tabs 渲染时过滤掉 visibility 为 false 的 item;若当前激活的 tab 被隐藏 → 自动回落到第一个可见 tab(避免空白)。

设计边界(与 #2579 一致)

  • 这是 Tier 2(page 层) 能力 —— 条件 / 排布归 page,不进对象层(ADR-0085 准入测试:对象层只放跨表面业务意图,不放「隐藏 / 重排」)。所以只加在 PageTabsProps,不碰 ObjectSchema
  • 复用现有 CEL(ExpressionInputSchema),不引入新表达式机制;与 PageComponentSchema.visibility、action visible / disabled、nav 可见条件同源。
  • 加性、向后兼容(可选字段)→ minor

改动范围

  • framework(spec):packages/spec/src/ui/component.zod.tsPageTabsProps.itemsvisibility;补测试。
  • objectui(渲染):page:tabs 渲染器按 visibility 过滤 item + 激活 tab 回落;补测试。

验收

  • page:tabs 某 item 带 visibility: 'record.status == "customer"':非 customer 记录看不到该 tab 头,customer 记录看得到。
  • 激活的 tab 被隐藏时自动落到第一个可见 tab,无空白面板。
  • 不带 visibility 的 item 行为完全不变。

Refs #2579.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions