'use strict'; /** * ui/routes/entries.js — главная страница: список записей + CRUD. * * Данные из /api/v1/entries (Bearer token из сессии). * Admin: поддержка ?company= (числовой PK) для управления другой компанией. * Формы с company_id скрытым полем → передаётся в API как ?company=. */ const { Router } = require('express'); const api = require('../api-client'); function createRouter() { const router = Router(); // Вычислить URL для возврата (с учётом выбранной компании) function backUrl(req) { const companyId = req.query.company || (req.body && req.body.company_id); if (!companyId || companyId === 'own') return '/?company=own'; return '/?company=' + companyId; } // Суффикс ?company= для вызовов API // 'own' = компания admin без ?company — API использует getOrCreateCompany function companyQuery(req) { const companyId = req.query.company || (req.body && req.body.company_id); if (!companyId || companyId === 'own') return ''; return '?company=' + companyId; } // GET / — список записей router.get('/', async (req, res) => { const token = api.token(req); try { let entries = [], limit = 15, selectedCompany = null, companies = []; if (req.user.isAdmin) { const cr = await api.get('/api/v1/companies', token); companies = cr.data.companies || []; const companyParam = req.query.company || ''; const companyId = companyParam && companyParam !== 'own' ? parseInt(companyParam, 10) : null; // Без параметра — редирект на свою компанию if (!companyParam) { return res.redirect('/?company=own'); } if (companyParam === 'own') { // Собственные записи admin (getOrCreateCompany внутри API) const er = await api.get('/api/v1/entries', token); entries = er.data.entries || []; limit = er.data.limit || 15; selectedCompany = { id: 'own', name: 'Моя компания', client_id: req.user.clientId }; } else { selectedCompany = companyId ? companies.find(c => c.id === companyId) || null : null; if (selectedCompany) { const er = await api.get('/api/v1/entries?company=' + companyId, token); entries = er.data.entries || []; limit = er.data.limit || selectedCompany.custom_limit || selectedCompany.default_limit || 15; } } } else { const er = await api.get('/api/v1/entries', token); entries = er.data.entries || []; limit = er.data.limit || 15; } res.render('index', { entries, limit, used: entries.length, user: req.user, isAdmin: req.user.isAdmin, companies, selectedCompany, error: req.query.error || null, success: req.query.success || null, csrfToken: '', }); } catch (e) { res.render('index', { entries: [], limit: 15, used: 0, user: req.user, isAdmin: req.user.isAdmin, companies: [], selectedCompany: null, error: 'Ошибка загрузки данных: ' + e.message, success: null, csrfToken: '', }); } }); // POST /add — создать запись router.post('/add', async (req, res) => { const token = api.token(req); const { value, comment } = req.body; const cq = companyQuery(req); const back = backUrl(req); try { const r = await api.post('/api/v1/entries' + cq, token, { value, comment }); if (r.status === 201) { const msg = r.data.wasNormalized ? 'Запись добавлена (CIDR нормализован до ' + r.data.entry.value_cidr + ')' : 'Запись добавлена'; return res.redirect(back + (back.includes('?') ? '&' : '?') + 'success=' + encodeURIComponent(msg)); } res.redirect(back + (back.includes('?') ? '&' : '?') + 'error=' + encodeURIComponent(r.data.error || 'Ошибка')); } catch (e) { res.redirect(back + (back.includes('?') ? '&' : '?') + 'error=' + encodeURIComponent(e.message)); } }); // POST /edit/:id — обновить запись router.post('/edit/:id', async (req, res) => { const token = api.token(req); const { value, comment } = req.body; const cq = companyQuery(req); const back = backUrl(req); try { const r = await api.patch('/api/v1/entries/' + req.params.id + cq, token, { value, comment }); if (r.status === 200) { return res.redirect(back + (back.includes('?') ? '&' : '?') + 'success=' + encodeURIComponent('Запись обновлена')); } res.redirect(back + (back.includes('?') ? '&' : '?') + 'error=' + encodeURIComponent(r.data.error || 'Ошибка')); } catch (e) { res.redirect(back + (back.includes('?') ? '&' : '?') + 'error=' + encodeURIComponent(e.message)); } }); // POST /delete/:id — удалить запись router.post('/delete/:id', async (req, res) => { const token = api.token(req); const cq = companyQuery(req); const back = backUrl(req); try { const r = await api.delete('/api/v1/entries/' + req.params.id + cq, token); if (r.status === 204) { return res.redirect(back + (back.includes('?') ? '&' : '?') + 'success=' + encodeURIComponent('Запись удалена')); } res.redirect(back + (back.includes('?') ? '&' : '?') + 'error=' + encodeURIComponent((r.data && r.data.error) || 'Ошибка')); } catch (e) { res.redirect(back + (back.includes('?') ? '&' : '?') + 'error=' + encodeURIComponent(e.message)); } }); return router; } module.exports = { createRouter };