diff --git a/application/dashboard.class.inc.php b/application/dashboard.class.inc.php index d0a98e667..c9635cecf 100644 --- a/application/dashboard.class.inc.php +++ b/application/dashboard.class.inc.php @@ -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('
'.htmlentities(Dict::S($this->sTitle), ENT_QUOTES, 'UTF-8', false).'
'); + $oPage->add('
'.htmlentities(Dict::S($this->sTitle), ENT_QUOTES, 'UTF-8', false).'
'); $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 __ + * @param string $sDashBoardId code of the dashboard either menu_id or __ * * @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( <<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 = '
'; if ($this->HasCustomDashboard()) { + $bStandardSelected = appUserPreferences::GetPref('display_original_dashboard_'.$sId, false); + $sStandard = Dict::S('UI:Toggle:StandardDashboard'); + $sSelectorHtml .= '
'.$sStandard.'
'; + $sSelectorHtml .= ''; + $sCustom = Dict::S('UI:Toggle:CustomDashboard'); + $sSelectorHtml .= '
'.$sCustom.'
'; } $sSelectorHtml .= '
'; + $sSelectorHtml = addslashes($sSelectorHtml); + $sFile = addslashes($this->GetDefinitionFile()); + $sReloadURL = $this->GetReloadURL(); $oPage->add_ready_script( <<add_script( +<<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( <<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'} }); diff --git a/application/itopwebpage.class.inc.php b/application/itopwebpage.class.inc.php index e3e66da9b..2a8ded99f 100644 --- a/application/itopwebpage.class.inc.php +++ b/application/itopwebpage.class.inc.php @@ -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:'); diff --git a/css/light-grey.css b/css/light-grey.css index 40e5f25e1..4b46f987b 100644 --- a/css/light-grey.css +++ b/css/light-grey.css @@ -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%; +} diff --git a/css/light-grey.scss b/css/light-grey.scss index faeb8f7c9..5b2823759 100644 --- a/css/light-grey.scss +++ b/css/light-grey.scss @@ -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%; +} \ No newline at end of file diff --git a/dictionaries/fr.dictionary.itop.ui.php b/dictionaries/fr.dictionary.itop.ui.php index 18f7c194d..29c11833f 100644 --- a/dictionaries/fr.dictionary.itop.ui.php +++ b/dictionaries/fr.dictionary.itop.ui.php @@ -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.
Utilisez la fonction "Aperçu avant impression" de votre navigateur pour prévisualiser avant d\'imprimer.
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:', diff --git a/js/round_checkbox.js b/js/round_checkbox.js deleted file mode 100644 index b7f385f8f..000000000 --- a/js/round_checkbox.js +++ /dev/null @@ -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 - -$('.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'); - } -}); \ No newline at end of file diff --git a/pages/ajax.render.php b/pages/ajax.render.php index 25b4379bb..c64700b5d 100644 --- a/pages/ajax.render.php +++ b/pages/ajax.render.php @@ -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( <<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(