Download plugins/Actions/javascripts/actionsDataTable.js from Leon4gr45/matomo: direct link, hf CLI and curl.
- Browser
- Download file 13.6 kB
-
https://huggingface.co/spaces/Leon4gr45/matomo/resolve/main/plugins/Actions/javascripts/actionsDataTable.js
- Command line
-
hf download hf://spaces/Leon4gr45/matomo/plugins/Actions/javascripts/actionsDataTable.js
-
curl -L -o actionsDataTable.js https://huggingface.co/spaces/Leon4gr45/matomo/resolve/main/plugins/Actions/javascripts/actionsDataTable.js
13.6 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 ($, require) { | |
| var exports = require('piwik/UI'), | |
| DataTable = exports.DataTable, | |
| dataTablePrototype = DataTable.prototype; | |
| // helper function for ActionDataTable | |
| function getLevelFromClass(style) { | |
| if (!style || typeof style == "undefined") return 0; | |
| var currentLevel = 0; | |
| var currentLevelIndex = style.indexOf('level'); | |
| if (currentLevelIndex >= 0) { | |
| currentLevel = Number(style.slice(currentLevelIndex + 5, currentLevelIndex + 6)); | |
| } | |
| return currentLevel; | |
| } | |
| /** | |
| * UI control that handles extra functionality for Actions datatables. | |
| * | |
| * @constructor | |
| */ | |
| exports.ActionsDataTable = function (element) { | |
| this.parentAttributeParent = ''; | |
| this.parentId = ''; | |
| this.disabledRowDom = {}; // to handle double click on '+' row | |
| DataTable.call(this, element); | |
| }; | |
| $.extend(exports.ActionsDataTable.prototype, dataTablePrototype, { | |
| //see dataTable::bindEventsAndApplyStyle | |
| bindEventsAndApplyStyle: function (domElem, rows) { | |
| var self = this; | |
| self.cleanParams(); | |
| self.preBindEventsAndApplyStyleHook(domElem, rows); | |
| if (!rows) { | |
| rows = $('tr', domElem); | |
| } | |
| self.numberOfSubtables = rows.filter('.subDataTable').click(function () { | |
| if (!self.param.filter_pattern_recursive) { | |
| // we don't display the link on the row with subDataTable when we are already | |
| // printing all the subTables (case of recursive search when the content is | |
| // including recursively all the subtables | |
| self.onClickActionSubDataTable(this); | |
| } | |
| }).length; | |
| self.applyCosmetics(domElem, rows); | |
| self.handleColumnHighlighting(domElem); | |
| self.handleRowActions(domElem, rows); | |
| self.handleLimit(domElem); | |
| self.handlePeriod(domElem); | |
| self.handleAnnotationsButton(domElem); | |
| self.handleExportBox(domElem); | |
| self.handleSort(domElem); | |
| self.handleOffsetInformation(domElem); | |
| if (self.workingDivId != undefined) { | |
| var dataTableLoadedProxy = function (response) { | |
| self.dataTableLoaded(response, self.workingDivId); | |
| }; | |
| self.handleConfigurationBox(domElem, dataTableLoadedProxy); | |
| self.handleSearchBox(domElem, dataTableLoadedProxy); | |
| } | |
| self.handleColumnDocumentation(domElem); | |
| self.handleRelatedReports(domElem); | |
| self.handleTriggeredEvents(domElem); | |
| self.handleCellTooltips(domElem); | |
| self.setFixWidthToMakeEllipsisWork(domElem); | |
| self.handleSummaryRow(domElem); | |
| self.openSubtableFromLevel0IfOnlyOneSubtableGiven(domElem); | |
| self.postBindEventsAndApplyStyleHook(domElem, rows); | |
| }, | |
| openSubtableFromLevel0IfOnlyOneSubtableGiven: function (domElem) { | |
| var $subtables = domElem.find('.subDataTable'); | |
| var hasOnlyOneSubtable = $subtables.length === 1; | |
| if (hasOnlyOneSubtable) { | |
| var hasOnlyOneRow = domElem.find('tbody tr.level0').length === 1; | |
| if (hasOnlyOneRow) { | |
| var $labels = $subtables.find('.label'); | |
| if ($labels.length) { | |
| $labels.first().click(); | |
| } | |
| } | |
| } | |
| }, | |
| openSubtableFromSubtableIfOnlyOneSubtableGiven: function (domElem) { | |
| var hasOnlyOneRow = domElem.length === 1; | |
| var hasOnlyOneSubtable = domElem.hasClass('subDataTable'); | |
| if (hasOnlyOneRow && hasOnlyOneSubtable) { | |
| // when subtable is loaded | |
| var $labels = domElem.find('.label'); | |
| if ($labels.length) { | |
| $labels.first().click(); | |
| } | |
| } | |
| }, | |
| //see dataTable::applyCosmetics | |
| applyCosmetics: function (domElem, rows) { | |
| var self = this; | |
| var rowsWithSubtables = rows.filter('.subDataTable'); | |
| rowsWithSubtables.css('font-weight', 'bold'); | |
| $("th:first-child", domElem).addClass('label'); | |
| $(rowsWithSubtables) | |
| .each(function () { | |
| if (self.param.filter_pattern_recursive) { | |
| $(this).addClass('expanded'); | |
| // remove tooltip "Click this row to expand or contract the subtable" | |
| $(this).attr('title', ''); | |
| } | |
| }); | |
| var rootRow = rows.first().prev(); | |
| // we look at the style of the row before the new rows to determine the rows' | |
| // level | |
| var level = rootRow.length ? getLevelFromClass(rootRow.attr('class')) + 1 : 0; | |
| rows.each(function () { | |
| var currentStyle = $(this).attr('class') || ''; | |
| if (currentStyle.indexOf('level') == -1) { | |
| $(this).addClass('level' + level); | |
| } | |
| // we add an attribute parent that contains the ID of all the parent categories | |
| // this ID is used when collapsing a parent row, it searches for all children rows | |
| // which 'parent' attribute's value contains the collapsed row ID | |
| $(this).prop('parent', function () { | |
| return self.parentAttributeParent + ' ' + self.parentId; | |
| }); | |
| }); | |
| self.addOddAndEvenClasses(domElem); | |
| }, | |
| addOddAndEvenClasses: function(domElem) { | |
| // empty | |
| }, | |
| handleRowActions: function (domElem, rows) { | |
| this.doHandleRowActions(rows); | |
| }, | |
| // Called when the user click on an actionDataTable row | |
| onClickActionSubDataTable: function (domElem) { | |
| var self = this; | |
| // get the idSubTable | |
| var idSubTable = $(domElem).attr('id'); | |
| var divIdToReplaceWithSubTable = 'subDataTable_' + idSubTable; | |
| var $insertAfter = $(domElem).nextUntil(':not(.comparePeriod):not(.comparisonRow)').last(); | |
| if (!$insertAfter.length) { | |
| $insertAfter = $(domElem); | |
| } | |
| var NextStyle = $insertAfter.next().attr('class'); | |
| var CurrentStyle = $(domElem).attr('class'); | |
| var currentRowLevel = getLevelFromClass(CurrentStyle); | |
| var nextRowLevel = getLevelFromClass(NextStyle); | |
| // if the row has not been clicked | |
| // which is the same as saying that the next row level is equal or less than the current row | |
| // because when we click a row the level of the next rows is higher (level2 row gives level3 rows) | |
| if (currentRowLevel >= nextRowLevel) { | |
| //unbind click to avoid double click problem | |
| $(domElem).off('click'); | |
| self.disabledRowDom = $(domElem); | |
| var numberOfColumns = $(domElem).children().length; | |
| $insertAfter.after('\ | |
| <tr id="' + divIdToReplaceWithSubTable + '" class="cellSubDataTable">\ | |
| <td colspan="' + numberOfColumns + '">\ | |
| <span class="loadingPiwik" style="display:inline">\ | |
| <span class="matomo-loader"><span></span><span></span><span></span></span>\ | |
| Loading...\ | |
| </span>\ | |
| </td>\ | |
| </tr>\ | |
| '); | |
| var savedActionVariable = self.param.action; | |
| // reset all the filters from the Parent table | |
| var filtersToRestore = self.resetAllFilters(); | |
| // Do not reset the sorting filters that must be applied to sub tables | |
| this.param['filter_sort_column'] = filtersToRestore['filter_sort_column']; | |
| this.param['filter_sort_order'] = filtersToRestore['filter_sort_order']; | |
| this.param['enable_filter_excludelowpop'] = filtersToRestore['enable_filter_excludelowpop']; | |
| self.param.idSubtable = idSubTable; | |
| self.param.action = self.props.subtable_controller_action; | |
| var extraParams = {}; | |
| extraParams.comparisonIdSubtables = self.getComparisonIdSubtables($(domElem)); | |
| self.reloadAjaxDataTable(false, function (resp) { | |
| self.actionsSubDataTableLoaded(resp, idSubTable); | |
| self.repositionRowActions($(domElem)); | |
| }, extraParams); | |
| self.param.action = savedActionVariable; | |
| self.restoreAllFilters(filtersToRestore); | |
| delete self.param.idSubtable; | |
| } | |
| // else we toggle all these rows | |
| else { | |
| var isExpanded = $(domElem).hasClass('subDataTable') && $(domElem).hasClass('expanded'); | |
| $(domElem).siblings().each(function () { | |
| var parents = $(this).prop('parent').split(' '); | |
| if (parents) { | |
| if (parents.indexOf(idSubTable) >= 0 | |
| || parents.indexOf('subDataTable_' + idSubTable) >= 0) { | |
| if (!isExpanded) { | |
| $(this).css('display', '').removeClass('hidden'); | |
| // unroll everything if the row is already opened | |
| var NextStyle = $(this).next().attr('class'); | |
| var CurrentStyle = $(this).attr('class'); | |
| var currentRowLevel = getLevelFromClass(CurrentStyle); | |
| var nextRowLevel = getLevelFromClass(NextStyle); | |
| if (currentRowLevel < nextRowLevel) { | |
| $(this).addClass('expanded'); | |
| } | |
| } | |
| else { | |
| $(this).css('display', 'none').addClass('hidden'); | |
| } | |
| self.repositionRowActions($(domElem)); | |
| } | |
| } | |
| }); | |
| self.$element.trigger('piwik:actionsSubTableToggled'); | |
| } | |
| // toggle the +/- image | |
| $(domElem).toggleClass('expanded'); | |
| }, | |
| //called when the full table actions is loaded | |
| dataTableLoaded: function (response, workingDivId) { | |
| var content = $(response); | |
| var idToReplace = workingDivId || $(content).attr('id'); | |
| //reset parents id | |
| self.parentAttributeParent = ''; | |
| self.parentId = ''; | |
| var dataTableSel = $('#' + idToReplace); | |
| // keep the original list of related reports | |
| var oldReportsElem = $('.datatableRelatedReports', dataTableSel); | |
| $('.datatableRelatedReports', content).replaceWith(oldReportsElem); | |
| dataTableSel.replaceWith(content); | |
| content.trigger('piwik:dataTableLoaded'); | |
| piwikHelper.compileVueEntryComponents(content); | |
| piwikHelper.lazyScrollTo(content[0], 400); | |
| return content; | |
| }, | |
| // Called when a set of rows for a category of actions is loaded | |
| actionsSubDataTableLoaded: function (response, idSubTable) { | |
| var self = this; | |
| var idToReplace = 'subDataTable_' + idSubTable; | |
| var root = $('#' + self.workingDivId); | |
| var response = $(response); | |
| self.parentAttributeParent = $('tr#' + idToReplace).prev().prop('parent'); | |
| self.parentId = idToReplace; | |
| $('tr#' + idToReplace, root).after(response).remove(); | |
| var requiredColumnCount = 0, availableColumnCount = 0; | |
| response.prev().find('td').each(function(){ requiredColumnCount += $(this).attr('colspan') || 1; }); | |
| response.find('td').each(function(){ availableColumnCount += $(this).attr('colspan') || 1; }); | |
| var missingColumns = requiredColumnCount - availableColumnCount; | |
| for (var i = 0; i < missingColumns; i++) { | |
| // if the subtable has fewer columns than the parent table, add some columns. | |
| // this happens for example, when the parent table has performance metrics and the subtable doesn't. | |
| response.append('<td>-</td>'); | |
| } | |
| var re = /subDataTable_(\d+)/; | |
| var ok = re.exec(self.parentId); | |
| if (ok) { | |
| self.parentId = ok[1]; | |
| } | |
| // we execute the bindDataTableEvent function for the new DIV | |
| self.bindEventsAndApplyStyle($('#' + self.workingDivId), response); | |
| self.$element.trigger('piwik:actionsSubDataTableLoaded'); | |
| //bind back the click event (disabled to avoid double-click problem) | |
| self.disabledRowDom.click( | |
| function () { | |
| self.onClickActionSubDataTable(this) | |
| }); | |
| self.openSubtableFromSubtableIfOnlyOneSubtableGiven(response); | |
| } | |
| }); | |
| })(jQuery, require); | |