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

211 lines
10 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.

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{% block title %}DevOpsLab{% endblock %}</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
crossorigin="anonymous"
/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"
integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="/static/css/main.css" />
<link rel="stylesheet" href="/static/css/forms.css" />
<link rel="stylesheet" href="/static/css/buttons.css" />
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<!-- CodeMirror для редактора кода -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/theme/monokai.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/yaml/yaml.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/dockerfile/dockerfile.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/shell/shell.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/edit/matchbrackets.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/edit/closebrackets.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/foldcode.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/foldgutter.min.js"></script>
<!-- js-yaml для валидации YAML -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/4.1.0/js-yaml.min.js"></script>
{% block head %}{% endblock %}
</head>
<body class="{% if not hide_sidebar %}with-sidebar{% endif %}" id="layout-body">
{% if not hide_sidebar %}
<div class="sidebar-overlay" id="sidebar-overlay" aria-hidden="true"></div>
{% include "components/sidebar.html" %}
{% endif %}
<div class="main-wrapper">
<header class="content-header">
<div class="content-header-inner">
<button type="button" class="sidebar-toggle-btn" id="sidebar-toggle-btn" aria-label="Открыть меню" title="Открыть меню">
<i class="fas fa-bars" aria-hidden="true"></i>
</button>
<h1 class="page-title mb-0">{% block page_title %}{% endblock %}</h1>
<div class="header-actions">
{% block header_actions %}{% endblock %}
</div>
</div>
</header>
<main class="main-content">
{% block content %}{% endblock %}
</main>
</div>
<!-- Универсальное модальное окно для сообщений -->
<div class="modal fade" id="messageModal" tabindex="-1" aria-labelledby="messageModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header" id="messageModalHeader">
<h5 class="modal-title" id="messageModalLabel">
<i class="fas fa-info-circle me-2" id="messageModalIcon"></i>
<span id="messageModalTitle">Сообщение</span>
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
</div>
<div class="modal-body" id="messageModalBody">
<p id="messageModalText"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">OK</button>
</div>
</div>
</div>
</div>
<!-- Модальное окно для подтверждения действий -->
<div class="modal fade" id="confirmModal" tabindex="-1" aria-labelledby="confirmModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header bg-warning">
<h5 class="modal-title" id="confirmModalLabel">
<i class="fas fa-exclamation-triangle me-2"></i>
Подтверждение действия
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
</div>
<div class="modal-body">
<p id="confirmModalText">Вы уверены, что хотите выполнить это действие?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" id="confirmModalCancel">
<i class="fas fa-times me-2"></i>Отмена
</button>
<button type="button" class="btn btn-danger" id="confirmModalConfirm">
<i class="fas fa-check me-2"></i>Подтвердить
</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
crossorigin="anonymous"></script>
<script src="/static/js/app.js"></script>
<script src="/static/js/editor.js"></script>
{% block scripts %}{% endblock %}
<script>
// Sidebar toggle functionality
document.addEventListener('DOMContentLoaded', function() {
const sidebar = document.getElementById('sidebar');
const sidebarToggle = document.getElementById('sidebar-toggle-btn');
const sidebarOverlay = document.getElementById('sidebar-overlay');
const sidebarCollapse = document.getElementById('sidebar-collapse-btn');
if (sidebarToggle) {
sidebarToggle.addEventListener('click', function() {
sidebar.classList.toggle('open');
sidebarOverlay.classList.toggle('visible');
});
}
if (sidebarOverlay) {
sidebarOverlay.addEventListener('click', function() {
sidebar.classList.remove('open');
sidebarOverlay.classList.remove('visible');
});
}
// Обработчик сворачивания sidebar полностью в app.js
// Не добавляем обработчик здесь, чтобы избежать конфликтов
});
// Dropdown menu toggle
function toggleToolsMenu(event) {
event.preventDefault();
const menu = document.getElementById('tools-menu');
menu.classList.toggle('open');
}
function toggleProfileMenu(event) {
event.preventDefault();
const menu = document.getElementById('profile-menu');
menu.classList.toggle('open');
}
function toggleSettingsMenu(event) {
event.preventDefault();
const menu = document.getElementById('settings-menu');
menu.classList.toggle('open');
}
/**
* Показывает модальное окно подтверждения вместо стандартного confirm()
* @param {string} message - Текст сообщения для подтверждения
* @param {string} title - Заголовок модального окна (опционально)
* @returns {Promise<boolean>} - Promise, который разрешается в true при подтверждении, false при отмене
*
* Автор: Сергей Антропов
* Сайт: https://devops.org.ru
*/
function showConfirmModal(message, title = 'Подтверждение действия') {
return new Promise((resolve) => {
const modal = document.getElementById('confirmModal');
const modalText = document.getElementById('confirmModalText');
const modalTitle = document.getElementById('confirmModalLabel');
const confirmBtn = document.getElementById('confirmModalConfirm');
const cancelBtn = document.getElementById('confirmModalCancel');
const bsModal = new bootstrap.Modal(modal);
// Устанавливаем текст сообщения
modalText.textContent = message;
// Устанавливаем заголовок
modalTitle.innerHTML = `<i class="fas fa-exclamation-triangle me-2"></i>${title}`;
// Обработчик подтверждения
const handleConfirm = () => {
bsModal.hide();
resolve(true);
// Удаляем обработчики после использования
confirmBtn.removeEventListener('click', handleConfirm);
cancelBtn.removeEventListener('click', handleCancel);
modal.removeEventListener('hidden.bs.modal', handleCancel);
};
// Обработчик отмены
const handleCancel = () => {
bsModal.hide();
resolve(false);
// Удаляем обработчики после использования
confirmBtn.removeEventListener('click', handleConfirm);
cancelBtn.removeEventListener('click', handleCancel);
modal.removeEventListener('hidden.bs.modal', handleCancel);
};
// Добавляем обработчики событий
confirmBtn.addEventListener('click', handleConfirm);
cancelBtn.addEventListener('click', handleCancel);
modal.addEventListener('hidden.bs.modal', handleCancel);
// Показываем модальное окно
bsModal.show();
});
}
</script>
</body>
</html>