Files
factorio-signal-exporter/web/components/ChartCard/TableViz.tsx

83 lines
3.1 KiB
TypeScript

import { useState, useEffect } from 'react';
import { CardShell } from './CardShell';
import type { ColorMap } from '@/lib/colors';
import type { ChartConfig, SignalRow } from '@/lib/types';
import { getColorMap, getItemColor } from '@/lib/colors';
import { useApp } from '@/lib/context';
import { formatSI } from '@/lib/formatNumber';
import { resolveName } from '@/lib/localization';
interface Props {
config: ChartConfig;
rows: SignalRow[];
onEdit: () => void;
onDelete: () => void;
}
export default function TableViz({ config, rows, onEdit, onDelete }: Props) {
const { localeMap } = useApp();
const [colorMap, setColorMap] = useState<ColorMap>(new Map());
useEffect(() => {
getColorMap().then(setColorMap);
}, []);
const latest = new Map<string, { green?: number; red?: number }>();
for (const row of rows) {
latest.set(`${row.combinator}::${row.item_key}`, { green: row.green, red: row.red });
}
const tableRows = [...latest.entries()].slice(0, config.series_limit);
return (
<CardShell title={config.title} onEdit={onEdit} onDelete={onDelete} empty={rows.length === 0}>
<div className="flex-1 overflow-y-auto">
<table className="w-full text-xs text-gray-300">
<thead className="sticky top-0 bg-gray-800">
<tr>
<th className="text-left px-2 py-1">Item</th>
<th className="text-left px-2 py-1">Combinator</th>
{config.signal_type !== 'red' && (
<th className="text-right px-2 py-1 text-green-400">Green</th>
)}
{config.signal_type !== 'green' && (
<th className="text-right px-2 py-1 text-red-400">Red (NP)</th>
)}
</tr>
</thead>
<tbody>
{tableRows.map(([key, vals]) => {
const [combinator, item_key] = key.split('::');
return (
<tr key={key} className="border-t border-gray-800 hover:bg-gray-800/50">
<td className="px-2 py-0.5 flex items-center gap-1.5">
<span
className="inline-block w-2 h-2 rounded-full shrink-0"
style={{ backgroundColor: getItemColor(item_key, colorMap) }}
/>
{resolveName(item_key, localeMap)}
</td>
<td className="px-2 py-0.5 text-gray-500">{combinator}</td>
{config.signal_type !== 'red' && (
<td
className={`px-2 py-0.5 text-right font-mono ${(vals.green ?? 0) < 0 ? 'text-red-400' : 'text-green-400'}`}
>
{vals.green != null ? formatSI(vals.green, undefined, 0) : '--'}
</td>
)}
{config.signal_type !== 'green' && (
<td className="px-2 py-0.5 text-right font-mono text-orange-400">
{vals.red != null ? formatSI(vals.red, undefined, 0) : '--'}
</td>
)}
</tr>
);
})}
</tbody>
</table>
</div>
</CardShell>
);
}