|
|
<!doctype html>
|
|
|
<html lang="ru">
|
|
|
<head>
|
|
|
<meta charset="UTF-8" />
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
|
<title>Панель Триангуляции</title>
|
|
|
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg" />
|
|
|
<link rel="stylesheet" href="/static/styles.css" />
|
|
|
</head>
|
|
|
<body>
|
|
|
<div class="bg-glow bg-glow-a"></div>
|
|
|
<div class="bg-glow bg-glow-b"></div>
|
|
|
|
|
|
<main id="app-shell" class="app-shell">
|
|
|
<aside id="side-nav" class="side-nav card">
|
|
|
<div class="nav-head">
|
|
|
<button id="menu-toggle" class="btn menu-toggle" type="button" aria-controls="menu-list" aria-expanded="true">Свернуть меню</button>
|
|
|
</div>
|
|
|
|
|
|
<div class="menu-wrap">
|
|
|
<div id="menu-list" class="menu-list">
|
|
|
<button class="menu-item menu-item-active" data-section="overview">Обзор</button>
|
|
|
<button class="menu-item" data-section="frequencies">Частоты</button>
|
|
|
<button class="menu-item" data-section="io">Вход/Выход</button>
|
|
|
<button class="menu-item" data-section="history">История</button>
|
|
|
<button class="menu-item" data-section="servers">Серверы</button>
|
|
|
<button class="menu-item" data-section="json">Конфигурация</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="side-meta">
|
|
|
<span id="updated-date" class="badge badge-meta">дата: н/д</span>
|
|
|
<span id="updated-time" class="badge badge-meta">время: н/д</span>
|
|
|
<span id="health-status" class="badge">состояние: н/д</span>
|
|
|
<span id="delivery-status" class="badge">доставка: н/д</span>
|
|
|
<label class="timezone-picker">
|
|
|
<span>часовой пояс</span>
|
|
|
<select id="timezone-select"></select>
|
|
|
</label>
|
|
|
</div>
|
|
|
</aside>
|
|
|
|
|
|
<section class="content-area">
|
|
|
<section id="section-overview" class="panel panel-active">
|
|
|
<header class="hero card">
|
|
|
<h2>Панель Радиопозиционирования</h2>
|
|
|
<p class="muted">Мониторинг и управление расчётом 3D триангуляции.</p>
|
|
|
<div class="hero-actions">
|
|
|
<button id="refresh-now" class="btn btn-primary">Обновить</button>
|
|
|
<button id="toggle-auto-refresh" class="btn" type="button">Пауза автообновления</button>
|
|
|
<span id="refresh-state" class="badge badge-meta">автообновление: вкл (2с)</span>
|
|
|
</div>
|
|
|
</header>
|
|
|
|
|
|
<article class="card">
|
|
|
<h2>Итоговая Позиция</h2>
|
|
|
<div class="result-box">
|
|
|
<div><span class="muted">Выбранная частота:</span> <b id="selected-freq">-</b></div>
|
|
|
<div><span class="muted">X:</span> <b id="pos-x">-</b></div>
|
|
|
<div><span class="muted">Y:</span> <b id="pos-y">-</b></div>
|
|
|
<div><span class="muted">Z:</span> <b id="pos-z">-</b></div>
|
|
|
<div><span class="muted">СКО (RMSE):</span> <b id="rmse">-</b></div>
|
|
|
</div>
|
|
|
</article>
|
|
|
|
|
|
<article class="card">
|
|
|
<h2>Оперативный Мониторинг</h2>
|
|
|
<div class="overview-metrics">
|
|
|
<div class="metric-tile">
|
|
|
<span class="metric-title">Входы online</span>
|
|
|
<b id="ov-input-online" class="metric-value">0/0</b>
|
|
|
</div>
|
|
|
<div class="metric-tile">
|
|
|
<span class="metric-title">Выходы online</span>
|
|
|
<b id="ov-output-online" class="metric-value">0/0</b>
|
|
|
</div>
|
|
|
<div class="metric-tile">
|
|
|
<span class="metric-title">События в истории</span>
|
|
|
<b id="ov-history-total" class="metric-value">0</b>
|
|
|
</div>
|
|
|
<div class="metric-tile">
|
|
|
<span class="metric-title">Успех доставки</span>
|
|
|
<b id="ov-success-rate" class="metric-value">0%</b>
|
|
|
</div>
|
|
|
</div>
|
|
|
</article>
|
|
|
</section>
|
|
|
|
|
|
<section id="section-frequencies" class="panel">
|
|
|
<article class="card">
|
|
|
<h2>Таблица По Частотам</h2>
|
|
|
<div class="table-wrap">
|
|
|
<table id="freq-table">
|
|
|
<thead>
|
|
|
<tr>
|
|
|
<th>Частота (МГц)</th>
|
|
|
<th>X</th>
|
|
|
<th>Y</th>
|
|
|
<th>Z</th>
|
|
|
<th>СКО (RMSE)</th>
|
|
|
<th>Точно</th>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
<tbody></tbody>
|
|
|
</table>
|
|
|
</div>
|
|
|
</article>
|
|
|
</section>
|
|
|
|
|
|
<section id="section-io" class="panel">
|
|
|
<article class="card">
|
|
|
<h2>Входные И Выходные Данные</h2>
|
|
|
<p class="muted">Оперативный мониторинг входящих измерений и фактической отправки на выходные серверы.</p>
|
|
|
<div class="io-grid">
|
|
|
<section class="io-block">
|
|
|
<h3>Входные Данные (Ресиверы)</h3>
|
|
|
<div id="input-flow" class="io-list"></div>
|
|
|
</section>
|
|
|
<section class="io-block">
|
|
|
<h3>Выходные Данные (Отправка)</h3>
|
|
|
<div id="output-flow" class="io-list"></div>
|
|
|
</section>
|
|
|
</div>
|
|
|
|
|
|
<h3 class="io-history-title">Управление Тестовыми Сбоями</h3>
|
|
|
<div id="error-controls" class="io-list"></div>
|
|
|
</article>
|
|
|
</section>
|
|
|
|
|
|
<section id="section-history" class="panel">
|
|
|
<article class="card history-dashboard">
|
|
|
<h2>История Входов И Выходов</h2>
|
|
|
<p class="muted">Связка входных измерений и отправки результата для отладки, SLA и диагностики ошибок.</p>
|
|
|
|
|
|
<div class="history-kpis">
|
|
|
<div class="kpi-card">
|
|
|
<span class="kpi-title">Событий</span>
|
|
|
<b id="hist-total" class="kpi-value">0</b>
|
|
|
</div>
|
|
|
<div class="kpi-card">
|
|
|
<span class="kpi-title">Успешно</span>
|
|
|
<b id="hist-ok" class="kpi-value">0</b>
|
|
|
</div>
|
|
|
<div class="kpi-card">
|
|
|
<span class="kpi-title">Проблемы</span>
|
|
|
<b id="hist-problem" class="kpi-value">0</b>
|
|
|
</div>
|
|
|
<div class="kpi-card">
|
|
|
<span class="kpi-title">Частот</span>
|
|
|
<b id="hist-freqs" class="kpi-value">0</b>
|
|
|
</div>
|
|
|
<div class="kpi-card">
|
|
|
<span class="kpi-title">Последнее событие</span>
|
|
|
<b id="hist-last" class="kpi-value">н/д</b>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="history-toolbar">
|
|
|
<label>
|
|
|
Статус
|
|
|
<select id="history-filter">
|
|
|
<option value="all">Все</option>
|
|
|
<option value="ok">Ок</option>
|
|
|
<option value="error">Ошибка</option>
|
|
|
<option value="partial">Частично</option>
|
|
|
<option value="skipped">Пропущено</option>
|
|
|
<option value="disabled">Отключено</option>
|
|
|
<option value="warming_up">Прогрев</option>
|
|
|
</select>
|
|
|
</label>
|
|
|
<div class="history-toolbar-right">
|
|
|
<label>
|
|
|
От (дата и время)
|
|
|
<input id="history-date-from" type="datetime-local" />
|
|
|
</label>
|
|
|
<label>
|
|
|
До (дата и время)
|
|
|
<input id="history-date-to" type="datetime-local" />
|
|
|
</label>
|
|
|
<label>
|
|
|
Страница
|
|
|
<select id="history-page-size">
|
|
|
<option value="10">10</option>
|
|
|
<option value="20">20</option>
|
|
|
<option value="50">50</option>
|
|
|
</select>
|
|
|
</label>
|
|
|
<div class="history-pager">
|
|
|
<button id="history-prev" class="btn" type="button">Назад</button>
|
|
|
<span id="history-page-info" class="badge badge-meta">Стр. 1/1 • 0 записей</span>
|
|
|
<button id="history-next" class="btn" type="button">Вперёд</button>
|
|
|
</div>
|
|
|
<button id="history-date-reset" class="btn" type="button">Сброс времени</button>
|
|
|
<button id="history-record-toggle" class="btn" type="button">Пауза записи</button>
|
|
|
<span id="history-record-state" class="badge badge-meta">запись: вкл</span>
|
|
|
<button id="clear-history" class="btn" type="button">Очистить историю</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="history-insights">
|
|
|
<section class="insight-panel">
|
|
|
<h3>Лента Последних Событий</h3>
|
|
|
<div id="history-feed" class="history-feed"></div>
|
|
|
</section>
|
|
|
<section class="insight-panel">
|
|
|
<h3>Диагностика Мониторинга</h3>
|
|
|
<div id="history-monitor" class="history-monitor"></div>
|
|
|
</section>
|
|
|
</div>
|
|
|
|
|
|
<div class="table-wrap history-table-wrap">
|
|
|
<table id="io-history-table">
|
|
|
<thead>
|
|
|
<tr>
|
|
|
<th>Время</th>
|
|
|
<th>Частота (МГц)</th>
|
|
|
<th>Вход (RSSI/Радиусы)</th>
|
|
|
<th>Передано На Выход</th>
|
|
|
<th>Статус</th>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
<tbody></tbody>
|
|
|
</table>
|
|
|
</div>
|
|
|
</article>
|
|
|
</section>
|
|
|
|
|
|
<section id="section-servers" class="panel">
|
|
|
<article class="card">
|
|
|
<h2>Настройка Серверов</h2>
|
|
|
<p class="muted">Доступы входа и выхода задаются отдельно. Общий фильтр входа автоматически применяется ко всем входным серверам.</p>
|
|
|
|
|
|
<h3 class="servers-title">Доступ К Входным Серверам</h3>
|
|
|
<div class="server-grid">
|
|
|
<label>Выбранный сервер
|
|
|
<select id="receiver-select"></select>
|
|
|
</label>
|
|
|
<div class="server-actions-row">
|
|
|
<button id="add-receiver" class="btn" type="button">Добавить вход</button>
|
|
|
<button id="remove-receiver" class="btn" type="button">Удалить вход</button>
|
|
|
<span id="receiver-count" class="badge">входов: 0</span>
|
|
|
</div>
|
|
|
<label>Имя ресивера<input id="rx-id" type="text" /></label>
|
|
|
<label>Адрес сервера (URL)<input id="rx-url" type="text" /></label>
|
|
|
<label>Частоты ресивера, МГц (через запятую)<input id="rx-frequencies" type="text" placeholder="433.92, 868.1" /></label>
|
|
|
<label>Координата X<input id="rx-center-x" type="number" step="0.001" /></label>
|
|
|
<label>Координата Y<input id="rx-center-y" type="number" step="0.001" /></label>
|
|
|
<label>Координата Z<input id="rx-center-z" type="number" step="0.001" /></label>
|
|
|
</div>
|
|
|
|
|
|
<h3 class="servers-title">Общий Фильтр Входа (Авто Для Всех)</h3>
|
|
|
<div class="server-grid">
|
|
|
<label>Фильтр включен
|
|
|
<select id="shared-filter-enabled">
|
|
|
<option value="true">да</option>
|
|
|
<option value="false">нет</option>
|
|
|
</select>
|
|
|
</label>
|
|
|
<label>Мин. частота, МГц<input id="shared-min-freq" type="number" step="0.001" min="0" /></label>
|
|
|
<label>Макс. частота, МГц<input id="shared-max-freq" type="number" step="0.001" min="0" /></label>
|
|
|
<label>Мин. RSSI, дБм<input id="shared-min-rssi" type="number" step="0.1" /></label>
|
|
|
<label>Макс. RSSI, дБм<input id="shared-max-rssi" type="number" step="0.1" /></label>
|
|
|
</div>
|
|
|
|
|
|
<h3 class="servers-title">Выходные Серверы</h3>
|
|
|
<div class="server-grid">
|
|
|
<label>Выбранный выход
|
|
|
<select id="output-select"></select>
|
|
|
</label>
|
|
|
<div class="server-actions-row">
|
|
|
<button id="add-output-server" class="btn" type="button">Добавить выход</button>
|
|
|
<button id="remove-output-server" class="btn" type="button">Удалить выход</button>
|
|
|
<span id="output-count" class="badge">выходов: 0</span>
|
|
|
</div>
|
|
|
<label>Имя выхода<input id="out-name" type="text" /></label>
|
|
|
<label>Токен записи (API, только сессия)<input id="write-token" type="password" /></label>
|
|
|
<label>IP/хост выхода<input id="out-ip" type="text" /></label>
|
|
|
</div>
|
|
|
|
|
|
<div class="editor-actions">
|
|
|
<button id="load-servers" class="btn">Загрузить</button>
|
|
|
<button id="save-servers" class="btn btn-primary">Сохранить серверы</button>
|
|
|
<span id="servers-state" class="badge">серверы: н/д</span>
|
|
|
</div>
|
|
|
</article>
|
|
|
</section>
|
|
|
|
|
|
<section id="section-json" class="panel">
|
|
|
<article class="card">
|
|
|
<h2>Конфигурация</h2>
|
|
|
<div class="editor-actions">
|
|
|
<button id="load-config" class="btn">Загрузить</button>
|
|
|
<button id="save-config" class="btn btn-primary">Сохранить конфиг</button>
|
|
|
<span id="config-state" class="badge">конфиг: н/д</span>
|
|
|
</div>
|
|
|
<textarea id="config-editor" class="editor" spellcheck="false"></textarea>
|
|
|
</article>
|
|
|
</section>
|
|
|
</section>
|
|
|
</main>
|
|
|
|
|
|
<script src="/static/app.js"></script>
|
|
|
<div id="toast-container" class="toast-container" aria-live="polite" aria-atomic="true"></div>
|
|
|
</body>
|
|
|
</html>
|
|
|
|