diff --git a/packages/sanity/src/tasks/src/tasks/components/activity/TasksActivityCommentItem.tsx b/packages/sanity/src/tasks/src/tasks/components/activity/TasksActivityCommentItem.tsx new file mode 100644 index 00000000000..975a2b10d77 --- /dev/null +++ b/packages/sanity/src/tasks/src/tasks/components/activity/TasksActivityCommentItem.tsx @@ -0,0 +1,30 @@ +import {CommentsListItem, type CommentsListItemProps} from '../../../../../structure/comments' +import {ActivityItem} from './TasksActivityItem' + +const COMMENTS_LIST_ITEM_AVATAR_CONFIG: CommentsListItemProps['avatarConfig'] = { + parentCommentAvatar: false, + threadCommentsAvatar: true, + replyAvatar: true, + avatarSize: 0, +} + +interface TasksActivityCommentItemProps extends Omit { + // ... +} + +export function TasksActivityCommentItem(props: TasksActivityCommentItemProps) { + const {parentComment} = props + + return ( + + + + ) +} diff --git a/packages/sanity/src/tasks/src/tasks/components/activity/TasksActivityLog.tsx b/packages/sanity/src/tasks/src/tasks/components/activity/TasksActivityLog.tsx index 4e39ec47bf2..71573f358bc 100644 --- a/packages/sanity/src/tasks/src/tasks/components/activity/TasksActivityLog.tsx +++ b/packages/sanity/src/tasks/src/tasks/components/activity/TasksActivityLog.tsx @@ -20,10 +20,9 @@ import {getJsonStream} from '../../../../../core/store/_legacy/history/history/g import { type CommentBaseCreatePayload, type CommentCreatePayload, + CommentDeleteDialog, type CommentInputProps, type CommentReactionOption, - CommentsListItem, - type CommentsListItemProps, type CommentThreadItem, type CommentUpdatePayload, useComments, @@ -35,8 +34,8 @@ import {getMentionedUsers} from '../form/utils' import {type FieldChange, trackFieldChanges} from './helpers/parseTransactions' import {EditedAt} from './TaskActivityEditedAt' import {TasksActivityCommentInput} from './TasksActivityCommentInput' +import {TasksActivityCommentItem} from './TasksActivityCommentItem' import {TasksActivityCreatedAt} from './TasksActivityCreatedAt' -import {ActivityItem} from './TasksActivityItem' import {TasksSubscribers} from './TasksSubscribers' function useActivityLog(task: TaskDocument) { @@ -107,13 +106,6 @@ const VARIANTS: Variants = { visible: {opacity: 1, x: 0}, } -const COMMENTS_LIST_ITEM_AVATAR_CONFIG: CommentsListItemProps['avatarConfig'] = { - parentCommentAvatar: false, - threadCommentsAvatar: true, - replyAvatar: true, - avatarSize: 0, -} - const MotionStack = styled(motion(Stack))`` interface TasksActivityLogProps { @@ -140,6 +132,10 @@ export function TasksActivityLog(props: TasksActivityLogProps) { const {title: workspaceTitle, basePath} = useWorkspace() const {comments, mentionOptions, operation, getComment} = useComments() + const [commentToDeleteId, setCommentToDeleteId] = useState(null) + const [commentDeleteError, setCommentDeleteError] = useState(null) + const [commentDeleteLoading, setCommentDeleteLoading] = useState(false) + const loading = comments.loading const taskComments = comments.data.open @@ -247,13 +243,21 @@ export function TasksActivityLog(props: TasksActivityLogProps) { [operation], ) - const handleCommentRemove = useCallback( - (id: string) => { - // TODO: - // The remove operation is not optimistic. We should display a - // dialog to confirm the removal and wait for the server to respond - // before removing the comment from the UI. (See `CommentsDocumentInspector`) - operation.remove(id) + const handleDeleteCommentStart = useCallback((id: string) => setCommentToDeleteId(id), []) + const handleDeleteCommentCancel = useCallback(() => setCommentToDeleteId(null), []) + + const handleDeleteCommentConfirm = useCallback( + async (id: string) => { + try { + setCommentDeleteLoading(true) + setCommentDeleteError(null) + await operation.remove(id) + setCommentToDeleteId(null) + } catch (err) { + setCommentDeleteError(err) + } finally { + setCommentDeleteLoading(false) + } }, [operation], ) @@ -284,80 +288,94 @@ export function TasksActivityLog(props: TasksActivityLogProps) { .sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()) }, [activityData, taskComments]) + const commentToDeleteIsParent = useMemo(() => { + const parent = taskComments.find((c) => c.parentComment?._id === commentToDeleteId) + const isParent = Boolean(parent && parent?.replies?.length > 0) + + return isParent + }, [commentToDeleteId, taskComments]) + return ( - - - - - Activity - - - - {currentUser?.id && ( - - )} - - - {loading && } - - - {!loading && ( - - {value.createdByUser && ( - - - - )} - - {currentUser && ( - - - {activity.map((item) => { - if (item._type === 'activity') { - return - } - return ( - - + {commentToDeleteId && ( + + )} + + + + + + Activity + + + + {currentUser?.id && ( + + )} + + + {loading && } + + + {!loading && ( + + {value.createdByUser && ( + + + + )} + + {currentUser && ( + + + {activity.map((item) => { + if (item._type === 'activity') { + return + } + + return ( + - - ) - })} - - - - - )} - - )} - - + ) + })} + + + + + )} + + )} + + + ) }