feat: Add SecuBox portal header to all System Hub views

Add unified SecuBox header navigation to all 10 System Hub views
for consistent portal integration when accessed from SecuBox Portal:
- overview.js, health.js, services.js, diagnostics.js
- logs.js, backup.js, components.js, settings.js
- dev-status.js, remote.js

Pattern: Wrap view content with secubox-page-wrapper and prepend
SbHeader.render() to hide LuCI sidebar when in portal context.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
CyberMind-FR 2026-01-09 15:46:48 +01:00
parent 3eacc6c4e7
commit 66aa12d6b6
10 changed files with 52 additions and 10 deletions

View File

@ -5,6 +5,7 @@
'require secubox-theme/theme as Theme'; 'require secubox-theme/theme as Theme';
'require system-hub/theme-assets as ThemeAssets'; 'require system-hub/theme-assets as ThemeAssets';
'require system-hub/nav as HubNav'; 'require system-hub/nav as HubNav';
'require secubox-portal/header as SbHeader';
var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) || var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
(document.documentElement && document.documentElement.getAttribute('lang')) || (document.documentElement && document.documentElement.getAttribute('lang')) ||
@ -27,7 +28,7 @@ return view.extend({
}, },
render: function() { render: function() {
return E('div', { 'class': 'system-hub-dashboard sh-backup-view' }, [ var container = E('div', { 'class': 'system-hub-dashboard sh-backup-view' }, [
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }), E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
ThemeAssets.stylesheet('common.css'), ThemeAssets.stylesheet('common.css'),
ThemeAssets.stylesheet('dashboard.css'), ThemeAssets.stylesheet('dashboard.css'),
@ -42,6 +43,11 @@ return view.extend({
this.renderMaintenanceCard() this.renderMaintenanceCard()
]) ])
]); ]);
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
wrapper.appendChild(SbHeader.render());
wrapper.appendChild(container);
return wrapper;
}, },
renderHeader: function() { renderHeader: function() {

View File

@ -7,6 +7,7 @@
'require secubox-theme/theme as Theme'; 'require secubox-theme/theme as Theme';
'require system-hub/theme-assets as ThemeAssets'; 'require system-hub/theme-assets as ThemeAssets';
'require system-hub/nav as HubNav'; 'require system-hub/nav as HubNav';
'require secubox-portal/header as SbHeader';
var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) || var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
(document.documentElement && document.documentElement.getAttribute('lang')) || (document.documentElement && document.documentElement.getAttribute('lang')) ||
@ -61,7 +62,10 @@ return view.extend({
}, this)); }, this));
}, this), 30); }, this), 30);
return view; var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
wrapper.appendChild(SbHeader.render());
wrapper.appendChild(view);
return wrapper;
}, },
renderFilterTabs: function() { renderFilterTabs: function() {

View File

@ -4,6 +4,7 @@
'require system-hub/theme-assets as ThemeAssets'; 'require system-hub/theme-assets as ThemeAssets';
'require system-hub/dev-status-widget as DevStatusWidget'; 'require system-hub/dev-status-widget as DevStatusWidget';
'require system-hub/nav as HubNav'; 'require system-hub/nav as HubNav';
'require secubox-portal/header as SbHeader';
return view.extend({ return view.extend({
widget: null, widget: null,
@ -53,7 +54,10 @@ return view.extend({
widget.render('dev-status-widget'); widget.render('dev-status-widget');
}); });
return container; var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
wrapper.appendChild(SbHeader.render());
wrapper.appendChild(container);
return wrapper;
}, },
renderHeader: function() { renderHeader: function() {

View File

@ -7,6 +7,7 @@
'require system-hub/api as API'; 'require system-hub/api as API';
'require system-hub/theme-assets as ThemeAssets'; 'require system-hub/theme-assets as ThemeAssets';
'require system-hub/nav as HubNav'; 'require system-hub/nav as HubNav';
'require secubox-portal/header as SbHeader';
var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) || var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
(document.documentElement && document.documentElement.getAttribute('lang')) || (document.documentElement && document.documentElement.getAttribute('lang')) ||
@ -114,7 +115,10 @@ return view.extend({
]) ])
]); ]);
return view; var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
wrapper.appendChild(SbHeader.render());
wrapper.appendChild(view);
return wrapper;
}, },
renderToggle: function(icon, label, desc, enabled, id) { renderToggle: function(icon, label, desc, enabled, id) {

View File

@ -7,6 +7,7 @@
'require secubox-theme/theme as Theme'; 'require secubox-theme/theme as Theme';
'require system-hub/theme-assets as ThemeAssets'; 'require system-hub/theme-assets as ThemeAssets';
'require system-hub/nav as HubNav'; 'require system-hub/nav as HubNav';
'require secubox-portal/header as SbHeader';
var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) || var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
(document.documentElement && document.documentElement.getAttribute('lang')) || (document.documentElement && document.documentElement.getAttribute('lang')) ||
@ -44,7 +45,10 @@ return view.extend({
}); });
}, 30); }, 30);
return container; var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
wrapper.appendChild(SbHeader.render());
wrapper.appendChild(container);
return wrapper;
}, },
renderHero: function() { renderHero: function() {

View File

@ -7,6 +7,7 @@
'require secubox-theme/theme as Theme'; 'require secubox-theme/theme as Theme';
'require system-hub/theme-assets as ThemeAssets'; 'require system-hub/theme-assets as ThemeAssets';
'require system-hub/nav as HubNav'; 'require system-hub/nav as HubNav';
'require secubox-portal/header as SbHeader';
var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) || var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
(document.documentElement && document.documentElement.getAttribute('lang')) || (document.documentElement && document.documentElement.getAttribute('lang')) ||
@ -60,7 +61,10 @@ return view.extend({
}); });
}, this.pollInterval); }, this.pollInterval);
return container; var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
wrapper.appendChild(SbHeader.render());
wrapper.appendChild(container);
return wrapper;
}, },
renderHero: function() { renderHero: function() {

View File

@ -7,6 +7,7 @@
'require secubox-theme/theme as Theme'; 'require secubox-theme/theme as Theme';
'require system-hub/theme-assets as ThemeAssets'; 'require system-hub/theme-assets as ThemeAssets';
'require system-hub/nav as HubNav'; 'require system-hub/nav as HubNav';
'require secubox-portal/header as SbHeader';
var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) || var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
(document.documentElement && document.documentElement.getAttribute('lang')) || (document.documentElement && document.documentElement.getAttribute('lang')) ||
@ -52,7 +53,10 @@ return view.extend({
}); });
}, 30); }, 30);
return container; var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
wrapper.appendChild(SbHeader.render());
wrapper.appendChild(container);
return wrapper;
}, },
renderPageHeader: function() { renderPageHeader: function() {

View File

@ -6,6 +6,7 @@
'require system-hub/api as API'; 'require system-hub/api as API';
'require system-hub/theme-assets as ThemeAssets'; 'require system-hub/theme-assets as ThemeAssets';
'require system-hub/nav as HubNav'; 'require system-hub/nav as HubNav';
'require secubox-portal/header as SbHeader';
var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) || var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
(document.documentElement && document.documentElement.getAttribute('lang')) || (document.documentElement && document.documentElement.getAttribute('lang')) ||
@ -244,7 +245,10 @@ return view.extend({
]) ])
]); ]);
return view; var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
wrapper.appendChild(SbHeader.render());
wrapper.appendChild(view);
return wrapper;
}, },
renderToggle: function(icon, label, desc, enabled, id) { renderToggle: function(icon, label, desc, enabled, id) {

View File

@ -7,6 +7,7 @@
'require secubox-theme/theme as Theme'; 'require secubox-theme/theme as Theme';
'require system-hub/theme-assets as ThemeAssets'; 'require system-hub/theme-assets as ThemeAssets';
'require system-hub/nav as HubNav'; 'require system-hub/nav as HubNav';
'require secubox-portal/header as SbHeader';
var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) || var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
(document.documentElement && document.documentElement.getAttribute('lang')) || (document.documentElement && document.documentElement.getAttribute('lang')) ||
@ -46,7 +47,10 @@ return view.extend({
}); });
}, 30); }, 30);
return container; var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
wrapper.appendChild(SbHeader.render());
wrapper.appendChild(container);
return wrapper;
}, },
normalizeServices: function(data) { normalizeServices: function(data) {

View File

@ -5,6 +5,7 @@
'require secubox-theme/theme as Theme'; 'require secubox-theme/theme as Theme';
'require system-hub/theme-assets as ThemeAssets'; 'require system-hub/theme-assets as ThemeAssets';
'require system-hub/nav as HubNav'; 'require system-hub/nav as HubNav';
'require secubox-portal/header as SbHeader';
var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) || var shLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
(document.documentElement && document.documentElement.getAttribute('lang')) || (document.documentElement && document.documentElement.getAttribute('lang')) ||
@ -36,7 +37,10 @@ return view.extend({
this.renderActions() this.renderActions()
]); ]);
return container; var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
wrapper.appendChild(SbHeader.render());
wrapper.appendChild(container);
return wrapper;
}, },
renderHeader: function() { renderHeader: function() {