feat: enhance connection validation and node creation logic, improve type handling in various components
This commit is contained in:
@@ -43,7 +43,7 @@ import { NodeFooterEdgeIndicators } from '../base/NodeFooterEdgeIndicators'
|
||||
import { NodeHeaderTitle } from '../base/NodeHeaderTitle'
|
||||
import { NodeMenubar } from '../base/NodeMenubar'
|
||||
|
||||
export type ConfigNodeData = { configType?: ConfigTypeId; content?: string; title?: string }
|
||||
export type ConfigNodeData = { configType?: ConfigTypeId; content?: string; title?: string; /** @deprecated use content */ plantuml?: string }
|
||||
|
||||
type Props = AbstractNodeProps<ConfigNodeData>
|
||||
|
||||
@@ -324,7 +324,7 @@ function ConfigNodeComponent({ id, data, width, height, selected }: Props) {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div ref={editorContainerRef} className="min-h-0 flex-1 w-full nodrag nopan overflow-hidden border-t border-input">
|
||||
<div ref={editorContainerRef as React.RefObject<HTMLDivElement>} className="min-h-0 flex-1 w-full nodrag nopan overflow-hidden border-t border-input">
|
||||
<CodeMirror
|
||||
// @ts-expect-error ref is { view, state, editor }; package ref type not in our node_modules
|
||||
ref={editorRef}
|
||||
|
||||
@@ -131,7 +131,7 @@ function FunctionNodeComponent({ id, data, width, height, selected }: Props) {
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div ref={editorContainerRef} className="min-h-0 flex-1 w-full nodrag nopan overflow-hidden border-t border-input">
|
||||
<div ref={editorContainerRef as React.RefObject<HTMLDivElement>} className="min-h-0 flex-1 w-full nodrag nopan overflow-hidden border-t border-input">
|
||||
<CodeMirror
|
||||
// @ts-expect-error ref is { view, state, editor }; package ref type not in our node_modules
|
||||
ref={editorRef}
|
||||
|
||||
@@ -51,8 +51,8 @@ function RenderingNodeComponent({ id, data, width, height, selected }: Props) {
|
||||
const incomingIds = sourceIds
|
||||
const srcId = incomingIds.length > 0 ? incomingIds[0] : null
|
||||
const srcNode = nodes.find((n: any) => n.id === srcId)
|
||||
const configTypeId = srcNode?.type === 'config' ? getConfigTypeId(srcNode.data) : 'plantuml'
|
||||
const sourceContent = srcNode?.type === 'config' ? getConfigContent(srcNode.data) : ''
|
||||
const configTypeId = srcNode?.type === 'config' ? getConfigTypeId((srcNode.data ?? undefined) as Record<string, unknown> | undefined) : 'plantuml'
|
||||
const sourceContent = srcNode?.type === 'config' ? getConfigContent((srcNode.data ?? undefined) as Record<string, unknown> | undefined) : ''
|
||||
const srcData = srcNode?.data ?? {}
|
||||
|
||||
/** Set of node IDs that can affect this render node (configs in the chain + variables/functions feeding them) */
|
||||
@@ -94,7 +94,7 @@ function RenderingNodeComponent({ id, data, width, height, selected }: Props) {
|
||||
if (!node) return
|
||||
visited.add(nodeId)
|
||||
out.add(nodeId)
|
||||
const content = getConfigContent(node.data)
|
||||
const content = getConfigContent((node.data ?? undefined) as Record<string, unknown> | undefined)
|
||||
for (const ref of getTemplateRefs(content)) {
|
||||
const refId = resolveRef(ref)
|
||||
if (refId && nodes.some((n: any) => n.id === refId && n.type === 'config') && isReachable(refId, id))
|
||||
@@ -223,7 +223,7 @@ function RenderingNodeComponent({ id, data, width, height, selected }: Props) {
|
||||
throw new Error(`Referenced config not connected to renderer: ${templateName}`)
|
||||
visited.add(refId)
|
||||
configIdsUsed.add(refId)
|
||||
const content = getConfigContent(node.data)
|
||||
const content = getConfigContent((node.data ?? undefined) as Record<string, unknown> | undefined)
|
||||
for (const ref of getTemplateRefs(content)) addConfigAndRefs(ref, visited)
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ function RenderingNodeComponent({ id, data, width, height, selected }: Props) {
|
||||
if (refId !== srcId && !isReachable(refId, id))
|
||||
throw new Error(`Referenced config not connected to renderer: ${name}`)
|
||||
return {
|
||||
src: getConfigContent(node.data),
|
||||
src: getConfigContent((node.data ?? undefined) as Record<string, unknown> | undefined),
|
||||
path: name,
|
||||
}
|
||||
},
|
||||
@@ -338,7 +338,7 @@ function RenderingNodeComponent({ id, data, width, height, selected }: Props) {
|
||||
for (const fid of functionIdsToRegister) {
|
||||
const src = nodes.find((n: any) => n.id === fid)
|
||||
if (!src || src.type !== 'function') continue
|
||||
const body = src.data?.body ?? 'return args[0];'
|
||||
const body = (src.data as { body?: string } | undefined)?.body ?? 'return args[0];'
|
||||
const parsed = parseFunctionSignature(body)
|
||||
const connectedVarIds = new Set<string>(functionConnectedVariableIds[fid] ?? [])
|
||||
const connectedFuncIds = functionConnectedFunctionIds[fid] ?? []
|
||||
@@ -432,7 +432,7 @@ function RenderingNodeComponent({ id, data, width, height, selected }: Props) {
|
||||
env.render(srcId!, nunjucksContext, async (nunjucksErr: Error | null, afterNunjucks: string) => {
|
||||
if (cancelled || thisRunId !== runIdRef.current) return
|
||||
if (nunjucksErr) {
|
||||
setSvgContent(null)
|
||||
setRenderedContent(null)
|
||||
setError({ kind: 'render', message: `Nunjucks: ${nunjucksErr.message}` })
|
||||
setLoading(false)
|
||||
return
|
||||
@@ -677,10 +677,10 @@ function RenderingNodeComponent({ id, data, width, height, selected }: Props) {
|
||||
</EmptyContent>
|
||||
</Empty>
|
||||
) : error ? (
|
||||
srcData?.renderError ? (
|
||||
srcData.renderError(error)
|
||||
) : srcData?.errorHtml ? (
|
||||
<div className="p-3 text-xs text-red-700 dark:text-red-400" dangerouslySetInnerHTML={{ __html: String(srcData.errorHtml) }} />
|
||||
(srcData as { renderError?: (err: { kind: string; message: string }) => React.ReactNode; errorHtml?: string })?.renderError ? (
|
||||
(srcData as { renderError: (err: { kind: string; message: string }) => React.ReactNode }).renderError(error)
|
||||
) : (srcData as { errorHtml?: string })?.errorHtml ? (
|
||||
<div className="p-3 text-xs text-red-700 dark:text-red-400" dangerouslySetInnerHTML={{ __html: String((srcData as { errorHtml: string }).errorHtml) }} />
|
||||
) : (
|
||||
<div className="flex flex-col gap-2 p-3">
|
||||
<p className="text-xs text-red-700 dark:text-red-400">{error.message}</p>
|
||||
@@ -706,7 +706,7 @@ function RenderingNodeComponent({ id, data, width, height, selected }: Props) {
|
||||
minScale={0.2}
|
||||
maxScale={4}
|
||||
centerOnInit
|
||||
onInit={(ref) => ref?.centerView(1, 0, 0)}
|
||||
onInit={(ref) => ref?.centerView(1, 200, 'easeOut')}
|
||||
panning={{ disabled: true }}
|
||||
wheel={{ disabled: true }}
|
||||
doubleClick={{ disabled: true }}
|
||||
|
||||
Reference in New Issue
Block a user