mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-06 14:05:46 +01:00
Allowing custom date range to be supplied in pageviews graph, closes #5541
This commit is contained in:
@@ -5,9 +5,14 @@
|
|||||||
"users": "Users",
|
"users": "Users",
|
||||||
"posts": "Posts",
|
"posts": "Posts",
|
||||||
"topics": "Topics",
|
"topics": "Topics",
|
||||||
"page-views-last-month": "Page views Last Month",
|
"page-views-last-month": "Last Month",
|
||||||
"page-views-this-month": "Page views This Month",
|
"page-views-this-month": "This Month",
|
||||||
"page-views-last-day": "Page views in last 24 hours",
|
"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 <code>YYYY-MM-DD</code>",
|
||||||
|
"page-views-custom-error": "Please enter a valid date range in the format <code>YYYY-MM-DD</code>",
|
||||||
|
|
||||||
"stats.day": "Day",
|
"stats.day": "Day",
|
||||||
"stats.week": "Week",
|
"stats.week": "Week",
|
||||||
|
|||||||
@@ -130,8 +130,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.pageview-stats {
|
.pageview-stats {
|
||||||
width:33%;
|
|
||||||
|
|
||||||
strong {
|
strong {
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
|
|||||||
$(window).on('resize', adjustPieCharts);
|
$(window).on('resize', adjustPieCharts);
|
||||||
adjustPieCharts();
|
adjustPieCharts();
|
||||||
|
|
||||||
$('[data-action="updateGraph"]').on('click', function () {
|
$('[data-action="updateGraph"]:not([data-units="custom"])').on('click', function () {
|
||||||
var until;
|
var until;
|
||||||
switch ($(this).attr('data-until')) {
|
switch ($(this).attr('data-until')) {
|
||||||
case 'last-month':
|
case 'last-month':
|
||||||
@@ -305,6 +305,60 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
|
|||||||
updateTrafficGraph($(this).attr('data-units'), until);
|
updateTrafficGraph($(this).attr('data-units'), until);
|
||||||
$('[data-action="updateGraph"]').removeClass('active');
|
$('[data-action="updateGraph"]').removeClass('active');
|
||||||
$(this).addClass('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);
|
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) {
|
if (!app.isFocused) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -334,6 +390,7 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
|
|||||||
graph: 'traffic',
|
graph: 'traffic',
|
||||||
units: units || 'hours',
|
units: units || 'hours',
|
||||||
until: until,
|
until: until,
|
||||||
|
amount: amount,
|
||||||
}, function (err, data) {
|
}, function (err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return app.alertError(err.message);
|
return app.alertError(err.message);
|
||||||
@@ -345,7 +402,7 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
|
|||||||
graphData.traffic = data;
|
graphData.traffic = data;
|
||||||
|
|
||||||
if (units === 'days') {
|
if (units === 'days') {
|
||||||
graphs.traffic.data.xLabels = utils.getDaysArray(until);
|
graphs.traffic.data.xLabels = utils.getDaysArray(until, amount);
|
||||||
} else {
|
} else {
|
||||||
graphs.traffic.data.xLabels = utils.getHoursArray();
|
graphs.traffic.data.xLabels = utils.getHoursArray();
|
||||||
|
|
||||||
@@ -364,6 +421,7 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
|
|||||||
graphs.traffic.update();
|
graphs.traffic.update();
|
||||||
currentGraph.units = units;
|
currentGraph.units = units;
|
||||||
currentGraph.until = until;
|
currentGraph.until = until;
|
||||||
|
currentGraph.amount = amount;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,7 +508,7 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
|
|||||||
}, realtime ? DEFAULTS.realtimeInterval : DEFAULTS.roomInterval);
|
}, realtime ? DEFAULTS.realtimeInterval : DEFAULTS.roomInterval);
|
||||||
|
|
||||||
intervals.graphs = setInterval(function () {
|
intervals.graphs = setInterval(function () {
|
||||||
updateTrafficGraph(currentGraph.units, currentGraph.until);
|
updateTrafficGraph(currentGraph.units, currentGraph.until, currentGraph.amount);
|
||||||
}, realtime ? DEFAULTS.realtimeInterval : DEFAULTS.graphInterval);
|
}, realtime ? DEFAULTS.realtimeInterval : DEFAULTS.graphInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -274,13 +274,13 @@
|
|||||||
return labels.reverse();
|
return labels.reverse();
|
||||||
},
|
},
|
||||||
|
|
||||||
getDaysArray: function (from) {
|
getDaysArray: function (from, amount) {
|
||||||
var currentDay = new Date(from || Date.now()).getTime();
|
var currentDay = new Date(from || Date.now()).getTime();
|
||||||
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
||||||
var labels = [];
|
var labels = [];
|
||||||
var tmpDate;
|
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));
|
tmpDate = new Date(currentDay - (1000 * 60 * 60 * 24 * x));
|
||||||
labels.push(months[tmpDate.getMonth()] + ' ' + tmpDate.getDate());
|
labels.push(months[tmpDate.getMonth()] + ' ' + tmpDate.getDate());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,11 +211,13 @@ SocketAdmin.analytics.get = function (socket, data, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Default returns views from past 24 hours, by hour
|
// Default returns views from past 24 hours, by hour
|
||||||
|
if (!data.amount) {
|
||||||
if (data.units === 'days') {
|
if (data.units === 'days') {
|
||||||
data.amount = 30;
|
data.amount = 30;
|
||||||
} else {
|
} else {
|
||||||
data.amount = 24;
|
data.amount = 24;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (data.graph === 'traffic') {
|
if (data.graph === 'traffic') {
|
||||||
async.parallel({
|
async.parallel({
|
||||||
|
|||||||
@@ -11,18 +11,24 @@
|
|||||||
<canvas id="analytics-traffic" width="100%" height="400"></canvas>
|
<canvas id="analytics-traffic" width="100%" height="400"></canvas>
|
||||||
</div>
|
</div>
|
||||||
<hr/>
|
<hr/>
|
||||||
<div class="text-center pull-left pageview-stats">
|
<div class="row">
|
||||||
<div><strong id="pageViewsLastMonth"></strong></div>
|
<div class="col-sm-3 hidden-xs text-center pageview-stats">
|
||||||
|
<div><strong id="pageViewsLastMonth">0</strong></div>
|
||||||
<div><a href="#" class="updatePageviewsGraph" data-action="updateGraph" data-units="days" data-until="last-month">[[admin/general/dashboard:page-views-last-month]]</a></div>
|
<div><a href="#" class="updatePageviewsGraph" data-action="updateGraph" data-units="days" data-until="last-month">[[admin/general/dashboard:page-views-last-month]]</a></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center pull-left pageview-stats">
|
<div class="col-sm-3 text-center pageview-stats">
|
||||||
<div><strong id="pageViewsThisMonth"></strong></div>
|
<div><strong id="pageViewsThisMonth">0</strong></div>
|
||||||
<div><a href="#" class="updatePageviewsGraph" data-action="updateGraph" data-units="days">[[admin/general/dashboard:page-views-this-month]]</a></div>
|
<div><a href="#" class="updatePageviewsGraph" data-action="updateGraph" data-units="days">[[admin/general/dashboard:page-views-this-month]]</a></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center pull-left pageview-stats">
|
<div class="col-sm-3 hidden-xs text-center pageview-stats">
|
||||||
<div><strong id="pageViewsPastDay"></strong></div>
|
<div><strong id="pageViewsPastDay">0</strong></div>
|
||||||
<div><a href="#" class="updatePageviewsGraph active" data-action="updateGraph" data-units="hours">[[admin/general/dashboard:page-views-last-day]]</a></div>
|
<div><a href="#" class="updatePageviewsGraph active" data-action="updateGraph" data-units="hours">[[admin/general/dashboard:page-views-last-day]]</a></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-sm-3 text-center pageview-stats">
|
||||||
|
<div><strong><i class="fa fa-clock-o"></i></strong></div>
|
||||||
|
<div><a href="#" class="updatePageviewsGraph" data-action="updateGraph" data-units="custom">[[admin/general/dashboard:page-views-custom]]</a></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
20
src/views/admin/partials/pageviews-range-select.tpl
Normal file
20
src/views/admin/partials/pageviews-range-select.tpl
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<form role="form">
|
||||||
|
<fieldset>
|
||||||
|
<div class="alert alert-danger hidden">[[admin/general/dashboard:page-views-custom-error]]</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="startRange">[[admin/general/dashboard:page-views-custom-start]]</label>
|
||||||
|
<input class="form-control" type="date" id="startRange" name="startRange" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="endRange">[[admin/general/dashboard:page-views-custom-end]]</label>
|
||||||
|
<input class="form-control" type="date" id="endRange" name="endRange" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="help-block">[[admin/general/dashboard:page-views-custom-help]]</p>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
Reference in New Issue
Block a user