basic function

This commit is contained in:
2026-03-06 23:03:42 +01:00
parent d690c94369
commit 49a6e5b4a3
4 changed files with 210 additions and 7 deletions

View File

@@ -45,7 +45,8 @@ export const ConfigNode = memo(function ConfigNode({ id, data }: Props) {
const incomingIds = incomingEdges.map((e: any) => e.source).sort()
const connectedConfigNodes = (ctx?.nodes ?? []).filter((n: any) => incomingIds.includes(n.id) && n.type === 'config')
const connectedVariableNodes = (ctx?.nodes ?? []).filter((n: any) => incomingIds.includes(n.id) && n.type === 'variable')
const hasDependencies = connectedConfigNodes.length > 0 || connectedVariableNodes.length > 0
const connectedFunctionNodes = (ctx?.nodes ?? []).filter((n: any) => incomingIds.includes(n.id) && n.type === 'function')
const hasDependencies = connectedConfigNodes.length > 0 || connectedVariableNodes.length > 0 || connectedFunctionNodes.length > 0
useEffect(() => {
if (setNodes) {
@@ -173,6 +174,48 @@ export const ConfigNode = memo(function ConfigNode({ id, data }: Props) {
[onChange, value]
)
const insertFunctionCall = useCallback(
(sourceNode: any, mode: 'prepend' | 'append' | 'cursor') => {
const insertText = `\${${sourceNode.id}()}` // user can add variable ids inside: ${funcId(var1, var2)}
const editor = editorRef.current
const monaco = monacoRef.current
try {
if (editor && monaco) {
const model = editor.getModel()
const lineCount = model.getLineCount()
const selection = editor.getSelection()
let range
if (mode === 'prepend') {
range = new monaco.Range(1, 1, 1, 1)
} else if (mode === 'append') {
range = new monaco.Range(lineCount + 1, 1, lineCount + 1, 1)
} else if (selection) {
range = new monaco.Range(selection.startLineNumber, selection.startColumn, selection.startLineNumber, selection.startColumn)
} else {
range = new monaco.Range(lineCount + 1, 1, lineCount + 1, 1)
}
editor.executeEdits('insert-fn', [{ range, text: insertText, forceMoveMarkers: true }])
const newVal = editor.getModel().getValue()
onChange(newVal)
return
}
if (mode === 'prepend') {
onChange(insertText + value)
} else {
onChange(value + insertText)
}
} catch (err) {
// eslint-disable-next-line no-console
console.error('Insert function call failed', err)
}
},
[onChange, value]
)
return (
<BaseNode className="w-80">
<BaseNodeHeader className="border-b">
@@ -231,6 +274,21 @@ export const ConfigNode = memo(function ConfigNode({ id, data }: Props) {
</MenubarSubContent>
</MenubarSub>
))}
{connectedFunctionNodes.map((n: any) => (
<MenubarSub key={`fn-${n.id}`}>
<MenubarSubTrigger className="text-xs">
{n.id}
</MenubarSubTrigger>
<MenubarSubContent>
<MenubarItem
className="text-xs"
onClick={() => insertFunctionCall(n, 'cursor')}
>
Insert at cursor
</MenubarItem>
</MenubarSubContent>
</MenubarSub>
))}
</MenubarContent>
</MenubarMenu>
</Menubar>