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:
parent
de40c8e533
commit
a9fca35644
@ -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
|
||||
};
|
||||
});
|
||||
|
||||
@ -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' }, [
|
||||
|
||||
@ -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', {
|
||||
|
||||
@ -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')
|
||||
])
|
||||
|
||||
Loading…
Reference in New Issue
Block a user