diff --git a/public/language/en-GB/admin/general/dashboard.json b/public/language/en-GB/admin/general/dashboard.json
index 02046bd17a..437e8e2461 100644
--- a/public/language/en-GB/admin/general/dashboard.json
+++ b/public/language/en-GB/admin/general/dashboard.json
@@ -5,9 +5,14 @@
"users": "Users",
"posts": "Posts",
"topics": "Topics",
- "page-views-last-month": "Page views Last Month",
- "page-views-this-month": "Page views This Month",
- "page-views-last-day": "Page views in last 24 hours",
+ "page-views-last-month": "Last Month",
+ "page-views-this-month": "This Month",
+ "page-views-last-day": "Last 24 hours",
+ "page-views-custom": "Custom Date Range",
+ "page-views-custom-start": "Range Start",
+ "page-views-custom-end": "Range End",
+ "page-views-custom-help": "Enter a date range of page views you would like to view. If no date picker is available, the accepted format is YYYY-MM-DD
",
+ "page-views-custom-error": "Please enter a valid date range in the format YYYY-MM-DD
",
"stats.day": "Day",
"stats.week": "Week",
diff --git a/public/less/admin/general/dashboard.less b/public/less/admin/general/dashboard.less
index 12e542e32a..6bbb49fc86 100644
--- a/public/less/admin/general/dashboard.less
+++ b/public/less/admin/general/dashboard.less
@@ -130,8 +130,6 @@
}
.pageview-stats {
- width:33%;
-
strong {
font-size: 22px;
}
diff --git a/public/src/admin/general/dashboard.js b/public/src/admin/general/dashboard.js
index 71ad4e3738..6b88483ac0 100644
--- a/public/src/admin/general/dashboard.js
+++ b/public/src/admin/general/dashboard.js
@@ -294,7 +294,7 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
$(window).on('resize', adjustPieCharts);
adjustPieCharts();
- $('[data-action="updateGraph"]').on('click', function () {
+ $('[data-action="updateGraph"]:not([data-units="custom"])').on('click', function () {
var until;
switch ($(this).attr('data-until')) {
case 'last-month':
@@ -305,6 +305,60 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
updateTrafficGraph($(this).attr('data-units'), until);
$('[data-action="updateGraph"]').removeClass('active');
$(this).addClass('active');
+
+ require(['translator'], function (translator) {
+ translator.translate('[[admin/general/dashboard:page-views-custom]]', function (translated) {
+ $('[data-action="updateGraph"][data-units="custom"]').text(translated);
+ });
+ });
+ });
+ $('[data-action="updateGraph"][data-units="custom"]').on('click', function () {
+ var targetEl = $(this);
+
+ templates.parse('admin/partials/pageviews-range-select', {}, function (html) {
+ var modal = bootbox.dialog({
+ title: '[[admin/general/dashboard:page-views-custom]]',
+ message: html,
+ buttons: {
+ submit: {
+ label: '[[global:search]]',
+ className: 'btn-primary',
+ callback: submit,
+ },
+ },
+ });
+
+ function submit() {
+ // NEED TO ADD VALIDATION HERE FOR YYYY-MM-DD
+ var formData = modal.find('form').serializeObject();
+ var validRegexp = /\d{4}-\d{2}-\d{2}/;
+
+ // Input validation
+ if (!formData.startRange && !formData.endRange) {
+ // No range? Assume last 30 days
+ updateTrafficGraph('days');
+ $('[data-action="updateGraph"]').removeClass('active');
+ $('[data-action="updateGraph"][data-units="days"]').addClass('active');
+ return;
+ } else if (!validRegexp.test(formData.startRange) || !validRegexp.test(formData.endRange)) {
+ // Invalid Input
+ modal.find('.alert-danger').removeClass('hidden');
+ return false;
+ }
+
+ var until = new Date(formData.endRange);
+ until.setDate(until.getDate() + 1);
+ until = until.getTime();
+ var amount = (until - new Date(formData.startRange).getTime()) / (1000 * 60 * 60 * 24);
+
+ updateTrafficGraph('days', until, amount);
+ $('[data-action="updateGraph"]').removeClass('active');
+ targetEl.addClass('active');
+
+ // Update "custom range" label
+ targetEl.html(formData.startRange + ' – ' + formData.endRange);
+ }
+ });
});
socket.emit('admin.rooms.getAll', Admin.updateRoomUsage);
@@ -325,7 +379,9 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
});
}
- function updateTrafficGraph(units, until) {
+ function updateTrafficGraph(units, until, amount) {
+ // until and amount are optional
+
if (!app.isFocused) {
return;
}
@@ -334,6 +390,7 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
graph: 'traffic',
units: units || 'hours',
until: until,
+ amount: amount,
}, function (err, data) {
if (err) {
return app.alertError(err.message);
@@ -345,7 +402,7 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
graphData.traffic = data;
if (units === 'days') {
- graphs.traffic.data.xLabels = utils.getDaysArray(until);
+ graphs.traffic.data.xLabels = utils.getDaysArray(until, amount);
} else {
graphs.traffic.data.xLabels = utils.getHoursArray();
@@ -364,6 +421,7 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
graphs.traffic.update();
currentGraph.units = units;
currentGraph.until = until;
+ currentGraph.amount = amount;
});
}
@@ -450,7 +508,7 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
}, realtime ? DEFAULTS.realtimeInterval : DEFAULTS.roomInterval);
intervals.graphs = setInterval(function () {
- updateTrafficGraph(currentGraph.units, currentGraph.until);
+ updateTrafficGraph(currentGraph.units, currentGraph.until, currentGraph.amount);
}, realtime ? DEFAULTS.realtimeInterval : DEFAULTS.graphInterval);
}
diff --git a/public/src/utils.js b/public/src/utils.js
index 7264bfcf8f..3a73c5fdd6 100644
--- a/public/src/utils.js
+++ b/public/src/utils.js
@@ -274,13 +274,13 @@
return labels.reverse();
},
- getDaysArray: function (from) {
+ getDaysArray: function (from, amount) {
var currentDay = new Date(from || Date.now()).getTime();
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
var labels = [];
var tmpDate;
- for (var x = 29; x >= 0; x -= 1) {
+ for (var x = (amount || 30) - 1; x >= 0; x -= 1) {
tmpDate = new Date(currentDay - (1000 * 60 * 60 * 24 * x));
labels.push(months[tmpDate.getMonth()] + ' ' + tmpDate.getDate());
}
diff --git a/src/socket.io/admin.js b/src/socket.io/admin.js
index 1b4d9ebada..2cdaa0161b 100644
--- a/src/socket.io/admin.js
+++ b/src/socket.io/admin.js
@@ -211,10 +211,12 @@ SocketAdmin.analytics.get = function (socket, data, callback) {
}
// Default returns views from past 24 hours, by hour
- if (data.units === 'days') {
- data.amount = 30;
- } else {
- data.amount = 24;
+ if (!data.amount) {
+ if (data.units === 'days') {
+ data.amount = 30;
+ } else {
+ data.amount = 24;
+ }
}
if (data.graph === 'traffic') {
diff --git a/src/views/admin/general/dashboard.tpl b/src/views/admin/general/dashboard.tpl
index d904637fe4..884fe5f2a8 100644
--- a/src/views/admin/general/dashboard.tpl
+++ b/src/views/admin/general/dashboard.tpl
@@ -11,17 +11,23 @@