diff --git a/web/app/components/workflow/comment-manager.tsx b/web/app/components/workflow/comment-manager.tsx new file mode 100644 index 0000000000..58fa93fa3d --- /dev/null +++ b/web/app/components/workflow/comment-manager.tsx @@ -0,0 +1,21 @@ +import { useEventListener } from 'ahooks' +import { useWorkflowStore } from './store' +import { useWorkflowComment } from './hooks/use-workflow-comment' + +const CommentManager = () => { + const workflowStore = useWorkflowStore() + const { handleCreateComment } = useWorkflowComment() + + useEventListener('click', (e) => { + const { controlMode, mousePosition } = workflowStore.getState() + + if (controlMode === 'comment') { + e.preventDefault() + handleCreateComment(mousePosition) + } + }) + + return null +} + +export default CommentManager diff --git a/web/app/components/workflow/comment/index.tsx b/web/app/components/workflow/comment/index.tsx new file mode 100644 index 0000000000..17b31c9ee6 --- /dev/null +++ b/web/app/components/workflow/comment/index.tsx @@ -0,0 +1,128 @@ +import type { FC } from 'react' +import { memo, useCallback, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { RiMessage3Line } from '@remixicon/react' +import { useStore } from '../store' +import { ControlMode } from '../types' +import type { WorkflowComment } from '@/service/workflow-comment' + +type CommentCursorProps = { + mousePosition: { elementX: number; elementY: number } +} + +export const CommentCursor: FC = memo(({ mousePosition }) => { + const controlMode = useStore(s => s.controlMode) + + if (controlMode !== ControlMode.Comment) + return null + + return ( +
+ +
+ ) +}) + +CommentCursor.displayName = 'CommentCursor' + +type CommentInputProps = { + position: { x: number; y: number } + onSubmit: (content: string) => void + onCancel: () => void +} + +export const CommentInput: FC = memo(({ position, onSubmit, onCancel }) => { + const { t } = useTranslation() + const [content, setContent] = useState('') + + const handleSubmit = useCallback(() => { + try { + if (content.trim()) { + onSubmit(content.trim()) + setContent('') + } + } + catch (error) { + console.error('Error in CommentInput handleSubmit:', error) + } + }, [content, onSubmit]) + + const handleKeyDown = useCallback((e: React.KeyboardEvent) => { + if (e.key === 'Enter' && !e.shiftKey) { + e.preventDefault() + handleSubmit() + } + else if (e.key === 'Escape') { + onCancel() + } + }, [handleSubmit, onCancel]) + + return ( +
+