Download plugins/Annotations/javascripts/annotations.js from Leon4gr45/matomo: direct link, hf CLI and curl.
- Browser
- Download file 23.8 kB
-
https://huggingface.co/spaces/Leon4gr45/matomo/resolve/main/plugins/Annotations/javascripts/annotations.js
- Command line
-
hf download hf://spaces/Leon4gr45/matomo/plugins/Annotations/javascripts/annotations.js
-
curl -L -o annotations.js https://huggingface.co/spaces/Leon4gr45/matomo/resolve/main/plugins/Annotations/javascripts/annotations.js
23.8 kB
| /*! | |
| * Matomo - free/libre analytics platform | |
| * | |
| * @link https://matomo.org | |
| * @license https://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'); | |
| // Do not need to include the period parameter as this is not used in the endpoint | |
| ajaxRequest.removeDefaultParameter('period'); | |
| 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'); | |
| // Do not need to include the period parameter as this is not used in the endpoint | |
| ajaxRequest.removeDefaultParameter('period'); | |
| 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'); | |
| placeAnnotationManager(manager, 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 | |
| }); | |
| }); | |
| }; | |
| var getPlotLinesLegendFooter = function (graphElem) { | |
| var legendFooter = $('.jqplot-legend-footer', graphElem); | |
| if (legendFooter.length) { | |
| return legendFooter; | |
| } | |
| return $(); | |
| }; | |
| var placeEvolutionAnnotations = function (annotations, graphElem) { | |
| var legendFooter = getPlotLinesLegendFooter(graphElem); | |
| if (legendFooter.length) { | |
| annotations.insertBefore(legendFooter); | |
| return; | |
| } | |
| annotations.insertBefore($('.dataTableFooterNavigation', graphElem)); | |
| }; | |
| var placeAnnotationManager = function (manager, graphElem) { | |
| var legendFooter = getPlotLinesLegendFooter(graphElem); | |
| if (legendFooter.length) { | |
| manager.insertBefore(legendFooter); | |
| return; | |
| } | |
| manager.insertAfter($('.evolution-annotations', graphElem)); | |
| }; | |
| // make annotation helpers globally accessible | |
| piwik.annotations = { | |
| showAnnotationViewer: showAnnotationViewer, | |
| placeEvolutionIcons: placeEvolutionIcons, | |
| placeEvolutionAnnotations: placeEvolutionAnnotations, | |
| api: annotationsApi | |
| }; | |
| }(jQuery, piwik)); | |