Веб-UI: темы, навигация API, статистика и доработки API

- Шапка: логотип Kubernetes, ссылка на главную, выпадающее меню API (Swagger/ReDoc/Health), переключатель светлой/тёмной темы (localStorage).
- Светлая тема в синей гамме; выравнивание кнопки темы в ряду с пилюлями.
- Дашборд: единая карточка ошибки health/stats, подсказка Docker/Podman, поле container_cli в GET /stats, total_workers_from_meta всегда число (0 без meta).
- Правки кластеров, job_store, compose, документация и частичные шаблоны.
This commit is contained in:
Sergey Antropoff
2026-04-04 07:58:19 +03:00
parent aa8003061e
commit 6f3daa33ec
20 changed files with 1885 additions and 451 deletions
+132
View File
@@ -0,0 +1,132 @@
{# Создание кластера, журнал задания и последние задания.
Автор: Сергей Антропов — https://devops.org.ru #}
{% extends "base.html" %}
{% block body_attrs %}data-dashboard-mode="create"{% endblock %}
{% block footer %}
<div class="footer-inner">
<p class="footer-copyright">
© {{ app_title }} ·
<a href="https://devops.org.ru" target="_blank" rel="noopener">devops.org.ru</a>
</p>
</div>
{% endblock %}
{% block content %}
<section class="card hero-panel cluster-create-hero" aria-labelledby="create-hero-title">
<h1 class="page-title" id="create-hero-title">Создание кластера</h1>
<p class="muted page-lead">
Укажите имя, версию образа kindest/node и число worker-нод. Операция выполняется в фоне; ход смотрите в журнале ниже.
</p>
</section>
<section class="card create-cluster-card">
<h2>Новый кластер</h2>
<form id="form-create" novalidate>
<div class="create-form-grid">
<div class="create-form-col">
<label for="fld-name">Имя (a-z0-9-)</label>
<input
id="fld-name"
name="name"
required
pattern="[a-z0-9]([-a-z0-9]*[a-z0-9])?"
maxlength="63"
placeholder="dev"
autocomplete="off"
/>
<label for="fld-workers">Worker-ноды (020)</label>
<input id="fld-workers" name="workers" type="number" min="0" max="20" value="2" />
</div>
<div class="create-form-col">
<label for="version-select">Тег образа kindest/node (подсказка) или введите версию вручную ниже</label>
<div class="row">
<select id="version-select" name="kubernetes_version_preset" aria-describedby="ver-hint">
<option value="">— загрузить список —</option>
</select>
</div>
<label for="kubernetes_version">Версия Kubernetes / тег node</label>
<input
name="kubernetes_version"
id="kubernetes_version"
required
placeholder="1.29.4 или v1.29.4"
autocomplete="off"
/>
</div>
<div class="create-form-span">
<div class="row create-actions">
<button type="submit">Создать кластер</button>
</div>
</div>
</div>
<div id="create-progress-wrap" class="create-progress-wrap hidden" aria-hidden="true">
<p class="create-progress-hint muted" id="create-progress-hint">
Идёт операция — шаг <code>kind create</code> может занять несколько минут при первом pull образов.
Ниже выводится журнал (скачивание образов и подъём нод).
</p>
<div
class="progress-track"
role="progressbar"
aria-valuemin="0"
aria-valuemax="100"
aria-valuenow="0"
aria-labelledby="create-progress-label"
id="create-progress-track"
>
<div class="progress-bar" id="create-progress-bar" style="width:0%"></div>
</div>
<p class="progress-label" id="create-progress-label"></p>
<div class="job-log-panel-wrap">
<label for="job-log-panel" class="job-log-label muted">Журнал задания</label>
<pre
id="job-log-panel"
class="mono job-log-panel"
role="log"
aria-live="polite"
aria-relevant="additions"
></pre>
</div>
<button type="button" id="btn-cancel-create" class="btn-secondary">Отменить</button>
</div>
<p id="create-msg" class="msg" aria-live="polite"></p>
<details id="job-details" class="job-details hidden">
<summary>Технические детали (JSON)</summary>
<pre id="job-json" class="mono job-json-pre" tabindex="0"></pre>
</details>
</form>
</section>
<section class="card jobs-card">
<div class="row spread jobs-card-toolbar">
<h2 id="jobs-heading" class="jobs-card-title">Последние задания</h2>
<button type="button" id="btn-jobs-clear" class="btn-secondary">Очистить завершённые</button>
</div>
<div class="table-wrap">
<table id="tbl-jobs" aria-label="Последние задания создания">
<thead>
<tr>
<th>Дата, время <span class="th-hint">(UTC)</span></th>
<th>Кластер</th>
<th>Статус</th>
<th>Сообщение</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<p id="jobs-msg" class="msg muted"></p>
</section>
{% include "partials/dashboard_modals.html" %}
{% endblock %}
{% block scripts %}
<script src="/static/js/dashboard.js" defer></script>
{% endblock %}