From a9fca3564426051d16de313d168bddbd80f5f0b4 Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Sun, 28 Dec 2025 19:35:54 +0100 Subject: [PATCH] fix: Release v0.4.4 - Improved version handling and helpers refactoring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This release focuses on consistent version display across all modules and proper OOP structure for network-modes helpers. ## Version Display Improvements (3 files) Added robust version resolution functions to handle various version field names: **SecuBox Dashboard** (dashboard.js): - Added getModuleVersion() function with fallback chain - Checks: version, pkg_version, package_version, packageVersion, Version - Handles both string and number types - Returns 'β€”' if no version found - Loads modules list from API for accurate version data **SecuBox Modules** (modules.js): - Added resolveModuleVersion() function with same fallback logic - Ensures consistent version display in module cards - Handles missing or undefined versions gracefully **System Hub Components** (components.js): - Added getComponentVersion() function with version fallback chain - Consistent version display across all components - Proper handling of edge cases (null, undefined, empty strings) ## Network Modes Refactoring (1 file) **helpers.js**: - Refactored from plain object export to baseclass.extend() - Proper OOP structure following LuCI conventions - Added 'require baseclass' import - All helper functions now properly encapsulated - Better integration with LuCI module system ## Benefits - Consistent version display across SecuBox, System Hub, and Components - Handles version field name variations (legacy, OpenWrt, custom) - Type-safe version handling (numbers β†’ strings) - Improved code maintainability with proper OOP structure - Better error handling for missing version information Summary: - 4 files changed (+85, -8) - 3 new version resolution functions - 1 OOP refactoring for helpers - Improved consistency and reliability πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- .../resources/network-modes/helpers.js | 5 +-- .../resources/view/secubox/dashboard.js | 36 ++++++++++++++++--- .../resources/view/secubox/modules.js | 26 +++++++++++++- .../resources/view/system-hub/components.js | 26 +++++++++++++- 4 files changed, 85 insertions(+), 8 deletions(-) diff --git a/luci-app-network-modes/htdocs/luci-static/resources/network-modes/helpers.js b/luci-app-network-modes/htdocs/luci-static/resources/network-modes/helpers.js index 15c3fb3b..f1c4fd69 100644 --- a/luci-app-network-modes/htdocs/luci-static/resources/network-modes/helpers.js +++ b/luci-app-network-modes/htdocs/luci-static/resources/network-modes/helpers.js @@ -1,4 +1,5 @@ 'use strict'; +'require baseclass'; 'require ui'; 'require network-modes.api as api'; @@ -156,7 +157,7 @@ function createNavigationTabs(activeId) { ]); } -return { +return baseclass.extend({ isToggleActive: isToggleActive, persistSettings: persistSettings, showGeneratedConfig: showGeneratedConfig, @@ -166,4 +167,4 @@ return { createList: createList, createStepper: createStepper, createNavigationTabs: createNavigationTabs -}; +}); diff --git a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/dashboard.js b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/dashboard.js index 4ef3b38b..1f0ed9ef 100644 --- a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/dashboard.js +++ b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/dashboard.js @@ -22,6 +22,7 @@ return view.extend({ dashboardData: null, healthData: null, alertsData: null, + modulesList: [], activeCategory: 'all', load: function() { @@ -33,11 +34,13 @@ return view.extend({ return Promise.all([ API.getDashboardData(), API.getSystemHealth(), - API.getAlerts() + API.getAlerts(), + API.getModules() ]).then(function(data) { self.dashboardData = data[0] || {}; self.healthData = data[1] || {}; self.alertsData = data[2] || {}; + self.modulesList = (data[3] && data[3].modules) || []; return data; }); }, @@ -157,7 +160,9 @@ return view.extend({ }, getFilteredModules: function() { - var modules = this.dashboardData.modules || []; + var modules = (this.modulesList && this.modulesList.length) + ? this.modulesList + : (this.dashboardData.modules || []); if (this.activeCategory === 'all') return modules; return modules.filter(function(module) { @@ -165,6 +170,29 @@ return view.extend({ }, this); }, + getModuleVersion: function(module) { + if (!module) + return 'β€”'; + + var candidates = [ + module.version, + module.pkg_version, + module.package_version, + module.packageVersion, + module.Version + ]; + + for (var i = 0; i < candidates.length; i++) { + var value = candidates[i]; + if (typeof value === 'number') + return String(value); + if (typeof value === 'string' && value.trim()) + return value.trim(); + } + + return 'β€”'; + }, + renderModuleCard: function(module) { var status = module.status || 'unknown'; var statusLabel = status === 'active' ? _('Running') : @@ -180,8 +208,8 @@ return view.extend({ ]), E('span', { 'class': 'sb-status-pill' }, statusLabel) ]), - E('div', { 'class': 'sb-module-meta' }, [ - E('span', {}, _('Version: ') + (module.version || '0.0.0')), + E('div', { 'class': 'sb-module-meta' }, [ + E('span', {}, _('Version: ') + this.getModuleVersion(module)), E('span', {}, _('Category: ') + (module.category || 'other')) ]), E('div', { 'class': 'sb-module-actions' }, [ diff --git a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/modules.js b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/modules.js index 588373d4..baebd237 100644 --- a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/modules.js +++ b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/modules.js @@ -159,6 +159,29 @@ return view.extend({ }); }, + resolveModuleVersion: function(module) { + if (!module) + return 'β€”'; + + var candidates = [ + module.version, + module.pkg_version, + module.package_version, + module.packageVersion, + module.Version + ]; + + for (var i = 0; i < candidates.length; i++) { + var value = candidates[i]; + if (typeof value === 'number') + return String(value); + if (typeof value === 'string' && value.trim()) + return value.trim(); + } + + return 'β€”'; + }, + renderModuleCard: function(module) { var self = this; var status = module.status || 'unknown'; @@ -175,6 +198,7 @@ return view.extend({ }; var statusLabel = isInstalled ? (statusLabels[status] || 'β—‹ DΓ©sactivΓ©') : statusLabels['not-installed']; + var versionLabel = this.resolveModuleVersion(module); return E('div', { 'class': 'secubox-module-card secubox-module-' + statusClass, @@ -189,7 +213,7 @@ return view.extend({ E('span', { 'class': 'secubox-module-category' }, this.getCategoryIcon(module.category) + ' ' + (module.category || 'other')), E('span', { 'class': 'secubox-module-version' }, - 'v' + (module.version || '0.0.9')) + versionLabel === 'β€”' ? versionLabel : 'v' + versionLabel) ]) ]), E('div', { diff --git a/luci-app-system-hub/htdocs/luci-static/resources/view/system-hub/components.js b/luci-app-system-hub/htdocs/luci-static/resources/view/system-hub/components.js index f4fbeefd..218959d1 100644 --- a/luci-app-system-hub/htdocs/luci-static/resources/view/system-hub/components.js +++ b/luci-app-system-hub/htdocs/luci-static/resources/view/system-hub/components.js @@ -114,11 +114,35 @@ return view.extend({ return filtered.map(L.bind(this.renderComponentCard, this)); }, + getComponentVersion: function(component) { + if (!component) + return 'β€”'; + + var candidates = [ + component.version, + component.pkg_version, + component.package_version, + component.packageVersion, + component.Version + ]; + + for (var i = 0; i < candidates.length; i++) { + var value = candidates[i]; + if (typeof value === 'number') + return String(value); + if (typeof value === 'string' && value.trim()) + return value.trim(); + } + + return 'β€”'; + }, + renderComponentCard: function(component) { var self = this; var isRunning = component.running; var isInstalled = component.installed; var statusClass = isRunning ? 'running' : (isInstalled ? 'stopped' : 'not-installed'); + var versionLabel = this.getComponentVersion(component); return E('div', { 'class': 'sh-component-card sh-component-' + statusClass, @@ -130,7 +154,7 @@ return view.extend({ E('h3', { 'class': 'sh-component-name' }, component.name || component.id), E('div', { 'class': 'sh-component-meta' }, [ E('span', { 'class': 'sh-component-version' }, - 'v' + (component.version || '0.0.9')), + versionLabel === 'β€”' ? versionLabel : 'v' + versionLabel), E('span', { 'class': 'sh-component-category' }, component.category || 'other') ])