fix: resize workflow canvas cause incorrect comment position

This commit is contained in:
hjlarry 2025-11-05 14:08:21 +08:00
parent ee3ded0fc2
commit 2f60288d86
5 changed files with 50 additions and 13 deletions

View File

@ -31,6 +31,12 @@ export const CommentIcon: FC<CommentIconProps> = 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<CommentIconProps> = 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<CommentIconProps> = memo(({ comment, onClick, isAct
<div
className="absolute z-10"
style={{
left: effectivePosition.x,
top: effectivePosition.y,
left: canvasPosition.x,
top: canvasPosition.y,
transform: 'translate(-50%, -50%)',
}}
data-role='comment-marker'
@ -224,8 +234,8 @@ export const CommentIcon: FC<CommentIconProps> = memo(({ comment, onClick, isAct
<div
className="absolute z-20"
style={{
left: (dragPosition ?? screenPosition).x - dynamicWidth / 2,
top: (dragPosition ?? screenPosition).y + 20,
left: (effectiveScreenPosition.x - containerLeft) - dynamicWidth / 2,
top: (effectiveScreenPosition.y - containerTop) + 20,
transform: 'translateY(-100%)',
}}
data-role='comment-preview'

View File

@ -247,6 +247,15 @@ export const CommentThread: FC<CommentThreadProps> = 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<CommentThreadProps> = memo(({
<div
className='absolute z-50 w-[360px] max-w-[360px]'
style={{
left: screenPosition.x + 40,
top: screenPosition.y,
left: canvasPosition.x + 40,
top: canvasPosition.y,
transform: 'translateY(-20%)',
}}
>

View File

@ -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)

View File

@ -446,7 +446,10 @@ export const Workflow: FC<WorkflowProps> = memo(({
)}
{pendingComment && (
<CommentInput
position={pendingComment}
position={{
x: pendingComment.elementX,
y: pendingComment.elementY,
}}
onSubmit={handleCommentSubmit}
onCancel={handleCommentCancel}
/>

View File

@ -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