feat(ui): add Artists, Songs, and Playlists to Default View options (#5754)

* Add resource lists to default view options

* refactor(ui): reuse getStoredDefaultView in AlbumList default-view redirect

Avoid duplicating the localStorage fallback logic and skip the unused
albumLists lookup in the resource-redirect branch, per PR review feedback.
This commit is contained in:
Deluan Quintão 2026-07-14 07:20:17 -04:00 committed by GitHub
parent feda8de7e9
commit 9ae252c418
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 80 additions and 9 deletions

View File

@ -28,7 +28,11 @@ import {
import AlbumListActions from './AlbumListActions'
import AlbumTableView from './AlbumTableView'
import AlbumGridView from './AlbumGridView'
import albumLists, { defaultAlbumList } from './albumLists'
import albumLists from './albumLists'
import {
getStoredDefaultView,
isResourceDefaultView,
} from '../personal/defaultViews'
import config from '../config'
import AlbumInfo from './AlbumInfo'
import ExpandInfoDialog from '../dialogs/ExpandInfoDialog'
@ -220,8 +224,10 @@ const AlbumList = (props) => {
// If it does not have filter/sort params (usually coming from Menu),
// reload with correct filter/sort params
if (!location.search) {
const type =
albumListType || localStorage.getItem('defaultView') || defaultAlbumList
const type = albumListType || getStoredDefaultView()
if (isResourceDefaultView(type)) {
return <Redirect to={`/${type}`} />
}
const listParams = albumLists[type]
if (type === 'random') {
refresh()

View File

@ -1,13 +1,10 @@
import { SelectInput, useTranslate } from 'react-admin'
import albumLists, { defaultAlbumList } from '../album/albumLists'
import { getDefaultViewChoices, getStoredDefaultView } from './defaultViews'
export const SelectDefaultView = (props) => {
const translate = useTranslate()
const current = localStorage.getItem('defaultView') || defaultAlbumList
const choices = Object.keys(albumLists).map((type) => ({
id: type,
name: translate(`resources.album.lists.${type}`),
}))
const current = getStoredDefaultView()
const choices = getDefaultViewChoices(translate)
return (
<SelectInput

View File

@ -0,0 +1,20 @@
import albumLists, { defaultAlbumList } from '../album/albumLists'
export const resourceDefaultViews = ['artist', 'song', 'playlist']
export const isResourceDefaultView = (defaultView) =>
resourceDefaultViews.includes(defaultView)
export const getDefaultViewChoices = (translate) => [
...Object.keys(albumLists).map((type) => ({
id: type,
name: translate(`resources.album.lists.${type}`),
})),
...resourceDefaultViews.map((resource) => ({
id: resource,
name: translate(`resources.${resource}.name`, { smart_count: 2 }),
})),
]
export const getStoredDefaultView = () =>
localStorage.getItem('defaultView') || defaultAlbumList

View File

@ -0,0 +1,48 @@
import {
getDefaultViewChoices,
getStoredDefaultView,
isResourceDefaultView,
resourceDefaultViews,
} from './defaultViews'
import albumLists, { defaultAlbumList } from '../album/albumLists'
describe('defaultViews', () => {
beforeEach(() => {
localStorage.clear()
})
it('includes album lists and top-level resource lists as choices', () => {
const choices = getDefaultViewChoices((key, options) =>
options?.smart_count ? `${key}:${options.smart_count}` : key,
)
expect(choices.map((choice) => choice.id)).toEqual([
...Object.keys(albumLists),
...resourceDefaultViews,
])
expect(choices).toEqual(
expect.arrayContaining([
{ id: 'artist', name: 'resources.artist.name:2' },
{ id: 'song', name: 'resources.song.name:2' },
{ id: 'playlist', name: 'resources.playlist.name:2' },
]),
)
})
it('identifies resource-backed default views', () => {
expect(isResourceDefaultView('artist')).toBe(true)
expect(isResourceDefaultView('song')).toBe(true)
expect(isResourceDefaultView('playlist')).toBe(true)
expect(isResourceDefaultView('recentlyAdded')).toBe(false)
})
it('falls back to the default album list when no default view is stored', () => {
expect(getStoredDefaultView()).toBe(defaultAlbumList)
})
it('returns the stored default view', () => {
localStorage.setItem('defaultView', 'playlist')
expect(getStoredDefaultView()).toBe('playlist')
})
})