Dashboards - Fixed issues + added 3 confirmation (on exit, save or cancel)

SVN:trunk[2199]
This commit is contained in:
Romain Quetiez
2012-09-21 15:15:05 +00:00
parent 4979a653ee
commit 2eddb57cbd
10 changed files with 161 additions and 23 deletions

View File

@@ -203,7 +203,7 @@ abstract class Dashboard
$oField = new DesignerLongTextField('dashboard_title', Dict::S('UI:DashboardEdit:DashboardTitle'), $this->sTitle);
$oForm->AddField($oField);
$this->SetFormParams($oForm);
$oForm->RenderAsPropertySheet($oPage);
$oForm->RenderAsPropertySheet($oPage, false, ':itop-dashboard');
$oPage->add('</div>');
$oPage->add_ready_script(
@@ -213,7 +213,7 @@ abstract class Dashboard
var sLayoutClass = $(this).val();
$(':itop-dashboard').dashboard('option', {layout_class: sLayoutClass});
} );
$('#row_attr_dashboard_title').property_field('option', {'do_apply': function() {
$('#row_attr_dashboard_title').property_field('option', {parent_selector: ':itop-dashboard', auto_apply: false, 'do_apply': function() {
var sTitle = $('#attr_dashboard_title').val();
$(':itop-dashboard').dashboard('option', {title: sTitle});
return true;
@@ -272,7 +272,7 @@ EOF
$oPage->add('<div class="dashlet_properties" id="dashlet_properties_'.$sId.'" style="display:none">');
$oForm = $oDashlet->GetForm();
$this->SetFormParams($oForm);
$oForm->RenderAsPropertySheet($oPage);
$oForm->RenderAsPropertySheet($oPage, false, ':itop-dashboard');
$oPage->add('</div>');
}
}
@@ -430,9 +430,15 @@ EOF
$sLayoutClass = addslashes($this->sLayoutClass);
$sTitle = addslashes($this->sTitle);
$sUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php';
$sExitConfirmationMessage = addslashes(Dict::S('UI:NavigateAwayConfirmationMessage'));
$sCancelConfirmationMessage = addslashes(Dict::S('UI:CancelConfirmationMessage'));
$sAutoApplyConfirmationMessage = addslashes(Dict::S('UI:AutoApplyConfirmationMessage'));
$oPage->add_ready_script(
<<<EOF
window.bLeavingOnUserAction = false;
$('#dashboard_editor').dialog({
height: $('body').height() - 50,
width: $('body').width() - 50,
@@ -440,9 +446,34 @@ $('#dashboard_editor').dialog({
title: '$sDialogTitle',
buttons: [
{ text: "$sOkButtonLabel", click: function() {
$('#dashboard_editor .ui-layout-center').dashboard('save'); /* $(this).dialog( "close" ); $(this).remove(); */
var oDashboard = $(':itop-dashboard').data('dashboard');
if (oDashboard.is_dirty())
{
if (!confirm('$sAutoApplyConfirmationMessage'))
{
return;
}
else
{
oDashboard.apply_changes();
}
}
window.bLeavingOnUserAction = true;
oDashboard.save();
} },
{ text: "$sCancelButtonLabel", click: function() {
var oDashboard = $(':itop-dashboard').data('dashboard');
if (oDashboard.is_modified())
{
if (!confirm('$sCancelConfirmationMessage'))
{
return;
}
}
window.bLeavingOnUserAction = true;
$(this).dialog( "close" );
$(this).remove();
} },
{ text: "$sCancelButtonLabel", click: function() { $(this).dialog( "close" ); $(this).remove(); } },
],
close: function() { $(this).remove(); }
});
@@ -497,6 +528,25 @@ $('#dashboard_editor').layout({
},
}
});
window.onbeforeunload = function() {
if (!window.bLeavingOnUserAction)
{
var oDashboard = $(':itop-dashboard').data('dashboard');
if (oDashboard)
{
if (oDashboard.is_dirty())
{
return '$sExitConfirmationMessage';
}
if (oDashboard.is_modified())
{
return '$sExitConfirmationMessage';
}
}
}
// return nothing ! safer for IE
};
EOF
);
$oPage->add_ready_script("");

View File

@@ -938,13 +938,13 @@ class DashletHeaderDynamic extends Dashlet
catch(Exception $e)
{
$oField = new DesignerTextField('group_by', Dict::S('UI:DashletHeaderDynamic:Prop-GroupBy'), $this->aProperties['group_by']);
$oField->SetMandatory();
$oField->SetReadOnly();
}
$oForm->AddField($oField);
$oField = new DesignerComboField('values', Dict::S('UI:DashletHeaderDynamic:Prop-Values'), $this->aProperties['values']);
$oField->MultipleSelection(true);
if (MetaModel::IsValidAttCode($sClass, $this->aProperties['group_by']))
if (isset($sClass) && MetaModel::IsValidAttCode($sClass, $this->aProperties['group_by']))
{
$aValues = MetaModel::GetAllowedValues_att($sClass, $this->aProperties['group_by']);
$oField->SetAllowedValues($aValues);

View File

@@ -144,7 +144,7 @@ class DesignerForm
}
public function RenderAsPropertySheet($oP, $bReturnHTML = false)
public function RenderAsPropertySheet($oP, $bReturnHTML = false, $sNotifyParentSelector = null)
{
$sReturn = '';
$sActionUrl = addslashes($this->sSubmitTo);
@@ -183,9 +183,11 @@ class DesignerForm
{
$sReturn .= $sValidationFields;
}
$sNotifyParentSelectorJS = is_null($sNotifyParentSelector) ? 'null' : "'".addslashes($sNotifyParentSelector)."'";
$sAutoApply = $oField->IsAutoApply() ? 'true' : 'false';
$this->AddReadyScript(
<<<EOF
$('#row_$sFieldId').property_field({field_id: '$sFieldId', value: '', submit_to: '$sActionUrl', submit_parameters: $sJSSubmitParams });
$('#row_$sFieldId').property_field({parent_selector: $sNotifyParentSelectorJS, field_id: '$sFieldId', auto_apply: $sAutoApply, value: '', submit_to: '$sActionUrl', submit_parameters: $sJSSubmitParams });
EOF
);
}
@@ -482,6 +484,7 @@ class DesignerFormField
protected $oForm;
protected $bMandatory;
protected $bReadOnly;
protected $bAutoApply;
public function __construct($sCode, $sLabel, $defaultValue)
{
@@ -490,6 +493,7 @@ class DesignerFormField
$this->defaultValue = $defaultValue;
$this->bMandatory = false;
$this->bReadOnly = false;
$this->bAutoApply = false;
}
public function GetCode()
@@ -517,7 +521,17 @@ class DesignerFormField
{
return ($this->oForm->IsReadOnly() || $this->bReadOnly);
}
public function SetAutoApply($bAutoApply)
{
$this->bAutoApply = $bAutoApply;
}
public function IsAutoApply()
{
return $this->bAutoApply;
}
public function Render(WebPage $oP, $sFormId, $sRenderMode='dialog')
{
$sId = $this->oForm->GetFieldId($this->sCode);
@@ -663,6 +677,8 @@ class DesignerComboField extends DesignerFormField
$this->aAllowedValues = array();
$this->bMultipleSelection = false;
$this->bOtherChoices = false;
$this->bAutoApply = true;
}
public function SetAllowedValues($aAllowedValues)
@@ -740,6 +756,7 @@ class DesignerBooleanField extends DesignerFormField
public function __construct($sCode, $sLabel = '', $defaultValue = '')
{
parent::__construct($sCode, $sLabel, $defaultValue);
$this->bAutoApply = true;
}
public function Render(WebPage $oP, $sFormId, $sRenderMode='dialog')
@@ -812,6 +829,7 @@ class DesignerIconSelectionField extends DesignerFormField
public function __construct($sCode, $sLabel = '', $defaultValue = '')
{
parent::__construct($sCode, $sLabel, $defaultValue);
$this->bAutoApply = true;
}
public function SetAllowedValues($aAllowedValues)

View File

@@ -1202,8 +1202,8 @@ td.prop_value {
tr.itop-property-field-modified td {
background: #fbb;
}
tr.itop-property-field-modified td.prop_value.hover {
background: #fbb;
tr.itop-property-field-modified td.hover {
background: #f99;
}
td.prop_value textarea, td.prop_value input[type=text]{
width: 98%;

View File

@@ -960,6 +960,8 @@ When associated with a trigger, each action is given an "order" number, specifyi
'UI:FavoriteOtherSettings' => 'Other Settings',
'UI:Favorites:Default_X_ItemsPerPage' => 'Default length for lists: %1$s items per page',
'UI:NavigateAwayConfirmationMessage' => 'Any modification will be discarded.',
'UI:CancelConfirmationMessage' => 'You will loose your changes. Continue anyway?',
'UI:AutoApplyConfirmationMessage' => 'Some changes have not been applied yet. Do you want itop to take them into account?',
'UI:Create_Class_InState' => 'Create the %1$s in state: ',
'UI:OrderByHint_Values' => 'Sort order: %1$s',
'UI:Menu:AddToDashboard' => 'Add To Dashboard...',

View File

@@ -804,6 +804,8 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé
'UI:FavoriteOtherSettings' => 'Autres réglages',
'UI:Favorites:Default_X_ItemsPerPage' => 'Longueur par défaut des listes: %1$s éléments par page',
'UI:NavigateAwayConfirmationMessage' => 'Toute modification sera perdue.',
'UI:CancelConfirmationMessage' => 'Vous allez perdre vos modifications. Voulez-vous continuer ?',
'UI:AutoApplyConfirmationMessage' => 'Des modifications n\'ont pas encore été prises en compte. Voulez-vous qu\'elles soient prises en compte automatiquement ?',
'UI:Create_Class_InState' => 'Créer l\'objet %1$s dans l\'état: ',
'UI:OrderByHint_Values' => 'Ordre de tri: %1$s',
'UI:Menu:AddToDashboard' => 'Ajouter au Tableau de Bord...',

View File

@@ -24,10 +24,13 @@ $(function()
var me = this;
this.element
.addClass('itop-dashboard');
.addClass('itop-dashboard')
.bind('mark_as_modified.itop-dashboard', function(){me.mark_as_modified();} );
this.ajax_div = $('<div></div>').appendTo(this.element);
this._make_draggable();
this.bModified = false;
},
// called when created, and later when changing options
@@ -96,6 +99,32 @@ $(function()
return oState;
},
// Modified means: at least one change has been applied
mark_as_modified: function()
{
this.bModified = true;
},
is_modified: function()
{
return this.bModified;
},
// Dirty means: at least one change has not been committed yet
is_dirty: function()
{
if ($('#dashboard_editor .ui-layout-east .itop-property-field-modified').size() > 0)
{
return true;
}
else
{
return false;
}
},
// Force the changes of all the properties being "dirty"
apply_changes: function()
{
$('#dashboard_editor .ui-layout-east .itop-property-field-modified').trigger('apply_changes');
},
save: function()
{
var oParams = this._get_state(this.options.submit_parameters);

View File

@@ -20,11 +20,30 @@ $(function()
this.element
.addClass('itop-dashlet')
.bind('click.itop-dashlet', function(event) { me._on_click(event); } );
this.closeBox = $('<div class="close-box"/>');
this.closeBox.click(function() { me._remove_dashlet(); }).hide().prependTo(this.element);
this._update();
},
// to call when the contents are changed
_update: function()
{
var me = this;
this.closeBox = $('<div class="close-box"/>');
this.closeBox
.click(function() { me._remove_dashlet(); })
.prependTo(this.element);
if (this.element.hasClass('dashlet-selected'))
{
this.closeBox.show();
}
else
{
this.closeBox.hide();
}
},
// called when created, and later when changing options
_refresh: function()
{
@@ -47,6 +66,7 @@ $(function()
{
// in 1.9 would use _superApply
$.Widget.prototype._setOptions.apply( this, arguments );
this._update();
},
// _setOption is called for each individual option that is changing
_setOption: function( key, value )

View File

@@ -8,21 +8,27 @@ $(function()
// default options
options:
{
parent_selector: null,
field_id: '',
submit_to: 'index.php',
submit_parameters: {operation: 'async_action'},
do_apply: null,
do_cancel: null
do_cancel: null,
auto_apply: false
},
// the constructor
_create: function()
{
this.element.addClass( "itop-property-field" );
var me = this;
this.element
.addClass( "itop-property-field" )
.bind('apply_changes.itop-property-field', function(){me._do_apply();} );
this.bModified = false;
var me = this;
if (this.options.field_id != '')
{
$('#'+this.options.field_id).bind('change.itop-property-field', function() { me._on_change(); });
@@ -80,6 +86,10 @@ $(function()
if (new_value != this.value)
{
this.bModified = true;
if (this.options.auto_apply)
{
this._do_apply();
}
}
else
{
@@ -105,6 +115,10 @@ $(function()
},
_do_apply: function()
{
if (this.options.parent_selector)
{
$(this.options.parent_selector).trigger('mark_as_modified');
}
if (this.options.do_apply)
{
// specific behavior...
@@ -214,15 +228,18 @@ function ValidateWithPattern(sFieldId, bMandatory, sPattern, sFormId)
re = new RegExp(sPattern);
bValid = re.test(currentVal);
}
if (oFormValidation[sFormId] == undefined) oFormValidation[sFormId] = [];
if (!bValid)
{
$('#v_'+sFieldId).addClass('ui-state-error');
if (oFormValidation[sFormId] == undefined) oFormValidation[sFormId] = [];
oFormValidation[sFormId].push(sFieldId);
}
else
{
$('#v_'+sFieldId).removeClass('ui-state-error');
// Remove the element from the array
iFieldIdPos = oFormValidation[sFormId].indexOf(sFieldId);
oFormValidation[sFormId].splice(iFieldIdPos, 1);
}
}

View File

@@ -696,7 +696,7 @@ try
// but is executed BEFORE all 'ready_scripts'
$oForm = $oDashlet->GetForm(); // Rebuild the form since the values/content changed
$oForm->SetSubmitParams(utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php', array('operation' => 'update_dashlet_property'));
$sHtml = addslashes($oForm->RenderAsPropertySheet($oPage, true /* bReturnHtml */));
$sHtml = addslashes($oForm->RenderAsPropertySheet($oPage, true /* bReturnHtml */, ':itop-dashboard'));
$sHtml = str_replace("\n", '', $sHtml);
$sHtml = str_replace("\r", '', $sHtml);
$oPage->add_script("$('#dashlet_properties_$sDashletId').html('$sHtml')"); // in ajax web page add_script has the same effect as add_ready_script // but is executed BEFORE all 'ready_scripts'
@@ -742,14 +742,14 @@ try
$sHtml = str_replace("\n", '', $sHtml);
$sHtml = str_replace("\r", '', $sHtml);
$oPage->add_script("$('#dashlet_$sDashletId').html('$sHtml')"); // in ajax web page add_script has the same effect as add_ready_script
$oPage->add_script("$('#dashlet_$sDashletId').html('$sHtml');"); // in ajax web page add_script has the same effect as add_ready_script
// but is executed BEFORE all 'ready_scripts'
}
if ($oDashlet->IsFormRedrawNeeded())
{
$oForm = $oDashlet->GetForm(); // Rebuild the form since the values/content changed
$oForm->SetSubmitParams(utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php', array('operation' => 'update_dashlet_property'));
$sHtml = addslashes($oForm->RenderAsPropertySheet($oPage, true /* bReturnHtml */));
$sHtml = addslashes($oForm->RenderAsPropertySheet($oPage, true /* bReturnHtml */, ':itop-dashboard'));
$sHtml = str_replace("\n", '', $sHtml);
$sHtml = str_replace("\r", '', $sHtml);
$oPage->add_script("$('#dashlet_properties_$sDashletId').html('$sHtml')"); // in ajax web page add_script has the same effect as add_ready_script // but is executed BEFORE all 'ready_scripts'