mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
fix(embedded): block layout should not be dependent on viewport (#3621)
* fix(embedded): block layout should not be dependent on viewport * address comments
This commit is contained in:
@@ -208,7 +208,8 @@ const reactFlowStyles = [
|
||||
'[&_.react-flow__node-subflowNode.selected]:!shadow-none',
|
||||
].join(' ')
|
||||
const reactFlowFitViewOptions = { padding: 0.6, maxZoom: 1.0 } as const
|
||||
const embeddedFitViewOptions = { padding: 0.15, maxZoom: 0.85, minZoom: 0.35 } as const
|
||||
const embeddedFitViewOptions = { padding: 0.15, maxZoom: 0.85, minZoom: 0.1 } as const
|
||||
const embeddedResizeFitViewOptions = { ...embeddedFitViewOptions, duration: 0 } as const
|
||||
const reactFlowProOptions = { hideAttribution: true } as const
|
||||
|
||||
/**
|
||||
@@ -244,7 +245,10 @@ const WorkflowContent = React.memo(
|
||||
const [potentialParentId, setPotentialParentId] = useState<string | null>(null)
|
||||
const [selectedEdges, setSelectedEdges] = useState<SelectedEdgesMap>(new Map())
|
||||
const [isErrorConnectionDrag, setIsErrorConnectionDrag] = useState(false)
|
||||
const canvasContainerRef = useRef<HTMLDivElement>(null)
|
||||
const selectedIdsRef = useRef<string[] | null>(null)
|
||||
const embeddedFitFrameRef = useRef<number | null>(null)
|
||||
const hasCompletedInitialEmbeddedFitRef = useRef(false)
|
||||
const canvasMode = useCanvasModeStore((state) => state.mode)
|
||||
const isHandMode = embedded ? true : canvasMode === 'hand'
|
||||
const { handleCanvasMouseDown, selectionProps } = useShiftSelectionLock({ isHandMode })
|
||||
@@ -373,6 +377,34 @@ const WorkflowContent = React.memo(
|
||||
]
|
||||
)
|
||||
|
||||
const scheduleEmbeddedFit = useCallback(() => {
|
||||
if (!embedded || !isWorkflowReady) return
|
||||
|
||||
if (embeddedFitFrameRef.current !== null) {
|
||||
cancelAnimationFrame(embeddedFitFrameRef.current)
|
||||
}
|
||||
|
||||
embeddedFitFrameRef.current = requestAnimationFrame(() => {
|
||||
embeddedFitFrameRef.current = null
|
||||
|
||||
const container = canvasContainerRef.current
|
||||
if (!container) return
|
||||
|
||||
const rect = container.getBoundingClientRect()
|
||||
if (rect.width <= 0 || rect.height <= 0) return
|
||||
|
||||
const nodes = reactFlowInstance.getNodes()
|
||||
if (nodes.length > 0) {
|
||||
void reactFlowInstance.fitView(embeddedResizeFitViewOptions)
|
||||
}
|
||||
|
||||
if (!hasCompletedInitialEmbeddedFitRef.current) {
|
||||
hasCompletedInitialEmbeddedFitRef.current = true
|
||||
setIsCanvasReady(true)
|
||||
}
|
||||
})
|
||||
}, [embedded, isWorkflowReady, reactFlowInstance])
|
||||
|
||||
const {
|
||||
getNodeDepth,
|
||||
getNodeAbsolutePosition,
|
||||
@@ -3750,10 +3782,46 @@ const WorkflowContent = React.memo(
|
||||
activeWorkflowId,
|
||||
])
|
||||
|
||||
useEffect(() => {
|
||||
if (!embedded || !isWorkflowReady) {
|
||||
return
|
||||
}
|
||||
|
||||
const container = canvasContainerRef.current
|
||||
if (!container) {
|
||||
return
|
||||
}
|
||||
|
||||
scheduleEmbeddedFit()
|
||||
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
scheduleEmbeddedFit()
|
||||
})
|
||||
|
||||
resizeObserver.observe(container)
|
||||
|
||||
return () => {
|
||||
resizeObserver.disconnect()
|
||||
|
||||
if (embeddedFitFrameRef.current !== null) {
|
||||
cancelAnimationFrame(embeddedFitFrameRef.current)
|
||||
embeddedFitFrameRef.current = null
|
||||
}
|
||||
}
|
||||
}, [embedded, isWorkflowReady, scheduleEmbeddedFit])
|
||||
|
||||
useEffect(() => {
|
||||
if (!embedded || !isWorkflowReady) {
|
||||
return
|
||||
}
|
||||
|
||||
scheduleEmbeddedFit()
|
||||
}, [blocksStructureHash, embedded, isWorkflowReady, scheduleEmbeddedFit])
|
||||
|
||||
return (
|
||||
<div className='flex h-full w-full overflow-hidden'>
|
||||
<div className='flex min-w-0 flex-1 flex-col'>
|
||||
<div className='relative flex-1 overflow-hidden'>
|
||||
<div ref={canvasContainerRef} className='relative flex-1 overflow-hidden'>
|
||||
{!isWorkflowReady && (
|
||||
<div className='absolute inset-0 z-[5] flex items-center justify-center bg-[var(--bg)]'>
|
||||
<div
|
||||
@@ -3791,8 +3859,12 @@ const WorkflowContent = React.memo(
|
||||
onDrop={effectivePermissions.canEdit ? onDrop : undefined}
|
||||
onDragOver={effectivePermissions.canEdit ? onDragOver : undefined}
|
||||
onInit={(instance) => {
|
||||
if (embedded) {
|
||||
return
|
||||
}
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
instance.fitView(embedded ? embeddedFitViewOptions : reactFlowFitViewOptions)
|
||||
instance.fitView(reactFlowFitViewOptions)
|
||||
setIsCanvasReady(true)
|
||||
})
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user