logboard/app/templates/index.html
Sergey Antropoff d570807c02 Исправление ошибки 500 при сохранении исключенных контейнеров
- Исправлен путь к файлу excluded_containers.json в функциях load_excluded_containers и save_excluded_containers
- Добавлено создание директории при необходимости
- Улучшено логирование операций с файлом
- Протестирована функциональность API endpoints
- Обновлен список исключенных контейнеров

Автор: Сергей Антропов
Сайт: https://devops.org.ru
2025-09-01 18:18:09 +03:00

412 lines
18 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="ru" data-theme="dark">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<title>LogBoard+</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<link rel="stylesheet" href="/static/css/index.css">
</head>
<body>
<div class="app-container">
<!-- Sidebar -->
<div class="sidebar" id="sidebar">
<!-- Логотип для свернутого состояния -->
<div class="sidebar-logo">
<i class="fas fa-terminal"></i>
</div>
<div class="sidebar-header">
<div class="header-top">
<h1><i class="fas fa-terminal"></i> LogBoard+</h1>
<div class="header-buttons">
<button class="options-btn" id="optionsBtn" title="Показать/скрыть настройки">
<i class="fas fa-cog"></i>
</button>
<button class="logout-btn" id="logoutBtn" title="Выйти">
<i class="fas fa-sign-out-alt"></i>
</button>
</div>
</div>
</div>
<div class="sidebar-controls">
<div class="control-group collapsible" data-section="tail">
<div class="control-header">
<label>Tail Lines</label>
<button class="collapse-btn" data-target="tail">
<i class="fas fa-chevron-down"></i>
</button>
</div>
<div class="control-content" id="tail-content">
<select id="tail">
<option value="50">50</option>
<option value="100" selected>100</option>
<option value="200">200</option>
<option value="300">300</option>
<option value="500">500</option>
<option value="1000">1000</option>
<option value="all">All logs</option>
</select>
</div>
</div>
<div class="control-group collapsible" data-section="options">
<div class="control-header">
<label>Options</label>
<button class="collapse-btn" data-target="options">
<i class="fas fa-chevron-down"></i>
</button>
</div>
<div class="control-content" id="options-content">
<div class="checkbox-group options-grid">
<div class="checkbox-item">
<input type="checkbox" id="autoscroll" checked>
<label for="autoscroll">Auto-scroll</label>
</div>
<div class="checkbox-item">
<input type="checkbox" id="wrap" checked>
<label for="wrap">Wrap text</label>
</div>
<div class="checkbox-item">
<input type="checkbox" id="autoupdate" checked>
<label for="autoupdate">Update logs</label>
</div>
<div class="checkbox-item">
<input type="checkbox" id="autoRefreshOnRestore" checked>
<label for="autoRefreshOnRestore">Refresh logs on panel restore</label>
</div>
</div>
</div>
</div>
<div class="control-group collapsible" data-section="actions">
<div class="control-header">
<label>Actions</label>
<button class="collapse-btn" data-target="actions">
<i class="fas fa-chevron-down"></i>
</button>
</div>
<div class="control-content" id="actions-content">
<div class="btn-group actions-grid">
<button id="refresh" class="btn"><i class="fas fa-sync-alt"></i> Refresh</button>
<button id="clear" class="btn"><i class="fas fa-trash"></i> Clear</button>
<button id="snapshot" class="btn btn-full-width"><i class="fas fa-download"></i> Download logs</button>
</div>
</div>
</div>
<div class="control-group collapsible" data-section="excluded">
<div class="control-header">
<label>Excluded</label>
<button class="collapse-btn" data-target="excluded">
<i class="fas fa-chevron-down"></i>
</button>
</div>
<div class="control-content" id="excluded-content">
<div class="excluded-containers-list" id="excludedContainersList">
<!-- Список будет загружен динамически -->
</div>
<div class="excluded-containers-controls">
<input type="text" id="newExcludedContainer" placeholder="Имя контейнера" class="excluded-input">
<button id="addExcludedContainer" class="btn btn-small">Добавить</button>
</div>
</div>
</div>
</div>
<!-- Container List -->
<div class="container-list" id="containerList">
<div class="container-item placeholder">
<div class="container-name">
<i class="fas fa-info-circle"></i>
Loading containers...
</div>
</div>
</div>
<!-- Миникарточки контейнеров для свернутого sidebar -->
<div class="mini-container-list" id="miniContainerList">
<div class="mini-container-item placeholder">
<div class="mini-container-icon">
<i class="fas fa-info-circle"></i>
</div>
<div class="mini-container-name">Loading...</div>
</div>
</div>
</div>
<!-- Кнопка сворачивания sidebar -->
<button class="sidebar-toggle" id="sidebarToggle" title="Свернуть/развернуть панель (Ctrl+B / Ctrl+И)">
<i class="fas fa-chevron-left"></i>
</button>
<!-- Main Content -->
<div class="main-content">
<!-- Header -->
<div class="header" id="header">
<button class="mobile-toggle" id="mobileToggle">
<i class="fas fa-bars"></i>
</button>
<h2 class="header-title">
Logs
</h2>
<span class="header-badge" id="projectBadge">
<div class="multi-select-container">
<div class="multi-select-display" id="projectSelectDisplay">
<span class="multi-select-text">All Projects</span>
<i class="fas fa-chevron-down"></i>
</div>
<div class="multi-select-dropdown" id="projectSelectDropdown" style="display: none;">
<div class="multi-select-option" data-value="all">
<input type="checkbox" id="project-all" checked>
<label for="project-all">All Projects</label>
</div>
</div>
</div>
</span>
<input id="filter" type="text" placeholder="Filter logs (regex)…" class="header-filter"/>
<div class="header-controls">
<div class="header-compact-controls">
<button class="counter-btn debug-btn" title="DEBUG">
<span class="counter-label">DEBUG</span>
<span class="counter-value cdbg">0</span>
</button>
<button class="counter-btn info-btn" title="INFO">
<span class="counter-label">INFO</span>
<span class="counter-value cinfo">0</span>
</button>
<button class="counter-btn warn-btn" title="WARN">
<span class="counter-label">WARN</span>
<span class="counter-value cwarn">0</span>
</button>
<button class="counter-btn error-btn" title="ERROR">
<span class="counter-label">ERROR</span>
<span class="counter-value cerr">0</span>
</button>
<button class="counter-btn other-btn" title="OTHER">
<span class="counter-label">OTHER</span>
<span class="counter-value cother">0</span>
</button>
</div>
<div class="theme-toggle">
<span>Theme</span>
<input id="themeSwitch" type="checkbox" />
</div>
<button id="wsstate" class="ws-status-btn">ws: off</button>
<button id="ajaxUpdateBtn" class="ajax-update-btn" title="AJAX Auto-update">update</button>
<button class="btn btn-small log-refresh-btn" title="Обновить логи и счетчики">
<i class="fas fa-sync-alt"></i> Refresh
</button>
<button class="help-btn" id="helpBtn" title="Справка">
<i class="fas fa-question-circle"></i>
</button>
<!-- Модальное окно для кнопки помощи -->
<div class="help-tooltip" id="helpTooltip">
<div class="help-tooltip-header">
<div class="help-tooltip-header-content">
<div class="help-tooltip-logo">LB</div>
<div class="help-tooltip-title">LogBoard+ - Справка</div>
</div>
<button class="help-tooltip-close" id="helpTooltipClose">
<i class="fas fa-times"></i>
</button>
</div>
<div class="help-tooltip-body">
<div class="help-tooltip-content-wrapper">
<div class="help-tooltip-left-column">
<div class="help-tooltip-section">
<div class="help-tooltip-section-title">О проекте</div>
<div class="help-tooltip-content">
<strong>LogBoard+</strong> - веб-интерфейс для мониторинга логов Docker контейнеров в реальном времени с поддержкой мультивыбора и автоматического обновления.
<br><br><strong>🎯 Идеально для локальной разработки:</strong><br>
• Второй монитор - логи всегда перед глазами<br>
• Быстрая отладка - без переключения терминалов<br>
• Мониторинг в реальном времени<br>
• Централизованный просмотр всех логов
<br><br><strong>🐳 Оптимизирован для Docker:</strong><br>
• Автоматическое обнаружение проектов<br>
• Multi-view режим для нескольких контейнеров<br>
• Интеграция с Docker API<br>
• Поддержка Docker Compose
</div>
</div>
<div class="help-tooltip-section">
<div class="help-tooltip-section-title">Горячие клавиши</div>
<div class="help-tooltip-hotkeys">
<div class="help-tooltip-hotkey">[</div>
<div class="help-tooltip-description">Предыдущий контейнер</div>
<div class="help-tooltip-hotkey">]</div>
<div class="help-tooltip-description">Следующий контейнер</div>
<div class="help-tooltip-hotkey">Ctrl+R</div>
<div class="help-tooltip-description">Обновить логи</div>
<div class="help-tooltip-hotkey">Ctrl+K</div>
<div class="help-tooltip-description">Обновить логи (альтернатива)</div>
<div class="help-tooltip-hotkey">Ctrl+B</div>
<div class="help-tooltip-description">Свернуть/развернуть sidebar</div>
<div class="help-tooltip-hotkey">Ctrl+F</div>
<div class="help-tooltip-description">Фокус на фильтр</div>
</div>
</div>
</div>
<div class="help-tooltip-right-column">
<div class="help-tooltip-section">
<div class="help-tooltip-section-title">Мышь и выделение</div>
<div class="help-tooltip-hotkeys">
<div class="help-tooltip-hotkey">Shift+клик</div>
<div class="help-tooltip-description">Добавить в мультивыбор</div>
<div class="help-tooltip-hotkey">Ctrl+клик</div>
<div class="help-tooltip-description">Добавить в мультивыбор</div>
<div class="help-tooltip-hotkey">Выделение текста</div>
<div class="help-tooltip-description">Показать кнопку копирования</div>
</div>
</div>
<div class="help-tooltip-section">
<div class="help-tooltip-section-title">Функции</div>
<div class="help-tooltip-hotkeys">
<div class="help-tooltip-hotkey">Кнопки уровней</div>
<div class="help-tooltip-description">Фильтрация по типу логов</div>
<div class="help-tooltip-hotkey">Auto-scroll</div>
<div class="help-tooltip-description">Автопрокрутка к новым логам</div>
<div class="help-tooltip-hotkey">Wrap text</div>
<div class="help-tooltip-description">Перенос длинных строк</div>
<div class="help-tooltip-hotkey">Auto-update</div>
<div class="help-tooltip-description">Автообновление логов</div>
<div class="help-tooltip-hotkey">Refresh</div>
<div class="help-tooltip-description">Принудительное обновление</div>
<div class="help-tooltip-hotkey">Clear</div>
<div class="help-tooltip-description">Очистить логи</div>
<div class="help-tooltip-hotkey">Download</div>
<div class="help-tooltip-description">Скачать логи</div>
</div>
</div>
</div>
</div>
</div>
<div class="help-tooltip-footer">
<div class="help-tooltip-author">
Автор: <a href="https://devops.org.ru" target="_blank">Сергей Антропов</a>
</div>
<div class="help-tooltip-version">
Версия 2.0
</div>
</div>
</div>
</div>
</div>
<!-- Log Area -->
<div class="log-area">
<!-- Multi-view panel для Single View режима -->
<div class="multi-view-panel" id="multiViewPanel">
<span id="multiViewPanelTitle">No container selected</span>
</div>
<div class="log-content">
<div class="single-view-panel" id="singleViewPanel">
<div class="single-view-header">
<h4 class="single-view-title" id="singleViewTitle">No container selected</h4>
<div class="single-view-levels">
<button class="level-btn debug-btn" data-level="debug" title="DEBUG">
<span class="level-label">DEBUG</span>
<span class="level-value" data-container="single">0</span>
</button>
<button class="level-btn info-btn" data-level="info" title="INFO">
<span class="level-label">INFO</span>
<span class="level-value" data-container="single">0</span>
</button>
<button class="level-btn warn-btn" data-level="warn" title="WARN">
<span class="level-label">WARN</span>
<span class="level-value" data-container="single">0</span>
</button>
<button class="level-btn error-btn" data-level="err" title="ERROR">
<span class="level-label">ERROR</span>
<span class="level-value" data-container="single">0</span>
</button>
<button class="level-btn other-btn" data-level="other" title="OTHER">
<span class="level-label">OTHER</span>
<span class="level-value" data-container="single">0</span>
</button>
</div>
</div>
<div class="single-view-content">
<pre class="log" id="logContent">No container selected</pre>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Legacy elements for compatibility -->
<div id="tabs" style="display: none;"></div>
<div id="idFilters" style="display: none;"></div>
<main id="grid" style="display: none;"></main>
<button id="copyFab" class="copy-fab" type="button">копировать</button>
<footer style="display: none;">© LogBoard+</footer>
<!-- Модальное окно с горячими клавишами -->
<div class="hotkeys-modal" id="hotkeysModal">
<div class="hotkeys-modal-content">
<div class="hotkeys-modal-header">
<h3 class="hotkeys-modal-title">
<i class="fas fa-keyboard"></i>
Горячие клавиши
</h3>
<button class="hotkeys-modal-close" id="hotkeysModalClose">
<i class="fas fa-times"></i>
</button>
</div>
<div class="hotkeys-modal-body">
<div class="hotkeys-section">
<h4 class="hotkeys-section-title">Навигация</h4>
<ul class="hotkeys-list">
<li><kbd>[</kbd> <kbd>]</kbd> <span>Переход между контейнерами</span></li>
<li><kbd>Ctrl</kbd> + <kbd></kbd> <span>Предыдущий контейнер</span></li>
<li><kbd>Ctrl</kbd> + <kbd></kbd> <span>Следующий контейнер</span></li>
</ul>
</div>
<div class="hotkeys-section">
<h4 class="hotkeys-section-title">Обновление</h4>
<ul class="hotkeys-list">
<li><kbd>Ctrl</kbd> + <kbd>R</kbd> <span>Обновить логи</span></li>
<li><kbd>Ctrl</kbd> + <kbd>K</kbd> <span>Обновить логи (альтернатива)</span></li>
</ul>
</div>
<div class="hotkeys-section">
<h4 class="hotkeys-section-title">Интерфейс</h4>
<ul class="hotkeys-list">
<li><kbd>Ctrl</kbd> + <kbd>B</kbd> <span>Свернуть/развернуть панель</span></li>
<li><kbd>Ctrl</kbd> + <kbd>И</kbd> <span>Свернуть/развернуть панель (русская раскладка)</span></li>
</ul>
</div>
</div>
</div>
</div>
<script src="/static/js/index.js"></script>
</body>
</html>