mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-06 22:40:14 -05:00
Fixed incorrect pagination after deleting top level comment
closes https://linear.app/ghost/issue/PLG-304 - added a refresh of the comments list when a top-level comment with no replies is deleted so the pagination resets and replies aren't missed when loading more due to a shift in the underlying paginated data
This commit is contained in:
parent
962939b99a
commit
137ea89a7b
3 changed files with 34 additions and 3 deletions
|
@ -271,7 +271,7 @@ async function unlikeComment({state, api, data: comment}: {state: EditableAppCon
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteComment({state, api, data: comment}: {state: EditableAppContext, api: GhostApi, data: {id: string}}) {
|
async function deleteComment({state, api, data: comment, dispatchAction}: {state: EditableAppContext, api: GhostApi, data: {id: string}, dispatchAction: DispatchActionType}) {
|
||||||
await api.comments.edit({
|
await api.comments.edit({
|
||||||
comment: {
|
comment: {
|
||||||
id: comment.id,
|
id: comment.id,
|
||||||
|
@ -279,6 +279,14 @@ async function deleteComment({state, api, data: comment}: {state: EditableAppCon
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// If we're deleting a top-level comment with no replies we refresh the
|
||||||
|
// whole comments section to maintain correct pagination
|
||||||
|
const commentToDelete = state.comments.find(c => c.id === comment.id);
|
||||||
|
if (commentToDelete && (!commentToDelete.replies || commentToDelete.replies.length === 0)) {
|
||||||
|
dispatchAction('setOrder', {order: state.order});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
comments: state.comments.map((topLevelComment) => {
|
comments: state.comments.map((topLevelComment) => {
|
||||||
// If the comment has replies we want to keep it so the replies are
|
// If the comment has replies we want to keep it so the replies are
|
||||||
|
|
|
@ -433,6 +433,22 @@ test.describe('Actions', async () => {
|
||||||
await expect(frame.getByTestId('replies-line')).toBeVisible();
|
await expect(frame.getByTestId('replies-line')).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Resets comments list after deleting a top-level comment', async ({page}) => {
|
||||||
|
const loggedInMember = buildMember();
|
||||||
|
mockedApi.setMember(loggedInMember);
|
||||||
|
// We have a page limit of 20, this will show the load more button
|
||||||
|
mockedApi.addComments(21, {member: loggedInMember});
|
||||||
|
|
||||||
|
const {frame} = await initializeTest(page);
|
||||||
|
await expect(frame.getByTestId('pagination-component')).toBeVisible();
|
||||||
|
|
||||||
|
const commentToDelete = frame.getByTestId('comment-component').nth(0);
|
||||||
|
await deleteComment(page, frame, commentToDelete);
|
||||||
|
|
||||||
|
// more button should have disappeared because the list was reloaded
|
||||||
|
await expect(frame.getByTestId('pagination-component')).not.toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
test.describe('Sorting', () => {
|
test.describe('Sorting', () => {
|
||||||
test('Renders Sorting Form dropdown', async ({page}) => {
|
test('Renders Sorting Form dropdown', async ({page}) => {
|
||||||
mockedApi.addComment({
|
mockedApi.addComment({
|
||||||
|
|
|
@ -330,7 +330,7 @@ export class MockedApi {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async getComment(route) {
|
async getOrDeleteComment(route) {
|
||||||
await this.#delayResponse();
|
await this.#delayResponse();
|
||||||
const url = new URL(route.request().url());
|
const url = new URL(route.request().url());
|
||||||
const commentId = url.pathname.split('/').reverse()[1];
|
const commentId = url.pathname.split('/').reverse()[1];
|
||||||
|
@ -344,6 +344,13 @@ export class MockedApi {
|
||||||
order: ''
|
order: ''
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (route.request().method() === 'PUT' && JSON.parse(route.request().postData()).comments?.[0]?.status === 'deleted') {
|
||||||
|
const comment = findCommentById(this.comments, commentId);
|
||||||
|
if (comment) {
|
||||||
|
comment.status = 'deleted';
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async likeComment(route) {
|
async likeComment(route) {
|
||||||
|
@ -523,7 +530,7 @@ export class MockedApi {
|
||||||
await page.route(`${path}/members/api/member/`, this.requestHandlers.getMember.bind(this));
|
await page.route(`${path}/members/api/member/`, this.requestHandlers.getMember.bind(this));
|
||||||
await page.route(`${path}/members/api/comments/*`, this.requestHandlers.addComment.bind(this));
|
await page.route(`${path}/members/api/comments/*`, this.requestHandlers.addComment.bind(this));
|
||||||
await page.route(`${path}/members/api/comments/post/*/*`, this.requestHandlers.browseComments.bind(this));
|
await page.route(`${path}/members/api/comments/post/*/*`, this.requestHandlers.browseComments.bind(this));
|
||||||
await page.route(`${path}/members/api/comments/*/`, this.requestHandlers.getComment.bind(this));
|
await page.route(`${path}/members/api/comments/*/`, this.requestHandlers.getOrDeleteComment.bind(this));
|
||||||
await page.route(`${path}/members/api/comments/*/like/`, this.requestHandlers.likeComment.bind(this));
|
await page.route(`${path}/members/api/comments/*/like/`, this.requestHandlers.likeComment.bind(this));
|
||||||
await page.route(`${path}/members/api/comments/*/replies/*`, this.requestHandlers.getReplies.bind(this));
|
await page.route(`${path}/members/api/comments/*/replies/*`, this.requestHandlers.getReplies.bind(this));
|
||||||
await page.route(`${path}/members/api/comments/counts/*`, this.requestHandlers.getCommentCounts.bind(this));
|
await page.route(`${path}/members/api/comments/counts/*`, this.requestHandlers.getCommentCounts.bind(this));
|
||||||
|
|
Loading…
Reference in a new issue