- Добавлена колонка 'Тип' во все таблицы истории сборок - Для push операций отображается registry вместо платформ - Сохранение пользователя при создании push лога - Исправлена ошибка с logger в push_docker_image endpoint - Улучшено отображение истории сборок с визуальными индикаторами
116 lines
4.3 KiB
HTML
116 lines
4.3 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Линтинг - DevOpsLab{% endblock %}
|
|
{% block page_title %}Проверка синтаксиса ролей{% endblock %}
|
|
|
|
{% block header_actions %}
|
|
<button type="button" class="btn btn-primary btn-sm" onclick="startLint('all')">
|
|
<i class="fas fa-check-circle me-2"></i>
|
|
Проверить все роли
|
|
</button>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="card mb-3">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">Выбор роли для проверки</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
{% if roles %}
|
|
<div class="row g-3">
|
|
{% for role in roles %}
|
|
<div class="col-12 col-md-6 col-lg-4">
|
|
<div class="card h-100">
|
|
<div class="card-body">
|
|
<h6 class="card-title">
|
|
<i class="fas fa-cube me-2"></i>
|
|
{{ role.name }}
|
|
</h6>
|
|
<a href="/roles/{{ role.name }}/lint" class="btn btn-primary btn-sm w-100">
|
|
<i class="fas fa-check-circle me-2"></i>
|
|
Проверить
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</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/create" class="btn btn-primary">
|
|
<i class="fas fa-plus me-2"></i>
|
|
Создать первую роль
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Логи линтинга -->
|
|
<div class="card" id="lint-logs-card" style="display: none;">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">Логи проверки</h5>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="log-container" id="lint-logs" style="height: 500px; overflow-y: auto; background: #1e1e1e; color: #d4d4d4; padding: 1rem; font-family: 'Courier New', monospace; font-size: 0.875rem;">
|
|
<!-- Логи будут добавлены через WebSocket -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
function startLint(roleName) {
|
|
const logsCard = document.getElementById('lint-logs-card');
|
|
const logsContainer = document.getElementById('lint-logs');
|
|
|
|
// Показываем контейнер логов
|
|
logsCard.style.display = 'block';
|
|
logsContainer.innerHTML = '';
|
|
|
|
// Создаем WebSocket подключение
|
|
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
const ws = new WebSocket(`${protocol}//${window.location.host}/ws/lint/${roleName}`);
|
|
|
|
ws.onmessage = (event) => {
|
|
const data = JSON.parse(event.data);
|
|
|
|
if (data.type === 'log' || data.type === 'info') {
|
|
const logLine = document.createElement('div');
|
|
logLine.className = `log-line log-${data.level || 'info'}`;
|
|
logLine.textContent = data.data;
|
|
logsContainer.appendChild(logLine);
|
|
|
|
// Автоскролл
|
|
logsContainer.scrollTop = logsContainer.scrollHeight;
|
|
} else if (data.type === 'error') {
|
|
const errorLine = document.createElement('div');
|
|
errorLine.className = 'log-line log-error';
|
|
errorLine.textContent = data.data;
|
|
logsContainer.appendChild(errorLine);
|
|
} else if (data.type === 'complete') {
|
|
const completeLine = document.createElement('div');
|
|
completeLine.className = 'log-line log-info';
|
|
completeLine.textContent = data.data || '✅ Проверка завершена';
|
|
logsContainer.appendChild(completeLine);
|
|
ws.close();
|
|
}
|
|
};
|
|
|
|
ws.onerror = (error) => {
|
|
const errorLine = document.createElement('div');
|
|
errorLine.className = 'log-line log-error';
|
|
errorLine.textContent = `❌ Ошибка подключения: ${error}`;
|
|
logsContainer.appendChild(errorLine);
|
|
};
|
|
|
|
ws.onclose = () => {
|
|
console.log('WebSocket закрыт');
|
|
};
|
|
}
|
|
</script>
|
|
{% endblock %}
|