diff --git a/webui/src/routes/stats/-route.test.tsx b/webui/src/routes/stats/-route.test.tsx index ec251ae9..20867072 100644 --- a/webui/src/routes/stats/-route.test.tsx +++ b/webui/src/routes/stats/-route.test.tsx @@ -117,14 +117,29 @@ describe('stats route', () => { await waitFor(() => expect(history.location.search).toContain('range=30d')); }); - it('hands artist detail navigation directly to the shell bridge', async () => { - renderStatsRoute(); + it('links artist names to the artist-detail route', async () => { + const { history } = renderStatsRoute(); + + const bubbleLink = await screen.findByRole('link', { + name: 'Open artist detail for Artist A', + }); + expect(bubbleLink).toHaveAttribute('href', '/artist-detail/library/7'); - fireEvent.click(await screen.findByRole('button', { name: 'Artist A' })); + const rankedLink = screen.getByRole('link', { name: 'Artist A' }); + expect(rankedLink).toHaveAttribute('href', '/artist-detail/library/7'); - expect(window.SoulSyncWebShellBridge?.navigateToArtistDetail).toHaveBeenCalledWith( - 7, - 'Artist A', + fireEvent.click(bubbleLink); + + await waitFor(() => expect(history.location.pathname).toBe('/artist-detail/library/7')); + await waitFor(() => + expect(window.SoulSyncWebShellBridge?.navigateToArtistDetail).toHaveBeenCalledWith( + '7', + '', + null, + { + skipRouteChange: true, + }, + ), ); }); diff --git a/webui/src/routes/stats/-ui/stats-page.module.css b/webui/src/routes/stats/-ui/stats-page.module.css index 17be6814..a6260111 100644 --- a/webui/src/routes/stats/-ui/stats-page.module.css +++ b/webui/src/routes/stats/-ui/stats-page.module.css @@ -364,10 +364,13 @@ border: none; padding: 0; cursor: pointer; + color: inherit; + text-decoration: none; + font: inherit; transition: transform 0.2s ease; } -.statsArtistBubble:disabled { +.statsArtistBubbleDisabled { cursor: default; } @@ -375,6 +378,10 @@ transform: translateY(-3px); } +.statsArtistBubbleDisabled:hover { + transform: none; +} + .statsBubbleImage { border-radius: 50%; background-size: cover; diff --git a/webui/src/routes/stats/-ui/stats-page.tsx b/webui/src/routes/stats/-ui/stats-page.tsx index 63259a7d..1c93b461 100644 --- a/webui/src/routes/stats/-ui/stats-page.tsx +++ b/webui/src/routes/stats/-ui/stats-page.tsx @@ -1,6 +1,6 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; -import { useNavigate } from '@tanstack/react-router'; -import { type ReactNode, useEffect, useRef, useState } from 'react'; +import { Link, useNavigate } from '@tanstack/react-router'; +import { type ComponentPropsWithoutRef, type ReactNode, useEffect, useRef, useState } from 'react'; import { Bar, BarChart, @@ -72,6 +72,8 @@ const STATS_CHART_CURSOR = { fill: 'rgba(var(--accent-rgb), 0.12)', } as const; +const ARTIST_DETAIL_SOURCE = 'library' as const; + export function StatsPage() { const bridge = useReactPageShell('stats'); @@ -136,10 +138,6 @@ export function StatsPage() { }); }; - const openArtistDetail = (artistId: string | number, artistName: string) => { - bridge.navigateToArtistDetail(artistId, artistName); - }; - return (
) : null}
@@ -509,13 +508,7 @@ function StatsRankedArtists({
);
}
-function StatsRankedAlbums({
- albums,
- onArtistSelect,
-}: {
- albums: StatsAlbumRow[];
- onArtistSelect: (artistId: string | number, artistName: string) => void;
-}) {
+function StatsRankedAlbums({ albums }: { albums: StatsAlbumRow[] }) {
return (