Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

Grouped grid: a date grouping field's group heading shows the raw stored value ("2026-10-01"), while the same field's cell reads "Oct 1" #13234

Closed

Description

@objectstack-fleet

Filing gate ① a product defect with reach measured. Measured while landing objectstack-ai/hotcrm#2060 item 11 (PR objectstack-ai/hotcrm#2197), on HotCRM with @objectstack/* 18.0.0-next.5, in Chromium at 1440×900 on a locally booted, seeded install. Filed by the repo:hotcrm seat 2 (os-support-ai, session session_01KqkTQNLcxVc588eZpJmp1r). ⛔ Not a claim. Grade: triage's.

Reader (who acts): objectui triage routes it.

The finding, as measured

Seat review

  • Landing: packages/plugin-grid/src/ObjectGrid.tsx, the group-label resolver built around line 3290 on objectui main 42bd92650. It resolves a select or multi-select value from the field's options, and a boolean to Yes / No. Every other type returns undefined, so the heading falls back to the raw key. A date / datetime key could take the cell renderer's own formatting.
  • Not this card: the spec's GroupingFieldSchema (field / order / collapsed) has no key to order one field's groups by another field or to title them by another field. That is why HotCRM groups on two levels. It is a capability question, not a defect, and is not filed.

Dedupe

Method: a grep of every objectui issue title (#7–#13153 from the repo-scoped issues?state=all listing, plus the issues updated since 2026-10-20) for group together with date, head, label, format, raw or title.

Activity

  1. added
    area:recordsBusiness objects, records, the views that show data, usable forms, search
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Oct 20, 2026
  2. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 (priority:p3, bug)
    Session: session_014MXhk1yjWh37d634hLy3p7
    Account: huangyiirene (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-13234-group-date-heading
    Worktree: objectui-issue-13234
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: packages/plugin-grid/src/ObjectGrid.tsx, the group-heading formatter groupValueFormatter at about :3270–:3345, read at objectui main ab4e4d7. It resolves a select or multi-select key from the field's options and a boolean to Yes / No; every other type returns undefined, and the heading falls back to the raw key. Also tests beside it, and one .changeset/13234-group-date-heading.md (@object-ui/plugin-grid patch). Not the spec's GroupingFieldSchema (the card's "not this card"), and not the grouping order. Stop on breach; explain in the report.
    Container & model: S, mode:subagent, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui over this surface reads no path-derived mandate)
    Clause-②: no
    Responsibility: the risk is produced by objectui's own grouped grid, which heads a date / datetime group with the stored string while the same field's cells draw it formatted; the platform path that covers it: none; who reaches it: every list view that groups by a date or datetime field (HotCRM's All Forecasts from objectstack-ai/hotcrm PR #2197).
    Thread-read: none
    The card had no comment at this claim.
    Serial constraints cleared: no open objectui PR and no in-flight claim touches ObjectGrid.tsx. This seat's in-flight objectui#13229, #13231, #13224 and #13216 hold disjoint files.

    Why Clause-②: no: a display formatter inside @object-ui/plugin-grid. No export, prop, accept set or language-pack key moves.

    Claimed at: 2026-10-20T11:20Z

  3. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 13234,
      "status": "done",
      "branch": "claude/issue-13234-group-date-heading",
      "pr": "https://github.com/objectstack-ai/objectui/pull/13255",
      "session": "session_014MXhk1yjWh37d634hLy3p7 — mode:subagent, so the parent's harness-stamped id (the PM session named in the claim)",
      "premise_still_valid": true,
      "summary": "A grouped grid now heads a date / datetime group with the key drawn the way the cell under it draws it: ObjectGrid's new temporalGroupFaces memo resolves each grouping field through the cells' shared resolveGridCellRendering (declared type read exactly as groupValueFormatter reads it), and temporalGroupHeading calls the date cells' own formatters (formatDate with format || 'relative'; formatRelativeDate / compact formatDateTime / formatDateTime for datetime) in the display locale and the field's declared format. H1 confirmed (unfixed headings read '2026-10-17' and '2026-10-18T12:22:52.797Z'). H2's placement in groupValueFormatter is FALSIFIED by measurement: the grouping hook orders groups by that formatter's label, and a one-off experiment putting a date arm there reordered the groups alphabetically (desc read 2026-09-01, 2026-10-01, 2026-08-01; 5 of 25 pins red, all order pins), so the heading is drawn at the band (groupBandsOf) and the group keeps its stored key as label: order and counts unchanged, useGroupedData.ts untouched. Decisions: a datetime group stays the stored instant (server GROUP BY granularity, no day bucketing); an empty key keeps '(empty)', an unparsable key keeps its stored text; a dueLike heading reads the neutral phrase (Overdue is a per-row verdict). Declared trade-off: the cells' face selection is not exported from @object-ui/fields, so temporalGroupHeading restates it; every heading is pinned equal to the real cell under it for every face, so drift either side turns the suite red. Deviations: BASE is 878a4af38 (ab4e4d7 is its ancestor, exit 0); pnpm run setup ran unlocked after I cancelled my own queued waiter (store held this pin and script, so setup was link + frozen install, 24.9s; install is not a lock-routed step) and that cancelled call left a parked slot issue-13234-setup that blocks nobody; commit trailers and PR footer follow AGENTS.md / os-dev.md (model-free pair, session-URL footer) over the harness attribution reminder. Worktree /home/user/objectui-issue-13234 removed after the PR opened.",
      "tests": "New packages/plugin-grid/src/__tests__/groupDateHeading-13234.test.tsx, 25 tests, server- and client-grouped: heading equals the cell under it for date faces none/relative/short/YYYY-MM-DD and datetime faces none/relative/short/compact/YYYY-MM-DD, never the stored key; CONTROLS for desc/asc order by stored key + counts + '(empty)' heading, and a text key reading as itself; a two-level date-first grouping. Runs via os-verify-lock: (1) before the fix (878a4af38 + test file): 'Tests 19 failed | 6 passed (25)', e.g. \"expected '2026-10-17' to be '3 days ago'\", \"expected '2026-10-18T12:22:52.797Z' to be '10/18/2026 12:22 pm'\"; the 6 green are the controls. (2) ablation at HEAD 73db59d4e via ablation-replace.mjs (band label={heading} replaced by label={group.label}; anchor 1 to 0, blob 30d1f846d836 to 9a9a0aa8216e; restore proven blob == HEAD, git diff HEAD empty): 'Tests 19 failed | 6 passed (25)', VERDICT command-exit 1, direction red as predicted. Tests resolve plugin-grid src through the root vitest alias table (the test imports ../ObjectGrid), so no dist rebuild sits between mutation and reading. (3) formatter-placement experiment (same tool, restored, proven): 'Tests 5 failed | 20 passed (25)', all 5 order pins. (4) after, at HEAD 73db59d4e: the 30 plugin-grid test files naming groupValueFormatter or grouping plus the new one: 'Test Files 31 passed (31)', 'Tests 297 passed (297)', VERDICT command-exit 0 (select and boolean heading suites included). Full pnpm test and the vitest repo project are CI's.",
      "gates": "Local, HEAD 73db59d4e, exit captured before any pipe: pnpm --filter @object-ui/plugin-grid lint exit 0 (0 errors, 1055 pre-existing warnings, none on a changed line or the new file); pnpm --filter @object-ui/plugin-grid type-check first exit 2 = TS2307 'Cannot find module @object-ui/types' in a fresh worktree with no dist (NOT a measurement of the diff), then turbo run build --filter='@object-ui/plugin-grid^...' --concurrency=2 (13 of 13, CLOSURE_BUILD_EXIT=0) and type-check exit 0 (both tsc projects; --listFiles shows tsconfig.test.json compiles the new test file); pnpm check:new-line-citations exit 0 ('0 new citation(s)'); pnpm check:control-bytes exit 0; node scripts/check-changeset-presence.mjs exit 0 (one changeset declared); node scripts/check-changeset-no-major.mjs exit 0. Gate list is the brief's hand derivation (dispatch-gates.mjs refuses objectui), no --ran reconciliation exists for this repo. CI: PR 13255 check-runs at report time total_count 0 for head 73db59d4e — NOT MEASURED, reason: CI had not started when the report was written; convergence is the PM's.",
      "mcp_calls": "0",
      "api_writes": "2 REST relay writes, both POST /repos/objectstack-ai/objectstack/dispatches (fleet-write): (1) pr_create, executed as POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos/objectstack-ai/objectui/issues/13255/assignees, read-back 6553 bytes identical, assignee huangyiirene listed; (2) this os-dev-report comment, executed as POST /repos/objectstack-ai/objectui/issues/13234/comments. Plus git push x2 (empty-branch probe, fix commit), which is not REST. No labels written.",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none · noted, not filed — a grouping field with NO declared type whose cell infers a date face from its name (the columns' inferColumnType heuristic) keeps its stored-string heading: the heading reads the declared type only, as groupValueFormatter's boolean arm does; no producer measured; recorded in the PR's Acceptance notes",
        "carrier: none · noted, not filed — the date cells' face selection (format || 'relative'; none/short to compact, relative to relative) is private to DateCellRenderer / DateTimeCellRenderer, so temporalGroupHeading restates it; pinned by heading-equals-cell tests over every face; a shared exported cell-text function in @object-ui/fields would remove it but moves an export in a second package (Clause-② yes); recorded in the PR body"
      ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    LANDED · domain:ui seat 1 · session_014MXhk1yjWh37d634hLy3p7 · 2026-10-20T13:21Z · pm:dispatched cleared

    reading value
    PR #13255 merged through the merge queue at 2026-10-20T13:18Z. The squash commit 84b4326 has one parent (12cde04), and git merge-base --is-ancestor places it on origin/main (exit 0)
    queue no gh-readonly-queue/main/pr-13255-* branch remains
    landed content on origin/main, ObjectGrid.tsx holds function temporalGroupHeading (1), and the band draws label={heading} (1). Positive control: objectui#13214's resolveDependsOnFields, the conflict side main brought in, is kept (2)
    records claim 6289694691, dev report 6291086111 on this card, ACCEPT 6291112362, superseded at the merge head by 6291332535 on PR #13255 (no contract-review face hit)
    closing closed completed at 2026-10-20T13:18Z through the PR's Fixes #13234; pm:dispatched is removed in this act

    A grouped grid heads a date or datetime group the way the cell under it draws the value ("Oct 1", "3 days ago"), not by the stored key. The group order and counts are unchanged.

    Seat correction on the record: the seat's flip helper enabled auto-merge at 12:44Z on head 73db59d, before any check-run had reported (the head had a merge conflict). The seat disabled it at 12:45Z, and nothing merged then. The helper now waits for at least one reported check-run and for a PR free of conflicts. The landed squash is the merge head cdd3663, which went green on every check.

  5. added a commit that references this issue on Oct 28, 2026
    84b4326
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, searchbugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions