186 lines
6.9 KiB
JavaScript
186 lines
6.9 KiB
JavaScript
// src/modules/router.js
|
||
|
||
import $ from 'jquery';
|
||
import { StatisticsPage } from '../pages/Statistics.js';
|
||
import { Subscriptions } from '../pages/Subscriptions.js';
|
||
import { Components } from '../pages/Components.js';
|
||
import { APITokens } from '../pages/APITokens.js';
|
||
import { getEnabledComponents } from './app.js';
|
||
import { OVPNConfig } from '../pages/OVPN.js';
|
||
import { TDNSConfig } from '../pages/TDNS.js';
|
||
import { FRRConfig } from '../pages/FRR.js';
|
||
import { ROSConfig } from '../pages/ROS.js';
|
||
import { DNSMASQConfig } from '../pages/DNSMASQ.js';
|
||
import { SRMPage } from '../pages/SRM.js';
|
||
import { SettingsPage } from '../pages/Settings.js';
|
||
import { LogsPage } from '../pages/Logs.js';
|
||
import { NetworkResourcesPage } from '../pages/NetworkResources.js';
|
||
import { UnlockSitePage } from '../pages/UnlockSite.js';
|
||
import { LocalStoragesPage } from '../pages/LocalStorages.js';
|
||
|
||
|
||
// Переменная для отслеживания текущего активного хеша (для корректного unmount)
|
||
let currentRouteHash = '';
|
||
|
||
|
||
// 1. Определение ВСЕХ возможных пунктов меню
|
||
const allMenuItems = [
|
||
{ label: 'Статистика', path: 'stats', component: null },
|
||
{ label: 'Подписки', path: 'subscriptions', component: null },
|
||
{ label: 'Настройки', path: 'settings', component: null },
|
||
{ label: 'Компоненты', path: 'components', component: null },
|
||
{ label: 'API', path: 'api', component: null },
|
||
{ label: 'Настройка OVPN', path: 'ovpn', component: 'ru.kirillius.pf.sdn.External.API.Components.OVPN' },
|
||
{ label: 'Настройка TDNS', path: 'tdns', component: 'ru.kirillius.pf.sdn.External.API.Components.TDNS' },
|
||
{ label: 'Настройка FRR', path: 'frr', component: 'ru.kirillius.pf.sdn.External.API.Components.FRR' },
|
||
{ label: 'Настройка ROS', path: 'ros', component: 'ru.kirillius.pf.sdn.External.API.Components.ROS' },
|
||
{ label: 'Настройка DNSMASQ', path: 'dnsmasq', component: 'ru.kirillius.pf.sdn.External.API.Components.DNSMASQ' },
|
||
{ label: 'SRM', path: 'srm', component: 'ru.kirillius.pf.sdn.External.API.Components.SRM' },
|
||
{ label: 'Журнал', path: 'logs', component: null },
|
||
{ label: 'Сетевые ресурсы', path: 'network-resources', component: null },
|
||
{ label: 'Разблокировка сайта', path: 'unlock-site', component: null },
|
||
{ label: 'Локальные хранилища', path: 'local-storages', component: null },
|
||
];
|
||
|
||
// 2. Определение страниц
|
||
const routes = {
|
||
'#stats': {
|
||
render: StatisticsPage.render,
|
||
mount: StatisticsPage.mount,
|
||
unmount: StatisticsPage.unmount
|
||
},
|
||
'#subscriptions': {
|
||
render: Subscriptions.render,
|
||
mount: Subscriptions.mount,
|
||
unmount: Subscriptions.unmount
|
||
},
|
||
'#settings': {
|
||
render: SettingsPage.render,
|
||
mount: SettingsPage.mount,
|
||
unmount: SettingsPage.unmount
|
||
},
|
||
'#components': {
|
||
render: Components.render,
|
||
mount: Components.mount,
|
||
unmount: Components.unmount
|
||
},
|
||
'#api': {
|
||
render: APITokens.render,
|
||
mount: APITokens.mount,
|
||
unmount: APITokens.unmount
|
||
},
|
||
'#ovpn': {
|
||
render: OVPNConfig.render,
|
||
mount: OVPNConfig.mount,
|
||
unmount: OVPNConfig.unmount
|
||
},
|
||
'#tdns': {
|
||
render: TDNSConfig.render,
|
||
mount: TDNSConfig.mount,
|
||
unmount: TDNSConfig.unmount
|
||
},
|
||
'#frr': {
|
||
render: FRRConfig.render,
|
||
mount: FRRConfig.mount,
|
||
unmount: FRRConfig.unmount
|
||
},
|
||
'#ros': {
|
||
render: ROSConfig.render,
|
||
mount: ROSConfig.mount,
|
||
unmount: ROSConfig.unmount
|
||
},
|
||
'#dnsmasq': {
|
||
render: DNSMASQConfig.render,
|
||
mount: DNSMASQConfig.mount,
|
||
unmount: DNSMASQConfig.unmount
|
||
},
|
||
'#srm': {
|
||
render: SRMPage.render,
|
||
mount: SRMPage.mount,
|
||
unmount: SRMPage.unmount
|
||
},
|
||
'#logs': {
|
||
render: LogsPage.render,
|
||
mount: LogsPage.mount,
|
||
unmount: LogsPage.unmount
|
||
},
|
||
'#network-resources': {
|
||
render: NetworkResourcesPage.render,
|
||
mount: NetworkResourcesPage.mount,
|
||
unmount: NetworkResourcesPage.unmount
|
||
},
|
||
'#unlock-site': {
|
||
render: UnlockSitePage.render,
|
||
mount: UnlockSitePage.mount,
|
||
unmount: UnlockSitePage.unmount
|
||
},
|
||
'#local-storages': {
|
||
render: LocalStoragesPage.render,
|
||
mount: LocalStoragesPage.mount,
|
||
unmount: LocalStoragesPage.unmount
|
||
}
|
||
};
|
||
|
||
// 🔥 Убедитесь, что здесь НЕТ слова 'export'
|
||
function getFilteredMenuItems() {
|
||
const enabled = getEnabledComponents();
|
||
|
||
return allMenuItems.filter(item => {
|
||
if (item.component === null) {
|
||
return true;
|
||
}
|
||
return enabled.includes(item.component);
|
||
});
|
||
}
|
||
|
||
// 3. Функция рендеринга страницы (без изменений)
|
||
export function renderPage(hash) {
|
||
const $contentArea = $('#content-area');
|
||
const key = hash.startsWith('#') ? hash : '#' + hash;
|
||
|
||
// Если страница уже открыта, просто обновляем меню и выходим
|
||
if (currentRouteHash === key) {
|
||
$('.menu-item').removeClass('active');
|
||
$(`.menu-item[data-path="${key.substring(1)}"]`).addClass('active');
|
||
return;
|
||
}
|
||
|
||
const previousKey = currentRouteHash || '#stats';
|
||
|
||
// Шаг 1: Если мы меняем страницу, и предыдущая страница имеет unmount, вызываем его
|
||
if (previousKey !== key && routes[previousKey] && routes[previousKey].unmount) {
|
||
routes[previousKey].unmount();
|
||
}
|
||
|
||
if (routes[key]) {
|
||
// Рендерим HTML
|
||
$contentArea.html(routes[key].render());
|
||
|
||
// Вызываем функцию монтирования
|
||
routes[key].mount();
|
||
|
||
// Обновляем активный пункт меню
|
||
$('.menu-item').removeClass('active');
|
||
$(`.menu-item[data-path="${key.substring(1)}"]`).addClass('active');
|
||
|
||
// Обновляем hash в адресной строке
|
||
if (window.location.hash !== key) {
|
||
history.pushState(null, null, key);
|
||
}
|
||
|
||
// Шаг 2: Успешно обновили страницу, сохраняем новый хеш
|
||
currentRouteHash = key;
|
||
|
||
} else {
|
||
// Если путь не найден, перенаправляем на "Статистику"
|
||
window.location.hash = 'stats';
|
||
}
|
||
}
|
||
|
||
// 4. Обработчик изменения хеша в браузере (для навигации по истории)
|
||
$(window).on('hashchange', function() {
|
||
renderPage(window.location.hash);
|
||
});
|
||
|
||
// 🔥 Оставляем ТОЛЬКО ОДИН экспорт в конце файла
|
||
export { getFilteredMenuItems }; |