refactor(webui): simplify stats artist detail handoff

- remove the stats page timeout and library pre-navigation hack
- hand artist detail opening directly to the legacy shell bridge
- add a route test covering the direct artist navigation bridge call
This commit is contained in:
Antti Kettunen 2026-05-14 17:27:48 +03:00
parent 1e052373a4
commit 92e86527c3
No known key found for this signature in database
GPG key ID: C6B2A3D250359BD7
2 changed files with 19 additions and 23 deletions

View file

@ -114,6 +114,17 @@ describe('stats route', () => {
await waitFor(() => expect(history.location.search).toContain('range=30d'));
});
it('hands artist detail navigation directly to the shell bridge', async () => {
renderStatsRoute();
fireEvent.click(await screen.findByRole('button', { name: 'Artist A' }));
expect(window.SoulSyncWebShellBridge?.navigateToArtistDetail).toHaveBeenCalledWith(
7,
'Artist A',
);
});
it('redirects back home when the page is not allowed', async () => {
window.SoulSyncWebShellBridge = createShellBridge({
isPageAllowed: vi.fn((pageId) => pageId !== 'stats'),

View file

@ -135,6 +135,10 @@ export function StatsPage() {
});
};
const openArtistDetail = (artistId: string | number, artistName: string) => {
bridge.navigateToArtistDetail(artistId, artistName);
};
return (
<div id="stats-container" className={styles.statsContainer} data-testid="stats-page">
<header className={styles.statsHeader}>
@ -214,31 +218,23 @@ export function StatsPage() {
<StatsSectionCard title="Top Artists">
<TopArtistsVisual
artists={cachedStats?.top_artists ?? []}
onArtistSelect={(artistId, artistName) =>
void openArtistDetail(bridge, artistId, artistName)
}
onArtistSelect={(artistId, artistName) => openArtistDetail(artistId, artistName)}
/>
<StatsRankedArtists
artists={cachedStats?.top_artists ?? []}
onArtistSelect={(artistId, artistName) =>
void openArtistDetail(bridge, artistId, artistName)
}
onArtistSelect={(artistId, artistName) => openArtistDetail(artistId, artistName)}
/>
</StatsSectionCard>
<StatsSectionCard title="Top Albums">
<StatsRankedAlbums
albums={cachedStats?.top_albums ?? []}
onArtistSelect={(artistId, artistName) =>
void openArtistDetail(bridge, artistId, artistName)
}
onArtistSelect={(artistId, artistName) => openArtistDetail(artistId, artistName)}
/>
</StatsSectionCard>
<StatsSectionCard title="Top Tracks">
<StatsRankedTracks
tracks={cachedStats?.top_tracks ?? []}
onArtistSelect={(artistId, artistName) =>
void openArtistDetail(bridge, artistId, artistName)
}
onArtistSelect={(artistId, artistName) => openArtistDetail(artistId, artistName)}
onPlay={(track) => playStatsTrack(bridge, track)}
/>
</StatsSectionCard>
@ -877,17 +873,6 @@ function EmptyListState({ message }: { message: string }) {
return <div className={styles.emptyListState}>{message}</div>;
}
async function openArtistDetail(
bridge: ShellBridge,
artistId: string | number,
artistName: string,
) {
await window.SoulSyncWebRouter?.navigateToPage('library');
window.setTimeout(() => {
bridge.navigateToArtistDetail(artistId, artistName);
}, 300);
}
async function playStatsTrack(
bridge: ShellBridge,
track: { title: string; artist: string; album: string },