Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export function AddComment( {
</HStack>
<CommentForm
onSubmit={ ( inputComment ) => {
onSubmit( inputComment );
onSubmit( { content: inputComment } );
} }
onCancel={ () => {
setShowCommentBoard( false );
Expand Down
47 changes: 21 additions & 26 deletions packages/editor/src/components/collab-sidebar/comments.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ const { Menu } = unlock( componentsPrivateApis );
* @param {Function} props.onEditComment - The function to handle comment editing.
* @param {Function} props.onAddReply - The function to add a reply to a comment.
* @param {Function} props.onCommentDelete - The function to delete a comment.
* @param {Function} props.onCommentResolve - The function to mark a comment as resolved.
* @param {Function} props.onCommentReopen - The function to reopen a resolved comment.
* @param {Function} props.setShowCommentBoard - The function to set the comment board visibility.
* @return {React.ReactNode} The rendered Comments component.
*/
Expand All @@ -51,8 +49,6 @@ export function Comments( {
onEditComment,
onAddReply,
onCommentDelete,
onCommentResolve,
onCommentReopen,
setShowCommentBoard,
} ) {
const { blockCommentId } = useSelect( ( select ) => {
Expand Down Expand Up @@ -90,8 +86,6 @@ export function Comments( {
thread={ thread }
onAddReply={ onAddReply }
onCommentDelete={ onCommentDelete }
onCommentResolve={ onCommentResolve }
onCommentReopen={ onCommentReopen }
onEditComment={ onEditComment }
isFocused={ focusThread === thread.id }
setFocusThread={ setFocusThread }
Expand All @@ -105,8 +99,6 @@ function Thread( {
onEditComment,
onAddReply,
onCommentDelete,
onCommentResolve,
onCommentReopen,
isFocused,
setFocusThread,
setShowCommentBoard,
Expand Down Expand Up @@ -148,8 +140,6 @@ function Thread( {
>
<CommentBoard
thread={ thread }
onResolve={ onCommentResolve }
onReopen={ onCommentReopen }
onEdit={ onEditComment }
onDelete={ onCommentDelete }
status={ thread.status }
Expand Down Expand Up @@ -225,9 +215,15 @@ function Thread( {
<CommentForm
onSubmit={ ( inputComment ) => {
if ( 'approved' === thread.status ) {
onCommentReopen( thread.id );
onEditComment( {
id: thread.id,
status: 'hold',
} );
}
onAddReply( inputComment, thread.id );
onAddReply( {
content: inputComment,
parent: thread.id,
} );
} }
onCancel={ ( event ) => {
event.stopPropagation(); // Prevent the parent onClick from being triggered
Expand Down Expand Up @@ -256,19 +252,12 @@ function Thread( {
);
}

const CommentBoard = ( {
thread,
onResolve,
onReopen,
onEdit,
onDelete,
status,
} ) => {
const CommentBoard = ( { thread, onEdit, onDelete, status } ) => {
const [ actionState, setActionState ] = useState( false );
const [ showConfirmDialog, setShowConfirmDialog ] = useState( false );

const handleConfirmDelete = () => {
onDelete( thread.id );
onDelete( thread );
setActionState( false );
setShowConfirmDialog( false );
};
Expand All @@ -295,17 +284,17 @@ const CommentBoard = ( {
setShowConfirmDialog( true );
},
},
onReopen &&
onEdit &&
status === 'approved' && {
id: 'reopen',
title: _x( 'Reopen', 'Reopen comment' ),
onClick: () => {
onReopen( thread.id );
onEdit( { id: thread.id, status: 'hold' } );
},
},
];

const canResolve = thread?.parent === 0 && onResolve;
const canResolve = thread?.parent === 0;
const moreActions = actions.filter( ( item ) => item?.onClick );

return (
Expand All @@ -329,7 +318,10 @@ const CommentBoard = ( {
disabled={ status === 'approved' }
accessibleWhenDisabled={ status === 'approved' }
onClick={ () => {
onResolve( thread.id );
onEdit( {
id: thread.id,
status: 'approved',
} );
} }
/>
) }
Expand Down Expand Up @@ -367,7 +359,10 @@ const CommentBoard = ( {
{ 'edit' === actionState ? (
<CommentForm
onSubmit={ ( value ) => {
onEdit( thread.id, value );
onEdit( {
id: thread.id,
content: value,
} );
setActionState( false );
} }
onCancel={ () => handleCancel() }
Expand Down
108 changes: 32 additions & 76 deletions packages/editor/src/components/collab-sidebar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import {
useSelect,
useDispatch,
resolveSelect,
subscribe,
} from '@wordpress/data';
import { useSelect, useDispatch, subscribe } from '@wordpress/data';
import { useState } from '@wordpress/element';
import { useViewportMatch } from '@wordpress/compose';
import { comment as commentIcon } from '@wordpress/icons';
Expand Down Expand Up @@ -58,17 +53,7 @@ function CollabSidebarContent( {
} ) {
const { createNotice } = useDispatch( noticesStore );
const { saveEntityRecord, deleteEntityRecord } = useDispatch( coreStore );
const { getEntityRecord } = resolveSelect( coreStore );

const { postId } = useSelect( ( select ) => {
const { getCurrentPostId } = select( editorStore );
const _postId = getCurrentPostId();

return {
postId: _postId,
};
}, [] );

const { getCurrentPostId } = useSelect( editorStore );
const { getSelectedBlockClientId } = useSelect( blockEditorStore );
const { updateBlockAttributes } = useDispatch( blockEditorStore );

Expand All @@ -83,31 +68,31 @@ function CollabSidebarContent( {
} );
};

const addNewComment = async ( comment, parentCommentId ) => {
const addNewComment = async ( { content, parent } ) => {
try {
const savedRecord = await saveEntityRecord(
'root',
'comment',
{
post: postId,
content: comment,
post: getCurrentPostId(),
content,
comment_type: 'block_comment',
comment_approved: 0,
...( parentCommentId ? { parent: parentCommentId } : {} ),
parent: parent || 0,
},
{ throwOnError: true }
);

// If it's a main comment, update the block attributes with the comment id.
if ( ! parentCommentId && savedRecord?.id ) {
if ( ! parent && savedRecord?.id ) {
updateBlockAttributes( getSelectedBlockClientId(), {
blockCommentId: savedRecord.id,
} );
}

createNotice(
'snackbar',
parentCommentId
parent
? __( 'Reply added successfully.' )
: __( 'Comment added successfully.' ),
{
Expand All @@ -120,78 +105,51 @@ function CollabSidebarContent( {
}
};

const onCommentResolve = async ( commentId ) => {
try {
await saveEntityRecord(
'root',
'comment',
{
id: commentId,
status: 'approved',
},
{ throwOnError: true }
);
createNotice( 'snackbar', __( 'Comment marked as resolved.' ), {
type: 'snackbar',
isDismissible: true,
} );
} catch ( error ) {
onError( error );
}
};
const onEditComment = async ( { id, content, status } ) => {
const messageType = status ? status : 'updated';
const messages = {
approved: __( 'Comment marked as resolved.' ),
hold: __( 'Comment reopened.' ),
updated: __( 'Comment updated.' ),
};

const onCommentReopen = async ( commentId ) => {
try {
await saveEntityRecord(
'root',
'comment',
{
id: commentId,
status: 'hold',
id,
content,
status,
},
{ throwOnError: true }
);
createNotice( 'snackbar', __( 'Comment reopened.' ), {
type: 'snackbar',
isDismissible: true,
} );
} catch ( error ) {
onError( error );
}
};

const onEditComment = async ( commentId, comment ) => {
try {
await saveEntityRecord(
'root',
'comment',
createNotice(
'snackbar',
messages[ messageType ] ?? __( 'Comment updated.' ),
{
id: commentId,
content: comment,
},
{ throwOnError: true }
type: 'snackbar',
isDismissible: true,
}
);
createNotice( 'snackbar', __( 'Comment updated.' ), {
type: 'snackbar',
isDismissible: true,
} );
} catch ( error ) {
onError( error );
}
};

const onCommentDelete = async ( commentId ) => {
const onCommentDelete = async ( comment ) => {
try {
const childComment = await getEntityRecord(
await deleteEntityRecord(
'root',
'comment',
commentId
comment.id,
undefined,
{
throwOnError: true,
}
);
await deleteEntityRecord( 'root', 'comment', commentId, undefined, {
throwOnError: true,
} );

if ( childComment && ! childComment.parent ) {
if ( ! comment.parent ) {
updateBlockAttributes( getSelectedBlockClientId(), {
blockCommentId: undefined,
} );
Expand Down Expand Up @@ -219,8 +177,6 @@ function CollabSidebarContent( {
onEditComment={ onEditComment }
onAddReply={ addNewComment }
onCommentDelete={ onCommentDelete }
onCommentResolve={ onCommentResolve }
onCommentReopen={ onCommentReopen }
showCommentBoard={ showCommentBoard }
setShowCommentBoard={ setShowCommentBoard }
/>
Expand Down
44 changes: 44 additions & 0 deletions test/e2e/specs/editor/various/block-comments.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,53 @@ test.describe( 'Block Comments', () => {
const resolveButton = page.getByRole( 'button', { name: 'Resolve' } );
await resolveButton.click();
await expect( resolveButton ).toBeDisabled();
await expect(
page
.getByRole( 'button', { name: 'Dismiss this notice' } )
.filter( { hasText: 'Comment marked as resolved.' } )
).toBeVisible();

await blockCommentUtils.clickBlockCommentActionMenuItem( 'Reopen' );
await expect( resolveButton ).toBeEnabled();
await expect(
page
.getByRole( 'button', { name: 'Dismiss this notice' } )
.filter( { hasText: 'Comment reopened.' } )
).toBeVisible();
} );

test( 'can reopen a resolved comment when adding a reply', async ( {
page,
blockCommentUtils,
} ) => {
await blockCommentUtils.addBlockWithComment( {
type: 'core/heading',
attributes: { content: 'Testing block comments' },
comment: 'Test comment to resolve.',
} );

const resolveButton = page.getByRole( 'button', { name: 'Resolve' } );
await resolveButton.click();
await expect( resolveButton ).toBeDisabled();
await expect(
page
.getByRole( 'button', { name: 'Dismiss this notice' } )
.filter( { hasText: 'Comment marked as resolved.' } )
).toBeVisible();

const commentForm = page.getByRole( 'textbox', { name: 'Comment' } );
await commentForm.fill( 'Test reply that reopens the comment.' );
await page
.getByRole( 'region', { name: 'Editor settings' } )
.getByRole( 'button', { name: 'Reopen & Reply', exact: true } )
.click();

await expect( resolveButton ).toBeEnabled();
await expect(
page
.getByRole( 'button', { name: 'Dismiss this notice' } )
.filter( { hasText: 'Comment reopened.' } )
).toBeVisible();
} );

test( 'selecting a block or comment marks it as an active', async ( {
Expand Down
Loading