import { useMemo, useState } from 'react' import { ListTodo, SearchIcon } from 'lucide-react' import { DataGridMutedCell, DataGridNameCell } from '@/components/data-grid-cell' import { StatusBadge } from '@/components/status-badge' import { DataGridColumnHeader } from '@/components/reui/data-grid/data-grid-column-header' import type { FilterField, FilterQuery } from '@/components/reui/filters/filters-types' import { ResourcePage, createTextFilterQuery, type DataGridColumnDef, } from '@/components/reui-kit' import { Badge } from '@/components/reui/badge' import { isRefreshJobKind, jobKindRu, jobSubtitleRu, jobTriggerRu } from '@/lib/ui-labels' import type { JobRow } from '@/types/api' const FAILED_STATUSES = ['failed', 'error', 'cancelled'] const filterFields: FilterField[] = [ { id: 'search', label: 'Поиск', icon: , type: 'text', placeholder: 'Поиск задач…', }, ] function tabFilter(item: JobRow, tabId: string): boolean { if (tabId === 'refresh') return isRefreshJobKind(item.kind) if (tabId === 'failed') return FAILED_STATUSES.includes(item.status.toLowerCase()) return true } export function ScheduleJobsGrid({ items, nameById = new Map(), isLoading = false, }: { items: JobRow[] nameById?: Map isLoading?: boolean }) { const [filterQuery, setFilterQuery] = useState(() => createTextFilterQuery('search'), ) const tabs = useMemo( () => [ { id: 'all', label: 'Все', count: items.length }, { id: 'refresh', label: 'Обновление', count: items.filter((job) => isRefreshJobKind(job.kind)).length, }, { id: 'failed', label: 'С ошибкой', count: items.filter((job) => FAILED_STATUSES.includes(job.status.toLowerCase())).length, }, ], [items], ) const columns = useMemo[]>( () => [ { accessorKey: 'kind', header: ({ column }) => , cell: ({ row }) => { const trigger = jobTriggerRu(row.original.meta?.trigger) return ( {jobKindRu(row.original.kind)} {trigger ? ( {trigger} ) : null} } subtitle={jobSubtitleRu(row.original.kind, row.original.meta, nameById)} /> ) }, meta: { headerTitle: 'Вид' }, }, { accessorKey: 'status', header: ({ column }) => , cell: ({ row }) => { const finished = row.original.finished_at const hint = finished ? new Date(finished).toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' }) : undefined return }, meta: { headerTitle: 'Статус' }, }, { id: 'created_at', accessorFn: (row) => row.created_at ?? '', header: ({ column }) => , cell: ({ row }) => ( {row.original.created_at ? new Date(row.original.created_at).toLocaleString('ru-RU') : '—'} ), meta: { headerTitle: 'Создана' }, }, { id: 'finished_at', accessorFn: (row) => row.finished_at ?? '', header: ({ column }) => , cell: ({ row }) => ( {row.original.finished_at ? new Date(row.original.finished_at).toLocaleString('ru-RU') : '—'} ), meta: { headerTitle: 'Завершена' }, }, { accessorKey: 'error', enableSorting: false, header: 'Ошибка', cell: ({ row }) => ( {row.original.error ?? ''} ), meta: { headerTitle: 'Ошибка' }, }, ], [nameById], ) return ( setFilterQuery(createTextFilterQuery('search'))} getFilterFieldValue={(item, field) => { if (field !== 'search') return undefined const subtitle = jobSubtitleRu(item.kind, item.meta, nameById) const trigger = jobTriggerRu(item.meta?.trigger) return `${jobKindRu(item.kind)} ${item.status} ${item.error ?? ''} ${item.job_id} ${subtitle ?? ''} ${trigger ?? ''}` }} columns={columns} data={items} getRowId={(row) => row.job_id} isLoading={isLoading} virtualization={items.length > 80} emptyState={{ title: 'Нет задач в выборке' }} /> ) }