secubox-openwrt/luci-app-network-modes/htdocs/luci-static/resources/view/network-modes/accesspoint.js
CyberMind-FR de40c8e533 feat: Release v0.4.3 - Dual menu access and enhanced permissions
This release adds dual menu access for Network Modes (both SecuBox and
LuCI Network menus) and significantly expands RPCD permissions for all
mode configuration operations.

## Network Modes - Dual Menu Access (2 files)
- Added Network Modes to standard LuCI Network menu (admin/network/modes)
- Maintains existing SecuBox menu location (admin/secubox/network/modes)
- Users can now access Network Modes from both locations
- Menu order: 60 in Network menu, 10 in SecuBox Network category

## Network Modes - Enhanced Permissions (1 file)
Added 13+ new RPCD methods to ACL for complete mode management:

Read permissions:
- preview_changes
- sniffer_config, ap_config, relay_config, router_config
- travel_config, doublenat_config, multiwan_config, vpnrelay_config
- travel_scan_networks

Write permissions:
- apply_mode, confirm_mode, rollback
- update_settings
- generate_wireguard_keys, apply_wireguard_config
- apply_mtu_clamping, enable_tcp_bbr
- add_vhost, generate_config

## Network Modes - View Updates (11 files)
Updated all mode views for consistency:
- helpers.js: 28 lines refactored
- overview.js: Enhanced view structure
- All mode views: wizard, router, multiwan, doublenat, accesspoint,
  relay, vpnrelay, travel, sniffer

## Theme Enhancements (1 file)
- theme.js: 89 lines added
- Enhanced theme initialization and configuration
- Improved component styling support

## SecuBox Dashboard (2 files)
- Updated dashboard.js and modules.js
- Improved view rendering and integration

## System Hub (3 files)
- Enhanced logs.js, overview.js, services.js
- Better view consistency and functionality

Summary:
- 19 files changed (+282, -36)
- Dual menu access for Network Modes
- 13+ new RPCD permission methods
- All network mode views updated
- Theme significantly enhanced

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-28 19:24:40 +01:00

193 lines
7.7 KiB
JavaScript

'use strict';
'require view';
'require dom';
'require ui';
'require network-modes.api as api';
'require network-modes.helpers as helpers';
'require secubox-theme/theme as Theme';
var nmLang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
(document.documentElement && document.documentElement.getAttribute('lang')) ||
(navigator.language ? navigator.language.split('-')[0] : 'en');
Theme.init({ language: nmLang });
function buildWifiToggle(flag, label, desc, active) {
return E('div', { 'class': 'nm-toggle' }, [
E('div', { 'class': 'nm-toggle-info' }, [
E('span', { 'class': 'nm-toggle-icon' }, '⚙️'),
E('div', {}, [
E('div', { 'class': 'nm-toggle-label' }, label),
E('div', { 'class': 'nm-toggle-desc' }, desc)
])
]),
E('div', {
'class': 'nm-toggle-switch' + (active ? ' active' : ''),
'data-setting': flag
})
]);
}
return view.extend({
title: _('Access Point Mode'),
load: function() {
return api.getApConfig();
},
render: function(data) {
var config = data || {};
var wifiTweaks = config.wifi_tweaks || {};
var hero = helpers.createHero({
icon: '📡',
title: _('Access Point Mode'),
subtitle: _('Dedicated WiFi uplink bridge with roaming optimizations, band steering, and 802.11r/k/v enhancements.'),
gradient: 'linear-gradient(135deg,#0ea5e9,#06b6d4)',
actions: [
E('button', { 'class': 'nm-btn nm-btn-primary', 'type': 'button', 'data-action': 'ap-save' }, ['💾 ', _('Save & Apply')]),
E('button', { 'class': 'nm-btn', 'type': 'button', 'data-action': 'ap-config' }, ['📝 ', _('Preview Config')])
]
});
var stats = E('div', { 'style': 'display:flex;flex-wrap:wrap;gap:12px;margin-bottom:24px;' }, [
helpers.createStatBadge({ label: _('Channel'), value: config.wifi_channel || 'AUTO' }),
helpers.createStatBadge({ label: _('Width'), value: config.wifi_htmode || 'VHT80' }),
helpers.createStatBadge({ label: _('TX Power'), value: (config.wifi_txpower || 20) + ' dBm' }),
helpers.createStatBadge({ label: _('PHY'), value: (config.wifi_phy || 'phy0').toUpperCase() })
]);
var radioSection = helpers.createSection({
title: _('Radio Parameters'),
icon: '📶',
badge: (config.wifi_driver || 'mac80211').toUpperCase(),
body: [
E('div', { 'class': 'nm-form-grid' }, [
E('div', { 'class': 'nm-form-group' }, [
E('label', { 'class': 'nm-form-label' }, _('WiFi Channel')),
E('select', { 'class': 'nm-select', 'id': 'wifi-channel' }, [
E('option', { 'value': 'auto', 'selected': config.wifi_channel === 'auto' }, _('Auto')),
E('optgroup', { 'label': _('2.4 GHz') },
(config.available_channels_2g || [1, 6, 11]).map(function(ch) {
return E('option', { 'value': ch, 'selected': Number(ch) === Number(config.wifi_channel) }, _('Channel ') + ch);
})
),
E('optgroup', { 'label': _('5 GHz') },
(config.available_channels_5g || [36, 40, 44, 48]).map(function(ch) {
return E('option', { 'value': ch, 'selected': Number(ch) === Number(config.wifi_channel) }, _('Channel ') + ch);
})
)
])
]),
E('div', { 'class': 'nm-form-group' }, [
E('label', { 'class': 'nm-form-label' }, _('Channel Width (HT mode)')),
E('select', { 'class': 'nm-select', 'id': 'wifi-htmode' },
(config.available_htmodes || ['HT20', 'HT40', 'VHT40', 'VHT80']).map(function(mode) {
return E('option', { 'value': mode, 'selected': mode === config.wifi_htmode }, mode);
})
)
])
]),
E('div', { 'class': 'nm-slider-container' }, [
E('div', { 'class': 'nm-slider-header' }, [
E('span', { 'class': 'nm-slider-label' }, _('Transmit Power')),
E('span', { 'class': 'nm-slider-value', 'id': 'txpower-value' }, (config.wifi_txpower || 20) + ' dBm')
]),
E('input', {
'type': 'range',
'class': 'nm-slider',
'id': 'wifi-txpower',
'min': '1',
'max': '30',
'value': config.wifi_txpower || 20
})
])
]
});
var optimSection = helpers.createSection({
title: _('Roaming & Optimizations'),
icon: '🚀',
body: [
buildWifiToggle('roaming_80211r', _('802.11r Fast BSS Transition'), _('Seamless roaming between APs'), wifiTweaks.roaming_80211r),
buildWifiToggle('rrm_80211k', _('802.11k Radio Resource'), _('Neighbor reports for smart handovers'), wifiTweaks.rrm_80211k),
buildWifiToggle('wnm_80211v', _('802.11v BSS Transition'), _('AP-assisted steering & WNM sleep'), wifiTweaks.wnm_80211v),
buildWifiToggle('band_steering', _('Band Steering'), _('Prefer 5 GHz when possible'), wifiTweaks.band_steering),
buildWifiToggle('airtime_fairness', _('Airtime Fairness'), _('Equal airtime for all clients'), wifiTweaks.airtime_fairness),
buildWifiToggle('beamforming', _('Beamforming'), _('Directional signal shaping'), wifiTweaks.beamforming !== false)
]
});
var bridgeSection = helpers.createSection({
title: _('Bridging & Uplink'),
icon: '🌉',
body: [
helpers.createList([
{ title: _('Bridge LAN to upstream'), description: _('LAN + uplink ports merged in br-lan'), suffix: E('span', { 'class': 'nm-badge' }, 'L2 Bridge') },
{ title: _('Disable NAT & DHCP'), description: _('Delegated gateway handles routing & IP leases'), suffix: E('span', { 'class': 'nm-badge' }, 'Policy') },
{ title: _('Multicast optimizations'), description: _('IGMP/MLD snooping for IPTV/AP isolation'), suffix: E('span', { 'class': 'nm-badge' }, 'Optimized') }
])
]
});
var container = E('div', { 'class': 'network-modes-dashboard accesspoint-mode' }, [
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
E('link', { 'rel': 'stylesheet', 'href': L.resource('network-modes/dashboard.css') }),
helpers.createNavigationTabs('accesspoint'),
hero,
stats,
radioSection,
optimSection,
bridgeSection
]);
container.querySelectorAll('.nm-toggle-switch').forEach(function(toggle) {
toggle.addEventListener('click', function() {
this.classList.toggle('active');
});
});
this.bindAccessPointActions(container);
return container;
},
bindAccessPointActions: function(container) {
var slider = container.querySelector('#wifi-txpower');
var valueDisplay = container.querySelector('#txpower-value');
if (slider && valueDisplay) {
slider.addEventListener('input', function() {
valueDisplay.textContent = this.value + ' dBm';
});
}
var saveBtn = container.querySelector('[data-action="ap-save"]');
var configBtn = container.querySelector('[data-action="ap-config"]');
if (saveBtn)
saveBtn.addEventListener('click', ui.createHandlerFn(this, 'saveAccessPointSettings', container));
if (configBtn)
configBtn.addEventListener('click', ui.createHandlerFn(helpers, helpers.showGeneratedConfig, 'accesspoint'));
},
saveAccessPointSettings: function(container) {
var toggles = {};
container.querySelectorAll('.nm-toggle-switch[data-setting]').forEach(function(toggle) {
var key = toggle.getAttribute('data-setting');
toggles[key] = helpers.isToggleActive(toggle);
});
var payload = {
wifi_channel: container.querySelector('#wifi-channel') ? container.querySelector('#wifi-channel').value : 'auto',
wifi_htmode: container.querySelector('#wifi-htmode') ? container.querySelector('#wifi-htmode').value : 'VHT80',
wifi_txpower: container.querySelector('#wifi-txpower') ? parseInt(container.querySelector('#wifi-txpower').value, 10) : 20,
roaming_enabled: toggles.roaming_80211r ? 1 : 0,
band_steering: toggles.band_steering ? 1 : 0,
rrm_enabled: toggles.rrm_80211k ? 1 : 0,
wnm_enabled: toggles.wnm_80211v ? 1 : 0,
airtime_fairness: toggles.airtime_fairness ? 1 : 0,
beamforming: toggles.beamforming ? 1 : 0
};
return helpers.persistSettings('accesspoint', payload);
}
});