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