1f2857e0e4
no issue When we open the editor, we fire 4 requests to fetch member counts. This commit fixes this by replacing those calls with the members count cache service.
105 lines
3.0 KiB
JavaScript
105 lines
3.0 KiB
JavaScript
import LimitService from '@tryghost/limit-service';
|
|
import RSVP from 'rsvp';
|
|
import Service, {inject as service} from '@ember/service';
|
|
import {bind} from '@ember/runloop';
|
|
import {inject} from 'ghost-admin/decorators/inject';
|
|
|
|
class LimitError {
|
|
constructor({errorType, errorDetails, message}) {
|
|
this.errorType = errorType;
|
|
this.errorDetails = errorDetails;
|
|
this.message = message;
|
|
}
|
|
}
|
|
|
|
class IncorrectUsageError extends LimitError {
|
|
constructor(options) {
|
|
super(Object.assign({errorType: 'IncorrectUsageError'}, options));
|
|
}
|
|
}
|
|
|
|
class HostLimitError extends LimitError {
|
|
constructor(options) {
|
|
super(Object.assign({errorType: 'HostLimitError'}, options));
|
|
}
|
|
}
|
|
|
|
export default class LimitsService extends Service {
|
|
@service store;
|
|
@service membersStats;
|
|
@service membersCountCache;
|
|
|
|
@inject config;
|
|
|
|
constructor() {
|
|
super(...arguments);
|
|
|
|
let limits = this.config.hostSettings?.limits;
|
|
|
|
this.limiter = new LimitService();
|
|
|
|
if (!limits) {
|
|
return;
|
|
}
|
|
|
|
let helpLink;
|
|
|
|
if (this.config.hostSettings?.billing?.enabled === true && this.config.hostSettings?.billing?.url) {
|
|
helpLink = this.config.hostSettings.billing?.url;
|
|
} else {
|
|
helpLink = 'https://ghost.org/help/';
|
|
}
|
|
|
|
this.limiter.loadLimits({
|
|
limits: this.decorateWithCountQueries(limits),
|
|
helpLink,
|
|
errors: {
|
|
HostLimitError,
|
|
IncorrectUsageError
|
|
}
|
|
});
|
|
}
|
|
|
|
async checkWouldGoOverLimit(limitName, metadata = {}) {
|
|
return this.limiter.checkWouldGoOverLimit(limitName, metadata);
|
|
}
|
|
|
|
decorateWithCountQueries(limits) {
|
|
if (limits.staff) {
|
|
limits.staff.currentCountQuery = bind(this, this.getStaffUsersCount);
|
|
}
|
|
|
|
if (limits.members) {
|
|
limits.members.currentCountQuery = bind(this, this.getMembersCount);
|
|
}
|
|
|
|
if (limits.newsletters) {
|
|
limits.newsletters.currentCountQuery = bind(this, this.getNewslettersCount);
|
|
}
|
|
|
|
return limits;
|
|
}
|
|
|
|
async getStaffUsersCount() {
|
|
return RSVP.hash({
|
|
users: this.store.findAll('user', {reload: true}),
|
|
invites: this.store.findAll('invite', {reload: true}),
|
|
roles: this.store.findAll('role', {reload: true}) // NOTE: roles have to be fetched as they are not always loaded with invites
|
|
}).then((data) => {
|
|
const staffUsers = data.users.filter(u => u.get('status') !== 'inactive' && u.role.get('name') !== 'Contributor');
|
|
const staffInvites = data.invites.filter(i => i.role.get('name') !== 'Contributor');
|
|
|
|
return staffUsers.length + staffInvites.length;
|
|
});
|
|
}
|
|
|
|
async getMembersCount() {
|
|
return this.membersCountCache.count({});
|
|
}
|
|
|
|
async getNewslettersCount() {
|
|
const activeNewsletters = await this.store.query('newsletter', {filter: 'status:active', limit: 'all'});
|
|
return activeNewsletters.length;
|
|
}
|
|
}
|