git add templates/! REFACOR INTERFEJSU git add templates/
This commit is contained in:
@ -2,116 +2,178 @@
|
||||
{% block title %}Moje urządzenia - RouterOS Update{% endblock %}
|
||||
|
||||
{% block extra_head %}
|
||||
<style>
|
||||
.progress-container {
|
||||
width: 50%;
|
||||
margin: 20px auto;
|
||||
background: #444;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.progress-bar {
|
||||
width: 0%;
|
||||
height: 30px;
|
||||
background: #4caf50;
|
||||
border-radius: 5px;
|
||||
transition: width 0.5s linear;
|
||||
}
|
||||
<style>
|
||||
/* Karta w trybie ciemnym */
|
||||
body.dark-mode .card {
|
||||
background-color: #1e1e1e;
|
||||
color: #ccc;
|
||||
border-color: #444;
|
||||
}
|
||||
|
||||
#mass-system-update-overlay, #mass-firmware-update-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,0.7);
|
||||
z-index: 1000;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding-top: 200px;
|
||||
}
|
||||
</style>
|
||||
/* Nagłówek karty w trybie ciemnym */
|
||||
body.dark-mode .card .card-header.bg-light {
|
||||
background-color: #333 !important;
|
||||
border-bottom: 1px solid #444;
|
||||
}
|
||||
|
||||
/* Tabela w trybie ciemnym */
|
||||
body.dark-mode .table thead.table-dark {
|
||||
background-color: #2a2a2a !important;
|
||||
color: #ccc !important;
|
||||
border-color: #444 !important;
|
||||
}
|
||||
body.dark-mode .table-hover tbody tr:hover {
|
||||
background-color: #2f2f2f;
|
||||
}
|
||||
body.dark-mode .table-bordered > :not(caption) > * > * {
|
||||
border-color: #444 !important;
|
||||
}
|
||||
|
||||
/* Styl paska postępu w overlay */
|
||||
.progress-container {
|
||||
width: 50%;
|
||||
margin: 20px auto;
|
||||
background: #444;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.progress-bar {
|
||||
width: 0%;
|
||||
height: 30px;
|
||||
background: #4caf50;
|
||||
border-radius: 5px;
|
||||
transition: width 0.5s linear;
|
||||
}
|
||||
#mass-system-update-overlay,
|
||||
#mass-firmware-update-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0; left: 0;
|
||||
width: 100%; height: 100%;
|
||||
background: rgba(0,0,0,0.7);
|
||||
z-index: 1000;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding-top: 200px;
|
||||
}
|
||||
|
||||
/* Prompt do firmware w overlay */
|
||||
#mass-firmware-reboot-prompt {
|
||||
display:none;
|
||||
position:fixed;
|
||||
top:0; left:0;
|
||||
width:100%; height:100%;
|
||||
background:rgba(0,0,0,0.7);
|
||||
z-index:1100;
|
||||
color:white;
|
||||
text-align:center;
|
||||
padding-top:200px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
{% block content %}
|
||||
<h2>Moje urządzenia</h2>
|
||||
<div class="row mb-3">
|
||||
<div class="col text-end">
|
||||
<button type="button" class="btn btn-success" onclick="window.location.href='{{ url_for('add_device') }}'">
|
||||
Dodaj nowe urządzenie
|
||||
</button>
|
||||
<div class="container">
|
||||
<h2 class="mb-4">Moje urządzenia</h2>
|
||||
|
||||
<!-- Karta z tabelą urządzeń i przyciskami masowych akcji -->
|
||||
<div class="card border-0 shadow">
|
||||
<div class="card-header bg-light d-flex align-items-center justify-content-between">
|
||||
<h5 class="mb-0">Lista urządzeń</h5>
|
||||
<button type="button" class="btn btn-success" onclick="window.location.href='{{ url_for('add_device') }}'">
|
||||
Dodaj nowe urządzenie
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<!-- Formularz z przyciskami masowych operacji -->
|
||||
<form id="mass-update-form">
|
||||
<div class="mb-3">
|
||||
<button type="button" id="mass-system-update-btn" class="btn btn-warning me-2">Aktualizuj system (masowo)</button>
|
||||
<button type="button" id="mass-firmware-update-btn" class="btn btn-danger me-2">Aktualizuj firmware (masowo)</button>
|
||||
<button type="submit" class="btn btn-primary">Odśwież wybrane</button>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover table-sm align-middle table-bordered">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th><input type="checkbox" id="select-all"></th>
|
||||
<th>Nazwa / Adres IP</th>
|
||||
<th>Ostatnie sprawdzenie</th>
|
||||
<th>Status</th>
|
||||
<th>System / Firmware</th>
|
||||
<th>Akcje</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for device in devices %}
|
||||
<tr>
|
||||
<td>
|
||||
<input type="checkbox" name="selected_devices" value="{{ device.id }}">
|
||||
</td>
|
||||
<td>
|
||||
{% if device.name %}
|
||||
{{ device.name }}
|
||||
<br><code class="text-muted">{{ device.ip }}</code>
|
||||
{% else %}
|
||||
{{ device.ip }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{{ device.last_check.strftime('%Y-%m-%d %H:%M:%S') if device.last_check else 'Brak' }}
|
||||
</td>
|
||||
<td>
|
||||
{% if device.update_required or (device.current_firmware and device.upgrade_firmware and device.current_firmware != device.upgrade_firmware) %}
|
||||
{% if device.update_required and (device.current_firmware and device.upgrade_firmware and device.current_firmware != device.upgrade_firmware) %}
|
||||
<span class="badge bg-danger">Wymaga aktualizacji <small>(system i firmware)</small></span>
|
||||
{% elif device.update_required %}
|
||||
<span class="badge bg-danger">Wymaga aktualizacji <small>(system)</small></span>
|
||||
{% else %}
|
||||
<span class="badge bg-danger">Wymaga aktualizacji <small>(firmware)</small></span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="badge bg-success">Aktualny</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td style="white-space: nowrap;">
|
||||
<small>
|
||||
<strong>System:</strong> {{ device.current_version or 'Brak' }}<br>
|
||||
<strong>Firmware:</strong> {{ device.current_firmware or 'Brak' }}<br>
|
||||
<strong>Upgrade FW:</strong> {{ device.upgrade_firmware or 'N/A' }}
|
||||
</small>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-info btn-sm"
|
||||
onclick="window.location.href='{{ url_for('device_detail', device_id=device.id) }}'">
|
||||
Szczegóły
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary btn-sm"
|
||||
onclick="window.location.href='{{ url_for('force_check', device_id=device.id) }}'">
|
||||
Sprawdź
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning btn-sm"
|
||||
onclick="window.location.href='{{ url_for('edit_device', device_id=device.id) }}'">
|
||||
Edytuj
|
||||
</button>
|
||||
<!-- Dodane przykładowe przyciski (potrzebna obsługa w backendzie) -->
|
||||
<button type="button" class="btn btn-outline-danger btn-sm"
|
||||
onclick="fetch('/device/{{ device.id }}/restart', {method: 'POST'}) .then(()=>location.reload());">
|
||||
Restart
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="6" class="text-center">Brak dodanych urządzeń.</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Formularz z przyciskami masowych operacji -->
|
||||
<form id="mass-update-form">
|
||||
<div class="mb-3">
|
||||
<button type="button" id="mass-system-update-btn" class="btn btn-warning">Aktualizuj system (masowo)</button>
|
||||
<button type="button" id="mass-firmware-update-btn" class="btn btn-danger">Aktualizuj firmware (masowo)</button>
|
||||
<button type="submit" class="btn btn-primary">Odśwież wybrane</button>
|
||||
</div>
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th><input type="checkbox" id="select-all"></th>
|
||||
<th>Nazwa / Adres IP</th>
|
||||
<th>Ostatnie sprawdzenie</th>
|
||||
<th>Status</th>
|
||||
<th>System / Firmware</th>
|
||||
<th>Akcje</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for device in devices %}
|
||||
<tr>
|
||||
<td>
|
||||
<input type="checkbox" name="selected_devices" value="{{ device.id }}">
|
||||
</td>
|
||||
<td>
|
||||
{% if device.name %}
|
||||
{{ device.name }} |
|
||||
<code><small class="text-muted">{{ device.ip }}</small></code>
|
||||
{% else %}
|
||||
{{ device.ip }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ device.last_check.strftime('%Y-%m-%d %H:%M:%S') if device.last_check else 'Brak' }}</td>
|
||||
<td>
|
||||
{% if device.update_required or (device.current_firmware and device.upgrade_firmware and device.current_firmware != device.upgrade_firmware) %}
|
||||
{% if device.update_required and (device.current_firmware and device.upgrade_firmware and device.current_firmware != device.upgrade_firmware) %}
|
||||
<span class="badge bg-danger">Wymaga aktualizacji <small>(system i firmware)</small></span>
|
||||
{% elif device.update_required %}
|
||||
<span class="badge bg-danger">Wymaga aktualizacji <small>(system)</small></span>
|
||||
{% else %}
|
||||
<span class="badge bg-danger">Wymaga aktualizacji <small>(firmware)</small></span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="badge bg-success">Aktualny</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<small>
|
||||
<strong>System:</strong> {{ device.current_version or 'Brak' }}<br>
|
||||
<strong>Firmware:</strong> {{ device.current_firmware or 'Brak' }}<br>
|
||||
<strong>Upgrade Firmware:</strong> {{ device.upgrade_firmware or 'N/A' }}
|
||||
</small>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-info btn-sm" onclick="window.location.href='{{ url_for('device_detail', device_id=device.id) }}'">Szczegóły</button>
|
||||
<button type="button" class="btn btn-secondary btn-sm" onclick="window.location.href='{{ url_for('force_check', device_id=device.id) }}'">Wymuś sprawdzenie</button>
|
||||
<button type="button" class="btn btn-warning btn-sm" onclick="window.location.href='{{ url_for('edit_device', device_id=device.id) }}'">Edytuj</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="6" class="text-center">Brak dodanych urządzeń.</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<!-- Overlay dla masowej aktualizacji systemu -->
|
||||
<div id="mass-system-update-overlay">
|
||||
@ -132,7 +194,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Dynamiczny prompt dla masowego restartu firmware -->
|
||||
<div id="mass-firmware-reboot-prompt" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.7); z-index:1100; color:white; text-align:center; padding-top:200px;">
|
||||
<div id="mass-firmware-reboot-prompt">
|
||||
<h3>Firmware update zakończony.</h3>
|
||||
<p>Czy chcesz zrestartować wszystkie wybrane urządzenia?</p>
|
||||
<button id="mass-firmware-reboot-btn" class="btn btn-danger">Restart urządzeń</button>
|
||||
@ -140,7 +202,7 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Dodajemy event listenery raz, aby uniknąć wielokrotnego przypisywania
|
||||
// Ten sam skrypt masowych akcji, przeniesiony bez zmian w logice
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.getElementById('select-all').addEventListener('change', function() {
|
||||
var checkboxes = document.querySelectorAll('input[name="selected_devices"]');
|
||||
@ -156,7 +218,6 @@
|
||||
});
|
||||
});
|
||||
|
||||
// Pobierz zaznaczone urządzenia
|
||||
function getSelectedDeviceIds() {
|
||||
var selected = [];
|
||||
var checkboxes = document.querySelectorAll('input[name="selected_devices"]:checked');
|
||||
@ -173,7 +234,6 @@
|
||||
alert("Wybierz przynajmniej jedno urządzenie.");
|
||||
return;
|
||||
}
|
||||
// Wysyłamy update systemu dla każdego urządzenia asynchronicznie
|
||||
selectedDevices.forEach(function(id) {
|
||||
fetch(`/device/${id}/update`, { method: 'POST' })
|
||||
.catch(function(error){ console.error('Błąd aktualizacji systemu dla urządzenia ' + id, error); });
|
||||
@ -191,7 +251,7 @@
|
||||
timerDisplay.textContent = timeLeft + ' sekund';
|
||||
if(timeLeft <= 0){
|
||||
clearInterval(interval);
|
||||
// Po zakończeniu odliczania, dla każdego urządzenia wykonaj force_check
|
||||
// Po zakończeniu odliczania, force_check
|
||||
selectedDevices.forEach(function(id) {
|
||||
fetch(`/device/${id}/force_check`, { method: 'GET' })
|
||||
.catch(function(error){ console.error('Błąd force check dla urządzenia ' + id, error); });
|
||||
@ -208,7 +268,6 @@
|
||||
alert("Wybierz przynajmniej jedno urządzenie.");
|
||||
return;
|
||||
}
|
||||
// Wysyłamy update firmware dla każdego urządzenia asynchronicznie
|
||||
selectedDevices.forEach(function(id) {
|
||||
fetch(`/device/${id}/update_firmware`, { method: 'POST' })
|
||||
.catch(function(error){ console.error('Błąd aktualizacji firmware dla urządzenia ' + id, error); });
|
||||
@ -217,7 +276,7 @@
|
||||
document.getElementById('mass-firmware-reboot-prompt').style.display = 'block';
|
||||
});
|
||||
|
||||
// Funkcja sekwencyjnego wysyłania reboot (z opóźnieniem)
|
||||
// Sekwencyjny reboot
|
||||
function sendRebootSequentially(devices, index = 0) {
|
||||
if (index >= devices.length) return Promise.resolve();
|
||||
return fetch(`/device/${devices[index]}/restart`, { method: 'POST' })
|
||||
@ -225,7 +284,6 @@
|
||||
console.error('Błąd wysyłania reboot dla urządzenia ' + devices[index], error);
|
||||
})
|
||||
.then(function() {
|
||||
// Opóźnienie 500 ms przed kolejnym rebootem
|
||||
return new Promise(resolve => setTimeout(resolve, 500));
|
||||
})
|
||||
.then(function() {
|
||||
@ -233,14 +291,11 @@
|
||||
});
|
||||
}
|
||||
|
||||
// Obsługa przycisku restartu w prompt dla masowego firmware update
|
||||
function onMassFirmwareReboot() {
|
||||
document.getElementById('mass-firmware-reboot-prompt').style.display = 'none';
|
||||
var selectedDevices = getSelectedDeviceIds();
|
||||
// Wysyłamy rebooty sekwencyjnie
|
||||
sendRebootSequentially(selectedDevices)
|
||||
.then(function() {
|
||||
// Po wysłaniu reboot dla wszystkich urządzeń, pokazujemy overlay z 2-minutowym paskiem postępu
|
||||
var overlay = document.getElementById('mass-firmware-update-overlay');
|
||||
overlay.style.display = 'block';
|
||||
var timeLeft = 120; // 120 sekund
|
||||
@ -253,7 +308,7 @@
|
||||
timerDisplay.textContent = timeLeft + ' sekund';
|
||||
if(timeLeft <= 0){
|
||||
clearInterval(interval);
|
||||
// Po zakończeniu odliczania, dla każdego urządzenia wykonaj force_check
|
||||
// Po zakończeniu odliczania, force_check
|
||||
selectedDevices.forEach(function(id) {
|
||||
fetch(`/device/${id}/force_check`, { method: 'GET' })
|
||||
.catch(function(error){ console.error('Błąd force check dla urządzenia ' + id, error); });
|
||||
@ -263,8 +318,8 @@
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
// Obsługa standardowego przycisku "Odśwież wybrane"
|
||||
|
||||
// Obsługa "Odśwież wybrane"
|
||||
document.getElementById('mass-update-form').addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
var selectedDevices = getSelectedDeviceIds();
|
||||
@ -279,4 +334,4 @@
|
||||
setTimeout(function(){ location.reload(); }, 2000);
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
Reference in New Issue
Block a user