naprawa błędów i nowe funkcje

This commit is contained in:
Mateusz Gruszczyński
2025-02-23 10:31:15 +01:00
parent 31c898ba0c
commit f39a4a9414
6 changed files with 188 additions and 42 deletions

View File

@ -8,6 +8,15 @@
<div class="card-body">
<form action="{{ url_for('advanced_schedule') }}" method="POST">
<div class="mb-3">
<div class="mb-3">
<label for="backup_retention_days" class="form-label">Próg retencji backupów (dni)</label>
<small>Usuwanie danych starszych niż ustawione w progu</small>
<input type="number" class="form-control" id="backup_retention_days" name="backup_retention_days" value="{{ settings.backup_retention_days }}">
</div>
<div class="mb-3">
<label for="log_retention_days" class="form-label">Próg retencji logów (dni)</label>
<input type="number" class="form-control" id="log_retention_days" name="log_retention_days" value="{{ settings.log_retention_days }}">
</div>
<label for="retention_cron" class="form-label">Harmonogram retencji (cron)</label>
<div class="input-group">
<input type="text" class="form-control" id="retention_cron" name="retention_cron" value="{{ settings.retention_cron }}">
@ -80,18 +89,15 @@
</div>
<script>
// Zmienna przechowująca ID pola, do którego ma być wpisane wyrażenie cron
var targetCronField = '';
function openCronModal(fieldId) {
targetCronField = fieldId;
// Wyzeruj wartości w modalu
document.getElementById('cron_minute').value = '*';
document.getElementById('cron_hour').value = '*';
document.getElementById('cron_day').value = '*';
document.getElementById('cron_month').value = '*';
document.getElementById('cron_dow').value = '*';
// Otwórz modal (przy użyciu Bootstrap 5)
var cronModal = new bootstrap.Modal(document.getElementById('cronModal'));
cronModal.show();
}
@ -102,10 +108,8 @@
var day = document.getElementById('cron_day').value || '*';
var month = document.getElementById('cron_month').value || '*';
var dow = document.getElementById('cron_dow').value || '*';
var cronExpr = minute + ' ' + hour + ' ' + day + ' ' + month + ' ' + dow;
document.getElementById(targetCronField).value = cronExpr;
// Zamknij modal
var modalEl = document.getElementById('cronModal');
var modalInstance = bootstrap.Modal.getInstance(modalEl);
modalInstance.hide();

View File

@ -21,6 +21,9 @@
.diff-add { color: green; }
.diff-rem { color: red; }
</style>
<!-- Blok head umożliwiający dołączenie dodatkowych stylów -->
{% block head %}{% endblock %}
</head>
<body>
<nav class="navbar navbar-expand navbar-dark bg-dark mb-4">
@ -32,8 +35,11 @@
<a href="{{ url_for('routers_list') }}" class="btn btn-secondary me-2">Urządzenia</a>
<a href="{{ url_for('diff_selector') }}" class="btn btn-secondary me-2">Diff selector</a>
<a href="{{ url_for('all_files') }}" class="btn btn-secondary me-2">Wszystkie pliki</a>
<a href="{{ url_for('logs_page') }}" class="btn btn-secondary me-2">Logi</a>
<a href="{{ url_for('settings_view') }}" class="btn btn-secondary me-2">Ustawienia</a>
<a href="{{ url_for('advanced_schedule') }}" class="btn btn-secondary me-2">Harmonogram</a>
<a href="{{ url_for('change_password') }}" class="btn btn-secondary me-2">Zmiana hasła</a>
<a href="{{ url_for('logout') }}" class="btn btn-secondary me-2">Wyloguj</a>
{% else %}
@ -112,5 +118,7 @@
});
}
</script>
<!-- Blok scripts umożliwiający dołączenie dodatkowych skryptów -->
{% block scripts %}{% endblock %}
</body>
</html>

View File

@ -91,7 +91,10 @@
<!-- Log operacji -->
<div class="card shadow-sm mb-4">
<div class="card-body">
<h5 class="card-title">Log operacji</h5>
<h5 class="card-title">
Log operacji
<a href="{{ url_for('logs_page') }}" class="btn btn-sm btn-outline-primary ms-2">Więcej logów</a>
</h5>
<table class="table table-sm table-bordered">
<thead>
<tr>

73
templates/logs.html Normal file
View File

@ -0,0 +1,73 @@
{% extends "base.html" %}
{% block head %}
{{ super() }}
<!-- DataTables CSS -->
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.4/css/dataTables.bootstrap5.min.css">
{% endblock %}
{% block content %}
<div class="container my-4">
<h2 class="text-center mb-4">Historia logów operacji</h2>
<!-- Formularz usuwania logów starszych od podanej liczby dni -->
<div class="card mb-4 shadow-sm">
<div class="card-body">
<form action="{{ url_for('delete_old_logs') }}" method="POST" class="row g-2 align-items-center">
<div class="col-auto">
<label for="delete_days" class="col-form-label">Usuń logi starsze niż:</label>
</div>
<div class="col-auto">
<input type="number" class="form-control" id="delete_days" name="delete_days" min="1" placeholder="Liczba dni" required>
</div>
<div class="col-auto">
<button type="submit" class="btn btn-danger">Usuń logi</button>
</div>
</form>
</div>
</div>
<!-- Tabela logów -->
<div class="card shadow-sm mb-4">
<div class="card-body">
<table id="logsTable" class="table table-striped table-bordered">
<thead class="table-dark">
<tr>
<th>Data</th>
<th>Wiadomość</th>
</tr>
</thead>
<tbody>
{% for log in logs %}
<tr>
<td>{{ log.timestamp.strftime("%Y-%m-%d %H:%M:%S") }}</td>
<td>{{ log.message }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="text-center mt-3">
<a href="{{ url_for('dashboard') }}" class="btn btn-outline-primary">Powrót do Dashboard</a>
</div>
</div>
{% endblock %}
{% block scripts %}
{{ super() }}
<!-- jQuery (jeśli nie jest już dołączone w base.html) -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- DataTables JS -->
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.13.4/js/dataTables.bootstrap5.min.js"></script>
<script>
$(document).ready(function() {
$('#logsTable').DataTable({
responsive: true,
order: [[0, 'desc']]
});
});
</script>
{% endblock %}

View File

@ -22,12 +22,12 @@
<div class="d-flex flex-wrap gap-2">
<!-- Mniejsze przyciski górne -->
<form action="{{ url_for('router_export', router_id=router.id) }}" method="POST" class="d-inline">
<button type="submit" class="btn btn-primary">Wykonaj /export</button>
<button type="submit" class="btn btn-primary btn-sm">Wykonaj /export</button>
</form>
<form action="{{ url_for('router_backup', router_id=router.id) }}" method="POST" class="d-inline">
<button type="submit" class="btn btn-secondary">Wykonaj backup binarny</button>
<button type="submit" class="btn btn-secondary btn-sm">Wykonaj backup binarny</button>
</form>
<a href="{{ url_for('edit_router', router_id=router.id) }}" class="btn btn-warning">Edytuj ustawienia</a>
<a href="{{ url_for('edit_router', router_id=router.id) }}" class="btn btn-warning btn-sm">Edytuj ustawienia</a>
</div>
</div>
</div>
@ -50,12 +50,12 @@
<!-- Formularz masowych akcji dla eksportów -->
<form id="export_mass_actions_form" action="{{ url_for('download_zip') }}" method="POST" class="mb-3">
<div class="d-flex justify-content-end">
<button type="submit" name="action" value="download" class="btn btn-lg btn-success">
<button type="submit" name="action" value="download" class="btn btn-success btn-sm">
<i class="bi bi-file-earmark-zip"></i> Pobierz zaznaczone (.zip)
</button>
</div>
</form>
<!-- Tabela z eksportami z podzielonymi kolumnami akcji -->
<!-- Tabela z eksportami -->
<table class="table table-bordered table-striped">
<thead class="table-dark">
<tr>
@ -87,19 +87,19 @@
{% endif %}
</td>
<td>
<a href="{{ url_for('download_file', filename=b.file_path|basename) }}" class="btn btn-lg btn-info" title="Pobierz">
<a href="{{ url_for('download_file', filename=b.file_path|basename) }}" class="btn btn-info btn-sm" title="Pobierz">
<i class="bi bi-download"></i>
</a>
</td>
<td>
<a href="{{ url_for('view_export', backup_id=b.id) }}" class="btn btn-lg btn-outline-primary" title="Podgląd">
<a href="{{ url_for('view_export', backup_id=b.id) }}" class="btn btn-outline-primary btn-sm" title="Podgląd">
<i class="bi bi-eye"></i>
</a>
</td>
<td>
<form action="{{ url_for('send_by_email', backup_id=b.id) }}" method="POST" class="d-inline">
<input type="hidden" name="next" value="{{ url_for('router_details', router_id=router.id) }}">
<button type="submit" class="btn btn-lg btn-primary" title="Wyślij mailem">
<button type="submit" class="btn btn-primary btn-sm" title="Wyślij mailem">
<i class="bi bi-envelope"></i>
</button>
</form>
@ -107,7 +107,7 @@
<td>
<form action="{{ url_for('delete_backup', backup_id=b.id) }}" method="POST" class="d-inline" onsubmit="return confirm('Na pewno usunąć backup?');">
<input type="hidden" name="next" value="{{ url_for('router_details', router_id=router.id) }}">
<button type="submit" class="btn btn-lg btn-danger" title="Usuń">
<button type="submit" class="btn btn-danger btn-sm" title="Usuń">
<i class="bi bi-trash"></i>
</button>
</form>
@ -130,12 +130,12 @@
<!-- Formularz masowych akcji dla backupów binarnych -->
<form id="binary_mass_actions_form" action="{{ url_for('download_zip') }}" method="POST" class="mb-3">
<div class="d-flex justify-content-end">
<button type="submit" name="action" value="download" class="btn btn-lg btn-success">
<button type="submit" name="action" value="download" class="btn btn-success btn-sm">
<i class="bi bi-file-earmark-zip"></i> Pobierz zaznaczone (.zip)
</button>
</div>
</form>
<!-- Tabela z backupami binarnymi z podzielonymi kolumnami akcji -->
<!-- Tabela z backupami binarnymi -->
<table class="table table-bordered table-striped">
<thead class="table-dark">
<tr>
@ -155,24 +155,27 @@
<td>
<input type="checkbox" name="backup_id" value="{{ b.id }}" form="binary_mass_actions_form">
</td>
<td>{{ b.file_path|basename }}</td>
<td>
<!-- Dodaj tooltip z sumą kontrolną -->
<span data-bs-toggle="tooltip" title="Checksum: {{ b.checksum }}">{{ b.file_path|basename }}</span>
</td>
<td>{{ b.file_path|filesize }}</td>
<td>{{ b.created_at.strftime("%Y-%m-%d %H:%M:%S") }}</td>
<td>
<a href="{{ url_for('download_file', filename=b.file_path|basename) }}" class="btn btn-lg btn-info" title="Pobierz">
<a href="{{ url_for('download_file', filename=b.file_path|basename) }}" class="btn btn-info btn-sm" title="Pobierz">
<i class="bi bi-download"></i>
</a>
</td>
<td>
<form action="{{ url_for('upload_backup', router_id=router.id, backup_id=b.id) }}" method="POST" class="d-inline">
<button type="submit" class="btn btn-lg btn-secondary" title="Wgraj do routera">
<button type="submit" class="btn btn-secondary btn-sm" title="Wgraj do routera">
<i class="bi bi-upload"></i>
</button>
</form>
</td>
<td>
<form action="{{ url_for('send_by_email', backup_id=b.id) }}" method="POST" class="d-inline">
<button type="submit" class="btn btn-lg btn-primary" title="Wyślij mailem">
<button type="submit" class="btn btn-primary btn-sm" title="Wyślij mailem">
<i class="bi bi-envelope"></i>
</button>
</form>
@ -180,7 +183,7 @@
<td>
<form action="{{ url_for('delete_backup', backup_id=b.id) }}" method="POST" class="d-inline" onsubmit="return confirm('Na pewno usunąć backup?');">
<input type="hidden" name="next" value="{{ url_for('router_details', router_id=router.id) }}">
<button type="submit" class="btn btn-lg btn-danger" title="Usuń">
<button type="submit" class="btn btn-danger btn-sm" title="Usuń">
<i class="bi bi-trash"></i>
</button>
</form>
@ -202,15 +205,11 @@
<script>
document.getElementById('select_all_export').addEventListener('change', function(e) {
var checkboxes = document.querySelectorAll('input[name="backup_id"][form="export_mass_actions_form"]');
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].checked = e.target.checked;
}
checkboxes.forEach(cb => cb.checked = e.target.checked);
});
document.getElementById('select_all_binary').addEventListener('change', function(e) {
var checkboxes = document.querySelectorAll('input[name="backup_id"][form="binary_mass_actions_form"]');
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].checked = e.target.checked;
}
checkboxes.forEach(cb => cb.checked = e.target.checked);
});
// Inicjalizacja zakładek Bootstrap (jeśli nie są już inicjowane globalnie)
@ -222,5 +221,11 @@ triggerTabList.forEach(function (triggerEl) {
tabTrigger.show();
});
});
// Inicjalizacja tooltipów Bootstrap
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
tooltipTriggerList.forEach(function (tooltipTriggerEl) {
new bootstrap.Tooltip(tooltipTriggerEl);
});
</script>
{% endblock %}