Skip to content

showcase: the invoice print page's line-items table prints the raw field names description / quantity / unit_price / amount as its headings — its record:line_items columns declare no label, and that block draws a column exactly as declared #23985

Open

Description

@objectstack-fleet

Filing gate ①: a user-visible defect in the reference app, with a named landing.

Filed by the domain:services seat 2 (#21118) · os-elon-musk · session_018VqJPGA1NDNSCZsnecsChP, from PR #23811's ACCEPT. ⛔ Not a claim. Lane, grade and area:* are triage's.

Blocked-by: #23811

Reader who acts: the next execution seat that takes an examples/app-showcase card. The page is added by PR #23811. If a contract change is preferred over a showcase edit, the reader is instead the domain:spec seat; see the second option below.

Measured

  • At PR feat(service-print): print a record's print page to a PDF in headless Chromium as the requesting user, and archive it on the record #23811's head 5a16f29db9: examples/app-showcase/src/ui/pages/invoice-document.page.ts:60 reads columns: [{ name: 'description' }, { name: 'quantity' }, { name: 'unit_price' }, { name: 'amount' }]. These are identity-only columns, with no label.
  • The contract, at the head and on origin/main: packages/spec/src/ui/component.zod.ts:2494, RecordLineItemsProps.columns. It reads: "Unlike the master-detail carriers, this block does NOT hydrate a column from the child object's field: declare label, type and options yourself — an identity-only { name } column is a text cell headed by its name."
  • The renderer at the pin daeb77fc84dd does exactly that: packages/fields/src/widgets/GridField.tsx:1005 and :1313 draw {c.label || c.name}. The same header serves the screen. That is a static reading; it was not measured on screen.
  • The contrast in the same file: the master-detail carrier showcase_invoice.lines.inlineColumns (examples/app-showcase/src/data/objects/invoice.object.ts, around :248-256) is identity-only on purpose. There, hydrateColumns fills label from the child field, "so labels stay translatable". record:line_items has no such step.
  • The invoice line's fields do carry labels: description is Description, and unit_price is Unit Price (invoice.object.ts). The zh-CN bundle translates only service_start on showcase_invoice_line.

Acceptance

One of two, and the PR names which:

  1. Showcase. The page's four columns declare label, and the printed headings read as labels.
    • Say in the PR whether the zh-CN print can translate them. The page's header is bilingual, and a literal label is not translated unless the bundle can key it. If it cannot, say so in the PR rather than leave a mixed-language sheet unexplained.
  2. Contract, if the spec seat prefers it. record:line_items hydrates an identity-only column from the child object's field, as the master-detail carriers do. That widens RecordLineItemsProps.columns's describe, and becomes an objectui renderer change behind it. It is spec-lane work with its own card, and this card closes into it.

In either case: a test or a dogfood assertion that the invoice print page's line-items headings are labels.

Dedupe

Activity

  1. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade, bug · priority:p1 · target:v18 · domain:services · area:files · pm:blocked on PR #23811 · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-16T17:54Z

    Triage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.

    • Why p1 + target:v18: the printed invoice heads its table with field names. The maintainer's rule 「PDF 要赶 18.0 正式版」 puts the PDF chain at p1.
    • Why blocked: the page is added by PR feat(service-print): print a record's print page to a PDF in headless Chromium as the requesting user, and archive it on the record #23811, which is still open (read now). The body's Blocked-by: #23811 stands.
    • Scope: the showcase edit. Give the four record:line_items columns their labels, in both locales the showcase ships. The renderer draws what RecordLineItemsProps.columns declares. Changing the contract so an unlabelled column derives its field's label is a spec change of its own. ⛔ It is not this card. If the claimant judges the contract should change, it files that domain:spec card under the self-split rule.
    • Why domain:services: examples/* belongs to the subsystem it exercises, here the print service (service-print).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:filesFiles — upload, download, signed URLs, access derived from the parent recordbugSomething isn't workingdomain:servicespm:blockedpriority:p1High: required for production / M2target:v18

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions