From 2f60288d8674eca96ffe54375ce1819f68543b74 Mon Sep 17 00:00:00 2001 From: hjlarry Date: Wed, 5 Nov 2025 14:08:21 +0800 Subject: [PATCH] fix: resize workflow canvas cause incorrect comment position --- .../workflow/comment/comment-icon.tsx | 20 ++++++++++++++----- .../components/workflow/comment/thread.tsx | 13 ++++++++++-- .../workflow/hooks/use-workflow-comment.ts | 14 ++++++++++--- web/app/components/workflow/index.tsx | 5 ++++- .../workflow/store/workflow/workflow-slice.ts | 11 ++++++++-- 5 files changed, 50 insertions(+), 13 deletions(-) diff --git a/web/app/components/workflow/comment/comment-icon.tsx b/web/app/components/workflow/comment/comment-icon.tsx index bde458cc46..f2b3a785b1 100644 --- a/web/app/components/workflow/comment/comment-icon.tsx +++ b/web/app/components/workflow/comment/comment-icon.tsx @@ -31,6 +31,12 @@ export const CommentIcon: FC = memo(({ comment, onClick, isAct hasMoved: boolean } | null>(null) + const workflowContainerRect = typeof document !== 'undefined' + ? document.getElementById('workflow-container')?.getBoundingClientRect() + : null + const containerLeft = workflowContainerRect?.left ?? 0 + const containerTop = workflowContainerRect?.top ?? 0 + const screenPosition = useMemo(() => { return flowToScreenPosition({ x: comment.position_x, @@ -38,7 +44,11 @@ export const CommentIcon: FC = memo(({ comment, onClick, isAct }) }, [comment.position_x, comment.position_y, viewport.x, viewport.y, viewport.zoom, flowToScreenPosition]) - const effectivePosition = dragPosition ?? screenPosition + const effectiveScreenPosition = dragPosition ?? screenPosition + const canvasPosition = useMemo(() => ({ + x: effectiveScreenPosition.x - containerLeft, + y: effectiveScreenPosition.y - containerTop, + }), [effectiveScreenPosition.x, effectiveScreenPosition.y, containerLeft, containerTop]) const cursorClass = useMemo(() => { if (!isAuthor) return 'cursor-pointer' @@ -186,8 +196,8 @@ export const CommentIcon: FC = memo(({ comment, onClick, isAct
= memo(({ comment, onClick, isAct
= memo(({ y: comment.position_y, }) }, [comment.position_x, comment.position_y, viewport.x, viewport.y, viewport.zoom, flowToScreenPosition]) + const workflowContainerRect = typeof document !== 'undefined' + ? document.getElementById('workflow-container')?.getBoundingClientRect() + : null + const containerLeft = workflowContainerRect?.left ?? 0 + const containerTop = workflowContainerRect?.top ?? 0 + const canvasPosition = useMemo(() => ({ + x: screenPosition.x - containerLeft, + y: screenPosition.y - containerTop, + }), [screenPosition.x, screenPosition.y, containerLeft, containerTop]) const handleStartEdit = useCallback((reply: WorkflowCommentDetailReply) => { setEditingReply({ id: reply.id, content: reply.content }) @@ -331,8 +340,8 @@ export const CommentThread: FC = memo(({
diff --git a/web/app/components/workflow/hooks/use-workflow-comment.ts b/web/app/components/workflow/hooks/use-workflow-comment.ts index e659f0238e..7c587f1a2d 100644 --- a/web/app/components/workflow/hooks/use-workflow-comment.ts +++ b/web/app/components/workflow/hooks/use-workflow-comment.ts @@ -107,7 +107,10 @@ export const useWorkflowComment = () => { try { // Convert screen position to flow position when submitting const { screenToFlowPosition } = reactflow - const flowPosition = screenToFlowPosition({ x: pendingComment.x, y: pendingComment.y }) + const flowPosition = screenToFlowPosition({ + x: pendingComment.pageX, + y: pendingComment.pageY, + }) const newComment = await createWorkflowComment(appId, { position_x: flowPosition.x, @@ -452,10 +455,15 @@ export const useWorkflowComment = () => { activeCommentIdRef.current = null }, [setActiveComment, setActiveCommentId, setActiveCommentLoading]) - const handleCreateComment = useCallback((mousePosition: { elementX: number; elementY: number }) => { + const handleCreateComment = useCallback((mousePosition: { + pageX: number + pageY: number + elementX: number + elementY: number + }) => { if (controlMode === ControlMode.Comment) { console.log('Setting pending comment at screen position:', mousePosition) - setPendingComment({ x: mousePosition.elementX, y: mousePosition.elementY }) + setPendingComment(mousePosition) } else { console.log('Control mode is not Comment:', controlMode) diff --git a/web/app/components/workflow/index.tsx b/web/app/components/workflow/index.tsx index 68f17f6813..403d292765 100644 --- a/web/app/components/workflow/index.tsx +++ b/web/app/components/workflow/index.tsx @@ -446,7 +446,10 @@ export const Workflow: FC = memo(({ )} {pendingComment && ( diff --git a/web/app/components/workflow/store/workflow/workflow-slice.ts b/web/app/components/workflow/store/workflow/workflow-slice.ts index b08171487b..e0463bb8cc 100644 --- a/web/app/components/workflow/store/workflow/workflow-slice.ts +++ b/web/app/components/workflow/store/workflow/workflow-slice.ts @@ -10,6 +10,13 @@ type PreviewRunningData = WorkflowRunningData & { resultText?: string } +type MousePosition = { + pageX: number + pageY: number + elementX: number + elementY: number +} + export type WorkflowSliceShape = { workflowRunningData?: PreviewRunningData setWorkflowRunningData: (workflowData: PreviewRunningData) => void @@ -21,9 +28,9 @@ export type WorkflowSliceShape = { setBundleNodeSize: (bundleNodeSize: WorkflowSliceShape['bundleNodeSize']) => void controlMode: 'pointer' | 'hand' | 'comment' setControlMode: (controlMode: WorkflowSliceShape['controlMode']) => void - pendingComment: { x: number; y: number } | null + pendingComment: MousePosition | null setPendingComment: (pendingComment: WorkflowSliceShape['pendingComment']) => void - mousePosition: { pageX: number; pageY: number; elementX: number; elementY: number } + mousePosition: MousePosition setMousePosition: (mousePosition: WorkflowSliceShape['mousePosition']) => void showConfirm?: { title: string; desc?: string; onConfirm: () => void } setShowConfirm: (showConfirm: WorkflowSliceShape['showConfirm']) => void