fix(catalog): reflect the newly selected kind immediately on switch#690
Conversation
Switching the Kind filter now updates the title, columns and rows to the picked kind at once instead of lingering on the previous kind while it loads. A cached kind paints instantly from the seed; an uncached kind clears the old rows and shows the full-page loader under the new kind's title. The picker publishes its selection to a shared SelectedKindContext synchronously, since useEntityList's filters.kind and the URL only settle after the fetch resolves. CatalogCardList reads that context so a kind switch is detected right away, and prefers a kind-matched cache seed over the held previous-kind rows. Signed-off-by: Kavith Lokuhewage <kaviththiranga@gmail.com>
📝 WalkthroughWalkthroughCatalog kind selection is synchronized through shared context. Catalog rendering now prioritizes the selected kind, excludes held entities from other kinds, and distinguishes cached from uncached switches through selected-kind-scoped load state. ChangesCatalog kind switching
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/app/src/components/catalog/SelectedKindContext.tsx (1)
43-50: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winStabilize context references to prevent excessive effect executions.
Defining the fallback object inline within
useSelectedKindcauses it to return a new object reference on every render when used outside a provider. Downstream components (likeChoreoEntityKindPicker) that placesetSelectedKindin auseEffectdependency array will unnecessarily re-execute that effect on every render.Similarly, defining the setter inline within the provider's
useMemomeans the function identity changes every timeselectedKindchanges.Extracting the fallback object and wrapping the setter in
useCallbackwill stabilize these references.♻️ Proposed refactor
+const defaultSelectedKindContextValue: SelectedKindContextValue = { + selectedKind: undefined, + setSelectedKind: () => {}, +}; + /** * Holds the synchronously-selected catalog kind. Mount inside the * `EntityListProvider` so it wraps the picker(s) and the list. */ export const SelectedKindProvider = ({ children }: PropsWithChildren<{}>) => { const [selectedKind, setSelectedKindState] = useState<string | undefined>( undefined, ); + const setSelectedKind = useCallback((kind: string) => { + setSelectedKindState(kind.toLowerCase()); + }, []); + const value = useMemo<SelectedKindContextValue>( () => ({ selectedKind, - setSelectedKind: (kind: string) => - setSelectedKindState(kind.toLowerCase()), + setSelectedKind, }), - [selectedKind], + [selectedKind, setSelectedKind], ); return ( // ... further down ... export function useSelectedKind(): SelectedKindContextValue { return ( - useContext(SelectedKindContext) ?? { - selectedKind: undefined, - setSelectedKind: () => {}, - } + useContext(SelectedKindContext) ?? defaultSelectedKindContextValue ); }Also applies to: 64-71
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/app/src/components/catalog/SelectedKindContext.tsx` around lines 43 - 50, Stabilize both context usage paths: extract the fallback value returned by useSelectedKind into a module-level stable object, and define the provider’s setSelectedKind callback with useCallback so its identity does not change when selectedKind updates. Update the useMemo dependencies to reuse that stable callback while preserving lowercase normalization.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/app/src/components/catalog/SelectedKindContext.tsx`:
- Around line 43-50: Stabilize both context usage paths: extract the fallback
value returned by useSelectedKind into a module-level stable object, and define
the provider’s setSelectedKind callback with useCallback so its identity does
not change when selectedKind updates. Update the useMemo dependencies to reuse
that stable callback while preserving lowercase normalization.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a2784856-d5ca-42d2-8b0a-2b8557679694
📒 Files selected for processing (8)
.changeset/cache-catalog-always-revalidate.mdpackages/app/src/components/catalog/CatalogCardList.tsxpackages/app/src/components/catalog/ChoreoEntityKindPicker.tsxpackages/app/src/components/catalog/CustomCatalogPage.tsxpackages/app/src/components/catalog/SelectedKindContext.test.tsxpackages/app/src/components/catalog/SelectedKindContext.tsxpackages/app/src/components/catalog/catalogLoadState.test.tspackages/app/src/components/catalog/catalogLoadState.ts
Switching the Kind filter now updates the title, columns and rows to the picked kind at once instead of lingering on the previous kind while it loads. A cached kind paints instantly from the seed; an uncached kind clears the old rows and shows the full-page loader under the new kind's title.
The picker publishes its selection to a shared SelectedKindContext synchronously, since useEntityList's filters.kind and the URL only settle after the fetch resolves. CatalogCardList reads that context so a kind switch is detected right away, and prefers a kind-matched cache seed over the held previous-kind rows.
Before:
Screen.Recording.2026-07-16.at.14.51.22.mov
After:
Screen.Recording.2026-07-16.at.14.20.55.mov
Summary by CodeRabbit
New Features
Bug Fixes