feat: Add SecuBox portal header to all Network Modes views
Add unified SecuBox header navigation to all 12 Network Modes views for consistent portal integration when accessed from SecuBox Portal: - overview.js, router.js, accesspoint.js, doublenat.js - multiwan.js, relay.js, sniffer.js, travel.js - vpnrelay.js, dmz.js, wizard.js, settings.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:
parent
7df952c2a7
commit
3eacc6c4e7
@ -5,6 +5,7 @@
|
|||||||
'require network-modes.api as api';
|
'require network-modes.api as api';
|
||||||
'require network-modes.helpers as helpers';
|
'require network-modes.helpers as helpers';
|
||||||
'require secubox-theme/theme as Theme';
|
'require secubox-theme/theme as Theme';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
||||||
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
||||||
@ -148,7 +149,11 @@ return view.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.bindAccessPointActions(container);
|
this.bindAccessPointActions(container);
|
||||||
return container;
|
|
||||||
|
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||||
|
wrapper.appendChild(SbHeader.render());
|
||||||
|
wrapper.appendChild(container);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
bindAccessPointActions: function(container) {
|
bindAccessPointActions: function(container) {
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
'require network-modes.api as api';
|
'require network-modes.api as api';
|
||||||
'require network-modes.helpers as helpers';
|
'require network-modes.helpers as helpers';
|
||||||
'require secubox-theme/theme as Theme';
|
'require secubox-theme/theme as Theme';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
var lang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
var lang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
||||||
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
||||||
@ -158,7 +159,11 @@ return view.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.bindActions(container);
|
this.bindActions(container);
|
||||||
return container;
|
|
||||||
|
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||||
|
wrapper.appendChild(SbHeader.render());
|
||||||
|
wrapper.appendChild(container);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
bindActions: function(container) {
|
bindActions: function(container) {
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
'require network-modes.api as api';
|
'require network-modes.api as api';
|
||||||
'require network-modes.helpers as helpers';
|
'require network-modes.helpers as helpers';
|
||||||
'require secubox-theme/theme as Theme';
|
'require secubox-theme/theme as Theme';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
||||||
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
||||||
@ -56,7 +57,11 @@ return view.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.bindActions(container);
|
this.bindActions(container);
|
||||||
return container;
|
|
||||||
|
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||||
|
wrapper.appendChild(SbHeader.render());
|
||||||
|
wrapper.appendChild(container);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
renderWanSection: function(wan) {
|
renderWanSection: function(wan) {
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
'require network-modes.api as api';
|
'require network-modes.api as api';
|
||||||
'require network-modes.helpers as helpers';
|
'require network-modes.helpers as helpers';
|
||||||
'require secubox-theme/theme as Theme';
|
'require secubox-theme/theme as Theme';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
||||||
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
||||||
@ -63,7 +64,11 @@ return view.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.bindActions(container);
|
this.bindActions(container);
|
||||||
return container;
|
|
||||||
|
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||||
|
wrapper.appendChild(SbHeader.render());
|
||||||
|
wrapper.appendChild(container);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
renderLinkStatus: function(links, candidates) {
|
renderLinkStatus: function(links, candidates) {
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
'require network-modes.helpers as helpers';
|
'require network-modes.helpers as helpers';
|
||||||
'require secubox/help as Help';
|
'require secubox/help as Help';
|
||||||
'require secubox-theme/theme as Theme';
|
'require secubox-theme/theme as Theme';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
// Initialize global theme respecting LuCI preferences
|
// Initialize global theme respecting LuCI preferences
|
||||||
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
||||||
@ -61,6 +62,10 @@ return view.extend({
|
|||||||
var modesData = (data.modes || {}).modes || [];
|
var modesData = (data.modes || {}).modes || [];
|
||||||
var currentMode = status.current_mode || 'router';
|
var currentMode = status.current_mode || 'router';
|
||||||
|
|
||||||
|
// Main wrapper with SecuBox header
|
||||||
|
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||||
|
wrapper.appendChild(SbHeader.render());
|
||||||
|
|
||||||
// Build a full mode map using backend data + fallbacks
|
// Build a full mode map using backend data + fallbacks
|
||||||
var baseOrder = ['router', 'doublenat', 'multiwan', 'vpnrelay', 'bridge', 'accesspoint', 'relay', 'travel', 'sniffer'];
|
var baseOrder = ['router', 'doublenat', 'multiwan', 'vpnrelay', 'bridge', 'accesspoint', 'relay', 'travel', 'sniffer'];
|
||||||
var modeInfos = {};
|
var modeInfos = {};
|
||||||
@ -361,8 +366,9 @@ return view.extend({
|
|||||||
// Include CSS
|
// Include CSS
|
||||||
var cssLink = E('link', { 'rel': 'stylesheet', 'href': L.resource('network-modes/dashboard.css') });
|
var cssLink = E('link', { 'rel': 'stylesheet', 'href': L.resource('network-modes/dashboard.css') });
|
||||||
document.head.appendChild(cssLink);
|
document.head.appendChild(cssLink);
|
||||||
|
|
||||||
return view;
|
wrapper.appendChild(view);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
renderHeader: function(status, currentModeInfo) {
|
renderHeader: function(status, currentModeInfo) {
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
'require network-modes.api as api';
|
'require network-modes.api as api';
|
||||||
'require network-modes.helpers as helpers';
|
'require network-modes.helpers as helpers';
|
||||||
'require secubox-theme/theme as Theme';
|
'require secubox-theme/theme as Theme';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
||||||
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
||||||
@ -181,7 +182,11 @@ return view.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.bindRelayActions(container);
|
this.bindRelayActions(container);
|
||||||
return container;
|
|
||||||
|
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||||
|
wrapper.appendChild(SbHeader.render());
|
||||||
|
wrapper.appendChild(container);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
bindRelayActions: function(container) {
|
bindRelayActions: function(container) {
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
'require network-modes.api as api';
|
'require network-modes.api as api';
|
||||||
'require network-modes.helpers as helpers';
|
'require network-modes.helpers as helpers';
|
||||||
'require secubox-theme/theme as Theme';
|
'require secubox-theme/theme as Theme';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
||||||
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
||||||
@ -47,6 +48,10 @@ return view.extend({
|
|||||||
var frontendConfig = config.https_frontend || {};
|
var frontendConfig = config.https_frontend || {};
|
||||||
var vhosts = config.virtual_hosts || [];
|
var vhosts = config.virtual_hosts || [];
|
||||||
|
|
||||||
|
// Main wrapper with SecuBox header
|
||||||
|
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||||
|
wrapper.appendChild(SbHeader.render());
|
||||||
|
|
||||||
var heroActions = [
|
var heroActions = [
|
||||||
E('button', { 'class': 'nm-btn nm-btn-primary', 'type': 'button', 'data-action': 'router-save' }, ['💾 ', _('Save & Apply')]),
|
E('button', { 'class': 'nm-btn nm-btn-primary', 'type': 'button', 'data-action': 'router-save' }, ['💾 ', _('Save & Apply')]),
|
||||||
E('button', { 'class': 'nm-btn', 'type': 'button', 'data-action': 'router-config' }, ['📝 ', _('Preview Config')]),
|
E('button', { 'class': 'nm-btn', 'type': 'button', 'data-action': 'router-config' }, ['📝 ', _('Preview Config')]),
|
||||||
@ -261,7 +266,8 @@ return view.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.bindRouterActions(container);
|
this.bindRouterActions(container);
|
||||||
return container;
|
wrapper.appendChild(container);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
bindRouterActions: function(container) {
|
bindRouterActions: function(container) {
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
'require uci';
|
'require uci';
|
||||||
'require network-modes/api as api';
|
'require network-modes/api as api';
|
||||||
'require network-modes.helpers as helpers';
|
'require network-modes.helpers as helpers';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
return view.extend({
|
return view.extend({
|
||||||
load: function() {
|
load: function() {
|
||||||
@ -255,13 +256,18 @@ return view.extend({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return m.render().then(function(formEl) {
|
return m.render().then(function(formEl) {
|
||||||
return E('div', { 'class': 'network-modes-dashboard nm-settings' }, [
|
var container = E('div', { 'class': 'network-modes-dashboard nm-settings' }, [
|
||||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
|
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
|
||||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('network-modes/common.css') }),
|
E('link', { 'rel': 'stylesheet', 'href': L.resource('network-modes/common.css') }),
|
||||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('network-modes/dashboard.css') }),
|
E('link', { 'rel': 'stylesheet', 'href': L.resource('network-modes/dashboard.css') }),
|
||||||
helpers.createNavigationTabs('settings'),
|
helpers.createNavigationTabs('settings'),
|
||||||
formEl
|
formEl
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||||
|
wrapper.appendChild(SbHeader.render());
|
||||||
|
wrapper.appendChild(container);
|
||||||
|
return wrapper;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
'require network-modes.api as api';
|
'require network-modes.api as api';
|
||||||
'require network-modes.helpers as helpers';
|
'require network-modes.helpers as helpers';
|
||||||
'require secubox-theme/theme as Theme';
|
'require secubox-theme/theme as Theme';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
||||||
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
||||||
@ -114,7 +115,11 @@ return view.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.bindSnifferActions(container);
|
this.bindSnifferActions(container);
|
||||||
return container;
|
|
||||||
|
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||||
|
wrapper.appendChild(SbHeader.render());
|
||||||
|
wrapper.appendChild(container);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
bindSnifferActions: function(container) {
|
bindSnifferActions: function(container) {
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
'require network-modes.helpers as helpers';
|
'require network-modes.helpers as helpers';
|
||||||
'require secubox/help as Help';
|
'require secubox/help as Help';
|
||||||
'require secubox-theme/theme as Theme';
|
'require secubox-theme/theme as Theme';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
||||||
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
||||||
@ -136,7 +137,11 @@ return view.extend({
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
this.bindTravelActions(container);
|
this.bindTravelActions(container);
|
||||||
return container;
|
|
||||||
|
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||||
|
wrapper.appendChild(SbHeader.render());
|
||||||
|
wrapper.appendChild(container);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
renderSelectField: function(label, id, options, selected) {
|
renderSelectField: function(label, id, options, selected) {
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
'require network-modes.api as api';
|
'require network-modes.api as api';
|
||||||
'require network-modes.helpers as helpers';
|
'require network-modes.helpers as helpers';
|
||||||
'require secubox-theme/theme as Theme';
|
'require secubox-theme/theme as Theme';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
||||||
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
||||||
@ -55,7 +56,11 @@ return view.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.bindActions(container);
|
this.bindActions(container);
|
||||||
return container;
|
|
||||||
|
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||||
|
wrapper.appendChild(SbHeader.render());
|
||||||
|
wrapper.appendChild(container);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
renderVpnSection: function(vpn, cfg) {
|
renderVpnSection: function(vpn, cfg) {
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
'require network-modes.helpers as helpers';
|
'require network-modes.helpers as helpers';
|
||||||
'require network-modes/api as API';
|
'require network-modes/api as API';
|
||||||
'require secubox-theme/theme as Theme';
|
'require secubox-theme/theme as Theme';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
var callGetAvailableModes = rpc.declare({
|
var callGetAvailableModes = rpc.declare({
|
||||||
object: 'luci.network-modes',
|
object: 'luci.network-modes',
|
||||||
@ -113,7 +114,10 @@ return view.extend({
|
|||||||
this.startRollbackPoll();
|
this.startRollbackPoll();
|
||||||
}
|
}
|
||||||
|
|
||||||
return container;
|
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||||
|
wrapper.appendChild(SbHeader.render());
|
||||||
|
wrapper.appendChild(container);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
renderStatusBadges: function(status, currentMode) {
|
renderStatusBadges: function(status, currentMode) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user