working epics ioc and tested
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
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<SignalMeta | null>(null);
|
||||
const [sv, setSv] = useState<SignalValue>({ 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 (
|
||||
<div class="info-panel">
|
||||
<div class="info-panel-header">
|
||||
<span class="info-panel-title">Signal Info</span>
|
||||
<button class="info-panel-close" onClick={onClose} title="Close">✕</button>
|
||||
</div>
|
||||
<div class="info-panel-body">
|
||||
<table class="info-table">
|
||||
<tbody>
|
||||
<tr><td class="info-key">Datasource</td><td class="info-val info-mono">{signal.ds}</td></tr>
|
||||
<tr><td class="info-key">Name</td><td class="info-val info-mono">{signal.name}</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="info-sep" />
|
||||
|
||||
<table class="info-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="info-key">Value</td>
|
||||
<td class="info-val">
|
||||
<span
|
||||
class="quality-dot"
|
||||
style={`background:${qualityColor(sv.quality)};display:inline-block;margin-right:5px;vertical-align:middle;`}
|
||||
/>
|
||||
{fmt(sv.value)}{meta?.unit ? ` ${meta.unit}` : ''}
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td class="info-key">Quality</td><td class="info-val">{sv.quality}</td></tr>
|
||||
<tr><td class="info-key">Timestamp</td><td class="info-val">{fmtTs(sv.ts)}</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{meta && (
|
||||
<div>
|
||||
<div class="info-sep" />
|
||||
<table class="info-table">
|
||||
<tbody>
|
||||
<tr><td class="info-key">Type</td><td class="info-val">{meta.type}</td></tr>
|
||||
{meta.unit && <tr><td class="info-key">Unit</td><td class="info-val">{meta.unit}</td></tr>}
|
||||
<tr><td class="info-key">Writable</td><td class="info-val">{meta.writable ? 'Yes' : 'No'}</td></tr>
|
||||
{(meta.displayLow !== 0 || meta.displayHigh !== 0) && (
|
||||
<tr>
|
||||
<td class="info-key">Display range</td>
|
||||
<td class="info-val">{meta.displayLow} … {meta.displayHigh}</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{meta.enumStrings && meta.enumStrings.length > 0 && (
|
||||
<div>
|
||||
<div class="info-sep" />
|
||||
<div class="info-section-hdr">States</div>
|
||||
<table class="info-table">
|
||||
<tbody>
|
||||
{meta.enumStrings.map((s, i) => (
|
||||
<tr key={i}>
|
||||
<td class="info-key">{i}</td>
|
||||
<td class="info-val info-mono">{s}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{meta.description && (
|
||||
<div>
|
||||
<div class="info-sep" />
|
||||
<div class="info-section-hdr">Description</div>
|
||||
<div class="info-desc">{meta.description}</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user