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 ui';
|
||||||
'require client-guardian/api as API';
|
'require client-guardian/api as API';
|
||||||
'require client-guardian/nav as CgNav';
|
'require client-guardian/nav as CgNav';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
return view.extend({
|
return view.extend({
|
||||||
load: function() {
|
load: function() {
|
||||||
@ -20,6 +21,10 @@ return view.extend({
|
|||||||
var alerts = data[0];
|
var alerts = data[0];
|
||||||
var logs = data[1].logs || [];
|
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' }, [
|
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('secubox-theme/secubox-theme.css') }),
|
||||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.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) {
|
renderToggle: function(icon, label, desc, enabled) {
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
'require ui';
|
'require ui';
|
||||||
'require rpc';
|
'require rpc';
|
||||||
'require client-guardian/nav as CgNav';
|
'require client-guardian/nav as CgNav';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
var callGetClients = rpc.declare({
|
var callGetClients = rpc.declare({
|
||||||
object: 'luci.client-guardian',
|
object: 'luci.client-guardian',
|
||||||
@ -76,6 +77,10 @@ return view.extend({
|
|||||||
var zones = Array.isArray(data[1]) ? data[1] : (data[1].zones || []);
|
var zones = Array.isArray(data[1]) ? data[1] : (data[1].zones || []);
|
||||||
var self = this;
|
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' }, [
|
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('secubox-theme/secubox-theme.css') }),
|
||||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.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) {
|
renderFilterTab: function(filter, label, count, active) {
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
'require ui';
|
'require ui';
|
||||||
'require client-guardian/api as API';
|
'require client-guardian/api as API';
|
||||||
'require client-guardian/nav as CgNav';
|
'require client-guardian/nav as CgNav';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
return view.extend({
|
return view.extend({
|
||||||
refreshInterval: 5000,
|
refreshInterval: 5000,
|
||||||
@ -17,6 +18,10 @@ return view.extend({
|
|||||||
var logs = data.logs || [];
|
var logs = data.logs || [];
|
||||||
var self = this;
|
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' }, [
|
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('secubox-theme/secubox-theme.css') }),
|
||||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.css') }),
|
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.css') }),
|
||||||
@ -119,7 +124,8 @@ return view.extend({
|
|||||||
// Setup auto-refresh
|
// Setup auto-refresh
|
||||||
poll.add(L.bind(this.pollLogs, this), this.refreshInterval);
|
poll.add(L.bind(this.pollLogs, this), this.refreshInterval);
|
||||||
|
|
||||||
return view;
|
wrapper.appendChild(view);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
renderLogs: function(logs) {
|
renderLogs: function(logs) {
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
'require ui';
|
'require ui';
|
||||||
'require rpc';
|
'require rpc';
|
||||||
'require client-guardian/nav as CgNav';
|
'require client-guardian/nav as CgNav';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
var callGetStatus = rpc.declare({
|
var callGetStatus = rpc.declare({
|
||||||
object: 'luci.client-guardian',
|
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 quarantineClients = clients.filter(function(c) { return c.status === 'unknown' || c.zone === 'quarantine'; });
|
||||||
var bannedClients = clients.filter(function(c) { return c.status === 'banned'; });
|
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' }, [
|
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('secubox-theme/secubox-theme.css') }),
|
||||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.css') }),
|
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.css') }),
|
||||||
@ -150,7 +155,8 @@ return view.extend({
|
|||||||
}, this), refreshInterval);
|
}, this), refreshInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
return view;
|
wrapper.appendChild(view);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
renderStatCard: function(icon, value, label) {
|
renderStatCard: function(icon, value, label) {
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
'require ui';
|
'require ui';
|
||||||
'require rpc';
|
'require rpc';
|
||||||
'require client-guardian/nav as CgNav';
|
'require client-guardian/nav as CgNav';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
var callGetParental = rpc.declare({
|
var callGetParental = rpc.declare({
|
||||||
object: 'luci.client-guardian',
|
object: 'luci.client-guardian',
|
||||||
@ -20,7 +21,11 @@ return view.extend({
|
|||||||
var filters = data.filters || [];
|
var filters = data.filters || [];
|
||||||
var urlLists = data.url_lists || [];
|
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('secubox-theme/secubox-theme.css') }),
|
||||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.css') }),
|
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.css') }),
|
||||||
CgNav.renderTabs('parental'),
|
CgNav.renderTabs('parental'),
|
||||||
@ -246,6 +251,9 @@ return view.extend({
|
|||||||
])
|
])
|
||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
wrapper.appendChild(view);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
renderScheduleDay: function(name, active) {
|
renderScheduleDay: function(name, active) {
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
'require uci';
|
'require uci';
|
||||||
'require client-guardian/api as API';
|
'require client-guardian/api as API';
|
||||||
'require client-guardian/nav as CgNav';
|
'require client-guardian/nav as CgNav';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
return view.extend({
|
return view.extend({
|
||||||
load: function() {
|
load: function() {
|
||||||
@ -222,12 +223,19 @@ return view.extend({
|
|||||||
|
|
||||||
rendered.insertBefore(infoBox, rendered.firstChild);
|
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('secubox-theme/secubox-theme.css') }),
|
||||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.css') }),
|
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.css') }),
|
||||||
CgNav.renderTabs('settings'),
|
CgNav.renderTabs('settings'),
|
||||||
rendered
|
rendered
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
wrapper.appendChild(view);
|
||||||
|
return wrapper;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
'require ui';
|
'require ui';
|
||||||
'require rpc';
|
'require rpc';
|
||||||
'require client-guardian/nav as CgNav';
|
'require client-guardian/nav as CgNav';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
var callGetZones = rpc.declare({
|
var callGetZones = rpc.declare({
|
||||||
object: 'luci.client-guardian',
|
object: 'luci.client-guardian',
|
||||||
@ -31,7 +32,11 @@ return view.extend({
|
|||||||
var zones = Array.isArray(data) ? data : (data.zones || []);
|
var zones = Array.isArray(data) ? data : (data.zones || []);
|
||||||
var self = this;
|
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('secubox-theme/secubox-theme.css') }),
|
||||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.css') }),
|
E('link', { 'rel': 'stylesheet', 'href': L.resource('client-guardian/dashboard.css') }),
|
||||||
CgNav.renderTabs('zones'),
|
CgNav.renderTabs('zones'),
|
||||||
@ -59,6 +64,9 @@ return view.extend({
|
|||||||
zones.map(L.bind(this.renderZoneCard, this))
|
zones.map(L.bind(this.renderZoneCard, this))
|
||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
wrapper.appendChild(view);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
renderZoneCard: function(zone) {
|
renderZoneCard: function(zone) {
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
'require poll';
|
'require poll';
|
||||||
'require ui';
|
'require ui';
|
||||||
'require media-flow/api as API';
|
'require media-flow/api as API';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
return view.extend({
|
return view.extend({
|
||||||
title: _('Media Flow Dashboard'),
|
title: _('Media Flow Dashboard'),
|
||||||
@ -36,6 +37,10 @@ return view.extend({
|
|||||||
var streams = streamsData.streams || [];
|
var streams = streamsData.streams || [];
|
||||||
var flowCount = streamsData.flow_count || status.active_flows || 0;
|
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
|
// Inject CSS
|
||||||
var css = `
|
var css = `
|
||||||
.mf-dashboard { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; color: #e4e4e7; }
|
.mf-dashboard { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; color: #e4e4e7; }
|
||||||
@ -241,7 +246,8 @@ return view.extend({
|
|||||||
}, this));
|
}, this));
|
||||||
}, this), this.pollInterval);
|
}, this), this.pollInterval);
|
||||||
|
|
||||||
return view;
|
wrapper.appendChild(view);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSaveApply: null,
|
handleSaveApply: null,
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
'require poll';
|
'require poll';
|
||||||
'require netdata-dashboard/api as API';
|
'require netdata-dashboard/api as API';
|
||||||
'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')) ||
|
||||||
@ -33,6 +34,10 @@ return view.extend({
|
|||||||
var netdataUrl = 'http://' + window.location.hostname + ':' + netdataPort;
|
var netdataUrl = 'http://' + window.location.hostname + ':' + netdataPort;
|
||||||
var alarmCount = this.countAlarms(alarms);
|
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' }, [
|
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('secubox-theme/secubox-theme.css') }),
|
||||||
E('link', { 'rel': 'stylesheet', 'href': L.resource('netdata-dashboard/dashboard.css') }),
|
E('link', { 'rel': 'stylesheet', 'href': L.resource('netdata-dashboard/dashboard.css') }),
|
||||||
@ -55,7 +60,8 @@ return view.extend({
|
|||||||
}, this));
|
}, this));
|
||||||
}, this), 5);
|
}, this), 5);
|
||||||
|
|
||||||
return view;
|
wrapper.appendChild(view);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
countAlarms: function(alarms) {
|
countAlarms: function(alarms) {
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
'require secubox-theme/theme as Theme';
|
'require secubox-theme/theme as Theme';
|
||||||
'require ui';
|
'require ui';
|
||||||
'require netdata-dashboard/api as API';
|
'require netdata-dashboard/api as API';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
return view.extend({
|
return view.extend({
|
||||||
load: function() {
|
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 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;';
|
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' }, [
|
var view = E('div', { 'class': 'cbi-map' }, [
|
||||||
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('h2', {}, _('Netdata Settings')),
|
E('h2', {}, _('Netdata Settings')),
|
||||||
@ -227,7 +232,8 @@ return view.extend({
|
|||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return view;
|
wrapper.appendChild(view);
|
||||||
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSaveApply: null,
|
handleSaveApply: null,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user