Major changes: logic add to panel, local variables, panel histor, users management...
This commit is contained in:
+51
-8
@@ -1,5 +1,7 @@
|
||||
import { h } from 'preact';
|
||||
import { useState } from 'preact/hooks';
|
||||
import { useState, useEffect } from 'preact/hooks';
|
||||
import { initLocalState } from './lib/localstate';
|
||||
import { logicEngine } from './lib/logic';
|
||||
import type { Interface, Widget, SignalRef } from './lib/types';
|
||||
import TextView from './widgets/TextView';
|
||||
import TextLabel from './widgets/TextLabel';
|
||||
@@ -15,6 +17,7 @@ import ImageWidget from './widgets/ImageWidget';
|
||||
import LinkWidget from './widgets/LinkWidget';
|
||||
import ContextMenu from './ContextMenu';
|
||||
import InfoPanel from './InfoPanel';
|
||||
import SplitLayout from './SplitLayout';
|
||||
|
||||
const COMPONENTS: Record<string, any> = {
|
||||
textview: TextView,
|
||||
@@ -42,15 +45,25 @@ interface Props {
|
||||
iface: Interface | null;
|
||||
onNavigate?: (interfaceId: string) => void;
|
||||
timeRange?: { start: string; end: string } | null;
|
||||
onPlot?: (signal: SignalRef) => void;
|
||||
}
|
||||
|
||||
export default function Canvas({ iface, onNavigate, timeRange, onPlot }: Props) {
|
||||
export default function Canvas({ iface, onNavigate, timeRange }: Props) {
|
||||
const [ctxMenu, setCtxMenu] = useState<CtxState>({
|
||||
visible: false, x: 0, y: 0, signal: null,
|
||||
});
|
||||
const [infoSignal, setInfoSignal] = useState<SignalRef | null>(null);
|
||||
|
||||
// Instantiate this panel's local state variables from their initial values.
|
||||
useEffect(() => {
|
||||
initLocalState(iface?.statevars);
|
||||
}, [iface?.id, iface?.statevars]);
|
||||
|
||||
// Activate panel logic for the live view; tear it down on unmount/panel switch.
|
||||
useEffect(() => {
|
||||
logicEngine.load(iface?.logic);
|
||||
return () => logicEngine.clear();
|
||||
}, [iface?.id, iface?.logic]);
|
||||
|
||||
function onCtxMenu(e: MouseEvent, widget: Widget) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@@ -65,10 +78,6 @@ export default function Canvas({ iface, onNavigate, timeRange, onPlot }: Props)
|
||||
if (ctxMenu.signal) setInfoSignal(ctxMenu.signal);
|
||||
}
|
||||
|
||||
function handlePlot() {
|
||||
if (ctxMenu.signal && onPlot) onPlot(ctxMenu.signal);
|
||||
}
|
||||
|
||||
if (!iface) {
|
||||
return (
|
||||
<div class="canvas-container">
|
||||
@@ -79,6 +88,41 @@ export default function Canvas({ iface, onNavigate, timeRange, onPlot }: Props)
|
||||
);
|
||||
}
|
||||
|
||||
// Plot panel: plots fill the viewport arranged in a recursive split layout.
|
||||
if (iface.kind === 'plot' && iface.layout) {
|
||||
const byId = new Map(iface.widgets.map(w => [w.id, w]));
|
||||
return (
|
||||
<div class="canvas-container">
|
||||
<div class="plot-panel-view">
|
||||
<SplitLayout
|
||||
layout={iface.layout}
|
||||
renderLeaf={(wid) => {
|
||||
const widget = byId.get(wid);
|
||||
if (!widget) return <div class="plot-pane-empty">missing plot</div>;
|
||||
return (
|
||||
<PlotWidget
|
||||
widget={widget}
|
||||
onContextMenu={(e: MouseEvent) => onCtxMenu(e, widget)}
|
||||
timeRange={timeRange}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ContextMenu
|
||||
{...ctxMenu}
|
||||
onClose={closeCtxMenu}
|
||||
onInfo={handleInfo}
|
||||
/>
|
||||
|
||||
{infoSignal && (
|
||||
<InfoPanel signal={infoSignal} onClose={() => setInfoSignal(null)} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="canvas-container">
|
||||
<div class="canvas-area" style={`width:${iface.w}px;height:${iface.h}px;`}>
|
||||
@@ -110,7 +154,6 @@ export default function Canvas({ iface, onNavigate, timeRange, onPlot }: Props)
|
||||
{...ctxMenu}
|
||||
onClose={closeCtxMenu}
|
||||
onInfo={handleInfo}
|
||||
onPlot={onPlot ? handlePlot : undefined}
|
||||
/>
|
||||
|
||||
{infoSignal && (
|
||||
|
||||
Reference in New Issue
Block a user