web : infinite scroll for project and dataset lists#41
web : infinite scroll for project and dataset lists#41
Conversation
|
Claude finished @surajmn1's task —— View job Reviewing Infinite Scroll ImplementationTodo List
Code Review SummaryThis PR implements infinite scrolling functionality for projects and datasets using a clean, well-structured approach. The implementation follows React best practices and integrates well with the existing TanStack Query architecture. ✅ StrengthsArchitecture & Design
Implementation Quality
User Experience
|
WalkthroughThis PR introduces infinite scrolling pagination across the projects and datasets pages. A new Changes
Sequence DiagramsequenceDiagram
participant User
participant Component as Page Component
participant Observer as useIntersectionObserver
participant RQ as React Query<br/>(useInfiniteQuery)
participant API as Server API
User->>Component: Scroll near load-more sentinel
Component->>Observer: Observing loadMoreRef element
Observer->>Observer: Check visibility threshold
alt Sentinel in view
Observer->>Component: inView = true
Component->>Component: Effect triggered (inView && hasNextPage)
Component->>RQ: fetchNextPage()
RQ->>API: GET /datasets?page=2&limit=12
API->>RQ: { results: [...], total: 45 }
RQ->>Component: Update datasetsData.pages
Component->>Component: Flatten pages → allDatasets
Component->>Component: Render new DatasetCards
else Sentinel not in view
Observer->>Component: inView = false
Component->>Component: Effect skipped
end
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~20–25 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 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 |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (4)
web/src/lib/queries/project/list-projects.ts (1)
39-57: Includelimitin the query key to prevent stale cache issues.If
limitchanges between calls (e.g., different components using different limits), React Query will return cached data for the wrong page size. Addinglimitto the query key ensures proper cache separation.Suggested fix
export const useProjectsInfinite = (limit = 12) => { return useInfiniteQuery<PaginatedResponse<Project>, Error>({ - queryKey: ["projects", "infinite"], + queryKey: ["projects", "infinite", limit], initialPageParam: 1, queryFn: ({ pageParam }) => fetchProjects({ limit, page: pageParam as number }),web/src/lib/queries/dataset/list-datasets.ts (1)
50-71: Includelimitin the query key for cache correctness.Same issue as
useProjectsInfinite— iflimitvaries, the cache could return data for a different page size.Suggested fix
export const useDatasetsInfinite = (projectId: string, limit = 12) => { return useInfiniteQuery<PaginatedResponse<Dataset>, Error>({ - queryKey: ["datasets", projectId, "infinite"], + queryKey: ["datasets", projectId, "infinite", limit], initialPageParam: 1, enabled: !!projectId,web/src/app/page.tsx (1)
367-380: Animation delay is constant; consider staggering for smoother UX.The
delay: 0.05is applied uniformly to all items, so they animate simultaneously. For a staggered effect where items appear one after another, useidx * 0.05.Suggested fix
{allProjects.map((project, idx) => ( <motion.div key={project.id} initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} - transition={{ delay: 0.05 }} + transition={{ delay: idx * 0.05 }} >web/src/app/projects/[projectId]/page.tsx (1)
176-189: Same animation delay issue — consider staggering.Like the home page, the delay is constant. For consistency and improved UX, consider using
idx * 0.05for staggered animations.Suggested fix
{allDatasets.map((dataset, idx) => ( <motion.div key={dataset.id} initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} - transition={{ delay: 0.05 }} + transition={{ delay: idx * 0.05 }} >
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
web/src/app/page.tsx(6 hunks)web/src/app/projects/[projectId]/page.tsx(7 hunks)web/src/hooks/use-intersection-observer.ts(1 hunks)web/src/lib/queries/dataset/list-datasets.ts(2 hunks)web/src/lib/queries/project/list-projects.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
web/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (web/CLAUDE.md)
web/src/**/*.{ts,tsx}: Use Next.js 15 with App Router and React 19 for the web frontend framework
Use TypeScript as the language for the web frontend
Generate and use types from API responses for type safety
Use dynamic imports and code splitting for optimal performance
Load DuckDB WASM on-demand and use web workers for client-side SQL execution
Files:
web/src/lib/queries/dataset/list-datasets.tsweb/src/hooks/use-intersection-observer.tsweb/src/lib/queries/project/list-projects.tsweb/src/app/page.tsxweb/src/app/projects/[projectId]/page.tsx
web/src/lib/{queries,mutations}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (web/CLAUDE.md)
Use React Query (TanStack Query) for server state management
Files:
web/src/lib/queries/dataset/list-datasets.tsweb/src/lib/queries/project/list-projects.ts
web/src/app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (web/CLAUDE.md)
Protect routes using the ProtectedRoute wrapper HOC for authentication-required pages
Files:
web/src/app/page.tsxweb/src/app/projects/[projectId]/page.tsx
🧠 Learnings (7)
📚 Learning: 2025-12-02T11:48:50.411Z
Learnt from: CR
Repo: factly/gopie PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2025-12-02T11:48:50.411Z
Learning: Applies to web/src/components/dataset/**upload**.{ts,tsx} : Use Uppy for dataset file uploads in upload components
Applied to files:
web/src/lib/queries/dataset/list-datasets.tsweb/src/app/projects/[projectId]/page.tsx
📚 Learning: 2025-12-02T11:48:50.411Z
Learnt from: CR
Repo: factly/gopie PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2025-12-02T11:48:50.411Z
Learning: Applies to web/src/lib/{queries,mutations}/**/*.{ts,tsx} : Use React Query (TanStack Query) for server state management
Applied to files:
web/src/lib/queries/dataset/list-datasets.tsweb/src/lib/queries/project/list-projects.tsweb/src/app/page.tsxweb/src/app/projects/[projectId]/page.tsx
📚 Learning: 2025-12-02T11:48:50.411Z
Learnt from: CR
Repo: factly/gopie PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2025-12-02T11:48:50.411Z
Learning: Applies to web/src/components/**/*.{ts,tsx} : Use pre-configured queries and mutations from lib/queries and lib/mutations for API calls
Applied to files:
web/src/lib/queries/dataset/list-datasets.tsweb/src/lib/queries/project/list-projects.tsweb/src/app/page.tsxweb/src/app/projects/[projectId]/page.tsx
📚 Learning: 2025-12-02T11:48:50.411Z
Learnt from: CR
Repo: factly/gopie PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2025-12-02T11:48:50.411Z
Learning: Applies to web/src/**/*.{test,spec}.{ts,tsx} : Use React Testing Library for component testing
Applied to files:
web/src/hooks/use-intersection-observer.ts
📚 Learning: 2025-12-02T11:48:50.411Z
Learnt from: CR
Repo: factly/gopie PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2025-12-02T11:48:50.411Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use Next.js 15 with App Router and React 19 for the web frontend framework
Applied to files:
web/src/app/page.tsx
📚 Learning: 2025-07-29T09:36:39.908Z
Learnt from: CR
Repo: factly/gopie PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-07-29T09:36:39.908Z
Learning: Applies to web/**/*.{js,jsx,ts,tsx} : Use Zustand for global state management and React Query for server state in the Next.js frontend
Applied to files:
web/src/app/page.tsxweb/src/app/projects/[projectId]/page.tsx
📚 Learning: 2025-12-02T11:48:50.411Z
Learnt from: CR
Repo: factly/gopie PR: 0
File: web/CLAUDE.md:0-0
Timestamp: 2025-12-02T11:48:50.411Z
Learning: Applies to web/src/components/**/*.{ts,tsx} : Always handle loading and error states in UI components
Applied to files:
web/src/app/page.tsx
🧬 Code graph analysis (4)
web/src/lib/queries/dataset/list-datasets.ts (1)
web/src/lib/api-client.ts (1)
PaginatedResponse(144-149)
web/src/lib/queries/project/list-projects.ts (1)
web/src/lib/api-client.ts (1)
PaginatedResponse(144-149)
web/src/app/page.tsx (2)
web/src/lib/queries/project/list-projects.ts (1)
useProjectsInfinite(39-58)web/src/hooks/use-intersection-observer.ts (1)
useIntersectionObserver(10-43)
web/src/app/projects/[projectId]/page.tsx (2)
web/src/lib/queries/dataset/list-datasets.ts (1)
useDatasetsInfinite(50-72)web/src/hooks/use-intersection-observer.ts (1)
useIntersectionObserver(10-43)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: claude-review
- GitHub Check: Analyze (go)
🔇 Additional comments (4)
web/src/hooks/use-intersection-observer.ts (1)
10-42: LGTM!Clean implementation with proper cleanup. The observer is correctly disconnected and
inViewis reset on unmount/disable, preventing stale state.web/src/app/page.tsx (1)
31-50: Infinite scroll integration looks good.The combination of
useProjectsInfinite,useIntersectionObserver, and the effect to triggerfetchNextPageis well-structured. Disabling the observer during fetches (enabled: hasNextPage && !isFetchingNextPage) prevents redundant API calls.web/src/app/projects/[projectId]/page.tsx (2)
39-58: Infinite scroll integration is correct.The datasets infinite query, intersection observer, and fetchNextPage effect follow the same solid pattern established in the home page. The
enabledguard on the observer prevents unnecessary fetches.
67-70: Query invalidation key matches — good.The invalidation uses
["datasets", projectId, "infinite"]which correctly matches the query key inuseDatasetsInfinite. If you adopt the suggested fix to includelimitin the query key, update this invalidation to match or use a partial match (predicate-based invalidation).
implements infinite scrolling for projects and datasets in home and project detail pages
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.