Skip to content

Object-list toolbar's "New" (and its mobile FAB) does not consume createPredicates — the create half is honoured on related lists only #5153

Description

@yinlianghui

Summary

Found while implementing #5142 (the object-list toolbar's Import button consuming importPredicates).

createPredicates has exactly one consumer in objectui: RelatedRecordActionsBridge (PR for #4646). That closed the related-list toolbar. The standalone object-list page has two more create entry points, and neither reads the key:

packages/app-shell/src/views/ObjectView.tsx:2129   header "New" button      (b4089beca)
packages/app-shell/src/views/ObjectView.tsx:2194   phone-only floating "+"  (b4089beca)

Both gate on affordances.create && can(objectDef.name, 'create') — the object-level verdict only. affordances.createPredicates is right there on the same resolved object and is dropped.

Why the standalone list is in scope for a toolbar predicate

The spec does not treat "standalone list" as a surface where toolbar predicates are inapplicable — it states the binding for it explicitly (RowCrudActionOverrideSchema docblock, @objectstack/spec@17.0.0):

> Toolbar affordances (create, import) have no row to bind … They evaluate once per toolbar against the record in scope where the toolbar renders: on a record page's related list that is the host (parent) record. On a standalone object list there is no record in scope, so a predicate reading record.* has nothing to bind and — per the fail-closed rule above — hides the button.

So the surface is in scope; what is absent there is only the record. Predicates over the host scope (os.user.*, features.*) bind normally and are the meaningful shape, and a record.* one is supposed to fail closed. Today the object-list page does neither: it ignores the envelope entirely.

Impact

An author writing one userActions.create object form gets two different verdicts for the same declaration, depending on which surface renders the button: honoured on a record page's related list, ignored on the object list page. visibleWhen: false — the objectui#3492 shape — does not hide the object list's "New".

Not reported from the field. Severity judged at filing time is unreliable in both directions (objectui#4646 came from a downstream project, #5142's twin did not), so this is filed plainly for triage rather than graded here.

Deliberately NOT done in the PR for #5142

That PR is scoped to the import key: it adds the consumer for importPredicates at ObjectView's single Import entry and widens UserActionsOverride.import to match. Extending it to create would have changed a second affordance on the same surface under an issue that names only one, so the create half is recorded here instead. The consumption shape it would mirror is already in the same file after that PR (importVisible / importDisabled, useRowPredicate with fallback: false, ?? true for visibleWhen, != null for disabledWhen), and UserActionsOverride.create is already the widened union — so this is the consumer half only, no type change needed.

Note the mobile FAB is a second render point of the same affordance, so both need the gate or they disagree with each other. (Import has no mobile counterpart by design — CSV import is desktop-only there — which is why #5142 had exactly one entry to close.)

Related

Activity

  1. yinlianghui commented on Aug 18, 2026

    @yinlianghui
    CollaboratorAuthor

    Filed unassigned from the #5142 run (os-dev, session_01GTRjn8xBqp75dk7kFupVRt) — recorded, not claimed. Searched open issues for the create half on the object-list page before filing; only #4646 (closed, related lists) and #5142 came back, so this is not a twin of either.


    Generated by Claude Code

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

    @yinlianghui
    CollaboratorAuthor

    认领(PM 派发,objectui 分片,批次 23):session_01GTRjn8xBqp75dk7kFupVRt,分支 claude/issue-5153-list-new-create-predicates,os-dev 席即将开工。

    排序条件已满足:PR #5154(import 半,同文件 ObjectView.tsx)已落 main(9f23d2b32)。范围:对象列表页「New」按钮(ObjectView.tsx:2129 附近)与移动端浮动 +(:2194 附近)消费 createPredicates —— 修法直接镜像同文件刚落的 import 半(useRowPredicate、visibleWhen fail-CLOSED / disabledWhen fail-SOFT、独立列表 scope=null 的 spec 原文语义)+ 测试 + changeset。⛔ 不动 RelatedRecordActionsBridge(关联列表半已由 PR #5145 落)。与在飞席位零重叠(当前在飞 0)。


    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

Labels

bugSomething isn't workingpm:queue

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions