discourse/app/assets/javascripts/admin/models/report.js

162 lines
4.2 KiB
JavaScript

Discourse.Report = Discourse.Model.extend({
reportUrl: function() {
return("/admin/reports/" + this.get('type'));
}.property('type'),
valueAt: function(numDaysAgo) {
if (this.data) {
var wantedDate = moment().subtract(numDaysAgo, 'days').format('YYYY-MM-DD');
var item = this.data.find( function(d) { return d.x === wantedDate; } );
if (item) {
return item.y;
}
}
return 0;
},
sumDays: function(startDaysAgo, endDaysAgo) {
if (this.data) {
var earliestDate = moment().subtract(endDaysAgo, 'days').startOf('day');
var latestDate = moment().subtract(startDaysAgo, 'days').startOf('day');
var d, sum = 0;
_.each(this.data,function(datum){
d = moment(datum.x);
if(d >= earliestDate && d <= latestDate) {
sum += datum.y;
}
});
return sum;
}
},
todayCount: function() {
return this.valueAt(0);
}.property('data'),
yesterdayCount: function() {
return this.valueAt(1);
}.property('data'),
lastSevenDaysCount: function() {
return this.sumDays(1,7);
}.property('data'),
lastThirtyDaysCount: function() {
return this.sumDays(1,30);
}.property('data'),
sevenDaysAgoCount: function() {
return this.valueAt(7);
}.property('data'),
thirtyDaysAgoCount: function() {
return this.valueAt(30);
}.property('data'),
yesterdayTrend: function() {
var yesterdayVal = this.valueAt(1);
var twoDaysAgoVal = this.valueAt(2);
if ( yesterdayVal > twoDaysAgoVal ) {
return 'trending-up';
} else if ( yesterdayVal < twoDaysAgoVal ) {
return 'trending-down';
} else {
return 'no-change';
}
}.property('data'),
sevenDayTrend: function() {
var currentPeriod = this.sumDays(1,7);
var prevPeriod = this.sumDays(8,14);
if ( currentPeriod > prevPeriod ) {
return 'trending-up';
} else if ( currentPeriod < prevPeriod ) {
return 'trending-down';
} else {
return 'no-change';
}
}.property('data'),
thirtyDayTrend: function() {
if( this.get('prev30Days') ) {
var currentPeriod = this.sumDays(1,30);
if( currentPeriod > this.get('prev30Days') ) {
return 'trending-up';
} else if ( currentPeriod < this.get('prev30Days') ) {
return 'trending-down';
}
}
return 'no-change';
}.property('data', 'prev30Days'),
icon: function() {
switch( this.get('type') ) {
case 'flags':
return 'fa-flag';
case 'likes':
return 'fa-heart';
default:
return null;
}
}.property('type'),
percentChangeString: function(val1, val2) {
var val = ((val1 - val2) / val2) * 100;
if( isNaN(val) || !isFinite(val) ) {
return null;
} else if( val > 0 ) {
return '+' + val.toFixed(0) + '%';
} else {
return val.toFixed(0) + '%';
}
},
changeTitle: function(val1, val2, prevPeriodString) {
var title = '';
var percentChange = this.percentChangeString(val1, val2);
if( percentChange ) {
title += percentChange + ' change. ';
}
title += 'Was ' + val2 + ' ' + prevPeriodString + '.';
return title;
},
yesterdayCountTitle: function() {
return this.changeTitle( this.valueAt(1), this.valueAt(2),'two days ago');
}.property('data'),
sevenDayCountTitle: function() {
return this.changeTitle( this.sumDays(1,7), this.sumDays(8,14), 'two weeks ago');
}.property('data'),
thirtyDayCountTitle: function() {
return this.changeTitle( this.sumDays(1,30), this.get('prev30Days'), 'in the previous 30 day period');
}.property('data'),
dataReversed: function() {
return this.get('data').toArray().reverse();
}.property('data')
});
Discourse.Report.reopenClass({
find: function(type) {
var model = Discourse.Report.create({type: type});
Discourse.ajax("/admin/reports/" + type).then(function (json) {
// Add a percent field to each tuple
var maxY = 0;
json.report.data.forEach(function (row) {
if (row.y > maxY) maxY = row.y;
});
if (maxY > 0) {
json.report.data.forEach(function (row) {
row.percentage = Math.round((row.y / maxY) * 100);
});
}
model.setProperties(json.report);
model.set('loaded', true);
});
return(model);
}
});