/*! * Matomo - free/libre analytics platform * * @link https://matomo.org * @license http://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); } // 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 if (!self.param.filter_pattern_recursive) { self.numberOfSubtables = rows.filter('.subDataTable').click(function () { 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('\