import { ChevronLeft, Database, ExternalLink, Search, X } from 'lucide-react'; import { useEffect, useMemo, useState } from 'react'; import { createPortal } from 'react-dom'; import type { OverviewDrillPayload } from '../model'; import { SortableColumnHeader, sortBy, toggleSort, type SortDirection } from '../../components/SortableColumnHeader'; interface OverviewDrillDialogProps { payload: OverviewDrillPayload | null; onClose: () => void; onPrimaryAction?: () => void; onGroupByChange?: (groupBy: 'station' | 'customer' | 'vehicle') => void; onRowSelect?: (row: Record) => void; } const TONE_CLASS = { default: 'text-slate-900', blue: 'text-sky-600', green: 'text-emerald-600', amber: 'text-amber-600', red: 'text-rose-600', } as const; export function OverviewDrillDialog({ payload, onClose, onPrimaryAction, onGroupByChange, onRowSelect }: OverviewDrillDialogProps) { const [sortKey, setSortKey] = useState(''); const [sortDirection, setSortDirection] = useState('desc'); useEffect(() => { if (!payload) return; const previousOverflow = document.body.style.overflow; document.body.style.overflow = 'hidden'; const onKeyDown = (event: KeyboardEvent) => { if (event.key === 'Escape') onClose(); }; document.addEventListener('keydown', onKeyDown); return () => { document.body.style.overflow = previousOverflow; document.removeEventListener('keydown', onKeyDown); }; }, [onClose, payload]); useEffect(() => { if (!payload?.columns.length) return; setSortKey(payload.columns[0].key); setSortDirection('desc'); }, [payload]); const sortedRows = useMemo( () => payload ? sortBy(payload.rows, sortKey, sortDirection, (row, key) => row[key]) : [], [payload, sortDirection, sortKey], ); const changeSort = (nextKey: string) => { const next = toggleSort(sortKey, sortDirection, nextKey); setSortKey(next.key); setSortDirection(next.direction); }; if (!payload || typeof document === 'undefined') return null; return createPortal(
{ if (event.target === event.currentTarget) onClose(); }} role="presentation" >

{payload.title}

{payload.subtitle}

{payload.metrics.map(metric => (
{metric.label}
{metric.value}
))}
{payload.groupByOptions?.length && onGroupByChange ? (
汇总维度
{payload.groupByOptions.map(groupBy => ( ))}
) : null} {payload.columns.length > 0 && payload.rows.length > 0 ? (
{payload.columns.map(column => ( ))} {sortedRows.map((row, rowIndex) => ( onRowSelect?.(row)} title={onRowSelect && payload.rowActionLabel ? payload.rowActionLabel : undefined} > {payload.columns.map(column => ( ))} ))}
{row[column.key]}
) : (
真实明细尚未接入当前总览接口

{payload.emptyMessage}

)} {payload.primaryActionLabel && onPrimaryAction ? (
) : null}
, document.body, ); }