- Добавлена колонка 'Тип' во все таблицы истории сборок - Для push операций отображается registry вместо платформ - Сохранение пользователя при создании push лога - Исправлена ошибка с logger в push_docker_image endpoint - Улучшено отображение истории сборок с визуальными индикаторами
211 lines
10 KiB
HTML
211 lines
10 KiB
HTML
<!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>
|