From 1a30c381d60a8243b6bc99d5f940074d1b7275bd Mon Sep 17 00:00:00 2001 From: Gabriel Oliveira Date: Wed, 27 Aug 2025 17:06:17 +0100 Subject: [PATCH 1/2] fix: clear timeouts and intervals before destroying sidebar component --- .../countly/vue/components/sidebar.js | 49 ++++++++++++++++--- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/frontend/express/public/javascripts/countly/vue/components/sidebar.js b/frontend/express/public/javascripts/countly/vue/components/sidebar.js index 01f51276600..cd62b3a9cc3 100644 --- a/frontend/express/public/javascripts/countly/vue/components/sidebar.js +++ b/frontend/express/public/javascripts/countly/vue/components/sidebar.js @@ -571,6 +571,10 @@ }, data: function() { return { + refsCheckInterval: null, + refsCheckTimeout: null, + onMainMenuMouseLeaveTimeout: null, + onOptionsMenuMouseLeaveTimeout: null, selectedMenuOptionLocal: null, versionInfo: countlyGlobal.countlyTypeName, countlySidebarVersionPath: '/dashboard#/' + countlyCommon.ACTIVE_APP_ID + '/versions', @@ -838,7 +842,7 @@ */ this.$nextTick(function() { this.$nextTick(function() { - setTimeout(function() { + self.onOptionsMenuMouseLeaveTimeout = setTimeout(function() { if (selectedOption && selectedOption.menu === "dashboards") { if (!self.onMainMenu && self.$refs.dashboards && self.$refs.dashboards[0] && !self.$refs.dashboards[0].hasOpenDrawer()) { 0; @@ -848,6 +852,9 @@ self.showMainMenu = false; } } + + clearTimeout(self.onOptionsMenuMouseLeaveTimeout); + self.onOptionsMenuMouseLeaveTimeout = null; }, 0); }); }); @@ -871,7 +878,7 @@ */ this.$nextTick(function() { this.$nextTick(function() { - setTimeout(function() { + self.onMainMenuMouseLeaveTimeout = setTimeout(function() { if (selectedOption && selectedOption.menu === "dashboards") { if (!self.onOptionsMenu && self.$refs.dashboards && self.$refs.dashboards[0] && !self.$refs.dashboards[0].hasOpenDrawer()) { /** @@ -880,6 +887,9 @@ self.showMainMenu = false; } } + + clearTimeout(self.onMainMenuMouseLeaveTimeout); + self.onMainMenuMouseLeaveTimeout = null; }, 0); }); }); @@ -962,7 +972,7 @@ * * Following technique of checking refs is just a fullproof way of doing it. */ - setTimeout(function() { + this.refsCheckTimeout = setTimeout(function() { self.$nextTick(function() { self.$nextTick(function() { /** @@ -978,7 +988,7 @@ * Clear the interval when the refs are found. */ var counter = 0; - var interval = setInterval(function() { + self.refsCheckInterval = setInterval(function() { if (counter > 10) { /** * Lets only check for the refs 10 times. @@ -990,13 +1000,19 @@ // eslint-disable-next-line no-console console.log("Refs not found in sidebar yet. Returning..."); - clearInterval(interval); + clearTimeout(self.refsCheckTimeout); + clearInterval(self.refsCheckInterval); + self.refsCheckTimeout = null; + self.refsCheckInterval = null; return; } if (Object.keys(self.$refs).length) { self.identifySelected(); - clearInterval(interval); + clearInterval(self.refsCheckInterval); + clearTimeout(self.refsCheckTimeout); + self.refsCheckTimeout = null; + self.refsCheckInterval = null; } counter++; @@ -1006,6 +1022,27 @@ }); }, 0); }, + beforeDestroy() { + if (this.refsCheckInterval) { + clearInterval(this.refsCheckInterval); + this.refsCheckInterval = null; + } + + if (this.onMainMenuMouseLeaveTimeout) { + clearTimeout(this.onMainMenuMouseLeaveTimeout); + this.onMainMenuMouseLeaveTimeout = null; + } + + if (this.onOptionsMenuMouseLeaveTimeout) { + clearTimeout(this.onOptionsMenuMouseLeaveTimeout); + this.onOptionsMenuMouseLeaveTimeout = null; + } + + if (this.refsCheckTimeout) { + clearTimeout(this.refsCheckTimeout); + this.refsCheckTimeout = null; + } + }, created: function() { var self = this; if (this.enableGuides) { From d1a05a3823cc861d809232548d84bf094448f5e7 Mon Sep 17 00:00:00 2001 From: Gabriel Oliveira Date: Wed, 27 Aug 2025 17:09:08 +0100 Subject: [PATCH 2/2] feat: only set new timeout if it does not exist --- .../countly/vue/components/sidebar.js | 50 ++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/frontend/express/public/javascripts/countly/vue/components/sidebar.js b/frontend/express/public/javascripts/countly/vue/components/sidebar.js index cd62b3a9cc3..e191d5e9b77 100644 --- a/frontend/express/public/javascripts/countly/vue/components/sidebar.js +++ b/frontend/express/public/javascripts/countly/vue/components/sidebar.js @@ -842,20 +842,22 @@ */ this.$nextTick(function() { this.$nextTick(function() { - self.onOptionsMenuMouseLeaveTimeout = setTimeout(function() { - if (selectedOption && selectedOption.menu === "dashboards") { - if (!self.onMainMenu && self.$refs.dashboards && self.$refs.dashboards[0] && !self.$refs.dashboards[0].hasOpenDrawer()) { - 0; - /** - * If not on the main menu, hide the main menu. - */ - self.showMainMenu = false; + if (!self.onOptionsMenuMouseLeaveTimeout) { + self.onOptionsMenuMouseLeaveTimeout = setTimeout(function() { + if (selectedOption && selectedOption.menu === "dashboards") { + if (!self.onMainMenu && self.$refs.dashboards && self.$refs.dashboards[0] && !self.$refs.dashboards[0].hasOpenDrawer()) { + 0; + /** + * If not on the main menu, hide the main menu. + */ + self.showMainMenu = false; + } } - } - clearTimeout(self.onOptionsMenuMouseLeaveTimeout); - self.onOptionsMenuMouseLeaveTimeout = null; - }, 0); + clearTimeout(self.onOptionsMenuMouseLeaveTimeout); + self.onOptionsMenuMouseLeaveTimeout = null; + }, 0); + } }); }); }, @@ -878,19 +880,21 @@ */ this.$nextTick(function() { this.$nextTick(function() { - self.onMainMenuMouseLeaveTimeout = setTimeout(function() { - if (selectedOption && selectedOption.menu === "dashboards") { - if (!self.onOptionsMenu && self.$refs.dashboards && self.$refs.dashboards[0] && !self.$refs.dashboards[0].hasOpenDrawer()) { - /** - * If not on the options menu, hide the main menu. - */ - self.showMainMenu = false; + if (!self.onMainMenuMouseLeaveTimeout) { + self.onMainMenuMouseLeaveTimeout = setTimeout(function() { + if (selectedOption && selectedOption.menu === "dashboards") { + if (!self.onOptionsMenu && self.$refs.dashboards && self.$refs.dashboards[0] && !self.$refs.dashboards[0].hasOpenDrawer()) { + /** + * If not on the options menu, hide the main menu. + */ + self.showMainMenu = false; + } } - } - clearTimeout(self.onMainMenuMouseLeaveTimeout); - self.onMainMenuMouseLeaveTimeout = null; - }, 0); + clearTimeout(self.onMainMenuMouseLeaveTimeout); + self.onMainMenuMouseLeaveTimeout = null; + }, 0); + } }); }); },