From 956698bd7c3d50e3a52d261c919164d1b4030941 Mon Sep 17 00:00:00 2001 From: mbeaulne Date: Tue, 24 Mar 2026 15:48:15 -0400 Subject: [PATCH] Update design for favourites --- .../FavoritesSection/FavoritesSection.tsx | 170 ---------------- .../Dashboard/DashboardFavoritesView.tsx | 182 +++++++++++++++++- 2 files changed, 180 insertions(+), 172 deletions(-) delete mode 100644 src/components/Home/FavoritesSection/FavoritesSection.tsx diff --git a/src/components/Home/FavoritesSection/FavoritesSection.tsx b/src/components/Home/FavoritesSection/FavoritesSection.tsx deleted file mode 100644 index 75114d38c..000000000 --- a/src/components/Home/FavoritesSection/FavoritesSection.tsx +++ /dev/null @@ -1,170 +0,0 @@ -import { useNavigate } from "@tanstack/react-router"; -import { - ChevronLeft, - ChevronRight, - GitBranch, - Play, - Star, - X, -} from "lucide-react"; -import { useState } from "react"; - -import { Button } from "@/components/ui/button"; -import { Icon } from "@/components/ui/icon"; -import { Input } from "@/components/ui/input"; -import { InlineStack } from "@/components/ui/layout"; -import { Paragraph, Text } from "@/components/ui/typography"; -import { type FavoriteItem, useFavorites } from "@/hooks/useFavorites"; -import { EDITOR_PATH, RUNS_BASE_PATH } from "@/routes/router"; - -const PAGE_SIZE = 10; - -function getFavoriteUrl(item: FavoriteItem): string { - if (item.type === "pipeline") return `${EDITOR_PATH}/${item.id}`; - return `${RUNS_BASE_PATH}/${item.id}`; -} - -const FavoriteChip = ({ item }: { item: FavoriteItem }) => { - const navigate = useNavigate(); - const { removeFavorite } = useFavorites(); - - const handleClick = () => { - navigate({ to: getFavoriteUrl(item) }); - }; - - const handleRemove = (e: React.MouseEvent) => { - e.stopPropagation(); - removeFavorite(item.type, item.id); - }; - - return ( -
- {item.type === "pipeline" ? ( - - ) : ( - - )} - {item.name} - -
- ); -}; - -export const FavoritesSection = () => { - const { favorites } = useFavorites(); - const [page, setPage] = useState(0); - const [query, setQuery] = useState(""); - - const filtered = query.trim() - ? favorites.filter((f) => { - const q = query.toLowerCase(); - return ( - f.id.toLowerCase().includes(q) || f.name.toLowerCase().includes(q) - ); - }) - : favorites; - - const totalPages = Math.ceil(filtered.length / PAGE_SIZE); - // Reset to last valid page if filtered results shrink - const safePage = Math.min(page, Math.max(0, totalPages - 1)); - const paginated = filtered.slice( - safePage * PAGE_SIZE, - (safePage + 1) * PAGE_SIZE, - ); - - return ( -
- - - - Favorites - - - - {favorites.length === 0 ? ( - - No favorites yet. Star a pipeline or run to pin it here. - - ) : ( -
-
- - { - setPage(0); - setQuery(e.target.value); - }} - className="pl-9 pr-8 w-full" - /> - {query && ( - - )} -
-
- {paginated.map((item) => ( - - ))} -
- - {totalPages > 1 && ( - - - - {safePage + 1} / {totalPages} - - - - )} -
- )} -
- ); -}; diff --git a/src/routes/Dashboard/DashboardFavoritesView.tsx b/src/routes/Dashboard/DashboardFavoritesView.tsx index 7a992312d..15999aa55 100644 --- a/src/routes/Dashboard/DashboardFavoritesView.tsx +++ b/src/routes/Dashboard/DashboardFavoritesView.tsx @@ -1,5 +1,183 @@ -import { FavoritesSection } from "@/components/Home/FavoritesSection/FavoritesSection"; +import { useNavigate } from "@tanstack/react-router"; +import { ChevronLeft, ChevronRight, GitBranch, Play, X } from "lucide-react"; +import { useState } from "react"; + +import { Button } from "@/components/ui/button"; +import { Icon } from "@/components/ui/icon"; +import { Input } from "@/components/ui/input"; +import { BlockStack, InlineStack } from "@/components/ui/layout"; +import { Paragraph, Text } from "@/components/ui/typography"; +import { type FavoriteItem, useFavorites } from "@/hooks/useFavorites"; +import { EDITOR_PATH, RUNS_BASE_PATH } from "@/routes/router"; + +const PAGE_SIZE = 16; + +function getFavoriteUrl(item: FavoriteItem): string { + if (item.type === "pipeline") return `${EDITOR_PATH}/${item.id}`; + return `${RUNS_BASE_PATH}/${item.id}`; +} + +const FavoriteCard = ({ item }: { item: FavoriteItem }) => { + const navigate = useNavigate(); + const { removeFavorite } = useFavorites(); + + const isPipeline = item.type === "pipeline"; + + return ( +
navigate({ to: getFavoriteUrl(item) })} + className={`group relative flex flex-col gap-2 p-3 border rounded-lg cursor-pointer transition-colors ${ + isPipeline + ? "bg-violet-50/40 hover:bg-violet-50 border-violet-100" + : "bg-emerald-50/40 hover:bg-emerald-50 border-emerald-100" + }`} + > + {/* Remove button */} + + + {/* Type badge */} + + {isPipeline ? ( + + ) : ( + + )} + + {isPipeline ? "Pipeline" : "Run"} + + + + {/* Name */} + + {item.name} + + + {/* ID */} + + {item.id} + +
+ ); +}; export function DashboardFavoritesView() { - return ; + const { favorites } = useFavorites(); + const [page, setPage] = useState(0); + const [query, setQuery] = useState(""); + + const filtered = query.trim() + ? favorites.filter((f) => { + const q = query.toLowerCase(); + return ( + f.id.toLowerCase().includes(q) || f.name.toLowerCase().includes(q) + ); + }) + : favorites; + + const totalPages = Math.ceil(filtered.length / PAGE_SIZE); + const safePage = Math.min(page, Math.max(0, totalPages - 1)); + const paginated = filtered.slice( + safePage * PAGE_SIZE, + (safePage + 1) * PAGE_SIZE, + ); + + return ( + + + Favorites + + + {favorites.length === 0 ? ( + + No favorites yet. Star a pipeline or run to pin it here. + + ) : ( + + {/* Search */} +
+ + { + setPage(0); + setQuery(e.target.value); + }} + className="pl-9 pr-8" + /> + {query && ( + + )} +
+ + {/* Grid */} + {paginated.length === 0 ? ( + + No results for “{query}”. + + ) : ( +
+ {paginated.map((item) => ( + + ))} +
+ )} + + {/* Pagination */} + {totalPages > 1 && ( + + + + {safePage + 1} / {totalPages} + + + + )} +
+ )} +
+ ); }