浏览代码

- Ask for confirmation when doing a CSV import/synchro that is considered as "risky" (based on thresholds from the config file)
- Added a "Restart" button to quickly start over a CSV import/synchro

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@1004 a333f486-631f-4898-b8df-5754b55c2be0

dflaven 14 年之前
父节点
当前提交
a7b730ecf1
共有 4 个文件被更改,包括 197 次插入3 次删除
  1. 33 0
      core/config.class.inc.php
  2. 1 0
      dictionaries/dictionary.itop.ui.php
  3. 1 0
      dictionaries/fr.dictionary.itop.ui.php
  4. 162 3
      pages/csvimport.php

+ 33 - 0
core/config.class.inc.php

@@ -151,6 +151,39 @@ class Config
 			'source_of_value' => '',
 			'source_of_value' => '',
 			'show_in_conf_sample' => false,
 			'show_in_conf_sample' => false,
 		),
 		),
+		// Levels that trigger a confirmation in the CSV import/synchro wizard
+		'csv_import_min_object_confirmation' => array(
+			'type' => 'integer',
+			'description' => 'Minimum number of objects to check for the confirmation percentages',
+			'default' => 3,
+			'value' => 3,
+			'source_of_value' => '',
+			'show_in_conf_sample' => false,
+		),
+		'csv_import_errors_percentage' => array(
+			'type' => 'integer',
+			'description' => 'Percentage of errors that trigger a confirmation in the CSV import',
+			'default' => 50,
+			'value' => 50,
+			'source_of_value' => '',
+			'show_in_conf_sample' => false,
+		),
+		'csv_import_modifications_percentage' => array(
+			'type' => 'integer',
+			'description' => 'Percentage of modifications that trigger a confirmation in the CSV import',
+			'default' => 50,
+			'value' => 50,
+			'source_of_value' => '',
+			'show_in_conf_sample' => false,
+		),
+		'csv_import_creations_percentage' => array(
+			'type' => 'integer',
+			'description' => 'Percentage of creations that trigger a confirmation in the CSV import',
+			'default' => 50,
+			'value' => 50,
+			'source_of_value' => '',
+			'show_in_conf_sample' => false,
+		),
 	);
 	);
 
 
 	public function IsProperty($sPropCode)
 	public function IsProperty($sPropCode)

+ 1 - 0
dictionaries/dictionary.itop.ui.php

@@ -336,6 +336,7 @@ Dict::Add('EN US', 'English', 'English', array(
 	'UI:Button:Cancel' => 'Cancel',
 	'UI:Button:Cancel' => 'Cancel',
 	'UI:Button:Apply' => 'Apply',
 	'UI:Button:Apply' => 'Apply',
 	'UI:Button:Back' => ' << Back ',
 	'UI:Button:Back' => ' << Back ',
+	'UI:Button:Restart' => ' |<< Restart ',
 	'UI:Button:Next' => ' Next >> ',
 	'UI:Button:Next' => ' Next >> ',
 	'UI:Button:Finish' => ' Finish ',
 	'UI:Button:Finish' => ' Finish ',
 	'UI:Button:DoImport' => ' Run the Import ! ',
 	'UI:Button:DoImport' => ' Run the Import ! ',

+ 1 - 0
dictionaries/fr.dictionary.itop.ui.php

@@ -338,6 +338,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
 	'UI:Button:Cancel' => 'Annuler',
 	'UI:Button:Cancel' => 'Annuler',
 	'UI:Button:Apply' => 'Appliquer',
 	'UI:Button:Apply' => 'Appliquer',
 	'UI:Button:Back' => ' << Retour ',
 	'UI:Button:Back' => ' << Retour ',
+	'UI:Button:Restart' => ' |<< Recommencer ',
 	'UI:Button:Next' => ' Suite >> ',
 	'UI:Button:Next' => ' Suite >> ',
 	'UI:Button:Finish' => ' Terminer ',
 	'UI:Button:Finish' => ' Terminer ',
 	'UI:Button:DoImport' => ' Lancer l\'import ! ',
 	'UI:Button:DoImport' => ' Lancer l\'import ! ',

+ 162 - 3
pages/csvimport.php

@@ -524,6 +524,8 @@ try
 			$sHtml .= "<td class=\"$sCSSMessageClass\" style=\"background-color:#f1f1f1;\">$sMessage</td>";
 			$sHtml .= "<td class=\"$sCSSMessageClass\" style=\"background-color:#f1f1f1;\">$sMessage</td>";
 			$sHtml .= '</tr>';
 			$sHtml .= '</tr>';
 		}
 		}
+		
+		$iUnchanged = count($aRes) - $iErrors - $iModified - $iCreated;
 		$sHtml .= '</table>';
 		$sHtml .= '</table>';
 		$oPage->add('<div class="wizContainer">');
 		$oPage->add('<div class="wizContainer">');
 		$oPage->add('<form enctype="multipart/form-data" id="wizForm" method="post">');
 		$oPage->add('<form enctype="multipart/form-data" id="wizForm" method="post">');
@@ -578,10 +580,43 @@ try
 		$oPage->add('<div style="overflow-y:auto" class="white">');
 		$oPage->add('<div style="overflow-y:auto" class="white">');
 		$oPage->add($sHtml);
 		$oPage->add($sHtml);
 		$oPage->add('</div> <!-- end of preview -->');
 		$oPage->add('</div> <!-- end of preview -->');
-		$oPage->add('<p><input type="button" value="'.Dict::S('UI:Button:Back').'" onClick="CSVGoBack()"/>&nbsp;&nbsp;');
+		$oPage->add('<p>');
+		if($bSimulate)
+		{
+			$oPage->add('<input type="button" value="'.Dict::S('UI:Button:Restart').'" onClick="CSVRestart()"/>&nbsp;&nbsp;');
+		}
+		$oPage->add('<input type="button" value="'.Dict::S('UI:Button:Back').'" onClick="CSVGoBack()"/>&nbsp;&nbsp;');
+
+		$bShouldConfirm = false;
 		if ($bSimulate)
 		if ($bSimulate)
 		{
 		{
-			$oPage->add('<input type="submit" value="'.Dict::S('UI:Button:DoImport').'" onClick="$(\'#wizForm\').block();"/></p>');
+			// if there are *too many* changes, we should ask the user for a confirmation
+			if (count($aRes) >= utils::GetConfig()->Get('csv_import_min_object_confirmation'))
+			{
+				$fErrorsPercentage = (100.0*$iErrors)/count($aRes);
+				if ($fErrorsPercentage >= utils::GetConfig()->Get('csv_import_errors_percentage'))
+				{
+					$sMessage = sprintf("%.0f %% of the loaded objects will be modified.", $fErrorsPercentage);
+					$bShouldConfirm = true;
+				}
+				$fCreatedPercentage = (100.0*$iCreated)/count($aRes);
+				if ($fCreatedPercentage >= utils::GetConfig()->Get('csv_import_creations_percentage'))
+				{
+					$sMessage = sprintf("%.0f %% of the loaded objects will be modified.", $fCreatedPercentage);
+					$bShouldConfirm = true;
+				}
+				$fModifiedPercentage = (100.0*$iModified)/count($aRes);
+				if ($fModifiedPercentage >= utils::GetConfig()->Get('csv_import_modifications_percentage'))
+				{
+					$sMessage = sprintf("%.0f %% of the loaded objects will be modified.", $fModifiedPercentage);
+					$bShouldConfirm = true;
+				}
+				
+			}
+			$iCount = count($aRes);
+			//$oPage->add('<input type="submit" value="'.Dict::S('UI:Button:DoImport').'" onClick="$(\'#wizForm\').block();"/></p>');
+			$sConfirm = $bShouldConfirm ? 'true' : 'false';
+			$oPage->add('<input type="button" value="'.Dict::S('UI:Button:DoImport')."\" onClick=\"return DoSubmit($sConfirm);\"/></p>");
 		}
 		}
 		else
 		else
 		{
 		{
@@ -589,6 +624,40 @@ try
 		}
 		}
 		$oPage->add('</form>');
 		$oPage->add('</form>');
 		$oPage->add('</div> <!-- end of wizForm -->');
 		$oPage->add('</div> <!-- end of wizForm -->');
+		
+		
+		if ($bShouldConfirm)
+		{
+			$oPage->add('<div id="dlg_confirmation" title="Please confirm the operation">');
+			$oPage->add('<p style="text-align:center"><b>'.$sMessage.'</b></p>');
+			$oPage->add('<p style="text-align:center">Are you sure you want to do this ?</p>');
+			$oPage->add('<div id="confirmation_chart"></div>');
+			$oPage->add('</div> <!-- end of dlg_confirmation -->');
+			$oPage->add_ready_script(
+<<<EOF
+	$('#dlg_confirmation').dialog( 
+		{
+			height: 'auto',
+			width: 500,
+			modal:true, 
+			autoOpen: false, 
+			buttons:
+			{
+				'Yes': RunImport,
+				'No': CancelImport 
+			} 
+		});
+		swfobject.embedSWF(	"../images/open-flash-chart.swf", 
+							"confirmation_chart", 
+							"100%", "300","9.0.0",
+							"expressInstall.swf",
+							{}, 
+							{'wmode': 'transparent'}
+						);
+EOF
+);
+		}
+		
 		$oPage->add_script(
 		$oPage->add_script(
 <<< EOF
 <<< EOF
 function CSVGoBack()
 function CSVGoBack()
@@ -598,10 +667,92 @@ function CSVGoBack()
 	
 	
 }
 }
 
 
+function CSVRestart()
+{
+	$('input[name=step]').val(1);
+	$('#wizForm').submit();
+	
+}
+
 function ToggleRows(sCSSClass)
 function ToggleRows(sCSSClass)
 {
 {
 	$('.'+sCSSClass).toggle();
 	$('.'+sCSSClass).toggle();
 }
 }
+
+function DoSubmit(bConfirm)
+{
+	if (bConfirm) //Ask for a confirmation
+	{
+		$('#dlg_confirmation').dialog('open');
+	}
+	else
+	{
+		// Submit the form
+		$('#wizForm').block();
+		$('#wizForm').submit();
+	}
+	return false;
+}
+
+function CancelImport()
+{
+	$('#dlg_confirmation').dialog('close');
+}
+
+function RunImport()
+{
+	$('#dlg_confirmation').dialog('close');
+	// Submit the form
+	$('#wizForm').block();
+	$('#wizForm').submit();
+}
+
+function open_flash_chart_data()
+{
+	var oResult = {
+		"elements": [
+			{
+				"type": "pie",
+				"tip": "#label# - #val# (#percent#)",
+				"font-size": 14,
+				"colours":
+				[
+					"#FF6666",
+					"#6666FF",
+					"#66FF66",
+					"#666666",
+				],
+				"values": 
+				[
+					{
+						"value": $iErrors,
+						"label": "Errors",
+						"alpha": 0.9
+					},
+					{
+						"value": $iModified,
+						"label": "Modified",
+						"alpha": 0.9
+					},
+					{
+						"value": $iCreated,
+						"label": "Created",
+						"alpha": 0.9
+					},
+					{
+						"value": $iUnchanged,
+						"label": "Unchanged",
+						"alpha": 0.9
+					}
+				]
+			}
+		],
+		"x_axis": null,
+		"font-size": 14,
+		"bg_colour": "#EEEEEE"
+	};
+	return JSON.stringify(oResult);
+}
 EOF
 EOF
 	);
 	);
 		if ($iErrors > 0)
 		if ($iErrors > 0)
@@ -716,7 +867,8 @@ EOF
 				$oPage->add('<input type="hidden" name="synchro_update['.$sKey.']" value="'.$value.'"/>');				
 				$oPage->add('<input type="hidden" name="synchro_update['.$sKey.']" value="'.$value.'"/>');				
 			}
 			}
 		}
 		}
-		$oPage->add('<p><input type="button" value="'.Dict::S('UI:Button:Back').'" onClick="CSVGoBack()"/>&nbsp;&nbsp;');
+		$oPage->add('<p><input type="button" value="'.Dict::S('UI:Button:Restart').'" onClick="CSVRestart()"/>&nbsp;&nbsp;');
+		$oPage->add('<input type="button" value="'.Dict::S('UI:Button:Back').'" onClick="CSVGoBack()"/>&nbsp;&nbsp;');
 		$oPage->add('<input type="submit" value="'.Dict::S('UI:Button:SimulateImport').'"/></p>');
 		$oPage->add('<input type="submit" value="'.Dict::S('UI:Button:SimulateImport').'"/></p>');
 		$oPage->add('</form>');
 		$oPage->add('</form>');
 		$oPage->add('</div>');
 		$oPage->add('</div>');
@@ -746,6 +898,13 @@ EOF
 		
 		
 	}
 	}
 
 
+	function CSVRestart()
+	{
+		$('input[name=step]').val(1);
+		$('#wizForm').submit();
+		
+	}
+
 	var ajax_request = null;
 	var ajax_request = null;
 	
 	
 	function DoMapping()
 	function DoMapping()