diff --git a/application/dashlet.class.inc.php b/application/dashlet.class.inc.php
index 2c21628aa..0464d58c7 100644
--- a/application/dashlet.class.inc.php
+++ b/application/dashlet.class.inc.php
@@ -700,12 +700,21 @@ abstract class DashletGroupBy extends Dashlet
$this->aProperties['query'] = 'SELECT Contact';
$this->aProperties['group_by'] = 'status';
$this->aProperties['style'] = 'table';
+ $this->aProperties['agregation_function'] = 'count';
+ $this->aProperties['agregation_attribute'] = '';
+ $this->aProperties['limit'] = '';
+ $this->aProperties['order_direction'] = 'desc';
}
protected $sGroupByLabel = null;
protected $sGroupByExpr = null;
protected $sGroupByAttCode = null;
protected $sFunction = null;
+ protected $sAgregationFunction = null;
+ protected $sAgregationAttribute = null;
+ protected $sLimit = null;
+ protected $sOrderDirection = null;
+ protected $sClass = null;
/**
* Compute Grouping
@@ -716,22 +725,27 @@ abstract class DashletGroupBy extends Dashlet
$this->sGroupByLabel = null;
$this->sGroupByAttCode = null;
$this->sFunction = null;
+ $this->sClass = null;
$sQuery = $this->aProperties['query'];
$sGroupBy = $this->aProperties['group_by'];
- $sStyle = $this->aProperties['style'];
+
+ $this->sAgregationFunction = $this->aProperties['agregation_function'];
+ $this->sAgregationAttribute = $this->aProperties['agregation_attribute'];
+ $this->sLimit = $this->aProperties['limit'];
+ $this->sOrderDirection = $this->aProperties['order_direction'];
// First perform the query - if the OQL is not ok, it will generate an exception : no need to go further
try
{
$oQuery = $this->oModelReflection->GetQuery($sQuery);
- $sClass = $oQuery->GetClass();
+ $this->sClass = $oQuery->GetClass();
$sClassAlias = $oQuery->GetClassAlias();
}
catch(Exception $e)
{
// Invalid query, let the user edit the dashlet/dashboard anyhow
- $sClass = '';
+ $this->sClass = null;
$sClassAlias = '';
}
// Check groupby... it can be wrong at this stage
@@ -745,9 +759,9 @@ abstract class DashletGroupBy extends Dashlet
$this->sGroupByAttCode = $sGroupBy;
$this->sFunction = null;
}
- if (($sClass != '') && $this->oModelReflection->IsValidAttCode($sClass, $this->sGroupByAttCode))
+ if ((!is_null($this->sClass)) && $this->oModelReflection->IsValidAttCode($this->sClass, $this->sGroupByAttCode))
{
- $sAttLabel = $this->oModelReflection->GetLabel($sClass, $this->sGroupByAttCode);
+ $sAttLabel = $this->oModelReflection->GetLabel($this->sClass, $this->sGroupByAttCode);
if (!is_null($this->sFunction))
{
switch($this->sFunction)
@@ -793,7 +807,6 @@ abstract class DashletGroupBy extends Dashlet
{
$sTitle = $this->aProperties['title'];
$sQuery = $this->aProperties['query'];
- $sGroupBy = $this->aProperties['group_by'];
$sStyle = $this->aProperties['style'];
// First perform the query - if the OQL is not ok, it will generate an exception : no need to go further
@@ -801,7 +814,6 @@ abstract class DashletGroupBy extends Dashlet
$oFilter->SetShowObsoleteData(utils::ShowObsoleteData());
$sClass = $oFilter->GetClass();
- $sClassAlias = $oFilter->GetClassAlias();
if (!$this->oModelReflection->IsValidAttCode($sClass, $this->sGroupByAttCode))
{
@@ -818,6 +830,10 @@ abstract class DashletGroupBy extends Dashlet
'chart_title' => $sTitle,
'group_by' => $this->sGroupByExpr,
'group_by_label' => $this->sGroupByLabel,
+ 'agregation_function' => $this->sAgregationFunction,
+ 'agregation_attribute' => $this->sAgregationAttribute,
+ 'limit' => $this->sLimit,
+ 'order_direction' => $this->sOrderDirection,
);
$sHtmlTitle = ''; // done in the itop block
break;
@@ -829,6 +845,10 @@ abstract class DashletGroupBy extends Dashlet
'chart_title' => $sTitle,
'group_by' => $this->sGroupByExpr,
'group_by_label' => $this->sGroupByLabel,
+ 'agregation_function' => $this->sAgregationFunction,
+ 'agregation_attribute' => $this->sAgregationAttribute,
+ 'limit' => $this->sLimit,
+ 'order_direction' => $this->sOrderDirection,
);
$sHtmlTitle = ''; // done in the itop block
break;
@@ -840,6 +860,10 @@ abstract class DashletGroupBy extends Dashlet
$aExtraParams = array(
'group_by' => $this->sGroupByExpr,
'group_by_label' => $this->sGroupByLabel,
+ 'agregation_function' => $this->sAgregationFunction,
+ 'agregation_attribute' => $this->sAgregationAttribute,
+ 'limit' => $this->sLimit,
+ 'order_direction' => $this->sOrderDirection,
);
break;
}
@@ -966,6 +990,10 @@ abstract class DashletGroupBy extends Dashlet
return $aGroupBy;
}
+ /**
+ * @param DesignerForm $oForm
+ * @throws DictExceptionMissingString
+ */
public function GetPropertiesFields(DesignerForm $oForm)
{
$oField = new DesignerTextField('title', Dict::S('UI:DashletGroupBy:Prop-Title'), $this->aProperties['title']);
@@ -1001,6 +1029,100 @@ abstract class DashletGroupBy extends Dashlet
$oField->SetMandatory();
$oField->SetAllowedValues($aStyles);
$oForm->AddField($oField);
+
+ $aFunctionAttributes = $this->GetNumericAttributes($this->aProperties['query']);
+ $aFunctions = $this->GetAllowedFunctions($aFunctionAttributes);
+ $oSelectorField = new DesignerFormSelectorField('agregation_function', Dict::S('UI:DashletGroupBy:Prop-Function'), $this->aProperties['agregation_function']);
+ $oForm->AddField($oSelectorField);
+ $oSelectorField->SetMandatory();
+ // Count sub-menu
+ $oSubForm = new DesignerForm();
+ $oSelectorField->AddSubForm($oSubForm, Dict::S('UI:GroupBy:count'), 'count');
+ foreach($aFunctions as $sFct => $sLabel)
+ {
+ $oSubForm = new DesignerForm();
+ $oField = new DesignerComboField('agregation_attribute', Dict::S('UI:DashletGroupBy:Prop-FunctionAttribute'), $this->aProperties['agregation_attribute']);
+ $oField->SetMandatory();
+ $oField->SetAllowedValues($aFunctionAttributes);
+ $oSubForm->AddField($oField);
+ $oSelectorField->AddSubForm($oSubForm, $sLabel, $sFct);
+ }
+
+ $aOrderDirections = array(
+ 'asc' => Dict::S('UI:DashletGroupBy:Order:asc'),
+ 'desc' => Dict::S('UI:DashletGroupBy:Order:desc'),
+ );
+ $oField = new DesignerComboField('order_direction', Dict::S('UI:DashletGroupBy:Prop-OrderDirection'), $this->aProperties['order_direction']);
+ $oField->SetMandatory();
+ $oField->SetAllowedValues($aOrderDirections);
+ $oForm->AddField($oField);
+
+ $oField = new DesignerIntegerField('limit', Dict::S('UI:DashletGroupBy:Prop-Limit'), $this->aProperties['limit']);
+ $oForm->AddField($oField);
+
+ }
+
+ /**
+ * @return array
+ * @throws DictExceptionMissingString
+ */
+ protected function GetOrderBy()
+ {
+ if (is_null($this->sClass))
+ {
+ return array();
+ }
+ return array(
+ $this->aProperties['group_by'] => $this->oModelReflection->GetLabel($this->sClass, $this->aProperties['group_by']),
+ '_itop_'.$this->aProperties['agregation_function'].'_' => Dict::S('UI:GroupBy:'.$this->aProperties['agregation_function']));
+ }
+
+ /**
+ * @return array
+ * @throws DictExceptionMissingString
+ */
+ protected function GetAllowedFunctions($aFunctionAttributes)
+ {
+ $aFunctions = array();
+
+ if (!empty($aFunctionAttributes) || is_null($this->sClass))
+ {
+ $aFunctions['sum'] = Dict::S('UI:GroupBy:sum');
+ $aFunctions['avg'] = Dict::S('UI:GroupBy:avg');
+ $aFunctions['min'] = Dict::S('UI:GroupBy:min');
+ $aFunctions['max'] = Dict::S('UI:GroupBy:max');
+ }
+
+ return $aFunctions;
+ }
+
+ /**
+ * @return array
+ */
+ protected function GetNumericAttributes($sOql)
+ {
+ $aFunctionAttributes = array();
+ $oQuery = $this->oModelReflection->GetQuery($sOql);
+ $sClass = $oQuery->GetClass();
+ if (is_null($sClass))
+ {
+ return $aFunctionAttributes;
+ }
+ foreach($this->oModelReflection->ListAttributes($sClass) as $sAttCode => $sAttType)
+ {
+ switch ($sAttType)
+ {
+ case 'AttributeDecimal':
+ case 'AttributeDuration':
+ case 'AttributeInteger':
+ case 'AttributePercentage':
+ $sLabel = $this->oModelReflection->GetLabel($sClass, $sAttCode);
+ $aFunctionAttributes[$sAttCode] = $sLabel;
+ break;
+ }
+ }
+
+ return $aFunctionAttributes;
}
public function Update($aValues, $aUpdatedFields)
@@ -1052,6 +1174,15 @@ abstract class DashletGroupBy extends Dashlet
$oDashlet->bRedrawNeeded = true;
$oDashlet->bFormRedrawNeeded = true;
}
+ if (in_array('group_by', $aUpdatedFields) || in_array('agregation_attribute', $aUpdatedFields) || in_array('order_direction', $aUpdatedFields) || in_array('limit', $aUpdatedFields))
+ {
+ $oDashlet->bRedrawNeeded = true;
+ }
+ if (in_array('agregation_function', $aUpdatedFields))
+ {
+ $oDashlet->bRedrawNeeded = true;
+ $oDashlet->bFormRedrawNeeded = true;
+ }
return $oDashlet;
}
diff --git a/application/displayblock.class.inc.php b/application/displayblock.class.inc.php
index c23abd980..1574966de 100644
--- a/application/displayblock.class.inc.php
+++ b/application/displayblock.class.inc.php
@@ -285,7 +285,19 @@ class DisplayBlock
}
$oPage->add($this->GetRenderContent($oPage, $aExtraParams, $sId));
}
-
+
+ /**
+ * @param WebPage $oPage
+ * @param array $aExtraParams
+ * @param $sId
+ * @return string
+ * @throws ApplicationException
+ * @throws CoreException
+ * @throws CoreWarning
+ * @throws DictExceptionMissingString
+ * @throws MySQLException
+ * @throws Exception
+ */
public function GetRenderContent(WebPage $oPage, $aExtraParams = array(), $sId)
{
$sHtml = '';
@@ -400,6 +412,7 @@ class DisplayBlock
case 'count':
if (isset($aExtraParams['group_by']))
{
+ $sAlias = $this->m_oFilter->GetClassAlias();
if (isset($aExtraParams['group_by_label']))
{
$oGroupByExp = Expression::FromOQL($aExtraParams['group_by']);
@@ -408,7 +421,6 @@ class DisplayBlock
else
{
// Backward compatibility: group_by is simply a field id
- $sAlias = $this->m_oFilter->GetClassAlias();
$oGroupByExp = new FieldExpression($aExtraParams['group_by'], $sAlias);
$sGroupByLabel = MetaModel::GetLabel($this->m_oFilter->GetClass(), $aExtraParams['group_by']);
}
@@ -430,7 +442,42 @@ class DisplayBlock
$aGroupBy = array();
$aGroupBy['grouped_by_1'] = $oGroupByExp;
- $sSql = $this->m_oFilter->MakeGroupByQuery($aQueryParams, $aGroupBy, true);
+ $aQueryParams = array();
+ if (isset($aExtraParams['query_params']))
+ {
+ $aQueryParams = $aExtraParams['query_params'];
+ }
+ $aFunctions = array();
+ $aOrderBy = array();
+ $sAgregationFunction = 'count';
+ $sFctVar = '_itop_count_';
+ $sAgregationAttr = '';
+ if (isset($aExtraParams['agregation_function']) && !empty($aExtraParams['agregation_attribute']))
+ {
+ $sAgregationFunction = $aExtraParams['agregation_function'];
+ $sAgregationAttr = $aExtraParams['agregation_attribute'];
+ $oAttrExpr = Expression::FromOQL('`'.$sAlias.'`.`'.$sAgregationAttr.'`');
+ $oFctExpr = new FunctionExpression(strtoupper($sAgregationFunction), array($oAttrExpr));
+ $sFctVar = '_itop_'.$sAgregationFunction.'_';
+ $aFunctions = array($sFctVar => $oFctExpr);
+ }
+ if (!empty($sAgregationAttr))
+ {
+ $sClass = $this->m_oFilter->GetClass();
+ $sAgregationAttr = MetaModel::GetLabel($sClass, $sAgregationAttr);
+ }
+ $iLimit = 0;
+ if (isset($aExtraParams['limit']))
+ {
+ $iLimit = intval($aExtraParams['limit']);
+ }
+ if (isset($aExtraParams['order_direction']))
+ {
+ $aOrderBy = array($sFctVar => ($aExtraParams['order_direction'] === 'asc'));
+ }
+
+ $sSql = $this->m_oFilter->MakeGroupByQuery($aQueryParams, $aGroupBy, true, $aFunctions, $aOrderBy, $iLimit);
+
$aRes = CMDBSource::QueryToArray($sSql);
$aGroupBy = array();
@@ -443,7 +490,7 @@ class DisplayBlock
$aValues[$iRow] = $sValue;
$sHtmlValue = $oGroupByExp->MakeValueLabel($this->m_oFilter, $sValue, $sValue);
$aLabels[$iRow] = $sHtmlValue;
- $aGroupBy[$iRow] = (int) $aRow['_itop_count_'];
+ $aGroupBy[$iRow] = (int) $aRow[$sFctVar];
$iTotalCount += $aRow['_itop_count_'];
}
@@ -459,12 +506,12 @@ class DisplayBlock
$oSubsetSearch->AddConditionExpression($oCondition);
$sFilter = urlencode($oSubsetSearch->serialize());
- $aData[] = array ( 'group' => $aLabels[$iRow],
+ $aData[] = array ('group' => $aLabels[$iRow],
'value' => "$iCount"); // TO DO: add the context information
}
$aAttribs =array(
'group' => array('label' => $sGroupByLabel, 'description' => ''),
- 'value' => array('label'=> Dict::S('UI:GroupBy:Count'), 'description' => Dict::S('UI:GroupBy:Count+'))
+ 'value' => array('label'=> Dict::S('UI:GroupBy:'.$sAgregationFunction), 'description' => Dict::Format('UI:GroupBy:'.$sAgregationFunction.'+', $sAgregationAttr))
);
$sFormat = isset($aExtraParams['format']) ? $aExtraParams['format'] : 'UI:Pagination:HeaderNoSelection';
$sHtml .= $oPage->GetP(Dict::Format($sFormat, $iTotalCount));
@@ -924,18 +971,21 @@ class DisplayBlock
$sFilter = $this->m_oFilter->serialize();
$oContext = new ApplicationContext();
$sContextParam = $oContext->GetForLink();
+ $sAgregationFunction = isset($aExtraParams['agregation_function']) ? $aExtraParams['agregation_function'] : '';
+ $sAgregationAttr = isset($aExtraParams['agregation_attribute']) ? $aExtraParams['agregation_attribute'] : '';
+ $sLimit = isset($aExtraParams['limit']) ? $aExtraParams['limit'] : '';
+ $sOrderBy = isset($aExtraParams['order_by']) ? $aExtraParams['order_by'] : '';
+ $sOrderDirection = isset($aExtraParams['order_direction']) ? $aExtraParams['order_direction'] : '';
if (isset($aExtraParams['group_by_label']))
{
- $sUrl = json_encode(utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$sGroupBy{$sGroupByExpr}¶ms[group_by_label]={$aExtraParams['group_by_label']}¶ms[chart_type]=$sChartType¶ms[currentId]=$sId{$iChartCounter}&id=$sId{$iChartCounter}&filter=".urlencode($sFilter).'&'.$sContextParam);
+ $sUrl = json_encode(utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$sGroupBy{$sGroupByExpr}¶ms[group_by_label]={$aExtraParams['group_by_label']}¶ms[chart_type]=$sChartType¶ms[currentId]=$sId{$iChartCounter}¶ms[order_direction]=$sOrderDirection¶ms[order_by]=$sOrderBy¶ms[limit]=$sLimit¶ms[agregation_function]=$sAgregationFunction¶ms[agregation_attribute]=$sAgregationAttr&id=$sId{$iChartCounter}&filter=".urlencode($sFilter).'&'.$sContextParam);
}
else
{
- $sUrl = json_encode(utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$sGroupBy{$sGroupByExpr}¶ms[chart_type]=$sChartType¶ms[currentId]=$sId{$iChartCounter}&id=$sId{$iChartCounter}&filter=".urlencode($sFilter).'&'.$sContextParam);
+ $sUrl = json_encode(utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$sGroupBy{$sGroupByExpr}¶ms[chart_type]=$sChartType¶ms[currentId]=$sId{$iChartCounter}¶ms[order_direction]=$sOrderDirection¶ms[order_by]=$sOrderBy¶ms[limit]=$sLimit¶ms[agregation_function]=$sAgregationFunction¶ms[agregation_attribute]=$sAgregationAttr&id=$sId{$iChartCounter}&filter=".urlencode($sFilter).'&'.$sContextParam);
}
-
- $sType = ($sChartType == 'pie') ? 'pie' : 'bar';
-
+
$oPage->add_ready_script(
<<m_oFilter->GetClassAlias();
if (isset($aExtraParams['group_by_label']))
{
$oGroupByExp = Expression::FromOQL($aExtraParams['group_by']);
- $sGroupByLabel = $aExtraParams['group_by_label'];
}
else
{
// Backward compatibility: group_by is simply a field id
- $sAlias = $this->m_oFilter->GetClassAlias();
$oGroupByExp = new FieldExpression($aExtraParams['group_by'], $sAlias);
- $sGroupByLabel = MetaModel::GetLabel($this->m_oFilter->GetClass(), $aExtraParams['group_by']);
}
$aGroupBy = array();
$aGroupBy['grouped_by_1'] = $oGroupByExp;
- $sSql = $this->m_oFilter->MakeGroupByQuery($aQueryParams, $aGroupBy, true);
+ $aQueryParams = array();
+ if (isset($aExtraParams['query_params']))
+ {
+ $aQueryParams = $aExtraParams['query_params'];
+ }
+ $aFunctions = array();
+ $aOrderBy = array();
+ $sFctVar = '_itop_count_';
+ if (isset($aExtraParams['agregation_function']) && !empty($aExtraParams['agregation_attribute']))
+ {
+ $sAgregationFunction = $aExtraParams['agregation_function'];
+ $sAgregationAttr = $aExtraParams['agregation_attribute'];
+ $oAttrExpr = Expression::FromOQL('`'.$sAlias.'`.`'.$sAgregationAttr.'`');
+ $oFctExpr = new FunctionExpression(strtoupper($sAgregationFunction), array($oAttrExpr));
+ $sFctVar = '_itop_'.$sAgregationFunction.'_';
+ $aFunctions = array($sFctVar => $oFctExpr);
+ }
+ $iLimit = 0;
+ if (isset($aExtraParams['limit']))
+ {
+ $iLimit = intval($aExtraParams['limit']);
+ }
+ if (isset($aExtraParams['order_direction']))
+ {
+ $aOrderBy = array($sFctVar => ($aExtraParams['order_direction'] === 'asc'));
+ }
+
+ $sSql = $this->m_oFilter->MakeGroupByQuery($aQueryParams, $aGroupBy, true, $aFunctions, $aOrderBy, $iLimit);
$aRes = CMDBSource::QueryToArray($sSql);
$oContext = new ApplicationContext();
$sContextParam = $oContext->GetForLink();
@@ -980,9 +1055,9 @@ EOF
{
$sValue = $aRow['grouped_by_1'];
$sHtmlValue = $oGroupByExp->MakeValueLabel($this->m_oFilter, $sValue, $sValue);
- $aGroupBy[(int)$iRow] = (int) $aRow['_itop_count_'];
+ $aGroupBy[(int)$iRow] = (int) $aRow[$sFctVar];
$iTotalCount += $aRow['_itop_count_'];
- $aValues[] = array('label' => html_entity_decode(strip_tags($sHtmlValue), ENT_QUOTES, 'UTF-8'), 'label_html' => $sHtmlValue, 'value' => (int) $aRow['_itop_count_']);
+ $aValues[] = array('label' => html_entity_decode(strip_tags($sHtmlValue), ENT_QUOTES, 'UTF-8'), 'label_html' => $sHtmlValue, 'value' => (int) $aRow[$sFctVar]);
// Build the search for this subset
$oSubsetSearch = $this->m_oFilter->DeepClone();
diff --git a/dictionaries/en.dictionary.itop.ui.php b/dictionaries/en.dictionary.itop.ui.php
index 236abed14..7a846865a 100644
--- a/dictionaries/en.dictionary.itop.ui.php
+++ b/dictionaries/en.dictionary.itop.ui.php
@@ -1217,6 +1217,27 @@ When associated with a trigger, each action is given an "order" number, specifyi
'UI:DashletGroupByTable:Label' => 'Group By (table)',
'UI:DashletGroupByTable:Description' => 'List (Grouped by a field)',
+ // New in 2.5
+ 'UI:DashletGroupBy:Prop-Function' => 'Agregation function',
+ 'UI:DashletGroupBy:Prop-FunctionAttribute' => 'Function attribute',
+ 'UI:DashletGroupBy:Prop-OrderDirection' => 'Direction',
+ 'UI:DashletGroupBy:Prop-Limit' => 'Limit',
+
+ 'UI:DashletGroupBy:Order:asc' => 'Ascending',
+ 'UI:DashletGroupBy:Order:desc' => 'Descending',
+
+ 'UI:GroupBy:count' => 'Count',
+ 'UI:GroupBy:count+' => 'Number of elements',
+ 'UI:GroupBy:sum' => 'Sum',
+ 'UI:GroupBy:sum+' => 'Sum of %1$s',
+ 'UI:GroupBy:avg' => 'Average',
+ 'UI:GroupBy:avg+' => 'Average of %1$s',
+ 'UI:GroupBy:min' => 'Minimum',
+ 'UI:GroupBy:min+' => 'Minimum of %1$s',
+ 'UI:GroupBy:max' => 'Maximum',
+ 'UI:GroupBy:max+' => 'Maximum of %1$s',
+ // ---
+
'UI:DashletHeaderStatic:Label' => 'Header',
'UI:DashletHeaderStatic:Description' => 'Displays an horizontal separator',
'UI:DashletHeaderStatic:Prop-Title' => 'Title',
diff --git a/dictionaries/fr.dictionary.itop.ui.php b/dictionaries/fr.dictionary.itop.ui.php
index 53ce55c32..8f94ee4c3 100644
--- a/dictionaries/fr.dictionary.itop.ui.php
+++ b/dictionaries/fr.dictionary.itop.ui.php
@@ -160,7 +160,6 @@ Dict::Add('FR FR', 'French', 'Français', array(
'Class:User/Attribute:status+' => 'Est-ce que ce compte utilisateur est actif, ou non?',
'Class:User/Attribute:status/Value:enabled' => 'Actif',
'Class:User/Attribute:status/Value:disabled' => 'Désactivé',
- 'Class:User/Attribute:status' => 'Etat',
'Class:User/Error:LoginMustBeUnique' => 'Le login doit être unique - "%1s" est déjà utilisé.',
'Class:User/Error:AtLeastOneProfileIsNeeded' => 'L\'utilisateur doit avoir au moins un profil.',
'Class:UserInternal' => 'Utilisateur interne',
@@ -1054,6 +1053,27 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé
'UI:DashletGroupByTable:Label' => 'Table',
'UI:DashletGroupByTable:Description' => 'Table',
+ // New in 2.5
+ 'UI:DashletGroupBy:Prop-Function' => 'Fonction d\'agregation',
+ 'UI:DashletGroupBy:Prop-FunctionAttribute' => 'Attribut',
+ 'UI:DashletGroupBy:Prop-OrderDirection' => 'Type de tri',
+ 'UI:DashletGroupBy:Prop-Limit' => 'Limite',
+
+ 'UI:DashletGroupBy:Order:asc' => 'Croissant',
+ 'UI:DashletGroupBy:Order:desc' => 'Décroissant',
+
+ 'UI:GroupBy:count' => 'Nombre',
+ 'UI:GroupBy:count+' => 'Nombre d\'éléments',
+ 'UI:GroupBy:sum' => 'Somme',
+ 'UI:GroupBy:sum+' => 'Somme : %1$s',
+ 'UI:GroupBy:avg' => 'Moyenne',
+ 'UI:GroupBy:avg+' => 'Moyenne : %1$s',
+ 'UI:GroupBy:min' => 'Minimum',
+ 'UI:GroupBy:min+' => 'Minimum : %1$s',
+ 'UI:GroupBy:max' => 'Maximum',
+ 'UI:GroupBy:max+' => 'Maximum : %1$s',
+ // ---
+
'UI:DashletHeaderStatic:Label' => 'En-tête',
'UI:DashletHeaderStatic:Description' => 'En-tête présenté comme une barre horizontale',
'UI:DashletHeaderStatic:Prop-Title' => 'Titre',
diff --git a/js/dashlet.js b/js/dashlet.js
index 7794baf06..2112d4a20 100644
--- a/js/dashlet.js
+++ b/js/dashlet.js
@@ -102,14 +102,19 @@ $(function()
{
var oParams = {};
var oProperties = $('#dashlet_properties_'+this.options.dashlet_id);
- oProperties.find(':itop-property_field').each(function(){
- var oWidget = $(this).data('itopProperty_field');
- if (oWidget)
- {
- var oVal = oWidget._get_committed_value();
- oParams[oVal.name] = oVal.value;
- }
- });
+ oProperties.find('.itop-property-field').each(function(){
+ var oWidget = $(this).data('itopProperty_field');
+ if (oWidget == undefined)
+ {
+ oWidget = $(this).data('itopSelector_property_field');
+ }
+ if (oWidget && $(this).is(':visible'))
+ {
+ var oVal = oWidget._get_committed_value();
+ oParams[oVal.name] = oVal.value;
+ }
+ });
+
oParams.dashlet_id = this.options.dashlet_id;
oParams.dashlet_class = this.options.dashlet_class;
return oParams;
diff --git a/pages/ajax.render.php b/pages/ajax.render.php
index c396b1488..7c7f7bf94 100644
--- a/pages/ajax.render.php
+++ b/pages/ajax.render.php
@@ -965,7 +965,7 @@ try
foreach($aUpdatedProperties as $sProp)
{
$sDecodedProp = str_replace('attr_', '', $sProp); // Remove the attr_ prefix
- $aCurrentValues[$sDecodedProp] = $aPreviousValues[$sProp]; // Set the previous value
+ $aCurrentValues[$sDecodedProp] = (isset($aPreviousValues[$sProp]) ? $aPreviousValues[$sProp] : ''); // Set the previous value
$aUpdatedDecoded[] = $sDecodedProp;
}