From 798000d19c1512a7dea0336896942f644446eedf Mon Sep 17 00:00:00 2001
From: Thomas Steur <thomas.steur@googlemail.com>
Date: Thu, 17 Apr 2014 07:08:05 +0200
Subject: [PATCH] refs #4987 started to work on piwik zen mode, will improve
 widgets later... still in exploration mode but is already pretty nice to use

---
 plugins/CoreHome/CoreHome.php                 |   2 +
 .../angularjs/common/filters/length.js        |  17 ++
 .../CoreHome/angularjs/common/filters/trim.js |  17 ++
 .../CoreHome/images/navigation_collapse.png   | Bin 0 -> 484 bytes
 plugins/CoreHome/images/navigation_expand.png | Bin 0 -> 502 bytes
 plugins/CoreHome/javascripts/menu.js          |  10 +-
 plugins/CoreHome/stylesheets/menu.less        |   8 +-
 plugins/CoreHome/templates/_menu.twig         |   5 +
 plugins/ZenMode/ZenMode.php                   |  39 +++++
 .../quick-access/quick-access-directive.js    |  99 +++++++++++
 .../angularjs/quick-access/quick-access.html  |  13 ++
 .../angularjs/quick-access/quick-access.less  |  17 ++
 .../angularjs/zen-mode/zen-mode-directive.js  |  60 +++++++
 .../zen-mode/zen-mode-switcher-directive.js   |  74 ++++++++
 .../ZenMode/angularjs/zen-mode/zen-mode.less  | 160 ++++++++++++++++++
 plugins/ZenMode/javascripts/zen-mode.js       |  28 +++
 plugins/ZenMode/plugin.json                   |   6 +
 17 files changed, 551 insertions(+), 4 deletions(-)
 create mode 100644 plugins/CoreHome/angularjs/common/filters/length.js
 create mode 100644 plugins/CoreHome/angularjs/common/filters/trim.js
 create mode 100755 plugins/CoreHome/images/navigation_collapse.png
 create mode 100755 plugins/CoreHome/images/navigation_expand.png
 create mode 100644 plugins/ZenMode/ZenMode.php
 create mode 100644 plugins/ZenMode/angularjs/quick-access/quick-access-directive.js
 create mode 100644 plugins/ZenMode/angularjs/quick-access/quick-access.html
 create mode 100644 plugins/ZenMode/angularjs/quick-access/quick-access.less
 create mode 100644 plugins/ZenMode/angularjs/zen-mode/zen-mode-directive.js
 create mode 100644 plugins/ZenMode/angularjs/zen-mode/zen-mode-switcher-directive.js
 create mode 100644 plugins/ZenMode/angularjs/zen-mode/zen-mode.less
 create mode 100644 plugins/ZenMode/javascripts/zen-mode.js
 create mode 100644 plugins/ZenMode/plugin.json

diff --git a/plugins/CoreHome/CoreHome.php b/plugins/CoreHome/CoreHome.php
index e2fd3b3062..9234602b44 100644
--- a/plugins/CoreHome/CoreHome.php
+++ b/plugins/CoreHome/CoreHome.php
@@ -103,6 +103,8 @@ class CoreHome extends \Piwik\Plugin
         $jsFiles[] = "plugins/CoreHome/angularjs/common/filters/translate.js";
         $jsFiles[] = "plugins/CoreHome/angularjs/common/filters/startfrom.js";
         $jsFiles[] = "plugins/CoreHome/angularjs/common/filters/evolution.js";
+        $jsFiles[] = "plugins/CoreHome/angularjs/common/filters/length.js";
+        $jsFiles[] = "plugins/CoreHome/angularjs/common/filters/trim.js";
 
         $jsFiles[] = "plugins/CoreHome/angularjs/common/directives/directive.js";
         $jsFiles[] = "plugins/CoreHome/angularjs/common/directives/autocomplete-matched.js";
diff --git a/plugins/CoreHome/angularjs/common/filters/length.js b/plugins/CoreHome/angularjs/common/filters/length.js
new file mode 100644
index 0000000000..20a63e6d2d
--- /dev/null
+++ b/plugins/CoreHome/angularjs/common/filters/length.js
@@ -0,0 +1,17 @@
+/*!
+ * Piwik - Web Analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+angular.module('piwikApp.filter').filter('length', function() {
+
+    return function(stringOrArray) {
+        if (stringOrArray && stringOrArray.length) {
+            return stringOrArray.length;
+        }
+
+        return 0;
+    };
+});
diff --git a/plugins/CoreHome/angularjs/common/filters/trim.js b/plugins/CoreHome/angularjs/common/filters/trim.js
new file mode 100644
index 0000000000..aa11cb8374
--- /dev/null
+++ b/plugins/CoreHome/angularjs/common/filters/trim.js
@@ -0,0 +1,17 @@
+/*!
+ * Piwik - Web Analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+angular.module('piwikApp.filter').filter('trim', function() {
+
+    return function(string) {
+        if (string) {
+            return $.trim('' + string);
+        }
+
+        return string;
+    };
+});
diff --git a/plugins/CoreHome/images/navigation_collapse.png b/plugins/CoreHome/images/navigation_collapse.png
new file mode 100755
index 0000000000000000000000000000000000000000..cbbab2b464610be6891d5eeb460df77722cf3206
GIT binary patch
literal 484
zcmV<A0UQ2_P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800052Nkl<ZSVv=I
z7+}CS!1gnYI$$&eMnhmU1SkptZEbBfP(gO}>eXN57HDKUz}niH_s5SPIUtKUI5?&p
zJ$m#rIgTL90h*ecl3ZL|dH?_a7Y13%$jJEi+qZ9%u3x|YoK#1U>;OGIJ#|)A)=Z$~
zT*#II9r5k=@88oeUAlCW6i1Nc00RR9D`sZq7@*}WP)iO0*+9D)ZJ{CY=kMRYOD<fv
zaEw?-5bXd%Lqk8HMLtl2{{!ju=gytm0pc4O8F>JyKu~Oe_&`T(Ie-5ACSn{xj00GJ
zmd67vH-{Sd8%WOsT7DMU0-zcbpqfOW7%S8fCxMPw2xR}k=McOOFg7*@#d8+WM{3X@
z2Bq|AXV0F!i_K7=dS$43Ua0z8Q1#z%IRd8xfIbpsVqyZNbaAL*FaG`eHyP-w*Z6z{
z)t3v@Cqaxpd=5y41v`)?=o4f|p@$sMF`(#}i_PIU9iXD3!p_gnUk3E`Gh*Tri{aq3
z0}Mr}j~_pF-MMq;CrJ(fDVC9u;e7Js$#-H>GcGlR%pfKgP+~tpy`v5o4S~@R7!82|
a4*>w^Po*JClDixL0000<MNUMnLSTZ4FwE!x

literal 0
HcmV?d00001

diff --git a/plugins/CoreHome/images/navigation_expand.png b/plugins/CoreHome/images/navigation_expand.png
new file mode 100755
index 0000000000000000000000000000000000000000..7d8dad34b0a1389d743c7aeca976c806f72226e7
GIT binary patch
literal 502
zcmV<S0SW$zP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80005KNkl<ZSVv=I
z7+}CS!1gnYI$$&eMnhmU1n`D{jEoHDlP6EUQ&LzFG6SarR8&;h`T6<F{{8#+?ELxj
z3xSUKL!v`i3=IwAfqJAqfBxKc=gys<*!1Ic08n!>BO{|ZNE4901*E2(J$v>WF^(`c
zHs%7V%liNSzZytAkUk0Y#9UGxAj-tVln2x-4t2x}U}#JR8uS{UBY+ME>B|M`lYr`b
z3Dh?Ump;5{0Np3RkoXJ@iM!Yw0aULH^*JxGAxBI$1ji*TI)DcM2I6_=&Ye4p><A+x
zBV!;x35Z#df}LR6A;tk<dw`Dc13JP7YUzI<y&mX@9Uwl?at|OC2udzc%eMf7d=oM0
zg=hzW3^On=uwrIrjseCm3)G^+Ku3WbV+RfLKY#!JU2@^Vg=5564%S1gLYO)|Jw0_+
zR@O|QBS0w~4uB5%_WSqm>6b2Dx=D(eBs&0PxTdD2Bo`MKD2E6`eg5{_w{MfKU%&pG
z6wAp90hk5W*4Df~e*DM*@i{m+rW`$b6qG|q24sZ*%oc5JZ8i}5>eZ{iNVXZOfg%Tx
sYbi?Fp@t!pm@ygxqaiRF0;3@S0I6xFA&E;Ik^lez07*qoM6N<$f)6CnTL1t6

literal 0
HcmV?d00001

diff --git a/plugins/CoreHome/javascripts/menu.js b/plugins/CoreHome/javascripts/menu.js
index a4ecb5eae1..798496989d 100644
--- a/plugins/CoreHome/javascripts/menu.js
+++ b/plugins/CoreHome/javascripts/menu.js
@@ -53,7 +53,15 @@ menu.prototype =
         // for all sub menu we want to have a unique id based on their module and action
         // for main menu we want to add just the module as its id.
         this.menuNode.find('li').each(function () {
-            var url = $(this).find('a').attr('href').substr(1);
+            var link = $(this).find('a');
+            if (!link) {
+                return;
+            }
+            var href = link.attr('href');
+            if (!href) {
+                return;
+            }
+            var url = href.substr(1);
             var module = broadcast.getValueFromUrl("module", url);
             var action = broadcast.getValueFromUrl("action", url);
             var moduleId = broadcast.getValueFromUrl("idGoal", url) || broadcast.getValueFromUrl("idDashboard", url);
diff --git a/plugins/CoreHome/stylesheets/menu.less b/plugins/CoreHome/stylesheets/menu.less
index f4a28a49a7..a25cd131f9 100644
--- a/plugins/CoreHome/stylesheets/menu.less
+++ b/plugins/CoreHome/stylesheets/menu.less
@@ -59,7 +59,7 @@
 }
 
 /* LEVEL2 NORMAL */
-.Menu--dashboard > .Menu-tabList > li > ul {
+.Menu--dashboard > .Menu-tabList > li ul {
   padding: 9px 0 5px 0;
   left: 0;
   top: -999em;
@@ -69,6 +69,7 @@
   background: none;
 }
 
+
 .Menu--dashboard > .Menu-tabList > li li {
     float: left;
     background: none;
@@ -88,9 +89,10 @@
     text-decoration: none;
 }
 
+
 /* LEVEL2 HOVER */
-.Menu--dashboard > .Menu-tabList > li.sfHover > ul,
-.Menu--dashboard > .Menu-tabList > li:hover > ul {
+.Menu--dashboard > .Menu-tabList > li.sfHover ul,
+.Menu--dashboard > .Menu-tabList > li:hover ul {
   z-index: 1;
   top: 100%;
   opacity: 1;
diff --git a/plugins/CoreHome/templates/_menu.twig b/plugins/CoreHome/templates/_menu.twig
index 4437b90d35..1701d14f91 100644
--- a/plugins/CoreHome/templates/_menu.twig
+++ b/plugins/CoreHome/templates/_menu.twig
@@ -1,4 +1,5 @@
 <div class="Menu--dashboard">
+
     <ul class="Menu-tabList">
         {% for level1,level2 in menu %}
             <li id="{{ level2._url|urlRewriteWithParameters }}">
@@ -18,6 +19,10 @@
                 </ul>
             </li>
         {% endfor %}
+        <li id="Searchmenu">
+            <span piwik-quick-access></span>
+        </li>
     </ul>
+
 </div>
 <div class="nav_sep"></div>
diff --git a/plugins/ZenMode/ZenMode.php b/plugins/ZenMode/ZenMode.php
new file mode 100644
index 0000000000..c112da43ce
--- /dev/null
+++ b/plugins/ZenMode/ZenMode.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+namespace Piwik\Plugins\ZenMode;
+
+/**
+ */
+class ZenMode extends \Piwik\Plugin
+{
+    /**
+     * @see Piwik\Plugin::getListHooksRegistered
+     */
+    public function getListHooksRegistered()
+    {
+        return array(
+            'AssetManager.getJavaScriptFiles' => 'getJsFiles',
+            'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
+        );
+    }
+
+    public function getJsFiles(&$jsFiles)
+    {
+        $jsFiles[] = "plugins/ZenMode/javascripts/zen-mode.js";
+        $jsFiles[] = "plugins/ZenMode/angularjs/quick-access/quick-access-directive.js";
+        $jsFiles[] = "plugins/ZenMode/angularjs/zen-mode/zen-mode-directive.js";
+        $jsFiles[] = "plugins/ZenMode/angularjs/zen-mode/zen-mode-switcher-directive.js";
+    }
+
+    public function getStylesheetFiles(&$stylesheets)
+    {
+        $stylesheets[] = "plugins/ZenMode/angularjs/quick-access/quick-access.less";
+        $stylesheets[] = "plugins/ZenMode/angularjs/zen-mode/zen-mode.less";
+    }
+}
diff --git a/plugins/ZenMode/angularjs/quick-access/quick-access-directive.js b/plugins/ZenMode/angularjs/quick-access/quick-access-directive.js
new file mode 100644
index 0000000000..c917d4fcc7
--- /dev/null
+++ b/plugins/ZenMode/angularjs/quick-access/quick-access-directive.js
@@ -0,0 +1,99 @@
+/*!
+ * Piwik - Web Analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+/**
+ * Usage:
+ * <div piwik-dialog="showDialog">...</div>
+ * Will show dialog once showDialog evaluates to true.
+ *
+ * Will execute the "executeMyFunction" function in the current scope once the yes button is pressed.
+ */
+angular.module('piwikApp.directive').directive('piwikQuickAccess', function($rootElement, $timeout) {
+
+    return {
+        restrict: 'A',
+        replace: true,
+        scope: {},
+        templateUrl: 'plugins/ZenMode/angularjs/quick-access/quick-access.html?cb=' + piwik.cacheBuster,
+        link: function (scope, element, attrs) {
+
+            var menuIndex = -1;
+
+            function getMenuEntries()
+            {
+                var menuEntries = [];
+
+                $rootElement.find('#topLeftBar .topBarElem a, #topRightBar .topBarElem a').each(function (index, element) {
+                    menuEntries.push({name: $(element).text(), index: ++menuIndex, category: 'menu'});
+                    $(element).attr('quick_access', menuIndex);
+                });
+
+                return menuEntries;
+            }
+            function getReportEntries()
+            {
+                var reportEntries = [];
+
+                $rootElement.find('.Menu-tabList a').each(function (index, element) {
+                    reportEntries.push({name: $(element).text(), menu: 'Report', index: ++menuIndex});
+                    $(element).attr('quick_access', menuIndex);
+                });
+
+                return reportEntries;
+            }
+
+            scope.menuEntries = getMenuEntries();
+            scope.reportEntries = getReportEntries();
+
+            scope.onKeypress = function (event) {
+
+                if (38 == event.which) {
+
+                    if (0 >= (this.search.index - 1)) {
+                        this.search.index = 0;
+                    } else {
+                        this.search.index--;
+                    }
+                } else if (40 == event.which) {
+                    // down
+                    var numTotal = element.find('li.result').length;
+
+                    if (numTotal <= (this.search.index + 1)) {
+                        this.search.index = numTotal - 1;
+                    } else {
+                        this.search.index++;
+                    }
+                } else if (13 == event.which) {
+                    var results = element.find('li.result');
+                    if (results && results.length && results[this.search.index]) {
+                        var selectedMenuElement = $(results[this.search.index]);
+                        $timeout(function () {
+                            selectedMenuElement.click();
+                        }, 20);
+                    }
+                }
+            };
+
+            scope.selectMenuItem = function (index) {
+                var target = $rootElement.find('[quick_access=' + index + ']');
+
+                if (target && target.length && target[0]) {
+                    var actualTarget = target[0];
+
+                    var href = $(actualTarget).attr('href');
+
+                    if (href && href.length > 10) {
+                        actualTarget.click();
+                    } else {
+                        $(actualTarget).click();
+                    }
+                }
+            };
+
+        }
+    };
+});
\ No newline at end of file
diff --git a/plugins/ZenMode/angularjs/quick-access/quick-access.html b/plugins/ZenMode/angularjs/quick-access/quick-access.html
new file mode 100644
index 0000000000..d1f6f98ae1
--- /dev/null
+++ b/plugins/ZenMode/angularjs/quick-access/quick-access.html
@@ -0,0 +1,13 @@
+<div class="quick-access">
+    <input ng-keydown="onKeypress($event)" ng-change="search.index=0" ng-model="search.term" type="text" placeholder="Search for anything"/>
+    <ul ng-show="search.term">
+        <li class="quick-access-category" ng-click="search.term='menu'">Menu</li>
+        <li class="no-result" ng-hide="menuEntries | filter:search.term | length">---</li>
+        <li class="result" ng-class="{selected: $index == search.index}" ng-click="selectMenuItem(entry.index)" ng-repeat="entry in menuEntries | filter:search.term"><a>{{ entry.name | trim }}</a></li>
+        <li class="quick-access-category">Websites</li>
+        <li class="no-result">---</li>
+        <li class="quick-access-category">Reports</li>
+        <li class="no-result" ng-hide="reportEntries | filter:search.term | length">---</li>
+        <li class="result" ng-class="{selected: ((menuEntries | filter:search.term | length) + $index) == search.index}" ng-click="selectMenuItem(entry.index)" ng-repeat="entry in reportEntries | filter:search.term"><a>{{ entry.name | trim }}</a></li>
+    </ul>
+</div>
\ No newline at end of file
diff --git a/plugins/ZenMode/angularjs/quick-access/quick-access.less b/plugins/ZenMode/angularjs/quick-access/quick-access.less
new file mode 100644
index 0000000000..c34793d0ec
--- /dev/null
+++ b/plugins/ZenMode/angularjs/quick-access/quick-access.less
@@ -0,0 +1,17 @@
+.quick-access {
+  .selected {
+    background-color: #f2f2f2 !important;
+  }
+  .quick-access-category {
+    text-align: left !important;
+    font-size: 14px;
+    padding: 5px;
+    cursor: pointer;
+  }
+  .result {
+    cursor: pointer;
+  }
+  .quick-access-category:hover {
+    background: none !important;
+  }
+}
\ No newline at end of file
diff --git a/plugins/ZenMode/angularjs/zen-mode/zen-mode-directive.js b/plugins/ZenMode/angularjs/zen-mode/zen-mode-directive.js
new file mode 100644
index 0000000000..480ff47f75
--- /dev/null
+++ b/plugins/ZenMode/angularjs/zen-mode/zen-mode-directive.js
@@ -0,0 +1,60 @@
+/*!
+ * Piwik - Web Analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+/**
+ * Usage:
+ * <div piwik-dialog="showDialog">...</div>
+ * Will show dialog once showDialog evaluates to true.
+ *
+ * Will execute the "executeMyFunction" function in the current scope once the yes button is pressed.
+ */
+angular.module('piwikApp.directive').directive('piwikZenMode', function($rootElement) {
+
+    return {
+        restrict: 'A',
+        compile: function (element, attrs) {
+            var zenMode = attrs.piwikZenMode;
+            var parent, prev, next;
+
+            if ('visible' == zenMode) {
+                element.hide();
+            }
+
+            $rootElement.bind('zen-mode', function (event, enabled) {
+                if (zenMode == 'visible') {
+                    enabled ? element.show() : element.hide();
+                } else if (zenMode == 'hidden') {
+                    enabled ? element.hide() : element.show();
+                } else if (zenMode) {
+                    if (enabled) {
+                        parent = element.parent();
+                        prev = element.prev();
+                        next = element.next();
+
+                        $rootElement.find(zenMode).prepend(element);
+
+                    } else {
+
+                        if (prev) {
+                            prev.after(element);
+                        } else if (next) {
+                            next.before(element);
+                        } else if (parent) {
+                            parent.append(element)
+                        }
+
+                        prev = next = parent = null;
+                    }
+                }
+            })
+
+            return function () {
+
+            };
+        }
+    };
+});
\ No newline at end of file
diff --git a/plugins/ZenMode/angularjs/zen-mode/zen-mode-switcher-directive.js b/plugins/ZenMode/angularjs/zen-mode/zen-mode-switcher-directive.js
new file mode 100644
index 0000000000..4b19bd1da3
--- /dev/null
+++ b/plugins/ZenMode/angularjs/zen-mode/zen-mode-switcher-directive.js
@@ -0,0 +1,74 @@
+/*!
+ * Piwik - Web Analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+/**
+ * Usage:
+ * <div piwik-dialog="showDialog">...</div>
+ * Will show dialog once showDialog evaluates to true.
+ *
+ * Will execute the "executeMyFunction" function in the current scope once the yes button is pressed.
+ */
+angular.module('piwikApp.directive').directive('piwikZenModeSwitcher', function($rootElement) {
+
+    var zenMode = false;
+
+    function updateZenMode()
+    {
+        $rootElement.toggleClass('zenMode');
+        $rootElement.trigger('zen-mode', zenMode);
+    }
+
+    function overMainLI () {
+        if (!zenMode) {
+            return;
+        }
+        var $this = $(this);
+        var position = $this.position();
+        var width = $this.width();
+
+        $this.find('ul').css({left: position.left + 'px', display: 'block', minWidth: width+'px'});
+    };
+
+    function outMainLI () {
+        if (!zenMode) {
+            return;
+        }
+        var $this = $(this);
+        $this.find('ul').css({left: '', display: '', minWidth: ''});
+    };
+
+    function onItemSelect()
+    {
+        $('.Menu--dashboard').find('ul ul').css('display', '')
+    }
+
+    var initDone = false;
+    function init () {
+        if (!initDone) {
+            initDone = true;
+            var menuNode = $('.Menu--dashboard');
+            menuNode.on('piwikSwitchPage', onItemSelect);
+            menuNode.find('li:has(ul)').hover(overMainLI, outMainLI);
+        }
+    }
+
+    return {
+        restrict: 'A',
+        compile: function (element, attrs) {
+
+            element.on('click', function() {
+                zenMode = !zenMode;
+                init();
+                updateZenMode();
+            });
+
+            return function () {
+            };
+
+        }
+    };
+});
\ No newline at end of file
diff --git a/plugins/ZenMode/angularjs/zen-mode/zen-mode.less b/plugins/ZenMode/angularjs/zen-mode/zen-mode.less
new file mode 100644
index 0000000000..da7e05e923
--- /dev/null
+++ b/plugins/ZenMode/angularjs/zen-mode/zen-mode.less
@@ -0,0 +1,160 @@
+.deactivateZenMode {
+  float:right;
+  margin-right: 13px;
+  margin-top: 4px;
+  display: none;
+  img {
+    width: 16px;
+    height: 16px;
+  }
+}
+
+.activateZenMode {
+  img {
+    margin-top: -3px;
+    margin-bottom: -3px;
+    width: 16px;
+    height: 16px;
+  }
+}
+
+.Menu--dashboard #Searchmenu {
+  display: none;
+}
+
+.zenMode {
+
+  #header {
+    display: none;
+  }
+
+  .Menu--dashboard #Searchmenu {
+    display: block;
+  }
+
+  .quick-access {
+    display: inline-block;
+    color: #999;
+    padding: 8px 20px 7px 20px;
+    input {
+      border:0px;
+      border-bottom: 1px solid #CCC;
+    }
+  }
+
+  .deactivateZenMode {
+    display: block;
+  }
+
+  .activateZenMode {
+    display: none;
+  }
+
+  .nav_sep {
+    display: none;
+  }
+
+  /* MENU LEVEL2 HOVER */
+  .Menu--dashboard > .Menu-tabList > li li {
+    float: none;
+  }
+
+  .Menu--dashboard > .Menu-tabList > li li:hover {
+    background-color: #f2f2f2;
+  }
+
+  .Menu--dashboard > .Menu-tabList > li ul {
+    display: none;
+  }
+
+  .Menu--dashboard > .Menu-tabList > li.sfHover ul,
+  .Menu--dashboard > .Menu-tabList > li:hover ul {
+    display: none;
+    z-index: 150;
+    background-color: #FFF;
+    width: auto;
+    border: 1px solid #D9D9D9;
+    padding-top: 0px;
+    border-top: 4px solid #D3291F;
+  }
+
+  #root .sites_selector_in_dashboard {
+    margin-top:0px;
+    margin-right: 0px;
+    display: none;
+  }
+
+  /* DATATABLES */
+  table.dataTable th.sortable {
+    background: @theme-color-background-base !important;
+    border-left: 0px;
+    border-bottom: 0px;
+  }
+
+  table.dataTable th.columnSorted {
+    font-weight: normal !important;
+  }
+
+  table.dataTable tr.subDataTable {
+    font-weight: normal !important;
+  }
+
+  table.dataTable tr.subDataTable td.label .plusMinus + .label .value {
+    font-weight: bold !important;
+  }
+
+  .widget {
+    border-color: @silver-85;
+
+    .widgetTop {
+      border-color: @silver-85;
+    }
+  }
+
+  .dataTableActions > .dataTableWrapper {
+    width: 100%;
+  }
+
+  table.dataTable tr td.columnodd {
+   // background-color: @theme-color-background-base !important;
+  }
+
+  table.dataTable tr td {
+    padding-top: 7px;
+    padding-bottom: 7px;
+  }
+
+  .dataTableFooterNavigation {
+    padding: 7px 0;
+  }
+
+  .dataTableFooterIcons {
+    border-top: 0px;
+  }
+
+  #content h2:nth-of-type(n+2) {
+    margin-top: 40px;
+  }
+
+  #content h2 {
+    padding-left: 10px;
+    font-size: 24px;
+  }
+
+  /*
+  table.dataTable tr td .value {
+    color: #999;
+  }
+
+  table.dataTable tr:nth-child(-n+5) td .value,
+  table.dataTable tr:hover td .value {
+    color: inherit;
+  }*/
+
+  table.dataTable tr:hover td.labeleven,
+  table.dataTable tr:hover td.columneven,
+  table.dataTable tr:hover td.labelodd,
+  table.dataTable tr:hover td.columnodd {
+    background-color: @silver-95 !important;
+  }
+}
diff --git a/plugins/ZenMode/javascripts/zen-mode.js b/plugins/ZenMode/javascripts/zen-mode.js
new file mode 100644
index 0000000000..3d951b86c4
--- /dev/null
+++ b/plugins/ZenMode/javascripts/zen-mode.js
@@ -0,0 +1,28 @@
+/*!
+ * Piwik - Web Analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+$(document).ready(function () {
+
+    if (!$('.Menu--dashboard').length) {
+        return;
+    }
+
+    var addedElement = $('#topRightBar').append(
+          '<span class="topBarElem activateZenMode" piwik-zen-mode-switcher>'
+        + '<img src="plugins/CoreHome/images/navigation_expand.png">'
+        + ' </span>'
+    );
+
+    piwikHelper.compileAngularComponents(addedElement);
+
+    addedElement = $('.Menu--dashboard').prepend(
+          '<span piwik-zen-mode-switcher class="deactivateZenMode">'
+        + '<img src="plugins/CoreHome/images/navigation_collapse.png" >'
+        + '</span>');
+
+    piwikHelper.compileAngularComponents(addedElement);
+});
diff --git a/plugins/ZenMode/plugin.json b/plugins/ZenMode/plugin.json
new file mode 100644
index 0000000000..af1e145d38
--- /dev/null
+++ b/plugins/ZenMode/plugin.json
@@ -0,0 +1,6 @@
+{
+ "name": "ZenMode",
+ "version": "0.1",
+ "description": "Switch to the Piwik Zen Mode",
+ "theme": false
+}
\ No newline at end of file
-- 
GitLab