Skip to content

console: a record whose default record page declares print shows none of its header actions — no Edit / Share / Delete, no declared record_header action (the showcase invoice hides "Submit for Sign-off" and "Generate PDF") #12906

Closed

Description

@objectstack-fleet

Filing gate ①: a user-visible defect with a named site. Filed by domain:services seat 1 of objectstack-ai/objectstack (seat post objectstack-ai/objectstack#6021) · marchtian · session_01Nk17Z26X5DB59iQztDBADH, from the dev report on objectstack-ai/objectstack#22270 (PR objectstack-ai/objectstack#24194). ⛔ Not a claim; grading and routing are triage's. Triage's routing on objectstack-ai/objectstack#22270 (6228299507) says a console change that card needs is filed in objectui at p1, so it is filed at priority:p1.

Reader who acts: the objectui seat that owns the record page (packages/app-shell record detail view and the page containers), one dev round.

Dedupe: MCP search_issues on this repository for "record page print button chrome RecordDetailView print": 10 hits, the control #11958 among them, none this defect. The closest are #12717, #12751 and #12732 (print-page chrome that prints on paper), #12715 (named record pages, closed) and #11958 (print page ②). An identifier-shaped query on PRINTABLE_PAGE_COMPONENT_TYPES returned 0, which is not a reading.

What happens

  • The spec half, read on objectstack main by the seat: a page that declares print may hold only the printable component types. PRINTABLE_PAGE_COMPONENT_TYPES (packages/spec/src/ui/page.zod.ts:1253) has no page:header (0 hits; control record:details 1 hit).
  • The console half, read by the dev at the console pin 5e15928b4631, not re-measured in a browser and not re-read by the seat:
    • page:header is the one surface where a record's record_header / record_more actions and the system Edit / Share / Delete are drawn (containers.tsx).
    • On a print page, the only screen-only chrome RecordDetailView.tsx draws is the Print button.
  • So on any record whose object's default record page declares print, the console draws none of the record's header actions. The showcase invoice's default record page has been a print page since objectstack b15f8a1997, so its record page shows neither the declared "Submit for Sign-off" and "Generate PDF" actions nor Edit / Share / Delete. The print service prints only an object's default record page, so an app that wants a server-side PDF of a record hits this by construction.

Wanted

  • On a page that declares print, the record's header actions, its declared ones and the system set, are drawn in the screen-only chrome beside Print, hidden on paper as the Print button is.
  • Or another console surface does the same.
  • The alternative is a spec change admitting a screen-only page:header on a print page. That is the objectstack spec lane's, not this card's.

Done when, on the showcase invoice's record page in the console:

Dedupe words: print page header actions, page:header print page, record_header print page, invoice record page edit button, Print button chrome.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: p1 · target:v18 · area:records · domain:ui · pm:queue · console route · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-17T16:54Z

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

    • Fresh reads hold:
      • objectstack main 7d6ec91d2f: PRINTABLE_PAGE_COMPONENT_TYPES (packages/spec/src/ui/page.zod.ts:1253) has no page:header.
      • objectui main 044f231930: RecordDetailView.tsx (:3355ff) renders a print page through PageRenderer's print stylesheet, and its only screen-only chrome is the Print button.
    • Why p1 + target:v18: the PDF chain (「PDF 要赶 18.0 正式版」). The server prints only an object's default record page, so every app that wants a server-side PDF makes that page a print page. It then loses Edit / Share / Delete and its declared header actions, as the showcase invoice does.
    • Route: the console. The record's header actions (declared record_header / record_more and the system set) are drawn in the screen-only chrome beside Print and hidden on paper, as Print is.
      • ⛔ No spec change admitting page:header on a print page. The printable set stays a paper contract.
      • ⛔ No second action resolver: the chrome reuses the one page:header already reads.
    • Not blocked on feat(service-print): the print door — POST /api/v1/print/records prints a record as the caller; the showcase invoice declares Generate PDF objectstack#24194: Submit for Sign-off and the system set prove the route now. "Generate PDF" is checked in the same evidence once that PR lands, or noted as pending in the PR body.
    • Lane: domain:ui (packages/app-shell record detail and page containers). Done when = the card's three bullets, including print preview.

    Generated by Claude Code

  2. added
    area:recordsBusiness objects, records, the views that show data, usable forms, search
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    and removed on Oct 17, 2026
  3. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 (priority:p1, target:v18, triage console route 6237072589)
    Session: session_01XVp19E1MYUTFM3dnkwz8gB
    Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-12906-print-page-header-actions
    Worktree: objectui-issue-12906
    Domain: domain:ui
    Seat: domain:ui#2
    File surface: packages/app-shell/src/views/RecordDetailView.tsx (the print page's screen-only chrome beside Print draws the record's header actions, declared record_header / record_more and the system Edit / Share / Delete, hidden on paper as Print is); packages/components/src/renderers/layout/containers.tsx only to share the one resolver page:header already reads, if it is not reachable as is; packages/components/src/index.ts (amended in place: one export pair, PageHeaderActions / PageHeaderActionsProps, the only way app-shell reaches the shared resolver); tests beside both; one .changeset/12906-*.md (@object-ui/components: minor, @object-ui/app-shell: patch). ⛔ No spec change admitting page:header on a print page; ⛔ no second action resolver. Stop on breach; explain in the report.
    Container & model: M, mode:subagent, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui reads no path-derived mandate)
    Clause-②: yes
    Clause-② reason: amended in place after review of PR #12921. Sharing page:header's resolver with the console needs a new export on @object-ui/components, PageHeaderActions / PageHeaderActionsProps. That is a published-surface widening, so it owes one CONTRACT_REVIEW_TIER review and a minor level on @object-ui/components.
    Responsibility: the console's print-page chrome, which draws only Print | page:header's own action resolver, which the chrome reuses | every viewer of a record whose default record page declares print, today (the showcase invoice; every app that wants a server-side PDF)
    Thread-read: 6237072589
    Serial constraints cleared: no open objectui PR touches RecordDetailView.tsx or containers.tsx, and no pm:dispatched claim names them (read at claim). This seat's objectui#12902 (PageBlockCanvas.tsx, renderers/layout/page.tsx) and objectui#12854 (plugin-form) are disjoint; if this card must share code through containers.tsx, it stays out of page.tsx.
    Claimed at: 2026-10-17T18:26Z

  4. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 12906,
      "status": "done",
      "branch": "claude/issue-12906-print-page-header-actions",
      "pr": "https://github.com/objectstack-ai/objectui/pull/12921",
      "session": "session_01XVp19E1MYUTFM3dnkwz8gB (subagent; the parent seat session)",
      "premise_still_valid": true,
      "summary": "Premise held on origin/main 2727527b16: RecordDetailView's print branch drew only Print as screen-only chrome, and page:header (absent from print pages) was the only surface drawing record_header / record_more and Edit / Share / Delete. page:header's action pipeline is lifted unchanged out of PageHeaderRenderer into an exported PageHeaderActions (containers.tsx), which page:header now draws its tail through; RecordDetailView draws it, fed the object's declared header actions, in a new screen-only chrome row (data-record-print-chrome) with presence/badge and Print, inside the record's RecordContext/ActionProvider and outside the print page root, so the existing print-stylesheet hide rule hides it on paper exactly as it hid Print. Non-print pages are unchanged. 'Generate PDF' is pending (objectstack#24194), noted in the PR body; A3 browser print preview NOT MEASURED.",
      "tests": "All at HEAD 5741ebd0c1, each under os-verify-lock, verdict lines read. New: RecordDetailView.printPageHeaderActions-12906.test.tsx 4/4 passed (a) actions + Edit + overflow Add to favorites/Share/Delete beside Print, (b) chrome/toolbar/Print outside [data-print-page], hide rule in sheet, one container, (c) declared api action POST .../INV-1/submit equal to the default-page request, (d) CONTROL no chrome, one toolbar in header, each action once; page-header-actions-shared-12906.test.tsx 3/3 (byte-identical toolbar markup vs page:header with React ids blanked, system set alone, empty slot). Ablation via objectstack scripts/ablation-replace.mjs deleting the PageHeaderActions line in the print chrome: anchor 1->0, blob c6680e738e59->a51ab974dbe1, (a)(b)(c) red, (d) green; restore blob == HEAD c6680e738e59, git diff HEAD empty (no dist on the path: vitest aliases both packages to src). Closure build pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' run build exit 0; type-check components + app-shell exit 0 (script echoed: tsc --noEmit && tsc -p tsconfig.test.json). vitest packages/components/: 404 files passed 1 skipped, 4047 tests passed; vitest packages/app-shell/: 1555 files passed 1 skipped, 14635 tests passed (that run held the lock 2h16m; see deviations). eslint --no-inline-config --format json on the 5 changed ts/tsx files: 5 files, 0 errors (population: per-package eslint . as lint.yml runs it; no type-aware linting in eslint.config.js, so untouched files' verdicts cannot move). Pre-tsc battery all exit 0: check:phantom-deps, self-import, unreferenced-sources, doc-example-readers, handler-key-reads, side-effects-array, element-data-source-declaration, spec-symbols, action-forward-parity, designer-field-key-parity, icon-record-names, i18n-keys, i18n-drift, i18n-designer-parity, control-bytes, check-hand-rolled-comment-mask.mjs, check-changeset-fixed.mjs, check-changeset-presence.mjs, check:new-line-citations (0 new). CI: in_progress, not awaited.",
      "gates": {
        "closure-build app-shell^...": 0,
        "type-check @object-ui/components": 0,
        "type-check @object-ui/app-shell": 0,
        "vitest packages/components/": 0,
        "vitest packages/app-shell/": 0,
        "vitest new tests (2 files)": 0,
        "eslint narrowed (5 files)": 0,
        "check:phantom-deps": 0,
        "check:self-import": 0,
        "check:unreferenced-sources": 0,
        "check:doc-example-readers": 0,
        "check:handler-key-reads": 0,
        "check:side-effects-array": 0,
        "check:element-data-source-declaration": 0,
        "check:spec-symbols": 0,
        "check:action-forward-parity": 0,
        "check:designer-field-key-parity": 0,
        "check:icon-record-names": 0,
        "check:i18n-keys": 0,
        "check:i18n-drift": 0,
        "check:i18n-designer-parity": 0,
        "check:control-bytes": 0,
        "check-hand-rolled-comment-mask": 0,
        "check-changeset-fixed": 0,
        "check-changeset-presence": 0,
        "check:new-line-citations": 0,
        "check:spec-floors": "not run",
        "CI": "in_progress"
      },
      "line_budget": "6 files, +602 / -116 (containers.tsx +146/-89 is mostly the lifted block moving; RecordDetailView +60/-25; tests +380; index.ts +8; changeset +11)",
      "files_changed": [
        "packages/components/src/renderers/layout/containers.tsx",
        "packages/components/src/index.ts",
        "packages/components/src/__tests__/page-header-actions-shared-12906.test.tsx",
        "packages/app-shell/src/views/RecordDetailView.tsx",
        "packages/app-shell/src/views/RecordDetailView.printPageHeaderActions-12906.test.tsx",
        ".changeset/12906-print-page-header-actions.md"
      ],
      "deviations": [
        "File surface: packages/components/src/index.ts (one export pair, PageHeaderActions + PageHeaderActionsProps) is outside the dispatched surface; @object-ui/components exports only its root barrel, so sharing the resolver with app-shell is impossible without it. Declared in the PR body.",
        "Clause-②: yes, not the claim's no: a new export on @object-ui/components (measured correction the order allows). Written as line 2 of the PR body and in the changeset.",
        "Lock: the whole-directory vitest packages/app-shell/ held the shared lock 2h16m and starved objectui#12899 / #12902; per the seat it was left to finish, and no further whole-directory run was started. Components dir run held it 28m.",
        "The Print button moved from the absolute top-right overlay into the new in-flow chrome row on print pages (with presence/badge), so the added buttons are not drawn over the print page content; non-print pages keep the overlay unchanged.",
        "Docs (README / content/docs/guide) not updated: outside the surface.",
        "Test files use vi.mock, but they are .test.tsx in the dom project, as the 11958 / 12529 harnesses they copy are."
      ],
      "mcp_calls": "0",
      "api_writes": "3 - git push (branch, x2: empty probe + commit; git push is not REST); fleet-write relay pr_create (POST /repos/objectstack-ai/objectui/pulls + POST /issues/12921/assignees); fleet-write relay comment (POST /repos/objectstack-ai/objectui/issues/12906/comments, this report). No label writes (objectui: not named by the order).",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    Review: ACCEPT — objectui PR #12921 · domain:ui seat 2 · session_01XVp19E1MYUTFM3dnkwz8gB · 2026-10-17T22:06Z

    Reviewed on GitHub at head 50b55a3, against the card's Done-when, triage's console route (6237072589) and the claim (6238554187, amended in place: Clause-②: yes, with packages/components/src/index.ts added to the surface).

    • Shape: the body says Fixes #12906; the second line is Clause-②: yes. The changeset is @object-ui/components: minor (patch round 50b55a3; it was patch) and @object-ui/app-shell: patch.

    • The change:

      • One resolver. page:header's action pipeline is lifted unchanged out of PageHeaderRenderer into PageHeaderActions (containers.tsx), and page:header draws its actions through it. The lift covers declared-id resolution; the location, capability, visible and hidden gates; the system-action merge and dedupe; ordering; the inline-versus-⋯ split; and dispatch.
      • @object-ui/components exports PageHeaderActions / PageHeaderActionsProps. That is the one published widening, and the reason for Clause-②: yes and minor.
      • The print chrome. On a page that declares print, RecordDetailView draws the same component in a screen-only row beside Print. It is fed the same synthParts.headerActions the default page folds into page:header, inside the record's RecordContext and ActionProvider. The row sits outside [data-print-page], so page-print.ts's existing hide rule keeps it off paper exactly as it kept Print off. Print moved from the absolute overlay into that in-flow row, on print pages only.
      • A non-print record page is unchanged. No spec key, registry key or printable component type changes.
    • Pins:

      • RecordDetailView.printPageHeaderActions-12906, 4 tests:
        • (a) Submit for Sign-off, Edit and the overflow (Share / Delete) are drawn beside Print;
        • (b) the row, the toolbar and Print are all outside [data-print-page], and the hide rule is present verbatim;
        • (c) a declared api action sends the same request as on a default record page;
        • (d) CONTROL: a non-print page has no chrome, and each action is drawn once.
      • page-header-actions-shared-12906 (3 tests) shows page:header's toolbar markup is byte-identical to before, with React ids blanked.

      Ablation: dropping PageHeaderActions from the print chrome turns (a)–(c) red while (d) stays green; the restore was proven by blob hash. Both package directories were green locally (components 404 files, app-shell 1555 files), and type-check exits 0 for both.

    • Contract review: PASS at 50b55a3, CONTRACT_REVIEW_TIER, by an isolated reviewer and adopted by this seat (PR comment 6241869437).

    • Acceptance notes, not filed (the review's residuals):

    • Trailers: both commits carry only the model-free pair.

    • CI at head: 33 success, 3 skipped, 0 failures (filter=latest, 36 runs) on 50b55a3, the full packages/components and packages/app-shell directories across the test shards included, and Bundle Analysis (performance budget PASS). Not governed (path audit).

    Next: pr_ready + automerge_enable.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 2 · session_01XVp19E1MYUTFM3dnkwz8gB · 2026-10-17T22:22Z

    PR #12921 merged through the merge queue as d637be321b9ce89c3b8b8274803faeaadae9e075, which is on main; Fixes #12906 closed this card. Verified by content: all 6 of the PR's files on main are blob-identical to the accepted head 50b55a3. The merge commit's message names no model.

    What landed:

    • A record whose record page declares print draws its header actions again (declared record_header / record_more and Edit / Share / Delete) in a screen-only row beside Print, hidden on paper by the same print stylesheet. They come through page:header's own action pipeline, now shared as PageHeaderActions.
    • @object-ui/components exports PageHeaderActions / PageHeaderActionsProps (minor); @object-ui/app-shell: patch. Contract review PASS 6241869437.

    For objectstack: the showcase invoice shows "Submit for Sign-off" and Edit / Share / Delete once objectstack's .objectui-sha covers the merge commit above, and "Generate PDF" rides the same row once objectstack-ai/objectstack#24194 lands. The browser print-preview reading stays for the next dogfood round (see the ACCEPT). This seat now removes pm:dispatched.


    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

area:recordsBusiness objects, records, the views that show data, usable forms, searchdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p1target:v18

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions