Spaces:
Sleeping
Sleeping
File size: 2,953 Bytes
cfaaa6c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | import { memo, useEffect } from 'react';
import { useUpdateNodeInternals } from '@xyflow/react';
import NodeShell from '../components/NodeShell.jsx';
import { useWorkflow } from '../context/WorkflowContext.jsx';
import { createBrowserId } from '../lib/ids.js';
import { getNodeAccent } from '../lib/nodeRegistry.js';
function ScriptFlowNode({ id, data, selected, type }) {
const { getNodeHandles, replaceNodeData, removeHandleConnections } = useWorkflow();
const updateNodeInternals = useUpdateNodeInternals();
const handles = getNodeHandles(type, data);
const runtime = data.runtime || {};
useEffect(() => {
updateNodeInternals(id);
}, [id, data.entries.length, data.hasScriptOutput, updateNodeInternals]);
const addEntry = (kind) => {
replaceNodeData(id, (current) => ({
...current,
entries: [...current.entries, { id: createBrowserId(`${kind}-slot`), kind }],
}));
};
const removeEntry = (entryId) => {
removeHandleConnections(id, entryId, 'target');
replaceNodeData(id, (current) => ({
...current,
entries: current.entries.filter((entry) => entry.id !== entryId),
}));
};
const toggleOutput = () => {
if (data.hasScriptOutput) {
removeHandleConnections(id, 'script-text', 'source');
}
replaceNodeData(id, (current) => ({
...current,
hasScriptOutput: !current.hasScriptOutput,
}));
};
return (
<NodeShell
nodeId={id}
title={data.title}
accent={getNodeAccent(type)}
selected={selected}
status={runtime.status}
inputs={handles.inputs}
outputs={handles.outputs}
className="node-shell--script"
bodyClassName="node-shell__body--script"
renderInputAddon={(input, index) =>
index === 0 ? null : (
<button type="button" className="nodrag node-shell__port-remove" onClick={() => removeEntry(input.id)}>
x
</button>
)
}
footer={
<div className="script-node__footer-buttons">
<button
type="button"
className="nodrag node-button node-button--ghost"
onClick={() => addEntry('user')}
disabled={data.hasScriptOutput}
>
+ User
</button>
<button
type="button"
className="nodrag node-button node-button--ghost"
onClick={() => addEntry('character')}
disabled={data.hasScriptOutput}
>
+ Character
</button>
<button
type="button"
className={`nodrag node-button ${data.hasScriptOutput ? 'is-active' : ''}`}
onClick={toggleOutput}
>
Output
</button>
</div>
}
>
<div className="script-node__spacer" />
{runtime.error ? <div className="node-error">{runtime.error}</div> : null}
</NodeShell>
);
}
export default memo(ScriptFlowNode);
|