import { h } from 'preact'; import { useEffect, useState } from 'preact/hooks'; import { getMetaStore, getSignalStore } from './lib/stores'; import type { SignalRef, SignalMeta, SignalValue } from './lib/types'; interface Props { signal: SignalRef; onClose: () => void; } function qualityColor(q: string): string { switch (q) { case 'good': return '#4ade80'; case 'uncertain': return '#fbbf24'; case 'bad': return '#f87171'; default: return '#6b7280'; } } function fmt(v: any): string { if (v === null || v === undefined) return '—'; if (typeof v === 'number') return Number.isFinite(v) ? v.toPrecision(6).replace(/\.?0+$/, '') : String(v); if (Array.isArray(v)) return `[${v.slice(0, 8).map((x: any) => fmt(x)).join(', ')}${v.length > 8 ? ', …' : ''}]`; return String(v); } function fmtTs(ts: string | null): string { if (!ts) return '—'; try { return new Date(ts).toLocaleString(); } catch { return ts; } } export default function InfoPanel({ signal, onClose }: Props) { const [meta, setMeta] = useState(null); const [sv, setSv] = useState({ value: null, quality: 'unknown', ts: null }); useEffect(() => { const unsubM = getMetaStore(signal).subscribe(setMeta); const unsubV = getSignalStore(signal).subscribe(setSv); return () => { unsubM(); unsubV(); }; }, [signal.ds, signal.name]); return (
Signal Info
Datasource{signal.ds}
Name{signal.name}
Value {fmt(sv.value)}{meta?.unit ? ` ${meta.unit}` : ''}
Quality{sv.quality}
Timestamp{fmtTs(sv.ts)}
{meta && (
{meta.unit && } {(meta.displayLow !== 0 || meta.displayHigh !== 0) && ( )}
Type{meta.type}
Unit{meta.unit}
Writable{meta.writable ? 'Yes' : 'No'}
Display range {meta.displayLow} … {meta.displayHigh}
{meta.tags && meta.tags.length > 0 && (
Tags
{meta.tags.map(t => ( {t} ))}
)} {meta.properties && Object.keys(meta.properties).length > 0 && (
Properties
{Object.entries(meta.properties).map(([k, v]) => ( ))}
{k} {v}
)} {meta.enumStrings && meta.enumStrings.length > 0 && (
States
{meta.enumStrings.map((s, i) => ( ))}
{i} {s}
)} {meta.description && (
Description
{meta.description}
)}
)}
); }