Files
gree-controller/web/js/router.js
T
2026-09-01 15:38:46 +02:00

97 lines
4.0 KiB
JavaScript

const VIEW_ROUTES = Object.freeze({
dashboard: '/dashboard',
devices: '/devices',
zones: '/zones',
groups: '/groups',
schedules: '/schedules',
automations: '/automations',
simulation: '/simulation',
night: '/night-mode',
homeassistant: '/home-assistant',
settings: '/settings',
logs: '/events',
});
const ROUTE_VIEWS = Object.freeze(Object.fromEntries(Object.entries(VIEW_ROUTES).map(([view, path]) => [path, view])));
const HISTORY_TABS = Object.freeze(['overview', 'zones', 'devices', 'sensors', 'custom']);
let routerInitialized = false;
function currentHistoryPath() {
const tab = HISTORY_TABS.includes(app.historyTab) ? app.historyTab : 'overview';
const params = new URLSearchParams();
const hours = $('#historyHours')?.value || new URLSearchParams(location.search).get('hours') || '24';
if (hours !== '24') params.set('hours', hours);
if (tab === 'zones' && app.historyZone !== 'all') params.set('zone', app.historyZone);
if (tab === 'devices' && app.historyDevice !== 'all') params.set('device', app.historyDevice);
if (tab === 'sensors' && app.historySensor !== 'all') params.set('sensor', app.historySensor);
if (tab === 'custom' && app.customChartSeries.length) params.set('chart', encodeChartSpec(app.customChartSeries));
const query = params.toString();
return `/history/${tab}${query ? `?${query}` : ''}`;
}
function pathForView(name) {
return name === 'history' ? currentHistoryPath() : (VIEW_ROUTES[name] || VIEW_ROUTES.dashboard);
}
function appRelativePath(pathname = location.pathname) {
if (!APP_BASE) return pathname || '/';
if (pathname === APP_BASE) return '/';
if (pathname.startsWith(`${APP_BASE}/`)) return pathname.slice(APP_BASE.length) || '/';
return pathname || '/';
}
function updateBrowserUrl(path, replace = false) {
const normalized = path.startsWith('/') ? path : `/${path}`;
const target = `${APP_BASE}${normalized}` || normalized;
const current = `${location.pathname}${location.search}`;
if (current === target) return;
history[replace ? 'replaceState' : 'pushState']({}, '', target);
}
function restoreCurrentRoute(previousView) {
updateBrowserUrl(previousView === 'history' ? currentHistoryPath() : pathForView(previousView), true);
}
function applyRouteFromLocation() {
const routePath = appRelativePath();
const parts = routePath.split('/').filter(Boolean);
const first = parts[0] || 'dashboard';
const params = new URLSearchParams(location.search);
const previousView = app.currentView;
app.standaloneSimulation = first === 'simulation' && params.get('standalone') === '1';
document.body.classList.toggle('simulation-standalone', app.standaloneSimulation);
if (first === 'simulation') {
app.simulationScope = ['units', 'groups'].includes(params.get('scope')) ? params.get('scope') : 'units';
app.simulationTarget = params.get('target') || 'all';
}
if (first === 'history') {
app.historyTab = HISTORY_TABS.includes(parts[1]) ? parts[1] : 'overview';
app.historyZone = params.get('zone') || 'all';
app.historyDevice = params.get('device') || 'all';
app.historySensor = params.get('sensor') || 'all';
const hours = params.get('hours');
if (hours && ['6', '24', '168', '720', '2160', '8760'].includes(hours) && $('#historyHours')) $('#historyHours').value = hours;
if (app.historyTab === 'custom' && params.get('chart')) app.customChartSeries = decodeChartSpec(params.get('chart'));
if (!showView('history', { push: false, scroll: false })) restoreCurrentRoute(previousView);
return;
}
const view = first === 'index.html' ? 'dashboard' : ROUTE_VIEWS[`/${first}`];
if (!showView(view || 'dashboard', { push: false, scroll: false })) {
restoreCurrentRoute(previousView);
return;
}
if (!parts.length || first === 'index.html') updateBrowserUrl(VIEW_ROUTES.dashboard, true);
}
function initRouter() {
if (!routerInitialized) {
window.addEventListener('popstate', applyRouteFromLocation);
routerInitialized = true;
}
applyRouteFromLocation();
}