Add ProcessCard base card for Workspace setup-progress#5580
Conversation
The forthcoming Workspace index card (CS-12277) discovers setup-progress jobs by querying the realm for `ProcessCard` instances via a codeRef, so the field names are a contract the Workspace reads. Define that CardDef: `listingName`, `stage`, `progressDone`/`progressTotal`, `startedAt`, `processStatus`, and an optional linked `setupSurvey`, with computed `percentComplete`/`progressLabel`/`statusLabel` and a shared isolated/embedded/fitted template rendering an accessible progress bar. Export ProcessCard from the base-realm test helper (mirroring CardsGrid) and cover the getters plus rendering with an integration test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Workspace Home inventory folds machinery types behind a "System (n)" link by matching the type's displayName against a fixed set that includes 'Process'. Use that exact displayName so ProcessCard is folded as system machinery rather than surfaced as content. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A remix is a realm or card cloned from a source. It runs through the same setup-progress lifecycle as a process, so RemixCard extends ProcessCard — reusing the job-progress contract the Workspace Home setup-bar reads — and adds the source it was remixed from. displayName 'Remix' matches the Workspace's system-type folding set. The shared progress template is inherited unchanged. Export RemixCard from the base-realm test helper and cover the inherited getters, subtype relationship, and rendering. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Address review: - remixedFrom is the only field RemixCard adds over ProcessCard, but nothing exercised it. Add a test that links a RemixCard to a source card and reads it back, pinning the card's reason to exist. - Drop `export default RemixCard` for consistency with ProcessCard and other base cards, which only expose a named export. The sole importer uses the named export, so nothing depends on the default. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
burieberry
left a comment
There was a problem hiding this comment.
There's a ProgressBar component that already has the theming in place that might be sufficient. I used it in software-factory/realm/overview.gts for software-factory setup progress.
Address the front-end review: use the shared themed ProgressBar instead of a hand-rolled track+fill; reference semantic role tokens (--muted-foreground, and --primary/--muted via ProgressBar) instead of the numbered palette; and set font-weight/font-size/line-height separately rather than the font shorthand, which resets the themed font-family. Update the rendering tests for the ProgressBar; percentComplete is already unit-tested directly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ents Capture two conventions surfaced in review: don't use the CSS font shorthand (it resets the themed font-family — set the weight/size/line-height axes separately), and reach for an existing themed @cardstack/boxel-ui component (e.g. ProgressBar) before hand-rolling a UI primitive. Also sharpen the color guidance to steer off the numbered palette toward the semantic role tokens (--muted, --muted-foreground, --primary). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
[Claude Code 🤖] Thanks for the review — all applied in the latest two commits:
The rendering tests now assert the shared progress bar renders ( I also captured the two conventions that weren't yet written down — no |
…and-remixcard-base-carddef
RemixCard inherits ProcessCard's template, which now renders the shared ProgressBar instead of a hand-rolled bar. Assert the shared progress bar renders rather than the removed bar/fill elements. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ddef' into cs-12286-land-remixcard-base-carddef
habdelra
left a comment
There was a problem hiding this comment.
[Claude Code 🤖] Reviewed with two lenses: (1) does a base card that exists purely as a contract for a not-yet-landed consumer hold up on its own, and (2) did the design-review swap to the shared ProgressBar land cleanly. I checked out the head branch and traced the fields, the template, the shared ProgressBar, the base CardDef.cardTitle it overrides, and the failing CI check.
Bottom line: no blocking issues. The card is small, well-tested, and idiomatic; the design-review feedback was correctly applied. The items worth acting on before merge are the stale accessibility claims and confirming the memory-baseline CI failure is the expected "new module, no baseline" case.
What lands right
- The
ProgressBarswap is the correct response to the review thread — it's the shared themed component, and it resolves the--muted/--primarytoken notes for free becauseProgressBarthemes its own track/fill internally. The unusedbarStylegetter was correctly dropped. - The getters are the right shape and are unit-tested directly rather than through the DOM:
percentCompleteclamps to 0–100 and returns 0 (notNaN) when the total is unknown or ≤ 0;progressLabelreturns''on unknown total;statusLabeldefaults to'running'.@max={{100}}against a value already normalized to a percentage is correct (double-clamping inProgressBaris harmless). - Module wiring is sound: base modules resolve by path (
@cardstack/base/process-card), so no manifest/registration entry is needed beyond the file itself; thebase-realm.tstest-helper addition correctly mirrors theCardsGridpattern. - The
gts-component-conventionsskill additions (nofontshorthand; reach for an existing themed boxel-ui component before hand-rolling; steer off the numbered palette toward semantic role tokens) are accurate and written evergreen.
On the earlier review thread
burieberry's ProgressBar suggestion is fully applied and the six styling threads are all addressed in the latest commits — nothing left open there.
Cross-cutting: the failing "Host Memory Baseline" check is this PR's new test module. The job log shows it failing with "2 module(s) exceeded hard memory threshold", and the two flagged modules are the two with no baseline row — one of which is Integration | Card | process-card at 5.9 MB (the other, an ai-assistant-panel module, isn't from this branch). A new host test module has no baseline entry, so it's measured against an absolute hard cap. 5.9 MB is not an obvious leak for a setupBaseRealm test (peers on the same run: read-source 5.7 MB, rendered-markdown 11.3 MB), so this reads as "new module, no baseline" rather than retention gone wrong — and the PR's mergeable_state is unstable, not blocked, so it's advisory rather than a required gate. Please confirm the intended flow: the Update Host Memory Baseline job was skipped on this PR (it runs on main), so the baseline should regenerate post-merge. If you want to be sure it's not genuine retention, a quick pass with the host-test-memory-leak lens on the two renderCard calls would settle it.
One thing this PR can't verify, by design. There is no consumer in the tree yet — no "System (n)" folding logic and nothing querying for ProcessCard — so the field-name spellings are the entire load-bearing surface and nothing pins them to what the forthcoming Workspace index card will read. That's acceptable for landing the card ahead of its consumer; just worth an integration test when the consumer lands that actually resolves ProcessCard via the codeRef and reads these fields, so a later rename of e.g. progressTotal fails loudly instead of silently.
Recommendations (all non-blocking; ordered by value)
- Fix the stale accessibility claims — the PR body still says "an accessible
role="progressbar"bar" and the rendering test is titled "…accessible attributes…", but the sharedProgressBarhas no progressbar role/aria-value*; adding those to the shared component is a clean follow-up. See the thread on the<ProgressBar>line. - Confirm the memory-baseline flow above (advisory vs. required; baseline regenerates on merge).
- Decide consciously whether
cardTitleshould dropcardInfo.name— consistent withTag/Country/CardsGrid, differs fromStyleReference. See the thread on thecardTitlefield. - Consider making the progress unit ("items") customizable or noun-free, since the card spans indexing/import/setup-flow jobs. See the thread on
progressLabel. - Give
fitteda compact variant only if it clips in the smallest tiles. See the thread on the format assignments.
Adjacent, out of scope (minor, whoever touches this next)
.process-carddeclarescontainer-type: inline-sizebut there are no@containerqueries, so it's inert (it does establish a query container + inline-size containment, which is harmless here).data-status={{@model.statusLabel}}on the status span is keyed by nothing — no CSS or test reads it. Fine as a deliberate styling/testing hook, otherwise removable.startedAtandsetupSurveyare unused in this card's own template — expected, since they're contract fields for the forthcoming consumer, not dead code.
Generated by Claude Code
…carddef Add RemixCard base card for realm remixes
…onent The circular "falls back to the card title" note on listingName now describes the actual relationship (cardTitle reads listingName). The rendering test title no longer claims accessible attributes it does not assert; the progressbar ARIA semantics live on the shared ProgressBar (added in #5586) rather than at this call site. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What
Adds
ProcessCard(packages/base/process-card.gts), a base CardDef representing a long-running setup-progress job (indexing, import, a guided setup flow).Why
A realm's index card surfaces setup-progress jobs on its Home tab by querying the realm for
ProcessCardinstances via acodeRef(codeRef(here, './process-card', 'ProcessCard')) rather than a static import. The field names here are therefore a contract that consumer reads, and the card must exist in the base realm for those jobs to resolve and render.(Unrelated to the
Wiki/process-card.jsonfixture in the software-factory realm, which is a documentation page that adoptsWikiand merely shares the filename.)Fields (the contract)
listingName,stage,processStatus(StringField),progressDone/progressTotal(NumberField),startedAt(DateTimeField), and an optional linkedsetupSurvey. Plus computedcardTitle(falls back to "Setup process") and getterspercentComplete/progressLabel/statusLabel, driving a shared isolated/embedded/fitted template. The bar is the shared themedProgressBarfrom boxel-ui; its progressbar ARIA semantics (role="progressbar",aria-value*) are added to the shared component in #5586.Tests
packages/host/tests/integration/components/process-card-test.gts— 10 tests covering the getters (fraction, clamping, unknown-total, status default) and rendering (aria attributes, copy, fill width, fallbacks).packages/host/tests/helpers/base-realm.ts— exportsProcessCardfrom the base-realm test helper (mirrors theCardsGridwiring) so tests exercise the real base card via the loader.Test plan: runs green locally against a full dev stack — 10 passed, 0 failed. Clean under glint (
ember-tsc --noEmit),ember-template-lint, and prettier.🤖 Generated with Claude Code