feat: добавлена пометка типа операции (Build/Push) в истории сборок Dockerfile
- Добавлена колонка 'Тип' во все таблицы истории сборок - Для push операций отображается registry вместо платформ - Сохранение пользователя при создании push лога - Исправлена ошибка с logger в push_docker_image endpoint - Улучшено отображение истории сборок с визуальными индикаторами
This commit is contained in:
213
app/templates/pages/tests/index.html
Normal file
213
app/templates/pages/tests/index.html
Normal file
@@ -0,0 +1,213 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}История тестов - DevOpsLab{% endblock %}
|
||||
{% block page_title %}История тестов{% endblock %}
|
||||
|
||||
{% block header_actions %}
|
||||
<a href="/roles" class="btn btn-secondary btn-sm">
|
||||
<i class="fas fa-arrow-left me-2"></i>
|
||||
Назад к ролям
|
||||
</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Фильтры -->
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
<form method="get" action="/tests" class="row g-3">
|
||||
<div class="col-12 col-md-4">
|
||||
<label class="form-label">Роль</label>
|
||||
<select name="role_name" class="form-select">
|
||||
<option value="">Все роли</option>
|
||||
{% for role in roles %}
|
||||
<option value="{{ role }}" {% if role_name == role %}selected{% endif %}>
|
||||
{{ role }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12 col-md-4">
|
||||
<label class="form-label">На странице</label>
|
||||
<select name="per_page" class="form-select" onchange="this.form.submit()">
|
||||
<option value="10" {% if per_page == 10 %}selected{% endif %}>10</option>
|
||||
<option value="20" {% if per_page == 20 %}selected{% endif %}>20</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="col-12 col-md-4 d-flex align-items-end">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-filter me-2"></i>
|
||||
Применить фильтры
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Список тестов -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0">История тестов</h5>
|
||||
<span class="text-muted small">
|
||||
Всего: <strong>{{ total }}</strong>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
{% if error %}
|
||||
<div class="alert alert-warning m-3">
|
||||
<i class="fas fa-exclamation-triangle me-2"></i>
|
||||
{{ error }}
|
||||
</div>
|
||||
{% elif tests %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover mb-0 align-middle">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th style="width: 15%;">Дата/Время</th>
|
||||
<th style="width: 20%;">Роль</th>
|
||||
<th style="width: 20%;">Preset</th>
|
||||
<th style="width: 10%;">Статус</th>
|
||||
<th style="width: 10%;">Длительность</th>
|
||||
<th style="width: 25%;">Команда</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for test in tests %}
|
||||
<tr>
|
||||
<td>
|
||||
<small class="text-muted">
|
||||
{{ test.created_at.strftime('%Y-%m-%d %H:%M:%S') if test.created_at else 'N/A' }}
|
||||
</small>
|
||||
</td>
|
||||
<td>
|
||||
{% if test.command %}
|
||||
{% set role_from_command = test.command.split()[2] if test.command.split()|length > 2 else 'N/A' %}
|
||||
<a href="/roles/{{ role_from_command }}" class="text-decoration-none">
|
||||
{{ role_from_command }}
|
||||
</a>
|
||||
{% else %}
|
||||
<span class="text-muted">N/A</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge bg-secondary">
|
||||
{% if test.command %}
|
||||
{% set preset_from_command = test.command.split()[3] if test.command.split()|length > 3 else 'default' %}
|
||||
{{ preset_from_command }}
|
||||
{% else %}
|
||||
default
|
||||
{% endif %}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
{% if test.status == 'success' %}
|
||||
<span class="badge bg-success">
|
||||
<i class="fas fa-check-circle me-1"></i>
|
||||
Успешно
|
||||
</span>
|
||||
{% elif test.status == 'failed' %}
|
||||
<span class="badge bg-danger">
|
||||
<i class="fas fa-times-circle me-1"></i>
|
||||
Ошибка
|
||||
</span>
|
||||
{% elif test.status == 'running' %}
|
||||
<span class="badge bg-info">
|
||||
<i class="fas fa-spinner fa-spin me-1"></i>
|
||||
Выполняется
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="badge bg-secondary">
|
||||
{{ test.status or 'N/A' }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if test.duration %}
|
||||
<small class="text-muted">{{ test.duration }}s</small>
|
||||
{% else %}
|
||||
<span class="text-muted">-</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<code class="small">{{ test.command[:50] }}{% if test.command|length > 50 %}...{% endif %}</code>
|
||||
</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">Тесты не найдены</p>
|
||||
<a href="/roles" class="btn btn-primary">
|
||||
<i class="fas fa-vial me-2"></i>
|
||||
Запустить тест
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if tests 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 }}&per_page={{ per_page }}{% if role_name %}&role_name={{ role_name }}{% 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 }}&per_page={{ per_page }}{% if role_name %}&role_name={{ role_name }}{% 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 }}&per_page={{ per_page }}{% if role_name %}&role_name={{ role_name }}{% 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="text-muted small">
|
||||
Показано {{ ((page - 1) * per_page) + 1 }} - {{ [page * per_page, total]|min }} из {{ total }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user