From 064a8aa6d73ac4e015871b9dece009f581c0deea Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 11 May 2017 11:41:28 -0400 Subject: [PATCH] Allowing custom date range to be supplied in pageviews graph, closes #5541 --- .../en-GB/admin/general/dashboard.json | 11 +++- public/less/admin/general/dashboard.less | 2 - public/src/admin/general/dashboard.js | 66 +++++++++++++++++-- public/src/utils.js | 4 +- src/socket.io/admin.js | 10 +-- src/views/admin/general/dashboard.tpl | 28 ++++---- .../admin/partials/pageviews-range-select.tpl | 20 ++++++ 7 files changed, 115 insertions(+), 26 deletions(-) create mode 100644 src/views/admin/partials/pageviews-range-select.tpl 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 @@
-
-
-
[[admin/general/dashboard:page-views-last-month]]
-
-
-
-
[[admin/general/dashboard:page-views-this-month]]
-
-
-
-
[[admin/general/dashboard:page-views-last-day]]
+
diff --git a/src/views/admin/partials/pageviews-range-select.tpl b/src/views/admin/partials/pageviews-range-select.tpl new file mode 100644 index 0000000000..e63166d3a5 --- /dev/null +++ b/src/views/admin/partials/pageviews-range-select.tpl @@ -0,0 +1,20 @@ +
+
+ +
+
+
+ + +
+
+
+
+ + +
+
+
+

[[admin/general/dashboard:page-views-custom-help]]

+
+
\ No newline at end of file