fix: Release v0.4.4 - Improved version handling and helpers refactoring

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 <noreply@anthropic.com>
This commit is contained in:
CyberMind-FR 2025-12-28 19:35:54 +01:00
parent de40c8e533
commit a9fca35644
4 changed files with 85 additions and 8 deletions

View File

@ -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
};
});

View File

@ -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' }, [

View File

@ -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', {

View File

@ -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')
])