diff --git a/application/dashboard.class.inc.php b/application/dashboard.class.inc.php index bc6ef3d80..6cf87500e 100644 --- a/application/dashboard.class.inc.php +++ b/application/dashboard.class.inc.php @@ -28,11 +28,12 @@ abstract class Dashboard protected $aWidgetsData; protected $oDOMNode; protected $sId; + protected $aCells; public function __construct($sId) { $this->sLayoutClass = null; - $this->aDashlets = array(); + $this->aCells = array(); $this->oDOMNode = null; $this->sId = $sId; } @@ -49,15 +50,21 @@ abstract class Dashboard $oTitleNode = $this->oDOMNode->getElementsByTagName('title')->item(0); $this->sTitle = $oTitleNode->textContent; - $oDashletsNode = $this->oDOMNode->getElementsByTagName('dashlets')->item(0); - $oDashletList = $oDashletsNode->getElementsByTagName('dashlet'); - foreach($oDashletList as $oDomNode) + $oCellsNode = $this->oDOMNode->getElementsByTagName('cells')->item(0); + $oCellsList = $oCellsNode->getElementsByTagName('cell'); + foreach($oCellsList as $oCellNode) { - $sDashletClass = $oDomNode->getAttribute('xsi:type'); - $sId = $oDomNode->getAttribute('id'); - $oNewDashlet = new $sDashletClass($sId); - $oNewDashlet->FromDOMNode($oDomNode); - $this->aDashlets[] = $oNewDashlet; + $aDashletList = array(); + $oDashletList = $oCellNode->getElementsByTagName('dashlet'); + foreach($oDashletList as $oDomNode) + { + $sDashletClass = $oDomNode->getAttribute('xsi:type'); + $sId = $oDomNode->getAttribute('id'); + $oNewDashlet = new $sDashletClass($sId); + $oNewDashlet->FromDOMNode($oDomNode); + $aDashletList[] = $oNewDashlet; + } + $this->aCells[] = $aDashletList; } } @@ -77,16 +84,21 @@ abstract class Dashboard $oNode = $oDoc->createElement('title', $this->sTitle); $oMainNode->appendChild($oNode); - $oDashletsNode = $oDoc->createElement('dashlets'); - $oMainNode->appendChild($oDashletsNode); + $oCellsNode = $oDoc->createElement('cells'); + $oMainNode->appendChild($oCellsNode); - foreach ($this->aDashlets as $oDashlet) + foreach ($this->aCells as $aCell) { - $oNode = $oDoc->createElement('dashlet'); - $oDashletsNode->appendChild($oNode); - $oNode->setAttribute('id', $oDashlet->GetID()); - $oNode->setAttribute('xsi:type', get_class($oDashlet)); - $oDashlet->ToDOMNode($oNode); + $oCellNode = $oDoc->createElement('cell'); + $oCellsNode->appendChild($oCellNode); + foreach ($aCell as $oDashlet) + { + $oNode = $oDoc->createElement('dashlet'); + $oCellNode->appendChild($oNode); + $oNode->setAttribute('id', $oDashlet->GetID()); + $oNode->setAttribute('xsi:type', get_class($oDashlet)); + $oDashlet->ToDOMNode($oNode); + } } $sXml = $oDoc->saveXML(); @@ -98,18 +110,23 @@ abstract class Dashboard $this->sLayoutClass = $aParams['layout_class']; $this->sTitle = $aParams['title']; - foreach($aParams['dashlets'] as $aDashletParams) + foreach($aParams['cells'] as $aCell) { - $sDashletClass = $aDashletParams['dashlet_class']; - $sId = $aDashletParams['dashlet_id']; - $oNewDashlet = new $sDashletClass($sId); - - $oForm = $oNewDashlet->GetForm(); - $oForm->SetParamsContainer($sId); - $oForm->SetPrefix(''); - $aValues = $oForm->ReadParams(); - $oNewDashlet->FromParams($aValues); - $this->aDashlets[] = $oNewDashlet; + $aCellDashlets = array(); + foreach($aCell as $aDashletParams) + { + $sDashletClass = $aDashletParams['dashlet_class']; + $sId = $aDashletParams['dashlet_id']; + $oNewDashlet = new $sDashletClass($sId); + + $oForm = $oNewDashlet->GetForm(); + $oForm->SetParamsContainer($sId); + $oForm->SetPrefix(''); + $aValues = $oForm->ReadParams(); + $oNewDashlet->FromParams($aValues); + $aCellDashlets[] = $oNewDashlet; + } + $this->aCells[] = $aCellDashlets; } } @@ -138,7 +155,7 @@ abstract class Dashboard { $this->sTitle = $sTitle; } - + public function AddDashlet() { } @@ -147,7 +164,7 @@ abstract class Dashboard { $oPage->add('

'.Dict::S($this->sTitle).'

'); $oLayout = new $this->sLayoutClass; - $oLayout->Render($oPage, $this->aDashlets, $bEditMode, $aExtraParams); + $oLayout->Render($oPage, $this->aCells, $bEditMode, $aExtraParams); if (!$bEditMode) { $oPage->add_linked_script('../js/dashlet.js'); @@ -173,7 +190,8 @@ abstract class Dashboard { $aCallSpec = array($sLayoutClass, 'GetInfo'); $aInfo = call_user_func($aCallSpec); - $oPage->add(''); // title="" on either the img or the label does nothing ! + $sChecked = ($this->sLayoutClass == $sLayoutClass) ? 'checked' : ''; + $oPage->add(''); // title="" on either the img or the label does nothing ! } } } @@ -229,17 +247,20 @@ EOF $oPage->add('
Dashlet Properties
'); $oPage->add('
'); - foreach($this->aDashlets as $oDashlet) + foreach($this->aCells as $aCell) { - $sId = $oDashlet->GetID(); - $sClass = get_class($oDashlet); - if ($oDashlet->IsVisible()) + foreach($aCell as $oDashlet) { - $oPage->add(''); + $sId = $oDashlet->GetID(); + $sClass = get_class($oDashlet); + if ($oDashlet->IsVisible()) + { + $oPage->add(''); + } } } $oPage->add('
'); @@ -252,6 +273,19 @@ EOF class RuntimeDashboard extends Dashboard { + protected $bCustomized; + + public function __construct($sId) + { + parent::__construct($sId); + $this->bCustomized = false; + } + + public function SetCustomFlag($bCustomized) + { + $this->bCustomized = $bCustomized; + } + protected function SetFormParams($oForm) { $oForm->SetSubmitParams(utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php', array('operation' => 'update_dashlet_property')); @@ -284,13 +318,41 @@ class RuntimeDashboard extends Dashboard } } + public function Revert() + { + $oUDSearch = new DBObjectSearch('UserDashboard'); + $oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '='); + $oUDSearch->AddCondition('menu_code', $this->sId, '='); + $oUDSet = new DBObjectSet($oUDSearch); + if ($oUDSet->Count() > 0) + { + // Assuming there is at most one couple {user, menu}! + $oUserDashboard = $oUDSet->Fetch(); + $oUserDashboard->DBDelete(); + } + } + public function Render($oPage, $bEditMode = false, $aExtraParams = array()) { parent::Render($oPage, $bEditMode, $aExtraParams); if (!$bEditMode) { - $sEditBtn = addslashes('
'); - $oPage->add_ready_script("$('#top-bar').prepend('$sEditBtn');"); + $sEditMenu = ""; + $sEditMenu = addslashes($sEditMenu); + //$sEditBtn = addslashes('
'); + $oPage->add_ready_script( +<<ul').popupmenu(); + +EOF + ); $oPage->add_script( <<add_ready_script("$('#dashboard_editor').layout({ east__size: 300 });"); + $oPage->add_ready_script(""); } } \ No newline at end of file diff --git a/application/dashboardlayout.class.inc.php b/application/dashboardlayout.class.inc.php index 31541555d..b7f990901 100644 --- a/application/dashboardlayout.class.inc.php +++ b/application/dashboardlayout.class.inc.php @@ -27,9 +27,8 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout $this->iNbCols = 1; } - public function Render($oPage, $aDashlets, $bEditMode = false, $aExtraParams = array()) + protected function TrimCell($aDashlets) { - // Trim the list of dashlets to remove the invisible ones at the end of the array $aKeys = array_reverse(array_keys($aDashlets)); $idx = 0; $bNoVisibleFound = true; @@ -46,24 +45,63 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout } $idx++; } + return $aDashlets; + } + + protected function TrimCellsArray($aCells) + { + foreach($aCells as $key => $aDashlets) + { + $aCells[$key] = $this->TrimCell($aDashlets); + } + $aKeys = array_reverse(array_keys($aCells)); + $idx = 0; + $bNoVisibleFound = true; + while($idx < count($aKeys) && $bNoVisibleFound) + { + $aDashlets = $aCells[$aKeys[$idx]]; + if (count($aDashlets) > 0) + { + $bNoVisibleFound = false; + } + else + { + unset($aCells[$aKeys[$idx]]); + } + $idx++; + } + return $aCells; + + } + + public function Render($oPage, $aCells, $bEditMode = false, $aExtraParams = array()) + { + // Trim the list of cells to remove the invisible/empty ones at the end of the array + $aCells = $this->TrimCellsArray($aCells); $oPage->add(''); - $iDashletIdx = 0; + $iCellIdx = 0; $fColSize = 100 / $this->iNbCols; - $sStyle = $bEditMode ? 'style="border: 1px #ccc dashed; width:'.$fColSize.'%;" class="layout_cell edit_mode"' : 'style="width: '.$fColSize.'%; "'; - $iNbRows = ceil(count($aDashlets) / $this->iNbCols); + $sStyle = $bEditMode ? 'style="border: 1px #ccc dashed; width:'.$fColSize.'%;" class="layout_cell edit_mode"' : 'style="width: '.$fColSize.'%;" class="dashboard"'; + $iNbRows = ceil(count($aCells) / $this->iNbCols); for($iRows = 0; $iRows < $iNbRows; $iRows++) { $oPage->add(''); for($iCols = 0; $iCols < $this->iNbCols; $iCols++) { $oPage->add("'); - $iDashletIdx++; + $iCellIdx++; } $oPage->add(''); } diff --git a/application/dashlet.class.inc.php b/application/dashlet.class.inc.php index 1daf75a49..ccb9f0cf6 100644 --- a/application/dashlet.class.inc.php +++ b/application/dashlet.class.inc.php @@ -26,6 +26,7 @@ abstract class Dashlet protected $bRedrawNeeded; protected $bFormRedrawNeeded; protected $aProperties; // array of {property => value} + protected $aCSSClasses; public function __construct($sId) { @@ -33,6 +34,7 @@ abstract class Dashlet $this->bRedrawNeeded = true; // By default: redraw each time a property changes $this->bFormRedrawNeeded = false; // By default: no need to redraw the form (independent fields) $this->aProperties = array(); // By default: there is no property + $this->aCSSClasses = array('dashlet'); } // Assuming that a property has the type of its default value, set in the constructor @@ -109,14 +111,15 @@ abstract class Dashlet public function DoRender($oPage, $bEditMode = false, $aExtraParams = array()) { + $sCSSClasses = implode(' ', $this->aCSSClasses); if ($bEditMode) { $sId = $this->GetID(); - $oPage->add('
'); + $oPage->add('
'); } else { - $oPage->add('
'); + $oPage->add('
'); } $this->Render($oPage, $bEditMode, $aExtraParams); $oPage->add('
'); @@ -293,7 +296,7 @@ class DashletObjectList extends Dashlet $oField = new DesignerTextField('title', 'Title', $this->aProperties['title']); $oForm->AddField($oField); - $oField = new DesignerTextField('query', 'Query', $this->aProperties['query']); + $oField = new DesignerLongTextField('query', 'Query', $this->aProperties['query']); $oForm->AddField($oField); $oField = new DesignerBooleanField('menu', 'Menu', $this->aProperties['menu']); @@ -379,7 +382,7 @@ abstract class DashletGroupBy extends Dashlet $oField = new DesignerTextField('title', 'Title', $this->aProperties['title']); $oForm->AddField($oField); - $oField = new DesignerTextField('query', 'Query', $this->aProperties['query']); + $oField = new DesignerLongTextField('query', 'Query', $this->aProperties['query']); $oForm->AddField($oField); // Group by field: build the list of possible values (attribute codes + ...) @@ -575,11 +578,13 @@ class DashletHeader extends Dashlet } $oPage->add('
'); + $oPage->add('
'); $aParams = array(); $sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM) $oBlock = DisplayBlock::FromTemplate($sXML); $oBlock->Display($oPage, $sBlockId, $aParams); $oPage->add('
'); + $oPage->add('
'); } public function GetPropertiesFields(DesignerForm $oForm) @@ -603,3 +608,43 @@ class DashletHeader extends Dashlet ); } } + + +class DashletBadge extends Dashlet +{ + public function __construct($sId) + { + parent::__construct($sId); + $this->aProperties['class'] = 'Contact'; + $this->aCSSClasses[] = 'dashlet-inline'; + $this->aCSSClasses[] = 'dashlet-badge'; + } + + public function Render($oPage, $bEditMode = false, $aExtraParams = array()) + { + $sClass = $this->aProperties['class']; + + $oPage->add('
'); + $sXml = "SELECT $sClass"; + $oBlock = DisplayBlock::FromTemplate($sXml); + $sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM) + $oBlock->Display($oPage, $sBlockId, $aExtraParams); + $oPage->add('
'); + } + + public function GetPropertiesFields(DesignerForm $oForm) + { + $oField = new DesignerTextField('class', 'Class', $this->aProperties['class']); + $oForm->AddField($oField); + } + + static public function GetInfo() + { + return array( + 'label' => 'Badge', + 'icon' => 'images/dashlet-badge.png', + 'description' => 'Object Icon with new/search', + ); + } +} + diff --git a/application/forms.class.inc.php b/application/forms.class.inc.php index f927e40dc..26fc25f3e 100644 --- a/application/forms.class.inc.php +++ b/application/forms.class.inc.php @@ -150,7 +150,7 @@ class DesignerForm if ($this->oParentForm == null) { $sFormId = $this->sFormId; - $sReturn = '
'; + $sReturn = ''; $sReturn .= '
"); - if (array_key_exists($iDashletIdx, $aDashlets)) + if (array_key_exists($iCellIdx, $aCells)) { - $oDashlet = $aDashlets[$iDashletIdx]; - if ($oDashlet->IsVisible()) + $aDashlets = $aCells[$iCellIdx]; + if (count($aDashlets) > 0) { - $oDashlet->DoRender($oPage, $bEditMode, $aExtraParams); + foreach($aDashlets as $oDashlet) + { + if ($oDashlet->IsVisible()) + { + $oDashlet->DoRender($oPage, $bEditMode, $aExtraParams); + } + } } else { @@ -75,7 +113,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout $oPage->add(' '); } $oPage->add('
'; $sReturn .= ''; } @@ -627,6 +627,29 @@ EOF } } +class DesignerLongTextField extends DesignerTextField +{ + public function Render(WebPage $oP, $sFormId, $sRenderMode='dialog') + { + $sId = $this->oForm->GetFieldId($this->sCode); + $sName = $this->oForm->GetFieldName($this->sCode); + $sValidation = $this->oForm->GetValidationArea($this->sCode); + $sPattern = addslashes($this->sValidationPattern); + $sMandatory = $this->bMandatory ? 'true' : 'false'; + $sReadOnly = $this->IsReadOnly() ? 'readonly' : ''; + $oP->add_ready_script( +<< $this->sLabel, 'value' => "".$sValidation); + } +} + class DesignerComboField extends DesignerFormField { protected $aAllowedValues; diff --git a/application/menunode.class.inc.php b/application/menunode.class.inc.php index 1321f0653..933bd03d5 100644 --- a/application/menunode.class.inc.php +++ b/application/menunode.class.inc.php @@ -807,9 +807,11 @@ class DashboardMenuNode extends MenuNode protected function GetDashboard() { - $sDashboardDefinition = @file_get_contents($this->sDashboardFile); + $sDashboardDefinition = @file_get_contents($this->sDashboardFile); if ($sDashboardDefinition !== false) { + $bCustomized = false; + // Search for an eventual user defined dashboard, overloading the existing one $oUDSearch = new DBObjectSearch('UserDashboard'); $oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '='); @@ -820,10 +822,12 @@ class DashboardMenuNode extends MenuNode // Assuming there is at most one couple {user, menu}! $oUserDashboard = $oUDSet->Fetch(); $sDashboardDefinition = $oUserDashboard->Get('contents'); + $bCustomized = true; + } - $oDashboard = new RuntimeDashboard($this->sMenuId); $oDashboard->FromXml($sDashboardDefinition); + $oDashboard->SetCustomFlag($bCustomized); } else {
PropertyValue