diff --git a/apps/comments-ui/src/components/content/forms/form.tsx b/apps/comments-ui/src/components/content/forms/form.tsx index 12d86cce9cb..dc4a6121070 100644 --- a/apps/comments-ui/src/components/content/forms/form.tsx +++ b/apps/comments-ui/src/components/content/forms/form.tsx @@ -241,7 +241,7 @@ const Form: React.FC = ({ const [progress, setProgress] = useState('default'); const formEl = useRef(null); - const memberName = member?.name ?? comment?.member?.name; + const memberName = member?.name; if (progress === 'sending' || (memberName && isAskingDetails)) { // Force open @@ -289,7 +289,6 @@ const Form: React.FC = ({ }; type FormWrapperProps = { - comment?: Comment; editor: Editor | null; isOpen: boolean; reduced: boolean; @@ -298,7 +297,6 @@ type FormWrapperProps = { }; const FormWrapper: React.FC = ({ - comment, editor, isOpen, reduced, @@ -307,8 +305,8 @@ const FormWrapper: React.FC = ({ }) => { const {member, dispatchAction} = useAppContext(); - const memberName = member?.name ?? comment?.member?.name; - const memberExpertise = member?.expertise ?? comment?.member?.expertise; + const memberName = member?.name; + const memberExpertise = member?.expertise; let openStyles = ''; if (isOpen) { diff --git a/apps/comments-ui/src/components/content/forms/reply-form.tsx b/apps/comments-ui/src/components/content/forms/reply-form.tsx index 5dd72004980..dca3d3fe613 100644 --- a/apps/comments-ui/src/components/content/forms/reply-form.tsx +++ b/apps/comments-ui/src/components/content/forms/reply-form.tsx @@ -45,7 +45,7 @@ const ReplyForm: React.FC = ({openForm, parent}) => { return (
- +
{ ); }); + test('Reply form does not inherit expertise from parent comment author', async ({page}) => { + // Set logged-in member with NO expertise + mockedApi.setMember({name: 'Jane Replier', expertise: null}); + + // Add a comment from a different member who HAS expertise + mockedApi.addComment({ + html: '

This is a comment from someone with expertise

', + member: buildMember({name: 'Expert User', expertise: 'Head of Comments'}) + }); + + const {frame} = await initializeTest(page); + + // Verify the parent comment shows the author's expertise + const parentComment = frame.getByTestId('comment-component').nth(0); + await expect(parentComment).toContainText('Head of Comments'); + + // Click reply on the parent comment + const replyButton = parentComment.getByTestId('reply-button'); + await replyButton.click(); + + // Wait for reply form to appear + const replyForm = frame.getByTestId('reply-form'); + await expect(replyForm).toBeVisible(); + + const editor = replyForm.getByTestId('form-editor'); + await waitEditorFocused(editor); + + // The reply form should show the logged-in member's info, NOT the parent's + await expect(replyForm.getByTestId('member-name')).toHaveText('Jane Replier'); + + // The expertise button should show "Add your expertise" since the + // logged-in member has no expertise - it should NOT show "Head of Comments" + const expertiseButton = replyForm.getByTestId('expertise-button'); + await expect(expertiseButton).toBeVisible(); + await expect(expertiseButton).toHaveText('·Add your expertise'); + }); + + test('Reply form does not inherit name from parent comment author', async ({page}) => { + // Set logged-in member with NO name (null triggers the fallback bug) + mockedApi.setMember({name: null, expertise: 'Some Expertise'}); + + // Add a comment from a different member who HAS a name + mockedApi.addComment({ + html: '

This is a comment from someone with a name

', + member: buildMember({name: 'Named Author', expertise: null}) + }); + + const {frame} = await initializeTest(page); + + // Verify the parent comment shows the author's name + const parentComment = frame.getByTestId('comment-component').nth(0); + await expect(parentComment).toContainText('Named Author'); + + // Click reply on the parent comment + const replyButton = parentComment.getByTestId('reply-button'); + await replyButton.click(); + + // Wait for reply form to appear + const replyForm = frame.getByTestId('reply-form'); + await expect(replyForm).toBeVisible(); + + // The reply form should NOT show the parent comment author's name + // It should either show nothing, "Anonymous", or prompt for a name + // but definitely NOT "Named Author" + const memberName = replyForm.getByTestId('member-name'); + await expect(memberName).not.toHaveText('Named Author'); + }); + async function deleteComment(page, frame, commentComponent) { await commentComponent.getByTestId('more-button').first().click(); await frame.getByTestId('delete').click(); diff --git a/apps/posts/src/views/comments/comments.tsx b/apps/posts/src/views/comments/comments.tsx index d59c5843b41..8a303757b3e 100644 --- a/apps/posts/src/views/comments/comments.tsx +++ b/apps/posts/src/views/comments/comments.tsx @@ -6,11 +6,14 @@ import CommentsList from './components/comments-list'; import React, {useCallback} from 'react'; import {Button, EmptyIndicator, LoadingIndicator, LucideIcon, createFilter} from '@tryghost/shade'; import {useBrowseComments} from '@tryghost/admin-x-framework/api/comments'; +import {useBrowseConfig} from '@tryghost/admin-x-framework/api/config'; import {useFilterState} from './hooks/use-filter-state'; import {useKnownFilterValues} from './hooks/use-known-filter-values'; const Comments: React.FC = () => { const {filters, nql, setFilters} = useFilterState(); + const {data: configData} = useBrowseConfig(); + const commentPermalinksEnabled = configData?.config?.labs?.commentPermalinks === true; const handleAddFilter = useCallback((field: string, value: string, operator: string = 'is') => { setFilters((prevFilters) => { @@ -72,6 +75,7 @@ const Comments: React.FC = () => {
) : ( ( - - - +