Migrate catalog card source to the v2 search surface#623
Open
habdelra wants to merge 4 commits into
Open
Conversation
Move catalog card source off the deprecated
`@context.prerenderedCardSearchComponent` and onto the v2
`@context.searchResultsComponent` (`<SearchResults>`), via the `@context`
search codemod plus hand-fixes for the shapes it can't transform mechanically.
Codemod-migrated:
- `components/grid.gts`, `blog-app/blog-post.gts`, and the reader-view / theme
searches in `blog-app/blog-app.gts` — the v1 query is adapted through
`searchEntryWireQueryFromQuery`, `<:response>` becomes
`{{#each results.entries}}`, and rows are addressed by `id`.
Hand-migrated (shapes the codemod leaves alone):
- `components/card-list.gts` — yields each row to a `:meta` block; the dynamic
`@format` binds through the query's `htmlQuery` field.
- `catalog-app/components/grid.gts` — hands each row to `<CardWithHydration>`
and branched on result count; now renders entries / loading skeleton /
no-results explicitly.
- `catalog-app/components/category-filter-group.gts` — the query is a per-sphere
`{{#each}}` value, adapted inline via `searchQueryForSphere`.
- `catalog-app/components/tag-filter-group.gts` — the result list is wrapped in
markup rather than rendered as a bare `{{#each}}`.
- `blog-app/blog-app.gts` — the library-posts search hands its list to wrapping
markup; its `<CardList>` `:meta` consumer reads the row `id`.
Consumer:
- `catalog-app/components/card-with-hydration.gts` — now takes a
`RenderableSearchEntryLike` and addresses the row by `id`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
habdelra
commented
Jun 19, 2026
habdelra
commented
Jun 19, 2026
habdelra
commented
Jun 19, 2026
habdelra
commented
Jun 19, 2026
Rename the codemod-generated searchResultsQuery* getters to describe the query they wrap: picksSearchQuery, latestSearchQuery, themeSearchQuery, libraryPostsSearchQuery. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Migrates catalog/blog UI components from the deprecated @context.prerenderedCardSearchComponent to the v2 @context.searchResultsComponent (<SearchResults>) surface by adapting v1 Query inputs into v2 SearchEntryWireQuery and updating templates to iterate results.entries keyed by id.
Changes:
- Replaced prerendered search component usage with v2 search results yielding (
as |results|) andresults.entries. - Added
searchEntryWireQueryFromQueryadapters (plusrealmsandhtmlQueryformat bindings where needed). - Updated consumers to treat rows as
RenderableSearchEntryLikeand useidinstead ofurl.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| components/grid.gts | Switches to v2 search results component and iterates results.entries. |
| components/card-list.gts | Switches to v2 search; yields RenderableSearchEntryLike to :meta; binds format via htmlQuery. |
| catalog-app/components/tag-filter-group.gts | Switches tag pills to v2 search results and uses id addressing. |
| catalog-app/components/grid.gts | Switches listing grid to v2 search results with explicit entries/loading/empty rendering. |
| catalog-app/components/category-filter-group.gts | Switches per-sphere category lists to v2 search results with inline query adaptation. |
| catalog-app/components/card-with-hydration.gts | Updates hydration wrapper to accept RenderableSearchEntryLike and address rows by id. |
| blog-app/blog-post.gts | Switches theme picker search to v2 search results and uses id. |
| blog-app/blog-app.gts | Switches multiple searches (picks/latest/theme/library) to v2 search results and updates :meta consumer to use id. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Type the blog query getters as `Query` (annotation) instead of casting at the call site; inline `latestQuery`'s `eq` so its values are `JSONValue`. - Render search results immediately and show the loading affordance only on the empty initial load — a live re-fetch keeps the previous entries — to match the hand-migrated components. The sphere filter likewise keeps its UI during a re-fetch instead of collapsing to a skeleton. - card-with-hydration: card ids never carry a file extension, so drop the `removeFileExtension` stripping and compare the id directly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CodeRef.module is a branded RealmResourceIdentifier, so the hand-written themeQuery code refs need rri() (codeRef() already brands the others). This clears the lint:types CodeRef-module type error. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
backspace
approved these changes
Jun 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Moves catalog card source off the deprecated
@context.prerenderedCardSearchComponentand onto the v2@context.searchResultsComponent(<SearchResults>) surface, via the@contextsearch codemod (from the boxel repo) plus hand-fixes for the shapes it can't transform mechanically.Codemod-migrated
components/grid.gts,blog-app/blog-post.gts, and the reader-view / theme-picker searches inblog-app/blog-app.gts— the v1 query is adapted throughsearchEntryWireQueryFromQuery,<:response>becomes{{#each results.entries}}, and rows are addressed byid.Hand-migrated (shapes the codemod leaves alone)
components/card-list.gts— yields each row to a:metablock; the dynamic@formatbinds through the query'shtmlQueryfield.catalog-app/components/grid.gts— hands each row to<CardWithHydration>and branched on result count; now renders entries / loading skeleton / no-results explicitly.catalog-app/components/category-filter-group.gts— the query is a per-sphere{{#each}}block value, adapted inline via asearchQueryForSpherehelper.catalog-app/components/tag-filter-group.gts— the result list is wrapped in markup rather than a bare{{#each}}.blog-app/blog-app.gts— the library-posts search hands its list to wrapping markup; its<CardList>:metaconsumer now reads the rowid.Consumer
catalog-app/components/card-with-hydration.gts— now takes aRenderableSearchEntryLikeand addresses the row byid.Where a search yields to children or has a skeleton/empty state, the list renders once
results.entriesis present (stale entries persist across a live re-fetch) and the loading affordance shows only on the empty initial load.Verification
.gtstranspiles through the realm's owngjsToPlaceholderJS+ babel lowering.@cardstack/*+ base types).Part of the unified-search Phase 1 codemod sweep across the first-party realms.