mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-26 12:21:36 +03:00
Added server-side search to new members screen (#1582)
requires https://github.com/TryGhost/Ghost/pull/11854 - ties the search input on the members screen to a `?search` query param, debounced at 250ms to avoid unnecessary API requests and UI churn - updated the members route's `model` hook to pass through the search param in the API request query parameters
This commit is contained in:
parent
76b93c3be7
commit
ff33eb978b
@ -7,17 +7,19 @@ import {formatNumber} from 'ghost-admin/helpers/format-number';
|
||||
import {pluralize} from 'ember-inflector';
|
||||
import {inject as service} from '@ember/service';
|
||||
import {task} from 'ember-concurrency-decorators';
|
||||
import {timeout} from 'ember-concurrency';
|
||||
import {tracked} from '@glimmer/tracking';
|
||||
|
||||
export default class MembersController extends Controller {
|
||||
@service feature;
|
||||
@service store;
|
||||
|
||||
queryParams = ['label'];
|
||||
queryParams = ['label', {searchParam: 'search'}];
|
||||
|
||||
@alias('model') members;
|
||||
|
||||
@tracked searchText = '';
|
||||
@tracked searchParam = '';
|
||||
@tracked label = null;
|
||||
@tracked modalLabel = null;
|
||||
@tracked showLabelModal = false;
|
||||
@ -56,7 +58,7 @@ export default class MembersController extends Controller {
|
||||
}
|
||||
|
||||
get showingAll() {
|
||||
return !this.searchText && !this.label;
|
||||
return !this.searchParam && !this.label;
|
||||
}
|
||||
|
||||
get availableLabels() {
|
||||
@ -88,6 +90,11 @@ export default class MembersController extends Controller {
|
||||
|
||||
// Actions -----------------------------------------------------------------
|
||||
|
||||
@action
|
||||
search(e) {
|
||||
this.searchTask.perform(e.target.value);
|
||||
}
|
||||
|
||||
@action
|
||||
exportData() {
|
||||
let exportUrl = ghostPaths().url.api('members/csv');
|
||||
@ -141,6 +148,12 @@ export default class MembersController extends Controller {
|
||||
|
||||
// Tasks -------------------------------------------------------------------
|
||||
|
||||
@task({restartable: true})
|
||||
*searchTask(query) {
|
||||
yield timeout(250); // debounce
|
||||
this.searchParam = query;
|
||||
}
|
||||
|
||||
@task
|
||||
*fetchLabelsTask() {
|
||||
if (!this._hasLoadedLabels) {
|
||||
@ -149,4 +162,10 @@ export default class MembersController extends Controller {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Internal ----------------------------------------------------------------
|
||||
|
||||
resetSearch() {
|
||||
this.searchText = '';
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,8 @@ export const DEFAULT_QUERY_PARAMS = {
|
||||
order: null
|
||||
},
|
||||
'members.index': {
|
||||
label: null
|
||||
label: null,
|
||||
searchParam: ''
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -8,7 +8,8 @@ export default class MembersRoute extends AuthenticatedRoute {
|
||||
@service store;
|
||||
|
||||
queryParams = {
|
||||
label: {refreshModel: true}
|
||||
label: {refreshModel: true},
|
||||
searchParam: {refreshModel: true, replace: true}
|
||||
};
|
||||
|
||||
// redirect to posts screen if:
|
||||
@ -24,12 +25,17 @@ export default class MembersRoute extends AuthenticatedRoute {
|
||||
}
|
||||
|
||||
model(params) {
|
||||
if (!params.searchParam) {
|
||||
this.controllerFor('members').resetSearch();
|
||||
}
|
||||
|
||||
// use a fixed created_at date so that subsequent pages have a consistent index
|
||||
let startDate = new Date();
|
||||
|
||||
// bypass the stale data shortcut if params change
|
||||
let forceReload = params.label !== this._lastLabel;
|
||||
let forceReload = params.label !== this._lastLabel || params.searchParam !== this._lastSearchParam;
|
||||
this._lastLabel = params.label;
|
||||
this._lastSearchParam = params.searchParam;
|
||||
|
||||
// unless we have a forced reload, do not re-fetch the members list unless it's more than a minute old
|
||||
// keeps navigation between list->details->list snappy
|
||||
@ -46,7 +52,8 @@ export default class MembersRoute extends AuthenticatedRoute {
|
||||
limit: range.length,
|
||||
page: range.start / range.length,
|
||||
order: 'created_at desc',
|
||||
filter: `${labelFilter}created_at:<='${moment.utc(this._startDate).format('YYYY-MM-DD HH:mm:ss')}'`
|
||||
filter: `${labelFilter}created_at:<='${moment.utc(this._startDate).format('YYYY-MM-DD HH:mm:ss')}'`,
|
||||
search: params.searchParam
|
||||
}, query);
|
||||
|
||||
return this.store.query('member', query).then((result) => {
|
||||
|
@ -13,9 +13,8 @@
|
||||
{{svg-jar "search" class="gh-input-search-icon"}}
|
||||
<GhTextInput
|
||||
placeholder="Search members..."
|
||||
@disabled={{true}}
|
||||
@value={{this.searchText}}
|
||||
@input={{action (mut this.searchText) value="target.value"}}
|
||||
@input={{this.search}}
|
||||
class="gh-members-list-searchfield {{if this.searchText "active"}}" />
|
||||
</div>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user