Skip to content

[finding] DeclaredActionsBar keeps an inline copy of the three-way row binding now named usePredicateRecordContext #4080

Description

@yinlianghui

Out-of-scope finding from objectui#4075 / PR #4079. Filed per PD #10unassigned, ungraded. Observation-class: nothing a user hits today, both copies are correct and produce identical bags.

Fact

PR #4077 fixed the root-only predicate binding in DeclaredActionsBar (packages/app-shell/src/views/DeclaredActionsBar.tsx) by building the bag inline:

const predicateContext = useMemo(
  () => ({ ...recordData, record: recordData, data: recordData }),
  [record],
);

PR #4079 fixed the same fault on the four generic action renderers and, rather than repeating that expression four more times, gave the rule one name: usePredicateRecordContext, exported from @object-ui/react beside useCondition (packages/react/src/hooks/useExpression.ts). @object-ui/app-shell already depends on @object-ui/react and DeclaredActionsBar already imports useCondition from it, so the migration is an import plus a one-line substitution.

Why it is worth recording rather than fixing in that PR

Two implementations of one binding rule is the shape objectui#3367 / #3842 rule against, and this family has already paid for it once at the toPredicateInput level (#3314 — two normalizations drifted, and the same visible: predicate reached different verdicts depending on which path surfaced the action). Nothing has drifted here yet; the risk is that the next change to the rule lands on one copy.

One non-cosmetic difference already exists, and it is the reason this is a real migration rather than a rename. usePredicateRecordContext returns an empty bag when there is no row, instead of { record: {}, data: {} } — because useCondition merges the local context OVER the ambient predicate scope, so binding an empty record blanks out a record a host put in the scope itself (a legitimate pattern, and how action-group-dropdown-visible.test.tsx drives those leaves; it went red on the first cut of #4079). DeclaredActionsBar's inline copy does not make that distinction. It is unreachable there today — the bar is always mounted over a record — so this is not a defect report, but the migration must keep the helper's semantics rather than restore the inline ones.

Suggested disposition

Migrate DeclaredActionsBar onto usePredicateRecordContext and delete the inline useMemo, keeping the helper's no-row semantics. Small, no user-visible change, no changeset.

Dedup

Searched open issues for DeclaredActionsBar predicate binding record, usePredicateRecordContext, three ways binding duplicate. Only objectui#4075 (this finding's parent, being closed by #4079) matches; no issue covers the duplicate implementation.

Refs: objectui#4075, objectui#4077, PR #4079, objectui#3367, objectui#3842, objectui#3314.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions