PageSourceSearch

https://udnet.ru/js/main.js?v=32

js udnet.ru collected 2026-10-08 23:44:17 UTC 5,642 bytes, 135 lines download raw bytes

1// Udnet Production CRM — точка входа.
2// Подключает модули и связывает навигацию между разделами.
3
4import { $, $$ } from './core/utils.js';
5import { showScreen } from './core/navigation.js';
6import { initParallax } from './core/parallax.js';
7import { initAuth, tryRestoreSession } from './core/auth.js?v=8';
8
9import { initStats, renderStats } from './modules/stats.js?v=4';
10import { initJournal, renderJournal } from './modules/journal.js';
11import { initSupply, renderSupply } from './modules/supply.js';
12import { initCatalogProducts, renderCatalogProducts } from './modules/catalog-products.js';
13import { initCatalogMaterials, renderCatalogMaterials } from './modules/catalog-materials.js';
14import { initCatalogTechcards, renderCatalogTechcards } from './modules/catalog-techcards.js';
15import { initProductAnalytics, renderProductAnalytics } from './modules/product-analytics.js?v=10';
16import { initBusiness, renderBusiness } from './modules/business-metrics.js?v=6';
17import { initCorp, renderCorp } from './modules/corp-docs.js?v=17';
18
19initParallax();
20initAuth();
21
22// =================== Routing table ===================
23const ROUTES = {
24  home: {
25    screen: '#screen-app',
26    crumb: 'Дашборд',
27    enter: () => {},
28  },
29  production: {
30    screen: '#screen-stats',
31    crumb: 'Статистика производства',
32    enter: async () => { initStats(); await renderStats(); },
33  },
34  stats: {
35    screen: '#screen-stats',
36    crumb: 'Статистика производства',
37    enter: async () => { initStats(); await renderStats(); },
38  },
39  journal: {
40    screen: '#screen-journal',
41    crumb: 'Статистика производства',
42    enter: async () => { initJournal(); await renderJournal(); },
43  },
44  supply: {
45    screen: '#screen-supply',
46    crumb: 'Снабжение',
47    enter: async () => { initSupply(); await renderSupply(); },
48  },
49  corp: {
50    screen: '#screen-corp',
51    crumb: 'Корпоративные документы',
52    enter: async () =>
52 { initCorp(); await renderCorp(); },
53  },
54  'product-analytics': {
55    screen: '#screen-product-analytics',
56    crumb: 'Товарная аналитика',
57    enter: async () => { initProductAnalytics(); await renderProductAnalytics(); },
58  },
59  business: {
60    screen: '#screen-business',
61    crumb: 'Бизнес-метрики',
62    enter: async () => { initBusiness(); await renderBusiness(); },
63  },
64  'catalog-products': {
65    screen: '#screen-catalog-products',
66    crumb: 'Каталог продукции',
67    enter: async () => { initCatalogProducts(); await renderCatalogProducts(); },
68  },
69  'catalog-techcards': {
70    screen: '#screen-catalog-techcards',
71    crumb: 'Тех-карты',
72    enter: async () => { initCatalogTechcards(); await renderCatalogTechcards(); },
73  },
74  'catalog-materials': {
75    screen: '#screen-catalog-materials',
76    crumb: 'Каталог сырья и упаковки',
77    enter: async () => { initCatalogMaterials(); await renderCatalogMaterials(); },
78  },
79};
80
81const NAV_KEY = 'udnet_nav';
82const ANALYST_ALLOWED = ['home', 'product-analytics'];
83// stats и journal живут под общим пунктом меню «Статистика производства» (production)
84const NAV_ALIAS = { stats: 'production', journal: 'production' };
85async function navigate(nav) {
86  // Аналитик не может уйти в другие разделы (даже по сохранённой навигации/прямой ссылке)
87  if (document.body.classList.contains('is-analyst') && !ANALYST_ALLOWED.includes(nav)) {
88    nav = 'product-analytics';
89  }
90  let route = ROUTES[nav];
91  if (!route) { nav = 'home'; route = ROUTES['home']; }
92  try { localStorage.setItem(NAV_KEY, nav); } catch (e) {}
93  // Подсветка пункта в сайдбаре
94  const activeNav = NAV_ALIAS[nav] || nav;
95  $$('.nav-link').forEach(l => l.classList.toggle('active', l.dataset.nav === activeNav));
96  // Хлебные крошки
97  const crumb = $('#crumbCurrent'); if (crumb) crumb.textContent = route.crumb;
98  // Показ нужного экрана
99  showScreen(route.screen);
100  // Догрузка контента
101  await route.enter();
102}
103
104// Слушаем кастомное событие из auth.js (после логина)
105document.addEventListener('app-nav', (e) => navigate(e.detail.nav));
106
107// Сайдбар
108$$('.nav-link').forEach(link => {
109  link.addEventListener('click', (e) => {
110    e.preventDefault();
111    navigate(link.dataset.nav);
112  });
113});
114
115// Карточки на главной странице — это просто визуальные ярлыки той же навигации
116$$("#modulesGrid .card").forEach(card => {
117  card.addEventListener("click", () => {
118    const mod = card.dataset.module;
119    if (ROUTES[mod]) navigate(mod);
120  });
121});
122
123// Восстановление сессии при загрузке
124tryRestoreSession();
125
126// Любые элементы с data-nav (кнопки внутри экранов) — тоже навигация
127$$('[data-nav]').forEach(el => {
128  if (el.classList.contains('nav-link')) return;
129  el.addEventListener('click', (e) => { e.preventDefault(); navigate(el.dataset.nav); });
130});
131
132
133
134/* Раздел «Бизнес-метрики» — доступен только роли management */
135window.__bizMgmtGuard = window.__bizMgmtGuard || setInterval(function(){try{var m=localStorage.getItem('udnet_role')==='management';var b=document.querySelector('[data-nav="business"]');if(b)b.style.display=m?'':'none';}catch(e){}},1000);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.