diff --git a/plugins/CoreHome/javascripts/broadcast.js b/plugins/CoreHome/javascripts/broadcast.js index b18f53319af99c04867c4f891ea210dd0c1d4ae4..b48ad77e10d08f5479b50b7a2435ea2e7337d87a 100644 --- a/plugins/CoreHome/javascripts/broadcast.js +++ b/plugins/CoreHome/javascripts/broadcast.js @@ -128,7 +128,7 @@ var broadcast = { broadcast.loadAjaxContent(hashUrl); // make sure the "Widgets & Dashboard" is deleted on reload - $('.top_controls .dashboardSettings').hide(); + $('.top_controls .dashboard-manager').hide(); $('#dashboardWidgetsArea').dashboard('destroy'); // remove unused controls @@ -423,6 +423,8 @@ var broadcast = { piwikHelper.hideAjaxLoading(); broadcast.lastUrlRequested = null; } + + initTopControls(); } var ajax = new ajaxHelper(); diff --git a/plugins/CoreHome/javascripts/top_controls.js b/plugins/CoreHome/javascripts/top_controls.js index 93e9c6993dfaf19a915f4208ae930c9a7356ac03..c2089648d067507d01b872c88459e223205a0c05 100644 --- a/plugins/CoreHome/javascripts/top_controls.js +++ b/plugins/CoreHome/javascripts/top_controls.js @@ -5,14 +5,20 @@ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later */ function initTopControls() { - if ($('#periodString').length) { - var left=0; - $('.top_controls').children('.js-autoLeftPanel').each(function(i, el){ - var control = $(el); - if (left) { - control.css({left: left}); - } - left+=control.outerWidth(true); - }); - } + var $topControlsContainer = $('.top_controls'), + left = 0; + $('.piwikTopControl').each(function () { + var $control = $(this); + if ($control.css('display') == 'none') { + return; + } + + $control.css('left', left); + + if (!$.contains($topControlsContainer[0], this)) { + $control.detach().appendTo($topControlsContainer); + } + + left += $control.outerWidth(true); + }); } \ No newline at end of file diff --git a/plugins/CoreHome/javascripts/uiControl.js b/plugins/CoreHome/javascripts/uiControl.js index 7c92d26a01ff2d8f5b7320e2d9668e2c2f4b6f04..1c3c8aaf19c2e7d8109c839072b70f059f07526e 100644 --- a/plugins/CoreHome/javascripts/uiControl.js +++ b/plugins/CoreHome/javascripts/uiControl.js @@ -18,6 +18,10 @@ * @param {Element} element The root element of the control. */ var UIControl = function (element) { + if (!element) { + throw new Error("no element passed to UIControl constructor"); + } + this._controlId = UIControl._controls.length; UIControl._controls.push(this); diff --git a/plugins/CoreHome/templates/_periodSelect.twig b/plugins/CoreHome/templates/_periodSelect.twig index b0f853c506a44801df53a608992b8f7d5f8284d8..6373adfd1bbfad99e89c3c120f266fcd9b30be1e 100644 --- a/plugins/CoreHome/templates/_periodSelect.twig +++ b/plugins/CoreHome/templates/_periodSelect.twig @@ -1,4 +1,4 @@ -<div id="periodString" class="js-autoLeftPanel"> +<div id="periodString" class="piwikTopControl"> <div id="date">{{ 'General_DateRange'|translate }} <strong>{{ prettyDate }}</strong></div> <div class="calendar-icon"></div> <div id="periodMore"> diff --git a/plugins/Dashboard/DashboardManagerControl.php b/plugins/Dashboard/DashboardManagerControl.php index 71727d61d1885e5b8173a800d5bdc8cc317aa0f3..af6303d2b0ca8ba1d07e17a58e4127717da36793 100644 --- a/plugins/Dashboard/DashboardManagerControl.php +++ b/plugins/Dashboard/DashboardManagerControl.php @@ -22,7 +22,7 @@ class DashboardManagerControl extends DashboardSettingsControlBase parent::__construct(); $this->jsClass = "DashboardManagerControl"; - $this->cssIdentifier = "dashboardSettings"; + $this->cssIdentifier = "dashboard-manager"; $this->addDashboardActions(); $this->addGeneralActions(); diff --git a/plugins/Dashboard/DashboardSettingsControlBase.php b/plugins/Dashboard/DashboardSettingsControlBase.php index e78b086b20344f76b73b28d7210630b1bcfe58ca..d546d33b79ce3eff3df2a3f202325ddbc997047b 100644 --- a/plugins/Dashboard/DashboardSettingsControlBase.php +++ b/plugins/Dashboard/DashboardSettingsControlBase.php @@ -23,7 +23,7 @@ abstract class DashboardSettingsControlBase extends UIControl { parent::__construct(); - $this->cssClass = "js-autoLeftPanel"; + $this->cssClass = "piwikTopControl dashboardSettings"; $this->dashboardActions = array(); $this->generalActions = array(); } diff --git a/plugins/Dashboard/javascripts/dashboard.js b/plugins/Dashboard/javascripts/dashboard.js index 3afdaff096a62c140c09a56c8aeef25e35d46364..7b1b2a25384ed731f87651fddf313da61e5f6710 100644 --- a/plugins/Dashboard/javascripts/dashboard.js +++ b/plugins/Dashboard/javascripts/dashboard.js @@ -8,7 +8,6 @@ function initDashboard(dashboardId, dashboardLayout) { $('.dashboardSettings').show(); - initTopControls(); // Embed dashboard if (!$('#topBars').length) { @@ -16,25 +15,6 @@ function initDashboard(dashboardId, dashboardLayout) { $('#Dashboard_embeddedIndex_' + dashboardId).addClass('sfHover'); } - $('.dashboardSettings').on('click', function (e) { - if ($(e.target).is('.dashboardSettings') || $(e.target).is('.dashboardSettings>span')) { - $('.dashboardSettings').toggleClass('visible'); - if ($('#dashboardWidgetsArea').dashboard('isDefaultDashboard')) { - $('.removeDashboardLink').hide(); - } else { - $('.removeDashboardLink').show(); - } - // fix position - $('.dashboardSettings').find('.widgetpreview-widgetlist').css('paddingTop', $('.dashboardSettings').find('.widgetpreview-categorylist').parent('li').position().top); - } - }); - $('body').on('mouseup', function (e) { - if (!$(e.target).parents('.dashboardSettings').length && !$(e.target).is('.dashboardSettings')) { - $('.dashboardSettings').widgetPreview('reset'); - $('.dashboardSettings').removeClass('visible'); - } - }); - widgetsHelper.getAvailableWidgets(); $('#dashboardWidgetsArea') @@ -44,18 +24,6 @@ function initDashboard(dashboardId, dashboardLayout) { layout: dashboardLayout }); - $('.dashboardSettings').widgetPreview({ - isWidgetAvailable: function (widgetUniqueId) { - return !$('#dashboardWidgetsArea').find('[widgetId=' + widgetUniqueId + ']').length; - }, - onSelect: function (widgetUniqueId) { - var widget = widgetsHelper.getWidgetObjectFromUniqueId(widgetUniqueId); - $('#dashboardWidgetsArea').dashboard('addWidget', widget.uniqueId, 1, widget.parameters, true, false); - $('.dashboardSettings').removeClass('visible'); - }, - resetOnSelect: true - }); - $('#columnPreview').find('>div').each(function () { var width = []; $('div', this).each(function () { @@ -68,13 +36,6 @@ function initDashboard(dashboardId, dashboardLayout) { $('#columnPreview').find('>div').removeClass('choosen'); $(this).addClass('choosen'); }); - - $('.submenu > li').on('mouseenter', function (event) { - if (!$('.widgetpreview-categorylist', event.target).length) { - $('.dashboardSettings').widgetPreview('reset'); - } - }); - } function createDashboard() { @@ -203,12 +164,68 @@ function copyDashboardToUser() { var DashboardSettingsControlBase = function (element) { UIControl.call(this, element); + // on menu item click, trigger action event on this var self = this; this.$element.on('click', 'ul.submenu li[data-action]', function (e) { $(self).trigger($(this).attr('data-action')); }); + + // open manager on open + this.$element.on('click', function (e) { + if ($(e.target).is('.dashboardSettings,.dashboardSettings>span')) { + self.$element.toggleClass('visible'); + + // fix position + self.$element + .find('.widgetpreview-widgetlist') + .css('paddingTop', self.$element.find('.widgetpreview-categorylist').parent('li').position().top); + + self.onOpen(); + } + }); + + // handle manager close + this.onBodyMouseUp = function (e) { + if (!$(e.target).closest('.dashboardSettings').length + && !$(e.target).is('.dashboardSettings') + ) { + self.$element.widgetPreview('reset'); + self.$element.removeClass('visible'); + } + }; + + $('body').on('mouseup', this.onBodyMouseUp); + + // setup widgetPreview + this.$element.widgetPreview({ + isWidgetAvailable: function (widgetUniqueId) { + return self.isWidgetAvailable(widgetUniqueId); + }, + onSelect: function (widgetUniqueId) { + var widget = widgetsHelper.getWidgetObjectFromUniqueId(widgetUniqueId); + self.$element.removeClass('visible'); + + self.widgetSelected(widget); + }, + resetOnSelect: true + }); + + // on enter widget list category, reset widget preview + this.$element.on('mouseenter', '.submenu > li', function (event) { + if (!$('.widgetpreview-categorylist', event.target).length) { + self.$element.widgetPreview('reset'); + } + }); }; + $.extend(DashboardSettingsControlBase.prototype, UIControl.prototype, { + _destroy: function () { + UIControl.prototype.call(this); + + $('body')[0].removeEventListener(this.onBodyMouseUp); + } + }); + exports.DashboardSettingsControlBase = DashboardSettingsControlBase; /** @@ -250,8 +267,26 @@ function copyDashboardToUser() { }); }; + $.extend(DashboardManagerControl.prototype, DashboardSettingsControlBase.prototype, { + onOpen: function () { + if ($('#dashboardWidgetsArea').dashboard('isDefaultDashboard')) { + $('.removeDashboardLink', this.$element).hide(); + } else { + $('.removeDashboardLink', this.$element).show(); + } + }, + + isWidgetAvailable: function (widgetUniqueId) { + return !$('#dashboardWidgetsArea').find('[widgetId=' + widgetUniqueId + ']').length; + }, + + widgetSelected: function (widget) { + $('#dashboardWidgetsArea').dashboard('addWidget', widget.uniqueId, 1, widget.parameters, true, false); + } + }); + DashboardManagerControl.initElements = function () { - UIControl.initElements(this, '.dashboardSettings'); + UIControl.initElements(this, '.dashboard-manager'); }; exports.DashboardManagerControl = DashboardManagerControl; diff --git a/plugins/Dashboard/templates/index.twig b/plugins/Dashboard/templates/index.twig index 5d34202044035c21591256c6f72dd99b7c5d3fc5..0a8831fe3fcfdbbe5c567e580c238eaba1a8fe31 100644 --- a/plugins/Dashboard/templates/index.twig +++ b/plugins/Dashboard/templates/index.twig @@ -3,7 +3,7 @@ {% include "@CoreHome/_periodSelect.twig" %} {{ postEvent("Template.nextToCalendar") }} {% render dashboardSettingsControl %} - <div id="Dashboard" class="js-autoLeftPanel"> + <div id="Dashboard" class="piwikTopControl"> <ul> {% for dashboard in dashboards %} <li class="dashboardMenuItem" id="Dashboard_embeddedIndex_{{ dashboard.iddashboard }}"> diff --git a/plugins/SegmentEditor/SegmentSelectorControl.php b/plugins/SegmentEditor/SegmentSelectorControl.php index bacc057e293e4bbbcc74cbc00e2565738b603f35..747bb6fdf5bd0b11cbb231d0b29162cb64c74d1e 100644 --- a/plugins/SegmentEditor/SegmentSelectorControl.php +++ b/plugins/SegmentEditor/SegmentSelectorControl.php @@ -30,7 +30,7 @@ class SegmentSelectorControl extends UIControl $this->jsClass = "SegmentSelectorControl"; $this->cssIdentifier = "segmentEditorPanel"; - $this->cssClass = "js-autoLeftPanel"; + $this->cssClass = "piwikTopControl"; $this->idSite = Common::getRequestVar('idSite', false, 'int'); diff --git a/plugins/SegmentEditor/javascripts/Segmentation.js b/plugins/SegmentEditor/javascripts/Segmentation.js index f8c1d6471845cd57917d01e796a2a18260c829f9..195318c679731408e8aa18b007e1372dd58061df 100644 --- a/plugins/SegmentEditor/javascripts/Segmentation.js +++ b/plugins/SegmentEditor/javascripts/Segmentation.js @@ -17,12 +17,13 @@ Segmentation = (function($) { self.currentSegmentStr = ""; self.segmentAccess = "read"; self.availableSegments = []; - self.editorTemplate = $('.SegmentEditor', self.target).detach(); for (var item in config) { self[item] = config[item]; } + self.editorTemplate = self.editorTemplate.detach(); + self.timer = ""; // variable for further use in timing events self.searchAllowed = true; @@ -967,7 +968,6 @@ Segmentation = (function($) { self.target.append(html); self.content = self.target.find(".segmentationContainer"); } - initTopControls(); // assign content to object attribute to make it easil accesible through all widget methods bindListEvents(); @@ -1005,7 +1005,7 @@ $(document).ready(function() { } var self = this; - var changeSegment = function(segmentDefinition){ + this.changeSegment = function(segmentDefinition) { self.$element.find('a.close').click(); segmentDefinition = cleanupSegmentDefinition(segmentDefinition); segmentDefinition = encodeURIComponent(segmentDefinition); @@ -1034,7 +1034,7 @@ $(document).ready(function() { if (response && response.result == 'error') { alert(response.message); } else { - changeSegment(params.definition); + self.changeSegment(params.definition); } }); ajaxHandler.send(true); @@ -1056,7 +1056,7 @@ $(document).ready(function() { if (response && response.result == 'error') { alert(response.message); } else { - changeSegment(params.definition); + self.changeSegment(params.definition); } }); ajaxHandler.send(true); @@ -1079,7 +1079,8 @@ $(document).ready(function() { if (response && response.result == 'error') { alert(response.message); } else { - return broadcast.propagateNewPage('segment='); + self.changeSegment(''); + $('.ui-dialog-content').dialog('close'); } }); @@ -1095,12 +1096,13 @@ $(document).ready(function() { this.impl = new Segmentation({ "target" : this.$element.find(".segmentListContainer"), + "editorTemplate": $('.SegmentEditor', self.$element), "segmentAccess" : "write", "availableSegments" : this.props.availableSegments, "addMethod": addSegment, "updateMethod": updateSegment, "deleteMethod": deleteSegment, - "segmentSelectMethod": changeSegment, + "segmentSelectMethod": function () { self.changeSegment.apply(this, arguments); }, "currentSegmentStr": segmentFromRequest, "translations": this.props.segmentTranslations });