- Добавлена колонка 'Тип' во все таблицы истории сборок - Для push операций отображается registry вместо платформ - Сохранение пользователя при создании push лога - Исправлена ошибка с logger в push_docker_image endpoint - Улучшено отображение истории сборок с визуальными индикаторами
164 lines
6.1 KiB
HTML
164 lines
6.1 KiB
HTML
{% extends "base.html" %}
|
||
|
||
{% block title %}Экспорт {{ role_name }} - DevOpsLab{% endblock %}
|
||
{% block page_title %}Экспорт роли: {{ role_name }}{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="card mb-3">
|
||
<div class="card-header">
|
||
<h5 class="mb-0">Настройки экспорта</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<form
|
||
hx-post="/api/v1/roles/{{ role_name }}/export"
|
||
hx-target="#export-result"
|
||
hx-swap="innerHTML"
|
||
class="space-y-4"
|
||
>
|
||
<!-- URL репозитория -->
|
||
<div class="mb-3">
|
||
<label class="form-label">URL Git репозитория *</label>
|
||
<input
|
||
type="url"
|
||
name="repo_url"
|
||
class="form-control"
|
||
placeholder="https://github.com/username/ansible-role-{{ role_name }}.git"
|
||
required
|
||
>
|
||
<div class="form-text">
|
||
Поддерживаются HTTPS и SSH URL (git@github.com:user/repo.git)
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Ветка -->
|
||
<div class="mb-3">
|
||
<label class="form-label">Ветка</label>
|
||
<input
|
||
type="text"
|
||
name="branch"
|
||
value="main"
|
||
class="form-control"
|
||
placeholder="main"
|
||
>
|
||
</div>
|
||
|
||
<!-- Версия -->
|
||
<div class="mb-3">
|
||
<label class="form-label">Версия (для создания тега)</label>
|
||
<input
|
||
type="text"
|
||
name="version"
|
||
class="form-control"
|
||
placeholder="1.0.0"
|
||
pattern="^[0-9]+\.[0-9]+\.[0-9]+$"
|
||
>
|
||
<div class="form-text">
|
||
Формат: X.Y.Z (например, 1.0.0). Будет создан тег v{version}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Компоненты -->
|
||
<div class="mb-3">
|
||
<label class="form-label">Компоненты для экспорта</label>
|
||
<div class="row g-2">
|
||
{% for component in components %}
|
||
<div class="col-12 col-md-6 col-lg-4">
|
||
<div class="form-check">
|
||
<input
|
||
class="form-check-input"
|
||
type="checkbox"
|
||
value="{{ component }}"
|
||
id="component-{{ component }}"
|
||
name="components"
|
||
checked
|
||
>
|
||
<label class="form-check-label" for="component-{{ component }}">
|
||
{{ component }}
|
||
</label>
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Секреты -->
|
||
<div class="mb-3">
|
||
<div class="form-check form-switch">
|
||
<input
|
||
class="form-check-input"
|
||
type="checkbox"
|
||
id="include-secrets"
|
||
name="include_secrets"
|
||
>
|
||
<label class="form-check-label" for="include-secrets">
|
||
Включать секреты из vars/ (не рекомендуется)
|
||
</label>
|
||
</div>
|
||
<div class="form-text text-warning">
|
||
⚠️ Если включено, секреты будут экспортированы. Используйте с осторожностью!
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Сообщение коммита -->
|
||
<div class="mb-3">
|
||
<label class="form-label">Сообщение коммита</label>
|
||
<textarea
|
||
name="commit_message"
|
||
class="form-control"
|
||
rows="2"
|
||
placeholder="Автоматически сгенерируется, если не указано"
|
||
></textarea>
|
||
</div>
|
||
|
||
<!-- Скрытое поле для компонентов -->
|
||
<input
|
||
type="hidden"
|
||
name="components"
|
||
id="components-json"
|
||
value="[]"
|
||
>
|
||
|
||
<!-- Результат -->
|
||
<div id="export-result" class="mt-4"></div>
|
||
|
||
<!-- Кнопки -->
|
||
<div class="d-flex gap-2">
|
||
<button type="submit" class="btn btn-primary">
|
||
<i class="fas fa-upload me-2"></i>
|
||
Экспортировать роль
|
||
</button>
|
||
<a href="/roles/{{ role_name }}" class="btn btn-secondary">
|
||
<i class="fas fa-arrow-left me-2"></i>
|
||
Отмена
|
||
</a>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
const form = document.querySelector('form');
|
||
const componentsInput = document.getElementById('components-json');
|
||
const checkboxes = document.querySelectorAll('input[name="components"]');
|
||
|
||
function updateComponents() {
|
||
const selected = Array.from(checkboxes)
|
||
.filter(cb => cb.checked)
|
||
.map(cb => cb.value);
|
||
componentsInput.value = JSON.stringify(selected);
|
||
}
|
||
|
||
checkboxes.forEach(cb => {
|
||
cb.addEventListener('change', updateComponents);
|
||
});
|
||
|
||
updateComponents();
|
||
|
||
form.addEventListener('submit', function(e) {
|
||
updateComponents();
|
||
});
|
||
});
|
||
</script>
|
||
{% endblock %}
|