From 68a1c0f0cb5742f05a3a95ae016750208a933612 Mon Sep 17 00:00:00 2001 From: vdumas Date: Wed, 7 Jun 2023 20:17:21 +0200 Subject: [PATCH] =?UTF-8?q?N=C2=B01350=20-=20Audit=20result=20and=20audit?= =?UTF-8?q?=20configuration:=20add=20navigation=20from=20one=20to=20the=20?= =?UTF-8?q?other?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/audit.category.class.inc.php | 18 +- application/audit.domain.class.inc.php | 21 +- application/audit.rule.class.inc.php | 39 +- dictionaries/en.dictionary.itop.ui.php | 262 +++++++------ dictionaries/fr.dictionary.itop.ui.php | 476 ++++++++++++----------- pages/audit.php | 279 ++++++------- 6 files changed, 571 insertions(+), 524 deletions(-) diff --git a/application/audit.category.class.inc.php b/application/audit.category.class.inc.php index 44a5ab128..d2c3ab0ee 100644 --- a/application/audit.category.class.inc.php +++ b/application/audit.category.class.inc.php @@ -74,15 +74,23 @@ class AuditCategory extends cmdbAbstractObject public function GetReportColor($iTotal, $iErrors) { $sResult = 'red'; - if ( ($iTotal == 0) || ($iErrors / $iTotal) <= ($this->Get('ok_error_tolerance') / 100) ) - { + if ( ($iTotal == 0) || ($iErrors / $iTotal) <= ($this->Get('ok_error_tolerance') / 100) ) { $sResult = 'green'; - } - else if ( ($iErrors / $iTotal) <= ($this->Get('warning_error_tolerance') / 100) ) - { + } else if (($iErrors / $iTotal) <= ($this->Get('warning_error_tolerance') / 100)) { $sResult = 'orange'; } + return $sResult; } + + public static function GetShortcutActions($sFinalClass) + { + $aShortcutActions = parent::GetShortcutActions($sFinalClass); + if (!in_array('UI:Menu:RunAudit', $aShortcutActions)) { + $aShortcutActions[] = 'UI:Menu:RunAudit'; + } + + return $aShortcutActions; + } } ?> diff --git a/application/audit.domain.class.inc.php b/application/audit.domain.class.inc.php index fbe03a207..2980292e9 100644 --- a/application/audit.domain.class.inc.php +++ b/application/audit.domain.class.inc.php @@ -47,19 +47,30 @@ class AuditDomain extends cmdbAbstractObject 'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-album.svg'), ); MetaModel::Init_Params($aParams); - MetaModel::Init_AddAttribute(new AttributeString("name", array("description"=>"Short name for this category", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); - MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array()))); - MetaModel::Init_AddAttribute(new AttributeImage("icon", array("is_null_allowed"=>true, "depends_on"=>array(), "display_max_width"=>96, "display_max_height"=>96, "storage_max_width"=>256, "storage_max_height"=>256, "default_image"=>null, "always_load_in_tables"=>false))); - MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("categories_list", array("linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "domain_id", "ext_key_to_remote" => "category_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => array()))); + MetaModel::Init_AddAttribute(new AttributeString("name", array("description" => "Short name for this category", "allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => array()))); + MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => array()))); + MetaModel::Init_AddAttribute(new AttributeImage("icon", array("is_null_allowed" => true, "depends_on" => array(), "display_max_width" => 96, "display_max_height" => 96, "storage_max_width" => 256, "storage_max_height" => 256, "default_image" => null, "always_load_in_tables" => false))); + MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("categories_list", + array("linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "domain_id", "ext_key_to_remote" => "category_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => array()))); // Display lists MetaModel::Init_SetZListItems('details', array('name', 'description', 'icon', 'categories_list')); // Attributes to be displayed for the complete details - MetaModel::Init_SetZListItems('list', array('description', )); // Attributes to be displayed for a list + MetaModel::Init_SetZListItems('list', array('description',)); // Attributes to be displayed for a list // Search criteria MetaModel::Init_SetZListItems('standard_search', array('description')); // Criteria of the std search form MetaModel::Init_SetZListItems('default_search', array('name', 'description')); // Criteria of the default search form } + public static function GetShortcutActions($sFinalClass) + { + $aShortcutActions = parent::GetShortcutActions($sFinalClass); + if (!in_array('UI:Menu:RunAudit', $aShortcutActions)) { + $aShortcutActions[] = 'UI:Menu:RunAudit'; + } + + return $aShortcutActions; + } + } /** diff --git a/application/audit.rule.class.inc.php b/application/audit.rule.class.inc.php index 5de1cd0a1..a8f82d738 100644 --- a/application/audit.rule.class.inc.php +++ b/application/audit.rule.class.inc.php @@ -35,23 +35,23 @@ class AuditRule extends cmdbAbstractObject { $aParams = array ( - "category" => "application, grant_by_profile", - "key_type" => "autoincrement", - "name_attcode" => "name", - "state_attcode" => "", - "reconc_keys" => array('name'), - "db_table" => "priv_auditrule", - "db_key_field" => "id", + "category" => "application, grant_by_profile", + "key_type" => "autoincrement", + "name_attcode" => "name", + "state_attcode" => "", + "reconc_keys" => array('name'), + "db_table" => "priv_auditrule", + "db_key_field" => "id", "db_finalclass_field" => "", - 'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit.svg'), + 'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit.svg'), ); MetaModel::Init_Params($aParams); - MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); - MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array()))); - MetaModel::Init_AddAttribute(new AttributeOQL("query", array("allowed_values"=>null, "sql"=>"query", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); - MetaModel::Init_AddAttribute(new AttributeEnum("valid_flag", array("allowed_values"=>new ValueSetEnum('true,false'), "sql"=>"valid_flag", "default_value"=>"true", "is_null_allowed"=>false, "depends_on"=>array()))); - MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", array("allowed_values"=>null, "sql"=>"category_id", "targetclass"=>"AuditCategory", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array()))); - MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", array("allowed_values"=>null, "extkey_attcode"=> 'category_id', "target_attcode"=>"name"))); + MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => array()))); + MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => array()))); + MetaModel::Init_AddAttribute(new AttributeOQL("query", array("allowed_values" => null, "sql" => "query", "default_value" => "", "is_null_allowed" => false, "depends_on" => array()))); + MetaModel::Init_AddAttribute(new AttributeEnum("valid_flag", array("allowed_values" => new ValueSetEnum('true,false'), "sql" => "valid_flag", "default_value" => "true", "is_null_allowed" => false, "depends_on" => array()))); + MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", array("allowed_values" => null, "sql" => "category_id", "targetclass" => "AuditCategory", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => array()))); + MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", array("allowed_values" => null, "extkey_attcode" => 'category_id', "target_attcode" => "name"))); // Display lists MetaModel::Init_SetZListItems('details', array('category_id', 'name', 'description', 'query', 'valid_flag')); // Attributes to be displayed for the complete details @@ -60,5 +60,16 @@ class AuditRule extends cmdbAbstractObject MetaModel::Init_SetZListItems('standard_search', array('category_id', 'name', 'description', 'valid_flag', 'query')); // Criteria of the std search form MetaModel::Init_SetZListItems('default_search', array('name', 'description', 'category_id')); // Criteria of the advanced search form } + + + public static function GetShortcutActions($sFinalClass) + { + $aShortcutActions = parent::GetShortcutActions($sFinalClass); + if (!in_array('UI:Menu:RunAudit', $aShortcutActions)) { + $aShortcutActions[] = 'UI:Menu:RunAudit'; + } + + return $aShortcutActions; + } } ?> diff --git a/dictionaries/en.dictionary.itop.ui.php b/dictionaries/en.dictionary.itop.ui.php index 318cfae63..99872c309 100644 --- a/dictionaries/en.dictionary.itop.ui.php +++ b/dictionaries/en.dictionary.itop.ui.php @@ -667,150 +667,154 @@ We hope you’ll enjoy this version as much as we enjoyed imagining and creating 'UI:CSVImport:ObjectsWereAdded' => '%1$d objects(s) were added.', 'UI:CSVImport:ObjectsHadErrors' => '%1$d objects(s) had errors.', 'UI:Title:CSVImportStep2' => 'Step 2 of 5: CSV data options', - 'UI:Title:CSVImportStep3' => 'Step 3 of 5: Data mapping', - 'UI:Title:CSVImportStep4' => 'Step 4 of 5: Import simulation', - 'UI:Title:CSVImportStep5' => 'Step 5 of 5: Import completed', - 'UI:CSVImport:LinesNotImported' => 'Lines that could not be loaded:', - 'UI:CSVImport:LinesNotImported+' => 'The following lines have not been imported because they contain errors', - 'UI:CSVImport:SeparatorComma+' => ', (comma)', - 'UI:CSVImport:SeparatorSemicolon+' => '; (semicolon)', - 'UI:CSVImport:SeparatorTab+' => 'tab', - 'UI:CSVImport:SeparatorOther' => 'other:', - 'UI:CSVImport:QualifierDoubleQuote+' => '" (double quote)', - 'UI:CSVImport:QualifierSimpleQuote+' => '\' (simple quote)', - 'UI:CSVImport:QualifierOther' => 'other:', - 'UI:CSVImport:TreatFirstLineAsHeader' => 'Treat the first line as a header (column names)', + 'UI:Title:CSVImportStep3' => 'Step 3 of 5: Data mapping', + 'UI:Title:CSVImportStep4' => 'Step 4 of 5: Import simulation', + 'UI:Title:CSVImportStep5' => 'Step 5 of 5: Import completed', + 'UI:CSVImport:LinesNotImported' => 'Lines that could not be loaded:', + 'UI:CSVImport:LinesNotImported+' => 'The following lines have not been imported because they contain errors', + 'UI:CSVImport:SeparatorComma+' => ', (comma)', + 'UI:CSVImport:SeparatorSemicolon+' => '; (semicolon)', + 'UI:CSVImport:SeparatorTab+' => 'tab', + 'UI:CSVImport:SeparatorOther' => 'other:', + 'UI:CSVImport:QualifierDoubleQuote+' => '" (double quote)', + 'UI:CSVImport:QualifierSimpleQuote+' => '\' (simple quote)', + 'UI:CSVImport:QualifierOther' => 'other:', + 'UI:CSVImport:TreatFirstLineAsHeader' => 'Treat the first line as a header (column names)', 'UI:CSVImport:Skip_N_LinesAtTheBeginning' => 'Skip %1$s line(s) at the beginning of the file', - 'UI:CSVImport:CSVDataPreview' => 'CSV Data Preview', - 'UI:CSVImport:SelectFile' => 'Select the file to import:', - 'UI:CSVImport:Tab:LoadFromFile' => 'Load from a file', - 'UI:CSVImport:Tab:CopyPaste' => 'Copy and paste data', - 'UI:CSVImport:Tab:Templates' => 'Templates', - 'UI:CSVImport:PasteData' => 'Paste the data to import:', - 'UI:CSVImport:PickClassForTemplate' => 'Pick the template to download: ', - 'UI:CSVImport:SeparatorCharacter' => 'Separator character:', - 'UI:CSVImport:TextQualifierCharacter' => 'Text qualifier character', - 'UI:CSVImport:CommentsAndHeader' => 'Comments and header', - 'UI:CSVImport:SelectClass' => 'Select the class to import:', - 'UI:CSVImport:AdvancedMode' => 'Advanced mode', - 'UI:CSVImport:AdvancedMode+' => 'In advanced mode the "id" (primary key) of the objects can be used to update and rename objects.'. + 'UI:CSVImport:CSVDataPreview' => 'CSV Data Preview', + 'UI:CSVImport:SelectFile' => 'Select the file to import:', + 'UI:CSVImport:Tab:LoadFromFile' => 'Load from a file', + 'UI:CSVImport:Tab:CopyPaste' => 'Copy and paste data', + 'UI:CSVImport:Tab:Templates' => 'Templates', + 'UI:CSVImport:PasteData' => 'Paste the data to import:', + 'UI:CSVImport:PickClassForTemplate' => 'Pick the template to download: ', + 'UI:CSVImport:SeparatorCharacter' => 'Separator character:', + 'UI:CSVImport:TextQualifierCharacter' => 'Text qualifier character', + 'UI:CSVImport:CommentsAndHeader' => 'Comments and header', + 'UI:CSVImport:SelectClass' => 'Select the class to import:', + 'UI:CSVImport:AdvancedMode' => 'Advanced mode', + 'UI:CSVImport:AdvancedMode+' => 'In advanced mode the "id" (primary key) of the objects can be used to update and rename objects.'. 'However the column "id" (if present) can only be used as a search criteria and can not be combined with any other search criteria.', - 'UI:CSVImport:SelectAClassFirst' => 'To configure the mapping, select a class first.', - 'UI:CSVImport:HeaderFields' => 'Fields', - 'UI:CSVImport:HeaderMappings' => 'Mappings', - 'UI:CSVImport:HeaderSearch' => 'Search?', - 'UI:CSVImport:AlertIncompleteMapping' => 'Please select a mapping for every field.', - 'UI:CSVImport:AlertMultipleMapping' => 'Please make sure that a target field is mapped only once.', - 'UI:CSVImport:AlertNoSearchCriteria' => 'Please select at least one search criteria', - 'UI:CSVImport:Encoding' => 'Character encoding', - 'UI:UniversalSearchTitle' => ITOP_APPLICATION_SHORT.' - Universal Search', - 'UI:UniversalSearch:Error' => 'Error: %1$s', - 'UI:UniversalSearch:LabelSelectTheClass' => 'Select the class to search: ', + 'UI:CSVImport:SelectAClassFirst' => 'To configure the mapping, select a class first.', + 'UI:CSVImport:HeaderFields' => 'Fields', + 'UI:CSVImport:HeaderMappings' => 'Mappings', + 'UI:CSVImport:HeaderSearch' => 'Search?', + 'UI:CSVImport:AlertIncompleteMapping' => 'Please select a mapping for every field.', + 'UI:CSVImport:AlertMultipleMapping' => 'Please make sure that a target field is mapped only once.', + 'UI:CSVImport:AlertNoSearchCriteria' => 'Please select at least one search criteria', + 'UI:CSVImport:Encoding' => 'Character encoding', + 'UI:UniversalSearchTitle' => ITOP_APPLICATION_SHORT.' - Universal Search', + 'UI:UniversalSearch:Error' => 'Error: %1$s', + 'UI:UniversalSearch:LabelSelectTheClass' => 'Select the class to search: ', - 'UI:CSVReport-Value-Modified' => 'Modified', - 'UI:CSVReport-Value-SetIssue' => 'Invalid value for attribute', - 'UI:CSVReport-Value-ChangeIssue' => '\'%1$s\' is an invalid value', - 'UI:CSVReport-Value-NoMatch' => 'No match for value \'%1$s\'', - 'UI:CSVReport-Value-NoMatch-PossibleValues' => 'Some possible \'%1$s\' value(s): %2$s', - 'UI:CSVReport-Value-NoMatch-NoObject' => 'There are no \'%1$s\' objects', - 'UI:CSVReport-Value-NoMatch-NoObject-ForCurrentUser' => 'There are no \'%1$s\' objects found with your current profile', + 'UI:CSVReport-Value-Modified' => 'Modified', + 'UI:CSVReport-Value-SetIssue' => 'Invalid value for attribute', + 'UI:CSVReport-Value-ChangeIssue' => '\'%1$s\' is an invalid value', + 'UI:CSVReport-Value-NoMatch' => 'No match for value \'%1$s\'', + 'UI:CSVReport-Value-NoMatch-PossibleValues' => 'Some possible \'%1$s\' value(s): %2$s', + 'UI:CSVReport-Value-NoMatch-NoObject' => 'There are no \'%1$s\' objects', + 'UI:CSVReport-Value-NoMatch-NoObject-ForCurrentUser' => 'There are no \'%1$s\' objects found with your current profile', 'UI:CSVReport-Value-NoMatch-SomeObjectNotVisibleForCurrentUser' => 'There are some \'%1$s\' objects not visible with your current profile', - 'UI:CSVReport-Value-Missing' => 'Missing mandatory value', - 'UI:CSVReport-Value-Ambiguous' => 'Ambiguous: found %1$s objects', - 'UI:CSVReport-Row-Unchanged' => 'unchanged', - 'UI:CSVReport-Row-Created' => 'created', - 'UI:CSVReport-Row-Updated' => 'updated %1$d cols', - 'UI:CSVReport-Row-Disappeared' => 'disappeared, changed %1$d cols', - 'UI:CSVReport-Row-Issue' => 'Issue: %1$s', - 'UI:CSVReport-Value-Issue-Null' => 'Null not allowed', - 'UI:CSVReport-Value-Issue-NotFound' => 'Object not found', - 'UI:CSVReport-Value-Issue-FoundMany' => 'Found %1$d matches', - 'UI:CSVReport-Value-Issue-Readonly' => 'The attribute \'%1$s\' is read-only and cannot be modified (current value: %2$s, proposed value: %3$s)', - 'UI:CSVReport-Value-Issue-Format' => 'Failed to process input: %1$s', - 'UI:CSVReport-Value-Issue-NoMatch' => 'Unexpected value for attribute \'%1$s\': no match found, check spelling', - 'UI:CSVReport-Value-Issue-AllowedValues' => 'Allowed \'%1$s\' value(s): %2$s', - 'UI:CSVReport-Value-Issue-Unknown' => 'Unexpected value for attribute \'%1$s\': %2$s', - 'UI:CSVReport-Row-Issue-Inconsistent' => 'Attributes not consistent with each others: %1$s', - 'UI:CSVReport-Row-Issue-Attribute' => 'Unexpected attribute value(s)', - 'UI:CSVReport-Row-Issue-MissingExtKey' => 'Could not be created, due to missing external key(s): %1$s', - 'UI:CSVReport-Row-Issue-DateFormat' => 'wrong date format', + 'UI:CSVReport-Value-Missing' => 'Missing mandatory value', + 'UI:CSVReport-Value-Ambiguous' => 'Ambiguous: found %1$s objects', + 'UI:CSVReport-Row-Unchanged' => 'unchanged', + 'UI:CSVReport-Row-Created' => 'created', + 'UI:CSVReport-Row-Updated' => 'updated %1$d cols', + 'UI:CSVReport-Row-Disappeared' => 'disappeared, changed %1$d cols', + 'UI:CSVReport-Row-Issue' => 'Issue: %1$s', + 'UI:CSVReport-Value-Issue-Null' => 'Null not allowed', + 'UI:CSVReport-Value-Issue-NotFound' => 'Object not found', + 'UI:CSVReport-Value-Issue-FoundMany' => 'Found %1$d matches', + 'UI:CSVReport-Value-Issue-Readonly' => 'The attribute \'%1$s\' is read-only and cannot be modified (current value: %2$s, proposed value: %3$s)', + 'UI:CSVReport-Value-Issue-Format' => 'Failed to process input: %1$s', + 'UI:CSVReport-Value-Issue-NoMatch' => 'Unexpected value for attribute \'%1$s\': no match found, check spelling', + 'UI:CSVReport-Value-Issue-AllowedValues' => 'Allowed \'%1$s\' value(s): %2$s', + 'UI:CSVReport-Value-Issue-Unknown' => 'Unexpected value for attribute \'%1$s\': %2$s', + 'UI:CSVReport-Row-Issue-Inconsistent' => 'Attributes not consistent with each others: %1$s', + 'UI:CSVReport-Row-Issue-Attribute' => 'Unexpected attribute value(s)', + 'UI:CSVReport-Row-Issue-MissingExtKey' => 'Could not be created, due to missing external key(s): %1$s', + 'UI:CSVReport-Row-Issue-DateFormat' => 'wrong date format', 'UI:CSVReport-Row-Issue-ExpectedDateFormat' => 'Expected format: %1$s', - 'UI:CSVReport-Row-Issue-Reconciliation' => 'failed to reconcile', - 'UI:CSVReport-Row-Issue-Ambiguous' => 'ambiguous reconciliation', - 'UI:CSVReport-Row-Issue-Internal' => 'Internal error: %1$s, %2$s', + 'UI:CSVReport-Row-Issue-Reconciliation' => 'failed to reconcile', + 'UI:CSVReport-Row-Issue-Ambiguous' => 'ambiguous reconciliation', + 'UI:CSVReport-Row-Issue-Internal' => 'Internal error: %1$s, %2$s', - 'UI:CSVReport-Icon-Unchanged' => 'Unchanged', - 'UI:CSVReport-Icon-Modified' => 'Modified', - 'UI:CSVReport-Icon-Missing' => 'Missing', + 'UI:CSVReport-Icon-Unchanged' => 'Unchanged', + 'UI:CSVReport-Icon-Modified' => 'Modified', + 'UI:CSVReport-Icon-Missing' => 'Missing', 'UI:CSVReport-Object-MissingToUpdate' => 'Missing object: will be updated', - 'UI:CSVReport-Object-MissingUpdated' => 'Missing object: updated', - 'UI:CSVReport-Icon-Created' => 'Created', - 'UI:CSVReport-Object-ToCreate' => 'Object will be created', - 'UI:CSVReport-Object-Created' => 'Object created', - 'UI:CSVReport-Icon-Error' => 'Error', - 'UI:CSVReport-Object-Error' => 'ERROR: %1$s', - 'UI:CSVReport-Object-Ambiguous' => 'AMBIGUOUS: %1$s', - 'UI:CSVReport-Stats-Errors' => '%1$.0f %% of the loaded objects have errors and will be ignored.', - 'UI:CSVReport-Stats-Created' => '%1$.0f %% of the loaded objects will be created.', - 'UI:CSVReport-Stats-Modified' => '%1$.0f %% of the loaded objects will be modified.', + 'UI:CSVReport-Object-MissingUpdated' => 'Missing object: updated', + 'UI:CSVReport-Icon-Created' => 'Created', + 'UI:CSVReport-Object-ToCreate' => 'Object will be created', + 'UI:CSVReport-Object-Created' => 'Object created', + 'UI:CSVReport-Icon-Error' => 'Error', + 'UI:CSVReport-Object-Error' => 'ERROR: %1$s', + 'UI:CSVReport-Object-Ambiguous' => 'AMBIGUOUS: %1$s', + 'UI:CSVReport-Stats-Errors' => '%1$.0f %% of the loaded objects have errors and will be ignored.', + 'UI:CSVReport-Stats-Created' => '%1$.0f %% of the loaded objects will be created.', + 'UI:CSVReport-Stats-Modified' => '%1$.0f %% of the loaded objects will be modified.', - 'UI:CSVExport:AdvancedMode' => 'Advanced mode', + 'UI:CSVExport:AdvancedMode' => 'Advanced mode', 'UI:CSVExport:AdvancedMode+' => 'In advanced mode, several columns are added to the export: the id of the object, the id of external keys and their reconciliation attributes.', - 'UI:CSVExport:LostChars' => 'Encoding issue', - 'UI:CSVExport:LostChars+' => 'The downloaded file will be encoded into %1$s. '.ITOP_APPLICATION_SHORT.' has detected some characters that are not compatible with this format. Those characters will either be replaced by a substitute (e.g. accentuated chars losing the accent), or they will be discarded. You can copy/paste the data from your web browser. Alternatively, you can contact your administrator to change the encoding (See parameter \'csv_file_default_charset\').', + 'UI:CSVExport:LostChars' => 'Encoding issue', + 'UI:CSVExport:LostChars+' => 'The downloaded file will be encoded into %1$s. '.ITOP_APPLICATION_SHORT.' has detected some characters that are not compatible with this format. Those characters will either be replaced by a substitute (e.g. accentuated chars losing the accent), or they will be discarded. You can copy/paste the data from your web browser. Alternatively, you can contact your administrator to change the encoding (See parameter \'csv_file_default_charset\').', - 'UI:Audit:Title' => ITOP_APPLICATION_SHORT.' - CMDB Audit', - 'UI:Audit:InteractiveAudit' => 'Interactive Audit', - 'UI:Audit:InteractiveAudit:Selection' => 'Audit - Domain Selection', - 'UI:Audit:InteractiveAudit:Selection+' => 'Select a domain to get the result for selected domain', - 'UI:Audit:InteractiveAudit:Selection:All' => 'All categories', - 'UI:Audit:InteractiveAudit:AllCategories' => 'Audit result for all categories', - 'UI:Audit:InteractiveAudit:SelectedCategories' => 'Audit result for %1$s categories / category', - 'UI:Audit:InteractiveAudit:SelectedDomain' => 'Audit result for domain: %1$s', - 'UI:Audit:HeaderAuditRule' => 'Audit Rule', - 'UI:Audit:HeaderNbObjects' => '# Objects', - 'UI:Audit:HeaderNbErrors' => '# Errors', - 'UI:Audit:PercentageOk' => '% Ok', - 'UI:Audit:OqlError' => 'OQL Error', - 'UI:Audit:Error:ValueNA' => 'n/a', - 'UI:Audit:ErrorIn_Rule' => 'Error in Rule', - 'UI:Audit:ErrorIn_Rule_Reason' => 'OQL Error in the Rule %1$s: %2$s.', - 'UI:Audit:ErrorIn_Category' => 'Error in Category', - 'UI:Audit:ErrorIn_Category_Reason' => 'OQL Error in the Category %1$s: %2$s.', - 'UI:Audit:AuditErrors' => 'Audit Errors', - 'UI:Audit:Dashboard:ObjectsAudited' => 'Objects audited', - 'UI:Audit:Dashboard:ObjectsInError' => 'Objects in errors', - 'UI:Audit:Dashboard:ObjectsValidated' => 'Objects validated', - 'UI:Audit:AuditCategory:Subtitle' => '%1$s errors ouf of %2$s - %3$s%%', + 'UI:Audit:Title' => ITOP_APPLICATION_SHORT.' - CMDB Audit', + 'UI:Audit:InteractiveAudit' => 'Audit results', + 'UI:Audit:InteractiveAudit:Back' => 'Back to audit results', + 'UI:Audit:InteractiveAudit:ForCategories' => 'Audit for categories', + 'UI:Audit:InteractiveAudit:Selection' => 'Audit - Domain Selection', + 'UI:Audit:InteractiveAudit:Selection+' => 'Select a domain to get the result for selected domain', + 'UI:Audit:InteractiveAudit:Selection:All' => 'All categories', + 'UI:Audit:InteractiveAudit:AllCategories' => 'For all categories', + 'UI:Audit:InteractiveAudit:SelectedCategories' => 'Restricted to %1$s categories / category', + 'UI:Audit:InteractiveAudit:SelectedDomain' => 'Restricted to the domain: %1$s', + 'UI:Audit:ViewRules' => 'Check the rules', + 'UI:Audit:ModifyCategory' => 'Edit the audit category', + 'UI:Audit:HeaderAuditRule' => 'Audit Rule', + 'UI:Audit:HeaderNbObjects' => '# Objects', + 'UI:Audit:HeaderNbErrors' => '# Errors', + 'UI:Audit:PercentageOk' => '% Ok', + 'UI:Audit:OqlError' => 'OQL Error', + 'UI:Audit:Error:ValueNA' => 'n/a', + 'UI:Audit:ErrorIn_Rule' => 'Error in Rule', + 'UI:Audit:ErrorIn_Rule_Reason' => 'OQL Error in the Rule %1$s: %2$s.', + 'UI:Audit:ErrorIn_Category' => 'Error in Category', + 'UI:Audit:ErrorIn_Category_Reason' => 'OQL Error in the Category %1$s: %2$s.', + 'UI:Audit:AuditErrors' => 'Audit Errors', + 'UI:Audit:Dashboard:ObjectsAudited' => 'Objects audited', + 'UI:Audit:Dashboard:ObjectsInError' => 'Objects in errors', + 'UI:Audit:Dashboard:ObjectsValidated' => 'Objects validated', + 'UI:Audit:AuditCategory:Subtitle' => '%1$s errors ouf of %2$s - %3$s%% of the object are valid', - 'UI:RunQuery:Title' => ITOP_APPLICATION_SHORT.' - OQL Query Evaluation', - 'UI:RunQuery:QueryExamples' => 'Query Examples', - 'UI:RunQuery:QueryResults' => 'Query Results', - 'UI:RunQuery:HeaderPurpose' => 'Purpose', - 'UI:RunQuery:HeaderPurpose+' => 'Explanation about the query', - 'UI:RunQuery:HeaderOQLExpression' => 'OQL Expression', + 'UI:RunQuery:Title' => ITOP_APPLICATION_SHORT.' - OQL Query Evaluation', + 'UI:RunQuery:QueryExamples' => 'Query Examples', + 'UI:RunQuery:QueryResults' => 'Query Results', + 'UI:RunQuery:HeaderPurpose' => 'Purpose', + 'UI:RunQuery:HeaderPurpose+' => 'Explanation about the query', + 'UI:RunQuery:HeaderOQLExpression' => 'OQL Expression', 'UI:RunQuery:HeaderOQLExpression+' => 'The query in OQL syntax', 'UI:RunQuery:ExpressionToEvaluate' => 'Expression to evaluate: ', - 'UI:RunQuery:QueryArguments' => 'Query Arguments', - 'UI:RunQuery:MoreInfo' => 'More information about the query: ', - 'UI:RunQuery:DevelopedQuery' => 'Redevelopped query expression: ', - 'UI:RunQuery:SerializedFilter' => 'Serialized filter: ', - 'UI:RunQuery:DevelopedOQL' => 'Developed OQL', - 'UI:RunQuery:DevelopedOQLCount' => 'Developed OQL for count', - 'UI:RunQuery:ResultSQLCount' => 'Resulting SQL for count', - 'UI:RunQuery:ResultSQL' => 'Resulting SQL', - 'UI:RunQuery:Error' => 'An error occured while running the query', - 'UI:Query:UrlForExcel' => 'URL to use for MS-Excel web queries', - 'UI:Query:UrlV1' => 'The list of fields has been left unspecified. The page export-V2.php cannot be invoked without this information. Therefore, the URL suggested here below points to the legacy page: export.php. This legacy version of the export has the following limitation: the list of exported fields may vary depending on the output format and the data model of '.ITOP_APPLICATION_SHORT.'.
Should you want to guarantee that the list of exported columns will remain stable on the long run, then you must specify a value for the attribute "Fields" and use the page export-V2.php.', - 'UI:Schema:Title' => ITOP_APPLICATION_SHORT.' objects schema', - 'UI:Schema:TitleForClass' => '%1$s schema', - 'UI:Schema:CategoryMenuItem' => 'Category %1$s', - 'UI:Schema:Relationships' => 'Relationships', - 'UI:Schema:AbstractClass' => 'Abstract class: no object from this class can be instantiated.', - 'UI:Schema:NonAbstractClass' => 'Non abstract class: objects from this class can be instantiated.', - 'UI:Schema:ClassHierarchyTitle' => 'Class hierarchy', + 'UI:RunQuery:QueryArguments' => 'Query Arguments', + 'UI:RunQuery:MoreInfo' => 'More information about the query: ', + 'UI:RunQuery:DevelopedQuery' => 'Redevelopped query expression: ', + 'UI:RunQuery:SerializedFilter' => 'Serialized filter: ', + 'UI:RunQuery:DevelopedOQL' => 'Developed OQL', + 'UI:RunQuery:DevelopedOQLCount' => 'Developed OQL for count', + 'UI:RunQuery:ResultSQLCount' => 'Resulting SQL for count', + 'UI:RunQuery:ResultSQL' => 'Resulting SQL', + 'UI:RunQuery:Error' => 'An error occured while running the query', + 'UI:Query:UrlForExcel' => 'URL to use for MS-Excel web queries', + 'UI:Query:UrlV1' => 'The list of fields has been left unspecified. The page export-V2.php cannot be invoked without this information. Therefore, the URL suggested here below points to the legacy page: export.php. This legacy version of the export has the following limitation: the list of exported fields may vary depending on the output format and the data model of '.ITOP_APPLICATION_SHORT.'.
Should you want to guarantee that the list of exported columns will remain stable on the long run, then you must specify a value for the attribute "Fields" and use the page export-V2.php.', + 'UI:Schema:Title' => ITOP_APPLICATION_SHORT.' objects schema', + 'UI:Schema:TitleForClass' => '%1$s schema', + 'UI:Schema:CategoryMenuItem' => 'Category %1$s', + 'UI:Schema:Relationships' => 'Relationships', + 'UI:Schema:AbstractClass' => 'Abstract class: no object from this class can be instantiated.', + 'UI:Schema:NonAbstractClass' => 'Non abstract class: objects from this class can be instantiated.', + 'UI:Schema:ClassHierarchyTitle' => 'Class hierarchy', 'UI:Schema:AllClasses' => 'All classes', 'UI:Schema:ExternalKey_To' => 'External key to %1$s', 'UI:Schema:Columns_Description' => 'Columns: %1$s', diff --git a/dictionaries/fr.dictionary.itop.ui.php b/dictionaries/fr.dictionary.itop.ui.php index 4f84642c4..2d869ec77 100644 --- a/dictionaries/fr.dictionary.itop.ui.php +++ b/dictionaries/fr.dictionary.itop.ui.php @@ -647,254 +647,264 @@ Nous espérons que vous aimerez cette version autant que nous avons eu du plaisi 'UI:CSVImport:ErrorExtendedAttCode' => 'Erreur interne: "%1$s" n\'est pas une code correct car "%2$s" n\'est pas une clef externe de la classe "%3$s"', 'UI:CSVImport:ObjectsWillStayUnchanged' => '%1$d objets(s) resteront inchangés.', 'UI:CSVImport:ObjectsWillBeModified' => '%1$d objets(s) seront modifiés.', - 'UI:CSVImport:ObjectsWillBeAdded' => '%1$d objets(s) seront créés.', - 'UI:CSVImport:ObjectsWillHaveErrors' => '%1$d objets(s) seront en erreur.', - 'UI:CSVImport:ObjectsRemainedUnchanged' => '%1$d objets(s) n\'ont pas changé.', - 'UI:CSVImport:ObjectsWereModified' => '%1$d objets(s)ont été modifiés.', - 'UI:CSVImport:ObjectsWereAdded' => '%1$d objets(s) ont été créés.', - 'UI:CSVImport:ObjectsHadErrors' => '%1$d ligne(s) contenaient des erreurs.', - 'UI:Title:CSVImportStep2' => 'Etape 2 sur 5: Options du format CSV', - 'UI:Title:CSVImportStep3' => 'Etape 3 sur 5: Correspondance des données', - 'UI:Title:CSVImportStep4' => 'Etape 4 sur 5: Simulation de l\'import', - 'UI:Title:CSVImportStep5' => 'Etape 5 sur 5: Import terminé', - 'UI:CSVImport:LinesNotImported' => 'Des lignes n\'ont pas été importées:', - 'UI:CSVImport:LinesNotImported+' => 'Les lignes suivantes n\'ont pas été importées car elles contenaient des erreurs.', - 'UI:CSVImport:SeparatorComma+' => ', (virgule)', - 'UI:CSVImport:SeparatorSemicolon+' => '; (point-virgule)', - 'UI:CSVImport:SeparatorTab+' => 'tab', - 'UI:CSVImport:SeparatorOther' => 'autre :', - 'UI:CSVImport:QualifierDoubleQuote+' => '" (guillemet double)', - 'UI:CSVImport:QualifierSimpleQuote+' => '\' (guillemet simple / apostrophe)', - 'UI:CSVImport:QualifierOther' => 'autre :', - 'UI:CSVImport:TreatFirstLineAsHeader' => 'La première ligne est l\'en-tête (noms des colonnes)', - 'UI:CSVImport:Skip_N_LinesAtTheBeginning' => 'Ignorer les %1$s premières lignes du fichier', - 'UI:CSVImport:CSVDataPreview' => 'Aperçu des données CSV', - 'UI:CSVImport:SelectFile' => 'Sélectionnez le fichier à importer:', - 'UI:CSVImport:Tab:LoadFromFile' => 'Import depuis un fichier', - 'UI:CSVImport:Tab:CopyPaste' => 'Copier/Coller de données', - 'UI:CSVImport:Tab:Templates' => 'Modèles', - 'UI:CSVImport:PasteData' => 'Collez ici les données à importer:', - 'UI:CSVImport:PickClassForTemplate' => 'Choisissez un modèle à télécharger: ', - 'UI:CSVImport:SeparatorCharacter' => 'Séparateur:', - 'UI:CSVImport:TextQualifierCharacter' => 'Délimiteur de texte', - 'UI:CSVImport:CommentsAndHeader' => 'Commentaires et en-tête', - 'UI:CSVImport:SelectClass' => 'Sélectionner le type d\'objets à importer:', - 'UI:CSVImport:AdvancedMode' => 'Mode expert', - 'UI:CSVImport:AdvancedMode+' => 'En mode expert, l\'"id" (clef primaire) des objets peut être utilisé pour renommer des objets.Cependant la colonne "id" (si elle est présente) ne peut être utilisée que comme clef de recherche et ne peut pas être combinée avec une autre clef de recherche.', - 'UI:CSVImport:SelectAClassFirst' => 'Pour configurer la correspondance, choississez d\'abord un type ci-dessus.', - 'UI:CSVImport:HeaderFields' => 'Champs', - 'UI:CSVImport:HeaderMappings' => 'Correspondance', - 'UI:CSVImport:HeaderSearch' => 'Recherche ?', - 'UI:CSVImport:AlertIncompleteMapping' => 'Veuillez choisir la correspondance pour chacun des champs.', - 'UI:CSVImport:AlertMultipleMapping' => 'Veuillez vous assurer que chaque champ cible est sélectionné une seule fois.', - 'UI:CSVImport:AlertNoSearchCriteria' => 'Veuillez choisir au moins une clef de recherche.', - 'UI:CSVImport:Encoding' => 'Encodage des caractères', - 'UI:UniversalSearchTitle' => ITOP_APPLICATION_SHORT.' - Recherche universelle', - 'UI:UniversalSearch:Error' => 'Erreur : %1$s', - 'UI:UniversalSearch:LabelSelectTheClass' => 'Sélectionnez le type d\'objets à rechercher : ', + 'UI:CSVImport:ObjectsWillBeAdded' => '%1$d objets(s) seront créés.', + 'UI:CSVImport:ObjectsWillHaveErrors' => '%1$d objets(s) seront en erreur.', + 'UI:CSVImport:ObjectsRemainedUnchanged' => '%1$d objets(s) n\'ont pas changé.', + 'UI:CSVImport:ObjectsWereModified' => '%1$d objets(s)ont été modifiés.', + 'UI:CSVImport:ObjectsWereAdded' => '%1$d objets(s) ont été créés.', + 'UI:CSVImport:ObjectsHadErrors' => '%1$d ligne(s) contenaient des erreurs.', + 'UI:Title:CSVImportStep2' => 'Etape 2 sur 5: Options du format CSV', + 'UI:Title:CSVImportStep3' => 'Etape 3 sur 5: Correspondance des données', + 'UI:Title:CSVImportStep4' => 'Etape 4 sur 5: Simulation de l\'import', + 'UI:Title:CSVImportStep5' => 'Etape 5 sur 5: Import terminé', + 'UI:CSVImport:LinesNotImported' => 'Des lignes n\'ont pas été importées:', + 'UI:CSVImport:LinesNotImported+' => 'Les lignes suivantes n\'ont pas été importées car elles contenaient des erreurs.', + 'UI:CSVImport:SeparatorComma+' => ', (virgule)', + 'UI:CSVImport:SeparatorSemicolon+' => '; (point-virgule)', + 'UI:CSVImport:SeparatorTab+' => 'tab', + 'UI:CSVImport:SeparatorOther' => 'autre :', + 'UI:CSVImport:QualifierDoubleQuote+' => '" (guillemet double)', + 'UI:CSVImport:QualifierSimpleQuote+' => '\' (guillemet simple / apostrophe)', + 'UI:CSVImport:QualifierOther' => 'autre :', + 'UI:CSVImport:TreatFirstLineAsHeader' => 'La première ligne est l\'en-tête (noms des colonnes)', + 'UI:CSVImport:Skip_N_LinesAtTheBeginning' => 'Ignorer les %1$s premières lignes du fichier', + 'UI:CSVImport:CSVDataPreview' => 'Aperçu des données CSV', + 'UI:CSVImport:SelectFile' => 'Sélectionnez le fichier à importer:', + 'UI:CSVImport:Tab:LoadFromFile' => 'Import depuis un fichier', + 'UI:CSVImport:Tab:CopyPaste' => 'Copier/Coller de données', + 'UI:CSVImport:Tab:Templates' => 'Modèles', + 'UI:CSVImport:PasteData' => 'Collez ici les données à importer:', + 'UI:CSVImport:PickClassForTemplate' => 'Choisissez un modèle à télécharger: ', + 'UI:CSVImport:SeparatorCharacter' => 'Séparateur:', + 'UI:CSVImport:TextQualifierCharacter' => 'Délimiteur de texte', + 'UI:CSVImport:CommentsAndHeader' => 'Commentaires et en-tête', + 'UI:CSVImport:SelectClass' => 'Sélectionner le type d\'objets à importer:', + 'UI:CSVImport:AdvancedMode' => 'Mode expert', + 'UI:CSVImport:AdvancedMode+' => 'En mode expert, l\'"id" (clef primaire) des objets peut être utilisé pour renommer des objets.Cependant la colonne "id" (si elle est présente) ne peut être utilisée que comme clef de recherche et ne peut pas être combinée avec une autre clef de recherche.', + 'UI:CSVImport:SelectAClassFirst' => 'Pour configurer la correspondance, choississez d\'abord un type ci-dessus.', + 'UI:CSVImport:HeaderFields' => 'Champs', + 'UI:CSVImport:HeaderMappings' => 'Correspondance', + 'UI:CSVImport:HeaderSearch' => 'Recherche ?', + 'UI:CSVImport:AlertIncompleteMapping' => 'Veuillez choisir la correspondance pour chacun des champs.', + 'UI:CSVImport:AlertMultipleMapping' => 'Veuillez vous assurer que chaque champ cible est sélectionné une seule fois.', + 'UI:CSVImport:AlertNoSearchCriteria' => 'Veuillez choisir au moins une clef de recherche.', + 'UI:CSVImport:Encoding' => 'Encodage des caractères', + 'UI:UniversalSearchTitle' => ITOP_APPLICATION_SHORT.' - Recherche universelle', + 'UI:UniversalSearch:Error' => 'Erreur : %1$s', + 'UI:UniversalSearch:LabelSelectTheClass' => 'Sélectionnez le type d\'objets à rechercher : ', - 'UI:CSVReport-Value-Modified' => 'Modifié', - 'UI:CSVReport-Value-SetIssue' => 'Valeur invalide', - 'UI:CSVReport-Value-ChangeIssue' => 'Ne peut pas prendre la valeur \'%1$s\'', - 'UI:CSVReport-Value-NoMatch' => 'Pas de correspondance avec \'%1$s\'', - 'UI:CSVReport-Value-NoMatch-PossibleValues' => 'Valeur(s) possible(s) pour l\'objet \'%1$s\' : %2$s', - 'UI:CSVReport-Value-NoMatch-NoObject' => 'Il n\'y a aucun objet \'%1$s\'', - 'UI:CSVReport-Value-NoMatch-NoObject-ForCurrentUser' => 'Il n\'y a aucun objet \'%1$s\' visible par votre utilisateur', + 'UI:CSVReport-Value-Modified' => 'Modifié', + 'UI:CSVReport-Value-SetIssue' => 'Valeur invalide', + 'UI:CSVReport-Value-ChangeIssue' => 'Ne peut pas prendre la valeur \'%1$s\'', + 'UI:CSVReport-Value-NoMatch' => 'Pas de correspondance avec \'%1$s\'', + 'UI:CSVReport-Value-NoMatch-PossibleValues' => 'Valeur(s) possible(s) pour l\'objet \'%1$s\' : %2$s', + 'UI:CSVReport-Value-NoMatch-NoObject' => 'Il n\'y a aucun objet \'%1$s\'', + 'UI:CSVReport-Value-NoMatch-NoObject-ForCurrentUser' => 'Il n\'y a aucun objet \'%1$s\' visible par votre utilisateur', 'UI:CSVReport-Value-NoMatch-SomeObjectNotVisibleForCurrentUser' => 'Il existe des objet(s) \'%1$s\' non visible(s) par votre utilisateur', - 'UI:CSVReport-Value-Missing' => 'Absence de valeur obligatoire', - 'UI:CSVReport-Value-Ambiguous' => 'Ambigüité: %1$d objets trouvés', - 'UI:CSVReport-Row-Unchanged' => 'inchangé', - 'UI:CSVReport-Row-Created' => 'créé', - 'UI:CSVReport-Row-Updated' => '%1$d colonnes modifiées', - 'UI:CSVReport-Row-Disappeared' => 'disparu, %1$d colonnes modifiées', - 'UI:CSVReport-Row-Issue' => 'Erreur: %1$s', - 'UI:CSVReport-Value-Issue-Null' => 'Valeur obligatoire', - 'UI:CSVReport-Value-Issue-NotFound' => 'Objet non trouvé', - 'UI:CSVReport-Value-Issue-FoundMany' => 'Plusieurs objets trouvés (%1$d)', - 'UI:CSVReport-Value-Issue-Readonly' => 'L\'attribut \'%1$s\' est en lecture seule (valeur courante: %2$s, valeur proposée: %3$s)', - 'UI:CSVReport-Value-Issue-Format' => 'Echec de traitement de la valeur: %1$s', - 'UI:CSVReport-Value-Issue-NoMatch' => 'Valeur incorrecte pour \'%1$s\': pas de correspondance, veuillez vérifier la syntaxe', - 'UI:CSVReport-Value-Issue-Unknown' => 'Valeur incorrecte pour \'%1$s\': %2$s', - 'UI:CSVReport-Row-Issue-Inconsistent' => 'Incohérence entre attributs: %1$s', - 'UI:CSVReport-Row-Issue-Attribute' => 'Des attributs ont des valeurs incorrectes', - 'UI:CSVReport-Row-Issue-MissingExtKey' => 'Ne peut pas être créé car il manque des clés externes : %1$s', - 'UI:CSVReport-Row-Issue-DateFormat' => 'Format de date incorrect', + 'UI:CSVReport-Value-Missing' => 'Absence de valeur obligatoire', + 'UI:CSVReport-Value-Ambiguous' => 'Ambigüité: %1$d objets trouvés', + 'UI:CSVReport-Row-Unchanged' => 'inchangé', + 'UI:CSVReport-Row-Created' => 'créé', + 'UI:CSVReport-Row-Updated' => '%1$d colonnes modifiées', + 'UI:CSVReport-Row-Disappeared' => 'disparu, %1$d colonnes modifiées', + 'UI:CSVReport-Row-Issue' => 'Erreur: %1$s', + 'UI:CSVReport-Value-Issue-Null' => 'Valeur obligatoire', + 'UI:CSVReport-Value-Issue-NotFound' => 'Objet non trouvé', + 'UI:CSVReport-Value-Issue-FoundMany' => 'Plusieurs objets trouvés (%1$d)', + 'UI:CSVReport-Value-Issue-Readonly' => 'L\'attribut \'%1$s\' est en lecture seule (valeur courante: %2$s, valeur proposée: %3$s)', + 'UI:CSVReport-Value-Issue-Format' => 'Echec de traitement de la valeur: %1$s', + 'UI:CSVReport-Value-Issue-NoMatch' => 'Valeur incorrecte pour \'%1$s\': pas de correspondance, veuillez vérifier la syntaxe', + 'UI:CSVReport-Value-Issue-Unknown' => 'Valeur incorrecte pour \'%1$s\': %2$s', + 'UI:CSVReport-Row-Issue-Inconsistent' => 'Incohérence entre attributs: %1$s', + 'UI:CSVReport-Row-Issue-Attribute' => 'Des attributs ont des valeurs incorrectes', + 'UI:CSVReport-Row-Issue-MissingExtKey' => 'Ne peut pas être créé car il manque des clés externes : %1$s', + 'UI:CSVReport-Row-Issue-DateFormat' => 'Format de date incorrect', 'UI:CSVReport-Row-Issue-Reconciliation' => 'Echec de réconciliation', - 'UI:CSVReport-Row-Issue-Ambiguous' => 'Réconciliation ambigüe', - 'UI:CSVReport-Row-Issue-Internal' => 'Erreur interne: %1$s, %2$s', + 'UI:CSVReport-Row-Issue-Ambiguous' => 'Réconciliation ambigüe', + 'UI:CSVReport-Row-Issue-Internal' => 'Erreur interne: %1$s, %2$s', - 'UI:CSVReport-Icon-Unchanged' => 'Non modifié', - 'UI:CSVReport-Icon-Modified' => 'Modifié', - 'UI:CSVReport-Icon-Missing' => 'A disparu', + 'UI:CSVReport-Icon-Unchanged' => 'Non modifié', + 'UI:CSVReport-Icon-Modified' => 'Modifié', + 'UI:CSVReport-Icon-Missing' => 'A disparu', 'UI:CSVReport-Object-MissingToUpdate' => 'Objet disparu: sera modifié', - 'UI:CSVReport-Object-MissingUpdated' => 'Objet disparu: modifié', - 'UI:CSVReport-Icon-Created' => 'Créé', - 'UI:CSVReport-Object-ToCreate' => 'L\'objet sera créé', - 'UI:CSVReport-Object-Created' => 'Objet créé', - 'UI:CSVReport-Icon-Error' => 'Erreur', - 'UI:CSVReport-Object-Error' => 'Erreur: %1$s', - 'UI:CSVReport-Object-Ambiguous' => 'Ambigüité: %1$s', - 'UI:CSVReport-Stats-Errors' => '%1$.0f %% des lignes chargées sont en erreur et seront ignorées.', - 'UI:CSVReport-Stats-Created' => '%1$.0f %% des lignes chargées vont engendrer un nouvel objet.', - 'UI:CSVReport-Stats-Modified' => '%1$.0f %% des lignes chargées vont modifier un objet.', + 'UI:CSVReport-Object-MissingUpdated' => 'Objet disparu: modifié', + 'UI:CSVReport-Icon-Created' => 'Créé', + 'UI:CSVReport-Object-ToCreate' => 'L\'objet sera créé', + 'UI:CSVReport-Object-Created' => 'Objet créé', + 'UI:CSVReport-Icon-Error' => 'Erreur', + 'UI:CSVReport-Object-Error' => 'Erreur: %1$s', + 'UI:CSVReport-Object-Ambiguous' => 'Ambigüité: %1$s', + 'UI:CSVReport-Stats-Errors' => '%1$.0f %% des lignes chargées sont en erreur et seront ignorées.', + 'UI:CSVReport-Stats-Created' => '%1$.0f %% des lignes chargées vont engendrer un nouvel objet.', + 'UI:CSVReport-Stats-Modified' => '%1$.0f %% des lignes chargées vont modifier un objet.', - 'UI:CSVExport:AdvancedMode' => 'Mode expert', + 'UI:CSVExport:AdvancedMode' => 'Mode expert', 'UI:CSVExport:AdvancedMode+' => 'Dans le mode expert, des colonnes supplémentaires apparaissent: l\'identifiant de l\'objet, la valeur des clés externes et leurs attributs de reconciliation.', - 'UI:CSVExport:LostChars' => 'Problème d\'encodage', - 'UI:CSVExport:LostChars+' => 'Le fichier téléchargé sera encodé en %1$s. iTop a détecté des caractères incompatible avec ce format. Ces caractères seront soit remplacés par des caractères de substitution (par exemple: \'é\' transformé en \'e\'), soit perdus. Vous pouvez utiliser le copier/coller depuis votre navigateur web, ou bien contacter votre administrateur pour que l\'encodage corresponde mieux à votre besoin (Cf. paramètre \'csv_file_default_charset\').', + 'UI:CSVExport:LostChars' => 'Problème d\'encodage', + 'UI:CSVExport:LostChars+' => 'Le fichier téléchargé sera encodé en %1$s. iTop a détecté des caractères incompatible avec ce format. Ces caractères seront soit remplacés par des caractères de substitution (par exemple: \'é\' transformé en \'e\'), soit perdus. Vous pouvez utiliser le copier/coller depuis votre navigateur web, ou bien contacter votre administrateur pour que l\'encodage corresponde mieux à votre besoin (Cf. paramètre \'csv_file_default_charset\').', - 'UI:Audit:Title' => ITOP_APPLICATION_SHORT.' - Audit de la CMDB', - 'UI:Audit:InteractiveAudit' => 'Audit Interactif', - 'UI:Audit:HeaderAuditRule' => 'Règle d\'audit', - 'UI:Audit:HeaderNbObjects' => 'Nb d\'Objets', - 'UI:Audit:HeaderNbErrors' => 'Nb d\'Erreurs', - 'UI:Audit:PercentageOk' => '% Ok', - 'UI:Audit:OqlError' => 'OQL Error~~', - 'UI:Audit:Error:ValueNA' => 'n/a~~', - 'UI:Audit:ErrorIn_Rule' => 'Error in Rule~~', - 'UI:Audit:ErrorIn_Rule_Reason' => 'Erreur OQL dans la règle %1$s: %2$s.', - 'UI:Audit:ErrorIn_Category' => 'Error in Category~~', - 'UI:Audit:ErrorIn_Category_Reason' => 'Erreur OQL dans la catégorie %1$s: %2$s.', - 'UI:Audit:AuditErrors' => 'Audit Errors~~', - 'UI:Audit:Dashboard:ObjectsAudited' => 'Objects audited~~', - 'UI:Audit:Dashboard:ObjectsInError' => 'Objects in errors~~', - 'UI:Audit:Dashboard:ObjectsValidated' => 'Objects validated~~', - 'UI:Audit:AuditCategory:Subtitle' => '%1$s errors ouf of %2$s - %3$s%%~~', + 'UI:Audit:Title' => ITOP_APPLICATION_SHORT.' - Audit de la CMDB', + 'UI:Audit:InteractiveAudit' => 'Résultats d\'audit', + 'UI:Audit:InteractiveAudit:Back' => 'Retour à l\'audit complet', + 'UI:Audit:InteractiveAudit:ForCategories' => 'Audit de catégories', + 'UI:Audit:InteractiveAudit:Selection' => 'Sélection d\'un audit', + 'UI:Audit:InteractiveAudit:Selection+' => 'Choisir un domaine pour obtenir les résultats d\'audit limités à ce domaine ou l\'"Audit intégral" mais qui peut échouer s\'il y a trop de régles et d\'objets à auditer', + 'UI:Audit:InteractiveAudit:Selection:All' => 'Audit intégral', + 'UI:Audit:InteractiveAudit:AllCategories' => 'Complet, incluant toutes les régles, sans limitation de domain ni de catégorie', + 'UI:Audit:InteractiveAudit:SelectedCategories' => 'Limités à %1$s catégorie(s)', + 'UI:Audit:InteractiveAudit:SelectedDomain' => 'Limités au domaine : %1$s', + 'UI:Audit:ViewRules' => 'Vérifier les régles d\'audit', + 'UI:Audit:ModifyCategory' => 'Editer la catégorie d\'audit', + 'UI:Audit:HeaderAuditRule' => 'Règle d\'audit', + 'UI:Audit:HeaderNbObjects' => 'Nb d\'Objets', + 'UI:Audit:HeaderNbErrors' => 'Nb d\'Erreurs', + 'UI:Audit:PercentageOk' => '% Ok', + 'UI:Audit:OqlError' => 'Erreur OQL', + 'UI:Audit:Error:ValueNA' => 'n/a', + 'UI:Audit:ErrorIn_Rule' => 'Erreur dans le régle', + 'UI:Audit:ErrorIn_Rule_Reason' => 'Erreur OQL dans la règle %1$s: %2$s.', + 'UI:Audit:ErrorIn_Category' => 'Erreur dans la catégorie', + 'UI:Audit:ErrorIn_Category_Reason' => 'Erreur OQL dans la catégorie %1$s: %2$s.', + 'UI:Audit:AuditErrors' => 'Audit Errors~~', + 'UI:Audit:Dashboard:ObjectsAudited' => 'Objets audités', + 'UI:Audit:Dashboard:ObjectsInError' => 'Objets en erreur', + 'UI:Audit:Dashboard:ObjectsValidated' => 'Objets valides', + 'UI:Audit:AuditCategory:Subtitle' => '%1$s en erreur sur %2$s - %3$s%% des objets sont valides', - 'UI:RunQuery:Title' => ITOP_APPLICATION_SHORT.' - Evaluation de requêtes OQL', - 'UI:RunQuery:QueryExamples' => 'Exemples de requêtes', - 'UI:RunQuery:QueryResults' => 'Résultats de la requête', - 'UI:RunQuery:HeaderPurpose' => 'Objectif', - 'UI:RunQuery:HeaderPurpose+' => 'But de la requête', - 'UI:RunQuery:HeaderOQLExpression' => 'Requête OQL', + 'UI:RunQuery:Title' => ITOP_APPLICATION_SHORT.' - Evaluation de requêtes OQL', + 'UI:RunQuery:QueryExamples' => 'Exemples de requêtes', + 'UI:RunQuery:QueryResults' => 'Résultats de la requête', + 'UI:RunQuery:HeaderPurpose' => 'Objectif', + 'UI:RunQuery:HeaderPurpose+' => 'But de la requête', + 'UI:RunQuery:HeaderOQLExpression' => 'Requête OQL', 'UI:RunQuery:HeaderOQLExpression+' => 'La requête en OQL', 'UI:RunQuery:ExpressionToEvaluate' => 'Requête à exécuter : ', - 'UI:RunQuery:QueryArguments' => 'Arguments de la requête', - 'UI:RunQuery:MoreInfo' => 'Plus d\'information sur la requête : ', - 'UI:RunQuery:DevelopedQuery' => 'Requête OQL décompilée : ', - 'UI:RunQuery:SerializedFilter' => 'Version sérialisée : ', - 'UI:RunQuery:DevelopedOQL' => 'OQL développé', - 'UI:RunQuery:DevelopedOQLCount' => 'OQL développé pour le compte', - 'UI:RunQuery:ResultSQLCount' => 'SQL généré pour le compte', - 'UI:RunQuery:ResultSQL' => 'SQL généré', - 'UI:RunQuery:Error' => 'Une erreur s\'est produite durant l\'exécution de la requête', - 'UI:Query:UrlForExcel' => 'Lien à copier-coller dans Excel, pour déclarer une source de données à partir du web', - 'UI:Query:UrlV1' => 'La liste des champs à exporter n\'a pas été spécifiée. La page export-V2.php ne peut pas fonctionner sans cette information. Par conséquent, le lien fourni ci-dessous pointe sur l\'ancienne page: export.php. Cette ancienne version de l\'export présente la limitation suivante : la liste des champs exportés varie en fonction du format de l\'export et du modèle de données.
Si vous devez garantir la stabilité du format de l\'export (liste des colonnes) sur le long terme, alors vous devrez renseigner l\'attribut "Champs" et utiliser la page export-V2.php.', - 'UI:Schema:Title' => 'Modèle de données '.ITOP_APPLICATION_SHORT, - 'UI:Schema:TitleForClass' => 'Modèle de données de %1$s~~', - 'UI:Schema:CategoryMenuItem' => 'Catégorie %1$s', - 'UI:Schema:Relationships' => 'Relations', - 'UI:Schema:AbstractClass' => 'Classe abstraite : les objets de cette classe ne peuvent pas être instanciés.', - 'UI:Schema:NonAbstractClass' => 'Classe concrète : les objets de cette classe peuvent être instanciés.', - 'UI:Schema:ClassHierarchyTitle' => 'Hiérachie des classes', - 'UI:Schema:AllClasses' => 'Toutes les classes', - 'UI:Schema:ExternalKey_To' => 'Clef externe vers %1$s', - 'UI:Schema:Columns_Description' => 'Colonnes : %1$s', - 'UI:Schema:Default_Description' => 'Valeur par défaut: "%1$s"', - 'UI:Schema:NullAllowed' => 'Null autorisé', - 'UI:Schema:NullNotAllowed' => 'Null interdit', - 'UI:Schema:Attributes' => 'Attributs', - 'UI:Schema:AttributeCode' => 'Code', - 'UI:Schema:AttributeCode+' => 'Code interne de l\'attribut', - 'UI:Schema:Label' => 'Label', - 'UI:Schema:Label+' => 'Label de l\'attribut', - 'UI:Schema:Type' => 'Type', + 'UI:RunQuery:QueryArguments' => 'Arguments de la requête', + 'UI:RunQuery:MoreInfo' => 'Plus d\'information sur la requête : ', + 'UI:RunQuery:DevelopedQuery' => 'Requête OQL décompilée : ', + 'UI:RunQuery:SerializedFilter' => 'Version sérialisée : ', + 'UI:RunQuery:DevelopedOQL' => 'OQL développé', + 'UI:RunQuery:DevelopedOQLCount' => 'OQL développé pour le compte', + 'UI:RunQuery:ResultSQLCount' => 'SQL généré pour le compte', + 'UI:RunQuery:ResultSQL' => 'SQL généré', + 'UI:RunQuery:Error' => 'Une erreur s\'est produite durant l\'exécution de la requête', + 'UI:Query:UrlForExcel' => 'Lien à copier-coller dans Excel, pour déclarer une source de données à partir du web', + 'UI:Query:UrlV1' => 'La liste des champs à exporter n\'a pas été spécifiée. La page export-V2.php ne peut pas fonctionner sans cette information. Par conséquent, le lien fourni ci-dessous pointe sur l\'ancienne page: export.php. Cette ancienne version de l\'export présente la limitation suivante : la liste des champs exportés varie en fonction du format de l\'export et du modèle de données.
Si vous devez garantir la stabilité du format de l\'export (liste des colonnes) sur le long terme, alors vous devrez renseigner l\'attribut "Champs" et utiliser la page export-V2.php.', + 'UI:Schema:Title' => 'Modèle de données '.ITOP_APPLICATION_SHORT, + 'UI:Schema:TitleForClass' => 'Modèle de données de %1$s~~', + 'UI:Schema:CategoryMenuItem' => 'Catégorie %1$s', + 'UI:Schema:Relationships' => 'Relations', + 'UI:Schema:AbstractClass' => 'Classe abstraite : les objets de cette classe ne peuvent pas être instanciés.', + 'UI:Schema:NonAbstractClass' => 'Classe concrète : les objets de cette classe peuvent être instanciés.', + 'UI:Schema:ClassHierarchyTitle' => 'Hiérachie des classes', + 'UI:Schema:AllClasses' => 'Toutes les classes', + 'UI:Schema:ExternalKey_To' => 'Clef externe vers %1$s', + 'UI:Schema:Columns_Description' => 'Colonnes : %1$s', + 'UI:Schema:Default_Description' => 'Valeur par défaut: "%1$s"', + 'UI:Schema:NullAllowed' => 'Null autorisé', + 'UI:Schema:NullNotAllowed' => 'Null interdit', + 'UI:Schema:Attributes' => 'Attributs', + 'UI:Schema:AttributeCode' => 'Code', + 'UI:Schema:AttributeCode+' => 'Code interne de l\'attribut', + 'UI:Schema:Label' => 'Label', + 'UI:Schema:Label+' => 'Label de l\'attribut', + 'UI:Schema:Type' => 'Type', - 'UI:Schema:Type+' => 'Type de données de l\'attribut', - 'UI:Schema:Origin' => 'Origine', - 'UI:Schema:Origin+' => 'La classe de base dans laquelle l\'attribut est défini', - 'UI:Schema:Description' => 'Description', - 'UI:Schema:Description+' => 'Description de l\'attribut', - 'UI:Schema:AllowedValues' => 'Valeurs possibles', - 'UI:Schema:AllowedValues+' => 'Restrictions des valeurs possibles pour cet attribut', - 'UI:Schema:MoreInfo' => 'Plus info', - 'UI:Schema:MoreInfo+' => 'Plus d\'information à propos de la définition de ce champ dans la base de données', - 'UI:Schema:SearchCriteria' => 'Critères de recherche', - 'UI:Schema:FilterCode' => 'Code', - 'UI:Schema:FilterCode+' => 'Code de ce critère de recherche', - 'UI:Schema:FilterDescription' => 'Description', - 'UI:Schema:FilterDescription+' => 'Description de ce critère de recherche', - 'UI:Schema:AvailOperators' => 'Opérateurs', - 'UI:Schema:AvailOperators+' => 'Opérateurs possibles pour ce critère de recherche', - 'UI:Schema:ChildClasses' => 'Classes dérivées', - 'UI:Schema:ReferencingClasses' => 'Classes faisant référence', - 'UI:Schema:RelatedClasses' => 'Classes reliées', - 'UI:Schema:LifeCycle' => 'Cycle de vie', - 'UI:Schema:Triggers' => 'Déclencheurs', - 'UI:Schema:Relation_Code_Description' => 'Relation %1$s (%2$s)', - 'UI:Schema:RelationDown_Description' => 'Sens descendant: %1$s', - 'UI:Schema:RelationUp_Description' => 'Sens montant: %1$s', - 'UI:Schema:RelationPropagates' => '%1$s: se propage sur %2$d niveau(x), requête: %3$s', - 'UI:Schema:RelationDoesNotPropagate' => '%1$s: ne se propage pas (%2$d niveaux), requête: %3$s', - 'UI:Schema:Class_ReferencingClasses_From_By' => '%1$s est référencé par la classe %2$s via le champ %3$s', + 'UI:Schema:Type+' => 'Type de données de l\'attribut', + 'UI:Schema:Origin' => 'Origine', + 'UI:Schema:Origin+' => 'La classe de base dans laquelle l\'attribut est défini', + 'UI:Schema:Description' => 'Description', + 'UI:Schema:Description+' => 'Description de l\'attribut', + 'UI:Schema:AllowedValues' => 'Valeurs possibles', + 'UI:Schema:AllowedValues+' => 'Restrictions des valeurs possibles pour cet attribut', + 'UI:Schema:MoreInfo' => 'Plus info', + 'UI:Schema:MoreInfo+' => 'Plus d\'information à propos de la définition de ce champ dans la base de données', + 'UI:Schema:SearchCriteria' => 'Critères de recherche', + 'UI:Schema:FilterCode' => 'Code', + 'UI:Schema:FilterCode+' => 'Code de ce critère de recherche', + 'UI:Schema:FilterDescription' => 'Description', + 'UI:Schema:FilterDescription+' => 'Description de ce critère de recherche', + 'UI:Schema:AvailOperators' => 'Opérateurs', + 'UI:Schema:AvailOperators+' => 'Opérateurs possibles pour ce critère de recherche', + 'UI:Schema:ChildClasses' => 'Classes dérivées', + 'UI:Schema:ReferencingClasses' => 'Classes faisant référence', + 'UI:Schema:RelatedClasses' => 'Classes reliées', + 'UI:Schema:LifeCycle' => 'Cycle de vie', + 'UI:Schema:Triggers' => 'Déclencheurs', + 'UI:Schema:Relation_Code_Description' => 'Relation %1$s (%2$s)', + 'UI:Schema:RelationDown_Description' => 'Sens descendant: %1$s', + 'UI:Schema:RelationUp_Description' => 'Sens montant: %1$s', + 'UI:Schema:RelationPropagates' => '%1$s: se propage sur %2$d niveau(x), requête: %3$s', + 'UI:Schema:RelationDoesNotPropagate' => '%1$s: ne se propage pas (%2$d niveaux), requête: %3$s', + 'UI:Schema:Class_ReferencingClasses_From_By' => '%1$s est référencé par la classe %2$s via le champ %3$s', 'UI:Schema:Class_IsLinkedTo_Class_Via_ClassAndAttribute' => '%1$s est lié à la classe %2$s via %3$s::%4$s', - 'UI:Schema:Links:1-n' => 'Classes pointant sur %1$s (liens 1:n) :', - 'UI:Schema:Links:n-n' => 'Classes liées à %1$s (liens n:n) :', - 'UI:Schema:Links:All' => 'Graphe de toutes les classes liées', - 'UI:Schema:NoLifeCyle' => 'Aucun cycle de vie n\'est défini pour cette classe.', - 'UI:Schema:LifeCycleTransitions' => 'États et Transitions', - 'UI:Schema:LifeCyleAttributeOptions' => 'Options des attributs', - 'UI:Schema:LifeCycleHiddenAttribute' => 'Caché', - 'UI:Schema:LifeCycleReadOnlyAttribute' => 'Lecture seule', - 'UI:Schema:LifeCycleMandatoryAttribute' => 'Obligatoire', - 'UI:Schema:LifeCycleAttributeMustChange' => 'Doit changer', - 'UI:Schema:LifeCycleAttributeMustPrompt' => 'L\'utilisateur se verra proposer de changer la valeur', - 'UI:Schema:LifeCycleEmptyList' => 'liste vide', - 'UI:Schema:ClassFilter' => 'Classe :', - 'UI:Schema:DisplayLabel' => 'Affichage :', - 'UI:Schema:DisplaySelector/LabelAndCode' => 'Label et code', - 'UI:Schema:DisplaySelector/Label' => 'Label', - 'UI:Schema:DisplaySelector/Code' => 'Code', - 'UI:Schema:Attribute/Filter' => 'Filtre', - 'UI:Schema:DefaultNullValue' => 'Valeur null par défaut : "%1$s"', - 'UI:Schema:Events' => 'Événements', - 'UI:Schema:Events:Defined' => 'Événements', - 'UI:Schema:Events:NoEvent' => 'Aucun événement défini', - 'UI:Schema:Events:Listeners' => 'Récepteurs d\'événements', - 'UI:Schema:Events:NoListener' => 'Aucun récepteur d\'événements', - 'UI:Schema:Events:Event' => 'Événement', - 'UI:Schema:Events:Description' => 'Description', - 'UI:Schema:Events:Listener' => 'Récepteur', - 'UI:Schema:Events:Rank' => 'Rang', - 'UI:Schema:Events:Module' => 'Module', - 'UI:LinksWidget:Autocomplete+' => 'Tapez les 3 premiers caractères...', - 'UI:Edit:SearchQuery' => 'Sélectionner une requête prédéfinie', - 'UI:Edit:TestQuery' => 'Tester la requête', - 'UI:Combo:SelectValue' => '--- choisissez une valeur ---', - 'UI:Label:SelectedObjects' => 'Objets sélectionnés: ', - 'UI:Label:AvailableObjects' => 'Objets disponibles: ', - 'UI:Link_Class_Attributes' => 'Attributs du type %1$s', - 'UI:SelectAllToggle+' => 'Tout sélectionner / Tout déselectionner', - 'UI:AddObjectsOf_Class_LinkedWith_Class_Instance' => 'Ajouter des objets de type %1$s liés à %3$s (%2$s)', - 'UI:AddObjectsOf_Class_LinkedWith_Class' => 'Ajouter des objets de type %1$s à lier à cet objet de type %2$s', - 'UI:ManageObjectsOf_Class_LinkedWith_Class_Instance' => 'Gérer les objets de type %1$s liés à %3$s (%2$s)', - 'UI:AddLinkedObjectsOf_Class' => 'Ajouter des %1$s', - 'UI:RemoveLinkedObjectsOf_Class' => 'Enlever les objets sélectionnés', - 'UI:Message:EmptyList:UseAdd' => 'La liste est vide, utilisez le bouton "Ajouter..." pour ajouter des objets.', - 'UI:Message:EmptyList:UseSearchForm' => 'Utilisez le formulaire de recherche ci-dessus pour trouver les objets à ajouter.', - 'UI:Wizard:FinalStepTitle' => 'Dernière étape: confirmation', - 'UI:Title:DeletionOf_Object' => 'Suppression de %1$s', - 'UI:Title:BulkDeletionOf_Count_ObjectsOf_Class' => 'Suppression massive de %1$d objets de type %2$s', - 'UI:Delete:NotAllowedToDelete' => 'Vous n\'êtes pas autorisé à supprimer cet objet', - 'UI:Delete:NotAllowedToUpdate_Fields' => 'Vous n\'êtes pas autorisé à mettre à jour les champs suivants : %1$s', - 'UI:Error:ActionNotAllowed' => 'Vous n\'êtes pas autorisé à effectuer cette action', - 'UI:Error:NotEnoughRightsToDelete' => 'Cet objet ne peut pas être supprimé car l\'utilisateur courant n\'a pas les droits nécessaires.', - 'UI:Error:CannotDeleteBecause' => 'Cet objet ne peut pas être effacé. Raison: %1$s', - 'UI:Error:CannotDeleteBecauseOfDepencies' => 'Cet objet ne peut pas être supprimé, des opérations manuelles sont nécessaire avant sa suppression.', - 'UI:Error:CannotDeleteBecauseManualOpNeeded' => 'Des opération manuelles sont nécessaires avant de pouvoir effacer cet objet', - 'UI:Archive_User_OnBehalfOf_User' => '%1$s pour %2$s', - 'UI:Delete:Deleted' => 'supprimé', - 'UI:Delete:AutomaticallyDeleted' => 'supprimé automatiquement', - 'UI:Delete:AutomaticResetOf_Fields' => 'mise à jour automatique des champ(s): %1$s', - 'UI:Delete:CleaningUpRefencesTo_Object' => 'Suppression de toutes les références vers %1$s...', + 'UI:Schema:Links:1-n' => 'Classes pointant sur %1$s (liens 1:n) :', + 'UI:Schema:Links:n-n' => 'Classes liées à %1$s (liens n:n) :', + 'UI:Schema:Links:All' => 'Graphe de toutes les classes liées', + 'UI:Schema:NoLifeCyle' => 'Aucun cycle de vie n\'est défini pour cette classe.', + 'UI:Schema:LifeCycleTransitions' => 'États et Transitions', + 'UI:Schema:LifeCyleAttributeOptions' => 'Options des attributs', + 'UI:Schema:LifeCycleHiddenAttribute' => 'Caché', + 'UI:Schema:LifeCycleReadOnlyAttribute' => 'Lecture seule', + 'UI:Schema:LifeCycleMandatoryAttribute' => 'Obligatoire', + 'UI:Schema:LifeCycleAttributeMustChange' => 'Doit changer', + 'UI:Schema:LifeCycleAttributeMustPrompt' => 'L\'utilisateur se verra proposer de changer la valeur', + 'UI:Schema:LifeCycleEmptyList' => 'liste vide', + 'UI:Schema:ClassFilter' => 'Classe :', + 'UI:Schema:DisplayLabel' => 'Affichage :', + 'UI:Schema:DisplaySelector/LabelAndCode' => 'Label et code', + 'UI:Schema:DisplaySelector/Label' => 'Label', + 'UI:Schema:DisplaySelector/Code' => 'Code', + 'UI:Schema:Attribute/Filter' => 'Filtre', + 'UI:Schema:DefaultNullValue' => 'Valeur null par défaut : "%1$s"', + 'UI:Schema:Events' => 'Événements', + 'UI:Schema:Events:Defined' => 'Événements', + 'UI:Schema:Events:NoEvent' => 'Aucun événement défini', + 'UI:Schema:Events:Listeners' => 'Récepteurs d\'événements', + 'UI:Schema:Events:NoListener' => 'Aucun récepteur d\'événements', + 'UI:Schema:Events:Event' => 'Événement', + 'UI:Schema:Events:Description' => 'Description', + 'UI:Schema:Events:Listener' => 'Récepteur', + 'UI:Schema:Events:Rank' => 'Rang', + 'UI:Schema:Events:Module' => 'Module', + 'UI:LinksWidget:Autocomplete+' => 'Tapez les 3 premiers caractères...', + 'UI:Edit:SearchQuery' => 'Sélectionner une requête prédéfinie', + 'UI:Edit:TestQuery' => 'Tester la requête', + 'UI:Combo:SelectValue' => '--- choisissez une valeur ---', + 'UI:Label:SelectedObjects' => 'Objets sélectionnés: ', + 'UI:Label:AvailableObjects' => 'Objets disponibles: ', + 'UI:Link_Class_Attributes' => 'Attributs du type %1$s', + 'UI:SelectAllToggle+' => 'Tout sélectionner / Tout déselectionner', + 'UI:AddObjectsOf_Class_LinkedWith_Class_Instance' => 'Ajouter des objets de type %1$s liés à %3$s (%2$s)', + 'UI:AddObjectsOf_Class_LinkedWith_Class' => 'Ajouter des objets de type %1$s à lier à cet objet de type %2$s', + 'UI:ManageObjectsOf_Class_LinkedWith_Class_Instance' => 'Gérer les objets de type %1$s liés à %3$s (%2$s)', + 'UI:AddLinkedObjectsOf_Class' => 'Ajouter des %1$s', + 'UI:RemoveLinkedObjectsOf_Class' => 'Enlever les objets sélectionnés', + 'UI:Message:EmptyList:UseAdd' => 'La liste est vide, utilisez le bouton "Ajouter..." pour ajouter des objets.', + 'UI:Message:EmptyList:UseSearchForm' => 'Utilisez le formulaire de recherche ci-dessus pour trouver les objets à ajouter.', + 'UI:Wizard:FinalStepTitle' => 'Dernière étape: confirmation', + 'UI:Title:DeletionOf_Object' => 'Suppression de %1$s', + 'UI:Title:BulkDeletionOf_Count_ObjectsOf_Class' => 'Suppression massive de %1$d objets de type %2$s', + 'UI:Delete:NotAllowedToDelete' => 'Vous n\'êtes pas autorisé à supprimer cet objet', + 'UI:Delete:NotAllowedToUpdate_Fields' => 'Vous n\'êtes pas autorisé à mettre à jour les champs suivants : %1$s', + 'UI:Error:ActionNotAllowed' => 'Vous n\'êtes pas autorisé à effectuer cette action', + 'UI:Error:NotEnoughRightsToDelete' => 'Cet objet ne peut pas être supprimé car l\'utilisateur courant n\'a pas les droits nécessaires.', + 'UI:Error:CannotDeleteBecause' => 'Cet objet ne peut pas être effacé. Raison: %1$s', + 'UI:Error:CannotDeleteBecauseOfDepencies' => 'Cet objet ne peut pas être supprimé, des opérations manuelles sont nécessaire avant sa suppression.', + 'UI:Error:CannotDeleteBecauseManualOpNeeded' => 'Des opération manuelles sont nécessaires avant de pouvoir effacer cet objet', + 'UI:Archive_User_OnBehalfOf_User' => '%1$s pour %2$s', + 'UI:Delete:Deleted' => 'supprimé', + 'UI:Delete:AutomaticallyDeleted' => 'supprimé automatiquement', + 'UI:Delete:AutomaticResetOf_Fields' => 'mise à jour automatique des champ(s): %1$s', + 'UI:Delete:CleaningUpRefencesTo_Object' => 'Suppression de toutes les références vers %1$s...', 'UI:Delete:CleaningUpRefencesTo_Several_ObjectsOf_Class' => 'Suppression de toutes les références vers les %1$d objets de type %2$s...', - 'UI:Delete:Done+' => 'Ce qui a été effectué...', - 'UI:Delete:_Name_Class_Deleted' => ' %2$s %1$s supprimé.', - 'UI:Delete:ConfirmDeletionOf_Name' => 'Suppression de %1$s', - 'UI:Delete:ConfirmDeletionOf_Count_ObjectsOf_Class' => 'Suppression de %1$d objets de type %2$s', - 'UI:Delete:CannotDeleteBecause' => 'Ne peut pas être supprimé: %1$s', + 'UI:Delete:Done+' => 'Ce qui a été effectué...', + 'UI:Delete:_Name_Class_Deleted' => ' %2$s %1$s supprimé.', + 'UI:Delete:ConfirmDeletionOf_Name' => 'Suppression de %1$s', + 'UI:Delete:ConfirmDeletionOf_Count_ObjectsOf_Class' => 'Suppression de %1$d objets de type %2$s', + 'UI:Delete:CannotDeleteBecause' => 'Ne peut pas être supprimé: %1$s', 'UI:Delete:ShouldBeDeletedAtomaticallyButNotPossible' => 'Devrait être supprimé automatiquement, mais cela n\'est pas possible: %1$s', 'UI:Delete:MustBeDeletedManuallyButNotPossible' => 'Doit être supprimé manuellement, mais cela n\'est pas possible: %1$s', 'UI:Delete:WillBeDeletedAutomatically' => 'Sera supprimé automatiquement', @@ -1082,8 +1092,6 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé 'UI:TagAdminMenu:NoTags' => 'Pas de champ étiquette configuré', 'UI:TagSetFieldData:Error' => 'Erreur: %1$s', - 'Menu:AuditCategories' => 'Catégories d\'audit',// Duplicated into itop-welcome-itil (will be removed from here...) - 'Menu:AuditCategories+' => 'Catégories d\'audit',// Duplicated into itop-welcome-itil (will be removed from here...) 'Menu:Notifications:Title' => 'Catégories d\'audit',// Duplicated into itop-welcome-itil (will be removed from here...) 'Menu:RunQueriesMenu' => 'Requêtes OQL',// Duplicated into itop-welcome-itil (will be removed from here...) diff --git a/pages/audit.php b/pages/audit.php index 536dcbf1d..0b02cce62 100644 --- a/pages/audit.php +++ b/pages/audit.php @@ -210,7 +210,7 @@ try $sTitle = Dict::S('UI:Audit:AuditErrors'); $oP->SetBreadCrumbEntry('ui-tool-auditerrors', $sTitle, '', '', 'fas fa-stethoscope', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES); - $oBackButton = ButtonUIBlockFactory::MakeIconLink('fas fa-chevron-left', Dict::S('Back to audit results'), "./audit.php?".$oAppContext->GetForLink()); + $oBackButton = ButtonUIBlockFactory::MakeIconLink('fas fa-chevron-left', Dict::S('UI:Audit:InteractiveAudit:Back'), "./audit.php?".$oAppContext->GetForLink()); $oP->AddUiBlock($oBackButton); $oP->AddUiBlock(TitleUIBlockFactory::MakeForPage($sTitle.$oAuditRule->Get('description'))); @@ -222,7 +222,7 @@ try // Adjust the size of the Textarea containing the CSV to fit almost all the remaining space $oP->add_ready_script(" $('#1>textarea').height(400);"); // adjust the size of the block $sExportUrl = utils::GetAbsoluteUrlAppRoot()."pages/audit.php?operation=csv&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey(); - $oDownloadButton = ButtonUIBlockFactory::MakeForAlternativePrimaryAction('fas fa-chevron-left', Dict::S('Back to audit results'), "./audit.php?".$oAppContext->GetForLink()); + $oDownloadButton = ButtonUIBlockFactory::MakeForAlternativePrimaryAction('fas fa-chevron-left', Dict::S('UI:Audit:InteractiveAudit:Back'), "./audit.php?".$oAppContext->GetForLink()); $oP->add_ready_script("$('a[href*=\"webservices/export.php?expression=\"]').attr('href', '".$sExportUrl."&filename=audit.csv".$sAdvanced."');"); $oP->add_ready_script("$('#1 :checkbox').removeAttr('onclick').on('click', function() { var sAdvanced = ''; if (this.checked) sAdvanced = '&advanced=1'; window.location.href='$sExportUrl'+sAdvanced; } );"); @@ -231,7 +231,6 @@ try case 'errors': $sTitle = Dict::S('UI:Audit:AuditErrors'); - $oP->SetBreadCrumbEntry('ui-tool-auditerrors', $sTitle, '', '', 'fas fa-stethoscope', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES); $iCategory = utils::ReadParam('category', ''); $iRuleIndex = utils::ReadParam('rule', 0); @@ -243,7 +242,10 @@ try $oFilter = GetRuleResultFilter($iRuleIndex, $oDefinitionFilter, $oAppContext); $oErrorObjectSet = new CMDBObjectSet($oFilter); $oAuditRule = MetaModel::GetObject('AuditRule', $iRuleIndex); - $oBackButton = ButtonUIBlockFactory::MakeIconLink('fas fa-chevron-left', Dict::S('Back to audit results'), "./audit.php?".$oAppContext->GetForLink()); + $sDescription = get_class($oAuditRule).": ".$oAuditRule->GetName(); + $oP->SetBreadCrumbEntry('ui-tool-auditerrors', $sTitle, $sDescription, '', 'fas fa-stethoscope', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES); + + $oBackButton = ButtonUIBlockFactory::MakeIconLink('fas fa-chevron-left', Dict::S('UI:Audit:InteractiveAudit:Back'), "./audit.php?".$oAppContext->GetForLink()); $oP->AddUiBlock($oBackButton); $oP->AddUiBlock(TitleUIBlockFactory::MakeForPage($sTitle.$oAuditRule->Get('description'))); $sBlockId = 'audit_errors'; @@ -314,140 +316,143 @@ try case 'audit': default: - $oP->SetBreadCrumbEntry('ui-tool-audit', Dict::S('Menu:Audit'), Dict::S('UI:Audit:InteractiveAudit'), '', 'fas fa-stethoscope', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES); - $oP->AddUiBlock(TitleUIBlockFactory::MakeForPage(Dict::S('UI:Audit:InteractiveAudit'))); - - $sDomainKey = utils::ReadParam('domain', ''); - $sCategories = utils::ReadParam('categories', '', false, utils::ENUM_SANITIZATION_FILTER_STRING); // May contain commas - - $oCategoriesSet = new DBObjectSet(new DBObjectSearch('AuditCategory')); - $sSubTitle = Dict::S('UI:Audit:InteractiveAudit:AllCategories'); - if(!empty($sCategories)) - { - $oCategoriesSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT AuditCategory WHERE id IN (:categories)", array('categories' => explode(',',$sCategories)))); - $sSubTitle = Dict::Format('UI:Audit:InteractiveAudit:SelectedCategories', $oCategoriesSet->Count()); - } - elseif (!empty($sDomainKey)) - { - $oAuditDomain = MetaModel::GetObject('AuditDomain', $sDomainKey); - $oCategoriesSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT AuditCategory AS c JOIN lnkAuditCategoryToAuditDomain AS lnk ON lnk.category_id = c.id WHERE lnk.domain_id = :domain", array('domain' => $oAuditDomain->GetKey()))); - $sSubTitle = Dict::Format('UI:Audit:InteractiveAudit:SelectedDomain', $oAuditDomain->GetName()); - } - - $oP->AddUiBlock(new Text($sSubTitle)); - - - $oTotalBlock = DashletFactory::MakeForDashletBadge('../images/icons/icons8-audit.svg', '#', 0, Dict::S('UI:Audit:Dashboard:ObjectsAudited')); - $oErrorBlock = DashletFactory::MakeForDashletBadge('../images/icons/icons8-delete.svg', '#', 0, Dict::S('UI:Audit:Dashboard:ObjectsInError')); - $oWorkingBlock = DashletFactory::MakeForDashletBadge('../images/icons/icons8-checkmark.svg', '#', 0, Dict::S('UI:Audit:Dashboard:ObjectsValidated')); - - $aCSSClasses = ['ibo-dashlet--is-inline', 'ibo-dashlet-badge']; - - $oDashletContainerTotal = new DashletContainer(); - $oDashletContainerError = new DashletContainer(); - $oDashletContainerWorking = new DashletContainer(); - - $oDashletContainerTotal->AddSubBlock($oTotalBlock)->AddCSSClasses($aCSSClasses); - $oDashletContainerError->AddSubBlock($oErrorBlock)->AddCSSClasses($aCSSClasses); - $oDashletContainerWorking->AddSubBlock($oWorkingBlock)->AddCSSClasses($aCSSClasses); - - $oDashboardRow = new DashboardRow(); - - $oDashboardColumnTotal = new DashboardColumn(false, true); - $oDashboardColumnError = new DashboardColumn(false, true); - $oDashboardColumnWorking = new DashboardColumn(false, true); - - $oDashboardColumnTotal->AddUIBlock($oDashletContainerTotal); - $oDashboardColumnError->AddUIBlock($oDashletContainerError); - $oDashboardColumnWorking->AddUIBlock($oDashletContainerWorking); - - $oDashboardRow->AddDashboardColumn($oDashboardColumnTotal); - $oDashboardRow->AddDashboardColumn($oDashboardColumnError); - $oDashboardRow->AddDashboardColumn($oDashboardColumnWorking); - - $oDashboardRow->AddCSSClass('ibo-audit--dashboard'); - - $oP->AddUiBlock($oDashboardRow); - - - - $aAuditCategoryPanels = []; - /** @var AuditCategory $oAuditCategory */ - while($oAuditCategory = $oCategoriesSet->fetch()) - { - $oAuditCategoryPanelBlock = new Panel($oAuditCategory->GetName()); - $oAuditCategoryPanelBlock->SetIsCollapsible(true); - $aResults = array(); - try - { - $iCount = 0; - $oDefinitionFilter = DBObjectSearch::FromOQL($oAuditCategory->Get('definition_set')); - $oDefinitionFilter->UpdateContextFromUser(); - FilterByContext($oDefinitionFilter, $oAppContext); - - $aObjectsWithErrors = array(); - if (!empty($currentOrganization)) - { - if (MetaModel::IsValidFilterCode($oDefinitionFilter->GetClass(), 'org_id')) - { - $oDefinitionFilter->AddCondition('org_id', $currentOrganization, '='); - } - } - $oDefinitionSet = new CMDBObjectSet($oDefinitionFilter); - $iCount = $oDefinitionSet->Count(); - $oRulesFilter = new DBObjectSearch('AuditRule'); - $oRulesFilter->AddCondition('category_id', $oAuditCategory->GetKey(), '='); - $oRulesSet = new DBObjectSet($oRulesFilter); - while($oAuditRule = $oRulesSet->fetch() ) - { - $aRow = array(); - $aRow['description'] = $oAuditRule->GetName(); - if ($iCount == 0) - { - // nothing to check, really ! - $aRow['nb_errors'] = "GetKey()."&rule=".$oAuditRule->GetKey()."\">0"; - $aRow['percent_ok'] = '100.00'; - $aRow['class'] = $oAuditCategory->GetReportColor($iCount, 0); - } - else - { - try - { - $oFilter = GetRuleResultFilter($oAuditRule->GetKey(), $oDefinitionFilter, $oAppContext); - $aErrors = $oFilter->ToDataArray(array('id')); - $iErrorsCount = count($aErrors); - foreach($aErrors as $aErrorRow) - { - $aObjectsWithErrors[$aErrorRow['id']] = true; - } - $aRow['nb_errors'] = ($iErrorsCount == 0) ? '0' : "GetKey()."&rule=".$oAuditRule->GetKey()."&".$oAppContext->GetForLink()."\">$iErrorsCount GetKey()."&rule=".$oAuditRule->GetKey()."&".$oAppContext->GetForLink()."\">"; - $aRow['percent_ok'] = sprintf('%.2f', 100.0 * (($iCount - $iErrorsCount) / $iCount)); - $aRow['class'] = $oAuditCategory->GetReportColor($iCount, $iErrorsCount); - } - catch(Exception $e) - { - $aRow['nb_errors'] = Dict::S('UI:Audit:OqlError'); - $aRow['percent_ok'] = Dict::S('UI:Audit:Error:ValueNA'); - $aRow['class'] = 'red'; - $sMessage = Dict::Format('UI:Audit:ErrorIn_Rule_Reason', $oAuditRule->GetHyperlink(), $e->getMessage()); - - $oErrorAlert = AlertUIBlockFactory::MakeForFailure(Dict::S('UI:Audit:ErrorIn_Rule'), $sMessage); - $oErrorAlert->AddCSSClass('ibo-audit--error-alert'); - $oP->AddUiBlock($oErrorAlert); - } - } - $aResults[] = $aRow; - } - $iTotalErrors = count($aObjectsWithErrors); - $sOverallPercentOk = ($iCount == 0) ? '100.00' : sprintf('%.2f', 100.0 * (($iCount - $iTotalErrors) / $iCount)); - $sClass = $oAuditCategory->GetReportColor($iCount, $iTotalErrors); - - $oTotalBlock->SetCount((int)$oTotalBlock->GetCount() + ($iCount)); - $oErrorBlock->SetCount((int)$oErrorBlock->GetCount() + $iTotalErrors); - $oWorkingBlock->SetCount((int)$oWorkingBlock->GetCount() + ($iCount - $iTotalErrors)); - $oAuditCategoryPanelBlock->SetSubTitle(Dict::Format('UI:Audit:AuditCategory:Subtitle', $iTotalErrors, $iCount, $sOverallPercentOk)); - + $sDomainKey = utils::ReadParam('domain', ''); + $sCategories = utils::ReadParam('categories', '', false, utils::ENUM_SANITIZATION_FILTER_STRING); // May contain commas + $oCategoriesSet = new DBObjectSet(new DBObjectSearch('AuditCategory')); + $sSubTitle = Dict::S('UI:Audit:InteractiveAudit:AllCategories'); + $sBreadCrumbLabel = Dict::S('Menu:Audit'); + $sBreadCrumbDescription = Dict::S('UI:Audit:InteractiveAudit'); + if (!empty($sCategories)) { + $oCategoriesSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT AuditCategory WHERE id IN (:categories)", array('categories' => explode(',', $sCategories)))); + $sSubTitle = Dict::Format('UI:Audit:InteractiveAudit:SelectedCategories', $oCategoriesSet->Count()); + $sBreadCrumbLabel = Dict::S('UI:Audit:InteractiveAudit:ForCategories'); + } elseif (!empty($sDomainKey)) { + $oAuditDomain = MetaModel::GetObject('AuditDomain', $sDomainKey); + $oCategoriesSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT AuditCategory AS c JOIN lnkAuditCategoryToAuditDomain AS lnk ON lnk.category_id = c.id WHERE lnk.domain_id = :domain", array('domain' => $oAuditDomain->GetKey()))); + $sSubTitle = Dict::Format('UI:Audit:InteractiveAudit:SelectedDomain', $oAuditDomain->GetName()); + $sBreadCrumbLabel = $oAuditDomain->GetName(); } + + $oP->SetBreadCrumbEntry('ui-tool-audit', $sBreadCrumbLabel, $sSubTitle, '', 'fas fa-stethoscope', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES); + + $oBackButton = ButtonUIBlockFactory::MakeIconLink('fas fa-stethoscope fa-lg', Dict::S('UI:Audit:InteractiveAudit:Back'), "./audit.php?".$oAppContext->GetForLink()); + $oP->AddUiBlock($oBackButton); + $oP->AddUiBlock(TitleUIBlockFactory::MakeForPage(Dict::S('UI:Audit:InteractiveAudit'))); + + $oP->AddUiBlock(new Text($sSubTitle)); + + + $oTotalBlock = DashletFactory::MakeForDashletBadge('../images/icons/icons8-audit.svg', '#', 0, Dict::S('UI:Audit:Dashboard:ObjectsAudited')); + $oErrorBlock = DashletFactory::MakeForDashletBadge('../images/icons/icons8-delete.svg', '#', 0, Dict::S('UI:Audit:Dashboard:ObjectsInError')); + $oWorkingBlock = DashletFactory::MakeForDashletBadge('../images/icons/icons8-checkmark.svg', '#', 0, Dict::S('UI:Audit:Dashboard:ObjectsValidated')); + + $aCSSClasses = ['ibo-dashlet--is-inline', 'ibo-dashlet-badge']; + + $oDashletContainerTotal = new DashletContainer(); + $oDashletContainerError = new DashletContainer(); + $oDashletContainerWorking = new DashletContainer(); + + $oDashletContainerTotal->AddSubBlock($oTotalBlock)->AddCSSClasses($aCSSClasses); + $oDashletContainerError->AddSubBlock($oErrorBlock)->AddCSSClasses($aCSSClasses); + $oDashletContainerWorking->AddSubBlock($oWorkingBlock)->AddCSSClasses($aCSSClasses); + + $oDashboardRow = new DashboardRow(); + + $oDashboardColumnTotal = new DashboardColumn(false, true); + $oDashboardColumnError = new DashboardColumn(false, true); + $oDashboardColumnWorking = new DashboardColumn(false, true); + + $oDashboardColumnTotal->AddUIBlock($oDashletContainerTotal); + $oDashboardColumnError->AddUIBlock($oDashletContainerError); + $oDashboardColumnWorking->AddUIBlock($oDashletContainerWorking); + + $oDashboardRow->AddDashboardColumn($oDashboardColumnTotal); + $oDashboardRow->AddDashboardColumn($oDashboardColumnError); + $oDashboardRow->AddDashboardColumn($oDashboardColumnWorking); + + $oDashboardRow->AddCSSClass('ibo-audit--dashboard'); + + $oP->AddUiBlock($oDashboardRow); + + + $oRouter = \Combodo\iTop\Service\Router\Router::GetInstance(); + $aAuditCategoryPanels = []; + /** @var AuditCategory $oAuditCategory */ + while ($oAuditCategory = $oCategoriesSet->fetch()) { + $oAuditCategoryPanelBlock = new Panel($oAuditCategory->GetName()); + $oAuditCategoryPanelBlock->SetIsCollapsible(true); + // Create toolbar and add it to panel + $oToolbar = \Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarUIBlockFactory::MakeForButton(); + $oAuditCategoryPanelBlock->AddToolbarBlock($oToolbar); + // Add a button in the above toolbar + $sAuditCategoryClass = get_class($oAuditCategory); + if (UserRights::IsActionAllowed($sAuditCategoryClass, UR_ACTION_READ)) { + $oToolbar->AddSubBlock(ButtonUIBlockFactory::MakeIconLink('fas fa-eye', Dict::S('UI:Audit:ViewRules'), ApplicationContext::MakeObjectUrl($sAuditCategoryClass, $oAuditCategory->GetKey()).'&#ObjectProperties=tab_ClassAuditCategoryAttributerules_list')); + } + if (UserRights::IsActionAllowed($sAuditCategoryClass, UR_ACTION_MODIFY)) { + $oToolbar->AddSubBlock(ButtonUIBlockFactory::MakeIconLink('fas fa-pen', Dict::S('UI:Audit:ModifyCategory'), $oRouter->GenerateUrl('object.modify', ['class' => $sAuditCategoryClass, 'id' => $oAuditCategory->GetKey()]))); + } + $aResults = array(); + try { + $iCount = 0; + $oDefinitionFilter = DBObjectSearch::FromOQL($oAuditCategory->Get('definition_set')); + $oDefinitionFilter->UpdateContextFromUser(); + FilterByContext($oDefinitionFilter, $oAppContext); + + $aObjectsWithErrors = array(); + if (!empty($currentOrganization)) { + if (MetaModel::IsValidFilterCode($oDefinitionFilter->GetClass(), 'org_id')) { + $oDefinitionFilter->AddCondition('org_id', $currentOrganization, '='); + } + } + $oDefinitionSet = new CMDBObjectSet($oDefinitionFilter); + $iCount = $oDefinitionSet->Count(); + $oRulesFilter = new DBObjectSearch('AuditRule'); + $oRulesFilter->AddCondition('category_id', $oAuditCategory->GetKey(), '='); + $oRulesSet = new DBObjectSet($oRulesFilter); + while ($oAuditRule = $oRulesSet->fetch()) { + $aRow = array(); + $aRow['description'] = $oAuditRule->GetName(); + if ($iCount == 0) { + // nothing to check, really ! + $aRow['nb_errors'] = "GetKey()."&rule=".$oAuditRule->GetKey()."\">0"; + $aRow['percent_ok'] = '100.00'; + $aRow['class'] = $oAuditCategory->GetReportColor($iCount, 0); + } else { + try { + $oFilter = GetRuleResultFilter($oAuditRule->GetKey(), $oDefinitionFilter, $oAppContext); + $aErrors = $oFilter->ToDataArray(array('id')); + $iErrorsCount = count($aErrors); + foreach ($aErrors as $aErrorRow) { + $aObjectsWithErrors[$aErrorRow['id']] = true; + } + $aRow['nb_errors'] = ($iErrorsCount == 0) ? '0' : "GetKey()."&rule=".$oAuditRule->GetKey()."&".$oAppContext->GetForLink()."\">$iErrorsCount GetKey()."&rule=".$oAuditRule->GetKey()."&".$oAppContext->GetForLink()."\">"; + $aRow['percent_ok'] = sprintf('%.2f', 100.0 * (($iCount - $iErrorsCount) / $iCount)); + $aRow['class'] = $oAuditCategory->GetReportColor($iCount, $iErrorsCount); + } + catch (Exception $e) { + $aRow['nb_errors'] = Dict::S('UI:Audit:OqlError'); + $aRow['percent_ok'] = Dict::S('UI:Audit:Error:ValueNA'); + $aRow['class'] = 'red'; + $sMessage = Dict::Format('UI:Audit:ErrorIn_Rule_Reason', $oAuditRule->GetHyperlink(), $e->getMessage()); + + $oErrorAlert = AlertUIBlockFactory::MakeForFailure(Dict::S('UI:Audit:ErrorIn_Rule'), $sMessage); + $oErrorAlert->AddCSSClass('ibo-audit--error-alert'); + $oP->AddUiBlock($oErrorAlert); + } + } + $aResults[] = $aRow; + } + $iTotalErrors = count($aObjectsWithErrors); + $sOverallPercentOk = ($iCount == 0) ? '100.00' : sprintf('%.2f', 100.0 * (($iCount - $iTotalErrors) / $iCount)); + $sClass = $oAuditCategory->GetReportColor($iCount, $iTotalErrors); + + $oTotalBlock->SetCount((int)$oTotalBlock->GetCount() + ($iCount)); + $oErrorBlock->SetCount((int)$oErrorBlock->GetCount() + $iTotalErrors); + $oWorkingBlock->SetCount((int)$oWorkingBlock->GetCount() + ($iCount - $iTotalErrors)); + $oAuditCategoryPanelBlock->SetSubTitle(Dict::Format('UI:Audit:AuditCategory:Subtitle', $iTotalErrors, $iCount, $sOverallPercentOk)); + + } catch(Exception $e) { $sMessage = Dict::Format('UI:Audit:ErrorIn_Category_Reason', $oAuditCategory->GetHyperlink(), utils::HtmlEntities($e->getMessage()));