Skip to content
Extraits de code Groupes Projets
Valider e4517efd rédigé par Julien Rouviere's avatar Julien Rouviere
Parcourir les fichiers

-Some refactoring

-Some design improvement in the menu
-Better draft for the widget selection menu

git-svn-id: http://dev.piwik.org/svn/trunk@264 59fd770c-687e-43c8-a1e3-f5a4ff64c105
parent e18c19f8
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
*/ */
abstract class Piwik_ViewDataTable_Graph extends Piwik_ViewDataTable abstract class Piwik_ViewDataTable_Graph extends Piwik_ViewDataTable
{ {
protected $width = 400; protected $width = '100%';
protected $height = 250; protected $height = 250;
...@@ -144,8 +144,8 @@ class Piwik_ViewDataTable_Graph_ChartEvolution extends Piwik_ViewDataTable_Graph ...@@ -144,8 +144,8 @@ class Piwik_ViewDataTable_Graph_ChartEvolution extends Piwik_ViewDataTable_Graph
function __construct() function __construct()
{ {
$this->valueParameterViewDataTable = 'generateDataChartEvolution'; $this->valueParameterViewDataTable = 'generateDataChartEvolution';
$this->width=700; $this->width='100%';
$this->height=150; $this->height=250;
} }
......
...@@ -24,7 +24,7 @@ class Piwik_Dashboard_Controller extends Piwik_Controller ...@@ -24,7 +24,7 @@ class Piwik_Dashboard_Controller extends Piwik_Controller
{ {
parent::__construct(); parent::__construct();
//FIXME: copy paste of Home controller => should be refactored //TODO: copy paste of Home controller => should be refactored
//in a 'master' controller for statistics (tracs #91) //in a 'master' controller for statistics (tracs #91)
$this->strDate = Piwik_Common::getRequestVar('date', 'yesterday','string'); $this->strDate = Piwik_Common::getRequestVar('date', 'yesterday','string');
...@@ -56,8 +56,8 @@ class Piwik_Dashboard_Controller extends Piwik_Controller ...@@ -56,8 +56,8 @@ class Piwik_Dashboard_Controller extends Piwik_Controller
header("Location:?module=Dashboard&action=index&idSite=1&period=day&date=yesterday"); header("Location:?module=Dashboard&action=index&idSite=1&period=day&date=yesterday");
} }
public function index() public function embeddedIndex()
{ {
$view = new Piwik_View('Dashboard/templates/index.tpl'); $view = new Piwik_View('Dashboard/templates/index.tpl');
$this->setGeneralVariablesView($view); $this->setGeneralVariablesView($view);
if(isset($_SESSION['layout'])) if(isset($_SESSION['layout']))
...@@ -66,13 +66,21 @@ class Piwik_Dashboard_Controller extends Piwik_Controller ...@@ -66,13 +66,21 @@ class Piwik_Dashboard_Controller extends Piwik_Controller
echo $view->render(); echo $view->render();
} }
public function index()
{
//add the header for stand-alone mode
$view = new Piwik_View('Dashboard/templates/header.tpl');
echo $view->render();
$this->embeddedIndex();
}
public function saveLayout() public function saveLayout()
{ {
$layout = Piwik_Common::getRequestVar('layout'); $layout = Piwik_Common::getRequestVar('layout');
$_SESSION['layout'] = $layout; $_SESSION['layout'] = $layout;
} }
//FIXME: copy paste of Home controller => should be refactored //TODO: copy paste of Home controller => should be refactored
//in a 'master' controller for statistics (tracs #91) //in a 'master' controller for statistics (tracs #91)
protected function setGeneralVariablesView($view) protected function setGeneralVariablesView($view)
{ {
...@@ -101,4 +109,5 @@ class Piwik_Dashboard_Controller extends Piwik_Controller ...@@ -101,4 +109,5 @@ class Piwik_Dashboard_Controller extends Piwik_Controller
$view->sites = Piwik_SitesManager_API::getSitesWithAtLeastViewAccess(); $view->sites = Piwik_SitesManager_API::getSitesWithAtLeastViewAccess();
$view->url = Piwik_Url::getCurrentUrl(); $view->url = Piwik_Url::getCurrentUrl();
} }
} }
\ No newline at end of file
...@@ -23,3 +23,5 @@ class Piwik_Dashboard extends Piwik_Plugin ...@@ -23,3 +23,5 @@ class Piwik_Dashboard extends Piwik_Plugin
); );
} }
} }
Piwik_AddMenu('Dashboard', '1', array('module' => 'Dashboard', 'action' => 'embeddedIndex'));
//there is a problem with loop when we extends javascript Array
function contains(array, searchElem) {
for(var i=0; i<array.length; i++) {
if (array[i]==searchElem) {
return true;
}
}
return false;
}
//fire-up everything on DOM ready event
$(document).ready(
function()
{
//generate dashboard layout and load every displayed widgets
generateLayout();
//build the menu
buildWidgetChooserMenu();
//setup widget dynamic behaviour
setupWidgetSortable();
}
);
function buildWidgetChooserMenu()
{
//menu show button
$('.button#addWidget').click(function(){
$(this).hide();
filterOutAlreadyLoadedWidget();
$('.menu#widgetChooser').show('slow');
});
//load menu widgets list
var menu = $('.menu#widgetChooser');
for(var plugin in piwik.availableWidgets)
{
var widgets = piwik.availableWidgets[plugin];
for(var i in widgets)
{
var subMenu1 = $('.subMenu1', menu);
var subMenu2 = $('.subMenu2', menu);
var exist = $('.subMenuItem#'+plugin, subMenu1);
if(exist.size()==0)
{
subMenu1.append('<div class="subMenuItem" id="'+plugin+'">'+plugin+'<div>');
subMenu2.append('<div class="subMenuItem" id="'+plugin+'"><div>');
}
var sm2Div = $('.subMenuItem#'+plugin, subMenu2);
sm2Div.append('<div class="button menuItem" pluginToLoad="'+plugin+'" actionToLoad="'+widgets[i][1]+'">'+widgets[i][0] + ' => (' + plugin +'.'+ widgets[i][1] + ')</div>');
}
}
$('.subMenuItem', subMenu2).hide();
bindMenuEvents(menu);
}
//disable widgets that are already in the dashboard
function filterOutAlreadyLoadedWidget()
{
//list loaded widget:
var widgets = new Array;
$('.col').each(
function()
{
widgets = widgets.concat(getWidgetInDom(this));
}
);
$('.menu#widgetChooser .menuItem').each(function(){
var plugin = $(this).attr('pluginToLoad');
var action = $(this).attr('actionToLoad');
if(contains(widgets, plugin+'.'+action))
{
$(this).hide();
}
else
{
$(this).show();
}
});
}
function bindMenuEvents(menu)
{
$('.subMenu1 .subMenuItem', menu).each(function(){
var plugin = $(this).attr('id');
var item = $('.subMenu2 .subMenuItem#'+plugin);
$(this).hover(
function()
{
$('.subMenu1 .subMenuItem', menu).removeClass('menuSelected');
$('.subMenu2 .subMenuItem', menu).hide();
$(this).addClass('menuSelected');
item.show();
},
function()
{
});
});
$('.menuItem', menu).click(function(){
var plugin = $(this).attr('pluginToLoad');
var action = $(this).attr('actionToLoad');
var exists = $('.parentDiv#'+action);
if(exists.size()>0)
{
alert('Widget already in dashboard');
}
else
{
menu.hide('slow');
addWidget(1, plugin, action);
saveLayout();
$('.button#addWidget').show();
}
});
}
function getWidgetInDom(domElem)
{
var items = $('.items:not(.dummyItem) .parentDiv', domElem);
var widgets = new Array;
for(var i=0; i<items.size(); i++)
{
widgets.push($(items[i]).attr('plugin')+'.'+$(items[i]).attr('id'));
}
return widgets;
}
function setupWidgetSortable()
{
//add a dummy item on each columns
$('.col').each(
function()
{
$(this).append('<div class="items dummyItem"><div class="handle dummyHandle"></div></div>');
});
hideUnnecessaryDummies();
makeSortable();
}
function generateLayout()
{
//dashboardLayout look like :
//'Actions.getActions~Actions.getDownloads|UserCountry.getCountry|Referers.getSearchEngines';
//'|' separate columns
//'~' separate widgets
//'.' separate plugin name from action name
var col = piwik.dashboardLayout.split('|');
for(var i=0; i<col.length; i++)
{
if(col[i] != '')
{
var widgets = col[i].split('~');
for(var j=0; j<widgets.length; j++)
{
var wid = widgets[j].split('.');
addWidget(i+1, wid[0], wid[1]);
}
}
}
}
function addWidget(colNumber, plugin, action)
{
var item = '<div class="items"><div class="widget"><div plugin="'+plugin+'"'+' id="'+action+'" class="parentDiv"></div></div></div>';
$('.col#'+colNumber).append(item);
loadItem($('.items #'+action).parents('.items'));
makeSortable();
}
function loadItem(domElem)
{
var plugin;
var action;
var title;
//load every parentDiv with asynchronous ajax
$('.parentDiv', domElem).each(
function()
{
plugin = $(this).attr('plugin');
action = $(this).attr('id')
// get the ID of the div and load with ajax
ajaxLoading(plugin, action);
});
//find the title of the widget
var widgets = piwik.availableWidgets[plugin];
for(var i in widgets)
{
if(action == widgets[i][1])
title = widgets[i][0]
}
//add an handle to each items
$('.widget', domElem).prepend('<div class="handle"><div class="widgetTitle">'+title+'</div><div class="button" id="close"><img src="themes/default/images/close.png" /></div></div>');
var button = $('.button#close', domElem);
//Only show handle buttons on mouse hover
$('.handle', domElem).hover(
function()
{
$(this).parent().addClass('widgetHover');
$(this).addClass('handleHover');
button.fadeIn(100);
},
function()
{
$(this).parent().removeClass('widgetHover');
$(this).removeClass('handleHover');
button.fadeOut(200);
}
);
//Bind click event on close button
button.click(onDeleteItem);
}
function makeSortable()
{
//launch 'sortable' property on every dashboard widgets
$('.sortDiv').sortableDestroy()
.sortable({
items:'.items',
hoverClass: 'hover',
handle: '.handle',
helper: getHelper,
start: onStart,
stop: onStop
});
}
function getHelper()
{
return $(this).clone().addClass('helper');
}
function onStart()
{
showDummies();
}
function onStop()
{
hideUnnecessaryDummies();
saveLayout();
}
function onDeleteItem(ev)
{
var target = this;
//ask confirmation and delete item
var question = $('.dialog#confirm').clone();
$('#yes', question).click(function()
{
$(target).parents('.items').fadeOut(500, function(){$(this).remove()});
showNecessaryDummies();
saveLayout();
makeSortable();
$.unblockUI();
});
$('#no', question).click($.unblockUI);
$.blockUI(question, { width: '300px' });
}
function showDummies()
{
$('.dummyItem').css('display', 'block');
}
function showNecessaryDummies()
{
showDummies();
//hideUnnecessaryDummies();
}
function hideUnnecessaryDummies()
{
$('.dummyItem').each(function(){
$(this).appendTo($(this).parent());
if($(this).siblings().size() > 0)
$(this).css('display', 'none');
});
}
function saveLayout()
{
var column = new Array;
//parse the dom to see how our div are sorted
$('.sortDiv .col').each(function() {
column.push(getWidgetInDom(this));
});
var ajaxRequest =
{
type: 'GET',
url: 'index.php',
dataType: 'html',
async: true,
error: ajaxHandleError, // Callback when the request fails
data: { module: 'Dashboard',
action: 'saveLayout' }
};
var layout = '';
for(var i=0; i<column.length; i++)
{
layout += column[i].join('~');
layout += '|';
}
ajaxRequest.data['layout'] = layout;
$.ajax(ajaxRequest);
}
function ajaxLoading(pluginId, actionId)
{
// When ajax replied, we replace the right div with the response
function onLoaded(response)
{
var content = $(response);
$('#'+actionId).html( $(content).html() );
}
//prepare and launch the ajax request
var ajaxRequest =
{
type: 'GET',
url: 'index.php',
dataType: 'html',
async: true,
error: ajaxHandleError, // Callback when the request fails
success: onLoaded, // Callback when the request succeeds
data: { module: pluginId,
action: actionId,
idSite: piwik.idSite,
period: piwik.period,
date: piwik.currentDateStr
}
};
$.ajax(ajaxRequest);
}
{* This header is for loading the dashboard in stand alone mode*}
<script type="text/javascript" src="libs/jquery/jquery.js"></script>
<script type="text/javascript" src="libs/jquery/jquery.scrollTo.js"></script>
<script type="text/javascript" src="libs/jquery/jquery.dimensions.js"></script>
<script type="text/javascript" src="libs/jquery/tooltip/jquery.tooltip.js"></script>
<script type="text/javascript" src="libs/jquery/truncate/jquery.truncate.js"></script>
<script type="text/javascript" src="themes/default/common.js"></script>
<script type="text/javascript" src="plugins/Home/templates/datatable.js"></script>
<script type="text/javascript" src="libs/swfobject/swfobject.js"></script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd "> <script type="text/javascript">
{* define some global constants for the following javascript includes *}
{literal} var piwik = new Object;
<script type="text/javascript" src="libs/jquery/jquery.js"></script> {if isset($layout) }
<script type="text/javascript" src="libs/jquery/jquery.scrollTo.js"></script> piwik.dashboardLayout = '{$layout}';
<script type="text/javascript" src="libs/jquery/jquery.dimensions.js"></script> {else}
//Load default layout...
<script type="text/javascript" src="libs/jquery/tooltip/jquery.tooltip.js"></script> piwik.dashboardLayout = 'Actions.getActions~Actions.getDownloads|UserCountry.getCountry~UserSettings.getPlugin|Referers.getSearchEngines~Referers.getKeywords';
<script type="text/javascript" src="libs/jquery/truncate/jquery.truncate.js"></script> {/if}
<script type="text/javascript" src="themes/default/common.js"></script>
<script type="text/javascript" src="plugins/Home/templates/datatable.js"></script> piwik.availableWidgets = {$availableWidgets};
piwik.idSite = {$idSite};
piwik.period = "{$period}";
piwik.currentDateStr = "{$date}";
</script>
<script type="text/javascript" src="libs/jquery/jquery.blockUI.js"></script> <script type="text/javascript" src="libs/jquery/jquery.blockUI.js"></script>
<script type="text/javascript" src="libs/jquery/ui.mouse.js"></script> <script type="text/javascript" src="libs/jquery/ui.mouse.js"></script>
<script type="text/javascript" src="libs/jquery/ui.sortable_modif.js"></script> <script type="text/javascript" src="libs/jquery/ui.sortable_modif.js"></script>
<script type="text/javascript" src="libs/swfobject/swfobject.js"></script>
<script type="text/javascript" src="plugins/Dashboard/templates/Dashboard.js"></script>
<link rel="stylesheet" href="libs/jquery/tooltip/jquery.tooltip.css"> <link rel="stylesheet" href="libs/jquery/tooltip/jquery.tooltip.css">
<link rel="stylesheet" href="plugins/Home/templates/datatable.css"> <link rel="stylesheet" href="plugins/Home/templates/datatable.css">
<script type="text/javascript">
$(document).ready(
function()
{
//get layout
var piwik_DashboardLayout = '';
{/literal}
{if isset($layout) }
piwik_DashboardLayout = '{$layout}';
{else}
//Load default layout...
piwik_DashboardLayout = 'Actions.getActions~Actions.getDownloads|UserCountry.getCountry~UserSettings.getPlugin|Referers.getSearchEngines~Referers.getKeywords';
{/if}
{literal}
//generate dashboard layout
var col = piwik_DashboardLayout.split('|');
for(var i in col)
{
if(col[i] != '')
{
var widgets = col[i].split('~');
for(var j in widgets)
{
var wid = widgets[j].split('.');
addWidget(Number(i)+1, wid[0], wid[1]);
}
}
}
//menu show button
$('.button#addWidget').click(function(){
$(this).hide();
$('.menu#widgetChooser').show('slow');
});
//load menu widgets list
{/literal} var availableWidgets = {$availableWidgets};
{literal} {literal}
var menu = $('.menu#widgetChooser');
for(var plugin in availableWidgets)
{
var widgets = availableWidgets[plugin];
for(var i in widgets)
{
menu.append('<div class="button menuItem" pluginToLoad="'+plugin+'" actionToLoad="'+widgets[i][1]+'">'+widgets[i][0] + ' => (' + plugin +'.'+ widgets[i][1] + ')</div>');
}
}
//bind menu ui events
$('.menuItem', menu).click(function(){
menu.hide('slow');
var plugin = $(this).attr('pluginToLoad');
var action = $(this).attr('actionToLoad');
addWidget(1, plugin, action);
saveLayout();
$('.button#addWidget').show();
});
//load every widgets
//$('.items').each(function(){loadItem(this)});
//add a dummy item on each columns
$('.col').each(
function()
{
$(this).append('<div class="items dummyItem"><div class="handle dummyHandle"></div></div>');
});
hideUnnecessaryDummies();
makeSortable();
}
);
function addWidget(colNumber, plugin, action)
{
var item = '<div class="items"><div plugin="'+plugin+'"'+' id="'+action+'" class="parentDiv"></div></div>';
$('.col#'+colNumber).append(item);
loadItem($('.items #'+action).parents('.items'));
makeSortable();
}
function loadItem(domElem)
{
//load every parentDiv with asynchronous ajax
$('.parentDiv', domElem).each(
function()
{
// get the ID of the div and load with ajax
ajaxLoading($(this).attr('plugin'), $(this).attr('id'));
});
//add an handle to each items
$(domElem).prepend('<div class="handle"><div class="button" id="close"><img src="themes/default/images/close.png" /></div></div>');
//Bind click event on close button
$('.button#close', domElem).click(onDeleteItem);
}
function makeSortable()
{
//launch 'sortable' property on every dashboard widgets
$('.sortDiv').sortableDestroy()
.sortable({
items:'.items',
hoverClass: 'hover',
handle: '.handle',
helper: getHelper,
start: onStart,
stop: onStop
});
}
function getHelper()
{
return $(this).clone().addClass('helper');
}
function onStart()
{
showDummies();
}
function onStop()
{
hideUnnecessaryDummies();
saveLayout();
}
function onDeleteItem(ev)
{
var target = this;
//ask confirmation and delete item
var question = $('.dialog#confirm').clone();
$('#yes', question).click(function()
{
$(target).parents('.items').remove();
ShowNecessaryDummies();
saveLayout();
makeSortable();
$.unblockUI();
});
$('#no', question).click($.unblockUI);
$.blockUI(question, { width: '300px' });
}
function showDummies()
{
$('.dummyItem').css('display', 'block');
}
function ShowNecessaryDummies()
{
showDummies();
hideUnnecessaryDummies();
}
function hideUnnecessaryDummies()
{
$('.dummyItem').each(function(){
$(this).appendTo($(this).parent());
if($(this).siblings().size() > 0)
$(this).css('display', 'none');
});
}
function saveLayout()
{
var column = new Array;
//parse the dom to see how our div are sorted
$('.sortDiv .col').each(function() {
var items = $('.items:not(.dummyItem) .parentDiv', this);
var widgets = new Array;
for(var i=0; i<items.size(); i++)
{
widgets.push($(items[i]).attr('plugin')+'.'+$(items[i]).attr('id'));
}
column.push(widgets);
});
var ajaxRequest =
{
type: 'GET',
url: 'index.php',
dataType: 'html',
async: true,
error: ajaxHandleError, // Callback when the request fails
data: { module: 'Dashboard',
action: 'saveLayout' }
};
var layout = '';
for(var i=0; i<column.length; i++)
{
layout += column[i].join('~');
layout += '|';
}
ajaxRequest.data['layout'] = layout;
$.ajax(ajaxRequest);
}
function ajaxLoading(pluginId, actionId)
{
// When ajax replied, we replace the right div with the response
function onLoaded(response)
{
var content = $(response);
$('#'+actionId).html( $(content).html() );
}
//prepare and launch the ajax request
var ajaxRequest =
{
type: 'GET',
url: 'index.php',
dataType: 'html',
async: true,
error: ajaxHandleError, // Callback when the request fails
success: onLoaded, // Callback when the request succeeds
data: { module: pluginId,
action: actionId,
{/literal} idSite: {$idSite},
period: '{$period}',
date: '{$date}'
{literal} }
};
$.ajax(ajaxRequest);
}
</script>
<style type="text/css"> <style type="text/css">
.col { *{
float:left; font-family: Georgia;
width: 33%;
} }
/*Overriding some dataTable css for better dashboard display*/ /*Overriding some dataTable css for better dashboard display*/
.parentDiv { .parentDiv {
width: 95%; width: 100%
} }
table.dataTable { table.dataTable {
width: 100%; width: 100%;
...@@ -268,20 +45,49 @@ table.dataTable { ...@@ -268,20 +45,49 @@ table.dataTable {
#dataTableFeatures { #dataTableFeatures {
width: 100%; width: 100%;
} }
/*--- end of dataTable.css modif*/
.col {
float:left;
width: 33%;
}
.hover { .hover {
border: 2px dashed; border: 2px dashed rgb(200,200,200);
} }
.items { .items {
background: white; background: white;
} }
.widget {
border: 1px solid rgb(230,230,230);
margin-top: 10px;
margin-bottom: 10px;
margin-right: 5px;
margin-left: 5px;
}
.widgetHover {
border: 1px solid rgb(200, 200, 200);
}
.handle { .handle {
background: gray; background: rgb(240,240,250);
width: 100%; width: 100%;
height: 14px; height: 20px;
cursor: move; cursor: move;
font-size: 10pt;
font-weight: bold;
}
.widgetTitle {
width: 80%;
float: left;
}
.handleHover {
background: rgb(200,200,230);
} }
.dummyItem { .dummyItem {
...@@ -296,6 +102,7 @@ table.dataTable { ...@@ -296,6 +102,7 @@ table.dataTable {
#close.button { #close.button {
float: right; float: right;
display: none;
} }
.dialog { .dialog {
...@@ -316,6 +123,28 @@ table.dataTable { ...@@ -316,6 +123,28 @@ table.dataTable {
display: none; display: none;
} }
.menuItem {
}
.menuSelected {
border: 1px dashed;
}
.subMenu1 {
float:left;
width: 15%;
cursor: pointer;
}
.subMenu2 {
float:left;
width: 40%;
cursor: pointer;
}
.subMenu3 {
float:left;
clear: both;
}
</style> </style>
{/literal} {/literal}
...@@ -334,6 +163,14 @@ table.dataTable { ...@@ -334,6 +163,14 @@ table.dataTable {
</div> </div>
<div class="menu" id="widgetChooser"> <div class="menu" id="widgetChooser">
<div class="subMenu1">
</div>
<div class="subMenu2">
</div>
<div class="subMenu3">
</div>
</div> </div>
<div class="col" id="1"> <div class="col" id="1">
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter