Add reset template functionality to channel management
Implemented a new endpoint for resetting the channel template, which clears the grid and removes future scheduled entries while preserving past and current recordings. Updated the frontend to include a reset button in the channel management interface, along with corresponding localization strings in English and Russian. Enhanced integration tests to verify the reset functionality, ensuring that the expected number of slots, layers, and entries are accurately reported after the reset operation.
This commit is contained in:
@@ -16,6 +16,7 @@ import type {
|
||||
GridProfileKind,
|
||||
LayerApplicability,
|
||||
PlanningRules,
|
||||
ResetTemplateResultDto,
|
||||
RestoreTemplateResultDto,
|
||||
ScheduleDiffDto,
|
||||
ScheduleEntryDto,
|
||||
@@ -89,6 +90,16 @@ export function restoreChannelTemplate(channelId: string) {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Полный сброс: снимает сетку и удаляет будущий эфир, собранный по ней. Прошлое и идущая сейчас
|
||||
* запись остаются — их нельзя вырезать из-под зрителя.
|
||||
*/
|
||||
export function resetChannelTemplate(channelId: string) {
|
||||
return apiRequest<ResetTemplateResultDto>(`/admin/channels/${channelId}/template/reset`, {
|
||||
method: 'POST',
|
||||
})
|
||||
}
|
||||
|
||||
/** Проверки сетки по правилам — считаются по шаблону, без прогона генератора. */
|
||||
export function getTemplateIssues(channelId: string) {
|
||||
return apiRequest<TemplateIssueDto[]>(`/admin/channels/${channelId}/template/issues`)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useMutation, useQuery } from '@tanstack/react-query'
|
||||
import { FileJson, Plus, Wand2 } from 'lucide-react'
|
||||
import { Eraser, FileJson, Plus, Wand2 } from 'lucide-react'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { HttpError } from '@/shared/api/client'
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
createSlot,
|
||||
deleteLayer,
|
||||
listChannels,
|
||||
resetChannelTemplate,
|
||||
toSlotBody,
|
||||
updateLayer,
|
||||
updateSlot,
|
||||
@@ -142,6 +143,28 @@ export function GridTab({
|
||||
onError,
|
||||
})
|
||||
|
||||
/**
|
||||
* Сброс сетки и собранного по ней эфира. Прошлое остаётся, поэтому «полностью» здесь — про
|
||||
* будущее: то, что уже показано зрителю, не переписывается.
|
||||
*/
|
||||
const resetMutation = useMutation({
|
||||
mutationFn: () => resetChannelTemplate(channelId),
|
||||
onSuccess: (result) => {
|
||||
toast.success(
|
||||
t('admin.channels.resetDone', {
|
||||
slots: result.slots,
|
||||
layers: result.layers,
|
||||
entries: result.entries,
|
||||
}),
|
||||
)
|
||||
// Пустая сетка отдаёт эфир аварийной группе целиком: без предупреждения админ решит, что
|
||||
// сброс не сработал, увидев в предпросмотре те же шоу через минуту после него.
|
||||
if (template?.fallbackGroupId) toast.message(t('admin.channels.resetHint'))
|
||||
onChanged()
|
||||
},
|
||||
onError,
|
||||
})
|
||||
|
||||
const moveSlotMutation = useMutation({
|
||||
mutationFn: ({
|
||||
slot,
|
||||
@@ -316,6 +339,20 @@ export function GridTab({
|
||||
<FileJson className="h-4 w-4" />
|
||||
{t('admin.channels.transfer.action')}
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="text-red-500 hover:text-red-400"
|
||||
disabled={resetMutation.isPending}
|
||||
onClick={() => {
|
||||
// Сетку и хвост эфира назад не вернёшь — спрашиваем, как и перед заменой сетки.
|
||||
if (!window.confirm(t('admin.channels.resetConfirm'))) return
|
||||
resetMutation.mutate()
|
||||
}}
|
||||
>
|
||||
<Eraser className="h-4 w-4" />
|
||||
{t('admin.channels.reset')}
|
||||
</Button>
|
||||
<span className="text-muted-foreground">{t('admin.channels.showForDate')}</span>
|
||||
<Input
|
||||
type="date"
|
||||
|
||||
Reference in New Issue
Block a user