Skip to content
Extraits de code Groupes Projets
dashboardObject.js 20,8 ko
Newer Older
  • Learn to ignore specific revisions
  • robocoder's avatar
    robocoder a validé
    /*!
    
     * Piwik - free/libre analytics platform
    
    robocoder's avatar
    robocoder a validé
     *
     * @link http://piwik.org
     * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
     */
    
    robocoder's avatar
    robocoder a validé
    
    
        /**
         * Current dashboard column layout
         * @type {object}
         */
    
        /**
         * Id of current dashboard
         * @type {int}
         */
    
        /**
         * Name of current dashboard
         * @type {string}
         */
    
        /**
         * Holds a reference to the dashboard element
         * @type {object}
         */
    
        /**
         * Boolean indicating wether the layout config has been changed or not
         * @type {boolean}
         */
    
         * all methods defined here are accessible with $(selector).dashboard('method', param, param, ...)
    
                    dashboardId = options.idDashboard;
                }
    
    
                    generateLayout(options.layout);
    
            /**
             * Destroys the dashboard object and all its childrens
             *
             * @return void
             */
    
                for (var i = 0; i < widgets.length; i++) {
    
                    $(widgets[i]).dashboardWidget('destroy');
                }
            },
    
            /**
             * Load dashboard with the given id
    
             *
             * @param {int} dashboardIdToLoad
    
            loadDashboard: function (dashboardIdToLoad) {
    
                dashboardId = dashboardIdToLoad;
    
    
                var element = $('[piwik-dashboard]');
                var scope = angular.element(element).scope();
                scope.fetchDashboard(dashboardIdToLoad);
    
    
            /**
             * Change current column layout to the given one
             *
             * @param {String} newLayout
             */
    
            setColumnLayout: function (newLayout) {
    
            /**
             * Returns the current column layout
             *
             * @return {String}
             */
    
            /**
             * Return the current dashboard name
             *
             * @return {String}
             */
    
            getDashboardName: function () {
    
            /**
             * Return the current dashboard id
             *
             * @return {int}
             */
    
                return dashboardId;
            },
    
    
            /**
             * Sets a new name for the current dashboard
             *
             * @param {String} newName
             */
    
            setDashboardName: function (newName) {
                dashboardName = newName;
    
                dashboardChanged = true;
                saveLayout();
            },
    
            /**
             * Adds a new widget to the dashboard
             *
             * @param {String}  uniqueId
             * @param {int}     columnNumber
             * @param {object}  widgetParameters
             * @param {boolean} addWidgetOnTop
             * @param {boolean} isHidden
             */
    
            addWidget: function (uniqueId, columnNumber, widgetParameters, addWidgetOnTop, isHidden) {
    
                addWidgetTemplate(uniqueId, columnNumber, widgetParameters, addWidgetOnTop, isHidden);
                reloadWidget(uniqueId);
    
            /**
             * Resets the current layout to the defaults
             */
    
                var ajaxRequest = new ajaxHelper();
                ajaxRequest.addParams({
    
                    module: 'Dashboard',
                    action: 'resetLayout',
    
                ajaxRequest.withTokenInUrl();
    
                        methods.loadDashboard.apply(this, [dashboardId])
    
                ajaxRequest.setLoadingElement();
                ajaxRequest.setFormat('html');
                ajaxRequest.send(true);
    
            /**
             * Removes the current dashboard
             */
    
             * Saves the current layout aus new default widget layout
    
            saveLayoutAsDefaultWidgetLayout: function () {
    
            },
    
            /**
             * Returns if the current loaded dashboard is the default dashboard
             */
    
            isDefaultDashboard: function () {
    
        function removeNonExistingWidgets(availableWidgets, layout)
        {
            var existingModuleAction = {};
            $.each(availableWidgets, function (category, widgets) {
                $.each(widgets, function (index, widget) {
                    existingModuleAction[widget.module + '.' + widget.action] = true;
                });
            });
    
            var columns = [];
            $.each(layout.columns, function (i, column) {
                var widgets = [];
    
                $.each(column, function (j, widget) {
                    if (!widget.parameters || !widget.parameters.module) {
                        return;
                    }
    
                    var method = widget.parameters.module + '.' + widget.parameters.action
                    if (existingModuleAction[method]) {
                        widgets.push(widget);
                    }
    
                });
    
                columns[i] = widgets;
            });
    
            layout.columns = columns;
    
            return layout;
        }
    
    
        /**
         * Generates the dashboard out of the given layout
         *
    
         * @param {object|string} layout
    
            dashboardLayout = parseLayout(layout);
    
    
            widgetsHelper.getAvailableWidgets(function (availableWidgets) {
                dashboardLayout = removeNonExistingWidgets(availableWidgets, dashboardLayout);
    
                piwikHelper.hideAjaxLoading();
                adjustDashboardColumns(dashboardLayout.config.layout);
    
                var dashboardContainsWidgets = false;
                for (var column = 0; column < dashboardLayout.columns.length; column++) {
                    for (var i in dashboardLayout.columns[column]) {
                        if (typeof dashboardLayout.columns[column][i] != 'object') {
                            // Fix IE8 bug: the "i in" loop contains i="indexOf", which would yield type function.
                            // If we would continue with i="indexOf", an invalid widget would be created.
                            continue;
                        }
                        var widget = dashboardLayout.columns[column][i];
                        dashboardContainsWidgets = true;
                        addWidgetTemplate(widget.uniqueId, column + 1, widget.parameters, false, widget.isHidden)
    
                if (!dashboardContainsWidgets) {
                    $(dashboardElement).trigger('dashboardempty');
                }
    
        /**
         * Adjust the dashboard columns to fit the new layout
         * removes or adds new columns if needed and sets the column sizes.
    
         *
         * @param {String} layout new layout in format xx-xx-xx
         * @return {void}
    
        function adjustDashboardColumns(layout) {
    
            var columnWidth = layout.split('-');
            var columnCount = columnWidth.length;
    
            var currentCount = $('.col', dashboardElement).length;
    
    
                $('.menuClear', dashboardElement).remove();
    
                for (var i = currentCount; i < columnCount; i++) {
    
                    if (dashboardLayout.columns.length < i) {
    
                        dashboardLayout.columns.push({});
                    }
                    $(dashboardElement).append('<div class="col"> </div>');
                }
                $(dashboardElement).append('<div class="menuClear"> </div>');
    
            } else if (currentCount > columnCount) {
    
                for (var i = columnCount; i < currentCount; i++) {
                    if (dashboardLayout.columns.length >= i) {
    
                    // move widgets to other columns depending on columns height
    
                    $('[widgetId]', $('.col:last')).each(function (id, elem) {
    
                        var cols = $('.col').slice(0, columnCount);
                        var smallestColumn = $(cols[0]);
                        var smallestColumnHeight = null;
    
                        cols.each(function (colId, col) {
    
                            if (smallestColumnHeight == null || smallestColumnHeight > $(col).height()) {
                                smallestColumnHeight = $(col).height();
                                smallestColumn = $(col);
                            }
                        });
    
                        $(elem).appendTo(smallestColumn);
                    });
    
    
            switch (layout) {
                case '100':
                    $('.col', dashboardElement).removeClass()
    
                    break;
                case '50-50':
                    $('.col', dashboardElement).removeClass()
    
                    $('.col', dashboardElement)[0].className = 'col col-sm-8';
                    $('.col', dashboardElement)[1].className = 'col col-sm-4';
    
                    $('.col', dashboardElement)[0].className = 'col col-sm-4';
                    $('.col', dashboardElement)[1].className = 'col col-sm-8';
    
                    $('.col', dashboardElement)[0].className = 'col col-sm-4';
                    $('.col', dashboardElement)[1].className = 'col col-sm-4';
                    $('.col', dashboardElement)[2].className = 'col col-sm-4';
    
                    $('.col', dashboardElement)[0].className = 'col col-sm-6';
                    $('.col', dashboardElement)[1].className = 'col col-sm-3';
                    $('.col', dashboardElement)[2].className = 'col col-sm-3';
    
                    $('.col', dashboardElement)[0].className = 'col col-sm-3';
                    $('.col', dashboardElement)[1].className = 'col col-sm-6';
                    $('.col', dashboardElement)[2].className = 'col col-sm-3';
    
                    $('.col', dashboardElement)[0].className = 'col col-sm-3';
                    $('.col', dashboardElement)[1].className = 'col col-sm-3';
                    $('.col', dashboardElement)[2].className = 'col col-sm-6';
    
                    break;
                case '25-25-25-25':
    
                    $('.col', dashboardElement)[0].className = 'col col-sm-3';
                    $('.col', dashboardElement)[1].className = 'col col-sm-3';
                    $('.col', dashboardElement)[2].className = 'col col-sm-3';
                    $('.col', dashboardElement)[3].className = 'col col-sm-3';
    
            // if dashboard column count is changed (not on initial load)
    
            if (currentCount > 0 && dashboardLayout.config.layout != layout) {
                dashboardChanged = true;
    
                dashboardLayout.config.layout = layout;
                saveLayout();
            }
    
            // trigger resize event on all widgets
            $('.widgetContent').each(function () {
                $(this).trigger('widget:resize');
    
    
        /**
         * Returns the given layout as an layout object
         * Used to parse old layout format into the new syntax
    
         *
         * @param {object}  layout  layout object or string
         * @return {object}
    
         */
        function parseLayout(layout) {
    
            // Handle layout array used in piwik before 1.7
            // column count was always 3, so use layout 33-33-33 as default
    
                    config: {layout: '33-33-33'},
                    columns: layout
    
                layout.config.layout = '33-33-33';
            }
    
            return layout;
    
        /**
         * Reloads the widget with the given uniqueId
         *
    
            $('[widgetId="' + uniqueId + '"]', dashboardElement).dashboardWidget('reload', false, true);
    
    
        /**
         * Adds an empty widget template to the dashboard in the given column
    
         * @param {String}    uniqueId
         * @param {int}       columnNumber
         * @param {object}    widgetParameters
         * @param {boolean}   addWidgetOnTop
         * @param {boolean}   isHidden
    
         */
        function addWidgetTemplate(uniqueId, columnNumber, widgetParameters, addWidgetOnTop, isHidden) {
    
            // do not try to add widget if given column number is to high
    
            if (columnNumber > $('.col', dashboardElement).length) {
    
            var widgetContent = '<div class="sortable" widgetId="' + uniqueId + '"></div>';
    
                $('.col:nth-child(' + columnNumber + ')', dashboardElement).prepend(widgetContent);
    
                $('.col:nth-child(' + columnNumber + ')', dashboardElement).append(widgetContent);
    
            $('[widgetId="' + uniqueId + '"]', dashboardElement).dashboardWidget({
    
                uniqueId: uniqueId,
                widgetParameters: widgetParameters,
    
                    saveLayout();
                },
                isHidden: isHidden
            });
        }
    
        /**
         * Make all widgets on the dashboard sortable
         */
    
        function makeWidgetsSortable() {
    
                if (!jQuery.support.noCloneEvent) {
    
                    $('object', this).hide();
                }
            }
    
            function onStop(event, ui) {
                $('object', this).show();
                $('.widgetHover', this).removeClass('widgetHover');
                $('.widgetTopHover', this).removeClass('widgetTopHover');
    
                if ($('.widget:has(".piwik-graph")', ui.item).length) {
    
                    reloadWidget($('.widget', ui.item).attr('id'));
                }
                saveLayout();
    
    
            //launch 'sortable' property on every dashboard widgets
    
            $( "div.col:data('ui-sortable')", dashboardElement ).sortable('destroy');
    
                        .sortable({
                            items: 'div.sortable',
                            opacity: 0.6,
                            forceHelperSize: true,
                            forcePlaceholderSize: true,
                            placeholder: 'hover',
                            handle: '.widgetTop',
                            helper: 'clone',
                            start: onStart,
                            stop: onStop,
                            connectWith: 'div.col'
                        });
    
         * Handle clicks for menu items for choosing between available dashboards
    
        function rebuildMenu() {
    
            if ($('[piwik-reporting-menu]').length) {
                // dashboard in reporting page (regular Piwik UI)
                angular.element(document).injector().invoke(function (reportingMenuModel) {
                    reportingMenuModel.reloadMenuItems();
                });
                return;
            }
    
            var _self = this;
    
            // widgetized
    
            var success = function (dashboards) {
    
    Thomas Steur's avatar
    Thomas Steur a validé
                var dashboardMenuList = $('#Dashboard_embeddedIndex_1').closest('ul');
    
                var dashboardMenuListItems = dashboardMenuList.find('>li');
    
                dashboardMenuListItems.filter(function () {
    
                    return $(this).attr('id').indexOf('Dashboard_embeddedIndex') == 0;
    
    Thomas Steur's avatar
    Thomas Steur a validé
                if (dashboards.length === 0) {
                    dashboards = [{iddashboard: 1, name: _pk_translate('Dashboard_Dashboard')}];
                }
    
    
                if (dashboards.length > 1
                    || dashboardMenuListItems.length >= 1
                ) {
    
                    var items = [];
                    for (var i = 0; i < dashboards.length; i++) {
    
    Thomas Steur's avatar
    Thomas Steur a validé
                        var $link = $('<a/>').attr('data-iddashboard', dashboards[i].iddashboard).text(dashboards[i].name).addClass('item');
                        var $li = $('<li/>').attr('id', 'Dashboard_embeddedIndex_' + dashboards[i].iddashboard).addClass('dashboardMenuItem').attr('role', 'menuitem').append($link);
    
    
                        items.push($li);
    
                        if (dashboards[i].iddashboard == dashboardId) {
                            dashboardName = dashboards[i].name;
    
                            $li.addClass('active');
    
    Thomas Steur's avatar
    Thomas Steur a validé
                dashboardMenuList.find('a[data-iddashboard]').click(function (e) {
    
    Thomas Steur's avatar
    Thomas Steur a validé
                    var idDashboard = $(this).attr('data-iddashboard');
    
    Thomas Steur's avatar
    Thomas Steur a validé
                    $('#Dashboard ul li').removeClass('active');
    
    
                    methods.loadDashboard.apply(_self, [idDashboard]);
    
    
    Thomas Steur's avatar
    Thomas Steur a validé
                    $(this).closest('li').addClass('active');
    
            var ajaxRequest = new ajaxHelper();
            ajaxRequest.addParams({
                module: 'Dashboard',
                action: 'getAllDashboards'
            }, 'get');
    
            ajaxRequest.withTokenInUrl();
    
        /**
         * Save the current layout in database if it has changed
    
         * @param {string}  [action]  action to perform (defaults to saveLayout)
    
                columns[columnNumber] = [];
    
                for (var j = 0; j < items.size(); j++) {
    
                    columns[columnNumber][j] = $(items[j]).dashboardWidget('getWidgetObject');
    
                    // Do not store segment in the dashboard layout
                    delete columns[columnNumber][j].parameters.segment;
    
            if (JSON.stringify(dashboardLayout.columns) != JSON.stringify(columns) || dashboardChanged || action) {
    
    
                dashboardLayout.columns = JSON.parse(JSON.stringify(columns));
    
                var ajaxRequest = new ajaxHelper();
                ajaxRequest.addParams({
                    module: 'Dashboard',
                    action: action,
                    idDashboard: dashboardId
                }, 'get');
                ajaxRequest.addParams({
                    layout: JSON.stringify(dashboardLayout),
                    name: dashboardName
                }, 'post');
                ajaxRequest.setCallback(
                    function () {
    
    
                ajaxRequest.withTokenInUrl();
    
                ajaxRequest.setFormat('html');
                ajaxRequest.send(false);
    
        }
    
        /**
         * Removes the current dashboard
         */
        function removeDashboard() {
    
                return; // dashboard with id 1 should never be deleted, as it is the default
            }
    
            var ajaxRequest = new ajaxHelper();
            ajaxRequest.setLoadingElement();
            ajaxRequest.addParams({
                module: 'Dashboard',
                action: 'removeDashboard',
                idDashboard: dashboardId
            }, 'get');
            ajaxRequest.setCallback(
                function () {
    
                    methods.loadDashboard.apply(this, [1]);
    
            ajaxRequest.withTokenInUrl();
    
            ajaxRequest.setFormat('html');
            ajaxRequest.send(true);
    
        $.fn.dashboard = function (method) {
            if (methods[method]) {
                return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
            } else if (typeof method === 'object' || !method) {
                return methods.init.apply(this, arguments);
    
                $.error('Method ' + method + ' does not exist on jQuery.dashboard');