Introduced a new endpoint for bulk filling collection posters, allowing for automatic assignment of posters to collections without existing images. Updated the DeleteShowCommand to include an option for cutting shows from future airings, enhancing the deletion process. Refactored related components and API calls to support these features, ensuring a seamless user experience. Additionally, updated localization strings to reflect the new functionalities and adjusted tests to verify correct behavior.
158 lines
6.1 KiB
TypeScript
158 lines
6.1 KiB
TypeScript
import { apiRequest } from '@/shared/api/client'
|
|
import type {
|
|
CreatedIdResponse,
|
|
EnrichShowsResult,
|
|
MetadataCandidate,
|
|
MissingEpisodesReport,
|
|
MissingSeasonsReport,
|
|
ShowAudience,
|
|
ShowDto,
|
|
ShowKind,
|
|
ShowSummaryDto,
|
|
ShowUsageDto,
|
|
} from '@/shared/api/types'
|
|
|
|
export function listShows(genreId?: string) {
|
|
const query = genreId ? `?${new URLSearchParams({ genreId }).toString()}` : ''
|
|
return apiRequest<ShowSummaryDto[]>(`/admin/shows${query}`)
|
|
}
|
|
|
|
export function getShow(id: string) {
|
|
return apiRequest<ShowDto>(`/admin/shows/${id}`)
|
|
}
|
|
|
|
export function createShow(body: {
|
|
name: string
|
|
kind: ShowKind
|
|
description?: string
|
|
originalName?: string
|
|
audience?: ShowAudience | null
|
|
}) {
|
|
return apiRequest<CreatedIdResponse>('/admin/shows', { method: 'POST', body })
|
|
}
|
|
|
|
/** `null` — снять проставленный рейтинг. */
|
|
export function setShowAudience(id: string, audience: ShowAudience | null) {
|
|
return apiRequest<void>(`/admin/shows/${id}/audience`, { method: 'PUT', body: { audience } })
|
|
}
|
|
|
|
/** Полностью заменяет набор жанров шоу; основной — primaryGenreId (иначе первый в списке). */
|
|
export function setShowGenres(id: string, genreIds: string[], primaryGenreId: string | null) {
|
|
return apiRequest<void>(`/admin/shows/${id}/genres`, {
|
|
method: 'PUT',
|
|
body: { genreIds, primaryGenreId },
|
|
})
|
|
}
|
|
|
|
export function renameShow(id: string, name: string) {
|
|
return apiRequest<void>(`/admin/shows/${id}/name`, { method: 'PUT', body: { name } })
|
|
}
|
|
|
|
export function setShowOriginalName(id: string, originalName: string | null) {
|
|
return apiRequest<void>(`/admin/shows/${id}/original-name`, {
|
|
method: 'PUT',
|
|
body: { originalName },
|
|
})
|
|
}
|
|
|
|
/** Массовая разметка отмеченных шоу: жанры и рейтинг применяются независимо. */
|
|
export function bulkTagShows(body: {
|
|
showIds: string[]
|
|
genreIds?: string[]
|
|
replaceGenres?: boolean
|
|
audience?: ShowAudience | null
|
|
setAudience?: boolean
|
|
}) {
|
|
return apiRequest<{ updated: number }>('/admin/shows/bulk/tag', { method: 'POST', body })
|
|
}
|
|
|
|
/** Массовое обогащение: найти метаданные по названию и применить тем, у кого нет привязки. */
|
|
export function bulkEnrichShows(showIds: string[], provider: string) {
|
|
return apiRequest<EnrichShowsResult>('/admin/shows/bulk/enrich', {
|
|
method: 'POST',
|
|
body: { showIds, provider },
|
|
})
|
|
}
|
|
|
|
/** Где шоу задействовано: группы, коллекции, каналы. */
|
|
export function getShowUsage(id: string) {
|
|
return apiRequest<ShowUsageDto>(`/admin/shows/${id}/usage`)
|
|
}
|
|
|
|
/**
|
|
* `withMedia` — снести заодно файлы шоу: иначе они переживут его осиротевшими.
|
|
* `withSchedule` — вырезать шоу из будущего эфира вместо отказа.
|
|
*/
|
|
export function deleteShow(id: string, withMedia = false, withSchedule = false) {
|
|
const query = new URLSearchParams()
|
|
if (withMedia) query.set('withMedia', 'true')
|
|
if (withSchedule) query.set('withSchedule', 'true')
|
|
const suffix = query.size > 0 ? `?${query.toString()}` : ''
|
|
|
|
return apiRequest<void>(`/admin/shows/${id}${suffix}`, { method: 'DELETE' })
|
|
}
|
|
|
|
export function addEpisode(showId: string, mediaAssetId: string) {
|
|
return apiRequest<CreatedIdResponse>(`/admin/shows/${showId}/episodes`, {
|
|
method: 'POST',
|
|
body: { mediaAssetId },
|
|
})
|
|
}
|
|
|
|
export function removeEpisode(showId: string, episodeId: string) {
|
|
return apiRequest<void>(`/admin/shows/${showId}/episodes/${episodeId}`, { method: 'DELETE' })
|
|
}
|
|
|
|
// ── Метаданные ────────────────────────────────────────────────────────────
|
|
|
|
export function getMetadataProviders() {
|
|
return apiRequest<string[]>('/admin/metadata/providers')
|
|
}
|
|
|
|
/** `kind` определяет, среди чего искать: у TMDb сериалы и фильмы — разные пространства id. */
|
|
export function searchMetadata(provider: string, query: string, kind: ShowKind) {
|
|
const q = new URLSearchParams({ provider, query, kind })
|
|
return apiRequest<MetadataCandidate[]>(`/admin/metadata/search?${q.toString()}`)
|
|
}
|
|
|
|
export function applyMetadata(showId: string, provider: string, externalId: string) {
|
|
return apiRequest<void>(`/admin/metadata/shows/${showId}/apply`, {
|
|
method: 'POST',
|
|
body: { provider, externalId },
|
|
})
|
|
}
|
|
|
|
export function updateMetadata(
|
|
showId: string,
|
|
body: { description: string | null; year: number | null },
|
|
) {
|
|
return apiRequest<void>(`/admin/metadata/shows/${showId}`, { method: 'PUT', body })
|
|
}
|
|
|
|
export function clearMetadata(showId: string) {
|
|
return apiRequest<void>(`/admin/metadata/shows/${showId}`, { method: 'DELETE' })
|
|
}
|
|
|
|
/** Привязать/снять постер шоу по ссылке на изображение из реестра (null — отвязать). */
|
|
export function setShowPoster(showId: string, imageId: string | null) {
|
|
return apiRequest<void>(`/admin/metadata/shows/${showId}/poster-image`, {
|
|
method: 'PUT',
|
|
body: { imageId },
|
|
})
|
|
}
|
|
|
|
/** Довыгрузить метаданные серий из привязанного источника. Возвращает число обновлённых. */
|
|
export function refreshEpisodesMetadata(showId: string) {
|
|
return apiRequest<number>(`/admin/metadata/shows/${showId}/refresh-episodes`, { method: 'POST' })
|
|
}
|
|
|
|
/** Отчёт: каких серий не хватает в загруженных сезонах (по данным источника). */
|
|
export function findMissingEpisodes(showId: string) {
|
|
return apiRequest<MissingEpisodesReport>(`/admin/metadata/shows/${showId}/missing-episodes`)
|
|
}
|
|
|
|
/** Отчёт: каких сезонов нет в библиотеке вовсе (по данным источника). */
|
|
export function findMissingSeasons(showId: string) {
|
|
return apiRequest<MissingSeasonsReport>(`/admin/metadata/shows/${showId}/missing-seasons`)
|
|
}
|