Add kind filter to ShowsPanel and update localization strings
ci / build-backend (push) Successful in 1m40s
ci / build-frontend (push) Successful in 52s
ci / tests (push) Successful in 1m51s
ci / sonar (push) Successful in 4m24s

Introduced a new client-side filter for show types in the ShowsPanel, allowing users to filter shows by their kind. Updated the sorting logic to accommodate this new filter. Additionally, added corresponding localization strings for both English and Russian to support the new filter options. These changes enhance the user experience by providing more granular control over show listings.
This commit is contained in:
Leonid Pershin
2026-07-28 03:33:07 +03:00
parent 05e9919a7b
commit ef5c56f04b
3 changed files with 23 additions and 2 deletions
@@ -41,6 +41,8 @@ export function ShowsPanel() {
// Фильтр по жанру — серверный: в списке видно только основной жанр, а отбирать нужно и по остальным.
const [genreFilter, setGenreFilter] = useState('all')
// Фильтр по типу — клиентский: тип уже приехал в списке, и гонять за ним запрос незачем.
const [kindFilter, setKindFilter] = useState<'all' | ShowKind>('all')
// Отмеченные для массовых действий. Живут отдельно от фильтров: сузил список — выбор не потерялся.
const [selected, setSelected] = useState<string[]>([])
const { data: genres } = useQuery({ queryKey: qk.genres.all, queryFn: listGenres })
@@ -59,7 +61,8 @@ export function ShowsPanel() {
s.name.toLowerCase().includes(q) || (s.originalName ?? '').toLowerCase().includes(q),
)
: all
return sortRows(matched, sort, {
const byKind = kindFilter === 'all' ? matched : matched.filter((s) => s.kind === kindFilter)
return sortRows(byKind, sort, {
name: (s) => s.name.toLowerCase(),
kind: (s) => s.kind,
// Без рейтинга — в начало: пустое значение сортируется раньше любого кода.
@@ -68,7 +71,7 @@ export function ShowsPanel() {
seasons: (s) => s.seasonCount,
episodes: (s) => s.episodeCount,
})
}, [data, query, sort])
}, [data, query, kindFilter, sort])
const totalPages = Math.max(1, Math.ceil(filtered.length / PAGE_SIZE))
const pageItems = filtered.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE)
const invalidate = () => queryClient.invalidateQueries({ queryKey: qk.shows.all })
@@ -171,6 +174,22 @@ export function ShowsPanel() {
setQuery(e.target.value)
}}
/>
<Select
value={kindFilter}
onValueChange={(v) => {
setPage(1)
setKindFilter(v as 'all' | ShowKind)
}}
>
<SelectTrigger className="w-48">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="all">{t('admin.shows.allKinds')}</SelectItem>
<SelectItem value="Series">{t('admin.shows.kinds.Series')}</SelectItem>
<SelectItem value="Single">{t('admin.shows.kinds.Single')}</SelectItem>
</SelectContent>
</Select>
<Select
value={genreFilter}
onValueChange={(v) => {
+1
View File
@@ -411,6 +411,7 @@ export const en = {
loadedSeasons: 'Loaded seasons',
genre: 'Genre',
allGenres: 'All genres',
allKinds: 'All kinds',
otherGenres: 'Other genres',
bulk: {
selected: 'Selected: {{count}}',
+1
View File
@@ -408,6 +408,7 @@ export const ru = {
loadedSeasons: 'Загружены сезоны',
genre: 'Жанр',
allGenres: 'Все жанры',
allKinds: 'Все типы',
otherGenres: 'Остальные жанры',
bulk: {
selected: 'Отмечено: {{count}}',