[PR #30616] fix: prevent empty state flash and add skeleton loading for app list #32894

Closed
opened 2026-02-21 20:52:16 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/langgenius/dify/pull/30616

State: closed
Merged: Yes


Summary

This PR fixes two UX issues with the Apps list page:

  1. Empty state flash when switching filters - Fixed by using TanStack Query's keepPreviousData to retain previous data while new data is being fetched
  2. Missing skeleton loading state and NewAppCard timing issue - Fixed by adding proper loading state handling and skeleton placeholders

Changes

web/service/use-apps.ts

  • Added keepPreviousData import from TanStack Query
  • Added placeholderData: keepPreviousData to useInfiniteAppList hook

web/app/components/apps/list.tsx

  • Added isFetching and isLoadingCurrentWorkspace state handling
  • Added showSkeleton and showEmpty computed values for cleaner conditional rendering
  • Updated NewAppCard rendering to show during permission loading with isLoading prop
  • Changed condition from isCurrentWorkspaceEditor to (isCurrentWorkspaceEditor || isLoadingCurrentWorkspace)

web/app/components/apps/new-app-card.tsx

  • Added isLoading prop (default: false)
  • Applied loading styles: opacity-50 and pointer-events-none when loading

web/app/components/apps/app-card-skeleton.tsx (NEW)

  • Created skeleton placeholder component that matches AppCard visual layout
  • Uses existing Skeleton base components

Screenshots

Before After
CleanShot 2026-01-06 at 15 21 43 CleanShot 2026-01-06 at 15 22 44

Related Issues

Closes #30614
Closes #30615

**Original Pull Request:** https://github.com/langgenius/dify/pull/30616 **State:** closed **Merged:** Yes --- ## Summary This PR fixes two UX issues with the Apps list page: 1. **Empty state flash when switching filters** - Fixed by using TanStack Query's `keepPreviousData` to retain previous data while new data is being fetched 2. **Missing skeleton loading state and NewAppCard timing issue** - Fixed by adding proper loading state handling and skeleton placeholders ## Changes ### `web/service/use-apps.ts` - Added `keepPreviousData` import from TanStack Query - Added `placeholderData: keepPreviousData` to `useInfiniteAppList` hook ### `web/app/components/apps/list.tsx` - Added `isFetching` and `isLoadingCurrentWorkspace` state handling - Added `showSkeleton` and `showEmpty` computed values for cleaner conditional rendering - Updated NewAppCard rendering to show during permission loading with `isLoading` prop - Changed condition from `isCurrentWorkspaceEditor` to `(isCurrentWorkspaceEditor || isLoadingCurrentWorkspace)` ### `web/app/components/apps/new-app-card.tsx` - Added `isLoading` prop (default: false) - Applied loading styles: `opacity-50` and `pointer-events-none` when loading ### `web/app/components/apps/app-card-skeleton.tsx` (NEW) - Created skeleton placeholder component that matches AppCard visual layout - Uses existing `Skeleton` base components ## Screenshots | Before | After | |--------|-------| |![CleanShot 2026-01-06 at 15 21 43](https://github.com/user-attachments/assets/c42d021b-c48e-42cc-9a8a-1fac7d1b4a1d)|![CleanShot 2026-01-06 at 15 22 44](https://github.com/user-attachments/assets/95565850-7db1-4220-9dfd-6428174222ed)| ## Related Issues Closes #30614 Closes #30615
yindo added the pull-request label 2026-02-21 20:52:16 -05:00
yindo closed this issue 2026-02-21 20:52:16 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#32894