|
|
@ -34,7 +34,6 @@ import { ConnectionDropMenu, type ConnectionIntent } from "./ConnectionDropMenu" |
|
|
import { MultiSelectToolbar } from "./MultiSelectToolbar"; |
|
|
import { MultiSelectToolbar } from "./MultiSelectToolbar"; |
|
|
import { EdgeToolbar } from "./EdgeToolbar"; |
|
|
import { EdgeToolbar } from "./EdgeToolbar"; |
|
|
import { GlobalImageHistory } from "./GlobalImageHistory"; |
|
|
import { GlobalImageHistory } from "./GlobalImageHistory"; |
|
|
import { NodeGenerationComposer } from "./composer/NodeGenerationComposer"; |
|
|
|
|
|
import { NodeType, NanoBananaNodeData, HandleType, PromptNodeData, SmartTextNodeData, LLMGenerateNodeData, PromptConstructorNodeData, AvailableVariable, SelectedModel, WorkflowNode } from "@/types"; |
|
|
import { NodeType, NanoBananaNodeData, HandleType, PromptNodeData, SmartTextNodeData, LLMGenerateNodeData, PromptConstructorNodeData, AvailableVariable, SelectedModel, WorkflowNode } from "@/types"; |
|
|
import { DEFAULT_NODE_DIMENSIONS, defaultNodeDimensions } from "@/store/utils/nodeDefaults"; |
|
|
import { DEFAULT_NODE_DIMENSIONS, defaultNodeDimensions } from "@/store/utils/nodeDefaults"; |
|
|
import { NodeHeaderProvider } from "./nodes/NodeHeaderContext"; |
|
|
import { NodeHeaderProvider } from "./nodes/NodeHeaderContext"; |
|
|
@ -76,7 +75,6 @@ import { useI18n } from "@/i18n"; |
|
|
import { buildDefaultGenerationNodeCreation } from "@/utils/defaultGenerationNodeModel"; |
|
|
import { buildDefaultGenerationNodeCreation } from "@/utils/defaultGenerationNodeModel"; |
|
|
import { isSmartImageGenerateMode } from "@/utils/smartImageMode"; |
|
|
import { isSmartImageGenerateMode } from "@/utils/smartImageMode"; |
|
|
import { deriveSmartTextMode } from "@/utils/smartTextMode"; |
|
|
import { deriveSmartTextMode } from "@/utils/smartTextMode"; |
|
|
import { useCanvasPreviewMode } from "@/components/CanvasPreviewModeContext"; |
|
|
|
|
|
import { getNodePrimaryImageUrl, getNodePrimaryMediaUrl, isTextOnlyContextMenuNode } from "@/utils/canvasNodeMedia"; |
|
|
import { getNodePrimaryImageUrl, getNodePrimaryMediaUrl, isTextOnlyContextMenuNode } from "@/utils/canvasNodeMedia"; |
|
|
import { |
|
|
import { |
|
|
canConnectOutputMediaToNode, |
|
|
canConnectOutputMediaToNode, |
|
|
@ -524,7 +522,6 @@ function getCanvasPanOnDrag(disabled: boolean): PanOnDragValue { |
|
|
|
|
|
|
|
|
export function WorkflowCanvas() { |
|
|
export function WorkflowCanvas() { |
|
|
const { t } = useI18n(); |
|
|
const { t } = useI18n(); |
|
|
const isPreviewMode = useCanvasPreviewMode(); |
|
|
|
|
|
const searchParams = useSearchParams(); |
|
|
const searchParams = useSearchParams(); |
|
|
const urlWorkflowId = searchParams?.get("workflowId") ?? null; |
|
|
const urlWorkflowId = searchParams?.get("workflowId") ?? null; |
|
|
const { nodes, edges, groups, isModalOpen, navigationTarget, canvasNavigationSettings, dimmedNodeIds, skippedNodeIds, providerSettings, isRunning } = |
|
|
const { nodes, edges, groups, isModalOpen, navigationTarget, canvasNavigationSettings, dimmedNodeIds, skippedNodeIds, providerSettings, isRunning } = |
|
|
@ -1003,35 +1000,6 @@ export function WorkflowCanvas() { |
|
|
() => allNodes.filter((node) => node.selected), |
|
|
() => allNodes.filter((node) => node.selected), |
|
|
[allNodes] |
|
|
[allNodes] |
|
|
); |
|
|
); |
|
|
const isSingleCanvasSelection = selectedCanvasNodes.length === 1; |
|
|
|
|
|
const selectedComposerTarget = useMemo(() => { |
|
|
|
|
|
if (isPreviewMode) return null; |
|
|
|
|
|
if (!isSingleCanvasSelection) return null; |
|
|
|
|
|
const node = selectedCanvasNodes[0]; |
|
|
|
|
|
if (!node || node.type === "group") return null; |
|
|
|
|
|
const position = absoluteNodePositions.get(node.id) ?? node.position; |
|
|
|
|
|
const dimensions = getWorkflowNodeDimensions(node); |
|
|
|
|
|
return { |
|
|
|
|
|
nodeId: node.id, |
|
|
|
|
|
position: { |
|
|
|
|
|
x: position.x + dimensions.width / 2, |
|
|
|
|
|
y: position.y + dimensions.height, |
|
|
|
|
|
}, |
|
|
|
|
|
}; |
|
|
|
|
|
}, [absoluteNodePositions, isPreviewMode, isSingleCanvasSelection, selectedCanvasNodes]); |
|
|
|
|
|
const [globalComposerTarget, setGlobalComposerTarget] = useState<{ |
|
|
|
|
|
nodeId: string; |
|
|
|
|
|
selected: boolean; |
|
|
|
|
|
position: { x: number; y: number }; |
|
|
|
|
|
} | null>(null); |
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
|
if (selectedComposerTarget) { |
|
|
|
|
|
setGlobalComposerTarget({ ...selectedComposerTarget, selected: true }); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
setGlobalComposerTarget((current) => current ? { ...current, selected: false } : null); |
|
|
|
|
|
}, [selectedComposerTarget]); |
|
|
|
|
|
|
|
|
|
|
|
const selectedBatchSourceNodeIds = useMemo(() => { |
|
|
const selectedBatchSourceNodeIds = useMemo(() => { |
|
|
const selectedGroupIds = selectedCanvasNodes |
|
|
const selectedGroupIds = selectedCanvasNodes |
|
|
@ -3193,13 +3161,6 @@ export function WorkflowCanvas() { |
|
|
}} |
|
|
}} |
|
|
/> |
|
|
/> |
|
|
)} |
|
|
)} |
|
|
{globalComposerTarget ? ( |
|
|
|
|
|
<NodeGenerationComposer |
|
|
|
|
|
nodeId={globalComposerTarget.nodeId} |
|
|
|
|
|
selected={globalComposerTarget.selected} |
|
|
|
|
|
position={globalComposerTarget.position} |
|
|
|
|
|
/> |
|
|
|
|
|
) : null} |
|
|
|
|
|
</ViewportPortal> |
|
|
</ViewportPortal> |
|
|
</ReactFlow> |
|
|
</ReactFlow> |
|
|
</NodeHeaderProvider> |
|
|
</NodeHeaderProvider> |
|
|
|