0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-24 23:48:13 -05:00

Added newsletter open rate stats

refs https://github.com/TryGhost/Team/issues/469

- Adds new chart to track newsletter open rates on dashboard
This commit is contained in:
Rish 2021-02-22 13:59:48 +05:30 committed by Rishabh Garg
parent 6592fabbe9
commit e554e26b02
3 changed files with 72 additions and 1 deletions

View file

@ -38,6 +38,13 @@ export default class DashboardController extends Controller {
@tracked @tracked
topMembersLoading = false; topMembersLoading = false;
@tracked
newsletterOpenRatesData = null;
@tracked
newsletterOpenRatesError = null;
@tracked
newsletterOpenRatesLoading = false;
get showTopMembers() { get showTopMembers() {
return this.feature.get('emailAnalytics') && this.settings.get('emailTrackOpens'); return this.feature.get('emailAnalytics') && this.settings.get('emailTrackOpens');
} }
@ -130,6 +137,7 @@ export default class DashboardController extends Controller {
loadCharts() { loadCharts() {
this.loadMRRStats(); this.loadMRRStats();
this.loadMemberCountStats(); this.loadMemberCountStats();
this.loadNewsletterOpenRates();
} }
loadEvents() { loadEvents() {
@ -143,6 +151,28 @@ export default class DashboardController extends Controller {
}); });
} }
loadNewsletterOpenRates() {
this.newsletterOpenRatesLoading = true;
this.membersStats.fetchNewsletterStats().then((results) => {
this.newsletterOpenRatesData = {
options: {
rangeInDays: 30
},
data: {
label: 'Open Rate',
dateLabels: results.map(d => d.submittedAt),
dateValues: results.map(d => d.openRate)
},
title: 'Open Rate',
stats: results
};
this.newsletterOpenRatesLoading = false;
}, (error) => {
this.newsletterOpenRatesError = error;
this.newsletterOpenRatesLoading = false;
});
}
loadTopMembers() { loadTopMembers() {
this.topMembersLoading = true; this.topMembersLoading = true;
let query = { let query = {

View file

@ -7,12 +7,14 @@ import {tracked} from '@glimmer/tracking';
export default class MembersStatsService extends Service { export default class MembersStatsService extends Service {
@service ajax; @service ajax;
@service ghostPaths; @service ghostPaths;
@service store;
@tracked days = '30'; @tracked days = '30';
@tracked stats = null; @tracked stats = null;
@tracked events = null; @tracked events = null;
@tracked countStats = null; @tracked countStats = null;
@tracked mrrStats = null; @tracked mrrStats = null;
@tracked newsletterStats = null;
fetch() { fetch() {
let daysChanged = this._lastFetchedDays !== this.days; let daysChanged = this._lastFetchedDays !== this.days;
@ -61,6 +63,22 @@ export default class MembersStatsService extends Service {
return this._fetchCountsTask.perform(); return this._fetchCountsTask.perform();
} }
fetchNewsletterStats() {
let staleData = this._lastFetchedNewsletterStats && this._lastFetchedNewsletterStats - new Date() > 1 * 60 * 1000;
// return an already in-progress promise unless params have changed
if (this._fetchNewsletterStatsTask.isRunning) {
return this._fetchNewsletterStatsTask.last;
}
// return existing stats unless data is > 1 min old
if (this.newsletterStats && !this._forceRefresh && !staleData) {
return Promise.resolve(this.countStats);
}
return this._fetchNewsletterStatsTask.perform();
}
fillDates(data) { fillDates(data) {
let currentRangeDate = moment().subtract(30, 'days'); let currentRangeDate = moment().subtract(30, 'days');
@ -123,6 +141,27 @@ export default class MembersStatsService extends Service {
this._forceRefresh = true; this._forceRefresh = true;
} }
@task
*_fetchNewsletterStatsTask() {
let query = {
filter: 'email_count:-0',
order: 'submitted_at desc',
limit: 10
};
const results = yield this.store.query('email', query);
const stats = results.map((d) => {
const {emailCount, openedCount, subject, submittedAt} = d;
const openRate = (emailCount && emailCount !== 0) ? (openedCount / emailCount).toFixed(1) : 0;
return {
subject,
submittedAt: moment(submittedAt).format('YYYY-MM-DD'),
openRate
};
});
this.newsletterStats = stats;
return stats;
}
@task @task
*_fetchCountsTask() { *_fetchCountsTask() {
this._lastFetchedCounts = new Date(); this._lastFetchedCounts = new Date();

View file

@ -70,7 +70,9 @@
<div class="growth">0.0%</div> <div class="growth">0.0%</div>
</div> </div>
</div> </div>
<div class="gh-dashboard-chart small"></div> <div class="gh-dashboard-chart small">
<GhMembersChart @nightShift={{feature "nightShift"}} @chartSize="small" @showSummary={{false}} @chartType="paid-members" @showRange={{false}} @chartStats={{this.newsletterOpenRatesData}} />
</div>
</div> </div>
</div> </div>
</section> </section>