feat: Add SecuBox portal header to Client Guardian, Media Flow, and Netdata views
Adds the unified SecuBox portal header navigation to: - Client Guardian: overview, clients, zones, logs, alerts, parental, settings - Media Flow: dashboard - Netdata Dashboard: dashboard, settings This hides the LuCI sidebar and provides consistent SecuBox navigation across all dashboards when accessed from the SecuBox Portal. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
56ec6f4483
commit
7df952c2a7
@ -7,6 +7,7 @@
|
||||
'require ui';
|
||||
'require client-guardian/api as API';
|
||||
'require client-guardian/nav as CgNav';
|
||||
'require secubox-portal/header as SbHeader';
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
@ -20,6 +21,10 @@ return view.extend({
|
||||
var alerts = data[0];
|
||||
var logs = data[1].logs || [];
|
||||
|
||||
// Main wrapper with SecuBox header
|
||||
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||
wrapper.appendChild(SbHeader.render());
|
||||
|
||||
var view = E('div', { 'class': 'client-guardian-dashboard' }, [
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.css') }),
|
||||
@ -164,7 +169,8 @@ return view.extend({
|
||||
])
|
||||
]);
|
||||
|
||||
return view;
|
||||
wrapper.appendChild(view);
|
||||
return wrapper;
|
||||
},
|
||||
|
||||
renderToggle: function(icon, label, desc, enabled) {
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
'require ui';
|
||||
'require rpc';
|
||||
'require client-guardian/nav as CgNav';
|
||||
'require secubox-portal/header as SbHeader';
|
||||
|
||||
var callGetClients = rpc.declare({
|
||||
object: 'luci.client-guardian',
|
||||
@ -76,6 +77,10 @@ return view.extend({
|
||||
var zones = Array.isArray(data[1]) ? data[1] : (data[1].zones || []);
|
||||
var self = this;
|
||||
|
||||
// Main wrapper with SecuBox header
|
||||
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||
wrapper.appendChild(SbHeader.render());
|
||||
|
||||
var view = E('div', { 'class': 'client-guardian-dashboard' }, [
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.css') }),
|
||||
@ -121,7 +126,8 @@ return view.extend({
|
||||
])
|
||||
]);
|
||||
|
||||
return view;
|
||||
wrapper.appendChild(view);
|
||||
return wrapper;
|
||||
},
|
||||
|
||||
renderFilterTab: function(filter, label, count, active) {
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
'require ui';
|
||||
'require client-guardian/api as API';
|
||||
'require client-guardian/nav as CgNav';
|
||||
'require secubox-portal/header as SbHeader';
|
||||
|
||||
return view.extend({
|
||||
refreshInterval: 5000,
|
||||
@ -17,6 +18,10 @@ return view.extend({
|
||||
var logs = data.logs || [];
|
||||
var self = this;
|
||||
|
||||
// Main wrapper with SecuBox header
|
||||
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||
wrapper.appendChild(SbHeader.render());
|
||||
|
||||
var view = E('div', { 'class': 'client-guardian-dashboard' }, [
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.css') }),
|
||||
@ -119,7 +124,8 @@ return view.extend({
|
||||
// Setup auto-refresh
|
||||
poll.add(L.bind(this.pollLogs, this), this.refreshInterval);
|
||||
|
||||
return view;
|
||||
wrapper.appendChild(view);
|
||||
return wrapper;
|
||||
},
|
||||
|
||||
renderLogs: function(logs) {
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
'require ui';
|
||||
'require rpc';
|
||||
'require client-guardian/nav as CgNav';
|
||||
'require secubox-portal/header as SbHeader';
|
||||
|
||||
var callGetStatus = rpc.declare({
|
||||
object: 'luci.client-guardian',
|
||||
@ -77,6 +78,10 @@ return view.extend({
|
||||
var quarantineClients = clients.filter(function(c) { return c.status === 'unknown' || c.zone === 'quarantine'; });
|
||||
var bannedClients = clients.filter(function(c) { return c.status === 'banned'; });
|
||||
|
||||
// Main wrapper with SecuBox header
|
||||
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||
wrapper.appendChild(SbHeader.render());
|
||||
|
||||
var view = E('div', { 'class': 'client-guardian-dashboard' }, [
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.css') }),
|
||||
@ -150,7 +155,8 @@ return view.extend({
|
||||
}, this), refreshInterval);
|
||||
}
|
||||
|
||||
return view;
|
||||
wrapper.appendChild(view);
|
||||
return wrapper;
|
||||
},
|
||||
|
||||
renderStatCard: function(icon, value, label) {
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
'require ui';
|
||||
'require rpc';
|
||||
'require client-guardian/nav as CgNav';
|
||||
'require secubox-portal/header as SbHeader';
|
||||
|
||||
var callGetParental = rpc.declare({
|
||||
object: 'luci.client-guardian',
|
||||
@ -20,7 +21,11 @@ return view.extend({
|
||||
var filters = data.filters || [];
|
||||
var urlLists = data.url_lists || [];
|
||||
|
||||
return E('div', { 'class': 'client-guardian-dashboard' }, [
|
||||
// Main wrapper with SecuBox header
|
||||
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||
wrapper.appendChild(SbHeader.render());
|
||||
|
||||
var view = E('div', { 'class': 'client-guardian-dashboard' }, [
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.css') }),
|
||||
CgNav.renderTabs('parental'),
|
||||
@ -246,6 +251,9 @@ return view.extend({
|
||||
])
|
||||
])
|
||||
]);
|
||||
|
||||
wrapper.appendChild(view);
|
||||
return wrapper;
|
||||
},
|
||||
|
||||
renderScheduleDay: function(name, active) {
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
'require uci';
|
||||
'require client-guardian/api as API';
|
||||
'require client-guardian/nav as CgNav';
|
||||
'require secubox-portal/header as SbHeader';
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
@ -222,12 +223,19 @@ return view.extend({
|
||||
|
||||
rendered.insertBefore(infoBox, rendered.firstChild);
|
||||
|
||||
return E('div', { 'class': 'client-guardian-dashboard' }, [
|
||||
// Main wrapper with SecuBox header
|
||||
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||
wrapper.appendChild(SbHeader.render());
|
||||
|
||||
var view = E('div', { 'class': 'client-guardian-dashboard' }, [
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.css') }),
|
||||
CgNav.renderTabs('settings'),
|
||||
rendered
|
||||
]);
|
||||
|
||||
wrapper.appendChild(view);
|
||||
return wrapper;
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
'require ui';
|
||||
'require rpc';
|
||||
'require client-guardian/nav as CgNav';
|
||||
'require secubox-portal/header as SbHeader';
|
||||
|
||||
var callGetZones = rpc.declare({
|
||||
object: 'luci.client-guardian',
|
||||
@ -31,7 +32,11 @@ return view.extend({
|
||||
var zones = Array.isArray(data) ? data : (data.zones || []);
|
||||
var self = this;
|
||||
|
||||
return E('div', { 'class': 'client-guardian-dashboard' }, [
|
||||
// Main wrapper with SecuBox header
|
||||
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||
wrapper.appendChild(SbHeader.render());
|
||||
|
||||
var view = E('div', { 'class': 'client-guardian-dashboard' }, [
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.css') }),
|
||||
CgNav.renderTabs('zones'),
|
||||
@ -59,6 +64,9 @@ return view.extend({
|
||||
zones.map(L.bind(this.renderZoneCard, this))
|
||||
)
|
||||
]);
|
||||
|
||||
wrapper.appendChild(view);
|
||||
return wrapper;
|
||||
},
|
||||
|
||||
renderZoneCard: function(zone) {
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
'require poll';
|
||||
'require ui';
|
||||
'require media-flow/api as API';
|
||||
'require secubox-portal/header as SbHeader';
|
||||
|
||||
return view.extend({
|
||||
title: _('Media Flow Dashboard'),
|
||||
@ -36,6 +37,10 @@ return view.extend({
|
||||
var streams = streamsData.streams || [];
|
||||
var flowCount = streamsData.flow_count || status.active_flows || 0;
|
||||
|
||||
// Main wrapper with SecuBox header
|
||||
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||
wrapper.appendChild(SbHeader.render());
|
||||
|
||||
// Inject CSS
|
||||
var css = `
|
||||
.mf-dashboard { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; color: #e4e4e7; }
|
||||
@ -241,7 +246,8 @@ return view.extend({
|
||||
}, this));
|
||||
}, this), this.pollInterval);
|
||||
|
||||
return view;
|
||||
wrapper.appendChild(view);
|
||||
return wrapper;
|
||||
},
|
||||
|
||||
handleSaveApply: null,
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
'require poll';
|
||||
'require netdata-dashboard/api as API';
|
||||
'require secubox-theme/theme as Theme';
|
||||
'require secubox-portal/header as SbHeader';
|
||||
|
||||
var lang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
||||
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
||||
@ -33,6 +34,10 @@ return view.extend({
|
||||
var netdataUrl = 'http://' + window.location.hostname + ':' + netdataPort;
|
||||
var alarmCount = this.countAlarms(alarms);
|
||||
|
||||
// Main wrapper with SecuBox header
|
||||
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||
wrapper.appendChild(SbHeader.render());
|
||||
|
||||
var view = E('div', { 'class': 'netdata-dashboard secubox-netdata' }, [
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('netdata-dashboard/dashboard.css') }),
|
||||
@ -55,7 +60,8 @@ return view.extend({
|
||||
}, this));
|
||||
}, this), 5);
|
||||
|
||||
return view;
|
||||
wrapper.appendChild(view);
|
||||
return wrapper;
|
||||
},
|
||||
|
||||
countAlarms: function(alarms) {
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
'require secubox-theme/theme as Theme';
|
||||
'require ui';
|
||||
'require netdata-dashboard/api as API';
|
||||
'require secubox-portal/header as SbHeader';
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
@ -27,6 +28,10 @@ return view.extend({
|
||||
var thStyle = 'padding: 0.75rem 1rem; text-align: left; font-weight: 600; width: 200px; background: #161b22; border-bottom: 1px solid #30363d;';
|
||||
var tdStyle = 'padding: 0.75rem 1rem; border-bottom: 1px solid #30363d;';
|
||||
|
||||
// Main wrapper with SecuBox header
|
||||
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||
wrapper.appendChild(SbHeader.render());
|
||||
|
||||
var view = E('div', { 'class': 'cbi-map' }, [
|
||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
|
||||
E('h2', {}, _('Netdata Settings')),
|
||||
@ -227,7 +232,8 @@ return view.extend({
|
||||
])
|
||||
]);
|
||||
|
||||
return view;
|
||||
wrapper.appendChild(view);
|
||||
return wrapper;
|
||||
},
|
||||
|
||||
handleSaveApply: null,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user