mirror of
https://github.com/langgenius/dify.git
synced 2026-04-28 20:17:29 +08:00
display comments avatar on the canvas
This commit is contained in:
parent
9fda130b3a
commit
d7f5da5df4
@ -1,6 +1,6 @@
|
|||||||
from flask_restful import fields
|
from flask_restful import fields
|
||||||
|
|
||||||
from libs.helper import TimestampField
|
from libs.helper import AvatarUrlField, TimestampField
|
||||||
|
|
||||||
# Basic account fields for comment creators/resolvers
|
# Basic account fields for comment creators/resolvers
|
||||||
comment_account_fields = {"id": fields.String, "name": fields.String, "email": fields.String}
|
comment_account_fields = {"id": fields.String, "name": fields.String, "email": fields.String}
|
||||||
@ -26,7 +26,7 @@ workflow_comment_participant_fields = {
|
|||||||
"id": fields.String,
|
"id": fields.String,
|
||||||
"name": fields.String,
|
"name": fields.String,
|
||||||
"email": fields.String,
|
"email": fields.String,
|
||||||
"avatar": fields.String,
|
"avatar_url": AvatarUrlField,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Basic comment fields (for list views)
|
# Basic comment fields (for list views)
|
||||||
|
|||||||
@ -1,16 +1,17 @@
|
|||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import { memo } from 'react'
|
import { memo } from 'react'
|
||||||
import type { WorkflowComment } from '@/service/workflow-comment'
|
import Avatar from '@/app/components/base/avatar'
|
||||||
|
import type { WorkflowCommentList } from '@/service/workflow-comment'
|
||||||
|
|
||||||
type CommentIconProps = {
|
type CommentIconProps = {
|
||||||
comment: WorkflowComment
|
comment: WorkflowCommentList
|
||||||
onClick: () => void
|
onClick: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CommentIcon: FC<CommentIconProps> = memo(({ comment, onClick }) => {
|
export const CommentIcon: FC<CommentIconProps> = memo(({ comment, onClick }) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="absolute z-40 flex h-8 w-8 cursor-pointer items-center justify-center rounded-full bg-blue-500 text-white shadow-lg hover:bg-blue-600"
|
className="absolute z-40 cursor-pointer"
|
||||||
style={{
|
style={{
|
||||||
left: comment.position_x,
|
left: comment.position_x,
|
||||||
top: comment.position_y,
|
top: comment.position_y,
|
||||||
@ -18,8 +19,19 @@ export const CommentIcon: FC<CommentIconProps> = memo(({ comment, onClick }) =>
|
|||||||
}}
|
}}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
<div className="flex h-6 w-6 items-center justify-center rounded-full bg-white text-xs font-medium text-blue-500">
|
<div className="relative h-14 w-14 overflow-hidden rounded-br-full rounded-tl-full rounded-tr-full">
|
||||||
{'A'}
|
<div className="absolute inset-1 overflow-hidden rounded-br-full rounded-tl-full rounded-tr-full bg-white">
|
||||||
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
|
<div className="h-10 w-10 overflow-hidden rounded-full">
|
||||||
|
<Avatar
|
||||||
|
avatar={comment.created_by_account.avatar_url}
|
||||||
|
name={comment.created_by_account.name}
|
||||||
|
size={40}
|
||||||
|
className="h-full w-full"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { useCallback, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
import { useParams } from 'next/navigation'
|
import { useParams } from 'next/navigation'
|
||||||
import { useStore } from '../store'
|
import { useStore } from '../store'
|
||||||
import { ControlMode } from '../types'
|
import { ControlMode } from '../types'
|
||||||
import type { WorkflowComment } from '@/service/workflow-comment'
|
import type { WorkflowComment } from '@/service/workflow-comment'
|
||||||
import { createWorkflowComment } from '@/service/workflow-comment'
|
import { createWorkflowComment, fetchWorkflowComments } from '@/service/workflow-comment'
|
||||||
|
|
||||||
export const useWorkflowComment = () => {
|
export const useWorkflowComment = () => {
|
||||||
const params = useParams()
|
const params = useParams()
|
||||||
@ -13,6 +13,29 @@ export const useWorkflowComment = () => {
|
|||||||
const pendingComment = useStore(s => s.pendingComment)
|
const pendingComment = useStore(s => s.pendingComment)
|
||||||
const setPendingComment = useStore(s => s.setPendingComment)
|
const setPendingComment = useStore(s => s.setPendingComment)
|
||||||
const [comments, setComments] = useState<WorkflowComment[]>([])
|
const [comments, setComments] = useState<WorkflowComment[]>([])
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
|
||||||
|
// 加载评论列表
|
||||||
|
const loadComments = useCallback(async () => {
|
||||||
|
if (!appId) return
|
||||||
|
|
||||||
|
setLoading(true)
|
||||||
|
try {
|
||||||
|
const commentsData = await fetchWorkflowComments(appId)
|
||||||
|
setComments(commentsData)
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('Failed to fetch comments:', error)
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
}, [appId])
|
||||||
|
|
||||||
|
// 初始化时加载评论
|
||||||
|
useEffect(() => {
|
||||||
|
loadComments()
|
||||||
|
}, [loadComments])
|
||||||
|
|
||||||
const handleCommentSubmit = useCallback(async (content: string) => {
|
const handleCommentSubmit = useCallback(async (content: string) => {
|
||||||
if (!pendingComment) return
|
if (!pendingComment) return
|
||||||
@ -77,10 +100,12 @@ export const useWorkflowComment = () => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
comments,
|
comments,
|
||||||
|
loading,
|
||||||
pendingComment,
|
pendingComment,
|
||||||
handleCommentSubmit,
|
handleCommentSubmit,
|
||||||
handleCommentCancel,
|
handleCommentCancel,
|
||||||
handleCommentIconClick,
|
handleCommentIconClick,
|
||||||
handleCreateComment,
|
handleCreateComment,
|
||||||
|
loadComments,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,26 +1,56 @@
|
|||||||
import { del, get, post, put } from './base'
|
import { del, get, post, put } from './base'
|
||||||
import type { CommonResponse } from '@/models/common'
|
import type { CommonResponse } from '@/models/common'
|
||||||
|
|
||||||
export type WorkflowComment = {
|
export type UserProfile = {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
email: string
|
||||||
|
avatar_url?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type WorkflowCommentList = {
|
||||||
id: string
|
id: string
|
||||||
app_id: string
|
|
||||||
position_x: number
|
position_x: number
|
||||||
position_y: number
|
position_y: number
|
||||||
content: string
|
content: string
|
||||||
created_by: string
|
created_by: string
|
||||||
|
created_by_account: UserProfile
|
||||||
created_at: string
|
created_at: string
|
||||||
updated_at: string
|
updated_at: string
|
||||||
resolved: boolean
|
resolved: boolean
|
||||||
resolved_by?: string
|
resolved_by?: string
|
||||||
|
resolved_by_account?: UserProfile
|
||||||
resolved_at?: string
|
resolved_at?: string
|
||||||
mentioned_user_ids: string[]
|
mention_count: number
|
||||||
replies_count: number
|
reply_count: number
|
||||||
author: {
|
participants: UserProfile[]
|
||||||
id: string
|
}
|
||||||
name: string
|
|
||||||
email: string
|
export type WorkflowCommentDetail = {
|
||||||
avatar?: string
|
id: string
|
||||||
}
|
position_x: number
|
||||||
|
position_y: number
|
||||||
|
content: string
|
||||||
|
created_by: string
|
||||||
|
created_by_account: UserProfile
|
||||||
|
created_at: string
|
||||||
|
updated_at: string
|
||||||
|
resolved: boolean
|
||||||
|
resolved_by?: string
|
||||||
|
resolved_by_account?: UserProfile
|
||||||
|
resolved_at?: string
|
||||||
|
replies: []
|
||||||
|
mentions: []
|
||||||
|
}
|
||||||
|
|
||||||
|
export type WorkflowCommentCreateRes = {
|
||||||
|
id: string
|
||||||
|
created_at: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type WorkflowCommentUpdateRes = {
|
||||||
|
id: string
|
||||||
|
updated_at: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WorkflowCommentReply = {
|
export type WorkflowCommentReply = {
|
||||||
@ -58,21 +88,21 @@ export type CreateReplyParams = {
|
|||||||
mentioned_user_ids?: string[]
|
mentioned_user_ids?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchWorkflowComments = async (appId: string): Promise<WorkflowComment[]> => {
|
export const fetchWorkflowComments = async (appId: string): Promise<WorkflowCommentList[]> => {
|
||||||
const response = await get<{ data: WorkflowComment[] }>(`apps/${appId}/workflow/comments`)
|
const response = await get<{ data: WorkflowCommentList[] }>(`apps/${appId}/workflow/comments`)
|
||||||
return response.data
|
return response.data
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createWorkflowComment = async (appId: string, params: CreateCommentParams): Promise<WorkflowComment> => {
|
export const createWorkflowComment = async (appId: string, params: CreateCommentParams): Promise<WorkflowCommentCreateRes> => {
|
||||||
return post<WorkflowComment>(`apps/${appId}/workflow/comments`, { body: params })
|
return post<WorkflowCommentCreateRes>(`apps/${appId}/workflow/comments`, { body: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchWorkflowComment = async (appId: string, commentId: string): Promise<WorkflowComment> => {
|
export const fetchWorkflowComment = async (appId: string, commentId: string): Promise<WorkflowCommentDetail> => {
|
||||||
return get<WorkflowComment>(`apps/${appId}/workflow/comments/${commentId}`)
|
return get<WorkflowCommentDetail>(`apps/${appId}/workflow/comments/${commentId}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updateWorkflowComment = async (appId: string, commentId: string, params: UpdateCommentParams): Promise<WorkflowComment> => {
|
export const updateWorkflowComment = async (appId: string, commentId: string, params: UpdateCommentParams): Promise<WorkflowCommentUpdateRes> => {
|
||||||
return put<WorkflowComment>(`apps/${appId}/workflow/comments/${commentId}`, { body: params })
|
return put<WorkflowCommentUpdateRes>(`apps/${appId}/workflow/comments/${commentId}`, { body: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deleteWorkflowComment = async (appId: string, commentId: string): Promise<CommonResponse> => {
|
export const deleteWorkflowComment = async (appId: string, commentId: string): Promise<CommonResponse> => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user