update Piwik to version 2.16 (fixes #91)

This commit is contained in:
oliver 2016-04-10 18:55:57 +02:00
commit 47263617c5
73 changed files with 418860 additions and 226988 deletions

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -11,7 +11,7 @@ use Piwik\Piwik;
use Piwik\WidgetsList;
/**
* This API is the <a href='http://piwik.org/docs/analytics-api/reference/' target='_blank'>Dashboard API</a>: it gives information about dashboards.
* This API is the <a href='http://piwik.org/docs/analytics-api/reference/' rel='noreferrer' target='_blank'>Dashboard API</a>: it gives information about dashboards.
*
* @method static \Piwik\Plugins\Dashboard\API getInstance()
*/
@ -19,9 +19,9 @@ class API extends \Piwik\Plugin\API
{
private $dashboard = null;
protected function __construct()
public function __construct(Dashboard $dashboard)
{
$this->dashboard = new Dashboard();
$this->dashboard = $dashboard;
}
/**
@ -130,7 +130,7 @@ class API extends \Piwik\Plugin\API
private function widgetExists($widget)
{
if (empty($widget->parameters)) {
if (empty($widget->parameters->module)) {
return false;
}

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -14,6 +14,7 @@ use Piwik\Piwik;
use Piwik\Session\SessionNamespace;
use Piwik\View;
use Piwik\WidgetsList;
use Piwik\FrontController;
/**
* Dashboard Controller
@ -38,11 +39,14 @@ class Controller extends \Piwik\Plugin\Controller
$view = new View($template);
$this->setGeneralVariablesView($view);
$view->availableWidgets = Common::json_encode(WidgetsList::get());
$view->availableWidgets = json_encode(WidgetsList::get());
$view->availableLayouts = $this->getAvailableLayouts();
$view->dashboardId = Common::getRequestVar('idDashboard', 1, 'int');
$view->dashboardLayout = $this->getLayout($view->dashboardId);
// get the layout via FrontController so controller events are posted
$view->dashboardLayout = FrontController::getInstance()->dispatch('Dashboard', 'getDashboardLayout',
array($checkToken = false));
return $view;
}
@ -66,35 +70,25 @@ class Controller extends \Piwik\Plugin\Controller
return $view->render();
}
public function getDashboardSettingsControl()
{
$view = new DashboardManagerControl();
$result = $view->render();
if (Common::getRequestVar('includeWidgetFactory', false)) {
$factoryTemplateView = new View("@Dashboard/_widgetFactoryTemplate");
$result .= $factoryTemplateView->render();
}
return $result;
}
public function getAvailableWidgets()
{
$this->checkTokenInUrl();
Json::sendHeaderJSON();
return Common::json_encode(WidgetsList::get());
return json_encode(WidgetsList::get());
}
public function getDashboardLayout()
public function getDashboardLayout($checkToken = true)
{
$this->checkTokenInUrl();
if ($checkToken) {
$this->checkTokenInUrl();
}
$idDashboard = Common::getRequestVar('idDashboard', 1, 'int');
$layout = $this->getLayout($idDashboard);
Json::sendHeaderJSON();
return $layout;
}
@ -111,38 +105,13 @@ class Controller extends \Piwik\Plugin\Controller
$session->dashboardLayout = $layout;
$session->setExpirationSeconds(1800);
} else {
$this->saveLayoutForUser(Piwik::getCurrentUserLogin(), $idDashboard, $layout);
$this->getModel()->updateLayoutForUser(Piwik::getCurrentUserLogin(), $idDashboard, $layout);
}
}
/**
* Records the layout in the DB for the given user.
*
* @param string $login
* @param int $idDashboard
* @param string $layout
*/
protected function saveLayoutForUser($login, $idDashboard, $layout)
private function getModel()
{
$paramsBind = array($login, $idDashboard, $layout, $layout);
$query = sprintf('INSERT INTO %s (login, iddashboard, layout) VALUES (?,?,?) ON DUPLICATE KEY UPDATE layout=?',
Common::prefixTable('user_dashboard'));
Db::query($query, $paramsBind);
}
/**
* Updates the name of a dashboard
*
* @param string $login
* @param int $idDashboard
* @param string $name
*/
protected function updateDashboardName($login, $idDashboard, $name)
{
$paramsBind = array($name, $login, $idDashboard);
$query = sprintf('UPDATE %s SET name = ? WHERE login = ? AND iddashboard = ?',
Common::prefixTable('user_dashboard'));
Db::query($query, $paramsBind);
return new Model();
}
/**
@ -160,9 +129,7 @@ class Controller extends \Piwik\Plugin\Controller
// first layout can't be removed
if ($idDashboard != 1) {
$query = sprintf('DELETE FROM %s WHERE iddashboard = ? AND login = ?',
Common::prefixTable('user_dashboard'));
Db::query($query, array($idDashboard, Piwik::getCurrentUserLogin()));
$this->getModel()->deleteDashboardForUser($idDashboard, Piwik::getCurrentUserLogin());
}
}
@ -178,11 +145,11 @@ class Controller extends \Piwik\Plugin\Controller
return '[]';
}
$login = Piwik::getCurrentUserLogin();
$login = Piwik::getCurrentUserLogin();
$dashboards = $this->dashboard->getAllDashboards($login);
Json::sendHeaderJSON();
return Common::json_encode($dashboards);
return json_encode($dashboards);
}
/**
@ -196,36 +163,20 @@ class Controller extends \Piwik\Plugin\Controller
if (Piwik::isUserIsAnonymous()) {
return '0';
}
$user = Piwik::getCurrentUserLogin();
$nextId = $this->getNextIdDashboard($user);
$name = urldecode(Common::getRequestVar('name', '', 'string'));
$type = urldecode(Common::getRequestVar('type', 'default', 'string'));
$name = urldecode(Common::getRequestVar('name', '', 'string'));
$type = urldecode(Common::getRequestVar('type', 'default', 'string'));
$layout = '{}';
$login = Piwik::getCurrentUserLogin();
if ($type == 'default') {
$layout = $this->dashboard->getDefaultLayout();
}
$query = sprintf('INSERT INTO %s (login, iddashboard, name, layout) VALUES (?, ?, ?, ?)',
Common::prefixTable('user_dashboard'));
Db::query($query, array($user, $nextId, $name, $layout));
$nextId = $this->getModel()->createNewDashboardForUser($login, $name, $layout);
Json::sendHeaderJSON();
return Common::json_encode($nextId);
}
private function getNextIdDashboard($login)
{
$nextIdQuery = sprintf('SELECT MAX(iddashboard)+1 FROM %s WHERE login = ?',
Common::prefixTable('user_dashboard'));
$nextId = Db::fetchOne($nextIdQuery, array($login));
if (empty($nextId)) {
$nextId = 1;
return $nextId;
}
return $nextId;
return json_encode($nextId);
}
public function copyDashboardToUser()
@ -235,21 +186,19 @@ class Controller extends \Piwik\Plugin\Controller
if (!Piwik::hasUserSuperUserAccess()) {
return '0';
}
$login = Piwik::getCurrentUserLogin();
$name = urldecode(Common::getRequestVar('name', '', 'string'));
$user = urldecode(Common::getRequestVar('user', '', 'string'));
$name = urldecode(Common::getRequestVar('name', '', 'string'));
$user = urldecode(Common::getRequestVar('user', '', 'string'));
$idDashboard = Common::getRequestVar('dashboardId', 0, 'int');
$layout = $this->dashboard->getLayoutForUser($login, $idDashboard);
if ($layout !== false) {
$nextId = $this->getNextIdDashboard($user);
$query = sprintf('INSERT INTO %s (login, iddashboard, name, layout) VALUES (?, ?, ?, ?)',
Common::prefixTable('user_dashboard'));
Db::query($query, array($user, $nextId, $name, $layout));
$nextId = $this->getModel()->createNewDashboardForUser($user, $name, $layout);
Json::sendHeaderJSON();
return Common::json_encode($nextId);
return json_encode($nextId);
}
}
@ -262,17 +211,19 @@ class Controller extends \Piwik\Plugin\Controller
{
$this->checkTokenInUrl();
$layout = Common::unsanitizeInputValue(Common::getRequestVar('layout'));
$layout = Common::unsanitizeInputValue(Common::getRequestVar('layout'));
$layout = strip_tags($layout);
$idDashboard = Common::getRequestVar('idDashboard', 1, 'int');
$name = Common::getRequestVar('name', '', 'string');
$name = Common::getRequestVar('name', '', 'string');
if (Piwik::isUserIsAnonymous()) {
$session = new SessionNamespace("Dashboard");
$session->dashboardLayout = $layout;
$session->setExpirationSeconds(1800);
} else {
$this->saveLayoutForUser(Piwik::getCurrentUserLogin(), $idDashboard, $layout);
$this->getModel()->updateLayoutForUser(Piwik::getCurrentUserLogin(), $idDashboard, $layout);
if (!empty($name)) {
$this->updateDashboardName(Piwik::getCurrentUserLogin(), $idDashboard, $name);
$this->getModel()->updateDashboardName(Piwik::getCurrentUserLogin(), $idDashboard, $name);
}
}
}
@ -286,10 +237,8 @@ class Controller extends \Piwik\Plugin\Controller
if (Piwik::hasUserSuperUserAccess()) {
$layout = Common::unsanitizeInputValue(Common::getRequestVar('layout'));
$paramsBind = array('', '1', $layout, $layout);
$query = sprintf('INSERT INTO %s (login, iddashboard, layout) VALUES (?,?,?) ON DUPLICATE KEY UPDATE layout=?',
Common::prefixTable('user_dashboard'));
Db::query($query, $paramsBind);
$layout = strip_tags($layout);
$this->getModel()->createOrUpdateDashboard('', '1', $layout);
}
}
@ -342,4 +291,3 @@ class Controller extends \Piwik\Plugin\Controller
}
}

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -8,14 +8,11 @@
*/
namespace Piwik\Plugins\Dashboard;
use Exception;
use Piwik\Common;
use Piwik\Container\StaticContainer;
use Piwik\Db;
use Piwik\DbHelper;
use Piwik\Menu\MenuMain;
use Piwik\Menu\MenuTop;
use Piwik\Piwik;
use Piwik\Site;
use Piwik\Plugin;
use Piwik\WidgetsList;
/**
@ -23,16 +20,14 @@ use Piwik\WidgetsList;
class Dashboard extends \Piwik\Plugin
{
/**
* @see Piwik\Plugin::getListHooksRegistered
* @see Piwik\Plugin::registerEvents
*/
public function getListHooksRegistered()
public function registerEvents()
{
return array(
'AssetManager.getJavaScriptFiles' => 'getJsFiles',
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
'UsersManager.deleteUser' => 'deleteDashboardLayout',
'Menu.Reporting.addItems' => 'addMenus',
'Menu.Top.addItems' => 'addTopMenu',
'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys'
);
}
@ -48,10 +43,7 @@ class Dashboard extends \Piwik\Plugin
*/
public function getLayoutForUser($login, $idDashboard)
{
$paramsBind = array($login, $idDashboard);
$query = sprintf('SELECT layout FROM %s WHERE login = ? AND iddashboard = ?',
Common::prefixTable('user_dashboard'));
$return = Db::fetchAll($query, $paramsBind);
$return = $this->getModel()->getLayoutForUser($login, $idDashboard);
if (count($return) == 0) {
return false;
@ -60,16 +52,29 @@ class Dashboard extends \Piwik\Plugin
return $return[0]['layout'];
}
private function getModel()
{
return new Model();
}
public function getDefaultLayout()
{
$defaultLayout = $this->getLayoutForUser('', 1);
if (empty($defaultLayout)) {
$topWidget = '';
$advertising = StaticContainer::get('Piwik\PiwikPro\Advertising');
if ($advertising->arePiwikProAdsEnabled() && Plugin\Manager::getInstance()->isPluginActivated('PiwikPro')) {
$topWidget .= '{"uniqueId":"widgetPiwikPropromoPiwikPro",'
. '"parameters":{"module":"PiwikPro","action":"promoPiwikPro"}},';
}
if (Piwik::hasUserSuperUserAccess()) {
$topWidget = '{"uniqueId":"widgetCoreHomegetDonateForm",'
$topWidget .= '{"uniqueId":"widgetCoreHomegetDonateForm",'
. '"parameters":{"module":"CoreHome","action":"getDonateForm"}},';
} else {
$topWidget = '{"uniqueId":"widgetCoreHomegetPromoVideo",'
$topWidget .= '{"uniqueId":"widgetCoreHomegetPromoVideo",'
. '"parameters":{"module":"CoreHome","action":"getPromoVideo"}},';
}
@ -81,19 +86,30 @@ class Dashboard extends \Piwik\Plugin
],
[
' . $topWidget . '
{"uniqueId":"widgetReferrersgetKeywords","parameters":{"module":"Referrers","action":"getKeywords"}},
{"uniqueId":"widgetReferrersgetWebsites","parameters":{"module":"Referrers","action":"getWebsites"}}
{"uniqueId":"widgetReferrersgetWebsites","parameters":{"module":"Referrers","action":"getWebsites"}},
{"uniqueId":"widgetVisitTimegetVisitInformationPerServerTime","parameters":{"module":"VisitTime","action":"getVisitInformationPerServerTime"}}
],
[
{"uniqueId":"widgetUserCountryMapvisitorMap","parameters":{"module":"UserCountryMap","action":"visitorMap"}},
{"uniqueId":"widgetUserSettingsgetBrowser","parameters":{"module":"UserSettings","action":"getBrowser"}},
{"uniqueId":"widgetDevicesDetectiongetBrowsers","parameters":{"module":"DevicesDetection","action":"getBrowsers"}},
{"uniqueId":"widgetReferrersgetSearchEngines","parameters":{"module":"Referrers","action":"getSearchEngines"}},
{"uniqueId":"widgetVisitTimegetVisitInformationPerServerTime","parameters":{"module":"VisitTime","action":"getVisitInformationPerServerTime"}},
{"uniqueId":"widgetExampleRssWidgetrssPiwik","parameters":{"module":"ExampleRssWidget","action":"rssPiwik"}}
]
]';
}
/**
* Allows other plugins to modify the default dashboard layout.
*
* @param string &$defaultLayout JSON encoded string of the default dashboard layout. Contains an
* array of columns where each column is an array of widgets. Each
* widget is an associative array w/ the following elements:
*
* * **uniqueId**: The widget's unique ID.
* * **parameters**: The array of query parameters that should be used to get this widget's report.
*/
Piwik::postEvent("Dashboard.changeDefaultDashboardLayout", array(&$defaultLayout));
$defaultLayout = $this->removeDisabledPluginFromLayout($defaultLayout);
return $defaultLayout;
@ -101,12 +117,10 @@ class Dashboard extends \Piwik\Plugin
public function getAllDashboards($login)
{
$dashboards = Db::fetchAll('SELECT iddashboard, name, layout
FROM ' . Common::prefixTable('user_dashboard') .
' WHERE login = ? ORDER BY iddashboard', array($login));
$dashboards = $this->getModel()->getAllDashboardsForUser($login);
$nameless = 1;
foreach ($dashboards AS &$dashboard) {
foreach ($dashboards as &$dashboard) {
if (empty($dashboard['name'])) {
$dashboard['name'] = Piwik::translate('Dashboard_DashboardOf', $login);
@ -188,43 +202,12 @@ class Dashboard extends \Piwik\Plugin
$layout = str_replace("\\\"", "\"", $layout);
$layout = str_replace("\n", "", $layout);
return Common::json_decode($layout, $assoc = false);
return json_decode($layout, $assoc = false);
}
public function encodeLayout($layout)
{
return Common::json_encode($layout);
}
public function addMenus()
{
MenuMain::getInstance()->add('Dashboard_Dashboard', '', array('module' => 'Dashboard', 'action' => 'embeddedIndex', 'idDashboard' => 1), true, 5);
if (!Piwik::isUserIsAnonymous()) {
$login = Piwik::getCurrentUserLogin();
$dashboards = $this->getAllDashboards($login);
$pos = 0;
foreach ($dashboards as $dashboard) {
MenuMain::getInstance()->add('Dashboard_Dashboard', $dashboard['name'], array('module' => 'Dashboard', 'action' => 'embeddedIndex', 'idDashboard' => $dashboard['iddashboard']), true, $pos);
$pos++;
}
}
}
public function addTopMenu()
{
$tooltip = false;
try {
$idSite = Common::getRequestVar('idSite');
$tooltip = Piwik::translate('Dashboard_TopLinkTooltip', Site::getNameFor($idSite));
} catch (Exception $ex) {
// if no idSite parameter, show no tooltip
}
$urlParams = array('module' => 'CoreHome', 'action' => 'index');
MenuTop::addEntry('Dashboard_Dashboard', $urlParams, true, 1, $isHTML = false, $tooltip);
return json_encode($layout);
}
public function getJsFiles(&$jsFiles)
@ -240,27 +223,22 @@ class Dashboard extends \Piwik\Plugin
{
$stylesheets[] = "plugins/CoreHome/stylesheets/dataTable.less";
$stylesheets[] = "plugins/Dashboard/stylesheets/dashboard.less";
$stylesheets[] = "plugins/Dashboard/stylesheets/widget.less";
}
public function deleteDashboardLayout($userLogin)
{
Db::query('DELETE FROM ' . Common::prefixTable('user_dashboard') . ' WHERE login = ?', array($userLogin));
$this->getModel()->deleteAllLayoutsForUser($userLogin);
}
public function install()
{
$dashboard = "login VARCHAR( 100 ) NOT NULL ,
iddashboard INT NOT NULL ,
name VARCHAR( 100 ) NULL DEFAULT NULL ,
layout TEXT NOT NULL,
PRIMARY KEY ( login , iddashboard )";
DbHelper::createTable('user_dashboard', $dashboard);
Model::install();
}
public function uninstall()
{
Db::dropTables(Common::prefixTable('user_dashboard'));
Model::uninstall();
}
public function getClientSideTranslationKeys(&$translationKeys)
@ -272,6 +250,8 @@ class Dashboard extends \Piwik\Plugin
$translationKeys[] = 'Dashboard_LoadingWidget';
$translationKeys[] = 'Dashboard_WidgetNotFound';
$translationKeys[] = 'Dashboard_DashboardCopied';
$translationKeys[] = 'Dashboard_Dashboard';
$translationKeys[] = 'Dashboard_RemoveDefaultDashboardNotPossible';
$translationKeys[] = 'General_Close';
$translationKeys[] = 'General_Refresh';
}

View file

@ -1,14 +1,12 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Dashboard;
use Piwik\View\UIControl;
/**
* Generates the HTML for the dashboard manager control.
*/
@ -20,9 +18,9 @@ class DashboardManagerControl extends DashboardSettingsControlBase
public function __construct()
{
parent::__construct();
$this->jsClass = "DashboardManagerControl";
$this->cssIdentifier = "dashboard-manager";
$this->cssIdentifier = "dashboard-manager piwikSelector";
$this->addDashboardActions();
$this->addGeneralActions();

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -22,8 +22,9 @@ abstract class DashboardSettingsControlBase extends UIControl
public function __construct()
{
parent::__construct();
$this->cssClass = "piwikTopControl dashboardSettings";
$this->cssClass = "borderedControl piwikTopControl dashboardSettings";
$this->htmlAttributes = array('piwik-expand-on-click' => '');
$this->dashboardActions = array();
$this->generalActions = array();
}

View file

@ -0,0 +1,61 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\Dashboard;
use Piwik\Db;
use Piwik\Menu\MenuReporting;
use Piwik\Menu\MenuTop;
use Piwik\Piwik;
use Piwik\Plugins\UsersManager\UserPreferences;
use Piwik\Site;
/**
*/
class Menu extends \Piwik\Plugin\Menu
{
public function configureReportingMenu(MenuReporting $menu)
{
$menu->addItem('Dashboard_Dashboard', '', array(), 5);
if (Piwik::isUserIsAnonymous()) {
$this->addDefaultDashboard($menu);
} else {
$login = Piwik::getCurrentUserLogin();
$dashboard = new Dashboard();
$dashboards = $dashboard->getAllDashboards($login);
if (empty($dashboards)) {
$this->addDefaultDashboard($menu);
} else {
$pos = 0;
foreach ($dashboards as $dashboard) {
$menu->addItem('Dashboard_Dashboard', $dashboard['name'], $this->urlForAction('embeddedIndex', array('idDashboard' => $dashboard['iddashboard'])), $pos);
$pos++;
}
}
}
}
private function addDefaultDashboard(MenuReporting $menu)
{
$menu->addItem('Dashboard_Dashboard', 'Dashboard_Dashboard', $this->urlForAction('embeddedIndex', array('idDashboard' => 1)));
}
public function configureTopMenu(MenuTop $menu)
{
$userPreferences = new UserPreferences();
$idSite = $userPreferences->getDefaultWebsiteId();
$tooltip = Piwik::translate('Dashboard_TopLinkTooltip', Site::getNameFor($idSite));
$urlParams = $this->urlForModuleActionWithDefaultUserParams('CoreHome', 'index') ;
$menu->addItem('Dashboard_Dashboard', null, $urlParams, 1, $tooltip);
}
}

View file

@ -0,0 +1,245 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Dashboard;
use Piwik\Common;
use Piwik\Db;
use Piwik\DbHelper;
use Piwik\WidgetsList;
class Model
{
private static $rawPrefix = 'user_dashboard';
private $table;
public function __construct()
{
$this->table = Common::prefixTable(self::$rawPrefix);
}
/**
* Returns the layout in the DB for the given user, or false if the layout has not been set yet.
* Parameters must be checked BEFORE this function call
*
* @param string $login
* @param int $idDashboard
*
* @return bool|string
*/
public function getLayoutForUser($login, $idDashboard)
{
$query = sprintf('SELECT layout FROM %s WHERE login = ? AND iddashboard = ?',
$this->table);
$bind = array($login, $idDashboard);
$layouts = Db::fetchAll($query, $bind);
return $layouts;
}
public function getAllDashboardsForUser($login)
{
$dashboards = Db::fetchAll('SELECT iddashboard, name, layout FROM ' . $this->table .
' WHERE login = ? ORDER BY iddashboard', array($login));
return $dashboards;
}
public function deleteAllLayoutsForUser($userLogin)
{
Db::query('DELETE FROM ' . $this->table . ' WHERE login = ?', array($userLogin));
}
/**
* Updates the name of a dashboard
*
* @param string $login
* @param int $idDashboard
* @param string $name
*/
public function updateDashboardName($login, $idDashboard, $name)
{
$bind = array($name, $login, $idDashboard);
$query = sprintf('UPDATE %s SET name = ? WHERE login = ? AND iddashboard = ?', $this->table);
Db::query($query, $bind);
}
/**
* Removes the dashboard with the given id
*/
public function deleteDashboardForUser($idDashboard, $login)
{
$query = sprintf('DELETE FROM %s WHERE iddashboard = ? AND login = ?', $this->table);
Db::query($query, array($idDashboard, $login));
}
/**
* Creates a new dashboard for the current user
* User needs to be logged in
*/
public function createNewDashboardForUser($login, $name, $layout)
{
$nextId = $this->getNextIdDashboard($login);
$query = sprintf('INSERT INTO %s (login, iddashboard, name, layout) VALUES (?, ?, ?, ?)', $this->table);
$bind = array($login, $nextId, $name, $layout);
Db::query($query, $bind);
return $nextId;
}
/**
* Saves the layout as default
*/
public function createOrUpdateDashboard($login, $idDashboard, $layout)
{
$bind = array($login, $idDashboard, $layout, $layout);
$query = sprintf('INSERT INTO %s (login, iddashboard, layout) VALUES (?,?,?) ON DUPLICATE KEY UPDATE layout=?',
$this->table);
Db::query($query, $bind);
}
private function getNextIdDashboard($login)
{
$nextIdQuery = sprintf('SELECT MAX(iddashboard)+1 FROM %s WHERE login = ?', $this->table);
$nextId = Db::fetchOne($nextIdQuery, array($login));
if (empty($nextId)) {
$nextId = 1;
}
return $nextId;
}
/**
* Records the layout in the DB for the given user.
*
* @param string $login
* @param int $idDashboard
* @param string $layout
*/
public function updateLayoutForUser($login, $idDashboard, $layout)
{
$bind = array($login, $idDashboard, $layout, $layout);
$query = sprintf('INSERT INTO %s (login, iddashboard, layout) VALUES (?,?,?) ON DUPLICATE KEY UPDATE layout=?',
$this->table);
Db::query($query, $bind);
}
public static function install()
{
$dashboard = "login VARCHAR( 100 ) NOT NULL ,
iddashboard INT NOT NULL ,
name VARCHAR( 100 ) NULL DEFAULT NULL ,
layout TEXT NOT NULL,
PRIMARY KEY ( login , iddashboard )";
DbHelper::createTable(self::$rawPrefix, $dashboard);
}
public static function uninstall()
{
Db::dropTables(Common::prefixTable(self::$rawPrefix));
}
/**
* Replaces widgets on the given dashboard layout with other ones
*
* It uses the given widget definitions to find the old and to create the new widgets
* Each widget is defined with an array containing the following information
* array (
* 'module' => string
* 'action' => string
* 'params' => array()
* )
*
* if $newWidget does not contain a widget definition at the current position,
* the old widget will simply be removed
*
* @param array $oldWidgets array containing widget definitions
* @param array $newWidgets array containing widget definitions
*/
public static function replaceDashboardWidgets($dashboardLayout, $oldWidgets, $newWidgets)
{
if (empty($dashboardLayout) || !isset($dashboardLayout->columns)) {
return $dashboardLayout;
}
$newColumns = array();
foreach ($dashboardLayout->columns as $id => $column) {
$newColumn = array();
foreach ($column as $widget) {
foreach ($oldWidgets AS $pos => $oldWidgetData) {
$oldWidgetId = WidgetsList::getWidgetUniqueId($oldWidgetData['module'], $oldWidgetData['action'], $oldWidgetData['params']);
if (empty($newWidgets[$pos])) {
continue 2;
}
$newWidget = $newWidgets[$pos];
if ($widget->uniqueId == $oldWidgetId) {
$newWidgetId = WidgetsList::getWidgetUniqueId($newWidget['module'], $newWidget['action'], $newWidget['params']);
// is new widget already is on dashboard just remove the old one
if (self::layoutContainsWidget($dashboardLayout, $newWidgetId)) {
continue 2;
}
$widget->uniqueId = $newWidgetId;
$widget->parameters->module = $newWidget['module'];
$widget->parameters->action = $newWidget['action'];
foreach ($newWidget['params'] as $key => $value) {
$widget->parameters->{$key} = $value;
}
}
}
$newColumn[] = $widget;
}
$newColumns[] = $newColumn;
}
$dashboardLayout->columns = $newColumns;
return $dashboardLayout;
}
/**
* Checks if a given dashboard layout contains a given widget
*
* @param $dashboardLayout
* @param $widgetId
* @return bool
*/
protected static function layoutContainsWidget($dashboardLayout, $widgetId)
{
if (!isset($dashboardLayout->columns)) {
return false;
}
foreach ($dashboardLayout->columns as $id => $column) {
foreach ($column as $widget) {
if ($widget->uniqueId == $widgetId) {
return true;
}
}
}
return false;
}
}

View file

@ -1,5 +1,5 @@
/*!
* Piwik - Web Analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -8,11 +8,12 @@
function initDashboard(dashboardId, dashboardLayout) {
$('.dashboardSettings').show();
initTopControls();
// Embed dashboard
if (!$('#topBars').length) {
if (!$('#header .navbar-right').length) {
$('.dashboardSettings').after($('#Dashboard'));
$('#Dashboard_embeddedIndex_' + dashboardId).addClass('sfHover');
$('#Dashboard_embeddedIndex_' + dashboardId).addClass('sfActive');
}
widgetsHelper.getAvailableWidgets();
@ -167,21 +168,15 @@ function copyDashboardToUser() {
// on menu item click, trigger action event on this
var self = this;
this.$element.on('click', 'ul.submenu li[data-action]', function (e) {
self.$element.toggleClass('visible');
$(self).trigger($(this).attr('data-action'));
if (!$(this).attr('disabled')) {
self.$element.removeClass('expanded');
$(self).trigger($(this).attr('data-action'));
}
});
// open manager on open
this.$element.on('click', function (e) {
if ($(e.target).is('.dashboardSettings,.dashboardSettings>span')) {
self.$element.toggleClass('visible');
// fix position
self.$element
.find('.widgetpreview-widgetlist')
.css('paddingTop', self.$element.find('.widgetpreview-categorylist').parent('li').position().top);
if ($(e.target).is('.dashboardSettings') || $(e.target).closest('.dashboardSettings').length) {
self.onOpen();
}
});
@ -192,7 +187,7 @@ function copyDashboardToUser() {
&& !$(e.target).is('.dashboardSettings')
) {
self.$element.widgetPreview('reset');
self.$element.removeClass('visible');
self.$element.removeClass('expanded');
}
};
@ -205,7 +200,7 @@ function copyDashboardToUser() {
},
onSelect: function (widgetUniqueId) {
var widget = widgetsHelper.getWidgetObjectFromUniqueId(widgetUniqueId);
self.$element.removeClass('visible');
self.$element.removeClass('expanded');
self.widgetSelected(widget);
},
@ -278,15 +273,29 @@ function copyDashboardToUser() {
$.extend(DashboardManagerControl.prototype, DashboardSettingsControlBase.prototype, {
onOpen: function () {
if ($('#dashboardWidgetsArea').dashboard('isDefaultDashboard')) {
$('.removeDashboardLink', this.$element).hide();
if ($('#dashboardWidgetsArea').dashboard('isDefaultDashboard')) {
$('[data-action=removeDashboard]', this.$element).attr('disabled', 'disabled');
$(this.$element).tooltip({
items: '[data-action=removeDashboard]',
show: false,
hide: false,
track: true,
content: function() {
return _pk_translate('Dashboard_RemoveDefaultDashboardNotPossible')
},
tooltipClass: 'small'
});
} else {
$('.removeDashboardLink', this.$element).show();
}
$('[data-action=removeDashboard]', this.$element).removeAttr('disabled');
// try to remove tooltip if any
try {
$(this.$element).tooltip('destroy');
} catch (e) { }
}
},
hide: function () {
this.$element.removeClass('visible');
this.$element.removeClass('expanded');
},
isWidgetAvailable: function (widgetUniqueId) {

View file

@ -1,5 +1,5 @@
/*!
* Piwik - Web Analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -297,8 +297,49 @@
}
}
for (var i = 0; i < columnCount; i++) {
$('.col', dashboardElement)[i].className = 'col width-' + columnWidth[i];
switch (layout) {
case '100':
$('.col', dashboardElement).removeClass()
.addClass('col col-sm-12');
break;
case '50-50':
$('.col', dashboardElement).removeClass()
.addClass('col col-sm-6');
break;
case '67-33':
$('.col', dashboardElement)[0].className = 'col col-sm-8';
$('.col', dashboardElement)[1].className = 'col col-sm-4';
break;
case '33-67':
$('.col', dashboardElement)[0].className = 'col col-sm-4';
$('.col', dashboardElement)[1].className = 'col col-sm-8';
break;
case '33-33-33':
$('.col', dashboardElement)[0].className = 'col col-sm-4';
$('.col', dashboardElement)[1].className = 'col col-sm-4';
$('.col', dashboardElement)[2].className = 'col col-sm-4';
break;
case '40-30-30':
$('.col', dashboardElement)[0].className = 'col col-sm-6';
$('.col', dashboardElement)[1].className = 'col col-sm-3';
$('.col', dashboardElement)[2].className = 'col col-sm-3';
break;
case '30-40-30':
$('.col', dashboardElement)[0].className = 'col col-sm-3';
$('.col', dashboardElement)[1].className = 'col col-sm-6';
$('.col', dashboardElement)[2].className = 'col col-sm-3';
break;
case '30-30-40':
$('.col', dashboardElement)[0].className = 'col col-sm-3';
$('.col', dashboardElement)[1].className = 'col col-sm-3';
$('.col', dashboardElement)[2].className = 'col col-sm-6';
break;
case '25-25-25-25':
$('.col', dashboardElement)[0].className = 'col col-sm-3';
$('.col', dashboardElement)[1].className = 'col col-sm-3';
$('.col', dashboardElement)[2].className = 'col col-sm-3';
$('.col', dashboardElement)[3].className = 'col col-sm-3';
break;
}
makeWidgetsSortable();
@ -436,25 +477,26 @@
return $(this).attr('id').indexOf('Dashboard_embeddedIndex') == 0;
}).remove();
if (dashboards.length === 0) {
dashboards = [{iddashboard: 1, name: _pk_translate('Dashboard_Dashboard')}];
}
if (dashboards.length > 1
|| dashboardMenuListItems.length >= 1
) {
dashboardMenuList.show();
var items = [];
for (var i = 0; i < dashboards.length; i++) {
var $link = $('<a/>').attr('data-idDashboard', dashboards[i].iddashboard).text(dashboards[i].name);
var $link = $('<a/>').attr('data-idDashboard', dashboards[i].iddashboard).text(dashboards[i].name).addClass('item title');
var $li = $('<li/>').attr('id', 'Dashboard_embeddedIndex_' + dashboards[i].iddashboard)
.addClass('dashboardMenuItem').append($link);
items.push($li);
if (dashboards[i].iddashboard == dashboardId) {
dashboardName = dashboards[i].name;
$li.addClass('sfHover');
$li.addClass('sfActive');
}
}
dashboardMenuList.prepend(items);
} else {
dashboardMenuList.hide();
}
dashboardMenuList.find('a[data-idDashboard]').click(function (e) {
@ -465,13 +507,13 @@
if (typeof piwikMenu != 'undefined') {
piwikMenu.activateMenu('Dashboard', 'embeddedIndex');
}
$('#Dashboard ul li').removeClass('sfHover');
$('#Dashboard ul li').removeClass('sfActive');
if ($(dashboardElement).length) {
$(dashboardElement).dashboard('loadDashboard', idDashboard);
} else {
broadcast.propagateAjax('module=Dashboard&action=embeddedIndex&idDashboard=' + idDashboard);
}
$(this).closest('li').addClass('sfHover');
$(this).closest('li').addClass('sfActive');
});
};

View file

@ -1,5 +1,5 @@
/*!
* Piwik - Web Analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -118,9 +118,12 @@
var self = this, currentWidget = this.element;
function onWidgetLoadedReplaceElementWithContent(loadedContent) {
$('.widgetContent', currentWidget).html(loadedContent);
$('.widgetContent', currentWidget).removeClass('loading');
$('.widgetContent', currentWidget).trigger('widget:create', [self]);
var $widgetContent = $('.widgetContent', currentWidget);
$widgetContent.html(loadedContent);
piwikHelper.compileAngularComponents($widgetContent);
$widgetContent.removeClass('loading');
$widgetContent.trigger('widget:create', [self]);
}
// Reading segment from hash tag (standard case) or from the URL (when embedding dashboard)
@ -134,7 +137,19 @@
}
var params = $.extend(this.widgetParameters, overrideParams || {});
widgetsHelper.loadWidgetAjax(this.uniqueId, params, onWidgetLoadedReplaceElementWithContent);
widgetsHelper.loadWidgetAjax(this.uniqueId, params, onWidgetLoadedReplaceElementWithContent, function (deferred, status) {
if (status == 'abort' || !deferred || deferred.status < 400 || deferred.status >= 600) {
return;
}
$('.widgetContent', currentWidget).removeClass('loading');
var errorMessage = _pk_translate('General_ErrorRequest', ['', '']);
if ($('#loadingError').html()) {
errorMessage = $('#loadingError').html();
}
$('.widgetContent', currentWidget).html('<div class="widgetLoadingError">' + errorMessage + '</div>');
});
return this;
},
@ -283,6 +298,8 @@
var width = Math.floor($('body').width() * 0.7);
var isFooterExpanded = $('.dataTableFeatures', this.element).hasClass('expanded');
var self = this;
this.element.dialog({
title: '',
@ -293,6 +310,9 @@
autoOpen: true,
close: function (event, ui) {
self.isMaximised = false;
if (!isFooterExpanded) {
$('.dataTableFeatures', self.element).removeClass('expanded');
}
$('body').off('.dashboardWidget');
$(this).dialog("destroy");
$('#' + self.uniqueId + '-placeholder').replaceWith(this);
@ -303,6 +323,7 @@
}
});
this.element.find('div.piwik-graph').trigger('resizeGraph');
$('.dataTableFeatures', this.element).addClass('expanded');
var currentWidget = this.element;
$('body').on('click.dashboardWidget', function (ev) {
@ -328,4 +349,4 @@
}
});
})(jQuery);
})(jQuery);

View file

@ -1,5 +1,5 @@
/*!
* Piwik - Web Analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -72,7 +72,7 @@ widgetsHelper.getWidgetNameFromUniqueId = function (uniqueId) {
* @param {function} onWidgetLoadedCallback callback to be executed after widget is loaded
* @return {object}
*/
widgetsHelper.loadWidgetAjax = function (widgetUniqueId, widgetParameters, onWidgetLoadedCallback) {
widgetsHelper.loadWidgetAjax = function (widgetUniqueId, widgetParameters, onWidgetLoadedCallback, onWidgetErrorCallback) {
var disableLink = broadcast.getValueFromUrl('disableLink');
if (disableLink.length) {
widgetParameters['disableLink'] = disableLink;
@ -83,6 +83,9 @@ widgetsHelper.loadWidgetAjax = function (widgetUniqueId, widgetParameters, onWid
var ajaxRequest = new ajaxHelper();
ajaxRequest.addParams(widgetParameters, 'get');
ajaxRequest.setCallback(onWidgetLoadedCallback);
if (onWidgetErrorCallback) {
ajaxRequest.setErrorCallback(onWidgetErrorCallback);
}
ajaxRequest.setFormat('html');
ajaxRequest.send(false);
return ajaxRequest;
@ -224,7 +227,12 @@ widgetsHelper.loadWidgetAjax = function (widgetUniqueId, widgetParameters, onWid
if ($('.' + settings.categorylistClass + ' .' + settings.choosenClass, widgetPreview).length) {
var position = $('.' + settings.categorylistClass + ' .' + settings.choosenClass, widgetPreview).position().top -
$('.' + settings.categorylistClass, widgetPreview).position().top;
$('.' + settings.categorylistClass, widgetPreview).position().top +
$('.dashboard-manager .addWidget').outerHeight();
if (!$('#content.admin').length) {
position += 10; // + padding defined in dashboard view
}
$('.' + settings.widgetlistClass, widgetPreview).css('top', position);
$('.' + settings.widgetlistClass, widgetPreview).css('marginBottom', position);
@ -278,6 +286,7 @@ widgetsHelper.loadWidgetAjax = function (widgetUniqueId, widgetParameters, onWid
$('li:not(.' + settings.unavailableClass + ')', widgetList).on('click', function () {
if (!$('.widgetLoading', widgetPreview).length) {
settings.onSelect($(this).attr('uniqueid'));
$(widgetPreview).closest('.dashboard-manager').removeClass('expanded');
if (settings.resetOnSelect) {
resetWidgetPreview(widgetPreview);
}
@ -338,6 +347,7 @@ widgetsHelper.loadWidgetAjax = function (widgetUniqueId, widgetParameters, onWid
settings.onPreviewLoaded(widgetUniqueId, widgetElement);
$('.' + settings.widgetpreviewClass + ' .widgetTop', widgetPreview).on('click', function () {
settings.onSelect(widgetUniqueId);
$(widgetPreview).closest('.dashboard-manager').removeClass('expanded');
if (settings.resetOnSelect) {
resetWidgetPreview(widgetPreview);
}

View file

@ -0,0 +1,11 @@
{
"Dashboard": {
"AddPreviewedWidget": "ቅድመ እይታ የተሰጠውን widget ወደ ዳሽቦርዱ ጨምር",
"Dashboard": "ዳሽቦርድ",
"DeleteWidgetConfirm": "እርግጠኛ ነህ ይህ widget ከዳሽቦርድ ይሰረዝ?",
"LoadingWidget": "widget በመጫን ላይ, እባክዎ ይጠበቁ...",
"SelectWidget": "ወደ ዳሽቦርድ የሚጨመረውን widget ምረጥ",
"WidgetNotFound": "Widget አልተገኘም",
"WidgetPreview": "የWidget ቅድመእይታ"
}
}

View file

@ -0,0 +1,36 @@
{
"Dashboard": {
"AddAWidget": "أضف عنصر واجهة",
"AddPreviewedWidget": "إضغط لتضيف عنصر واجهة إلى لوحة المعلومات",
"ChangeDashboardLayout": "تغيير تخطيط لوحة المعلومات",
"CopyDashboardToUser": "إنسخ لوحة المعلومات إلى مستخدِم",
"CreateNewDashboard": "إنشاء لوحة معلومات جديدة",
"Dashboard": "لوحة المعلومات",
"DashboardCopied": "تم نسخ لوحة المعلومات الحالية إلى المستخدم المحدَّد بنجاح.",
"DashboardEmptyNotification": "اللوحة الرئيسية فارغة تماماً. ابدأ بإضافة بعد التطبيقات أو قم بتنضيد اللوحة الرئيسية إلى الإعدادات الافتراضية.",
"DashboardName": "اسم اللوحة:",
"DashboardOf": "لوحة معلومات %s",
"DefaultDashboard": "اللوحة الافتراضية - تستخدم المجموعة الافتراضية من التطبيقات وتخطيط الأعمدة.",
"DeleteWidgetConfirm": "هل ترغب حقاً في حذف لوحة الأداة هذه من لوحة التحكم.",
"EmptyDashboard": "لوحة المعلومات فارغة - إختر عناصر التحكم التي تفضّلها",
"LoadingWidget": "جاري تحميل الأداة، الرجاء الانتظار...",
"ManageDashboard": "إدارة اللوحة",
"Maximise": "تكبير",
"Minimise": "تصغير",
"NotUndo": "لن يمكنك التراجع عن هذه العملية.",
"PluginDescription": "لوحة معلومات تحليلات الويب الخاصة بك. خصّص لوحة معلوماتك بإضافة عناصر واجهة جديدة وسحبها وإسقاطها أينما شئت ، بإمكانك أيضاً تغيير تخطيط أعمدة لوحة المعلومات. يمكن لكل مستخدم إدارة لوحة معلومات يخصصها كما يشاء.",
"RemoveDashboard": "إزالة اللوحة",
"RemoveDashboardConfirm": "هل أنت متأكد من رغبتك حذف لوحة المعلومات \"%s\" ؟",
"RenameDashboard": "إعادة تسمية اللوحة",
"ResetDashboard": "أعد ضبط لوحة المعلومات",
"ResetDashboardConfirm": "هل ترغب حقاً في تنضيد تخطيط اللوحة الرئيسية ومجموعة التطبيقات المعروضة فيها إلى الافتراضية؟",
"SelectDashboardLayout": "فضلاً إختر التخطيط الجديد للوحة المعلومات",
"SelectWidget": "اختر لوحة الأداة لإضافتها للوحة التحكم",
"SetAsDefaultWidgets": "اضبط كمجموعة التطبيقات الافتراضية",
"SetAsDefaultWidgetsConfirm": "هل أنت متأكد أنك تريد جعل عناصر الواجهة المختارة حالياً وتخطيط لوحة المعلومات هذا القالب الافتراضي للوحة المعلومات ؟",
"SetAsDefaultWidgetsConfirmHelp": "سيتم استخدام مجموعة التطبيقات هذه ومخطط أعمدة اللوحة عند إنشاء لوحات جديدة أو عند استخدام خاصية \"%s\".",
"TopLinkTooltip": "عرض تقارير إحصاءات الويب لـ %s",
"WidgetNotFound": "لم يتم العثور على الأداة",
"WidgetPreview": "معاينة لوحة الأداة"
}
}

View file

@ -0,0 +1,12 @@
{
"Dashboard": {
"AddPreviewedWidget": "Дадаць предпросмотренный віджэт на інформпанель",
"Dashboard": "Інфармацыйная панэль",
"DeleteWidgetConfirm": "Вы ўпэўнены, што жадаеце выдаліць гэты віджэт з інфармацыйнай панэлі?",
"LoadingWidget": "Загрузка віджэта, калі ласка пачакайце...",
"Maximise": "Максімалізаваць",
"SelectWidget": "Абярыце віджэт для дадання на інформпанель",
"WidgetNotFound": "Віджэт не знойдзены",
"WidgetPreview": "Прадпрагляд віджэта"
}
}

View file

@ -0,0 +1,36 @@
{
"Dashboard": {
"AddAWidget": "Добави нова джаджа",
"AddPreviewedWidget": "Добави джаджата на таблото",
"ChangeDashboardLayout": "Сменете изледа на таблото",
"CopyDashboardToUser": "Копиране на табло при потребител",
"CreateNewDashboard": "Направете ново табло",
"Dashboard": "Табло",
"DashboardCopied": "Настоящото табло е успешно копирано при избрания потребител.",
"DashboardEmptyNotification": "Вашето табло не съдържа никакви джаджи. Започнете с добавяне на някои джаджи или просто нулирайте таблото, за да изберете джаджите по подразбиране.",
"DashboardName": "Име на табло:",
"DashboardOf": "Табло за %s",
"DefaultDashboard": "Табло по подразбиране - Използвайте джаджите по подразбиране и изгледа на колоните.",
"DeleteWidgetConfirm": "Наистина ли искате да изтриете тази джаджа от таблото?",
"EmptyDashboard": "Изпразнете таблото - Изберете любимите си джаджи",
"LoadingWidget": "Зарежда джаджата, почакайте...",
"ManageDashboard": "Управлявате таблото",
"Maximise": "Максимизиране",
"Minimise": "Минимизиране",
"NotUndo": "Вие няма да можете да отмените тази операция",
"PluginDescription": "Вашето табло за уеб анализи. Настройте вашия панел добавяйки нови джаджи, които можете да ги влачите, също така променяйки оформлението на колоните. Всеки потребител поотделно може да настрои своето табло.",
"RemoveDashboard": "Премахнете таблото",
"RemoveDashboardConfirm": "Сигурни ли сте че искате да премахнете таблото \"%s\"?",
"RenameDashboard": "Сменете името на таблото",
"ResetDashboard": "Зареди отново таблото",
"ResetDashboardConfirm": "Сигурен ли сте че искате да заредите отново плана на таблото с избраните по подразбиране джаджи?",
"SelectDashboardLayout": "Моля, изберете Вашият нов изглед на табло",
"SelectWidget": "Изберете джаджа, която да добавите на таблото",
"SetAsDefaultWidgets": "Поставете по подразбиране избора на джаджи",
"SetAsDefaultWidgetsConfirm": "Сигурни ли сте, че искате да настроите настоящата селекция на джаджи и оформление на таблото по подразбиране?",
"SetAsDefaultWidgetsConfirmHelp": "Селекцията на джаджи и колоните на изгледа на таблото ще бъдат използвани, когато потребителят създаде ново табло, или когато \"%s\" функция е използвана.",
"TopLinkTooltip": "Вижте доклада за уеб анализи за %s.",
"WidgetNotFound": "Несъществуваща джаджа",
"WidgetPreview": "Преглед на джаджата"
}
}

View file

@ -0,0 +1,9 @@
{
"Dashboard": {
"CreateNewDashboard": "নতুন ড্যাশবোর্ড তৈরি করুন",
"Dashboard": "ড্যাশবোর্ড",
"DashboardName": "ড্যাশবোর্ডের নাম:",
"RemoveDashboard": "ড্যাশবোর্ড মুছে ফেলুন",
"RenameDashboard": "ড্যাশবোর্ডের নাম পরিবর্তন"
}
}

View file

@ -0,0 +1,7 @@
{
"Dashboard": {
"Dashboard": "Kontrolna ploča",
"Maximise": "Maksimiziraj",
"Minimise": "Minimiziraj"
}
}

View file

@ -0,0 +1,36 @@
{
"Dashboard": {
"AddAWidget": "Afegir un Giny",
"AddPreviewedWidget": "Afegeix el giny al tauler",
"ChangeDashboardLayout": "Canviar el disseny del tauler",
"CopyDashboardToUser": "Copiar tauler a l'usuari",
"CreateNewDashboard": "Crear un nou tauler",
"Dashboard": "Tauler",
"DashboardCopied": "S'ha copiat correctament el tauler a l'usuari seleccionat",
"DashboardEmptyNotification": "El vostre tauler no conté cap giny. Comenceu per afegir alguns ginys o restablieu el tauler a la selecció de ginys per defecte.",
"DashboardName": "Nom del tauler:",
"DashboardOf": "Tauler de %s",
"DefaultDashboard": "Tauler per defecte - Utilitzant la selecció de ginys i l'estructura de columnes per defecte",
"DeleteWidgetConfirm": "Realment voleu esborrar aquest giny?",
"EmptyDashboard": "Tauler buit - Seleccioneu els vostres ginys preferits",
"LoadingWidget": "S'està carregant el giny…",
"ManageDashboard": "Administrar tauler",
"Maximise": "Maximitza",
"Minimise": "Minimitza",
"NotUndo": "No podreu desfer aquesta operació",
"PluginDescription": "El teu taulell d'analítica web. Personalitza el teu taulell afegint nous ginys, arrossega i solta per a moure'ls i canvia l'estructura de columnes. Cada usuari pot tenir el seu taulell personalitzat.",
"RemoveDashboard": "Elimina el tauler",
"RemoveDashboardConfirm": "Esteu segurs que voleu eliminar el tauler \"%s\"?",
"RenameDashboard": "Reanomena el tauler",
"ResetDashboard": "Reinicialitza el tauler",
"ResetDashboardConfirm": "Esteu segurs que voleu reiniciar la disposició del vostre tauler a la selecció de ginys per defecte?",
"SelectDashboardLayout": "Seleccioneu la nova disposició del vostre tauler",
"SelectWidget": "Escolliu el giny que voleu afegir a la consola",
"SetAsDefaultWidgets": "Marca com a selecció de ginys per defecte.",
"SetAsDefaultWidgetsConfirm": "Esteu segurs que voleu definir la selecció de ginys i la disposició del tauler actuals per a la plantilla de tauler per defecte?",
"SetAsDefaultWidgetsConfirmHelp": "Aquesta selecció de ginys i la disposició de columnes del tauler es faran servir quan qualsevol usuari crei un nou tauler o quan s'utiltiza la funció \"%s\".",
"TopLinkTooltip": "Mostra els informes d'analítica web per %s.",
"WidgetNotFound": "Aquest giny no s'ha trobat",
"WidgetPreview": "Previsualitza el giny"
}
}

View file

@ -0,0 +1,37 @@
{
"Dashboard": {
"AddAWidget": "Přidat widget",
"AddPreviewedWidget": "Přidat widget v náhledu na nástěnku",
"ChangeDashboardLayout": "Změnit rozvržení nástěnky",
"CopyDashboardToUser": "Zkopírovat přehled uživateli",
"CreateNewDashboard": "Vytvořit novou nástěnku",
"Dashboard": "Nástěnka",
"DashboardCopied": "Přehled byl úspěšně zkopírován vybranému uživateli.",
"DashboardEmptyNotification": "Vaše nástěnka neobsahuje žádné widgety. Nějaké přidejte, nebo obnovte výchozí výběr widgetů na nástěnce.",
"DashboardName": "Jméno nástěnky:",
"DashboardOf": "Nástěnka %s",
"DefaultDashboard": "Výchozí nástěnka - používáte výchozí rozvržení nástěnky",
"DeleteWidgetConfirm": "Opravdu chcete odstranit tento widget z nástěnky?",
"EmptyDashboard": "Prázdná nástěnka - vyberte si své oblíbené widgety",
"LoadingWidget": "Načítání widgetu, chvíli strpení...",
"ManageDashboard": "Správa nástěnky",
"Maximise": "Maximalizovat",
"Minimise": "Minimalizovat",
"NotUndo": "Tuto operaci nemůžete vrátit zpět.",
"PluginDescription": "Vaše nástěnka analýzy webu. Přizpůsobte si vaši nástěnku přidáním nových widgetů, jejich přesunutím nebo změnou rozvržení sloupců. Každý uživatel může přizpůsobit svou vlastní nástěnku.",
"RemoveDashboard": "Odstranit nástěnku",
"RemoveDashboardConfirm": "Opravdu chcete odstranit nástěnku: %s?",
"RemoveDefaultDashboardNotPossible": "Výchozí nástěnka nemůže být odstraněna",
"RenameDashboard": "Přejmenovat nástěnku",
"ResetDashboard": "Obnovit nástěnku",
"ResetDashboardConfirm": "Opravdu chcete obnovit nastavení nástěnky do továrního stavu?",
"SelectDashboardLayout": "Prosím vyberte nové rozvržení nástěnky",
"SelectWidget": "Zvolte widget pro přidání na nástěnku",
"SetAsDefaultWidgets": "Nastavit výchozí výběr widgetů",
"SetAsDefaultWidgetsConfirm": "Opravdu chcete nastavit toto rozvržení widgetů jako výchozí?",
"SetAsDefaultWidgetsConfirmHelp": "Tyto widgety a jejich rozvržení budou použity vždy, když někdo vytvoří novou nástěnku nebo použije vlastnost %s.",
"TopLinkTooltip": "Zobraz analytické hlášení webu pro %s.",
"WidgetNotFound": "Widget nenalezen",
"WidgetPreview": "Náhled widgetu"
}
}

View file

@ -0,0 +1,5 @@
{
"Dashboard": {
"Dashboard": "Dangosfwrdd"
}
}

Some files were not shown because too many files have changed in this diff Show more