Files
DevOpsLab/app/templates/pages/presets/list.html
Сергей Антропов 1fbf9185a2 feat: добавлена пометка типа операции (Build/Push) в истории сборок Dockerfile
- Добавлена колонка 'Тип' во все таблицы истории сборок
- Для push операций отображается registry вместо платформ
- Сохранение пользователя при создании push лога
- Исправлена ошибка с logger в push_docker_image endpoint
- Улучшено отображение истории сборок с визуальными индикаторами
2026-02-15 22:59:02 +03:00

228 lines
11 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.

{% extends "base.html" %}
{% block title %}Preset'ы - DevOpsLab{% endblock %}
{% block page_title %}Preset'ы Molecule{% endblock %}
{% block header_actions %}
<a href="/presets/create" class="btn btn-primary btn-sm">
<i class="fas fa-plus me-2"></i>
Создать preset
</a>
{% endblock %}
{% block content %}
<!-- Поиск и фильтры -->
<div class="card mb-3">
<div class="card-body">
<form method="get" action="/presets" class="row g-3">
<div class="col-12 col-md-6">
<input
type="text"
name="search"
value="{{ search }}"
placeholder="Поиск по имени или описанию..."
class="form-control"
>
</div>
<div class="col-12 col-md-3">
<select name="category" class="form-select">
<option value="">Все категории</option>
<option value="main" {% if category == 'main' %}selected{% endif %}>Основные</option>
<option value="k8s" {% if category == 'k8s' %}selected{% endif %}>Kubernetes</option>
</select>
</div>
<div class="col-12 col-md-3">
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary">
<i class="fas fa-search me-1"></i>
Поиск
</button>
{% if search or category %}
<a href="/presets" class="btn btn-outline-secondary">
<i class="fas fa-times me-1"></i>
Сброс
</a>
{% endif %}
</div>
</div>
</form>
</div>
</div>
<!-- Таблица preset'ов -->
<div class="card mb-3">
<div class="card-header">
<div class="d-flex justify-content-between align-items-center">
<h5 class="mb-0">Список preset'ов</h5>
<span class="text-muted small">
Всего: <strong>{{ total }}</strong>
</span>
</div>
</div>
<div class="card-body p-0">
{% if presets %}
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead>
<tr>
<th style="width: 25%;">Имя</th>
<th style="width: 15%;">Категория</th>
<th style="width: 30%;">Описание</th>
<th style="width: 15%;">Хосты</th>
<th style="width: 15%;">Действия</th>
</tr>
</thead>
<tbody>
{% for preset in presets %}
<tr>
<td>
<a href="/presets/{{ preset.name }}{% if preset.category == 'k8s' %}?category=k8s{% endif %}" class="text-decoration-none fw-semibold">
{{ preset.name }}
</a>
</td>
<td>
{% if preset.category == 'k8s' %}
<span class="badge bg-primary">Kubernetes</span>
{% else %}
<span class="badge bg-secondary">Основной</span>
{% endif %}
</td>
<td>
<span class="text-muted small">
{{ preset.description[:80] if preset.description else "Нет описания" }}{% if preset.description and preset.description|length > 80 %}...{% endif %}
</span>
</td>
<td>
<span class="badge bg-info">{{ preset.hosts_count|default(0) }}</span>
{% if preset.groups %}
<div class="mt-1">
{% for group in preset.groups[:2] %}
<span class="badge bg-light text-dark small">{{ group }}</span>
{% endfor %}
{% if preset.groups|length > 2 %}
<span class="badge bg-light text-dark small">+{{ preset.groups|length - 2 }}</span>
{% endif %}
</div>
{% endif %}
</td>
<td>
<div class="btn-group btn-group-sm">
<a
href="/presets/{{ preset.name }}/edit{% if preset.category == 'k8s' %}?category=k8s{% endif %}"
class="btn btn-outline-primary"
title="Редактировать"
>
<i class="fas fa-edit"></i>
</a>
<button
hx-delete="/api/v1/presets/{{ preset.name }}?category={{ preset.category or 'main' }}"
hx-confirm="Удалить preset '{{ preset.name }}'?"
hx-target="closest tr"
hx-swap="outerHTML"
class="btn btn-outline-danger"
title="Удалить"
>
<i class="fas fa-trash"></i>
</button>
<a
href="/presets/{{ preset.name }}{% if preset.category == 'k8s' %}?category=k8s{% endif %}"
class="btn btn-outline-secondary"
title="Детали"
>
<i class="fas fa-info-circle"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="text-center py-5">
<i class="fas fa-inbox fa-3x text-muted mb-3"></i>
<p class="text-muted mb-3">Preset'ы не найдены</p>
<a href="/presets/create" class="btn btn-primary">
<i class="fas fa-plus me-2"></i>
Создать первый preset
</a>
</div>
{% endif %}
</div>
{% if presets and total_pages > 1 %}
<div class="card-footer">
<div class="d-flex justify-content-between align-items-center flex-wrap gap-3">
<!-- Пагинация -->
<nav aria-label="Навигация по страницам">
<ul class="pagination mb-0">
{% if page > 1 %}
<li class="page-item">
<a class="page-link" href="?page={{ page - 1 }}{% if search %}&search={{ search }}{% endif %}{% if category %}&category={{ category }}{% endif %}">
<i class="fas fa-chevron-left"></i>
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link">
<i class="fas fa-chevron-left"></i>
</span>
</li>
{% endif %}
{% for p in range(1, total_pages + 1) %}
{% if p == page %}
<li class="page-item active">
<span class="page-link">{{ p }}</span>
</li>
{% elif p == 1 or p == total_pages or (p >= page - 2 and p <= page + 2) %}
<li class="page-item">
<a class="page-link" href="?page={{ p }}{% if search %}&search={{ search }}{% endif %}{% if category %}&category={{ category }}{% endif %}">{{ p }}</a>
</li>
{% elif p == page - 3 or p == page + 3 %}
<li class="page-item disabled">
<span class="page-link">...</span>
</li>
{% endif %}
{% endfor %}
{% if page < total_pages %}
<li class="page-item">
<a class="page-link" href="?page={{ page + 1 }}{% if search %}&search={{ search }}{% endif %}{% if category %}&category={{ category }}{% endif %}">
<i class="fas fa-chevron-right"></i>
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link">
<i class="fas fa-chevron-right"></i>
</span>
</li>
{% endif %}
</ul>
</nav>
<!-- Выбор количества на странице -->
<div class="d-flex align-items-center gap-2">
<span class="text-muted small">На странице:</span>
<select
class="form-select form-select-sm pagination-per-page-select"
style="width: auto;"
onchange="window.location.href = '?page=1&per_page=' + this.value + '{% if search %}&search={{ search }}{% endif %}{% if category %}&category={{ category }}{% endif %}'"
>
<option value="10" {% if per_page == 10 %}selected{% endif %}>10</option>
<option value="25" {% if per_page == 25 %}selected{% endif %}>25</option>
<option value="50" {% if per_page == 50 %}selected{% endif %}>50</option>
<option value="100" {% if per_page == 100 %}selected{% endif %}>100</option>
</select>
</div>
<!-- Информация о странице -->
<div class="text-muted small">
Показано {{ ((page - 1) * per_page) + 1 }} - {{ [page * per_page, total]|min }} из {{ total }}
</div>
</div>
</div>
{% endif %}
</div>
{% endblock %}