Revert "Improved performance in Admin Posts view (#20503)" (#20514)

ref https://linear.app/tryghost/issue/ONC-111

This reverts commit 3d9d552271.

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.
This commit is contained in:
Steve Larson 2024-07-02 09:27:44 -05:00 committed by GitHub
parent 3618632129
commit fe31ee34e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 49 additions and 97 deletions

View File

@ -1,39 +1,14 @@
<MultiList::List @model={{@list}} class="posts-list gh-list {{unless @model "no-posts"}} feature-memberAttribution" as |list| >
{{!-- always order as scheduled, draft, remainder --}}
{{#if (or @model.scheduledPosts (or @model.draftPosts @model.publishedAndSentPosts))}}
{{#if @model.scheduledPosts}}
{{#each @model.scheduledPosts as |post|}}
<list.item @id={{post.id}} class="gh-posts-list-item-group">
<PostsList::ListItem
@post={{post}}
data-test-post-id={{post.id}}
/>
</list.item>
{{/each}}
{{/if}}
{{#if (and @model.draftPosts (or (not @model.scheduledPosts) (and @model.scheduledPosts @model.scheduledPosts.reachedInfinity)))}}
{{#each @model.draftPosts as |post|}}
<list.item @id={{post.id}} class="gh-posts-list-item-group">
<PostsList::ListItem
@post={{post}}
data-test-post-id={{post.id}}
/>
</list.item>
{{/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|}}
<list.item @id={{post.id}} class="gh-posts-list-item-group">
<PostsList::ListItem
@post={{post}}
data-test-post-id={{post.id}}
/>
</list.item>
{{/each}}
{{/if}}
{{#each @model as |post|}}
<list.item @id={{post.id}} class="gh-posts-list-item-group">
<PostsList::ListItem
@post={{post}}
data-test-post-id={{post.id}}
/>
</list.item>
{{else}}
{{yield}}
{{/if}}
{{/each}}
</MultiList::List>
{{!-- The currently selected item or items are passed to the context menu --}}

View File

@ -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]';

View File

@ -30,7 +30,7 @@
<section class="view-container content-list">
<PostsList::List
@model={{@model}}
@model={{this.postsInfinityModel}}
@list={{this.selectionList}}
>
<li class="no-posts-box" data-test-no-posts-box>
@ -51,26 +51,11 @@
</li>
</PostsList::List>
{{!-- only show one infinity loader wheel at a time - always order as scheduled, draft, remainder --}}
{{#if @model.scheduledPosts}}
<GhInfinityLoader
@infinityModel={{@model.scheduledPosts}}
@infinityModel={{this.postsInfinityModel}}
@scrollable=".gh-main"
@triggerOffset={{1000}} />
{{/if}}
{{#if (and @model.draftPosts (or (not @model.scheduledPosts) (and @model.scheduledPosts @model.scheduledPosts.reachedInfinity)))}}
<GhInfinityLoader
@infinityModel={{@model.draftPosts}}
@scrollable=".gh-main"
@triggerOffset={{1000}} />
{{/if}}
{{#if (and @model.publishedAndSentPosts (and (or (not @model.scheduledPosts) @model.scheduledPosts.reachedInfinity) (or (not @model.draftPosts) @model.draftPosts.reachedInfinity)))}}
<GhInfinityLoader
@infinityModel={{@model.publishedAndSentPosts}}
@scrollable=".gh-main"
@triggerOffset={{1000}} />
{{/if}}
</section>
{{outlet}}
</section>

View File

@ -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