N°1408 - Dashboard selector

This commit is contained in:
Eric
2018-10-12 08:54:11 +02:00
parent d7df975971
commit c17f7caa29
7 changed files with 244 additions and 48 deletions

View File

@@ -390,7 +390,7 @@ abstract class Dashboard
$oField = new DesignerHiddenField('dashboard_id', '', $this->sId);
$oForm->AddField($oField);
$oField = new DesignerLongTextField('dashboard_title', Dict::S('UI:DashboardEdit:DashboardTitle'), $this->sTitle);
$oField = new DesignerTextField('dashboard_title', Dict::S('UI:DashboardEdit:DashboardTitle'), $this->sTitle);
$oForm->AddField($oField);
$oField = new DesignerBooleanField('auto_reload', Dict::S('UI:DashboardEdit:AutoReload'), $this->bAutoReload);
@@ -455,7 +455,7 @@ EOF
*/
public function Render($oPage, $bEditMode = false, $aExtraParams = array(), $bCanEdit = true)
{
$oPage->add('<div class="dashboard-title">'.htmlentities(Dict::S($this->sTitle), ENT_QUOTES, 'UTF-8', false).'</div>');
$oPage->add('<div class="dashboard-title-line"><div class="dashboard-title">'.htmlentities(Dict::S($this->sTitle), ENT_QUOTES, 'UTF-8', false).'</div></div>');
$oLayout = new $this->sLayoutClass;
/** @var \DashboardLayoutMultiCol $oLayout */
@@ -654,7 +654,7 @@ class RuntimeDashboard extends Dashboard
/**
* @param string $sDashboardFile file name relative to the current module folder
* @param string $sDashBoardCode code of the dashboard either menu_id or <class>__<attcode>
* @param string $sDashBoardId code of the dashboard either menu_id or <class>__<attcode>
*
* @return null|RuntimeDashboard
* @throws \CoreException
@@ -663,16 +663,16 @@ class RuntimeDashboard extends Dashboard
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
*/
public static function GetDashboard($sDashboardFile, $sDashBoardCode)
public static function GetDashboard($sDashboardFile, $sDashBoardId)
{
$bCustomized = false;
if (!appUserPreferences::GetPref('display_original_dashboard_'.$sDashBoardCode, false))
if (!appUserPreferences::GetPref('display_original_dashboard_'.$sDashBoardId, false))
{
// Search for an eventual user defined dashboard
$oUDSearch = new DBObjectSearch('UserDashboard');
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
$oUDSearch->AddCondition('menu_code', $sDashBoardCode, '=');
$oUDSearch->AddCondition('menu_code', $sDashBoardId, '=');
$oUDSet = new DBObjectSet($oUDSearch);
if ($oUDSet->Count() > 0)
{
@@ -693,7 +693,7 @@ class RuntimeDashboard extends Dashboard
if ($sDashboardDefinition !== false)
{
$oDashboard = new RuntimeDashboard($sDashBoardCode);
$oDashboard = new RuntimeDashboard($sDashBoardId);
$oDashboard->FromXml($sDashboardDefinition);
$oDashboard->SetCustomFlag($bCustomized);
$oDashboard->SetDefinitionFile($sDashboardFile);
@@ -745,6 +745,7 @@ class RuntimeDashboard extends Dashboard
$sFile = addslashes($this->GetDefinitionFile());
$sExtraParams = json_encode($aAjaxParams);
$iReloadInterval = 1000 * $this->GetAutoReloadInterval();
$sReloadURL = $this->GetReloadURL();
$oPage->add_script(
<<<EOF
if (typeof(AutoReloadDashboardId$sDivId) !== 'undefined')
@@ -762,7 +763,7 @@ class RuntimeDashboard extends Dashboard
{
$('.dashboard_contents#$sDivId').block();
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
{ operation: 'reload_dashboard', dashboard_id: '$sId', file: '$sFile', extra_params: $sExtraParams},
{ operation: 'reload_dashboard', dashboard_id: '$sId', file: '$sFile', extra_params: $sExtraParams, reload_url: '$sReloadURL'},
function(data){
$('.dashboard_contents#$sDivId').html(data);
$('.dashboard_contents#$sDivId').unblock();
@@ -788,7 +789,7 @@ EOF
if ($bCanEdit)
{
$this->RenderDashboardSelector($oPage);
$this->RenderSelector($oPage);
$this->RenderEditionTools($oPage, $aAjaxParams);
}
}
@@ -797,18 +798,57 @@ EOF
/**
* @param \iTopWebPage $oPage
*/
protected function RenderDashboardSelector($oPage)
protected function RenderSelector($oPage, $aExtraParams = array())
{
$sId = $this->GetId();
$sDivId = preg_replace('/[^a-zA-Z0-9_]/', '', $sId);
if (isset($aExtraParams['query_params']['this->object()']))
{
/** @var \DBObject $oObj */
$oObj = $aExtraParams['query_params']['this->object()'];
$aAjaxParams = array('this->class' => get_class($oObj), 'this->id' => $oObj->GetKey());
}
else
{
$aAjaxParams = $aExtraParams;
}
$sExtraParams = json_encode($aAjaxParams);
$sSelectorHtml = '<div class="dashboard-selector">';
if ($this->HasCustomDashboard())
{
$bStandardSelected = appUserPreferences::GetPref('display_original_dashboard_'.$sId, false);
$sStandard = Dict::S('UI:Toggle:StandardDashboard');
$sSelectorHtml .= '<div class="selector-label">'.$sStandard.'</div>';
$sSelectorHtml .= '<label class="switch"><input type="checkbox" onchange="ToggleDashboardSelector'.$sDivId.'();" '.($bStandardSelected ? '' : 'checked').'><span class="slider round"></span></label></input></label>';
$sCustom = Dict::S('UI:Toggle:CustomDashboard');
$sSelectorHtml .= '<div class="selector-label">'.$sCustom.'</div>';
}
$sSelectorHtml .= '</div>';
$sSelectorHtml = addslashes($sSelectorHtml);
$sFile = addslashes($this->GetDefinitionFile());
$sReloadURL = $this->GetReloadURL();
$oPage->add_ready_script(
<<<EOF
$('.dashboard-title').after('$sSelectorHtml');
EOF
);
$oPage->add_script(
<<<EOF
function ToggleDashboardSelector$sDivId()
{
$('.dashboard_contents#$sDivId').block();
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
{ operation: 'toggle_dashboard', dashboard_id: '$sId', file: '$sFile', extra_params: $sExtraParams, reload_url: '$sReloadURL' },
function(data) {
$('.dashboard_contents#$sDivId').html(data);
$('.dashboard_contents#$sDivId').unblock();
}
);
}
EOF
);
}
@@ -846,8 +886,16 @@ EOF
$aActions = array();
$sFile = addslashes($this->sDefinitionFile);
$sJSExtraParams = json_encode($aExtraParams);
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:Edit'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
$bCanEdit = true;
if ($this->HasCustomDashboard())
{
$bCanEdit = !appUserPreferences::GetPref('display_original_dashboard_'.$this->GetId(), false);
}
if ($bCanEdit)
{
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:Edit'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
}
if ($this->bCustomized)
{
@@ -861,7 +909,7 @@ EOF
$sReloadURL = $this->GetReloadURL();
$oPage->add_ready_script(
<<<EOF
$('.dashboard-selector').after('$sEditMenu');
$('.dashboard-title').after('$sEditMenu');
$('#DashboardMenu>ul').popupmenu();
EOF
@@ -973,6 +1021,7 @@ EOF
$sAutoReload = $this->bAutoReload ? 'true' : 'false';
$sAutoReloadSec = (string) $this->iAutoReloadSec;
$sTitle = addslashes($this->sTitle);
$sFile = addslashes($this->GetDefinitionFile());
$sUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php';
$sReloadURL = $this->GetReloadURL();
@@ -1026,8 +1075,8 @@ $('#dashboard_editor').dialog({
$('#dashboard_editor .ui-layout-center').runtimedashboard({
dashboard_id: '$sId', layout_class: '$sLayoutClass', title: '$sTitle',
auto_reload: $sAutoReload, auto_reload_sec: $sAutoReloadSec,
submit_to: '$sUrl', submit_parameters: {operation: 'save_dashboard', extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
render_to: '$sUrl', render_parameters: {operation: 'render_dashboard', extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
submit_to: '$sUrl', submit_parameters: {operation: 'save_dashboard', file: '$sFile', extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
render_to: '$sUrl', render_parameters: {operation: 'render_dashboard', file: '$sFile', extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
new_dashlet_parameters: {operation: 'new_dashlet'}
});

View File

@@ -102,11 +102,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
$this->add_linked_script('../js/jquery.magnific-popup.min.js');
$this->add_linked_script('../js/breadcrumb.js');
$this->add_linked_script('../js/moment.min.js');
$this->add_linked_script('../js/round_checkbox.js');
$sSearchAny = addslashes(Dict::S('UI:SearchValue:Any'));
$sSearchNbSelected = addslashes(Dict::S('UI:SearchValue:NbSelected'));
$this->add_dict_entry('UI:FillAllMandatoryFields');
$this->add_dict_entries('Error:');

View File

@@ -2253,6 +2253,17 @@ a.summary, a.summary:hover {
width: 100%;
background-color: #fff;
}
.dashboard-selector {
display: block;
float: right;
margin-top: 10px;
}
.dashboard-selector .selector-label {
display: inline-block;
margin-left: 10px;
margin-right: 10px;
vertical-align: super;
}
#DashboardMenu {
display: block;
float: right;
@@ -2950,3 +2961,56 @@ table.listResults .originColor {
padding-top: 0.3em;
border: none;
}
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 41px;
height: 23px;
vertical-align: baseline;
}
/* Hide default HTML checkbox */
.switch input {
display: none;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: 0.4s;
transition: 0.4s;
}
.slider:before {
position: absolute;
content: "";
height: 17px;
width: 17px;
left: 4px;
bottom: 3px;
background-color: white;
-webkit-transition: 0.4s;
transition: 0.4s;
}
input:checked + .slider {
background-color: #ea7d1e;
}
input:focus + .slider {
box-shadow: 0 0 1px #ea7d1e;
}
input:checked + .slider:before {
-webkit-transform: translateX(16px);
-ms-transform: translateX(16px);
transform: translateX(16px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}

View File

@@ -2590,6 +2590,9 @@ a.summary, a.summary:hover {
text-align: center;
}
.dashboard-title-line {
}
.dashboard-title {
display: block;
float: left;
@@ -2606,6 +2609,22 @@ a.summary, a.summary:hover {
background-color: $white;
}
.dashboard-selector {
display: block;
float: right;
margin-top: 10px;
.selector-label {
display: inline-block;
margin-left: 10px;
margin-right: 10px;
vertical-align: super;
}
}
#DashboardMenu {
display: block;
float: right;
@@ -3417,3 +3436,64 @@ table.listResults .originColor{
}
}
}
// Round Toggle
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 41px;
height: 23px;
vertical-align: baseline;
}
/* Hide default HTML checkbox */
.switch input {display:none;}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 17px;
width: 17px;
left: 4px;
bottom: 3px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: $combodo-orange;
}
input:focus + .slider {
box-shadow: 0 0 1px $combodo-orange;
}
input:checked + .slider:before {
-webkit-transform: translateX(16px);
-ms-transform: translateX(16px);
transform: translateX(16px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}

View File

@@ -982,7 +982,14 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé
'UI:Button:Refresh' => 'Rafraîchir',
'UI:Button:GoPrint' => 'Imprimer...',
'UI:ExplainPrintable' => 'Cliquez sur les icones %1$s pour cacher des éléments lors de l\'impression.<br/>Utilisez la fonction "Aperçu avant impression" de votre navigateur pour prévisualiser avant d\'imprimer.<br/>Note: cet en-tête ainsi que les icones %1$s ne seront pas imprimés.',
'UI:PrintResolution:FullSize' => 'Pleine largeur',
'UI:PrintResolution:A4Portrait' => 'A4 Portrait',
'UI:PrintResolution:A4Landscape' => 'A4 Paysage',
'UI:PrintResolution:LetterPortrait' => 'US Letter Portrait',
'UI:PrintResolution:LetterLandscape' => 'US Letter Paysage',
'UI:Toggle:StandardDashboard' => 'Standard',
'UI:Toggle:CustomDashboard' => 'Modifié',
'UI:ConfigureThisList' => 'Configurer Cette Liste...',
'UI:ListConfigurationTitle' => 'Configuration de la liste',
'UI:ColumnsAndSortOrder' => 'Colonnes et ordre de tri:',

View File

@@ -1,25 +0,0 @@
// Copyright (C) 2010-2018 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
$('.round-btn').click(function() {
var mainParent = $(this).parent('.round-checkbox');
if($(mainParent).find('input.round-btn').is(':checked')) {
$(mainParent).addClass('active');
} else {
$(mainParent).removeClass('active');
}
});

View File

@@ -950,6 +950,30 @@ try
$oPage->add(json_encode($aResult));
break;
case 'toggle_dashboard':
$oPage->SetContentType('text/html');
$sDashboardId = utils::ReadParam('dashboard_id', '', false, 'raw_data');
$bStandardSelected = appUserPreferences::GetPref('display_original_dashboard_'.$sDashboardId, false);
appUserPreferences::UnsetPref('display_original_dashboard_'.$sDashboardId);
appUserPreferences::SetPref('display_original_dashboard_'.$sDashboardId, !$bStandardSelected);
$aExtraParams = utils::ReadParam('extra_params', array(), false, 'raw_data');
$sDashboardFile = utils::ReadParam('file', '', false, 'raw_data');
$sReloadURL = utils::ReadParam('reload_url', '', false, 'raw_data');
$oDashboard = RuntimeDashboard::GetDashboard($sDashboardFile, $sDashboardId);
$aResult = array('error' => '');
if (!is_null($oDashboard))
{
if (!empty($sReloadURL))
{
$oDashboard->SetReloadURL($sReloadURL);
}
$oDashboard->Render($oPage, false, $aExtraParams);
}
$oPage->add_ready_script("$('.dashboard_contents table.listResults').tableHover(); $('.dashboard_contents table.listResults').tablesorter( { widgets: ['myZebra', 'truncatedList']} );");
break;
case 'reload_dashboard':
$oPage->SetContentType('text/html');
$sDashboardId = utils::ReadParam('dashboard_id', '', false, 'raw_data');
@@ -983,14 +1007,14 @@ try
$oDashboard = new RuntimeDashboard($sDashboardId);
$oDashboard->FromParams($aParams);
$oDashboard->Save();
$sFile = $oDashboard->GetDefinitionFile();
$sDashboardFile = addslashes(utils::ReadParam('file', '', false, 'raw_data'));
$sDivId = preg_replace('/[^a-zA-Z0-9_]/', '', $sDashboardId);
// trigger a reload of the current page since the dashboard just changed
$oPage->add_script(
<<<EOF
$('.dashboard_contents#$sDivId').block();
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
{ operation: 'reload_dashboard', dashboard_id: '$sDashboardId', file: '$sFile', extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
{ operation: 'reload_dashboard', dashboard_id: '$sDashboardId', file: '$sDashboardFile', extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
function(data){
$('.dashboard_contents#$sDivId').html(data);
$('.dashboard_contents#$sDivId').unblock();
@@ -1002,9 +1026,10 @@ EOF
case 'revert_dashboard':
$sDashboardId = utils::ReadParam('dashboard_id', '', false, 'raw_data');
appUserPreferences::UnsetPref('display_original_dashboard_'.$sDashboardId);
$oDashboard = new RuntimeDashboard($sDashboardId);
$oDashboard->Revert();
$sFile = $oDashboard->GetDefinitionFile();
$sFile = addslashes($oDashboard->GetDefinitionFile());
$sDivId = preg_replace('/[^a-zA-Z0-9_]/', '', $sDashboardId);
// trigger a reload of the current page since the dashboard just changed
$oPage->add_script(