From 7fc5b79bf52dd2fa30a71ccc822ea115b3f27922 Mon Sep 17 00:00:00 2001 From: Maxim Date: Thu, 18 Jun 2026 15:24:24 +0300 Subject: [PATCH] =?UTF-8?q?=D0=91=D0=BE=D0=BA=D0=BE=D0=B2=D0=B0=D1=8F=20?= =?UTF-8?q?=D0=BF=D0=B0=D0=BD=D0=B5=D0=BB=D1=8C=20=D0=B2=20=D0=B4=D0=B0?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D1=85=20=D0=B4=D0=BB=D1=8F=20=D0=B6=D1=83?= =?UTF-8?q?=D1=80=D0=BD=D0=B0=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/server/web/css/logs.css | 29 +++++++++++++ cmd/server/web/js/logs.ts | 84 +++++++++++++++++++++++++++++++------ cmd/server/web/logs.html | 2 +- 3 files changed, 101 insertions(+), 14 deletions(-) diff --git a/cmd/server/web/css/logs.css b/cmd/server/web/css/logs.css index af373e8..0aad398 100644 --- a/cmd/server/web/css/logs.css +++ b/cmd/server/web/css/logs.css @@ -617,4 +617,33 @@ @keyframes spin { to { transform: rotate(360deg); } +} + +/* ===== БОКОВАЯ ПАНЕЛЬ ===== */ +.logs-sidebar { + flex: 0 0 280px; + border-right: 1px solid #00ff88; + padding-right: 16px; + padding-left: 4px; + overflow-y: auto; + overflow-x: visible; + transition: all 0.3s ease; +} + +.logs-sidebar.hidden { + flex: 0 0 0 !important; + width: 0 !important; + min-width: 0 !important; + padding: 0 !important; + border: none !important; + overflow: hidden !important; + opacity: 0; +} + +.logs-container { + display: flex; + gap: 20px; + height: calc(100vh - 120px); + overflow: visible; + transition: gap 0.3s ease; } \ No newline at end of file diff --git a/cmd/server/web/js/logs.ts b/cmd/server/web/js/logs.ts index 9446d4c..3b83663 100644 --- a/cmd/server/web/js/logs.ts +++ b/cmd/server/web/js/logs.ts @@ -108,6 +108,10 @@ const DOM = { eventsContent: document.getElementById('eventsContent') as HTMLElement | null, serverTime: document.getElementById('server-time') as HTMLElement | null, + // Боковая панель + logsSidebar: document.querySelector('.logs-sidebar') as HTMLElement | null, + logsContainer: document.querySelector('.logs-container') as HTMLElement | null, + // Элементы пагинации для данных dataPageInfo: document.getElementById('dataPageInfo') as HTMLElement | null, dataPrevPageBtn: document.getElementById('dataPrevPage') as HTMLButtonElement | null, @@ -127,6 +131,29 @@ const DOM = { goToPageBtn: document.getElementById('goToPage') as HTMLButtonElement | null, }; +// ============================================ +// УПРАВЛЕНИЕ БОКОВОЙ ПАНЕЛЬЮ +// ============================================ + +/** + * Показать/скрыть боковую панель в зависимости от активной вкладки + */ +function toggleSidebar(show: boolean): void { + if (!DOM.logsSidebar || !DOM.logsContainer) return; + + if (show) { + // Показываем панель + DOM.logsSidebar.style.display = 'block'; + DOM.logsSidebar.style.flex = '0 0 280px'; + DOM.logsContainer.style.gap = '20px'; + } else { + // Скрываем панель + DOM.logsSidebar.style.display = 'none'; + DOM.logsSidebar.style.flex = '0 0 0'; + DOM.logsContainer.style.gap = '0'; + } +} + // ============================================ // ФУНКЦИИ ЗАГРУЗКИ ДАННЫХ // ============================================ @@ -206,7 +233,6 @@ async function loadFileData(filename: string, page: number = 1): Promise { const response = await fetch(url); - // Проверяем статус ответа if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } @@ -222,7 +248,6 @@ async function loadFileData(filename: string, page: number = 1): Promise { } catch (error) { console.error('[Logs] Ошибка загрузки данных:', error); if (DOM.dataTableContainer) { - // Показываем информативное сообщение, а не красную ошибку DOM.dataTableContainer.innerHTML = `
Нет данных для отображения
@@ -230,7 +255,6 @@ async function loadFileData(filename: string, page: number = 1): Promise {
`; } - // Сбрасываем пагинацию if (DOM.dataPageInfo) { DOM.dataPageInfo.textContent = 'Нет записей'; } @@ -319,15 +343,13 @@ function renderData(data: LogDataResponse): void { `; } - // График - показываем все данные (ограничиваем для производительности) + // График if (DOM.logChart && data.total > 0) { - // Для графика загружаем все данные (но не более 5000 точек) - // В реальности лучше отдельный API для графика const history = samples.map((s: LogSample) => s.signal); drawChart(DOM.logChart, history); } - // Таблица - показываем текущую страницу + // Таблица if (samples.length > 0 && DOM.dataTableContainer) { let html = ` @@ -360,7 +382,12 @@ function renderData(data: LogDataResponse): void { html += '
'; DOM.dataTableContainer.innerHTML = html; } else if (DOM.dataTableContainer) { - DOM.dataTableContainer.innerHTML = '

Нет данных

'; + DOM.dataTableContainer.innerHTML = ` +
+
Нет данных
+
Выберите файл с данными
+
+ `; } } @@ -372,7 +399,12 @@ function renderEvents(data: EventsResponse): void { let html = ''; if (data.events.length === 0) { - html = '
Нет событий
'; + html = ` +
+
Нет событий
+
Журнал событий пуст
+
+ `; } else { data.events.forEach((e: Event, index: number) => { const num = index + 1; @@ -514,7 +546,6 @@ function initDataPaginationControls(): void { let paginationContainer = document.getElementById('dataPaginationContainer'); if (!paginationContainer) { - // Ищем место для вставки (перед таблицей) const tableContainer = document.getElementById('dataTableContainer'); if (!tableContainer) return; @@ -535,7 +566,6 @@ function initDataPaginationControls(): void { `; - // Вставляем перед таблицей dataTab.insertBefore(paginationContainer, tableContainer); } @@ -648,8 +678,27 @@ function initTabs(): void { const targetTab = document.getElementById(`tab-${tabName}`); if (targetTab) targetTab.classList.add('active'); - if (tabName === 'events' && state.currentEvents.length === 0) { - void loadEvents(1); + // ===== УПРАВЛЕНИЕ БОКОВОЙ ПАНЕЛЬЮ ===== + if (tabName === 'data') { + // Показываем боковую панель для вкладки "Данные" + toggleSidebar(true); + // Если данные ещё не загружены, загружаем + if (!state.currentData) { + const firstFile = document.querySelector('.log-file-item'); + if (firstFile) { + const fileName = firstFile.querySelector('.file-name')?.textContent; + if (fileName) { + void loadFileData(fileName, 1); + } + } + } + } else if (tabName === 'events') { + // Скрываем боковую панель для вкладки "События" + toggleSidebar(false); + // Загружаем события, если их нет + if (state.currentEvents.length === 0) { + void loadEvents(1); + } } }); }); @@ -658,6 +707,9 @@ function initTabs(): void { async function init(): Promise { console.log('[Logs] Инициализация...'); + // По умолчанию показываем боковую панель + toggleSidebar(true); + initDataPaginationControls(); initEventsPaginationControls(); initTabs(); @@ -669,9 +721,15 @@ async function init(): Promise { void updateTime(); }, 1000); + // Проверяем, какая вкладка активна при загрузке + const dataTab = document.getElementById('tab-data'); const eventsTab = document.getElementById('tab-events'); + if (eventsTab && eventsTab.classList.contains('active')) { + toggleSidebar(false); await loadEvents(1); + } else { + toggleSidebar(true); } console.log('[Logs] Инициализация завершена'); diff --git a/cmd/server/web/logs.html b/cmd/server/web/logs.html index 6a0d46c..f11d54a 100644 --- a/cmd/server/web/logs.html +++ b/cmd/server/web/logs.html @@ -37,7 +37,7 @@
-
+

Файлы данных