баг-фикс 30/34

This commit is contained in:
Zuev
2026-07-19 14:40:43 +03:00
parent 3d798c13e3
commit bc0e1ab1b4
172 changed files with 13431 additions and 2910 deletions

View File

@@ -1,18 +1,17 @@
// OTel: загружаем только на продакшене (не на localhost)
if (!['localhost', '127.0.0.1'].includes(window.location.hostname)) {
import('./otel.js').catch(e => console.warn('OTel init skipped:', e.message));
}
import { api, isAuthenticatedAsAny, logout } from './api.js';
import { applyRippleEffect, closeAllDropdownsOnOutsideClick } from './utils.js';
import { api, initializeSession, logout } from './api.js';
import { applyRippleEffect, closeAllDropdownsOnOutsideClick, renderStatusMessage } from './utils.js';
import { startDropdownAutoObserver, initAllCustomDropdowns } from './dropdown.js';
import { ADMIN_APP_ROLES, SETTINGS_ROLES, capabilitiesForRole } from './role-capabilities.js';
import { initializeTelemetry } from '../../telemetry.js';
const AUTHORIZED_ROLES = ['ADMIN', 'EDUCATION_OFFICE', 'DEPARTMENT', 'SCHEDULE_VIEWER'];
const currentRole = localStorage.getItem('role');
if (!isAuthenticatedAsAny(AUTHORIZED_ROLES)) {
window.location.href = '/';
async function bootstrap() {
const session = await initializeSession();
if (!session || !ADMIN_APP_ROLES.includes(session.role)) {
window.location.replace('/');
return;
}
const currentRole = session.role;
void initializeTelemetry();
// Global initialization for Custom Selects
document.addEventListener('DOMContentLoaded', () => {
@@ -120,25 +119,6 @@ const ROUTES = {
},
};
const ROLE_NAVIGATION = {
ADMIN: {
defaultTab: 'dashboard',
tabs: ['dashboard', 'teacher-requests', 'schedule', 'academic-calendar', 'auditorium-workload', 'schedule-view', 'classrooms', 'groups', 'university-structure', 'subjects', 'users']
},
EDUCATION_OFFICE: {
defaultTab: 'dashboard',
tabs: ['dashboard', 'schedule', 'academic-calendar', 'auditorium-workload', 'schedule-view', 'classrooms']
},
DEPARTMENT: {
defaultTab: 'department-workspace',
tabs: ['department-workspace', 'schedule-view']
},
SCHEDULE_VIEWER: {
defaultTab: 'schedule-view',
tabs: ['schedule-view']
}
};
let currentTab = null;
// DOM Elements
@@ -153,8 +133,8 @@ const btnLogout = document.getElementById('btn-logout');
const main = document.querySelector('.main');
const teacherRequestsNavBadge = document.getElementById('teacher-requests-nav-badge');
const teacherRequestsTitleBadge = document.getElementById('teacher-requests-title-badge');
const roleNavigation = ROLE_NAVIGATION[currentRole] || ROLE_NAVIGATION.SCHEDULE_VIEWER;
const allowedTabs = new Set(roleNavigation.tabs);
const roleCapabilities = capabilitiesForRole(currentRole);
const allowedTabs = new Set(roleCapabilities.adminTabs);
// Setup Global Effects
applyRippleEffect();
@@ -258,8 +238,8 @@ async function switchTab(tab) {
window.location.hash = tab;
}
} catch (e) {
appContent.innerHTML = `<div class="form-alert error">Ошибка загрузки вкладки: ${e.message}</div>`;
console.error(e);
renderStatusMessage(appContent, 'Не удалось загрузить выбранную вкладку');
console.error('Не удалось загрузить вкладку');
}
// Close mobile menu if open
@@ -274,7 +254,7 @@ function configureRoleInterface() {
const settingsLink = document.querySelector('.settings-menu a[href="/admin/settings/"]');
if (settingsLink) {
settingsLink.hidden = !['ADMIN', 'EDUCATION_OFFICE'].includes(currentRole);
settingsLink.hidden = !SETTINGS_ROLES.includes(currentRole);
}
const firstAllowedTitle = {
@@ -297,7 +277,7 @@ async function refreshTeacherRequestBadge(countOverride = null) {
} catch (error) {
if (teacherRequestsNavBadge) teacherRequestsNavBadge.hidden = true;
if (teacherRequestsTitleBadge) teacherRequestsTitleBadge.hidden = true;
console.warn('Не удалось загрузить счётчик заявок:', error.message);
console.warn('Не удалось загрузить счётчик заявок');
}
}
@@ -323,7 +303,7 @@ document.addEventListener('teacherRequestsChanged', (event) => {
});
const hashTab = window.location.hash.replace('#', '');
switchTab(allowedTabs.has(hashTab) ? hashTab : roleNavigation.defaultTab);
switchTab(allowedTabs.has(hashTab) ? hashTab : roleCapabilities.defaultAdminTab);
window.addEventListener('hashchange', () => {
const hashTab = window.location.hash.replace('#', '');
@@ -331,3 +311,6 @@ window.addEventListener('hashchange', () => {
switchTab(hashTab);
}
});
}
await bootstrap();