122 lines
4.4 KiB
JavaScript
122 lines
4.4 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';
|
||
|
||
|
||
// Переменная для отслеживания текущего активного хеша (для корректного 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' },
|
||
];
|
||
|
||
// 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: () => '<h1 class="page-title">Системные Настройки</h1><p>Конфигурация сети, пользователя и безопасности.</p>',
|
||
mount: () => {},
|
||
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
|
||
}
|
||
};
|
||
|
||
// 🔥 Убедитесь, что здесь НЕТ слова '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 }; |