diff --git a/.doc/contributing-guide/2023.contributing-stickers-side-by-side.png b/.doc/contributing-guide/2023.contributing-stickers-side-by-side.png new file mode 100644 index 000000000..e477510ba Binary files /dev/null and b/.doc/contributing-guide/2023.contributing-stickers-side-by-side.png differ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f0b67267a..30251f064 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -161,4 +161,4 @@ We have one sticker per contribution type. You might get multiple stickers with Here is the design of each stickers for year 2022: -![iTop stickers 2022](.doc/contributing-guide/2022.contributing-stickers-side-by-side.png) +![iTop stickers 2023](.doc/contributing-guide/2023.contributing-stickers-side-by-side.png) diff --git a/application/dashboard.class.inc.php b/application/dashboard.class.inc.php index 8bc91c721..872d52f37 100644 --- a/application/dashboard.class.inc.php +++ b/application/dashboard.class.inc.php @@ -918,7 +918,7 @@ class RuntimeDashboard extends Dashboard { $bCustomized = false; - $sDashboardFileSanitized = utils::RealPath($sDashboardFile, APPROOT); + $sDashboardFileSanitized = utils::RealPath(APPROOT.$sDashboardFile, APPROOT); if (false === $sDashboardFileSanitized) { throw new SecurityException('Invalid dashboard file !'); } @@ -1141,7 +1141,7 @@ JS $oToolbar->AddSubBlock($oActionButton); $aActions = array(); - $sFile = addslashes($this->sDefinitionFile); + $sFile = addslashes(utils::LocalPath($this->sDefinitionFile)); $sJSExtraParams = json_encode($aExtraParams); if ($this->HasCustomDashboard()) { $oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:EditCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)"); diff --git a/js/dashboard.js b/js/dashboard.js index 6441ed317..2699e189e 100644 --- a/js/dashboard.js +++ b/js/dashboard.js @@ -332,11 +332,14 @@ $(function() oParams.dashlet_class = sDashletClass; oParams.dashlet_id = sDashletId; oParams.dashlet_type = options.dashlet_type; + oParams.ajax_promise_id = 'ajax_promise_' + sDashletId; var me = this; $.post(this.options.render_to, oParams, function (data) { me.ajax_div.html(data); - me.add_dashlet_finalize(options, sDashletId, sDashletClass); - me.mark_as_modified(); + window[oParams.ajax_promise_id].then(function(){ + me.add_dashlet_finalize(options, sDashletId, sDashletClass); + me.mark_as_modified(); + }); }); }, on_dashlet_moved: function (oDashlet, oReceiver, bRefresh) { diff --git a/tests/php-unit-tests/integration-tests/DictionariesConsistencyAfterSetupTest.php b/tests/php-unit-tests/integration-tests/DictionariesConsistencyAfterSetupTest.php index 8b54282f6..4c6446910 100644 --- a/tests/php-unit-tests/integration-tests/DictionariesConsistencyAfterSetupTest.php +++ b/tests/php-unit-tests/integration-tests/DictionariesConsistencyAfterSetupTest.php @@ -151,6 +151,12 @@ class DictionariesConsistencyAfterSetupTest extends ItopTestCase $aMismatchedKeys = []; foreach ($aKeyArgsCountMap[$sReferenceLangCode] as $sKey => $iExpectedNbOfArgs){ + if (0 === $iExpectedNbOfArgs){ + //no arg needed in EN. + //let s assume job has been done correctly in EN to simplify + continue; + } + if (in_array($sKey, self::$aLabelCodeNotToCheck)){ //false positive: do not test continue;