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

157 lines
4.5 KiB
Text
Raw Normal View History

import round from "discourse/lib/round";
const Report = Discourse.Model.extend({
2015-08-04 12:23:56 -04:00
reportUrl: Discourse.computed.fmt("type", "/admin/reports/%@"),
2013-03-30 14:07:25 -04:00
valueAt(numDaysAgo) {
2013-03-30 14:07:25 -04:00
if (this.data) {
2015-08-04 12:23:56 -04:00
const wantedDate = moment().subtract(numDaysAgo, "days").format("YYYY-MM-DD");
const item = this.data.find(d => d.x === wantedDate);
2013-03-30 14:07:25 -04:00
if (item) {
return item.y;
}
}
return 0;
},
2015-08-04 12:23:56 -04:00
valueFor(startDaysAgo, endDaysAgo) {
2013-03-30 14:07:25 -04:00
if (this.data) {
2015-08-04 12:23:56 -04:00
const earliestDate = moment().subtract(endDaysAgo, "days").startOf("day");
const latestDate = moment().subtract(startDaysAgo, "days").startOf("day");
var d, sum = 0, count = 0;
_.each(this.data, datum => {
d = moment(datum.x);
2015-08-04 12:23:56 -04:00
if (d >= earliestDate && d <= latestDate) {
2013-03-30 14:07:25 -04:00
sum += datum.y;
2015-08-04 12:23:56 -04:00
count++;
2013-03-30 14:07:25 -04:00
}
});
2015-08-04 12:23:56 -04:00
if (this.get("method") === "average") { sum /= count; }
return round(sum, -2);
2013-03-30 14:07:25 -04:00
}
},
2015-08-04 12:23:56 -04:00
todayCount: function() { return this.valueAt(0); }.property("data"),
yesterdayCount: function() { return this.valueAt(1); }.property("data"),
sevenDaysAgoCount: function() { return this.valueAt(7); }.property("data"),
thirtyDaysAgoCount: function() { return this.valueAt(30); }.property("data"),
2015-08-04 12:23:56 -04:00
lastSevenDaysCount: function() { return this.valueFor(1, 7); }.property("data"),
lastThirtyDaysCount: function() { return this.valueFor(1, 30); }.property("data"),
2013-03-30 14:07:25 -04:00
yesterdayTrend: function() {
2015-08-04 12:23:56 -04:00
const yesterdayVal = this.valueAt(1);
const twoDaysAgoVal = this.valueAt(2);
if (yesterdayVal > twoDaysAgoVal) {
return "trending-up";
} else if (yesterdayVal < twoDaysAgoVal) {
return "trending-down";
2013-03-30 14:07:25 -04:00
} else {
2015-08-04 12:23:56 -04:00
return "no-change";
2013-03-30 14:07:25 -04:00
}
2015-08-04 12:23:56 -04:00
}.property("data"),
2013-03-30 14:07:25 -04:00
sevenDayTrend: function() {
2015-08-04 12:23:56 -04:00
const currentPeriod = this.valueFor(1, 7);
const prevPeriod = this.valueFor(8, 14);
if (currentPeriod > prevPeriod) {
return "trending-up";
} else if (currentPeriod < prevPeriod) {
return "trending-down";
2013-03-30 14:07:25 -04:00
} else {
2015-08-04 12:23:56 -04:00
return "no-change";
2013-03-30 14:07:25 -04:00
}
2015-08-04 12:23:56 -04:00
}.property("data"),
2013-03-30 14:07:25 -04:00
thirtyDayTrend: function() {
2015-08-04 12:23:56 -04:00
if (this.get("prev30Days")) {
const currentPeriod = this.valueFor(1, 30);
if (currentPeriod > this.get("prev30Days")) {
return "trending-up";
} else if (currentPeriod < this.get("prev30Days")) {
return "trending-down";
2013-03-30 14:07:25 -04:00
}
}
2015-08-04 12:23:56 -04:00
return "no-change";
}.property("data", "prev30Days"),
2013-04-16 18:37:35 -04:00
icon: function() {
2015-08-04 12:23:56 -04:00
switch (this.get("type")) {
case "flags": return "flag";
case "likes": return "heart";
default: return null;
2013-04-16 18:37:35 -04:00
}
2015-08-04 12:23:56 -04:00
}.property("type"),
method: function() {
if (this.get("type") === "time_to_first_response") {
return "average";
} else {
return "sum";
}
}.property("type"),
percentChangeString(val1, val2) {
2015-08-04 12:23:56 -04:00
const val = ((val1 - val2) / val2) * 100;
if (isNaN(val) || !isFinite(val)) {
return null;
2015-08-04 12:23:56 -04:00
} else if (val > 0) {
return "+" + val.toFixed(0) + "%";
} else {
2015-08-04 12:23:56 -04:00
return val.toFixed(0) + "%";
}
},
changeTitle(val1, val2, prevPeriodString) {
2015-08-04 12:23:56 -04:00
const percentChange = this.percentChangeString(val1, val2);
var title = "";
if (percentChange) { title += percentChange + " change. "; }
title += "Was " + val2 + " " + prevPeriodString + ".";
return title;
},
yesterdayCountTitle: function() {
2015-08-04 12:23:56 -04:00
return this.changeTitle(this.valueAt(1), this.valueAt(2), "two days ago");
}.property("data"),
sevenDayCountTitle: function() {
2015-08-04 12:23:56 -04:00
return this.changeTitle(this.valueFor(1, 7), this.valueFor(8, 14), "two weeks ago");
}.property("data"),
thirtyDayCountTitle: function() {
2015-08-04 12:23:56 -04:00
return this.changeTitle(this.valueFor(1, 30), this.get("prev30Days"), "in the previous 30 day period");
}.property("data"),
dataReversed: function() {
2015-08-04 12:23:56 -04:00
return this.get("data").toArray().reverse();
}.property("data")
});
Report.reopenClass({
find(type, startDate, endDate, categoryId) {
return Discourse.ajax("/admin/reports/" + type, {
data: {
start_date: startDate,
end_date: endDate,
category_id: categoryId
}
}).then(json => {
// Add a percent field to each tuple
let maxY = 0;
json.report.data.forEach(row => {
if (row.y > maxY) maxY = row.y;
});
if (maxY > 0) {
json.report.data.forEach(row => row.percentage = Math.round((row.y / maxY) * 100));
}
const model = Discourse.Report.create({ type: type });
model.setProperties(json.report);
return model;
});
}
});
export default Report;