Enhance channel management with apply report feature
Added functionality to display a consolidated apply report for warnings after applying channel templates, improving user experience by reducing clutter from individual warning notifications. Updated the ChannelDetail component to manage the new report state and integrated the ApplyReportDialog for displaying the report. Refactored the Problems component to utilize a new PlanningWarnings component for better organization of warning messages. Localization strings were updated to include new report-related texts in both English and Russian.
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import { useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import type { PlanningWarningDto } from '@/shared/api/types'
|
||||
|
||||
/** Сколько строк одного вида показываем целиком: дальше это уже не чтение, а простыня. */
|
||||
const DETAILS_LIMIT = 20
|
||||
|
||||
/**
|
||||
* Предупреждения планировщика, сгруппированные по виду: десять однотипных строк — это одна
|
||||
* проблема, и читать их надо вместе, а не по одной.
|
||||
*/
|
||||
export function PlanningWarnings({ warnings }: Readonly<{ warnings: PlanningWarningDto[] }>) {
|
||||
const { t } = useTranslation()
|
||||
// Ключ строки — «вид + порядковый номер внутри вида»: у предупреждения нет своего id, а текст
|
||||
// повторяется (одна и та же причина на разных слотах), и позиция здесь — единственное, что его
|
||||
// отличает. Считаем ключ при группировке, чтобы список не пересобирался на каждый рендер.
|
||||
const grouped = useMemo(() => {
|
||||
const map = new Map<string, { key: string; text: string }[]>()
|
||||
for (const warning of warnings) {
|
||||
const list = map.get(warning.kind) ?? []
|
||||
list.push({ key: `${warning.kind}#${list.length}`, text: warning.details })
|
||||
map.set(warning.kind, list)
|
||||
}
|
||||
return [...map.entries()]
|
||||
}, [warnings])
|
||||
|
||||
if (grouped.length === 0)
|
||||
return <p className="text-sm text-muted-foreground">{t('admin.channels.noProblems')}</p>
|
||||
|
||||
return (
|
||||
<ul className="flex flex-col gap-2 text-xs">
|
||||
{grouped.map(([kind, details]) => (
|
||||
<li key={kind} className="flex flex-col gap-0.5">
|
||||
<span className="font-medium text-amber-500">
|
||||
{t(`admin.channels.warnings.${kind}`)} · {details.length}
|
||||
</span>
|
||||
{details.slice(0, DETAILS_LIMIT).map((detail) => (
|
||||
<span key={detail.key} className="text-muted-foreground">
|
||||
{detail.text}
|
||||
</span>
|
||||
))}
|
||||
{details.length > DETAILS_LIMIT && (
|
||||
<span className="text-muted-foreground">
|
||||
{t('admin.channels.andMore', { count: details.length - DETAILS_LIMIT })}
|
||||
</span>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user