UI: навигация, документация, favicon; журнал развёртывания; валидация формы

- Меню API: ссылка «Теги образов», обёртка прокрутки пилюль, z-index и padding против обрезки hover
- Документация: ширина колонки как у дашборда (72rem)
- Favicon SVG + GET /favicon.ico, link в base.html
- provision_log.json, GET .../provision-log, кнопка в таблице кластеров
- Валидация create: имя, workers, тег kindest; модалка alert
- Прочие правки из сессии (clusters, job_store, стили, шаблоны)
This commit is contained in:
Sergey Antropoff
2026-04-04 08:15:15 +03:00
parent 6f3daa33ec
commit 4546f50aef
19 changed files with 723 additions and 103 deletions
+25 -8
View File
@@ -5,6 +5,8 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/static/favicon.svg" type="image/svg+xml" />
<link rel="alternate icon" href="/favicon.ico" />
<title>{% block page_title %}{{ app_title }}{% endblock %} — kind</title>
{# Тема до первой отрисовки: localStorage kind_k8s_theme или prefers-color-scheme #}
<script>
@@ -52,8 +54,11 @@
</a>
{# Один ряд flex: Панель, Документация, API, тема — общий align-items: center #}
<nav class="nav-links top-nav-actions" aria-label="Разделы и оформление">
<a href="/" class="nav-link nav-pill{% if nav_active|default('') == 'panel' %} nav-pill--active{% endif %}">Панель</a>
<a href="/documentation" class="nav-link nav-pill{% if nav_active|default('') == 'documentation' %} nav-pill--active{% endif %}">Документация</a>
{# Прокрутка только у пилюль: overflow-x на nav обрезал бы выпадающее меню API (position: absolute). #}
<div class="nav-links-scroll">
<a href="/" class="nav-link nav-pill{% if nav_active|default('') == 'panel' %} nav-pill--active{% endif %}">Панель</a>
<a href="/documentation" class="nav-link nav-pill{% if nav_active|default('') == 'documentation' %} nav-pill--active{% endif %}">Документация</a>
</div>
<div class="nav-dropdown">
<button
type="button"
@@ -90,6 +95,16 @@
data-open-window="kind_health"
>Health</a>
</li>
<li role="none">
<a
role="menuitem"
href="https://hub.docker.com/r/kindest/node/tags"
class="nav-dropdown__link nav-pill--ext"
target="_blank"
rel="noopener noreferrer"
title="Список тегов kindest/node на Docker Hub (новое окно)"
>Теги образов</a>
</li>
</ul>
</div>
<button type="button" id="theme-toggle" class="theme-toggle theme-toggle--nav-end">
@@ -199,12 +214,14 @@
});
});
document.addEventListener("click", function () {
closeApiMenu();
});
dd.addEventListener("click", function (e) {
e.stopPropagation();
});
/* Закрытие по клику вне блока API (фаза capture: не конфликтует с открытием по кнопке). */
document.addEventListener(
"click",
function (e) {
if (!dd.contains(e.target)) closeApiMenu();
},
true,
);
document.addEventListener("keydown", function (e) {
if (e.key === "Escape") closeApiMenu();
+25 -12
View File
@@ -22,10 +22,10 @@
</section>
<section class="card create-cluster-card">
<h2>Новый кластер</h2>
<h2 class="create-cluster-card__title">Новый кластер</h2>
<form id="form-create" novalidate>
<div class="create-form-grid">
<div class="create-form-col">
<div class="create-form-field">
<label for="fld-name">Имя (a-z0-9-)</label>
<input
id="fld-name"
@@ -36,18 +36,31 @@
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>
<div class="create-form-field">
<label for="version-select">
<a
href="https://hub.docker.com/r/kindest/node/tags"
target="_blank"
rel="noopener noreferrer"
class="create-form-doc-link"
title="Список тегов kindest/node на Docker Hub (новое окно)"
>Тег образа</a><span class="create-form-doc-link__ext" aria-hidden="true"></span>
<span class="create-form-label-rest">
kindest/node — список или версия вручную ниже</span>
</label>
<select id="version-select" name="kubernetes_version_preset">
<option value="">— загрузить список —</option>
</select>
</div>
<div class="create-form-field">
<label for="fld-workers">Worker-ноды (020)</label>
<input id="fld-workers" name="workers" type="number" min="0" max="20" step="1" value="2" />
</div>
<div class="create-form-field">
<label for="kubernetes_version">Версия Kubernetes / тег node</label>
<input
name="kubernetes_version"
+1 -2
View File
@@ -2,8 +2,7 @@
Автор: Сергей Антропов — https://devops.org.ru #}
{% extends "base.html" %}
{# Полная ширина контента и подвала — см. .doc-layout-full в style.css #}
{% block body_extra_class %} doc-layout-full{% endblock %}
{# Ширина колонки как у панели: .app-main max-width 72rem (секция «Ресурсы узлов (сводка)» и др.). #}
{% block page_title %}Документация{% endblock %}
@@ -42,6 +42,34 @@
</div>
</div>
<div
id="provision-log-modal-overlay"
class="modal-overlay provision-log-modal-overlay hidden"
role="dialog"
aria-modal="true"
aria-labelledby="provision-log-modal-title"
>
<div class="modal-box modal-box--provision-log">
<div class="modal-head modal-head--cluster">
<h3 id="provision-log-modal-title" class="modal-title-text modal-title-text--center">
Журнал развёртывания
</h3>
<div class="modal-toolbar" role="toolbar" aria-label="Закрыть окно">
<button type="button" class="modal-close btn-secondary" id="provision-log-modal-close">
Закрыть
</button>
</div>
</div>
<p id="provision-log-modal-sub" class="muted modal-sub" aria-live="polite"></p>
<pre
id="provision-log-body"
class="mono provision-log-body"
role="region"
aria-label="JSON журнала развёртывания"
></pre>
</div>
</div>
<div
id="confirm-modal-overlay"
class="modal-overlay confirm-modal-overlay hidden"