From f3c136640612e519b690ee2d7910d24a3c37241b Mon Sep 17 00:00:00 2001 From: Simon Backx Date: Wed, 17 Jan 2024 17:06:06 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fixed=20searching=20posts=20in?= =?UTF-8?q?=20member=20filters=20(#19505)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixes PROD-201 The issue was caused because we were searching the 'name' field instead of the 'title' field. This also increases the performance when loading the posts: - Makes sure no relations are loaded - Only return the fields we actually need - Stop using limit=all, and replaced it with network based search --- .../app/components/gh-resource-select.js | 60 +++++++++++++++---- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/ghost/admin/app/components/gh-resource-select.js b/ghost/admin/app/components/gh-resource-select.js index 9bc2f08f59..061399cd85 100644 --- a/ghost/admin/app/components/gh-resource-select.js +++ b/ghost/admin/app/components/gh-resource-select.js @@ -6,9 +6,18 @@ import { filterOptions } from 'ember-power-select/utils/group-utils'; import {inject as service} from '@ember/service'; -import {task} from 'ember-concurrency'; +import {task, timeout} from 'ember-concurrency'; import {tracked} from '@glimmer/tracking'; +const DEBOUNCE_MS = 200; + +function mapResource(resource) { + return { + id: resource.id, + title: resource.title + }; +} + export default class GhResourceSelect extends Component { @service store; @@ -19,7 +28,7 @@ export default class GhResourceSelect extends Component { } get searchField() { - return this.args.searchField === undefined ? 'name' : this.args.searchField; + return this.args.searchField === undefined ? 'title' : this.args.searchField; } @action @@ -40,6 +49,11 @@ export default class GhResourceSelect extends Component { newOptions = this._filter(A(newOptions), term); + if (newOptions.length === 0) { + // Do a query lookup + newOptions = yield this.fetchOptionsForSearchTask.perform(term); + } + return newOptions; } @@ -112,23 +126,16 @@ export default class GhResourceSelect extends Component { @task *fetchOptionsTask() { const options = yield []; - + if (this.args.type === 'email') { - const posts = yield this.store.query('post', {filter: '(status:published,status:sent)+newsletter_id:-null', limit: 'all'}); + const posts = yield this.store.query('post', {filter: '(status:published,status:sent)+newsletter_id:-null', limit: '25', fields: 'id,title'}); options.push(...posts.map(mapResource)); this._options = options; return; } - const posts = yield this.store.query('post', {filter: 'status:published', limit: 'all'}); - const pages = yield this.store.query('page', {filter: 'status:published', limit: 'all'}); - - function mapResource(resource) { - return { - id: resource.id, - title: resource.title - }; - } + const posts = yield this.store.query('post', {filter: 'status:published', limit: '25', fields: 'id,title'}); + const pages = yield this.store.query('page', {filter: 'status:published', limit: '25', fields: 'id,title'}); if (posts.length > 0) { options.push({ @@ -146,4 +153,31 @@ export default class GhResourceSelect extends Component { this._options = options; } + + @task({restartable: true}) + *fetchOptionsForSearchTask(searchTerm) { + // Debounce + yield timeout(DEBOUNCE_MS); + + const options = yield []; + + if (this.args.type === 'email') { + const posts = yield this.store.query('post', {filter: '(status:published,status:sent)+newsletter_id:-null+title:~\'' + searchTerm.replace('\'', '\\\'') + '\'', limit: '10', fields: 'id,title'}); + options.push(...posts.map(mapResource)); + return options; + } + + const posts = yield this.store.query('post', {filter: 'status:published+title:~\'' + searchTerm.replace('\'', '\\\'') + '\'', limit: '10', fields: 'id,title'}); + const pages = yield this.store.query('page', {filter: 'status:published+title:~\'' + searchTerm.replace('\'', '\\\'') + '\'', limit: '10', fields: 'id,title'}); + + if (posts.length > 0) { + options.push(...posts.map(mapResource)); + } + + if (pages.length > 0) { + options.push(...pages.map(mapResource)); + } + + return options; + } }