diff --git a/plugins/CoreHome/CoreHome.php b/plugins/CoreHome/CoreHome.php
index 5d9a523a59681442bb9e3c3da12d7aeba02f0e53..5e24324539b07d49adf3f1eda657802353b8937e 100644
--- a/plugins/CoreHome/CoreHome.php
+++ b/plugins/CoreHome/CoreHome.php
@@ -68,6 +68,7 @@ class CoreHome extends \Piwik\Plugin
         $jsFiles[] = "libs/jquery/jquery.mousewheel.js";
         $jsFiles[] = "libs/jquery/mwheelIntent.js";
         $jsFiles[] = "libs/javascript/sprintf.js";
+        $jsFiles[] = "libs/angularjs/angular.js";
         $jsFiles[] = "plugins/Zeitgeist/javascripts/piwikHelper.js";
         $jsFiles[] = "plugins/Zeitgeist/javascripts/ajaxHelper.js";
         $jsFiles[] = "plugins/CoreHome/javascripts/require.js";
@@ -89,6 +90,11 @@ class CoreHome extends \Piwik\Plugin
         $jsFiles[] = "plugins/CoreHome/javascripts/color_manager.js";
         $jsFiles[] = "plugins/CoreHome/javascripts/notification.js";
         $jsFiles[] = "plugins/CoreHome/javascripts/notification_parser.js";
+        $jsFiles[] = "plugins/CoreHome/javascripts/piwikApp.js";
+        $jsFiles[] = "plugins/CoreHome/javascripts/filters/filters.js";
+        $jsFiles[] = "plugins/CoreHome/javascripts/dependencies/PiwikApi.js";
+        $jsFiles[] = "plugins/CoreHome/javascripts/directives/directives.js";
+        $jsFiles[] = "plugins/CoreHome/javascripts/siteselector/siteSelectorController.js";
     }
 
     public function getClientSideTranslationKeys(&$translationKeys)
@@ -98,6 +104,7 @@ class CoreHome extends \Piwik\Plugin
         $translationKeys[] = 'General_Show';
         $translationKeys[] = 'General_Hide';
         $translationKeys[] = 'General_YearShort';
+        $translationKeys[] = 'General_MultiSitesSummary';
         $translationKeys[] = 'CoreHome_YouAreUsingTheLatestVersion';
         $translationKeys[] = 'CoreHome_IncludeRowsWithLowPopulation';
         $translationKeys[] = 'CoreHome_ExcludeRowsWithLowPopulation';
@@ -107,6 +114,7 @@ class CoreHome extends \Piwik\Plugin
         $translationKeys[] = 'CoreHome_PageOf';
         $translationKeys[] = 'CoreHome_FlattenDataTable';
         $translationKeys[] = 'CoreHome_UnFlattenDataTable';
+        $translationKeys[] = 'SitesManager_NotFound';
         $translationKeys[] = 'Annotations_ViewAndAddAnnotations';
         $translationKeys[] = 'General_RowEvolutionRowActionTooltipTitle';
         $translationKeys[] = 'General_RowEvolutionRowActionTooltip';
diff --git a/plugins/CoreHome/javascripts/dependencies/PiwikApi.js b/plugins/CoreHome/javascripts/dependencies/PiwikApi.js
new file mode 100644
index 0000000000000000000000000000000000000000..87328e6239d086a86ef1f5f9f7763258881edef3
--- /dev/null
+++ b/plugins/CoreHome/javascripts/dependencies/PiwikApi.js
@@ -0,0 +1,202 @@
+/*!
+ * Piwik - Web Analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+piwikApp.factory('piwikApi', function ($http, $q, $rootScope) {
+
+    var url = 'index.php';
+    var format = 'json';
+    var getParams  = {};
+    var postParams = {};
+
+    var piwikApi = {};
+
+    /**
+     * Adds params to the request.
+     * If params are given more then once, the latest given value is used for the request
+     *
+     * @param {object}  params
+     * @param {string}  type  type of given parameters (POST or GET)
+     * @return {void}
+     */
+    piwikApi.addParams = function (params, type) {
+        if (typeof params == 'string') {
+            params = broadcast.getValuesFromUrl(params);
+        }
+
+        for (var key in params) {
+            if(type.toLowerCase() == 'get') {
+                getParams[key] = params[key];
+            } else if(type.toLowerCase() == 'post') {
+                postParams[key] = params[key];
+            }
+        }
+    };
+
+    /**
+     * Sets the base URL to use in the AJAX request.
+     *
+     * @param {string} url
+     */
+    piwikApi.setUrl = function (url) {
+        this.addParams(broadcast.getValuesFromUrl(url), 'GET');
+    };
+
+    /**
+     * Gets this helper instance ready to send a bulk request. Each argument to this
+     * function is a single request to use.
+     */
+    piwikApi.setBulkRequests = function () {
+        var urls = [];
+        for (var i = 0; i != arguments.length; ++i) {
+            urls.push($.param(arguments[i]));
+        }
+
+        this.addParams({
+            module: 'API',
+            method: 'API.getBulkRequest',
+            urls: urls,
+            format: 'json'
+        }, 'post');
+    };
+
+    /**
+     * Sets the response format for the request
+     *
+     * @param {string} theFormat  response format (e.g. json, html, ...)
+     * @return {void}
+     */
+    piwikApi.setFormat = function (theFormat) {
+        format = theFormat;
+    };
+
+    /**
+     * Send the request
+     * @param {Boolean} [sync]  indicates if the request should be synchronous (defaults to false)
+     * @return {void}
+     */
+    piwikApi.send = function () {
+
+        var deferred = $q.defer();
+
+        var onError = function (message) {
+            deferred.reject(message);
+        };
+
+        var onSuccess  = function (response) {
+            if (response && response.result == 'error') {
+
+                if (response.message) {
+                    onError(response.message);
+
+                    var UI = require('piwik/UI');
+                    var notification = new UI.Notification();
+                    notification.show(response.message, {
+                        context: 'error',
+                        type: 'toast',
+                        id: 'ajaxHelper'
+                    });
+                    notification.scrollToNotification();
+                } else {
+                    onError(null);
+                }
+
+            } else {
+                deferred.resolve(response);
+            }
+        };
+
+        var ajaxCall = {
+            method: 'POST',
+            url: url,
+            responseType: format,
+            params: _mixinDefaultGetParams(getParams),
+            data: $.param(_mixinDefaultPostParams(postParams)),
+            timeout: deferred.promise,
+            headers: {'Content-Type': 'application/x-www-form-urlencoded'}
+        };
+
+        $http(ajaxCall).success(onSuccess).error(onError);
+
+        return deferred.promise;
+    };
+
+    /**
+     * Mixin the default parameters to send as POST
+     *
+     * @param {object}   params   parameter object
+     * @return {object}
+     * @private
+     */
+     function _mixinDefaultPostParams (params) {
+
+        var defaultParams = {
+            token_auth: piwik.token_auth
+        };
+
+        for (var index in defaultParams) {
+            if (!params[index]) {
+                params[index] = defaultParams[index];
+            }
+        }
+
+        return params;
+    };
+
+    /**
+     * Mixin the default parameters to send as GET
+     *
+     * @param {object}   getParamsToMixin   parameter object
+     * @return {object}
+     * @private
+     */
+    function _mixinDefaultGetParams (getParamsToMixin) {
+
+        var defaultParams = {
+            idSite:  piwik.idSite || broadcast.getValueFromUrl('idSite'),
+            period:  piwik.period || broadcast.getValueFromUrl('period'),
+            segment: broadcast.getValueFromHash('segment', window.location.href.split('#')[1])
+        };
+
+        // never append token_auth to url
+        if (getParamsToMixin.token_auth) {
+            getParamsToMixin.token_auth = null;
+            delete getParamsToMixin.token_auth;
+        }
+
+        for (var key in defaultParams) {
+            if (!getParamsToMixin[key] && !postParams[key] && defaultParams[key]) {
+                getParamsToMixin[key] = defaultParams[key];
+            }
+        }
+
+        // handle default date & period if not already set
+        if (!getParamsToMixin.date && !postParams.date) {
+            getParamsToMixin.date = piwik.currentDateString || broadcast.getValueFromUrl('date');
+            if (getParamsToMixin.period == 'range' && piwik.currentDateString) {
+                getParamsToMixin.date = piwik.startDateString + ',' + getParamsToMixin.date;
+            }
+        }
+
+        return getParamsToMixin;
+    };
+
+    /**
+     * Convenient method for making an API request
+     * @param getParams
+     */
+    piwikApi.fetch = function (getParams) {
+
+        getParams.module = 'API';
+        getParams.format = 'JSON';
+
+        this.addParams(getParams, 'GET');
+
+        return this.send();
+    };
+
+    return piwikApi;
+});
diff --git a/plugins/CoreHome/javascripts/directives/directives.js b/plugins/CoreHome/javascripts/directives/directives.js
new file mode 100644
index 0000000000000000000000000000000000000000..028a54e8f65927069c0d7fe7fe7947018a561a62
--- /dev/null
+++ b/plugins/CoreHome/javascripts/directives/directives.js
@@ -0,0 +1,57 @@
+/*!
+ * Piwik - Web Analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+piwikApp.directive('piwikFocusAnywhereButHere', function($document){
+    return {
+        restrict: 'A',
+        link: function(scope, element, attr, ctrl) {
+
+            function onClickOutsideElement (event) {
+                if (element.has(event.target).length === 0) {
+                    scope.$apply(attr.piwikFocusAnywhereButHere);
+                }
+            }
+
+            function onEscapeHandler (event) {
+                if (event.which === 27) {
+                    scope.$apply(attr.piwikFocusAnywhereButHere);
+                }
+            }
+
+            $document.on('keyup', onEscapeHandler);
+            $document.on('mouseup', onClickOutsideElement);
+            scope.$on('$destroy', function() {
+                $document.off('mouseup', onClickOutsideElement);
+                $document.off('keyup', onEscapeHandler);
+            });
+        }
+    }
+});
+
+piwikApp.directive('piwikAutocompleteMatched', function() {
+    return function(scope, element, attrs) {
+        var searchTerm;
+
+        scope.$watch(attrs.autocompleteMatched, function(value) {
+            searchTerm = value;
+            updateText();
+        });
+
+        function updateText () {
+            if (!searchTerm) {
+                return;
+            }
+            var content = element.text();
+            var startTerm = content.toLowerCase().indexOf(searchTerm);
+            if (-1 !== startTerm) {
+                var word = content.substr(startTerm, searchTerm.length);
+                content = content.replace(word, '<span class="autocompleteMatched">' + word + '</span>');
+                element.html(content);
+            };
+        }
+    };
+});
\ No newline at end of file
diff --git a/plugins/CoreHome/javascripts/filters/filters.js b/plugins/CoreHome/javascripts/filters/filters.js
new file mode 100644
index 0000000000000000000000000000000000000000..8e8002bf785f1c2ab4cbbd6b597b97fb0571f78a
--- /dev/null
+++ b/plugins/CoreHome/javascripts/filters/filters.js
@@ -0,0 +1,21 @@
+/*!
+ * Piwik - Web Analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+piwikApp.filter('translate', function() {
+    return function(key) {
+        return _pk_translate(key);
+    }
+});
+
+piwikApp.filter('default', function() {
+    return function(value, defaultValue) {
+        if (!value) {
+            return defaultValue;
+        }
+        return value;
+    }
+});
diff --git a/plugins/CoreHome/javascripts/piwikApp.js b/plugins/CoreHome/javascripts/piwikApp.js
new file mode 100644
index 0000000000000000000000000000000000000000..36dc2c55c4cf2043b1576c5c2dcb655436a77d10
--- /dev/null
+++ b/plugins/CoreHome/javascripts/piwikApp.js
@@ -0,0 +1,2 @@
+var piwikApp  = angular.module('piwikApp', []);
+var customApp = angular.module('app', []);
diff --git a/plugins/CoreHome/javascripts/siteselector/siteSelector.tpl.html b/plugins/CoreHome/javascripts/siteselector/siteSelector.tpl.html
new file mode 100644
index 0000000000000000000000000000000000000000..2a01bf5f131622f4c0e8f03e02f3aca81ada2b6a
--- /dev/null
+++ b/plugins/CoreHome/javascripts/siteselector/siteSelector.tpl.html
@@ -0,0 +1,49 @@
+<div ng-class="{'sites_autocomplete--dropdown': (hasMultipleWebsites || showAllSitesItem)}"
+     id="{{ siteSelectorId }}">
+    <div piwik-focus-anywhere-but-here="showSitesList=false" class="custom_select">
+
+        <input ng-if="inputName" ng-model="selectedSiteId" type="hidden" name="{{ inputName }}" value=""/>
+
+        <a ng-click="showSitesList=!showSitesList; showSitesList && loadInitialSites()" href="javascript:void(0)"
+           class="custom_select_main_link" ng-class="{'loading': isLoading}"
+           data-siteid="{{ selectedSiteId }}">
+            <span>{{ siteName }}</span>
+        </a>
+
+        <div ng-show="showSitesList" class="custom_select_block">
+
+            <div ng-click="siteName='Ddd'" ng-show="allWebsitesLinkLocation=='top' && showAllSitesItem" class="custom_select_all" style="clear: both;">
+                <a href="#">
+                    {{ allSitesItemText | default:'General_MultiSitesSummary'|translate }}
+                </a>
+            </div>
+
+            <div class="custom_select_container">
+                <ul class="custom_select_ul_list">
+                    <li ng-focus="searchTerm=site.name" ng-click="$parent.showSitesList=false; switchSite(site)" ng-repeat="site in sites" ng-hide="!showSelectedSite && piwik.idSite==site.idsite">
+                        <a href="javascript:void(0)" piwik-autocomplete-matched="searchTerm">{{ site.name }}</a>
+                    </li>
+                </ul>
+                <ul ng-show="!sites.length" class="ui-autocomplete ui-front ui-menu ui-widget ui-widget-content ui-corner-all siteSelect">
+                    <li class="ui-menu-item" style="float:none;position:static">
+                        <a class="ui-corner-all" style="float:none;position:static" tabindex="-1">{{ ('SitesManager_NotFound' | translate) + ' ' + searchTerm }}</a>
+                    </li>
+                </ul>
+            </div>
+
+            <div ng-click="siteName='Ddd'" ng-show="allWebsitesLinkLocation=='bottom' && showAllSitesItem" class="custom_select_all" style="clear: both;">
+                <a href="#">
+                    {{ allSitesItemText | default:'General_MultiSitesSummary'|translate }}
+                </a>
+            </div>
+
+            <div class="custom_select_search" ng-show="show_autocompleter">
+                <input type="text" ng-focus="showSitesList" ng-click="searchTerm=''" ng-model="searchTerm" ng-change="searchSite(searchTerm)" length="15" class="websiteSearch inp"/>
+                <input type="submit" value="Search" class="but"/>
+                <img title="Clear" ng-show="searchTerm" ng-click="searchTerm=''; loadInitialSites()" class="reset" style="position: relative; top: 4px; left: -44px; cursor: pointer;"
+                     src="plugins/CoreHome/images/reset_search.png"/>
+            </div>
+        </div>
+    </div>
+
+</div>
diff --git a/plugins/CoreHome/javascripts/siteselector/siteSelectorController.js b/plugins/CoreHome/javascripts/siteselector/siteSelectorController.js
new file mode 100644
index 0000000000000000000000000000000000000000..b099cdede4e7eb69a8ba53f43864f5b2a3aa305c
--- /dev/null
+++ b/plugins/CoreHome/javascripts/siteselector/siteSelectorController.js
@@ -0,0 +1,91 @@
+/*!
+ * Piwik - Web Analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+piwikApp.controller('SiteSelectorCtrl', ['$scope', 'piwikApi', function($scope, piwikApi){
+    var filterLimit = 10;
+
+    $scope.templateUrl = 'plugins/CoreHome/javascripts/siteselector//siteSelector.tpl.html';
+    $scope.allWebsitesLinkLocation = 'bottom';
+    $scope.sites = [];
+    $scope.showSelectedSite = false;
+    $scope.show_autocompleter = true;
+    $scope.siteSelectorId = '';
+    $scope.switchSiteOnSelect = false;
+    $scope.hasMultipleWebsites = false;
+    $scope.isLoading = false;
+    $scope.showAllSitesItem = true;
+    $scope.selectedSiteId = 0;
+    $scope.searchTerm = '';
+    $scope.max_sitename_width = 130; // can be removed?
+
+    $scope.switchSite = function (site) {
+        if (!$scope.switchSiteOnSelect || piwik.idSite == site.idsite) {
+            $scope.selectedSiteId = site.idsite;
+            $scope.siteName = site.name;
+            return;
+        }
+
+        if (site.idsite == 'all' && !$scope.showAllSitesItem) {
+            broadcast.propagateNewPage('module=MultiSites&action=index');
+        } else {
+            broadcast.propagateNewPage($scope.getUrlForWebsiteId(site.idsite), false);
+        }
+    };
+
+    $scope.getUrlForWebsiteId = function (idSite) {
+        var idSiteParam   = 'idSite=' + idSite;
+        var newParameters = 'segment=&' + idSiteParam;
+        var hash = broadcast.isHashExists() ? broadcast.getHashFromUrl() : "";
+        return piwikHelper.getCurrentQueryStringWithParametersModified(newParameters)
+            + '#' + piwikHelper.getQueryStringWithParametersModified(hash.substring(1), newParameters);
+    };
+
+    $scope.updateWebsitesList = function (websites) {
+        angular.forEach(websites, function (website) {
+            website.name = piwikHelper.htmlDecode(website.name);
+        });
+
+        $scope.sites = websites;
+
+        if (!$scope.siteName) {
+            $scope.siteName = websites[0].name;
+        }
+
+        $scope.hasMultipleWebsites = websites.length > 1;
+    };
+
+    $scope.searchSite = function (term) {
+        if (!term) {
+            $scope.loadInitialSites();
+            return;
+        }
+        $scope.isLoading = true;
+        piwikApi.fetch({
+            method: 'SitesManager.getPatternMatchSites',
+            filter_limit: filterLimit,
+            pattern: term
+        }).then(function (response) {
+            $scope.updateWebsitesList(response);
+        }).finally(function () {
+            $scope.isLoading = false;
+        });
+    };
+
+    $scope.loadInitialSites = function () {
+        $scope.isLoading = true;
+        piwikApi.fetch({
+            method: 'SitesManager.getSitesWithAtLeastViewAccess',
+            filter_limit: filterLimit,
+            showColumns: 'name,idsite'
+        }).then(function (response) {
+            $scope.updateWebsitesList(response);
+        }).finally(function () {
+            $scope.isLoading = false;
+        });
+    }
+
+}]);
\ No newline at end of file
diff --git a/plugins/CoreHome/javascripts/siteselector/tests.js b/plugins/CoreHome/javascripts/siteselector/tests.js
new file mode 100644
index 0000000000000000000000000000000000000000..92b3089007dd8b0064c69665503ccce8920f565e
--- /dev/null
+++ b/plugins/CoreHome/javascripts/siteselector/tests.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
+ */
+
+describe('SiteSelector Tests', function() {
+    beforeEach(module(function() {
+        return function(inject1, inject2) {
+        }
+    }));
+
+    it('should fetch all websites', function() {
+        expect(1).toBe(1);
+    });
+});
\ No newline at end of file
diff --git a/plugins/CoreHome/templates/_siteSelect.twig b/plugins/CoreHome/templates/_siteSelect.twig
index 071673c1e073e69b30ff3e62aebf0a6cda6c7319..84092ac04e87c06008fc555aa2581a222ffbba08 100644
--- a/plugins/CoreHome/templates/_siteSelect.twig
+++ b/plugins/CoreHome/templates/_siteSelect.twig
@@ -1,67 +1 @@
-{# The following parameters can be used to customize this widget when 'include'-ing:
- * 
- * - showAllSitesItem true if the 'All Websites' option should be shown, false if otherwise. Default = true.
- * - allSitesItemText The text to use for the 'All Websites' option. Default = 'All Websites'.
- * - allWebsitesLinkLocation The location of the 'All Websites' option. Can be 'top' or 'bottom'. Default = 'bottom'.
- * - showSelectedSite false if the currently selected site should be excluded from the list of sites. Default = false.
- * - sites The list of sites to use. By default, the first N sites are used. They are retrieved in View.
- * - show_autocompleter Whether to show the autocompleter or not. Default true.
- * - switchSiteOnSelect Whether to change the page w/ a new idSite value when a site is selected, or not.
- *                      Default = true.
- * - inputName If set, a hidden <input> w/ name == $inputName is created which will hold the selected site's ID. For
- *             use with <form> elements.
- * - siteName The currently selected site name. Defaults to the first name in $sites set by View.
- * - idSite The currently selected idSite. Defaults to the first id in $sites set by View.
- #}
-{% set sitesSelector_allWebsitesLink %}
-    <div class="custom_select_all" style="clear: both;">
-        <a href="#" {% if showAllSitesItem is defined and showAllSitesItem == false %}style="display:none;"{% endif %}>
-            {% if allSitesItemText is defined %}
-                {{ allSitesItemText }}
-            {% else %}
-                {{ 'General_MultiSitesSummary'|translate }}
-            {% endif %}
-        </a>
-    </div>
-{% endset %}
-<div class="sites_autocomplete {% if sites|length > 1 %}sites_autocomplete--dropdown{% endif %}"
-        {% if siteSelectorId is defined %}id="{{ siteSelectorId }}"{% endif %}
-        {% if switchSiteOnSelect is not defined or switchSiteOnSelect %}data-switch-site-on-select="1"{% endif %}>
-    <div class="custom_select">
-
-        <a href="#" onclick="return false" class="custom_select_main_link" data-loading="0" data-siteid="{% if idSite is defined %}{{ idSite }}{% else %}{{ sites[0].idsite }}{% endif %}">
-            <span>{% if siteName is defined %}{{ siteName|raw }}{% else %}{{ sites[0].name|raw }}{% endif %}</span>
-        </a>
-
-        <div class="custom_select_block">
-            {% if allWebsitesLinkLocation is defined and allWebsitesLinkLocation == 'top' %}
-                {{ sitesSelector_allWebsitesLink }}
-            {% endif %}
-            <div class="custom_select_container">
-                <ul class="custom_select_ul_list">
-                    {% for info in sites %}
-                        <li {% if (showSelectedSite is not defined or showSelectedSite == false) and idSite == info.idsite %} style="display: none;"{% endif %}>
-                            <a href="#" data-siteid="{{ info.idsite }}">{{ info.name|raw }}</a>
-                        </li>
-                    {% endfor %}
-                </ul>
-            </div>
-            {% if allWebsitesLinkLocation is not defined or allWebsitesLinkLocation == 'bottom' %}
-                {{ sitesSelector_allWebsitesLink }}
-            {% endif %}
-            <div class="custom_select_search" {% if show_autocompleter == false %}style="display:none;"{% endif %}>
-                <input type="text" length="15" class="websiteSearch inp"/>
-                <input type="hidden" class="max_sitename_width" value="130"/>
-                <input type="submit" value="Search" class="but"/>
-                <img title="Clear" class="reset" style="position: relative; top: 4px; left: -44px; cursor: pointer; display: none;"
-                     src="plugins/CoreHome/images/reset_search.png"/>
-            </div>
-        </div>
-    </div>
-    {% if inputName is defined %}
-        <input type="hidden" name="{{ inputName }}" value="{% if idSite is defined %}{{ idSite }}{% else %}{{ sites[0].idsite }}{% endif %}"/>
-    {% endif %}
-</div>
-<script type="text/javascript">
-    $(document).ready(function () { piwik.initSiteSelectors(); });
-</script>
+<div ng-include src="templateUrl" ng-init="siteName='test';inputName='test2'" ng-controller="SiteSelectorCtrl" class="sites_autocomplete"></div>
\ No newline at end of file
diff --git a/plugins/Morpheus/stylesheets/forms.less b/plugins/Morpheus/stylesheets/forms.less
index 95f79d2e39a6aab8f87f673b38b338b9e65d38ff..842df5164d0b5595fca5942b80d7fb59fa25ae20 100644
--- a/plugins/Morpheus/stylesheets/forms.less
+++ b/plugins/Morpheus/stylesheets/forms.less
@@ -79,7 +79,7 @@ button[type="button"],
 
 
 .sites_autocomplete--dropdown {
-    .custom_select_main_link[data-loading="0"]:before {
+    .custom_select_main_link:not(.loading):before {
         color: @brand-red;
         font-size: 0.7em;
         top: 2px;
diff --git a/plugins/Zeitgeist/stylesheets/ui/_siteSelect.less b/plugins/Zeitgeist/stylesheets/ui/_siteSelect.less
index 80dcf97d1c45764d74efbbe26cf8a2e46088802b..cd6dd28ff5d075b0fd2aa248372900fbacc005f2 100644
--- a/plugins/Zeitgeist/stylesheets/ui/_siteSelect.less
+++ b/plugins/Zeitgeist/stylesheets/ui/_siteSelect.less
@@ -64,7 +64,7 @@
   padding: 0 20px 0 4px;
 }
 
-.sites_autocomplete--dropdown .custom_select_main_link[data-loading="0"]:before {
+.sites_autocomplete--dropdown .custom_select_main_link:not(.loading):before {
   content: " \25BC";
   position: absolute;
   right: 0;
@@ -78,7 +78,7 @@
   position: relative;
 }
 
-.sites_autocomplete .custom_select_main_link[data-loading="1"] {
+.sites_autocomplete .custom_select_main_link.loading {
   background: url(plugins/Zeitgeist/images/loading-blue.gif) no-repeat right 3px;
 }
 
@@ -144,9 +144,8 @@
 }
 
 .custom_select_block {
-  height: 0;
   overflow: hidden;
-  max-width:140px;
+  max-width: inherit
 }
 
 .custom_select_block_show {
diff --git a/plugins/Zeitgeist/templates/dashboard.twig b/plugins/Zeitgeist/templates/dashboard.twig
index 282f51f6c8c9d469de1d422d6942b3d9e6d2d8e6..d2778327a45ced9f83953f49358ef430aded6921 100644
--- a/plugins/Zeitgeist/templates/dashboard.twig
+++ b/plugins/Zeitgeist/templates/dashboard.twig
@@ -1,8 +1,8 @@
 <!DOCTYPE html>
 <!--[if lt IE 9 ]>
-<html class="old-ie"> <![endif]-->
+<html class="old-ie" id="ng-app" ng-app="piwikApp"> <![endif]-->
 <!--[if (gte IE 9)|!(IE)]><!-->
-<html><!--<![endif]-->
+<html id="ng-app" ng-app="piwikApp"><!--<![endif]-->
     <head>
         {% block head %}            
             <meta charset="utf-8">
@@ -23,7 +23,7 @@
             <![endif]-->
         {% endblock %}
     </head>
-    <body>
+    <body ng-app="app">
     {% include "_iframeBuster.twig" %}
     {% include "@CoreHome/_javaScriptDisabled.twig" %}