Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Steur <tsteur@users.noreply.github.com>2016-08-29 04:30:52 +0300
committerGitHub <noreply@github.com>2016-08-29 04:30:52 +0300
commit0c9c30b731ccbacf47e154b9f7a590af49e3d799 (patch)
treec5cf2f6437bb2ee7f3675350ee4b0b6acbbae7d3 /plugins/UsersManager
parentbfdf0bed670f247bf9b1d466e3bcf651e98ab634 (diff)
Better UI for Piwik 3, more responsive, faster, lots of other fixes (#10397)
* improved ui and responsiveness * improve rss widget * commit changes for ui again, got lost after the last commit * fix more tests * restoring files * fix fonts * fix more tests * more test fixes * fix some system tests * fix tests * fix system and ui tests * fix updater tests * make a page as loaded once the callback is called * enable verbose * more verbose output * enable phantomjs debug flag * debug should be a phantomjs option * trying to fix installation tests * fixes #10173 to not compile css files as less * trying to minimize js/css requests to hopefully prevent random ui test fails * disable verbose mode * fix updater and installation * lots of bugfixes and ui tweaks * fix reset dashboard * various bugfixes * fix integration tests * fix text color * hoping to fix installation tests this way * cache css/js resources for an hour, should speed up tests and prevent some random issues * we need to avoid installing plugins multiple times at the same time when requesting resources * finally getting the colors right again * fix most tests, more tests for theme * use an h2 element for titles for better accessibility * fix headline color * use actual theme text color (piwik-black) * fix small font size was applied on all p elements * fix tests * now improving all the datatables * trying to ignore images for visitor log * Revert "trying to ignore images for visitor log" This reverts commit ad1ff7267aae14ad905bef130e956c8593c4fb22. * fix tests * fix we had always ignored a max label width * trying to fix file permissions * fix more file permissions * Improved plugins update API (#10028) * refs #7983 let plugins add or remove fields to websites and better settings api * * Hide CorePluginsAdmin API methods * More documentation * Added some more tests * improved updates API for plugins * better error code as duplicate column cannot really happen when not actually renaming a colum Conflicts: core/Updates/3.0.0-b1.php plugins/CoreUpdater/Commands/Update/CliUpdateObserver.php * fix DB field piwik_log_visit.location_provider too small (#10003) * fixes #9564 fix DB field piwik_log_visit.location_provider too small * use new plugins updater API * DB field piwik_log_visit.visit_total_actions too small (#10002) * fixes #9565 DB field piwik_log_visit.visit_total_actions too small * change type of some db columns that are too small * fix tests (#10040) Conflicts: plugins/CoreAdminHome/Menu.php plugins/Goals/Menu.php plugins/MobileMessaging/Menu.php plugins/SitesManager/Menu.php plugins/UsersManager/Menu.php tests/PHPUnit/System/expected/test_apiGetReportMetadata__API.getWidgetMetadata.xml * fix more file permissions * repair more file permissions * repair more file permissions * trying to make ui tests work again, the table was missing * fix some encoding issues * cross browser fixes and usability improvement * move back the config icon, need to find a better solution later * more cross browser fixes * bugfixes * fix ui tests * fix encoding issue * fix various issues with the ui tests when a test gets aborted * also skip this visitor log test when aborted * there were 3 css files that were loaded separately, merge them instead into one css * forgot to add the actual manifest * do not add manifest if custom logo is specified * load font css files first as it was before merging them into big css * fix link icon was not aligned anymore * minor fixes * setting it back to 4px * in popovers the font variable was always ignored and a different font loaded * forgot to update screenshots * fix remaining tests * this should fix an update error * added 3 new widgets system check, system summary and plugin updates * tweak new widgets content * no page reload when changing date or segment * in admin home show only enabled widgets * refs #10295 use getMockBuilder instead of deprecated getMock * fix some ui tests * fix various bugs * fix more tests * fix ui tests * add a space between loading image and loading message * fix docs so they appear on developer.piwik.org * improved documentation * introduce new Widget::renderTemplate method for consistency with controllers * remove no longer needed files * testing system fonts * fix strong was not really bold * more useful system summary * remove ubuntu font * fix most tests and removed most em elements * fix tests * fix headline was very thin * update submodule * update submodules * update submodule * fix failing ui tests * update submodules
Diffstat (limited to 'plugins/UsersManager')
-rw-r--r--plugins/UsersManager/Controller.php56
-rw-r--r--plugins/UsersManager/Menu.php4
-rw-r--r--plugins/UsersManager/UsersManager.php9
-rw-r--r--plugins/UsersManager/angularjs/give-user-view-access/give-user-view-access.controller.js167
-rw-r--r--plugins/UsersManager/angularjs/manage-super-user/manage-super-user.controller.js76
-rw-r--r--plugins/UsersManager/angularjs/manage-user-access/manage-user-access.controller.js96
-rw-r--r--plugins/UsersManager/angularjs/manage-users/manage-users.controller.js193
-rw-r--r--plugins/UsersManager/angularjs/personal-settings/anonymous-settings.controller.js47
-rw-r--r--plugins/UsersManager/angularjs/personal-settings/personal-settings.controller.js64
-rw-r--r--plugins/UsersManager/javascripts/giveViewAccess.js176
-rw-r--r--plugins/UsersManager/javascripts/usersManager.js312
-rw-r--r--plugins/UsersManager/javascripts/usersSettings.js99
-rw-r--r--plugins/UsersManager/lang/en.json2
-rw-r--r--plugins/UsersManager/stylesheets/usersManager.less21
-rw-r--r--plugins/UsersManager/templates/anonymousSettings.twig75
-rw-r--r--plugins/UsersManager/templates/index.twig263
-rw-r--r--plugins/UsersManager/templates/userSettings.twig174
17 files changed, 977 insertions, 857 deletions
diff --git a/plugins/UsersManager/Controller.php b/plugins/UsersManager/Controller.php
index b0bb0a88f0..921d7a035c 100644
--- a/plugins/UsersManager/Controller.php
+++ b/plugins/UsersManager/Controller.php
@@ -255,24 +255,45 @@ class Controller extends ControllerAdmin
if ($defaultReport == 'MultiSites') {
$defaultSiteId = $userPreferences->getDefaultWebsiteId();
+ $reportOptionsValue = $defaultSiteId;
$view->defaultReportIdSite = $defaultSiteId;
$view->defaultReportSiteName = Site::getNameFor($defaultSiteId);
} else {
+ $reportOptionsValue = $defaultReport;
$view->defaultReportIdSite = $defaultReport;
$view->defaultReportSiteName = Site::getNameFor($defaultReport);
}
+ $view->defaultReportOptions = array(
+ array('key' => 'MultiSites', 'value' => Piwik::translate('General_AllWebsitesDashboard')),
+ array('key' => $reportOptionsValue, 'value' => Piwik::translate('General_DashboardForASpecificWebsite')),
+ );
+
$view->defaultDate = $this->getDefaultDateForUser($userLogin);
$view->availableDefaultDates = $this->getDefaultDates();
- $view->languages = APILanguagesManager::getInstance()->getAvailableLanguageNames();
+ $languages = APILanguagesManager::getInstance()->getAvailableLanguageNames();
+ $languageOptions = array();
+ foreach ($languages as $language) {
+ $languageOptions[] = array(
+ 'key' => $language['code'],
+ 'value' => $language['name']
+ );
+ }
+
+ $view->languageOptions = $languageOptions;
$view->currentLanguageCode = LanguagesManager::getLanguageCodeForCurrentUser();
- $view->currentTimeformat = LanguagesManager::uses12HourClockForCurrentUser();
+ $view->currentTimeformat = (int) LanguagesManager::uses12HourClockForCurrentUser();
$view->ignoreCookieSet = IgnoreCookie::isIgnoreCookieFound();
$view->piwikHost = Url::getCurrentHost();
$this->setBasicVariablesView($view);
+ $view->timeFormats = array(
+ '1' => Piwik::translate('General_12HourClock'),
+ '0' => Piwik::translate('General_24HourClock')
+ );
+
return $view->render();
}
@@ -316,23 +337,28 @@ class Controller extends ControllerAdmin
if (!Piwik::hasUserSuperUserAccess()) {
return;
}
+
$userLogin = 'anonymous';
// Which websites are available to the anonymous users?
$anonymousSitesAccess = Request::processRequest('UsersManager.getSitesAccessFromUser', array('userLogin' => $userLogin));
$anonymousSites = array();
+ $idSites = array();
foreach ($anonymousSitesAccess as $info) {
$idSite = $info['site'];
+ $idSites[] = $idSite;
$site = Request::processRequest('SitesManager.getSiteFromId', array('idSite' => $idSite));
// Work around manual website deletion
if (!empty($site)) {
- $anonymousSites[$idSite] = $site;
+ $anonymousSites[] = array('key' => $idSite, 'value' => $site['name']);
}
}
$view->anonymousSites = $anonymousSites;
+ $anonymousDefaultSite = '';
+
// Which report is displayed by default to the anonymous user?
$anonymousDefaultReport = Request::processRequest('UsersManager.getUserPreference', array('userLogin' => $userLogin, 'preferenceName' => APIUsersManager::PREFERENCE_DEFAULT_REPORT));
if ($anonymousDefaultReport === false) {
@@ -342,13 +368,29 @@ class Controller extends ControllerAdmin
// we manually imitate what would happen, in case the anonymous user logs in
// and is redirected to the first website available to him in the list
// @see getDefaultWebsiteId()
- reset($anonymousSites);
- $anonymousDefaultReport = key($anonymousSites);
+ $anonymousDefaultReport = '1';
+ $anonymousDefaultSite = $anonymousSites[0]['key'];
}
}
- $view->anonymousDefaultReport = $anonymousDefaultReport;
+ if (is_numeric($anonymousDefaultReport)) {
+ $anonymousDefaultSite = $anonymousDefaultReport;
+ $anonymousDefaultReport = '1'; // a website is selected, we make sure "Dashboard for a specific site" gets pre-selected
+ }
+
+ if ((empty($anonymousDefaultSite) || !in_array($anonymousDefaultSite, $idSites)) && !empty($idSites)) {
+ $anonymousDefaultSite = $anonymousSites[0]['key'];
+ }
+
+ $view->anonymousDefaultReport = $anonymousDefaultReport;
+ $view->anonymousDefaultSite = $anonymousDefaultSite;
$view->anonymousDefaultDate = $this->getDefaultDateForUser($userLogin);
+
+ $view->defaultReportOptions = array(
+ array('key' => 'Login', 'value' => Piwik::translate('UsersManager_TheLoginScreen')),
+ array('key' => 'MultiSites', 'value' => Piwik::translate('General_AllWebsitesDashboard'), 'disabled' => empty($anonymousSites)),
+ array('key' => '1', 'value' => Piwik::translate('General_DashboardForASpecificWebsite')),
+ );
}
/**
@@ -394,6 +436,8 @@ class Controller extends ControllerAdmin
$timeFormat = Common::getRequestVar('timeformat');
$userLogin = Piwik::getCurrentUserLogin();
+ Piwik::checkUserHasSuperUserAccessOrIsTheUser($userLogin);
+
$this->processPasswordChange($userLogin);
LanguagesManager::setLanguageForSession($language);
diff --git a/plugins/UsersManager/Menu.php b/plugins/UsersManager/Menu.php
index c95506dca3..f3844f1fa0 100644
--- a/plugins/UsersManager/Menu.php
+++ b/plugins/UsersManager/Menu.php
@@ -16,11 +16,11 @@ class Menu extends \Piwik\Plugin\Menu
public function configureAdminMenu(MenuAdmin $menu)
{
if (Piwik::isUserHasSomeAdminAccess()) {
- $menu->addManageItem('UsersManager_MenuUsers', $this->urlForAction('index'), $order = 15);
+ $menu->addSystemItem('UsersManager_MenuUsers', $this->urlForAction('index'), $order = 15);
}
if (Piwik::hasUserSuperUserAccess() && API::getInstance()->getSitesAccessFromUser('anonymous')) {
- $menu->addManageItem('UsersManager_AnonymousUser', $this->urlForAction('anonymousSettings'), $order = 16);
+ $menu->addSystemItem('UsersManager_AnonymousUser', $this->urlForAction('anonymousSettings'), $order = 16);
}
if (!Piwik::isUserIsAnonymous()) {
diff --git a/plugins/UsersManager/UsersManager.php b/plugins/UsersManager/UsersManager.php
index d8a038eb56..7e3bd11a63 100644
--- a/plugins/UsersManager/UsersManager.php
+++ b/plugins/UsersManager/UsersManager.php
@@ -92,9 +92,12 @@ class UsersManager extends \Piwik\Plugin
*/
public function getJsFiles(&$jsFiles)
{
- $jsFiles[] = "plugins/UsersManager/javascripts/usersManager.js";
- $jsFiles[] = "plugins/UsersManager/javascripts/usersSettings.js";
- $jsFiles[] = "plugins/UsersManager/javascripts/giveViewAccess.js";
+ $jsFiles[] = "plugins/UsersManager/angularjs/personal-settings/personal-settings.controller.js";
+ $jsFiles[] = "plugins/UsersManager/angularjs/personal-settings/anonymous-settings.controller.js";
+ $jsFiles[] = "plugins/UsersManager/angularjs/manage-super-user/manage-super-user.controller.js";
+ $jsFiles[] = "plugins/UsersManager/angularjs/manage-user-access/manage-user-access.controller.js";
+ $jsFiles[] = "plugins/UsersManager/angularjs/manage-users/manage-users.controller.js";
+ $jsFiles[] = "plugins/UsersManager/angularjs/give-user-view-access/give-user-view-access.controller.js";
}
/**
diff --git a/plugins/UsersManager/angularjs/give-user-view-access/give-user-view-access.controller.js b/plugins/UsersManager/angularjs/give-user-view-access/give-user-view-access.controller.js
new file mode 100644
index 0000000000..d44f145ad9
--- /dev/null
+++ b/plugins/UsersManager/angularjs/give-user-view-access/give-user-view-access.controller.js
@@ -0,0 +1,167 @@
+/*!
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+(function () {
+ angular.module('piwikApp').controller('GiveUserViewAccessController', GiveUserViewAccessController);
+
+ GiveUserViewAccessController.$inject = ['piwikApi', '$window'];
+
+ function GiveUserViewAccessController(piwikApi, $window) {
+
+ var self = this;
+ this.isLoading = false;
+ this.showForm = false;
+ this.usernameOrEmail = '';
+
+ var requestOptions = {placeat: '#ajaxErrorGiveViewAccess'};
+
+ function hideLoading() {
+ self.isLoading = false;
+ }
+
+ function showLoading() {
+ self.isLoading = true;
+ }
+
+ function showErrorNotification(errorMessage)
+ {
+ var placeAt = requestOptions.placeat;
+ $(placeAt).show();
+
+ var UI = require('piwik/UI');
+ var notification = new UI.Notification();
+ notification.show(errorMessage, {
+ placeat: placeAt,
+ context: 'error',
+ id: 'ajaxHelper',
+ type: null
+ });
+ notification.scrollToNotification();
+ hideLoading();
+ }
+
+ function sendViewAccess(userLogin)
+ {
+ var parameters = {userLogin: userLogin, access: 'view', idSites: getIdSites()};
+
+ piwikApi.post({
+ module: 'API',
+ format: 'json',
+ method: 'UsersManager.setUserAccess'
+ }, parameters, requestOptions).then(function () {
+ $window.location.reload();
+ hideLoading();
+ }, function () {
+ hideLoading();
+ });
+ }
+ function getIdSites() {
+ return $('#usersManagerSiteSelect').attr('siteid');
+ }
+
+ function setViewAccessForUserToAllWebsitesIfUserConfirms(userLogin)
+ {
+ // ask confirmation
+ $('#confirm').find('.login').text(userLogin);
+
+ function onValidate() {
+ sendViewAccess(userLogin);
+ }
+
+ piwikHelper.modalConfirm('#confirm', {yes: onValidate, no: hideLoading})
+ }
+
+ function setViewAccessForUserIfNotAlreadyHasAccess(userLogin, idSites)
+ {
+ piwikApi.fetch({
+ method: 'UsersManager.getUsersAccessFromSite',
+ userLogin: userLogin,
+ idSite: idSites
+ }, requestOptions).then(function (users) {
+ var userLogins = [];
+ if (users) {
+ angular.forEach(users, function (val, key) {
+ userLogins.push((''+ key).toLowerCase());
+ });
+ }
+
+ if (-1 !== userLogins.indexOf(userLogin.toLowerCase())) {
+ showErrorNotification(_pk_translate('UsersManager_ExceptionUserHasViewAccessAlready'));
+ } else {
+ sendViewAccess(userLogin);
+ }
+
+ }, function () {
+ hideLoading();
+ });
+ }
+
+ function ifUserExists(usernameOrEmail)
+ {
+ return piwikApi.fetch({
+ method: 'UsersManager.userExists',
+ userLogin: usernameOrEmail,
+ }, requestOptions).then(function (response) {
+
+ return response;
+
+ }, function () {
+ hideLoading();
+ });
+ }
+
+ function getUsernameFromEmail(usernameOrEmail, callback)
+ {
+ return piwikApi.fetch({
+ method: 'UsersManager.getUserLoginFromUserEmail',
+ userEmail: usernameOrEmail,
+ }, requestOptions).then(function (response) {
+ return response;
+ }, function () {
+ hideLoading();
+ });
+ }
+
+ function giveViewAccessToUser(userLogin)
+ {
+ var idSites = getIdSites();
+
+ if (idSites === 'all') {
+ setViewAccessForUserToAllWebsitesIfUserConfirms(userLogin);
+ } else {
+ setViewAccessForUserIfNotAlreadyHasAccess(userLogin, idSites);
+ }
+ }
+
+ this.giveAccess = function () {
+
+ if (!this.usernameOrEmail) {
+ showErrorNotification(_pk_translate('UsersManager_ExceptionNoValueForUsernameOrEmail'));
+ return;
+ }
+
+ showLoading();
+
+ ifUserExists(this.usernameOrEmail).then(function (isUserName) {
+ if (isUserName && isUserName.value) {
+ giveViewAccessToUser(self.usernameOrEmail);
+ } else {
+ getUsernameFromEmail(self.usernameOrEmail).then(function (login) {
+ if (login && login.value) {
+ giveViewAccessToUser(login.value);
+ } else {
+ hideLoading();
+ }
+ });
+ }
+ });
+ };
+
+ this.showViewAccessForm = function () {
+ this.showForm = true;
+ }
+ }
+})(); \ No newline at end of file
diff --git a/plugins/UsersManager/angularjs/manage-super-user/manage-super-user.controller.js b/plugins/UsersManager/angularjs/manage-super-user/manage-super-user.controller.js
new file mode 100644
index 0000000000..eb8c3ed9d4
--- /dev/null
+++ b/plugins/UsersManager/angularjs/manage-super-user/manage-super-user.controller.js
@@ -0,0 +1,76 @@
+/*!
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+(function () {
+ angular.module('piwikApp').controller('ManageSuperUserController', ManageSuperUserController);
+
+ ManageSuperUserController.$inject = ['piwikApi', '$timeout'];
+
+ function ManageSuperUserController(piwikApi, $timeout) {
+
+ var self = this;
+ this.isLoading = false;
+
+ function updateSuperUserAccess(login, hasSuperUserAccess)
+ {
+ self.isLoading = true;
+
+ $timeout(function () {
+ piwik.helper.lazyScrollTo('.loadingManageSuperUser', 40);
+ });
+
+ piwikApi.post({
+ module: 'API',
+ method: 'UsersManager.setSuperUserAccess'
+ }, {userLogin: login, hasSuperUserAccess: hasSuperUserAccess}).then(function () {
+
+ self.isLoading = false;
+
+ var UI = require('piwik/UI');
+ var notification = new UI.Notification();
+ notification.show(_pk_translate('General_Done'), {
+ placeat: '#superUserAccessUpdated',
+ context: 'success',
+ noclear: true,
+ type: 'toast',
+ style: {display: 'inline-block', marginTop: '10px', marginBottom: '30px'},
+ id: 'usersManagerSuperUserAccessUpdated'
+ });
+ notification.scrollToNotification();
+ piwikHelper.redirect();
+
+ }, function () {
+ self.isLoading = false;
+ });
+ }
+
+ this.removeSuperUserAccess = function (login) {
+ var message = 'UsersManager_ConfirmProhibitOtherUsersSuperUserAccess';
+ if (login == piwik.userLogin) {
+ message = 'UsersManager_ConfirmProhibitMySuperUserAccess';
+ }
+
+ message = _pk_translate(message, [login]);
+
+ $('#superUserAccessConfirm h2').text(message);
+
+ piwikHelper.modalConfirm('#superUserAccessConfirm', {yes: function () {
+ updateSuperUserAccess(login, 0);
+ }});
+ };
+
+ this.giveSuperUserAccess = function (login) {
+
+ var message = _pk_translate('UsersManager_ConfirmGrantSuperUserAccess', [login]);
+
+ $('#superUserAccessConfirm h2').text(message);
+
+ piwikHelper.modalConfirm('#superUserAccessConfirm', {yes: function () {
+ updateSuperUserAccess(login, 1);
+ }});
+ };
+ }
+})(); \ No newline at end of file
diff --git a/plugins/UsersManager/angularjs/manage-user-access/manage-user-access.controller.js b/plugins/UsersManager/angularjs/manage-user-access/manage-user-access.controller.js
new file mode 100644
index 0000000000..4ed851d68d
--- /dev/null
+++ b/plugins/UsersManager/angularjs/manage-user-access/manage-user-access.controller.js
@@ -0,0 +1,96 @@
+/*!
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+(function () {
+ angular.module('piwikApp').controller('ManageUserAccessController', ManageUserAccessController);
+
+ ManageUserAccessController.$inject = ['piwik', 'piwikApi', '$timeout'];
+
+ function ManageUserAccessController(piwik, piwikApi, $timeout) {
+
+ var self = this;
+ this.isLoading = false;
+
+ function launchAjaxRequest(login, access, successCallback) {
+
+ self.isLoading = true;
+
+ $timeout(function () {
+ piwik.helper.lazyScrollTo('.loadingManageUserAccess', 50);
+ });
+
+ var parameters = {userLogin: login, access: access, idSites: self.site.id};
+
+ return piwikApi.post({
+ module: 'API',
+ format: 'json',
+ method: 'UsersManager.setUserAccess'
+ }, parameters).then(function (response) {
+ self.isLoading = false;
+ return response;
+ }, function () {
+ self.isLoading = false;
+ });
+ }
+
+ this.siteChanged = function () {
+ if (this.site && this.site.id != piwik.idSite) {
+ piwik.broadcast.propagateNewPage('segment=&idSite=' + this.site.id, false);
+ }
+ };
+
+ this.setAccess = function (login, access) {
+
+ // callback called when the ajax request Update the user permissions is successful
+ function successCallback(response) {
+ var mainDiv = $('[data-login="' + login + '"]');
+ mainDiv.find('.accessGranted')
+ .attr("src", "plugins/UsersManager/images/no-access.png")
+ .attr("class", "updateAccess")
+ .click(function () {
+ var access = $(this).parent().attr('id')
+ self.setAccess(login, access);
+ })
+ ;
+ mainDiv.find('#' + access + ' img')
+ .attr('src', "plugins/UsersManager/images/ok.png")
+ .attr('class', "accessGranted")
+ ;
+
+ var UI = require('piwik/UI');
+ var notification = new UI.Notification();
+ notification.show(_pk_translate('General_Done'), {
+ placeat: '#accessUpdated',
+ context: 'success',
+ noclear: true,
+ type: 'toast',
+ style: {display: 'inline-block', marginTop: '10px'},
+ id: 'usersManagerAccessUpdated'
+ });
+
+ // reload if user anonymous was updated, since we display a Notice message when anon has view access
+ if (login == 'anonymous') {
+ window.location.reload();
+ }
+ }
+
+ if (this.site.id == 'all') {
+
+ //ask confirmation
+ $('#confirm').find('.login').text(login);
+
+ function onValidate() {
+ launchAjaxRequest(login, access).then(successCallback);
+ }
+
+ piwikHelper.modalConfirm('#confirm', {yes: onValidate})
+ }
+ else {
+ launchAjaxRequest(login, access).then(successCallback);
+ }
+ }
+ }
+})(); \ No newline at end of file
diff --git a/plugins/UsersManager/angularjs/manage-users/manage-users.controller.js b/plugins/UsersManager/angularjs/manage-users/manage-users.controller.js
new file mode 100644
index 0000000000..1df74622de
--- /dev/null
+++ b/plugins/UsersManager/angularjs/manage-users/manage-users.controller.js
@@ -0,0 +1,193 @@
+/*!
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+(function () {
+ angular.module('piwikApp').controller('ManageUsersController', ManageUsersController);
+
+ ManageUsersController.$inject = ['piwik', 'piwikApi', '$timeout'];
+
+ function ManageUsersController(piwik, piwikApi, $timeout) {
+ // remember to keep controller very simple. Create a service/factory (model) if needed
+
+ var self = this;
+ var alreadyEdited = {};
+
+ this.isLoading = false;
+ this.showCreateUser = true;
+
+ function setIsLoading()
+ {
+ self.isLoading = true;
+ $timeout(function () {
+ piwik.helper.lazyScrollTo('.loadingManageUsers', 50);
+ });
+ }
+
+ function sendUpdateUserAJAX(row) {
+ var parameters = {};
+ parameters.userLogin = $(row).children('#userLogin').html();
+ var password = $(row).find('input#password').val();
+ if (password != '-') parameters.password = password;
+ parameters.email = $(row).find('input#email').val();
+ parameters.alias = $(row).find('input#alias').val();
+
+ setIsLoading();
+
+ piwikApi.post({
+ module: 'API',
+ method: 'UsersManager.updateUser'
+ }, parameters).then(function () {
+ piwik.helper.redirect();
+ self.isLoading = false;
+ }, function () {
+ self.isLoading = false;
+ });
+ }
+
+ function sendDeleteUserAJAX(login) {
+
+ setIsLoading();
+
+ piwikApi.post({
+ module: 'API',
+ method: 'UsersManager.deleteUser'
+ }, {userLogin: login}).then(function () {
+ piwik.helper.redirect();
+ self.isLoading = false;
+ }, function () {
+ self.isLoading = false;
+ });
+ }
+
+ function sendAddUserAJAX(row) {
+ var parameters = {};
+ parameters.userLogin = $(row).find('input#useradd_login').val();
+ parameters.password = $(row).find('input#useradd_password').val();
+ parameters.email = $(row).find('input#useradd_email').val();
+ parameters.alias = $(row).find('input#useradd_alias').val();
+
+ setIsLoading();
+
+ piwikApi.post({
+ module: 'API',
+ method: 'UsersManager.addUser'
+ }, parameters).then(function () {
+ piwik.helper.redirect();
+ self.isLoading = false;
+ }, function () {
+ self.isLoading = false;
+ });
+ }
+
+ function submitOnEnter(e) {
+ var key = e.keyCode || e.which;
+ if (key == 13) {
+ $(this).find('.adduser').click();
+ $(this).find('.updateuser').click();
+ }
+ }
+
+ this.editUser = function (idRow) {
+ if (alreadyEdited[idRow] == 1) {
+ return;
+ }
+
+ alreadyEdited[idRow] = 1;
+
+ var $row = $('tr#' + idRow);
+
+ $row.find('.editable').keypress(submitOnEnter);
+ $row.find('.editable').each(
+ // make the fields editable
+ // change the EDIT button to VALID button
+ function (i, n) {
+ var contentBefore = $(n).text();
+ var idName = $(n).attr('id');
+ if (idName != 'userLogin') {
+ var contentAfter = '<input id="' + idName + '" value="' + piwikHelper.htmlEntities(contentBefore) + '" size="25" />';
+ $(n).html(contentAfter);
+ }
+ }
+ );
+
+ var $delete = $row.find('.edituser');
+
+ $delete
+ .toggle()
+ .parent()
+ .prepend($('<a class="canceluser">' + _pk_translate('General_OrCancel', ['', '']) + '</a>')
+ .click(function () {
+ piwikHelper.redirect();
+ })
+ ).prepend($('<input type="submit" class="btn updateuser" value="' + _pk_translate('General_Save') + '" />')
+ .click(function () {
+ var onValidate = function () {
+ sendUpdateUserAJAX($('tr#' + idRow));
+ };
+ if ($('tr#' + idRow).find('input#password').val() != '-') {
+ piwikHelper.modalConfirm('#confirmPasswordChange', {yes: onValidate});
+ } else {
+ onValidate();
+ }
+ })
+ );
+ }
+
+ this.createUser = function () {
+ this.showCreateUser = false;
+
+ var numberOfRows = $('table#users')[0].rows.length;
+ var newRowId = numberOfRows + 1;
+ newRowId = 'row' + newRowId;
+
+ $($.parseHTML(' <tr id="' + newRowId + '" class="addNewUserRow">\
+ <td><input id="useradd_login" placeholder="username" size="10" /></td>\
+ <td><input id="useradd_password" placeholder="password" size="10" /></td>\
+ <td><input id="useradd_email" placeholder="email@domain.com" size="15" /></td>\
+ <td><input id="useradd_alias" placeholder="alias" size="15" /></td>\
+ <td>-</td>\
+ <td>-</td>\
+ <td><input type="submit" class="btn adduser" value="' + _pk_translate('General_Save') + '" /></td>\
+ <td><span class="cancel">' + sprintf(_pk_translate('General_OrCancel'), "", "") + '</span></td>\
+ </tr>'))
+ .appendTo('#users')
+ ;
+ $('#' + newRowId).keypress(submitOnEnter);
+ $('.adduser').click(function () { sendAddUserAJAX($('tr#' + newRowId)); });
+ $('.cancel').click(function () {
+ piwikHelper.hideAjaxError();
+ $(this).parents('tr').remove();
+ $('.add-user').toggle();
+ });
+ };
+
+ this.deleteUser = function (loginToDelete) {
+
+ var idRow = $(this).attr('id');
+
+ var message = _pk_translate('UsersManager_DeleteConfirm');
+ $('#confirmUserRemove').find('h2').text(sprintf(message, '"' + loginToDelete + '"'));
+
+ piwikHelper.modalConfirm('#confirmUserRemove', {yes: function () {
+ sendDeleteUserAJAX(loginToDelete);
+ }});
+ };
+
+ $(document).ready(function () {
+ var alreadyEdited = [];
+ // when click on edituser, the cells become editable
+
+ // Show the token_auth
+ $('.token_auth').click(function () {
+ var token = $(this).data('token');
+ if ($(this).text() != token) {
+ $(this).text(token);
+ }
+ });
+ });
+
+ }
+})(); \ No newline at end of file
diff --git a/plugins/UsersManager/angularjs/personal-settings/anonymous-settings.controller.js b/plugins/UsersManager/angularjs/personal-settings/anonymous-settings.controller.js
new file mode 100644
index 0000000000..9c4e30e1e2
--- /dev/null
+++ b/plugins/UsersManager/angularjs/personal-settings/anonymous-settings.controller.js
@@ -0,0 +1,47 @@
+/*!
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+(function () {
+ angular.module('piwikApp').controller('AnonymousSettingsController', AnonymousSettingsController);
+
+ AnonymousSettingsController.$inject = ['piwikApi'];
+
+ function AnonymousSettingsController(piwikApi) {
+ // remember to keep controller very simple. Create a service/factory (model) if needed
+
+ var self = this;
+
+ function updateSettings(postParams)
+ {
+ self.loading = true;
+
+ piwikApi.withTokenInUrl();
+ piwikApi.post({
+ module: 'UsersManager', action: 'recordAnonymousUserSettings', format: 'json'
+ }, postParams).then(function (success) {
+ var UI = require('piwik/UI');
+ var notification = new UI.Notification();
+ notification.show(_pk_translate('CoreAdminHome_SettingsSaveSuccess'), {
+ id: 'anonymousUserSettings', context: 'success'});
+ notification.scrollToNotification();
+
+ self.loading = false;
+ }, function (errorMessage) {
+ self.loading = false;
+ });
+ }
+
+ this.save = function () {
+
+ var postParams = {
+ anonymousDefaultReport: this.defaultReport == '1' ? this.defaultReportWebsite : this.defaultReport,
+ anonymousDefaultDate: this.defaultDate
+ };
+
+ updateSettings(postParams);
+ };
+ }
+})(); \ No newline at end of file
diff --git a/plugins/UsersManager/angularjs/personal-settings/personal-settings.controller.js b/plugins/UsersManager/angularjs/personal-settings/personal-settings.controller.js
new file mode 100644
index 0000000000..a14c47390a
--- /dev/null
+++ b/plugins/UsersManager/angularjs/personal-settings/personal-settings.controller.js
@@ -0,0 +1,64 @@
+/*!
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+(function () {
+ angular.module('piwikApp').controller('PersonalSettingsController', PersonalSettingsController);
+
+ PersonalSettingsController.$inject = ['piwikApi'];
+
+ function PersonalSettingsController(piwikApi) {
+ // remember to keep controller very simple. Create a service/factory (model) if needed
+
+ var self = this;
+
+ function updateSettings(postParams)
+ {
+ self.loading = true;
+
+ piwikApi.withTokenInUrl();
+ piwikApi.post({
+ module: 'UsersManager', action: 'recordUserSettings', format: 'json'
+ }, postParams).then(function (success) {
+ var UI = require('piwik/UI');
+ var notification = new UI.Notification();
+ notification.show(_pk_translate('CoreAdminHome_SettingsSaveSuccess'), {
+ id: 'PersonalSettingsSuccess', context: 'success'});
+ notification.scrollToNotification();
+
+ self.loading = false;
+ }, function (errorMessage) {
+ self.loading = false;
+ });
+ }
+
+ this.save = function () {
+
+ var postParams = {
+ alias: this.alias,
+ email: this.email,
+ defaultReport: this.defaultReport == 'MultiSites' ? this.defaultReport : this.site.id,
+ defaultDate: this.defaultDate,
+ language: this.language,
+ timeformat: this.timeformat,
+ };
+
+ if (this.passwordBis) {
+ postParams.passwordBis = this.passwordBis;
+ }
+
+ if (this.password) {
+ postParams.password = this.password;
+
+ piwikHelper.modalConfirm('#confirmPasswordChange', {yes: function () {
+ updateSettings(postParams);
+ }});
+ } else {
+ updateSettings(postParams);
+ }
+
+ };
+ }
+})(); \ No newline at end of file
diff --git a/plugins/UsersManager/javascripts/giveViewAccess.js b/plugins/UsersManager/javascripts/giveViewAccess.js
deleted file mode 100644
index 3db1bc3889..0000000000
--- a/plugins/UsersManager/javascripts/giveViewAccess.js
+++ /dev/null
@@ -1,176 +0,0 @@
-/*!
- * Piwik - free/libre analytics platform
- *
- * @link http://piwik.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- */
-
-$(document).ready(function () {
-
- function hideLoading()
- {
- $('#giveUserAccessToViewReports').prop('disabled', false);
- $('#ajaxLoadingGiveViewAccess').hide();
- }
-
- function showLoading()
- {
- $('#giveUserAccessToViewReports').prop('disabled', true);
- $('#ajaxLoadingGiveViewAccess').show();
- }
-
- function showErrorNotification(errorMessage)
- {
- var placeAt = '#ajaxErrorGiveViewAccess';
- $(placeAt).show();
-
- var UI = require('piwik/UI');
- var notification = new UI.Notification();
- notification.show(errorMessage, {
- placeat: placeAt,
- context: 'error',
- id: 'ajaxHelper',
- type: null
- });
- notification.scrollToNotification();
- hideLoading();
- }
-
- function createNewAjaxHelper()
- {
- var ajaxHandler = new ajaxHelper();
- ajaxHandler.setCompleteCallback(function (xhr, status) {
- if (xhr &&
- xhr.responseJSON &&
- xhr.responseJSON.message &&
- xhr.responseJSON.result &&
- xhr.responseJSON.result == 'error') {
- hideLoading();
- }
- if (status && String(status).toLowerCase() !== 'sucess') {
- hideLoading();
- }
- });
- ajaxHandler.addParams({
- module: 'API',
- format: 'json'
- }, 'GET');
- ajaxHandler.setErrorElement('#ajaxErrorGiveViewAccess');
-
- return ajaxHandler;
- }
-
- function sendViewAccess(userLogin)
- {
- sendUpdateUserAccess(userLogin, 'view', function () { window.location.reload(); });
- setTimeout(hideLoading, 250);
- // we hide loading after a bit since we cannot influence the ajax request in case of any error
- }
-
- function setViewAccessForUserToAllWebsitesIfUserConfirms(userLogin)
- {
- // ask confirmation
- $('#confirm').find('#login').text(userLogin);
-
- function onValidate() {
- sendViewAccess(userLogin);
- }
-
- piwikHelper.modalConfirm('#confirm', {yes: onValidate, no: hideLoading})
- }
-
- function setViewAccessForUserIfNotAlreadyHasAccess(userLogin, idSites)
- {
- var ajaxHandler = createNewAjaxHelper();
- ajaxHandler.addParams({
- method: 'UsersManager.getUsersAccessFromSite',
- userLogin: userLogin,
- idSite: idSites
- }, 'GET');
- ajaxHandler.setCallback(function (users) {
- var userLogins = [];
- if (users && users[0]) {
- userLogins = $.map(users[0], function (val, key) {
- return (''+ key).toLowerCase();
- });
- }
-
- if (-1 !== userLogins.indexOf(userLogin.toLowerCase())) {
- showErrorNotification(_pk_translate('UsersManager_ExceptionUserHasViewAccessAlready'));
- } else {
- sendViewAccess(userLogin);
- }
-
- });
- ajaxHandler.send();
- }
-
- function ifUserExists(usernameOrEmail, callback)
- {
- var ajaxHandler = createNewAjaxHelper();
- ajaxHandler.addParams({
- method: 'UsersManager.userExists',
- userLogin: usernameOrEmail,
- }, 'GET');
- ajaxHandler.setCallback(callback);
- ajaxHandler.send();
- }
-
- function getUsernameFromEmail(usernameOrEmail, callback)
- {
- var ajaxHandler = createNewAjaxHelper();
- ajaxHandler.addParams({
- method: 'UsersManager.getUserLoginFromUserEmail',
- userEmail: usernameOrEmail,
- }, 'GET');
- ajaxHandler.setCallback(callback);
- ajaxHandler.send();
- }
-
- function giveViewAccessToUser(userLogin)
- {
- var idSites = getIdSites();
-
- if (idSites === 'all') {
- setViewAccessForUserToAllWebsitesIfUserConfirms(userLogin);
- } else {
- setViewAccessForUserIfNotAlreadyHasAccess(userLogin, idSites);
- }
- }
-
- $('#showGiveViewAccessForm').click(function () {
- $('#giveViewAccessForm').toggle()
- });
-
- $('#giveViewAccessForm #user_invite').keypress(function (e) {
- var key = e.keyCode || e.which;
- if (key == 13) {
- $('#giveViewAccessForm #giveUserAccessToViewReports').click();
- }
- });
-
- $('#giveViewAccessForm #giveUserAccessToViewReports').click(function () {
- showLoading();
-
- var usernameOrEmail = $('#user_invite').val();
-
- if (!usernameOrEmail) {
- showErrorNotification(_pk_translate('UsersManager_ExceptionNoValueForUsernameOrEmail'));
- return;
- }
-
- ifUserExists(usernameOrEmail, function (isUserName) {
- if (isUserName && isUserName.value) {
- giveViewAccessToUser(usernameOrEmail);
- } else {
- getUsernameFromEmail(usernameOrEmail, function (login) {
- if (login && login.value) {
- giveViewAccessToUser(login.value);
- } else {
- hideLoading();
- }
- });
- }
- });
- });
-});
diff --git a/plugins/UsersManager/javascripts/usersManager.js b/plugins/UsersManager/javascripts/usersManager.js
deleted file mode 100644
index 5624cb272a..0000000000
--- a/plugins/UsersManager/javascripts/usersManager.js
+++ /dev/null
@@ -1,312 +0,0 @@
-/*!
- * Piwik - free/libre analytics platform
- *
- * @link http://piwik.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- */
-
-function sendUpdateUserAJAX(row) {
- var parameters = {};
- parameters.userLogin = $(row).children('#userLogin').html();
- var password = $(row).find('input#password').val();
- if (password != '-') parameters.password = password;
- parameters.email = $(row).find('input#email').val();
- parameters.alias = $(row).find('input#alias').val();
-
- var ajaxHandler = new ajaxHelper();
- ajaxHandler.addParams({
- module: 'API',
- format: 'json',
- method: 'UsersManager.updateUser'
- }, 'GET');
- ajaxHandler.addParams(parameters, 'POST');
- ajaxHandler.redirectOnSuccess();
- ajaxHandler.setLoadingElement();
- ajaxHandler.send(true);
-}
-
-function sendDeleteUserAJAX(login) {
- var ajaxHandler = new ajaxHelper();
- ajaxHandler.addParams({
- module: 'API',
- format: 'json',
- method: 'UsersManager.deleteUser'
- }, 'GET');
- ajaxHandler.addParams({userLogin: login}, 'POST');
- ajaxHandler.redirectOnSuccess();
- ajaxHandler.setLoadingElement('#ajaxLoadingUsersManagement');
- ajaxHandler.setErrorElement('#ajaxErrorUsersManagement');
- ajaxHandler.send(true);
-}
-
-function sendAddUserAJAX(row) {
- var parameters = {};
- parameters.userLogin = $(row).find('input#useradd_login').val();
- parameters.password = $(row).find('input#useradd_password').val();
- parameters.email = $(row).find('input#useradd_email').val();
- parameters.alias = $(row).find('input#useradd_alias').val();
-
- var ajaxHandler = new ajaxHelper();
- ajaxHandler.addParams({
- module: 'API',
- format: 'json',
- method: 'UsersManager.addUser'
- }, 'GET');
- ajaxHandler.addParams(parameters, 'POST');
- ajaxHandler.redirectOnSuccess();
- ajaxHandler.setLoadingElement('#ajaxLoadingUsersManagement');
- ajaxHandler.setErrorElement('#ajaxErrorUsersManagement');
- ajaxHandler.send(true);
-}
-
-function getIdSites() {
- return $('#usersManagerSiteSelect').attr('siteid');
-}
-
-function sendUpdateUserAccess(login, access, successCallback) {
- var parameters = {};
- parameters.userLogin = login;
- parameters.access = access;
- parameters.idSites = getIdSites();
-
- var ajaxHandler = new ajaxHelper();
- ajaxHandler.addParams({
- module: 'API',
- format: 'json',
- method: 'UsersManager.setUserAccess'
- }, 'GET');
- ajaxHandler.addParams(parameters, 'POST');
- ajaxHandler.setCallback(successCallback);
- ajaxHandler.setLoadingElement('#ajaxLoadingUsersManagement');
- ajaxHandler.setErrorElement('#ajaxErrorUsersManagement');
- ajaxHandler.send(true);
-}
-
-function submitOnEnter(e) {
- var key = e.keyCode || e.which;
- if (key == 13) {
- $(this).find('.adduser').click();
- $(this).find('.updateuser').click();
- }
-}
-
-function launchAjaxRequest(self, successCallback) {
- sendUpdateUserAccess(
- $(self).parent().parent().find('#login').html(), //if changed change also the modal
- $(self).parent().attr('id'),
- successCallback
- );
-}
-
-function updateSuperUserAccess(login, hasSuperUserAccess)
-{
- var parameters = {};
- parameters.userLogin = login;
- parameters.hasSuperUserAccess = hasSuperUserAccess ? 1: 0;
-
- var ajaxHandler = new ajaxHelper();
- ajaxHandler.addParams({
- module: 'API',
- format: 'json',
- method: 'UsersManager.setSuperUserAccess'
- }, 'GET');
- ajaxHandler.addParams(parameters, 'POST');
- ajaxHandler.setCallback(function () {
-
- var UI = require('piwik/UI');
- var notification = new UI.Notification();
- notification.show(_pk_translate('General_Done'), {
- placeat: '#superUserAccessUpdated',
- context: 'success',
- noclear: true,
- type: 'toast',
- style: {display: 'inline-block', marginTop: '10px', marginBottom: '30px'},
- id: 'usersManagerSuperUserAccessUpdated'
- });
- notification.scrollToNotification();
- piwikHelper.redirect();
- });
- ajaxHandler.setLoadingElement('#ajaxErrorSuperUsersManagement');
- ajaxHandler.setErrorElement('#ajaxErrorSuperUsersManagement');
- ajaxHandler.send(true);
-}
-
-function bindUpdateSuperUserAccess() {
- var login = $(this).parents('td').data('login');
- var hasAccess = parseInt($(this).data('hasaccess'), 10);
-
- var message = 'UsersManager_ConfirmGrantSuperUserAccess';
- if (hasAccess && login == piwik.userLogin) {
- message = 'UsersManager_ConfirmProhibitMySuperUserAccess';
- } else if (hasAccess) {
- message = 'UsersManager_ConfirmProhibitOtherUsersSuperUserAccess';
- }
-
- message = _pk_translate(message, [login]);
-
- $('#superUserAccessConfirm h2').text(message);
-
- piwikHelper.modalConfirm('#superUserAccessConfirm', {yes: function () {
- updateSuperUserAccess(login, !hasAccess);
- }});
-}
-
-function bindUpdateAccess() {
- var self = this;
- // callback called when the ajax request Update the user permissions is successful
- function successCallback(response) {
- var mainDiv = $(self).parent().parent();
- var login = $('#login', mainDiv).text();
- mainDiv.find('.accessGranted')
- .attr("src", "plugins/UsersManager/images/no-access.png")
- .attr("class", "updateAccess")
- .click(bindUpdateAccess)
- ;
- $(self)
- .attr('src', "plugins/UsersManager/images/ok.png")
- .attr('class', "accessGranted")
- ;
-
- var UI = require('piwik/UI');
- var notification = new UI.Notification();
- notification.show(_pk_translate('General_Done'), {
- placeat: '#accessUpdated',
- context: 'success',
- noclear: true,
- type: 'toast',
- style: {display: 'inline-block', marginTop: '10px'},
- id: 'usersManagerAccessUpdated'
- });
-
- // reload if user anonymous was updated, since we display a Notice message when anon has view access
- if (login == 'anonymous') {
- window.location.reload();
- }
- }
-
- var idSite = getIdSites();
- if (idSite == 'all') {
- var target = this;
-
- //ask confirmation
- var userLogin = $(this).parent().parent().find('#login').text();
- $('#confirm').find('#login').text(userLogin); // if changed here change also the launchAjaxRequest
-
- function onValidate() {
- launchAjaxRequest(target, successCallback);
- }
-
- piwikHelper.modalConfirm('#confirm', {yes: onValidate})
- }
- else {
- launchAjaxRequest(this, successCallback);
- }
-}
-
-$(document).ready(function () {
- var alreadyEdited = [];
- // when click on edituser, the cells become editable
- $('.edituser')
- .click(function () {
- piwikHelper.hideAjaxError();
- var idRow = $(this).attr('id');
- if (alreadyEdited[idRow] == 1) return;
- alreadyEdited[idRow] = 1;
- $('tr#' + idRow + ' .editable').each(
- // make the fields editable
- // change the EDIT button to VALID button
- function (i, n) {
- var contentBefore = $(n).text();
- var idName = $(n).attr('id');
- if (idName != 'userLogin') {
- var contentAfter = '<input id="' + idName + '" value="' + piwikHelper.htmlEntities(contentBefore) + '" size="25" />';
- $(n).html(contentAfter);
- }
- }
- );
-
- $(this)
- .toggle()
- .parent()
- .prepend($('<a class="canceluser">' + _pk_translate('General_OrCancel', ['', '']) + '</a>')
- .click(function () {
- piwikHelper.redirect();
- })
- ).prepend($('<input type="submit" class="submit updateuser" value="' + _pk_translate('General_Save') + '" />')
- .click(function () {
- var onValidate = function () {
- sendUpdateUserAJAX($('tr#' + idRow));
- };
- if ($('tr#' + idRow).find('input#password').val() != '-') {
- piwikHelper.modalConfirm('#confirmPasswordChange', {yes: onValidate});
- } else {
- onValidate();
- }
- })
- );
- });
-
- $('.editable').keypress(submitOnEnter);
-
- $('td.editable')
- .click(function () { $(this).parent().find('.edituser').click(); });
-
- // when click on deleteuser, the we ask for confirmation and then delete the user
- $('.deleteuser')
- .click(function () {
- piwikHelper.hideAjaxError();
- var idRow = $(this).attr('id');
- var loginToDelete = $(this).parent().parent().find('#userLogin').html();
- $('#confirmUserRemove').find('h2').text(sprintf(_pk_translate('UsersManager_DeleteConfirm'), '"' + loginToDelete + '"'));
- piwikHelper.modalConfirm('#confirmUserRemove', {yes: function () { sendDeleteUserAJAX(loginToDelete); }});
- }
- );
-
- $('.admin .user .add-user').click(function () {
- piwikHelper.hideAjaxError();
- $(this).toggle();
-
- var numberOfRows = $('table#users')[0].rows.length;
- var newRowId = numberOfRows + 1;
- newRowId = 'row' + newRowId;
-
- $($.parseHTML(' <tr id="' + newRowId + '">\
- <td><input id="useradd_login" placeholder="username" size="10" /></td>\
- <td><input id="useradd_password" placeholder="password" size="10" /></td>\
- <td><input id="useradd_email" placeholder="email@domain.com" size="15" /></td>\
- <td><input id="useradd_alias" placeholder="alias" size="15" /></td>\
- <td>-</td>\
- <td>-</td>\
- <td><input type="submit" class="submit adduser" value="' + _pk_translate('General_Save') + '" /></td>\
- <td><span class="cancel">' + sprintf(_pk_translate('General_OrCancel'), "", "") + '</span></td>\
- </tr>'))
- .appendTo('#users')
- ;
- $('#' + newRowId).keypress(submitOnEnter);
- $('.adduser').click(function () { sendAddUserAJAX($('tr#' + newRowId)); });
- $('.cancel').click(function () {
- piwikHelper.hideAjaxError();
- $(this).parents('tr').remove();
- $('.add-user').toggle();
- });
- });
-
- $('#access .updateAccess').click(bindUpdateAccess);
-
- $('#superUserAccess .accessGranted, #superUserAccess .updateAccess').click(bindUpdateSuperUserAccess);
-
- // when a site is selected, reload the page w/o showing the ajax loading element
- $('#usersManagerSiteSelect').bind('change', function (e, site) {
- if (site.id != piwik.idSite) {
- piwik.broadcast.propagateNewPage('segment=&idSite=' + site.id, false);
- }
- });
-
- // Show the token_auth
- $('.token_auth').click(function () {
- var token = $(this).data('token');
- if ($(this).text() != token) {
- $(this).text(token);
- }
- });
-});
diff --git a/plugins/UsersManager/javascripts/usersSettings.js b/plugins/UsersManager/javascripts/usersSettings.js
deleted file mode 100644
index 1708e64bf7..0000000000
--- a/plugins/UsersManager/javascripts/usersSettings.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/*!
- * Piwik - free/libre analytics platform
- *
- * @link http://piwik.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- */
-
-function sendUserSettingsAJAX() {
- var params;
- var defaultDate = $('input[name=defaultDate]:checked').val();
- if (defaultDate == 'today' || defaultDate == 'yesterday') {
- params = 'period=day&date=' + defaultDate;
- } else if (defaultDate.indexOf('last') >= 0
- || defaultDate.indexOf('previous') >= 0) {
- params = 'period=range&date=' + defaultDate;
- } else {
- params = 'date=today&period=' + defaultDate;
- }
-
- var alias = $('#alias').val();
- var email = $('#email').val();
- var password = $('#password').val();
- var passwordBis = $('#passwordBis').val();
- var defaultReport = $('input[name=defaultReport]:checked').val();
-
- if (defaultReport == 1) {
- defaultReport = $('#defaultReportSiteSelector').attr('siteid');
- }
- var postParams = {};
- postParams.alias = alias;
- postParams.email = email;
- if (password) {
- postParams.password = password;
- }
- if (passwordBis) {
- postParams.passwordBis = passwordBis;
- }
- postParams.defaultReport = defaultReport;
- postParams.defaultDate = defaultDate;
- postParams.language = $('#userSettingsTable #language').val();
- postParams.timeformat = $('#userSettingsTable #timeformat').val();
-
- var ajaxHandler = new ajaxHelper();
- ajaxHandler.addParams({
- module: 'UsersManager',
- format: 'json',
- action: 'recordUserSettings'
- }, 'GET');
- ajaxHandler.withTokenInUrl();
- ajaxHandler.addParams(postParams, 'POST');
- ajaxHandler.redirectOnSuccess(params);
- ajaxHandler.setLoadingElement('#ajaxLoadingUserSettings');
- ajaxHandler.setErrorElement('#ajaxErrorUserSettings');
- ajaxHandler.send(true);
-}
-function sendAnonymousUserSettingsAJAX() {
- var anonymousDefaultReport = $('input[name=anonymousDefaultReport]:checked').val();
- if (anonymousDefaultReport == 1) {
- anonymousDefaultReport = $('#anonymousDefaultReportWebsite').find('option:selected').val();
- }
- var anonymousDefaultDate = $('input[name=anonymousDefaultDate]:checked').val();
-
- var ajaxHandler = new ajaxHelper();
- ajaxHandler.addParams({
- module: 'UsersManager',
- format: 'json',
- action: 'recordAnonymousUserSettings'
- }, 'GET');
- ajaxHandler.withTokenInUrl();
- ajaxHandler.addParams({
- anonymousDefaultReport: anonymousDefaultReport,
- anonymousDefaultDate: anonymousDefaultDate
- }, 'POST');
- ajaxHandler.redirectOnSuccess();
- ajaxHandler.setLoadingElement('#ajaxLoadingAnonymousUserSettings');
- ajaxHandler.setErrorElement('#ajaxErrorAnonymousUserSettings');
- ajaxHandler.send(true);
-}
-
-$(document).ready(function () {
- $('#userSettingsSubmit').click(function () {
- if ($('#password').length > 0 && $('#password').val() != '') {
- piwikHelper.modalConfirm('#confirmPasswordChange', {yes: sendUserSettingsAJAX});
- } else {
- sendUserSettingsAJAX();
- }
-
- });
- $('#userSettingsTable').find('input').keypress(function (e) {
- var key = e.keyCode || e.which;
- if (key == 13) {
- $('#userSettingsSubmit').click();
- }
- });
-
- $('#anonymousUserSettingsSubmit').click(function () {
- sendAnonymousUserSettingsAJAX();
- });
-});
diff --git a/plugins/UsersManager/lang/en.json b/plugins/UsersManager/lang/en.json
index a4a07421c0..7111d6acb0 100644
--- a/plugins/UsersManager/lang/en.json
+++ b/plugins/UsersManager/lang/en.json
@@ -37,7 +37,7 @@
"ExceptionNoValueForUsernameOrEmail": "Please enter a username or email address.",
"ExcludeVisitsViaCookie": "Exclude your visits using a cookie",
"ForAnonymousUsersReportDateToLoadByDefault": "For anonymous users, report date to load by default",
- "GiveViewAccess": "Give view access",
+ "GiveViewAccess": "Give view access for %1$s",
"GiveViewAccessTitle": "Give an existing user access to view reports for %s",
"GiveViewAccessInstructions": "To give an existing user view access for %s enter the username or email address of an existing user",
"IfYouWouldLikeToChangeThePasswordTypeANewOne": "If you would like to change the password type a new one. Otherwise leave this blank.",
diff --git a/plugins/UsersManager/stylesheets/usersManager.less b/plugins/UsersManager/stylesheets/usersManager.less
index f8f0f9de92..90355b5b4f 100644
--- a/plugins/UsersManager/stylesheets/usersManager.less
+++ b/plugins/UsersManager/stylesheets/usersManager.less
@@ -1,6 +1,8 @@
#users .editable:hover,
#users .addrow:hover,
-#users .updateAccess:hover,
+#superUserAccess .updateAccess:hover,
+#superUserAccess .accessGranted:hover,
+#manageUserAccess .updateAccess:hover,
#users .accessGranted:hover,
#users .adduser:hover, .edituser:hover,
#users .deleteuser:hover,
@@ -9,6 +11,14 @@
cursor: pointer;
}
+#users .addNewUserRow td {
+ padding: 0 16px;
+}
+
+#users td {
+ vertical-align: middle !important;
+}
+
#userSettingsTable {
.sites_autocomplete {
margin-left: 20px;
@@ -16,6 +26,10 @@
}
}
+#users #token_auth_user {
+ border-color: @theme-color-background-tinyContrast;
+}
+
#users .canceluser {
margin-top: 10px;
margin-bottom: 10px;
@@ -48,8 +62,11 @@
text-align: left;
}
+#ajaxErrorGiveViewAccess {
+ margin-top: 16px;
+}
+
#giveViewAccessForm {
- display: none;
margin-left: 30px;
#user_invite {
diff --git a/plugins/UsersManager/templates/anonymousSettings.twig b/plugins/UsersManager/templates/anonymousSettings.twig
index 32c606499f..1050bf52d3 100644
--- a/plugins/UsersManager/templates/anonymousSettings.twig
+++ b/plugins/UsersManager/templates/anonymousSettings.twig
@@ -4,9 +4,7 @@
{% block content %}
{% if isSuperUser %}
-
- <h2 piwik-enriched-headline>{{ title }}</h2>
-
+<div piwik-content-block content-title="{{ title|e('html_attr') }}">
{% if anonymousSites|length == 0 %}
<div class="alert alert-info">
@@ -15,64 +13,33 @@
{% else %}
- {{ ajax.errorDiv('ajaxErrorAnonymousUserSettings') }}
- {{ ajax.loadingDiv('ajaxLoadingAnonymousUserSettings') }}
+ <div piwik-form ng-controller="AnonymousSettingsController as anonymousSettings">
- <div class="form-group">
- <label>
- {{ 'UsersManager_WhenUsersAreNotLoggedInAndVisitPiwikTheyShouldAccess'|translate }}
- </label>
- <fieldset>
- <label class="radio">
- <input id="anonymousDefaultReport-login" type="radio" value="Login"
- name="anonymousDefaultReport"
- {% if anonymousDefaultReport==loginModule %} checked="checked"{% endif %} />
- {{ 'UsersManager_TheLoginScreen'|translate }}
- </label>
- <label class="radio">
- <input id="anonymousDefaultReport-multisites"
- {% if anonymousSites is empty %}disabled="disabled" {% endif %}
- type="radio" value="MultiSites" name="anonymousDefaultReport"
- {% if anonymousDefaultReport=='MultiSites' %} checked="checked"{% endif %} />
- {{ 'General_AllWebsitesDashboard'|translate }}
- </label>
+ <div piwik-field uicontrol="radio" name="anonymousDefaultReport"
+ ng-model="anonymousSettings.defaultReport"
+ introduction="{{ 'UsersManager_WhenUsersAreNotLoggedInAndVisitPiwikTheyShouldAccess'|translate|e('html_attr') }}"
+ value="{{ anonymousDefaultReport }}"
+ options="{{ defaultReportOptions|json_encode }}">
+ </div>
- <label class="radio">
- <input id="anonymousDefaultReport-specific"
- {% if anonymousSites is empty %}disabled="disabled" {% endif %}
- type="radio" value="1" name="anonymousDefaultReport"
- {% if anonymousDefaultReport>0 %} checked="checked"{% endif %} />
- {{ 'General_DashboardForASpecificWebsite'|translate }}
+ <div piwik-field uicontrol="select" name="anonymousDefaultReportWebsite"
+ ng-model="anonymousSettings.defaultReportWebsite"
+ options="{{ anonymousSites|json_encode }}"
+ value="{{ anonymousDefaultSite }}">
+ </div>
- {% if anonymousSites is not empty %}
- <select id="anonymousDefaultReportWebsite">
- {% for info in anonymousSites %}
- <option value="{{ info.idsite }}" {% if anonymousDefaultReport==info.idsite %} selected="selected"{% endif %}>
- {{ info.name|raw }}
- </option>
- {% endfor %}
- </select>
- {% endif %}
- </label>
+ <div piwik-field uicontrol="radio" name="anonymousDefaultDate"
+ ng-model="anonymousSettings.defaultDate"
+ introduction="{{ 'UsersManager_ForAnonymousUsersReportDateToLoadByDefault'|translate|e('html_attr') }}"
+ value="{{ anonymousDefaultDate }}"
+ options="{{ availableDefaultDates|json_encode }}">
+ </div>
- </fieldset>
- </div>
+ <div piwik-save-button saving="anonymousSettings.loading" onconfirm="anonymousSettings.save()"></div>
- <div class="form-group">
- <label>{{ 'UsersManager_ForAnonymousUsersReportDateToLoadByDefault'|translate }}</label>
- <fieldset>
- {% for value,description in availableDefaultDates %}
- <label class="radio">
- <input type="radio" name="anonymousDefaultDate"
- {% if anonymousDefaultDate==value %}checked="checked" {% endif %}value="{{ value }}"/>
- {{ description }}
- </label>
- {% endfor %}
- </fieldset>
</div>
- <input type="submit" value="{{ 'General_Save'|translate }}" id="anonymousUserSettingsSubmit" class="submit"/>
-
{% endif %}
+</div>
{% endif %}
{% endblock %} \ No newline at end of file
diff --git a/plugins/UsersManager/templates/index.twig b/plugins/UsersManager/templates/index.twig
index d6f6edfdbd..b4f75df6cc 100644
--- a/plugins/UsersManager/templates/index.twig
+++ b/plugins/UsersManager/templates/index.twig
@@ -4,43 +4,51 @@
{% block content %}
-<h2 piwik-enriched-headline
- help-url="http://piwik.org/docs/manage-users/">{{ title }}</h2>
-<div id="sites" class="usersManager">
- <section class="sites_selector_container">
- <p>{{ 'UsersManager_MainDescription'|translate }}</p>
-
- {% set applyAllSitesText %}
- <strong>{{ 'UsersManager_ApplyToAllWebsites'|translate }}</strong>
- {% endset %}
-
- <div piwik-siteselector
- show-selected-site="true"
- only-sites-with-admin-access="true"
- class="sites_autocomplete"
- siteid="{{ idSiteSelected }}"
- sitename="{{ defaultReportSiteName }}"
- all-sites-text="{{ applyAllSitesText|raw }}"
- all-sites-location="top"
- id="usersManagerSiteSelect"
- switch-site-on-select="false"></div>
- </section>
-</div>
+<div piwik-content-block
+ content-title="{{ title|e('html_attr') }}"
+ feature="true"
+ style="width:800px;"
+ help-url="https://piwik.org/docs/manage-users/"
+ >
+<div ng-controller="ManageUserAccessController as manageUserAccess">
+ <div id="sites" class="usersManager">
+ <section class="sites_selector_container">
+ <p>{{ 'UsersManager_MainDescription'|translate }}</p>
+
+ {% set applyAllSitesText %}
+ <strong>{{ 'UsersManager_ApplyToAllWebsites'|translate }}</strong>
+ {% endset %}
+
+ <div piwik-siteselector
+ show-selected-site="true"
+ only-sites-with-admin-access="true"
+ class="sites_autocomplete"
+ ng-model="manageUserAccess.site"
+ ng-change="manageUserAccess.siteChanged()"
+ siteid="{{ idSiteSelected }}"
+ sitename="{{ defaultReportSiteName }}"
+ all-sites-text="{{ applyAllSitesText|raw }}"
+ all-sites-location="top"
+ id="usersManagerSiteSelect"
+ switch-site-on-select="false"></div>
+ </section>
+ </div>
-{% block websiteAccessTable %}
+ {% block websiteAccessTable %}
-{% import 'ajaxMacros.twig' as ajax %}
-{{ ajax.errorDiv }}
-{{ ajax.loadingDiv }}
+ {% import 'ajaxMacros.twig' as ajax %}
+
+ <div piwik-activity-indicator class="loadingManageUserAccess" loading="manageUserAccess.isLoading"></div>
+ <div id="accessUpdated" style="vertical-align:top;"></div>
-<div class="entityContainer" style="width:600px;margin-top:16px;">
{% if anonymousHasViewAccess %}
<br/>
<div class="alert alert-warning">
{{ ['UsersManager_AnonymousUserHasViewAccess'|translate("'anonymous'","'view'"), 'UsersManager_AnonymousUserHasViewAccess2'|translate]|join(' ') }}
</div>
{% endif %}
- <table class="entityTable dataTable" id="access" style="display:inline-table;width:550px;">
+
+ <table piwik-content-table id="manageUserAccess">
<thead>
<tr>
<th class='first'>{{ 'UsersManager_User'|translate }}</th>
@@ -53,11 +61,11 @@
<tbody>
{% set accesValid %}<img src='plugins/UsersManager/images/ok.png' class='accessGranted' />{% endset %}
- {% set accesInvalid %}<img src='plugins/UsersManager/images/no-access.png' class='updateAccess' />{% endset %}
{% set superUserAccess %}<span title="{{ 'UsersManager_ExceptionSuperUserAccess'|translate }}">N/A</span>{% endset %}
+
{% for login,access in usersAccessByWebsite %}
{% if userIsSuperUser or (hasOnlyAdminAccess and (access!='noaccess' or idSiteSelected == 'all')) %}
- <tr>
+ <tr data-login="{{ login|e('html_attr') }}">
<td id='login'>{{ login }}</td>
<td>{{ usersAliasByLogin[login]|raw }}</td>
<td id='noaccess'>
@@ -66,7 +74,9 @@
{% elseif access=='noaccess' and idSiteSelected != 'all' %}
{{ accesValid }}
{% else %}
- {{ accesInvalid }}
+ <img src='plugins/UsersManager/images/no-access.png' class='updateAccess'
+ ng-click='manageUserAccess.setAccess({{ login|json_encode}}, "noaccess")'
+ />
{% endif %}&nbsp;</td>
<td id='view'>
{% if login in superUserLogins %}
@@ -74,7 +84,9 @@
{% elseif access == 'view' and idSiteSelected != 'all' %}
{{ accesValid }}
{% else %}
- {{ accesInvalid }}
+ <img src='plugins/UsersManager/images/no-access.png' class='updateAccess'
+ ng-click='manageUserAccess.setAccess({{ login|json_encode}}, "view")'
+ />
{% endif %}&nbsp;</td>
<td id='admin'>
{% if login in superUserLogins %}
@@ -82,7 +94,13 @@
{% elseif login == 'anonymous' %}
N/A
{% else %}
- {% if access == 'admin' and idSiteSelected != 'all' %}{{ accesValid }}{% else %}{{ accesInvalid }}{% endif %}&nbsp;
+ {% if access == 'admin' and idSiteSelected != 'all' %}
+ {{ accesValid }}
+ {% else %}
+ <img src='plugins/UsersManager/images/no-access.png' class='updateAccess'
+ ng-click='manageUserAccess.setAccess({{ login|json_encode}}, "admin")'
+ />
+ {% endif %}&nbsp;
{% endif %}
</td>
</tr>
@@ -90,37 +108,47 @@
{% endfor %}
</tbody>
</table>
- <div id="accessUpdated" style="vertical-align:top;"></div>
-</div>
-{% if hasOnlyAdminAccess %}
- <p>
- <button id="showGiveViewAccessForm" class="add-user btn btn-lg btn-flat">
- <span class="icon-add"></span>
- {{ 'UsersManager_GiveViewAccessTitle'|translate('"' ~ defaultReportSiteName ~ '"')|raw }}
- </button>
- </p>
- <form id="giveViewAccessForm">
- <div class="form-group">
- <input type="text" name="user_invite"
- id="user_invite"
- placeholder="{{ 'UsersManager_EnterUsernameOrEmail'|translate|e('html_attr') }}"
- title="{{ 'UsersManager_GiveViewAccessInstructions'|translate("'" ~ defaultReportSiteName ~ "'")|e('html_attr') }}">
+ {% if hasOnlyAdminAccess %}
+ <div class="tableActionBar">
+ <div ng-controller="GiveUserViewAccessController as giveViewAccess" piwik-form>
+ <button id="showGiveViewAccessForm"
+ ng-show="!giveViewAccess.showForm" ng-click="giveViewAccess.showViewAccessForm()">
+ <span class="icon-add"></span>
+ {{ 'UsersManager_GiveViewAccessTitle'|translate('"' ~ defaultReportSiteName ~ '"')|raw }}
+ </button>
+
+ <form id="giveViewAccessForm" ng-show="giveViewAccess.showForm">
+ <div piwik-field uicontrol="text" name="user_invite"
+ ng-model="giveViewAccess.usernameOrEmail"
+ full-width="true"
+ title="{{ 'UsersManager_EnterUsernameOrEmail'|translate|e('html_attr') }}"
+ >
+ </div>
+
+ <div piwik-save-button id="giveUserAccessToViewReports"
+ onconfirm="giveViewAccess.giveAccess()"
+ saving="giveViewAccess.isLoading"
+ value="{{ 'UsersManager_GiveViewAccess'|translate("'" ~ defaultReportSiteName ~ "'")|e('html_attr') }}"></div>
+
+ </form>
+ </div>
</div>
+ <div id="ajaxErrorGiveViewAccess">
- <input class="btn" type="button" id="giveUserAccessToViewReports" value="{{ 'UsersManager_GiveViewAccess'|translate|e('html_attr') }}">
- </form>
- {{ ajax.errorDiv('ajaxErrorGiveViewAccess') }}
- {{ ajax.loadingDiv('ajaxLoadingGiveViewAccess') }}
-{% endif %}
+ </div>
+ {% endif %}
+</div>
+</div>
<div class="ui-confirm" id="confirm">
- <h2>{{ 'UsersManager_ChangeAllConfirm'|translate("<span id='login'></span>")|raw }}</h2>
+ <h2>{{ 'UsersManager_ChangeAllConfirm'|translate("<span class='login'></span>")|raw }}</h2>
<input role="yes" type="button" value="{{ 'General_Yes'|translate }}"/>
<input role="no" type="button" value="{{ 'General_No'|translate }}"/>
</div>
{% if userIsSuperUser %}
+<div piwik-content-block content-title="{{ 'UsersManager_UsersManagement'|translate|e('html_attr') }}">
<div class="ui-confirm" id="confirmUserRemove">
<h2></h2>
<input role="yes" type="button" value="{{ 'General_Yes'|translate }}"/>
@@ -132,14 +160,14 @@
<input role="no" type="button" value="{{ 'General_No'|translate }}"/>
</div>
<br/>
- <h2>{{ 'UsersManager_UsersManagement'|translate }}</h2>
<p>{{ 'UsersManager_UsersManagementMainDescription'|translate }}
{{ 'UsersManager_ThereAreCurrentlyNRegisteredUsers'|translate("<b>"~usersCount~"</b>")|raw }}</p>
{% import 'ajaxMacros.twig' as ajax %}
- {{ ajax.errorDiv('ajaxErrorUsersManagement') }}
- {{ ajax.loadingDiv('ajaxLoadingUsersManagement') }}
- <div class="user entityContainer" style="margin-bottom:50px;">
- <table class="entityTable dataTable" id="users">
+
+ <div class="user" ng-controller="ManageUsersController as manageUsers">
+ <div piwik-activity-indicator class="loadingManageUsers" loading="manageUsers.isLoading"></div>
+
+ <table piwik-content-table id="users">
<thead>
<tr>
<th>{{ 'General_Username'|translate }}</th>
@@ -159,21 +187,24 @@
{% for i,user in users %}
{% if user.login != 'anonymous' %}
<tr class="editable" id="row{{ i }}">
- <td id="userLogin" class="editable">{{ user.login }}</td>
- <td id="password" class="editable">-</td>
- <td id="email" class="editable">{{ user.email }}</td>
- <td id="alias" class="editable">{{ user.alias|raw }}</td>
- <td id="token_auth" class="token_auth" data-token="{{ user.token_auth }}">{{ user.token_auth|slice(0, 8) }}…</td>
+ <td id="userLogin" class="editable" ng-click='manageUsers.editUser("row{{ i|e('js') }}")'>{{ user.login }}</td>
+ <td id="password" class="editable" ng-click='manageUsers.editUser("row{{ i|e('js') }}")'>-</td>
+ <td id="email" class="editable" ng-click='manageUsers.editUser("row{{ i|e('js') }}")'>{{ user.email }}</td>
+ <td id="alias" class="editable" ng-click='manageUsers.editUser("row{{ i|e('js') }}")'>{{ user.alias|raw }}</td>
+ <td id="token_auth_user" class="token_auth" data-token="{{ user.token_auth }}">{{ user.token_auth|slice(0, 8) }}…</td>
{% if user.last_seen is defined %}
<td id="last_seen">{% if user.last_seen is empty %}-{% else %}{{ 'General_TimeAgo'|translate(user.last_seen)|raw }}{% endif %}</td>
{% endif %}
- <td class="text-center">
- <button class="edituser btn btn-flat" id="row{{ i }}" title="{{ 'General_Edit'|translate }}">
+ <td class="center">
+ <button ng-click='manageUsers.editUser("row{{ i|e('js') }}")'
+ class="edituser table-action" title="{{ 'General_Edit'|translate }}">
<span class="icon-edit"></span>
</button>
</td>
- <td class="text-center">
- <button class="deleteuser btn btn-flat" id="row{{ i }}" title="{{ 'General_Delete'|translate }}">
+ <td class="center">
+ <button class="deleteuser table-action"
+ ng-click='manageUsers.deleteUser({{ user.login|json_encode }})'
+ title="{{ 'General_Delete'|translate }}">
<span class="icon-delete"></span>
</button>
</td>
@@ -182,60 +213,76 @@
{% endfor %}
</tbody>
</table>
- <p>
- <button class="add-user btn btn-lg btn-flat">
+
+ <div class="tableActionBar">
+ <button class="add-user" ng-click="manageUsers.createUser()" ng-show="manageUsers.showCreateUser">
<span class="icon-add"></span>
{{ 'UsersManager_AddUser'|translate }}
</button>
- </p>
+ </div>
</div>
+</div>
- <h2 id="super_user_access">{{ 'UsersManager_SuperUserAccessManagement'|translate }}</h2>
- <p>{{ 'UsersManager_SuperUserAccessManagementMainDescription'|translate }} <br/>
- {{ 'UsersManager_SuperUserAccessManagementGrantMore'|translate }}</p>
+<div piwik-content-block
+ id="super_user_access"
+ style="width:800px;"
+ content-title="{{ 'UsersManager_SuperUserAccessManagement'|translate|e('html_attr') }}">
- {{ ajax.errorDiv('ajaxErrorSuperUsersManagement') }}
- {{ ajax.loadingDiv('ajaxLoadingSuperUsersManagement') }}
+ <div ng-controller="ManageSuperUserController as manageSuperUser">
- <table class="entityTable dataTable" id="superUserAccess" style="display:inline-table;width:400px;">
- <thead>
- <tr>
- <th class='first'>{{ 'UsersManager_User'|translate }}</th>
- <th>{{ 'UsersManager_Alias'|translate }}</th>
- <th>{{ 'Installation_SuperUser'|translate }}</th>
- </tr>
- </thead>
+ <p>{{ 'UsersManager_SuperUserAccessManagementMainDescription'|translate }} <br/>
+ {{ 'UsersManager_SuperUserAccessManagementGrantMore'|translate }}</p>
- <tbody>
- {% if users|length > 1 %}
- {% for login,alias in usersAliasByLogin if login != 'anonymous' %}
+ <div piwik-activity-indicator class="loadingManageSuperUser" loading="manageSuperUser.isLoading"></div>
+
+ <div id="superUserAccessUpdated" style="vertical-align:top;"></div>
+
+ <table piwik-content-table id="superUserAccess" >
+ <thead>
+ <tr>
+ <th class='first'>{{ 'UsersManager_User'|translate }}</th>
+ <th>{{ 'UsersManager_Alias'|translate }}</th>
+ <th>{{ 'Installation_SuperUser'|translate }}</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% if users|length > 1 %}
+ {% for login,alias in usersAliasByLogin if login != 'anonymous' %}
+ <tr>
+ <td id='login'>{{ login }}</td>
+ <td>{{ alias|raw }}</td>
+ <td id='superuser'>
+ {% if login in superUserLogins %}
+ <img src='plugins/UsersManager/images/ok.png' class='accessGranted'
+ ng-click='manageSuperUser.removeSuperUserAccess({{ login|json_encode}})' />
+ {% endif %}
+ {% if not (login in superUserLogins) %}
+ <img src='plugins/UsersManager/images/no-access.png' class='updateAccess'
+ ng-click='manageSuperUser.giveSuperUserAccess({{ login|json_encode }})' />
+ {% endif %}
+ &nbsp;
+ </td>
+ </tr>
+ {% endfor %}
+ {% else %}
<tr>
- <td id='login'>{{ login }}</td>
- <td>{{ alias|raw }}</td>
- <td id='superuser' data-login="{{ login|e('html_attr') }}">
- <img src='plugins/UsersManager/images/ok.png' class='accessGranted' data-hasaccess="1" {% if not (login in superUserLogins) %}style="display:none"{% endif %} />
- <img src='plugins/UsersManager/images/no-access.png' class='updateAccess' data-hasaccess="0" {% if login in superUserLogins %}style="display:none"{% endif %} />
- &nbsp;
+ <td colspan="3">
+ {{ 'UsersManager_NoUsersExist'|translate }}
</td>
</tr>
- {% endfor %}
- {% else %}
- <tr>
- <td colspan="3">
- {{ 'UsersManager_NoUsersExist'|translate }}
- </td>
- </tr>
- {% endif %}
- </tbody>
- </table>
+ {% endif %}
+ </tbody>
+ </table>
- <div id="superUserAccessUpdated" style="vertical-align:top;"></div>
+ <div class="ui-confirm" id="superUserAccessConfirm">
+ <h2> </h2>
+ <input role="yes" type="button" value="{{ 'General_Yes'|translate }}"/>
+ <input role="no" type="button" value="{{ 'General_No'|translate }}"/>
+ </div>
- <div class="ui-confirm" id="superUserAccessConfirm">
- <h2> </h2>
- <input role="yes" type="button" value="{{ 'General_Yes'|translate }}"/>
- <input role="no" type="button" value="{{ 'General_No'|translate }}"/>
</div>
+</div>
{% endif %}
{% endblock %}
diff --git a/plugins/UsersManager/templates/userSettings.twig b/plugins/UsersManager/templates/userSettings.twig
index 48d5f47ed9..2c802670d0 100644
--- a/plugins/UsersManager/templates/userSettings.twig
+++ b/plugins/UsersManager/templates/userSettings.twig
@@ -4,67 +4,62 @@
{% block content %}
-<h2 piwik-enriched-headline>{{ title }}</h2>
-
<div class="ui-confirm" id="confirmPasswordChange">
<h2>{{ 'UsersManager_ChangePasswordConfirm'|translate }}</h2>
<input role="yes" type="button" value="{{ 'General_Yes'|translate }}"/>
<input role="no" type="button" value="{{ 'General_No'|translate }}"/>
</div>
-<form id="userSettingsTable">
+<div piwik-content-block content-title="{{ title|e('html_attr') }}" feature="true">
+ <form id="userSettingsTable" piwik-form ng-controller="PersonalSettingsController as personalSettings">
- <div class="form-group">
- <label for="username">{{ 'General_Username'|translate }}</label>
- <div class="form-help">{{ 'UsersManager_YourUsernameCannotBeChanged'|translate }}</div>
- <input value="{{ userLogin }}" id="username" disabled="disabled"/>
- </div>
+ <div piwik-field uicontrol="text" name="username"
+ title="{{ 'General_Username'|translate|e('html_attr') }}"
+ value="{{ userLogin }}" disabled="true"
+ ng-model="personalSettings.username"
+ inline-help="{{ 'UsersManager_YourUsernameCannotBeChanged'|translate|e('html_attr') }}">
+ </div>
- <div class="form-group">
- <label for="alias">{{ 'UsersManager_Alias'|translate }}</label>
- <input value="{{ userAlias }}" id="alias" />
- </div>
+ <div piwik-field uicontrol="text" name="alias"
+ ng-model="personalSettings.alias"
+ title="{{ 'UsersManager_Alias'|translate|e('html_attr') }}"
+ value="{{ userAlias|raw }}">
+ </div>
- <div class="form-group">
- <label for="email">{{ 'UsersManager_Email'|translate }}</label>
- <input value="{{ userEmail }}" id="email"/>
- </div>
+ <div piwik-field uicontrol="text" name="email"
+ ng-model="personalSettings.email"
+ title="{{ 'UsersManager_Email'|translate|e('html_attr') }}"
+ value="{{ userEmail }}">
+ </div>
- <div class="form-group">
- <label for="language">{{ 'General_Language'|translate }}</label>
- <div class="form-help">
+ <div id="languageHelp" class="inline-help-node">
<a href="?module=Proxy&amp;action=redirect&amp;url=http://piwik.org/translations/" target="_blank">
{{ 'LanguagesManager_AboutPiwikTranslations'|translate }}</a>
</div>
- <select name="language" id="language">
- {% for language in languages %}
- <option value="{{ language.code }}" {% if language.code == currentLanguageCode %}selected="selected"{% endif %}
- title="{{ language.name }} ({{ language.english_name }})">{{ language.name }}</option>
- {% endfor %}
- </select>
- </div>
-
- <div class="form-group">
- <label for="timeformat">{{ 'General_TimeFormat'|translate }}</label>
- <select name="timeformat" id="timeformat">
- <option value="1" {% if currentTimeformat == 1 %}selected="selected"{% endif %} title="{{ 'General_12HourClock'|translate }}">{{ 'General_12HourClock'|translate }}</option>
- <option value="0" {% if currentTimeformat == 0 %}selected="selected"{% endif %} title="{{ 'General_24HourClock'|translate }}">{{ 'General_24HourClock'|translate }}</option>
- </select>
- </div>
-
- <div class="form-group">
- <label>{{ 'UsersManager_ReportToLoadByDefault'|translate }}</label>
- <label class="radio">
- <input id="defaultReportRadioAll" type="radio" value="MultiSites"
- name="defaultReport"{% if defaultReport=='MultiSites' %} checked="checked"{% endif %} />
- {{ 'General_AllWebsitesDashboard'|translate }}
- </label>
- <label class="radio">
- <input id="defaultReportSpecific" type="radio" value="1"
- name="defaultReport"{% if defaultReport != 'MultiSites' %} checked="checked"{% endif %} />
- {{ 'General_DashboardForASpecificWebsite'|translate }}
- </label>
+
+ <div piwik-field uicontrol="select" name="language"
+ ng-model="personalSettings.language"
+ title="{{ 'General_Language'|translate|e('html_attr') }}"
+ options="{{ languageOptions|json_encode }}"
+ inline-help="#languageHelp"
+ value="{{ currentLanguageCode }}">
+ </div>
+
+ <div piwik-field uicontrol="select" name="timeformat"
+ ng-model="personalSettings.timeformat"
+ title="{{ 'General_TimeFormat'|translate|e('html_attr') }}"
+ value="{{ currentTimeformat }}" options="{{ timeFormats|json_encode }}">
+ </div>
+
+ <div piwik-field uicontrol="radio" name="defaultReport"
+ ng-model="personalSettings.defaultReport"
+ introduction="{{ 'UsersManager_ReportToLoadByDefault'|translate|e('html_attr') }}"
+ title="{{ 'General_AllWebsitesDashboard'|translate|e('html_attr') }}"
+ value="{{ defaultReport }}" options="{{ defaultReportOptions|json_encode }}">
+ </div>
+
<div piwik-siteselector
+ ng-model="personalSettings.site"
show-selected-site="true"
class="sites_autocomplete"
siteid="{{ defaultReportIdSite }}"
@@ -73,58 +68,47 @@
show-all-sites-item="false"
showselectedsite="true"
id="defaultReportSiteSelector"
- ></div>
- </div>
-
- <div class="form-group">
- <label>{{ 'UsersManager_ReportDateToLoadByDefault'|translate }}</label>
- {% for value,description in availableDefaultDates %}
- <label class="radio">
- <input id="defaultDate-{{ loop.index }}" type="radio"{% if defaultDate==value %} checked="checked"{% endif %} value="{{ value }}" name="defaultDate"/>
- {{ description }}
- </label>
- {% endfor %}
- </div>
-
- {% if isValidHost is defined and isValidHost %}
- <div class="form-group">
- <label for="password">{{ 'General_ChangePassword'|translate }}</label>
- <div class="form-help">
- {{ 'UsersManager_IfYouWouldLikeToChangeThePasswordTypeANewOne'|translate }}
- </div>
- <input value="" autocomplete="off" id="password" type="password"/>
- </div>
- <div class="form-group">
- <div class="form-help">
- {{ 'UsersManager_TypeYourPasswordAgain'|translate }}
- </div>
- <input value="" autocomplete="off" id="passwordBis" type="password"/>
- </div>
- {% endif %}
+ ></div>
- {% if isValidHost is not defined or not isValidHost %}
- <div class="alert alert-danger">
- {{ 'UsersManager_InjectedHostCannotChangePwd'|translate(invalidHost) }}
- {% if not isSuperUser %}{{ 'UsersManager_EmailYourAdministrator'|translate(invalidHostMailLinkStart,'</a>')|raw }}{% endif %}
+ <div piwik-field uicontrol="radio" name="defaultDate"
+ ng-model="personalSettings.defaultDate"
+ introduction="{{ 'UsersManager_ReportDateToLoadByDefault'|translate|e('html_attr') }}"
+ value="{{ defaultDate }}" options="{{ availableDefaultDates|json_encode }}">
</div>
- {% endif %}
- {% import 'ajaxMacros.twig' as ajax %}
- {{ ajax.errorDiv('ajaxErrorUserSettings') }}
- {{ ajax.loadingDiv('ajaxLoadingUserSettings') }}
+ {% if isValidHost is defined and isValidHost %}
- <button type="button" id="userSettingsSubmit">{{ 'General_Save'|translate }}</button>
+ <div piwik-field uicontrol="password" name="password" autocomplete="off"
+ ng-model="personalSettings.password"
+ introduction="{{ 'General_ChangePassword'|translate|e('html_attr') }}"
+ title="{{ 'Login_NewPassword'|translate|e('html_attr') }}"
+ value="" inline-help="{{ 'UsersManager_IfYouWouldLikeToChangeThePasswordTypeANewOne'|translate|e('html_attr') }}">
+ </div>
+
+ <div piwik-field uicontrol="password" name="passwordBis" autocomplete="off"
+ ng-model="personalSettings.passwordBis"
+ title="{{ 'Login_NewPasswordRepeat'|translate|e('html_attr') }}"
+ value="" inline-help="{{ 'UsersManager_TypeYourPasswordAgain'|translate|e('html_attr') }}">
+ </div>
+ {% endif %}
-</form>
+ {% if isValidHost is not defined or not isValidHost %}
+ <div class="alert alert-danger">
+ {{ 'UsersManager_InjectedHostCannotChangePwd'|translate(invalidHost) }}
+ {% if not isSuperUser %}{{ 'UsersManager_EmailYourAdministrator'|translate(invalidHostMailLinkStart,'</a>')|raw }}{% endif %}
+ </div>
+ {% endif %}
- <hr />
+ <div piwik-save-button onconfirm="personalSettings.save()"
+ saving="personalSettings.loading"></div>
- <h2 piwik-enriched-headline>{{ 'CoreAdminHome_PersonalPluginSettings'|translate }}</h2>
+ </form>
+</div>
- <div piwik-plugin-settings mode="user"></div>
+<div piwik-plugin-settings mode="user"></div>
- <hr />
- <h2 id="excludeCookie">{{ 'UsersManager_ExcludeVisitsViaCookie'|translate }}</h2>
+<div piwik-content-block
+ content-title="{{ 'UsersManager_ExcludeVisitsViaCookie'|translate|e('html_attr') }}">
<p>
{% if ignoreCookieSet %}
{{ 'UsersManager_YourVisitsAreIgnoredOnDomain'|translate("<strong>", piwikHost, "</strong>")|raw }}
@@ -133,8 +117,10 @@
{% endif %}
</p>
<span style="margin-left:20px;">
-<a href='{{ linkTo({'ignoreSalt':ignoreSalt, 'action':'setIgnoreCookie'}) }}#excludeCookie'>&rsaquo; {% if ignoreCookieSet %}{{ 'UsersManager_ClickHereToDeleteTheCookie'|translate }}
- {% else %}{{'UsersManager_ClickHereToSetTheCookieOnDomain'|translate(piwikHost) }}{% endif %}
- <br/>
-</a></span>
+ <a href='{{ linkTo({'ignoreSalt':ignoreSalt, 'action':'setIgnoreCookie'}) }}#excludeCookie'>&rsaquo; {% if ignoreCookieSet %}{{ 'UsersManager_ClickHereToDeleteTheCookie'|translate }}
+ {% else %}{{'UsersManager_ClickHereToSetTheCookieOnDomain'|translate(piwikHost) }}{% endif %}
+ <br/>
+ </a></span>
+</div>
+
{% endblock %}