From b35b86684eed3f3e2ed3d8085d20f3ed2e77d39a Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Fri, 30 Jan 2026 09:30:54 +0100 Subject: [PATCH] fix(crowdsec-dashboard): Use baseclass.singleton for theme manager Fix "not a constructor" error by using baseclass.singleton() pattern instead of baseclass.extend() with manual instantiation. Theme module now exports a singleton directly. Co-Authored-By: Claude Opus 4.5 --- .../resources/crowdsec-dashboard/theme.js | 7 +++---- .../view/crowdsec-dashboard/overview.js | 10 +++------- .../view/crowdsec-dashboard/settings.js | 18 +++++++----------- 3 files changed, 13 insertions(+), 22 deletions(-) diff --git a/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/crowdsec-dashboard/theme.js b/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/crowdsec-dashboard/theme.js index ebc88999..741ec6fc 100644 --- a/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/crowdsec-dashboard/theme.js +++ b/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/crowdsec-dashboard/theme.js @@ -3,7 +3,7 @@ 'require uci'; /** - * CrowdSec Dashboard Theme Manager + * CrowdSec Dashboard Theme Manager (Singleton) * Handles loading and switching between UI themes * * Available themes: @@ -13,11 +13,10 @@ * * Profiles can extend themes with custom configurations * - * Usage: var theme = new (require('crowdsec-dashboard.theme'))(); - * theme.init().then(function() { ... }); + * Usage: theme.init().then(function() { ... }); */ -return baseclass.extend({ +return baseclass.singleton({ // Available themes themes: { 'classic': { diff --git a/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/view/crowdsec-dashboard/overview.js b/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/view/crowdsec-dashboard/overview.js index e6b9fb03..4f6dceea 100644 --- a/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/view/crowdsec-dashboard/overview.js +++ b/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/view/crowdsec-dashboard/overview.js @@ -5,7 +5,7 @@ 'require ui'; 'require uci'; 'require crowdsec-dashboard.api as api'; -'require crowdsec-dashboard.theme as ThemeClass'; +'require crowdsec-dashboard.theme as theme'; /** * CrowdSec SOC Dashboard - Overview @@ -13,16 +13,12 @@ * Version 1.1.0 */ -var themeInstance = new ThemeClass(); - return view.extend({ title: _('CrowdSec SOC'), - theme: themeInstance, load: function() { - var self = this; return Promise.all([ - self.theme.init(), + theme.init(), api.getOverview().catch(function() { return {}; }) ]); }, @@ -34,7 +30,7 @@ return view.extend({ // Apply theme class document.body.classList.add('cs-fullwidth'); - var view = E('div', { 'class': self.theme.getDashboardClass() }, [ + var view = E('div', { 'class': theme.getDashboardClass() }, [ this.renderHeader(status), this.renderNav('overview'), E('div', { 'id': 'cs-stats' }, this.renderStats(status)), diff --git a/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/view/crowdsec-dashboard/settings.js b/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/view/crowdsec-dashboard/settings.js index fde6c79c..c764d55c 100644 --- a/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/view/crowdsec-dashboard/settings.js +++ b/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/view/crowdsec-dashboard/settings.js @@ -4,7 +4,7 @@ 'require ui'; 'require uci'; 'require crowdsec-dashboard.api as api'; -'require crowdsec-dashboard.theme as ThemeClass'; +'require crowdsec-dashboard.theme as theme'; /** * CrowdSec SOC - Settings View @@ -12,19 +12,15 @@ * With theme/appearance settings */ -var themeInstance = new ThemeClass(); - return view.extend({ title: _('Settings'), status: {}, machines: [], collections: [], - theme: themeInstance, load: function() { - var self = this; return Promise.all([ - self.theme.init(), + theme.init(), api.getStatus(), api.getMachines(), api.getCollections(), @@ -46,7 +42,7 @@ return view.extend({ document.body.classList.add('cs-fullwidth'); - return E('div', { 'class': self.theme.getDashboardClass() }, [ + return E('div', { 'class': theme.getDashboardClass() }, [ this.renderHeader(), this.renderNav('settings'), E('div', { 'class': 'cs-stats' }, this.renderServiceStats()), @@ -93,8 +89,8 @@ return view.extend({ var currentTheme = uci.get('crowdsec-dashboard', 'main', 'theme') || 'classic'; var currentProfile = uci.get('crowdsec-dashboard', 'main', 'profile') || 'default'; - var themes = this.theme.getThemes(); - var profiles = this.theme.getProfiles(); + var themes = theme.getThemes(); + var profiles = theme.getProfiles(); return E('div', {}, [ E('div', { 'style': 'margin-bottom: 16px;' }, [ @@ -131,11 +127,11 @@ return view.extend({ }, previewTheme: function(themeName) { - this.theme.switchTheme(themeName); + theme.switchTheme(themeName); }, previewProfile: function(profileName) { - this.theme.switchProfile(profileName); + theme.switchProfile(profileName); }, saveAppearance: function() {