Refactor ChannelDetail component to improve template copying functionality and update translations. Change variable names for clarity, ensuring the source channel is correctly referenced when copying templates. Enhance user confirmation prompts and update related UI elements for better user experience.
build / backend (push) Successful in 1m10s
build / frontend (push) Successful in 34s
tests / backend-tests (push) Successful in 3m42s

This commit is contained in:
Leonid Pershin
2026-07-26 20:17:45 +03:00
parent 9c865e1faa
commit f36dbfa9cb
3 changed files with 337 additions and 321 deletions
@@ -58,7 +58,7 @@ export function ChannelDetail({ channelId }: { channelId: string }) {
const [copyTargets, setCopyTargets] = useState<number[]>([])
const [applyOpen, setApplyOpen] = useState(false)
const [traceEntryId, setTraceEntryId] = useState<string | null>(null)
const [copyToChannel, setCopyToChannel] = useState('')
const [copyFromChannel, setCopyFromChannel] = useState('')
const [tab, setTab] = useState<ChannelTab>('settings')
const { data: channel, isLoading } = useQuery({
@@ -163,9 +163,9 @@ export function ChannelDetail({ channelId }: { channelId: string }) {
})
const copyTemplateMutation = useMutation({
mutationFn: (targetChannelId: string) => copyTemplateTo(channelId, targetChannelId),
mutationFn: (sourceChannelId: string) => copyTemplateTo(sourceChannelId, channelId),
onSuccess: (result) => {
setCopyToChannel('')
setCopyFromChannel('')
toast.success(
t('admin.channels.templateCopied', { layers: result.layers, slots: result.slots }),
)
@@ -345,10 +345,10 @@ export function ChannelDetail({ channelId }: { channelId: string }) {
</span>
<select
className="h-8 rounded-md border border-border bg-transparent px-2 text-sm"
value={copyToChannel}
onChange={(e) => setCopyToChannel(e.target.value)}
value={copyFromChannel}
onChange={(e) => setCopyFromChannel(e.target.value)}
>
<option value="">{t('admin.channels.pickTargetChannel')}</option>
<option value="">{t('admin.channels.pickSourceChannel')}</option>
{(channels ?? [])
.filter((c) => c.id !== channelId)
.map((c) => (
@@ -360,10 +360,14 @@ export function ChannelDetail({ channelId }: { channelId: string }) {
<Button
size="sm"
variant="outline"
disabled={!copyToChannel || copyTemplateMutation.isPending}
onClick={() => copyTemplateMutation.mutate(copyToChannel)}
disabled={!copyFromChannel || copyTemplateMutation.isPending}
onClick={() => {
// Замена своей сетки — необратимая правка, поэтому спрашиваем перед ней.
if (!window.confirm(t('admin.channels.copyTemplateConfirm'))) return
copyTemplateMutation.mutate(copyFromChannel)
}}
>
{t('admin.channels.copy')}
{t('admin.channels.copyHere')}
</Button>
<p className="text-xs text-muted-foreground">
{t('admin.channels.copyTemplateHint')}
+12 -6
View File
@@ -470,10 +470,13 @@ const resources = {
diffSummary: 'Затронет {{total}} записей, изменятся {{changed}}',
diffSoon: 'В ближайшие сутки изменится записей: {{count}}',
diffNoChanges: 'Эфир не изменится',
copyTemplate: 'Копировать сетку',
pickTargetChannel: 'Выберите канал',
copyTemplate: 'Скопировать сетку с канала',
pickSourceChannel: 'Выберите канал-источник',
copyHere: 'Скопировать сюда',
copyTemplateHint:
'Слои, слоты, стыки и правила уедут на выбранный канал, его прежняя сетка заменится. Группы общие и не копируются.',
'Слои, слоты, стыки и правила выбранного канала заменят сетку этого канала. Группы общие и не копируются.',
copyTemplateConfirm:
'Текущая сетка этого канала будет заменена сеткой выбранного канала. Продолжить?',
templateCopied: 'Скопировано: слоёв {{layers}}, слотов {{slots}}',
copyDroppedBumpers: 'Врезок без блока заставки: {{count}} — донастройте руками',
postChecks: 'Пост-проверки',
@@ -1174,10 +1177,13 @@ const resources = {
diffSummary: 'Affects {{total}} entries, {{changed}} will change',
diffSoon: 'Entries changing within 24 hours: {{count}}',
diffNoChanges: 'The air will not change',
copyTemplate: 'Copy grid',
pickTargetChannel: 'Pick a channel',
copyTemplate: 'Copy a grid from a channel',
pickSourceChannel: 'Pick the source channel',
copyHere: 'Copy here',
copyTemplateHint:
'Layers, slots, junctions and rules move to the chosen channel, replacing its grid. Groups are shared and not copied.',
'Layers, slots, junctions and rules of the chosen channel replace this channel grid. Groups are shared and not copied.',
copyTemplateConfirm:
'This channel grid will be replaced with the chosen channel grid. Continue?',
templateCopied: 'Copied: {{layers}} layers, {{slots}} slots',
copyDroppedBumpers: 'Breaks left without a bumper block: {{count}} — set them up by hand',
postChecks: 'Post-checks',