Skip to content

showcase: author an emptyState fixture on the Urgent task view - #8036

Merged
hotlong merged 1 commit into
mainfrom
claude/issue-7714-showcase-emptystate-fixture
Aug 12, 2026
Merged

showcase: author an emptyState fixture on the Urgent task view#8036
hotlong merged 1 commit into
mainfrom
claude/issue-7714-showcase-emptystate-fixture

Conversation

@hotlong

Copy link
Copy Markdown
Contributor

Fixes#7714

What

packages/spec declares a per-view empty-state translation surface — objects.OBJECT._views.VIEW.emptyState.title / .message — it is authorable on a list view, and it is documented. But no view anywhere under examples/ authored one, so the declared key group had no reachable instance on the stock fixture. The i18n surface-matrix check therefore had nothing to resolve and was recorded as waived-for-missing-fixture rather than actually run.

This authors the specimen and translates it in both bundle locales. Fixture-only, entirely inside examples/app-showcase/src/**; no spec change — the surface was already declared and authorable, and the card exists precisely because nothing used it.

  • src/ui/views/task.view.tslistViews.urgent gains emptyState: { title, message }
  • src/system/translations/index.ts — the matching en and zh-CN entries under _views.urgent

Why this view

This is the whole substance of an otherwise small diff, so stating it plainly: emptiness means different things on a filtered saved view and on an unfiltered object list.

An unfiltered list that is empty is a setup state — "nothing exists yet" — and the showcase seed deliberately never produces it (data/seed/index.ts seeds inquiries specifically so "every view renders real data"). A filtered view that is empty is a steady state — "nothing matches right now" — which a running deployment hits constantly. That second case is what per-view empty-state copy exists to serve, which makes it the spelling worth pinning as the fixture.

listViews.urgent (filter: priority equals urgent) is the strongest instance of it, for two reasons beyond being filtered:

  1. Empty is the outcome the user wants. The copy can report good news ("Nothing needs immediate attention right now") instead of nagging about absent data. A plausible message is the difference between a fixture people trust and maintain and one they route around.
  2. It is reachable without touching the seed. The two urgent seed rows are exactly what the neighbouring bulk_actions view's showcase_mark_done exists to clear — so a demo user empties this view by using the app, not by editing fixtures. That kept the change inside the declared file surface.

Why the en arm is not a mirror

The en side of this bundle carried no _views block at all before this change; all fifteen live on the zh-CN side. The new en block is deliberately only the emptyState group, not a mirror: view labels are already English in the view file, so restating all fifteen would be fifteen fake translations of exactly the kind the bundle's own header warns about.

The emptyState group earns its entry because a key present in one locale cannot demonstrate a locale-resolving surface — an en session would read the view's inline source string through the fallback path, which is a different code path and proves nothing about the resolver. Both arms present is what gives the surface-matrix check the same key resolving to different copy per locale.

Verification

Gates derived from the touched paths via scripts/pm/dispatch-gates.mjs (it named no path-scoped family; the implicated ones were run by convention).

GateResult
pnpm --filter '@objectstack/example-showcase...' buildgreen — the showcase's own metadata validation accepts the view definition
check:i18n-coverageOK (12 config(s), 660 baselined untranslated string(s), none new)
check:i18nOK (9 package(s) — all bundles in sync, no undeclared authoring keys)
check:nul-bytesOK (scanned 7331 text file(s) … no raw ASCII control bytes)

Reverse verification — direction predicted before running.i18n-extract.ts emits _views.VIEW.emptyState.title / .message as real expected entries, so the prediction was that dropping the bundle entries while keeping the view's emptyState should make the ratchet go red by exactly two. Reverting only the translations file and re-running gave:

examples/app-showcase/objectstack.config.ts: untranslated declared strings grew 451 → 453.

+2, as predicted. That is what proves the fixture genuinely reaches the extractor rather than sitting inert, and it is why both keys are translated in the same change: leaving them untranslated widens the frozen count (fails the ratchet), and translating anything extra would push it below baseline (which the same gate rejects). Restored via patch file, both gates re-confirmed green.

Notes

  • No changeset, and skip-changeset applies: @objectstack/example-showcase is private: true, which scripts/check-changeset-fixed.mjs excludes by design (if (!pkg.name || pkg.private === true) continue).
  • Worth recording for whoever picks up the QA item: no resolver in this repo reads _views.VIEW.emptyStatei18n-resolver.ts resolves label and description only. The consumer is the objectui list renderer. That does not affect this card (the gap filed was the missing fixture, and the extractor/coverage path does read the key, as the reverse verification above shows), but a checklist item expecting a framework-side resolver call would be looking in the wrong repo.
  • Related: finding: showcase seed assigns tasks to non-user emails — a stock reassignment lands an inbox row nobody can read #7746 remains referenced as the nearest fixture precedent; nothing here changes its state.

Generated by Claude Code

The spec declares a per-view empty-state translation surface
(`objects.<object>._views.<view>.emptyState.{title,message}`), it is
authorable on a list view and it is documented — but no view anywhere
under `examples/` authored one, so the declared key group had no
reachable instance on the stock fixture. The i18n surface-matrix check
had nothing to resolve and was recorded as waived-for-missing-fixture
rather than actually run.
Author the specimen on `showcase_task.listViews.urgent` and translate it
in both bundle locales.
The view choice is the substance here. Emptiness means different things
on a filtered saved view and on an unfiltered object list: empty and
unfiltered is a setup state ("nothing exists yet") that the showcase
seed deliberately never produces, while empty and filtered is a steady
state ("nothing matches right now") that a running deployment hits
constantly. On this particular filter the empty result is also the
outcome the user wants, so the copy reports good news instead of nagging
about absent data — which is the case per-view empty-state copy exists
to serve. It stays reachable without touching the seed, too: the two
urgent seed rows are what the neighbouring `bulk_actions` view's
`showcase_mark_done` is there to clear.
The `en` arm is a first for this bundle, which until now carried `_views`
only on the zh-CN side. It is deliberately not a mirror: view labels are
already English in the view file, so restating all fifteen would be
fifteen fake translations of exactly the kind this bundle's header warns
about. Only the `emptyState` group is pinned, because a key present in
one locale cannot demonstrate a locale-resolving surface — an `en`
session would read the view's inline source string through the fallback
path instead, which is a different code path.
No changeset: `@objectstack/example-showcase` is a private workspace
package, which the changeset gate excludes by design.
@vercel

vercelBot commented Aug 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 12, 2026 12:51pm

Request Review

@hotlonghotlong added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 12, 2026 — with Claude
@hotlong
hotlong marked this pull request as ready for review August 12, 2026 13:37
@hotlong
hotlong added this pull request to the merge queueAug 12, 2026
Merged via the queue into main with commit e9490c7Aug 12, 2026
28 checks passed
@hotlong
hotlong deleted the claude/issue-7714-showcase-emptystate-fixture branch August 12, 2026 13:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

showcase: no view authors an emptyState, so the objects._views.<view>.emptyState translation surface has no fixture to test

2 participants

@hotlong@claude