forked from vergnet/site-accueil-insa
601 lines
22 KiB
JavaScript
601 lines
22 KiB
JavaScript
/*!
|
|
* Matomo - free/libre analytics platform
|
|
*
|
|
* @link https://matomo.org
|
|
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
|
*/
|
|
|
|
(function ($, piwik) {
|
|
|
|
var annotationsApi = {
|
|
|
|
// calls Annotations.getAnnotationManager
|
|
getAnnotationManager: function (idSite, date, period, lastN, callback) {
|
|
var ajaxParams =
|
|
{
|
|
module: 'Annotations',
|
|
action: 'getAnnotationManager',
|
|
idSite: idSite,
|
|
date: date,
|
|
period: period,
|
|
filter_limit: '-1'
|
|
};
|
|
if (lastN) {
|
|
ajaxParams.lastN = lastN;
|
|
}
|
|
|
|
var ajaxRequest = new ajaxHelper();
|
|
ajaxRequest.addParams(ajaxParams, 'get');
|
|
ajaxRequest.setCallback(callback);
|
|
ajaxRequest.setFormat('html');
|
|
ajaxRequest.send();
|
|
},
|
|
|
|
// calls Annotations.addAnnotation
|
|
addAnnotation: function (idSite, managerDate, managerPeriod, date, note, callback) {
|
|
var ajaxParams =
|
|
{
|
|
module: 'Annotations',
|
|
action: 'addAnnotation',
|
|
idSite: idSite,
|
|
date: date,
|
|
managerDate: managerDate,
|
|
managerPeriod: managerPeriod,
|
|
note: note
|
|
};
|
|
|
|
var ajaxRequest = new ajaxHelper();
|
|
ajaxRequest.addParams(ajaxParams, 'get');
|
|
ajaxRequest.withTokenInUrl();
|
|
ajaxRequest.setCallback(callback);
|
|
ajaxRequest.setFormat('html');
|
|
ajaxRequest.send();
|
|
},
|
|
|
|
// calls Annotations.saveAnnotation
|
|
saveAnnotation: function (idSite, idNote, date, noteData, callback) {
|
|
var ajaxParams =
|
|
{
|
|
module: 'Annotations',
|
|
action: 'saveAnnotation',
|
|
idSite: idSite,
|
|
idNote: idNote,
|
|
date: date
|
|
};
|
|
|
|
for (var key in noteData) {
|
|
ajaxParams[key] = noteData[key];
|
|
}
|
|
|
|
var ajaxRequest = new ajaxHelper();
|
|
ajaxRequest.addParams(ajaxParams, 'get');
|
|
ajaxRequest.withTokenInUrl();
|
|
ajaxRequest.setCallback(callback);
|
|
ajaxRequest.setFormat('html');
|
|
ajaxRequest.send();
|
|
},
|
|
|
|
// calls Annotations.deleteAnnotation
|
|
deleteAnnotation: function (idSite, idNote, managerDate, managerPeriod, callback) {
|
|
var ajaxParams =
|
|
{
|
|
module: 'Annotations',
|
|
action: 'deleteAnnotation',
|
|
idSite: idSite,
|
|
idNote: idNote,
|
|
date: managerDate,
|
|
period: managerPeriod
|
|
};
|
|
|
|
var ajaxRequest = new ajaxHelper();
|
|
ajaxRequest.addParams(ajaxParams, 'get');
|
|
ajaxRequest.withTokenInUrl();
|
|
ajaxRequest.setCallback(callback);
|
|
ajaxRequest.setFormat('html');
|
|
ajaxRequest.send();
|
|
},
|
|
|
|
// calls Annotations.getEvolutionIcons
|
|
getEvolutionIcons: function (idSite, date, period, lastN, callback) {
|
|
var ajaxParams =
|
|
{
|
|
module: 'Annotations',
|
|
action: 'getEvolutionIcons',
|
|
idSite: idSite,
|
|
date: date,
|
|
period: period,
|
|
filter_limit: '-1'
|
|
};
|
|
if (lastN) {
|
|
ajaxParams.lastN = lastN;
|
|
}
|
|
|
|
var ajaxRequest = new ajaxHelper();
|
|
ajaxRequest.addParams(ajaxParams, 'get');
|
|
ajaxRequest.withTokenInUrl();
|
|
ajaxRequest.setFormat('html');
|
|
ajaxRequest.setCallback(callback);
|
|
ajaxRequest.send();
|
|
}
|
|
};
|
|
|
|
var today = new Date();
|
|
|
|
/**
|
|
* Returns options to configure an annotation's datepicker shown in edit mode.
|
|
*
|
|
* @param {Element} annotation The annotation element.
|
|
*/
|
|
var getDatePickerOptions = function (annotation) {
|
|
var annotationDateStr = annotation.attr('data-date'),
|
|
parts = annotationDateStr.split('-'),
|
|
annotationDate = new Date(parts[0], parts[1] - 1, parts[2]);
|
|
|
|
var result = piwik.getBaseDatePickerOptions(annotationDate);
|
|
result.showButtonPanel = true;
|
|
result.currentText = _pk_translate('Intl_Today');
|
|
|
|
// make sure days before site start & after today cannot be selected
|
|
var piwikMinDate = result.minDate;
|
|
result.beforeShowDay = function (date) {
|
|
var valid = true;
|
|
|
|
// if date is after today or before date of site creation, it cannot be selected
|
|
if (date > today
|
|
|| date < piwikMinDate) {
|
|
valid = false;
|
|
}
|
|
|
|
return [valid, ''];
|
|
};
|
|
|
|
// on select a date, change the text of the edit date link
|
|
result.onSelect = function (dateText) {
|
|
$('.annotation-period-edit>a', annotation).text(dateText);
|
|
$('.datepicker', annotation).hide();
|
|
};
|
|
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Switches the current mode of an annotation between the view/edit modes.
|
|
*
|
|
* @param {Element} inAnnotationElement An element within the annotation to toggle the mode of.
|
|
* Should be two levels nested in the .annotation-value
|
|
* element.
|
|
* @return {Element} The .annotation-value element.
|
|
*/
|
|
var toggleAnnotationMode = function (inAnnotationElement) {
|
|
var annotation = $(inAnnotationElement).closest('.annotation');
|
|
annotation.toggleClass('edit')
|
|
$('.annotation-period,.annotation-period-edit,.delete-annotation,' +
|
|
'.annotation-edit-mode,.annotation-view-mode', annotation).toggle();
|
|
|
|
return $(inAnnotationElement).find('.annotation-value');
|
|
};
|
|
|
|
/**
|
|
* Creates the datepicker for an annotation element.
|
|
*
|
|
* @param {Element} annotation The annotation element.
|
|
*/
|
|
var createDatePicker = function (annotation) {
|
|
$('.datepicker', annotation).datepicker(getDatePickerOptions(annotation)).hide();
|
|
};
|
|
|
|
/**
|
|
* Creates datepickers for every period edit in an annotation manager.
|
|
*
|
|
* @param {Element} manager The annotation manager element.
|
|
*/
|
|
var createDatePickers = function (manager) {
|
|
$('.annotation-period-edit', manager).each(function () {
|
|
createDatePicker($(this).parent().parent());
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Replaces the HTML of an annotation manager element, and resets date/period
|
|
* attributes.
|
|
*
|
|
* @param {Element} manager The annotation manager.
|
|
* @param {string} html The HTML of the new annotation manager.
|
|
*/
|
|
var replaceAnnotationManager = function (manager, html) {
|
|
var newManager = $(html);
|
|
manager.html(newManager.html())
|
|
.attr('data-date', newManager.attr('data-date'))
|
|
.attr('data-period', newManager.attr('data-period'));
|
|
createDatePickers(manager);
|
|
};
|
|
|
|
/**
|
|
* Returns true if an annotation element is starred, false if otherwise.
|
|
*
|
|
* @param {Element} annotation The annotation element.
|
|
* @return {boolean}
|
|
*/
|
|
var isAnnotationStarred = function (annotation) {
|
|
return !!(+$('.annotation-star', annotation).attr('data-starred') == 1);
|
|
};
|
|
|
|
/**
|
|
* Replaces the HTML of an annotation element with HTML returned from Piwik, and
|
|
* makes sure the data attributes are correct.
|
|
*
|
|
* @param {Element} annotation The annotation element.
|
|
* @param {string} html The replacement HTML (or alternatively, the replacement
|
|
* element/jQuery object).
|
|
*/
|
|
var replaceAnnotationHtml = function (annotation, html) {
|
|
var newHtml = $(html);
|
|
annotation.html(newHtml.html()).attr('data-date', newHtml.attr('data-date'));
|
|
createDatePicker(annotation);
|
|
};
|
|
|
|
/**
|
|
* Binds events to an annotation manager element.
|
|
*
|
|
* @param {Element} manager The annotation manager.
|
|
* @param {int} idSite The site ID the manager is showing annotations for.
|
|
* @param {function} onAnnotationCountChange Callback that is called when there is a change
|
|
* in the number of annotations and/or starred annotations,
|
|
* eg, when a user adds a new one or deletes an existing one.
|
|
*/
|
|
var bindAnnotationManagerEvents = function (manager, idSite, onAnnotationCountChange) {
|
|
if (!onAnnotationCountChange) {
|
|
onAnnotationCountChange = function () {};
|
|
}
|
|
|
|
// show new annotation row if create new annotation link is clicked
|
|
manager.on('click', '.add-annotation', function (e) {
|
|
e.preventDefault();
|
|
|
|
var $newRow = $('.new-annotation-row', manager);
|
|
$newRow.show();
|
|
$(this).hide();
|
|
|
|
return false;
|
|
});
|
|
|
|
// hide new annotation row if cancel button clicked
|
|
manager.on('click', '.new-annotation-cancel', function () {
|
|
var newAnnotationRow = $(this).parent().parent();
|
|
newAnnotationRow.hide();
|
|
|
|
$('.add-annotation', newAnnotationRow.closest('.annotation-manager')).show();
|
|
});
|
|
|
|
// save new annotation when new annotation row save is clicked
|
|
manager.on('click', '.new-annotation-save', function () {
|
|
var addRow = $(this).parent().parent(),
|
|
addNoteInput = addRow.find('.new-annotation-edit'),
|
|
noteDate = addRow.find('.annotation-period-edit>a').text();
|
|
|
|
// do nothing if input is empty
|
|
if (!addNoteInput.val()) {
|
|
return;
|
|
}
|
|
|
|
// disable input & link
|
|
addNoteInput.attr('disabled', 'disabled');
|
|
$(this).attr('disabled', 'disabled');
|
|
|
|
// add a new annotation for the site, date & period
|
|
annotationsApi.addAnnotation(
|
|
idSite,
|
|
manager.attr('data-date'),
|
|
manager.attr('data-period'),
|
|
noteDate,
|
|
addNoteInput.val(),
|
|
function (response) {
|
|
replaceAnnotationManager(manager, response);
|
|
|
|
// increment annotation count for this date
|
|
onAnnotationCountChange(noteDate, 1, 0);
|
|
}
|
|
);
|
|
});
|
|
|
|
// add new annotation when enter key pressed on new annotation input
|
|
manager.on('keypress', '.new-annotation-edit', function (e) {
|
|
if (e.which == 13) {
|
|
$(this).parent().find('.new-annotation-save').click();
|
|
}
|
|
});
|
|
|
|
// show annotation editor if edit link, annotation text or period text is clicked
|
|
manager.on('click', '.annotation-enter-edit-mode', function (e) {
|
|
e.preventDefault();
|
|
|
|
var annotationContent = toggleAnnotationMode(this);
|
|
annotationContent.find('.annotation-edit').focus();
|
|
|
|
return false;
|
|
});
|
|
|
|
// hide annotation editor if cancel button is clicked
|
|
manager.on('click', '.annotation-cancel', function () {
|
|
toggleAnnotationMode(this);
|
|
});
|
|
|
|
// save annotation if save button clicked
|
|
manager.on('click', '.annotation-edit-mode .annotation-save', function () {
|
|
var annotation = $(this).parent().parent().parent(),
|
|
input = $('.annotation-edit', annotation),
|
|
dateEditText = $('.annotation-period-edit>a', annotation).text();
|
|
|
|
// if annotation value/date has not changed, just show the view mode instead of edit
|
|
if (input[0].defaultValue == input.val()
|
|
&& dateEditText == annotation.attr('data-date')) {
|
|
toggleAnnotationMode(this);
|
|
return;
|
|
}
|
|
|
|
// disable input while ajax is happening
|
|
input.attr('disabled', 'disabled');
|
|
$(this).attr('disabled', 'disabled');
|
|
|
|
// save the note w/ the new note text & date
|
|
annotationsApi.saveAnnotation(
|
|
idSite,
|
|
annotation.attr('data-id'),
|
|
dateEditText,
|
|
{
|
|
note: input.val()
|
|
},
|
|
function (response) {
|
|
response = $(response);
|
|
|
|
var newDate = response.attr('data-date'),
|
|
isStarred = isAnnotationStarred(response),
|
|
originalDate = annotation.attr('data-date');
|
|
|
|
replaceAnnotationHtml(annotation, response);
|
|
|
|
// if the date has been changed, update the evolution icon counts to reflect the change
|
|
if (originalDate != newDate) {
|
|
// reduce count for original date
|
|
onAnnotationCountChange(originalDate, -1, isStarred ? -1 : 0);
|
|
|
|
// increase count for new date
|
|
onAnnotationCountChange(newDate, 1, isStarred ? 1 : 0);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
|
|
// save annotation if 'enter' pressed on input
|
|
manager.on('keypress', '.annotation-value input', function (e) {
|
|
if (e.which == 13) {
|
|
$(this).parent().find('.annotation-save').click();
|
|
}
|
|
});
|
|
|
|
// delete annotation if delete link clicked
|
|
manager.on('click', '.delete-annotation', function (e) {
|
|
e.preventDefault();
|
|
|
|
var annotation = $(this).parent().parent();
|
|
$(this).attr('disabled', 'disabled');
|
|
|
|
// delete annotation by ajax
|
|
annotationsApi.deleteAnnotation(
|
|
idSite,
|
|
annotation.attr('data-id'),
|
|
manager.attr('data-date'),
|
|
manager.attr('data-period'),
|
|
function (response) {
|
|
replaceAnnotationManager(manager, response);
|
|
|
|
// update evolution icons
|
|
var isStarred = isAnnotationStarred(annotation);
|
|
onAnnotationCountChange(annotation.attr('data-date'), -1, isStarred ? -1 : 0);
|
|
}
|
|
);
|
|
|
|
return false;
|
|
});
|
|
|
|
// star/unstar annotation if star clicked
|
|
manager.on('click', '.annotation-star-changeable', function (e) {
|
|
var annotation = $(this).parent().parent(),
|
|
newStarredVal = $(this).attr('data-starred') == 0 ? 1 : 0 // flip existing 'starred' value
|
|
;
|
|
|
|
// perform ajax request to star annotation
|
|
annotationsApi.saveAnnotation(
|
|
idSite,
|
|
annotation.attr('data-id'),
|
|
annotation.attr('data-date'),
|
|
{
|
|
starred: newStarredVal
|
|
},
|
|
function (response) {
|
|
replaceAnnotationHtml(annotation, response);
|
|
|
|
// change starred count for this annotation in evolution graph based on what we're
|
|
// changing the starred value to
|
|
onAnnotationCountChange(annotation.attr('data-date'), 0, newStarredVal == 0 ? -1 : 1);
|
|
}
|
|
);
|
|
});
|
|
|
|
// when period edit is clicked, show datepicker
|
|
manager.on('click', '.annotation-period-edit>a', function (e) {
|
|
e.preventDefault();
|
|
$('.datepicker', $(this).parent()).toggle();
|
|
return false;
|
|
});
|
|
|
|
// make sure datepicker popups are closed if someone clicks elsewhere
|
|
$('body').on('mouseup', function (e) {
|
|
var container = $('.annotation-period-edit>.datepicker:visible').parent();
|
|
|
|
if (!container.has(e.target).length) {
|
|
container.find('.datepicker').hide();
|
|
}
|
|
});
|
|
};
|
|
|
|
// used in below function
|
|
var loadingAnnotationManager = false;
|
|
|
|
/**
|
|
* Shows an annotation manager under a report for a specific site & date range.
|
|
*
|
|
* @param {Element} domElem The element of the report to show the annotation manager
|
|
* under.
|
|
* @param {int} idSite The ID of the site to show the annotations of.
|
|
* @param {string} date The start date of the period.
|
|
* @param {string} period The period type.
|
|
* @param {int} lastN Whether to include the last N periods in the date range or not. Can
|
|
* be undefined.
|
|
* @param {function} [callback]
|
|
*/
|
|
var showAnnotationViewer = function (domElem, idSite, date, period, lastN, callback) {
|
|
var addToAnnotationCount = function (date, amt, starAmt) {
|
|
if (date.indexOf(',') != -1) {
|
|
date = date.split(',')[0];
|
|
}
|
|
|
|
$('.evolution-annotations>span[data-date]', domElem).each(function () {
|
|
if ($(this).attr('data-date') == date) {
|
|
// get counts from attributes (and convert them to ints)
|
|
var starredCount = +$(this).attr('data-starred'),
|
|
annotationCount = +$(this).attr('data-count');
|
|
|
|
// modify the starred count & make sure the correct image is used
|
|
var newStarCount = starredCount + starAmt;
|
|
var newAnno = 'icon-annotation';
|
|
if (newStarCount > 0) {
|
|
newAnno += ' starred';
|
|
}
|
|
$(this).attr('data-starred', newStarCount).find('span').attr('class', newAnno);
|
|
|
|
// modify the annotation count & hide/show based on new count
|
|
var newCount = annotationCount + amt;
|
|
$(this).attr('data-count', newCount).css('opacity', newCount > 0 ? 1 : 0);
|
|
|
|
return false;
|
|
}
|
|
});
|
|
};
|
|
|
|
var manager = $('.annotation-manager', domElem);
|
|
if (manager.length) {
|
|
// if annotations for the requested date + period are already loaded, then just toggle the
|
|
// visibility of the annotation viewer. otherwise, we reload the annotations.
|
|
if (manager.attr('data-date') == date
|
|
&& manager.attr('data-period') == period) {
|
|
// toggle manager view
|
|
if (manager.is(':hidden')) {
|
|
manager.slideDown('slow', function () { if (callback) callback(manager) });
|
|
}
|
|
else {
|
|
manager.slideUp('slow', function () { if (callback) callback(manager) });
|
|
}
|
|
}
|
|
else {
|
|
// show nothing but the loading gif
|
|
$('.annotations', manager).html('');
|
|
$('.loadingPiwik', manager).show();
|
|
|
|
// reload annotation manager for new date/period
|
|
annotationsApi.getAnnotationManager(idSite, date, period, lastN, function (response) {
|
|
|
|
replaceAnnotationManager(manager, response);
|
|
|
|
createDatePickers(manager);
|
|
|
|
// show if hidden
|
|
if (manager.is(':hidden')) {
|
|
manager.slideDown('slow', function () { if (callback) callback(manager) });
|
|
}
|
|
else {
|
|
if (callback) {
|
|
callback(manager);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
else {
|
|
// if we are already loading the annotation manager, don't load it again
|
|
if (loadingAnnotationManager) {
|
|
return;
|
|
}
|
|
|
|
loadingAnnotationManager = true;
|
|
|
|
$('.loadingPiwikBelow', domElem).insertAfter($('.evolution-annotations', domElem));
|
|
|
|
var loading = $('.loadingPiwikBelow', domElem).css({display: 'block'});
|
|
|
|
// the annotations for this report have not been retrieved yet, so do an ajax request
|
|
// & show the result
|
|
annotationsApi.getAnnotationManager(idSite, date, period, lastN, function (response) {
|
|
var manager = $(response).hide();
|
|
|
|
// if an error occurred (and response does not contain the annotation manager), do nothing
|
|
if (!manager.hasClass('annotation-manager')) {
|
|
return;
|
|
}
|
|
|
|
// create datepickers for each shown annotation
|
|
createDatePickers(manager);
|
|
|
|
bindAnnotationManagerEvents(manager, idSite, addToAnnotationCount);
|
|
|
|
loading.css('visibility', 'hidden');
|
|
|
|
// add & show annotation manager
|
|
manager.insertAfter($('.evolution-annotations', domElem));
|
|
|
|
manager.slideDown('slow', function () {
|
|
loading.hide().css('visibility', 'visible');
|
|
loadingAnnotationManager = false;
|
|
|
|
if (callback) callback(manager)
|
|
});
|
|
});
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Determines the x-coordinates of a set of evolution annotation icons.
|
|
*
|
|
* @param {Element} annotations The '.evolution-annotations' element.
|
|
* @param {Element} graphElem The evolution graph's datatable element.
|
|
*/
|
|
var placeEvolutionIcons = function (annotations, graphElem) {
|
|
var canvases = $('.piwik-graph .jqplot-xaxis canvas', graphElem),
|
|
noteSize = 16;
|
|
|
|
// if no graph available, hide all icons
|
|
if (!canvases || canvases.length == 0) {
|
|
$('span[data-date]', annotations).hide();
|
|
return true;
|
|
}
|
|
|
|
// set position of each individual icon
|
|
$('span[data-date]', annotations).each(function (i) {
|
|
var canvas = $(canvases[i]),
|
|
canvasCenterX = canvas.position().left + (canvas.width() / 2);
|
|
$(this).css({
|
|
left: canvasCenterX - noteSize / 2,
|
|
// show if there are annotations for this x-axis tick
|
|
opacity: +$(this).attr('data-count') > 0 ? 1 : 0
|
|
});
|
|
});
|
|
};
|
|
|
|
// make showAnnotationViewer, placeEvolutionIcons & annotationsApi globally accessible
|
|
piwik.annotations = {
|
|
showAnnotationViewer: showAnnotationViewer,
|
|
placeEvolutionIcons: placeEvolutionIcons,
|
|
api: annotationsApi
|
|
};
|
|
|
|
}(jQuery, piwik));
|