use multiselect for navidrome song tag filters

This commit is contained in:
jeffvli
2025-12-28 01:26:36 -08:00
parent 18a864a049
commit 7f52b31b40
@@ -2,10 +2,7 @@ import { useSuspenseQuery } from '@tanstack/react-query';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { import { MultiSelectWithInvalidData } from '/@/renderer/components/select-with-invalid-data';
MultiSelectWithInvalidData,
SelectWithInvalidData,
} from '/@/renderer/components/select-with-invalid-data';
import { useListContext } from '/@/renderer/context/list-context'; import { useListContext } from '/@/renderer/context/list-context';
import { useGenreList } from '/@/renderer/features/genres/api/genres-api'; import { useGenreList } from '/@/renderer/features/genres/api/genres-api';
import { sharedQueries } from '/@/renderer/features/shared/api/shared-api'; import { sharedQueries } from '/@/renderer/features/shared/api/shared-api';
@@ -114,10 +111,10 @@ export const NavidromeSongFilters = () => {
interface TagFilterItemProps { interface TagFilterItemProps {
label: string; label: string;
onChange: (value: null | string) => void; onChange: (value: null | string[]) => void;
options: Array<{ id: string; name: string }>; options: Array<{ id: string; name: string }>;
tagValue: string; tagValue: string;
value: string | undefined; value: string | string[] | undefined;
} }
const TagFilterItem = ({ label, onChange, options, tagValue, value }: TagFilterItemProps) => { const TagFilterItem = ({ label, onChange, options, tagValue, value }: TagFilterItemProps) => {
@@ -130,15 +127,20 @@ const TagFilterItem = ({ label, onChange, options, tagValue, value }: TagFilterI
[options], [options],
); );
const defaultValue = useMemo(() => {
if (!value) return [];
return Array.isArray(value) ? value : [value];
}, [value]);
return ( return (
<SelectWithInvalidData <MultiSelectWithInvalidData
clearable clearable
data={selectData} data={selectData}
defaultValue={value} defaultValue={defaultValue}
key={tagValue} key={tagValue}
label={label} label={label}
limit={100} limit={100}
onChange={onChange} onChange={(e) => (e && e.length > 0 ? onChange(e) : onChange(null))}
searchable searchable
/> />
); );
@@ -159,7 +161,7 @@ const TagFilters = () => {
); );
const handleTagFilter = useMemo( const handleTagFilter = useMemo(
() => (tag: string, e: null | string) => { () => (tag: string, e: null | string[]) => {
setCustom({ [tag]: e }); setCustom({ [tag]: e });
}, },
[setCustom], [setCustom],
@@ -191,7 +193,7 @@ const TagFilters = () => {
onChange={(e) => handleTagFilter(tag.value, e)} onChange={(e) => handleTagFilter(tag.value, e)}
options={tag.options} options={tag.options}
tagValue={tag.value} tagValue={tag.value}
value={query._custom?.[tag.value] as string | undefined} value={query._custom?.[tag.value] as string | string[] | undefined}
/> />
))} ))}
</> </>