multichannel support + colormap inherit
This commit is contained in:
@@ -436,6 +436,9 @@ function Flow() {
|
||||
case 'overlay':
|
||||
updateNodeData(msg.data.node_id, { overlay: msg.data.overlay });
|
||||
break;
|
||||
case 'node_warning':
|
||||
updateNodeData(msg.data.node_id, { warning: msg.data.message });
|
||||
break;
|
||||
}
|
||||
});
|
||||
api.initWS();
|
||||
@@ -500,9 +503,36 @@ function Flow() {
|
||||
data: {
|
||||
...n.data,
|
||||
widgetValues: { ...n.data.widgetValues, [name]: value },
|
||||
// Clear warning when user changes a value
|
||||
warning: null,
|
||||
},
|
||||
};
|
||||
}));
|
||||
|
||||
// If this is a filename/name change on a LoadFile/LoadDemo node, fetch channels
|
||||
if ((name === 'filename' || name === 'name') && value) {
|
||||
const node = reactFlow.getNode(nodeId);
|
||||
if (node && (node.data.className === 'LoadFile' || node.data.className === 'LoadDemo')) {
|
||||
api.getChannels(value).then((channels) => {
|
||||
setNodes((prev) => prev.map((n) => {
|
||||
if (n.id !== nodeId) return n;
|
||||
return {
|
||||
...n,
|
||||
data: {
|
||||
...n.data,
|
||||
definition: {
|
||||
...n.data.definition,
|
||||
output: channels.map((c) => c.type),
|
||||
output_name: channels.map((c) => c.name),
|
||||
},
|
||||
},
|
||||
};
|
||||
}));
|
||||
reactFlow.updateNodeInternals(nodeId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
scheduleAutoRun();
|
||||
}, [setNodes]); // scheduleAutoRun is stable (no deps)
|
||||
|
||||
@@ -568,6 +598,27 @@ function Flow() {
|
||||
|
||||
setNodes((ns) => [...ns, newNode]);
|
||||
|
||||
// For LoadFile/LoadDemo, auto-fetch channels for the default value
|
||||
if (className === 'LoadDemo' && widgetValues.name) {
|
||||
api.getChannels(widgetValues.name).then((channels) => {
|
||||
setNodes((prev) => prev.map((n) => {
|
||||
if (n.id !== newNodeId) return n;
|
||||
return {
|
||||
...n,
|
||||
data: {
|
||||
...n.data,
|
||||
definition: {
|
||||
...n.data.definition,
|
||||
output: channels.map((c) => c.type),
|
||||
output_name: channels.map((c) => c.name),
|
||||
},
|
||||
},
|
||||
};
|
||||
}));
|
||||
reactFlow.updateNodeInternals(newNodeId);
|
||||
});
|
||||
}
|
||||
|
||||
// Auto-connect if this was triggered by dropping a connection on blank space
|
||||
if (contextMenu.pendingHandleId) {
|
||||
const filterType = contextMenu.filterType;
|
||||
|
||||
@@ -211,6 +211,11 @@ function CustomNode({ id, data }) {
|
||||
);
|
||||
})}
|
||||
|
||||
{/* Warning notification */}
|
||||
{data.warning && (
|
||||
<div className="node-warning">{data.warning}</div>
|
||||
)}
|
||||
|
||||
{/* Widget rows */}
|
||||
{widgets.map((w) => (
|
||||
<div className="widget-row" key={w.name}>
|
||||
|
||||
@@ -34,6 +34,12 @@ export async function uploadFile(file) {
|
||||
return r.json();
|
||||
}
|
||||
|
||||
export async function getChannels(filepath) {
|
||||
const r = await fetch(`/channels?file=${encodeURIComponent(filepath)}`);
|
||||
if (!r.ok) return [{ name: 'field', type: 'DATA_FIELD' }];
|
||||
return r.json();
|
||||
}
|
||||
|
||||
export async function runPrompt(prompt) {
|
||||
const r = await fetch('/prompt', {
|
||||
method: 'POST',
|
||||
|
||||
@@ -82,10 +82,7 @@ html, body, #root {
|
||||
padding: 4px 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
max-width: 400px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 60%;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
.status-bar.info { color: #90caf9; }
|
||||
@@ -155,6 +152,15 @@ html, body, #root {
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.node-warning {
|
||||
padding: 3px 10px;
|
||||
font-size: 10px;
|
||||
color: #fbbf24;
|
||||
background: rgba(251, 191, 36, 0.1);
|
||||
border-top: 1px solid rgba(251, 191, 36, 0.2);
|
||||
border-bottom: 1px solid rgba(251, 191, 36, 0.2);
|
||||
}
|
||||
|
||||
/* ── I/O rows ──────────────────────────────────────────────────────── */
|
||||
.io-row {
|
||||
display: flex;
|
||||
|
||||
@@ -9,6 +9,7 @@ export default defineConfig({
|
||||
'/nodes': 'http://127.0.0.1:8188',
|
||||
'/files': 'http://127.0.0.1:8188',
|
||||
'/browse': 'http://127.0.0.1:8188',
|
||||
'/channels': 'http://127.0.0.1:8188',
|
||||
'/upload': 'http://127.0.0.1:8188',
|
||||
'/download': 'http://127.0.0.1:8188',
|
||||
'/prompt': 'http://127.0.0.1:8188',
|
||||
|
||||
Reference in New Issue
Block a user