import { memo, useCallback, useMemo, useState } from 'react' import { RiCheckLine, RiCheckboxCircleFill, RiCheckboxCircleLine, RiCloseLine, RiFilter3Line } from '@remixicon/react' import { useStore } from '@/app/components/workflow/store' import type { WorkflowCommentList } from '@/service/workflow-comment' import { useWorkflowComment } from '@/app/components/workflow/hooks/use-workflow-comment' import { UserAvatarList } from '@/app/components/base/user-avatar-list' import cn from '@/utils/classnames' import { ControlMode } from '@/app/components/workflow/types' import { resolveWorkflowComment } from '@/service/workflow-comment' import { useParams } from 'next/navigation' import { useFormatTimeFromNow } from '@/app/components/workflow/hooks' import { useAppContext } from '@/context/app-context' import { collaborationManager } from '@/app/components/workflow/collaboration' const CommentsPanel = () => { const activeCommentId = useStore(s => s.activeCommentId) const setActiveCommentId = useStore(s => s.setActiveCommentId) const setControlMode = useStore(s => s.setControlMode) const { comments, loading, loadComments, handleCommentIconClick } = useWorkflowComment() const params = useParams() const appId = params.appId as string const { formatTimeFromNow } = useFormatTimeFromNow() const [filter, setFilter] = useState<'all' | 'unresolved' | 'mine'>('all') const [showFilter, setShowFilter] = useState(false) const handleSelect = useCallback((comment: WorkflowCommentList) => { handleCommentIconClick(comment) }, [handleCommentIconClick]) const { userProfile } = useAppContext() const filteredSorted = useMemo(() => { let data = comments if (filter === 'unresolved') data = data.filter(c => !c.resolved) else if (filter === 'mine') data = data.filter(c => c.created_by === userProfile?.id) return data }, [comments, filter, userProfile?.id]) const handleResolve = useCallback(async (comment: WorkflowCommentList) => { if (comment.resolved) return if (!appId) return try { await resolveWorkflowComment(appId, comment.id) collaborationManager.emitCommentsUpdate(appId) await loadComments() setActiveCommentId(comment.id) } catch (e) { console.error('Resolve comment failed', e) } }, [appId, loadComments, setActiveCommentId]) const handleFilterChange = useCallback((value: 'all' | 'unresolved' | 'mine') => { setFilter(value) setShowFilter(false) }, []) return (
Comments
{showFilter && (
)}
{ setControlMode(ControlMode.Pointer) setActiveCommentId(null) }} >
{filteredSorted.map((c) => { const isActive = activeCommentId === c.id return (
handleSelect(c)} >
{c.resolved ? ( ) : ( { e.preventDefault() e.stopPropagation() handleResolve(c) }} /> )}
{/* Header row: creator + time */}
{c.created_by_account.name}
{formatTimeFromNow(c.updated_at * 1000)}
{/* Content */}
{c.content}
{/* Footer */} {c.reply_count > 0 && (
{c.reply_count} replies
)}
) })} {!loading && filteredSorted.length === 0 && (
No comments yet
)}
) } export default memo(CommentsPanel)