Ghost/ghost/admin/app/controllers/members-activity.js
Kevin Ansfield 98eb75ef06 Added member search/filter UI to the members-activity screen
refs https://github.com/TryGhost/Team/issues/1290

- renamed `@updateExcludedEvents` to `@onChange` and updated associated action name so we have consistent naming for our select-like components
- added `<MembersActivity::MemberFilter>` component
  - utilises `<PowerSelect>` with a custom trigger component and  and a debounced search via the member's API
  - does not use `<PowerSelect>`'s default "selected" behaviour in favor of replacing the select with a button to provide a clearer "reset filter" UX that's easier to build/style outside of the power-select components
  - added `.ember-power-select-trigger-reset` class to reset margins, paddings, borders, and heights so that it's easier for a custom trigger's contents to control the display
2022-01-27 15:00:40 +00:00

66 lines
1.7 KiB
JavaScript

import Controller from '@ember/controller';
import {action} from '@ember/object';
import {inject as service} from '@ember/service';
import {tracked} from '@glimmer/tracking';
export default class MembersActivityController extends Controller {
@service router;
@service store;
queryParams = ['excludedEvents', 'member'];
@tracked excludedEvents = null;
@tracked member = null;
get filter() {
const filterParts = [];
filterParts.push(this._getTypeFilter());
filterParts.push(this._getMemberFilter());
return filterParts.filter(p => !!p).join('+');
}
get memberRecord() {
if (!this.member) {
return null;
}
// TODO: {reload: true} here shouldn't be needed but without it
// the template renders nothing if the record is already in the store
return this.store.findRecord('member', this.member, {reload: true});
}
@action
changeExcludedEvents(newList) {
this.router.transitionTo({queryParams: {excludedEvents: newList}});
}
@action
changeMember(member) {
this.router.transitionTo({queryParams: {member: member?.id}});
}
_getTypeFilter() {
let excludedEvents = this.member ?
new Set() :
new Set(['email_opened_event', 'email_delivered_event', 'email_failed_event']);
(this.excludedEvents || '').split(',').forEach(event => event && excludedEvents.add(event));
if (excludedEvents.size > 0) {
return `type:-[${Array.from(excludedEvents).join(',')}]`;
} else {
return;
}
}
_getMemberFilter() {
if (!this.member) {
return;
}
return `data.member_id:${this.member}`;
}
}