From fe31ee34e8c4dce6bfdd81ef8960c5c2fefd0518 Mon Sep 17 00:00:00 2001
From: Steve Larson <9larsons@gmail.com>
Date: Tue, 2 Jul 2024 09:27:44 -0500
Subject: [PATCH] Revert "Improved performance in Admin Posts view (#20503)"
(#20514)
ref https://linear.app/tryghost/issue/ONC-111
This reverts commit 3d9d5522719fafc99d6a354862f10c2e606b782b.
This commit broke bulk post actions which we do not have tests for, so
we will need to address that as well as add tests.
---
.../admin/app/components/posts-list/list.hbs | 41 ++++-------------
ghost/admin/app/routes/posts.js | 45 ++++++-------------
ghost/admin/app/templates/posts.hbs | 21 ++-------
ghost/admin/tests/acceptance/content-test.js | 39 +++++++++-------
4 files changed, 49 insertions(+), 97 deletions(-)
diff --git a/ghost/admin/app/components/posts-list/list.hbs b/ghost/admin/app/components/posts-list/list.hbs
index b1ab3acd99..4755c76d62 100644
--- a/ghost/admin/app/components/posts-list/list.hbs
+++ b/ghost/admin/app/components/posts-list/list.hbs
@@ -1,39 +1,14 @@
- {{!-- always order as scheduled, draft, remainder --}}
- {{#if (or @model.scheduledPosts (or @model.draftPosts @model.publishedAndSentPosts))}}
- {{#if @model.scheduledPosts}}
- {{#each @model.scheduledPosts as |post|}}
-
-
-
- {{/each}}
- {{/if}}
- {{#if (and @model.draftPosts (or (not @model.scheduledPosts) (and @model.scheduledPosts @model.scheduledPosts.reachedInfinity)))}}
- {{#each @model.draftPosts as |post|}}
-
-
-
- {{/each}}
- {{/if}}
- {{#if (and @model.publishedAndSentPosts (and (or (not @model.scheduledPosts) @model.scheduledPosts.reachedInfinity) (or (not @model.draftPosts) @model.draftPosts.reachedInfinity)))}}
- {{#each @model.publishedAndSentPosts as |post|}}
-
-
-
- {{/each}}
- {{/if}}
+ {{#each @model as |post|}}
+
+
+
{{else}}
{{yield}}
- {{/if}}
+ {{/each}}
{{!-- The currently selected item or items are passed to the context menu --}}
diff --git a/ghost/admin/app/routes/posts.js b/ghost/admin/app/routes/posts.js
index f4e6966403..93e7d5d4ab 100644
--- a/ghost/admin/app/routes/posts.js
+++ b/ghost/admin/app/routes/posts.js
@@ -1,5 +1,4 @@
import AuthenticatedRoute from 'ghost-admin/routes/authenticated';
-import RSVP from 'rsvp';
import {action} from '@ember/object';
import {assign} from '@ember/polyfills';
import {isBlank} from '@ember/utils';
@@ -47,46 +46,36 @@ export default class PostsRoute extends AuthenticatedRoute {
totalPagesParam: 'meta.pagination.pages'
};
- // type filters are actually mapping statuses
assign(filterParams, this._getTypeFilters(params.type));
if (params.type === 'featured') {
filterParams.featured = true;
}
- // authors and contributors can only view their own posts
if (user.isAuthor) {
+ // authors can only view their own posts
filterParams.authors = user.slug;
} else if (user.isContributor) {
+ // Contributors can only view their own draft posts
filterParams.authors = user.slug;
- // otherwise we need to filter by author if present
+ // filterParams.status = 'draft';
} else if (params.author) {
filterParams.authors = params.author;
}
+ let filter = this._filterString(filterParams);
+ if (!isBlank(filter)) {
+ queryParams.filter = filter;
+ }
+
+ if (!isBlank(params.order)) {
+ queryParams.order = params.order;
+ }
+
let perPage = this.perPage;
+ let paginationSettings = assign({perPage, startingPage: 1}, paginationParams, queryParams);
- const filterStatuses = filterParams.status;
- let models = {};
- if (filterStatuses.includes('scheduled')) {
- let scheduledPostsParams = {...queryParams, order: params.order || 'published_at desc', filter: this._filterString({...filterParams, status: 'scheduled'})};
- models.scheduledPosts = this.infinity.model('post', assign({perPage, startingPage: 1}, paginationParams, scheduledPostsParams));
- }
- if (filterStatuses.includes('draft')) {
- let draftPostsParams = {...queryParams, order: params.order || 'updated_at desc', filter: this._filterString({...filterParams, status: 'draft'})};
- models.draftPosts = this.infinity.model('post', assign({perPage, startingPage: 1}, paginationParams, draftPostsParams));
- }
- if (filterStatuses.includes('published') || filterStatuses.includes('sent')) {
- let publishedAndSentPostsParams;
- if (filterStatuses.includes('published') && filterStatuses.includes('sent')) {
- publishedAndSentPostsParams = {...queryParams, order: params.order || 'published_at desc', filter: this._filterString({...filterParams, status: '[published,sent]'})};
- } else {
- publishedAndSentPostsParams = {...queryParams, order: params.order || 'published_at desc', filter: this._filterString({...filterParams, status: filterStatuses.includes('published') ? 'published' : 'sent'})};
- }
- models.publishedAndSentPosts = this.infinity.model('post', assign({perPage, startingPage: 1}, paginationParams, publishedAndSentPostsParams));
- }
-
- return RSVP.hash(models);
+ return this.infinity.model(this.modelName, paginationSettings);
}
// trigger a background load of all tags and authors for use in filter dropdowns
@@ -131,12 +120,6 @@ export default class PostsRoute extends AuthenticatedRoute {
};
}
- /**
- * Returns an object containing the status filter based on the given type.
- *
- * @param {string} type - The type of filter to generate (draft, published, scheduled, sent).
- * @returns {Object} - An object containing the status filter.
- */
_getTypeFilters(type) {
let status = '[draft,scheduled,published,sent]';
diff --git a/ghost/admin/app/templates/posts.hbs b/ghost/admin/app/templates/posts.hbs
index abe3f88a47..f0d0b6bbe8 100644
--- a/ghost/admin/app/templates/posts.hbs
+++ b/ghost/admin/app/templates/posts.hbs
@@ -30,7 +30,7 @@
@@ -51,26 +51,11 @@
- {{!-- only show one infinity loader wheel at a time - always order as scheduled, draft, remainder --}}
- {{#if @model.scheduledPosts}}
- {{/if}}
- {{#if (and @model.draftPosts (or (not @model.scheduledPosts) (and @model.scheduledPosts @model.scheduledPosts.reachedInfinity)))}}
-
- {{/if}}
- {{#if (and @model.publishedAndSentPosts (and (or (not @model.scheduledPosts) @model.scheduledPosts.reachedInfinity) (or (not @model.draftPosts) @model.draftPosts.reachedInfinity)))}}
-
- {{/if}}
-
+
{{outlet}}
diff --git a/ghost/admin/tests/acceptance/content-test.js b/ghost/admin/tests/acceptance/content-test.js
index 996f4eec00..da312358da 100644
--- a/ghost/admin/tests/acceptance/content-test.js
+++ b/ghost/admin/tests/acceptance/content-test.js
@@ -1,6 +1,6 @@
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
import {beforeEach, describe, it} from 'mocha';
-import {blur, click, currentURL, fillIn, find, findAll, visit} from '@ember/test-helpers';
+import {blur, click, currentURL, fillIn, find, findAll, settled, visit} from '@ember/test-helpers';
import {clickTrigger, selectChoose} from 'ember-power-select/test-support/helpers';
import {expect} from 'chai';
import {setupApplicationTest} from 'ember-mocha';
@@ -41,7 +41,7 @@ describe('Acceptance: Content', function () {
return await authenticateSession();
});
- it('displays and filters posts', async function () {
+ it.skip('displays and filters posts', async function () {
await visit('/posts');
// Not checking request here as it won't be the last request made
// Displays all posts + pages
@@ -81,29 +81,38 @@ describe('Acceptance: Content', function () {
// show all posts
await selectChoose('[data-test-type-select]', 'All posts');
- // Posts are ordered scheduled -> draft -> published/sent
- // check API request is correct - we submit one request for scheduled, one for drafts, and one for published+sent
- [lastRequest] = this.server.pretender.handledRequests.slice(-3);
- expect(lastRequest.queryParams.filter, '"all" request status filter').to.have.string('status:scheduled');
- [lastRequest] = this.server.pretender.handledRequests.slice(-2);
- expect(lastRequest.queryParams.filter, '"all" request status filter').to.have.string('status:draft');
+ // API request is correct
[lastRequest] = this.server.pretender.handledRequests.slice(-1);
- expect(lastRequest.queryParams.filter, '"all" request status filter').to.have.string('status:[published,sent]');
-
- // check order display is correct
- let postIds = findAll('[data-test-post-id]').map(el => el.getAttribute('data-test-post-id'));
- expect(postIds, 'post order').to.deep.equal([scheduledPost.id, draftPost.id, publishedPost.id, authorPost.id]);
+ expect(lastRequest.queryParams.filter, '"all" request status filter').to.have.string('status:[draft,scheduled,published]');
// show all posts by editor
- await selectChoose('[data-test-type-select]', 'Published posts');
await selectChoose('[data-test-author-select]', editor.name);
// API request is correct
[lastRequest] = this.server.pretender.handledRequests.slice(-1);
expect(lastRequest.queryParams.filter, '"editor" request status filter')
- .to.have.string('status:published');
+ .to.have.string('status:[draft,scheduled,published]');
expect(lastRequest.queryParams.filter, '"editor" request filter param')
.to.have.string(`authors:${editor.slug}`);
+
+ // Post status is only visible when members is enabled
+ expect(find('[data-test-visibility-select]'), 'access dropdown before members enabled').to.not.exist;
+ let featureService = this.owner.lookup('service:feature');
+ featureService.set('members', true);
+ await settled();
+ expect(find('[data-test-visibility-select]'), 'access dropdown after members enabled').to.exist;
+
+ await selectChoose('[data-test-visibility-select]', 'Paid members-only');
+ [lastRequest] = this.server.pretender.handledRequests.slice(-1);
+ expect(lastRequest.queryParams.filter, '"visibility" request filter param')
+ .to.have.string('visibility:[paid,tiers]+status:[draft,scheduled,published]');
+
+ // Displays editor post
+ // TODO: implement "filter" param support and fix mirage post->author association
+ // expect(find('[data-test-post-id]').length, 'editor post count').to.equal(1);
+ // expect(find(`[data-test-post-id="${authorPost.id}"]`), 'author post').to.exist;
+
+ // TODO: test tags dropdown
});
// TODO: skipped due to consistently random failures on Travis