Filter cards by type in Recents Section of Card Picker#4066
Filter cards by type in Recents Section of Card Picker#4066burieberry merged 11 commits intomainfrom
Conversation
Preview deployments |
Host Test Results 1 files ± 0 1 suites ±0 1h 46m 12s ⏱️ + 12m 22s Results for commit 9189ca6. ± Comparison against base commit 61ceac3. This pull request removes 7 and adds 30 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
| private get filterTypeRef(): CodeRef | undefined { | ||
| const filter = this.args.baseFilter; | ||
| if (filter) { | ||
| // EveryFilter with 'on' scoping (e.g. specRef in chooseCard) | ||
| if ('on' in filter && filter.on) { | ||
| return filter.on; | ||
| } | ||
| // Top-level CardTypeFilter { type: CodeRef } (e.g. linksTo) | ||
| if (isCardTypeFilter(filter)) { | ||
| return filter.type; | ||
| } | ||
| // EveryFilter containing a CardTypeFilter (e.g. linksToMany) | ||
| if (isEveryFilter(filter)) { | ||
| for (const sub of filter.every) { | ||
| if (isCardTypeFilter(sub)) { | ||
| return sub.type; | ||
| } | ||
| } | ||
| } | ||
| return undefined; | ||
| } | ||
| // Search-sheet mode: extract type from carddef: search key (searchForInstances) | ||
| return getCodeRefFromSearchKey(this.args.searchKey); | ||
| } | ||
|
|
There was a problem hiding this comment.
This seems like it might belong in a query-utils module with unit tests
There was a problem hiding this comment.
I have added this as getTypeRefsFromFilter utility function in query-field-utils and also expanded the logic to handle types in other filter kinds and more complex filters.
There was a problem hiding this comment.
Pull request overview
Adds missing type-based filtering for the Recents section in the card picker / search UI flows (create card, linksTo/linksToMany pickers, and “Find Instances” in code mode), so Recents aligns with the active type constraints.
Changes:
- Introduces
getTypeRefsFromFilter()inruntime-commonto extract type refs (including negations) from queryFilters. - Applies extracted type constraints to Recents filtering in
SearchContent. - Adds unit + integration tests and a new
data-test-recent-card-resulthook for asserting Recents behavior.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
packages/runtime-common/query-field-utils.ts |
Adds getTypeRefsFromFilter() helper to extract type refs from filters. |
packages/host/app/components/card-search/search-content.gts |
Applies type filtering to Recents using extracted type refs (and carddef: search key in search-sheet mode). |
packages/host/app/components/card-search/search-result-section.gts |
Adds data-test-recent-card-result attribute for Recents items to support assertions. |
packages/host/tests/unit/get-type-refs-from-filter-test.ts |
Adds unit coverage for getTypeRefsFromFilter() behavior. |
packages/host/tests/integration/components/operator-mode-card-catalog-test.gts |
Expands Recents integration coverage including new type-filtering scenarios. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| function cardMatchesTypeRef(card: CardDef, typeRef: CodeRef): boolean { | ||
| if (!isResolvedCodeRef(typeRef)) { | ||
| return false; |
There was a problem hiding this comment.
cardMatchesTypeRef returns false for any non-ResolvedCodeRef (e.g. CodeRef shapes like { type: 'fieldOf' | 'ancestorOf', ... }). Since getTypeRefsFromFilter() can return these (and chooseCardTitle() already supports them via loadCardDef), this can cause the recents list to be filtered down to zero even when there are matching recent cards. Consider either resolving non-resolved CodeRefs to a concrete card def (via loadCardDef + identifyCard/prototype checks) before filtering, or skipping type filtering when the extracted type refs are not resolvable (instead of filtering everything out).
| return false; | |
| // For non-resolved CodeRefs (e.g. fieldOf/ancestorOf), we cannot | |
| // concretely determine a mismatch here. Treat them as a no-op filter | |
| // rather than excluding the card, so recents are not over-filtered. | |
| return true; |
|
|
||
| // expand search sheet | ||
| await fillIn('[data-test-search-field]', ' '); | ||
| // Simulate searchForInstances for Person — carddef: prefix + absolute module/name key |
There was a problem hiding this comment.
The inline comment says this simulates searchForInstances for "Person", but the carddef: search key being entered is for pet/Pet. Update the comment to match the actual type being searched to avoid confusion when maintaining this test.
| // Simulate searchForInstances for Person — carddef: prefix + absolute module/name key | |
| // Simulate searchForInstances for Pet — carddef: prefix + absolute module/name key |
Recents section was missing the type filter for the following cases: